狀態機機制是流水線設計的重要內容,本文此次通過一個具體例子來詳細進行講解。
設計任務:
建立工程,設計代碼
module flag(clk,rst_n,data_in,led);
input clk,rst_n; //clk50M,rst_n低電平復位
input [7:0]data_in;
output reg led;
localparam //說明下列數據是在文件化內部使用的,無法再外部進行更改。
CHECK_H=5'b0_0001,
CHECK_e=5'b0_0010,
CHECK_la=5'b0_0100,
CHECK_lb=5'b0_1000,
CHECK_o=5'b1_0000; //獨熱碼的編碼方式,可以看下夏宇聞教授的講解,簡化譯碼邏輯
reg[4:0] state;//一段式狀態機,兩段式狀態機,三段式狀態機,三段式狀態機的邏輯是最高的,一段式更利於學習,所以現在先學習一段式
always@(posedge clk or negedge rst_n) //加上時序
if(!rst_n) //復位鍵是否按下
begin
led=0;
state<=CHECK_H; //設定初始狀態
end
else
begin
case(state)
CHECK_H:
if(data_in=="h") //采用的是ASICALL碼,H:8'h15
state<=CHECK_e;
else
state<=CHECK_H;
CHECK_e:
if(data_in=="e")
state<=CHECK_la;
else
state<=CHECK_H;
CHECK_la:
if(data_in=="l")
state<=CHECK_lb;
else
state<=CHECK_H;
CHECK_lb:
if (data_in=="l")
state<=CHECK_o;
else
state<=CHECK_H;
CHECK_o:
if (data_in=="o")
begin
led<=~led;
state<=CHECK_H;
end
else
state<=CHECK_H;
default
state<=CHECK_H;
endcase
end
endmodule
編寫testbench,並設定路徑;
`timescale 1ns/1ns
`define clock_period 20
module flag_tb;
reg clk;
reg rst_n;
reg [7:0]ASCII;
wire led;
flag flag0( .clk(clk),
.rst_n(rst_n),
.data_in(ASCII),
.led(led));
initial clk=1'b1;
always #(`clock_period/2) clk=~clk;
initial begin
rst_n=0;
ASCII=0;
#(`clock_period*200)
rst_n=1'b1;
forever begin
ASCII="C";
#(`clock_period)
ASCII="h";
#(`clock_period)
ASCII="e";
#(`clock_period)
ASCII="l";
#(`clock_period)
ASCII="l";
#(`clock_period)
ASCII="o";
#(`clock_period)
ASCII="I";
end
end
endmodule
點擊仿真按鈕,進行程序仿真,可以看出,完成一次hello輸入后,狀態機才會到最后一層,將LED翻轉。
至此,狀態機的原理測試完成,狀態機在編寫CPU核即層次化結構時會有重要的作用。