状态机的设计实例

状态机机制是流水线设计的重要内容,本文此次通过一个具体例子来详细进行讲解。

设计任务:

 建立工程,设计代码

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核即层次化结构时会有重要的作用。

原文地址:https://www.cnblogs.com/noticeable/p/7202255.html