状态机编写方式
状态机设计编写有三种方式,分别是一段式、两段式、三段式三种方式。
设计目的
通过一段式状态机编写,实现字符串检测“Hello”功能。
设计思路
首先对不同状态进行编码,字符串检测过程中,需要顺次对每一个字符串进行检测,首先检测“H”,如果是则跳到下一状态检测“e”,如果不是则继续检测“H”,如果下一状态是“e”,则进行状态跳转,以此类推。当最终实现检测时,使得led状态翻转。
设计代码编写
对应设计思路编写设计代码
module hello(Clk,Rst_n,data,led);
input Clk;
input Rst_n;
input [7:0]data;//ascii码为八位数据
output reg led;
localparam//文件内部使用,无法在外部进行更改
//参数定义,define
//编码方式:独热码,格雷码,二进制编码
CHECK_H = 5'b0_0001,
CHECK_E = 5'b0_0010,
CHECK_L1 = 5'b0_0100,
CHECK_L2 = 5'b0_1000,
CHECK_O = 5'b1_0000;
reg[4:0]state;
//状态机编写方式1、一段式2、两段式3、三段式状态机
//一段式状态机编写
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)begin
led <= 1'b1;
state <= CHECK_H;
end
else begin
case(state)
CHECK_H:
if(data == "H")
state <= CHECK_E;
else
state <= CHECK_H;
CHECK_E:
if(data == "e")
state <= CHECK_L1;
else
state <= CHECK_H;
CHECK_L1:
if(data == "l")
state <= CHECK_L2;
else
state <= CHECK_H;
CHECK_L2:
if(data == "l")
state <= CHECK_O;
else
state <= CHECK_H;
CHECK_O:
begin
state <= CHECK_H;
if(data == "O")
led <= ~led;
else
led <= led;
end
default:state <= CHECK_H ;
endcase
end
endmodule
测试代码编写
编写testbench文件
在编写testbench文件的过程中,激励输入的数据随机给一段字符串数据,其中包含“Hello”,可以观察输出状态
新关键词:重复一直执行的语句forever语句
`timescale 1ns/1ns
`define clock_period 20
module hello_tb;
reg Clk;
reg Rst_n;
reg [7:0]ASCII;
wire led;
hello hello_0(
.Clk (Clk),
.Rst_n (Rst_n),
.data (ASCII),
.led (led)
);
initial Clk = 1;
always #(`clock_period/2)Clk = ~Clk;
initial begin
Rst_n = 1;
#(`clock_period*200);//延时200个时钟周期
Rst_n = 0;
#(`clock_period*200);//延时200个整数系统时钟周期之后开始forever语句,这样ASCII数据的发送与时钟沿对齐,
//不利于观测测量结果。可以将传输数据ascii延迟非整数周期个之后进行观测 #(`clock_period*200+1);
Rst_n = 1; //后仿真时候输出端报错为STX状态,查找资料后发现,需要将复位信号拉低后过一段时间再拉高即可
forever begin//forever语句 会连续不断一直执行下去
ASCII = "I";
#(`clock_period);
ASCII = "h";
#(`clock_period);
ASCII = "e";
#(`clock_period);
ASCII = "l";
#(`clock_period);
ASCII = "o";
#(`clock_period);
ASCII = "H";
#(`clock_period);
ASCII = "e";
#(`clock_period);
ASCII = "l";
#(`clock_period);
ASCII = "l";
#(`clock_period);
ASCII = "O";
#(`clock_period);
end
end
endmodule