一、逻辑设计
二、代码
module State_Hello(Clk,Rst_n,data,led);
input Clk;
input Rst_n;
input [7:0]data; //检测字母,每个字母由8位的ASCII码表示
output reg led;
localparam //之前采用parameter
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
state <= 5'b0;
led = 1'b0;
end
else begin
case(state)
CHECK_H:
if(data == "H") //H 对应8'h15
state <= CHECK_e;
else
state <= CHECK_H;
CHECK_e:
if(data == "e")
state <= CHECK_la;
else
state <= CHECK_H;
CHECK_la:
if(data == "l")
state <= CHECK_lb;
else
state <= CHECK_H;
CHECK_lb:
if(data == "l")
state <= CHECK_o;
else
state <= CHECK_H;
CHECK_o:
if(data == "o")begin
led = ~led;
state <= CHECK_H;
end
else
state <= CHECK_H;
default:
state <= CHECK_H;
endcase
end
endmodule
`timescale 1ns/1ps
`define clock_period 20
module State_Hello_tb;
reg Clk;
reg Rst_n;
reg [7:0]data;
wire led;
State_Hello hello(
.Clk(Clk),
.Rst_n(Rst_n),
.data(data),
.led(led)
);
initial Clk = 1'b0;
always#(`clock_period/2) Clk = ~ Clk;
initial begin
Rst_n = 1'b0;
#(`clock_period * 20);
Rst_n = 1'b1;
#(`clock_period * 20);
forever begin
data = "I";
#(`clock_period);
data = "b";
#(`clock_period);
data = "H";
#(`clock_period);
data = "e";
#(`clock_period);
data = "l";
#(`clock_period);
data = "l";
#(`clock_period);
data = "O";
#(`clock_period);
data = "H";
#(`clock_period);
data = "e";
#(`clock_period);
data = "l";
#(`clock_period);
data = "l";
#(`clock_period);
data = "o";
#(`clock_period);
data = "h";
#(`clock_period);
end
end
endmodule
三、存在问题
1、当发送"HHello"时,第一个时钟周期进入CHECK_H检测第一个"H",第二个时钟周期进入CHECK_e检测第二个"H",这时state=CHECK_H,第三个时钟周期进入CHECK_H检测"e",…所以这种情况下无法检测出"Hello"。
2、后仿真时,先会出现红色的线。是因为没有赋初值,本实验中data和led都出现了这种情况,只需要先赋值就行。