前言
本文介绍的是用Verilog语言编写一个用于识别2进制序列“1011”的状态机。
一、设计要求
基本要求:
电路每个时钟周期输入1比特数据,当捕获到1011的时钟周期,电路输出1,否则输出0。
使用序列101011010作为输出的测试序列。
扩展要求:
给你的电路添加输入使能端口,只有输入使能EN为1的时钟周期,才从输入的数据端口向内部获取1比特序列数据。
二、问题分析
分析:题目要求在序列中捕获到“1011”的时钟周期时,电路输出1,其他的情况都输出0,而且只有使能EN为1时才能从输入的数据端口向内部获取1比特序列数据,因此需要考虑以下几个问题:
1.不使能时,即EN=0时,下一个状态是什么?
举一个例子,比如序列10111这个序列,EN在前三个周期和第五个周期使能,第四个周期不使能,那么输出是不是为1呢?
答案是否定的。如果第四个周期也使能,那毫无疑问输出为1,但第四个周期不使能,如果10111在上述使能的条件下输出为1的话,那么10101在这个使能条件下输出也为1,显然不正确,因此,凡是使能EN=0时,都退回到初始状态,也就是ST0。
2.在状态递进的过程中要考虑到每一组的状态,而不是四个一组直接比较向后推进。
比如测试序列101011010101不能简单的看作是三组,即1010、1101、0101,这样显然在1011时输出不能为1,故在代码中要考虑这个问题,正确的应该是将1010、0101、1011、0110、1101、1010、0101、1010、0101这九组依次查询,显然1011就在其中,输出在这个序列到来时自然会输出1。
三、状态跳转逻辑表
四、输出逻辑表
五、Verilog HDL代码
2进制序列“1011”的状态机的Verilog HDL代码如下:
module stateR1011(
CLK ,
RST ,
IN ,
EN ,
OUT );
input CLK ;
input RST ;
input EN ;
input IN ;
output OUT ;
parameter ST0 = 0;
parameter ST1 = 1;
parameter ST2 = 2;
parameter ST3 = 3;
parameter ST4 = 4;
reg [4-2:0]stateR;
reg [4-2:0]next_state;
reg OUT;
always @ (IN or EN or stateR) begin
case (stateR)
ST0 :begin
if(EN == 1 && IN == 1) next_state = ST1 ;
else next_state = ST0 ;
end
ST1 :begin
if(EN == 1 && IN == 0) next_state = ST2 ;
else if(EN == 1 && IN == 1) next_state = ST1 ;
else next_state = ST0 ;
end
ST2 :begin
if(EN == 1 && IN == 1) next_state = ST3 ;
else next_state = ST0 ;
end
ST3 :begin
if(EN == 1 && IN == 1) next_state = ST4 ;
else if(EN == 1 && IN == 0) next_state = ST2 ;
else next_state = ST0 ;
end
ST4 :begin
next_state = ST0 ;
end
endcase
end
always @ (stateR) begin
if(stateR == ST4)
OUT = 1'b1;
else
OUT = 1'b0;
end
always @ (posedge CLK or posedge RST)begin
if(RST)
stateR <= ST0;
else
stateR <= next_state;
end
endmodule
六、由Verilog HDL代码生成的示意图
代码编译后在Tools——>Netlists——>State Machine Viewer可以查看自动生成的状态机示意图。
七、波形仿真
由仿真波形可以看出,在使能EN=1和复位RST=0时,遇到1011信号,输出为1;在1011序列中只要有EN=0或RST=1,其输出就为0,这符合题目要求。
总结
以上就是用Verilog设计一个用于识别2进制序列“1011”的状态机的全部内容了,通过这个例子,我们在以后编写状态机时就能有一个良好的思路,从而使得操作流程简单明了。