状态机机制是流水线设计的重要内容,本文此次通过一个具体例子来详细进行讲解。
设计任务:
建立工程,设计代码
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 endendmodule
编写testbench,并设定路径;
`timescale 1ns/1ns
`define clock_period 20module 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核即层次化结构时会有重要的作用。