编码仿真作业题2:(50分)
完成一个序列检测器101011011的序列检测,完成RTL编程,完成testbench的编写,并利用VCS进行仿真。
序列检测器是时序数字电路中非常常见的设计之一。它的主要功能是:将一个指定的序列从数字码流中识别出来。接下来就以设计“01101”这个序列的检测器为例,说明Verilog HDL语言的具体应用。设X为数字码流输入,Z为检出标记输出,高电平表示“发现指定序列”,低电平表示“没有发现指定的序列”。设输入的码流为“001101101111011111...”,在时钟2~6中,码流X里出现指定序列“01101”,对应输出Z在第6个时钟变为高电平“1”,表示发现指定"01101”,Z输出“1”。同理在第9个时钟对应输出Z也为“1”。
1、画出状态转换图
2、定义信号和位宽
3、编写序列检测状态机RTL编码
module homework_8_2(
clk ,
rst_n ,
din ,
dout ,
);
input clk ;
input rst_n ;
input din ;
output dout ;
reg dout ;
reg [3:0]state_c ;
reg [3:0]state_n ;
wire s02s1_start ;
wire s12s2_start ;
wire s22s0_start ;
wire s22s3_start ;
wire s32s4_start ;
wire s32s1_start ;
wire s42s0_start ;
wire s42s5_start ;
wire s52s4_start ;
wire s52s6_start ;
wire s62s7_start ;
wire s62s1_start ;
wire s72s0_start ;
wire s72s8_start ;
wire s82s4_start ;
wire s82s0_start ;
parameter S0 = 0;
parameter S1 = 1;
parameter S2 = 2;
parameter S3 = 3;
parameter S4 = 4;
parameter S5 = 5;
parameter S6 = 6;
parameter S7 = 7;
parameter S8 = 8;
//四段式状态机
//第一段:同步时序always模块,格式化描述次态寄存器迁移到现态寄存器(不需更改)
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
state_c <= S0;
end
else begin
state_c <= state_n;
end
end
//第二段:组合逻辑always模块,描述状态转移条件判断
always @(*)begin
case(state_c)
S0:begin
if(s02s1_start)begin
state_n = S1;
end
else begin
state_n = state_c;
end
end
S1:begin
if(s12s2_start)begin
state_n = S2;
end
else begin
state_n =state_c;
end
end
S2:begin
if(s22s0_start)begin
state_n = S0;
end
else if(s22s3_start)begin
state_n = S3;
end
else begin
state_n =state_c;
end
end
S3:begin
if(s32s4_start)begin
state_n = S4;
end
else if(s32s1_start)begin
state_n = S1;
end
else begin
state_n =state_c;
end
end
S4:begin
if(s42s0_start)begin
state_n = S0;
end
else if(s42s5_start)begin
state_n = S5;
end
else begin
state_n =state_c;
end
end
S5:begin
if(s52s4_start)begin
state_n = S4;
end
else if(s52s6_start)begin
state_n = S6;
end
else begin
state_n =state_c;
end
end
S6:begin
if(s62s7_start)begin
state_n = S7;
end
else if(s62s1_start)begin
state_n = S1;
end
else begin
state_n =state_c;
end
end
S7:begin
if(s72s0_start)begin
state_n = S0;
end
else if(s72s8_start)begin
state_n = S8;
end
else begin
state_n =state_c;
end
end
S8:begin
if(s82s4_start)begin
state_n = S4;
end
else if(s82s0_start)begin
state_n = S0;
end
else begin
state_n =state_c;
end
end
default:begin
state_n =S0;
end
endcase
end
//第三段:设计转移条件
//assign s02s0_start = state_c ==S0 && din==0 ;
assign s02s1_start = state_c ==S0 && din==1 ;
//assign s12s1_start = state_c ==S1 && din==1 ;
assign s12s2_start = state_c ==S1 && din==0 ;
assign s22s0_start = state_c ==S2 && din==0 ;
assign s22s3_start = state_c ==S2 && din==1 ;
assign s32s4_start = state_c ==S3 && din==0 ;
assign s32s1_start = state_c ==S3 && din==1 ;
assign s42s0_start = state_c ==S4 && din==0 ;
assign s42s5_start = state_c ==S4 && din==1 ;
assign s52s4_start = state_c ==S5 && din==0 ;
assign s52s6_start = state_c ==S5 && din==1 ;
assign s62s7_start = state_c ==S6 && din==0 ;
assign s62s1_start = state_c ==S6 && din==1 ;
assign s72s0_start = state_c ==S7 && din==0 ;
assign s72s8_start = state_c ==S7 && din==1 ;
assign s82s4_start = state_c ==S8 && din==0 ;
assign s82s0_start = state_c ==S8 && din==1 ;
//第四段:同步时序always模块,格式化描述寄存器输出(可有多个输出)
always @(posedge clk or negedge rst_n)begin
if(rst_n == 0)begin
dout <= 0;
end
else if(state_c ==S8 && din==1 )begin
dout <= 1;
end
else begin
dout <= 0;
end
end
endmodule
4、编写测试代码
`timescale 1 ns/ 1 ns
module tb_homework_8_2();
reg clk ;
reg rst_n ;
reg din ;
wire dout ;
parameter CYCLE = 20;
parameter RST_TIME = 3;
homework_8_2 uut(
.clk (clk ),
.rst_n (rst_n ),
.din (din ),
.dout (dout )
);
initial begin
clk = 0;
forever
#(CYCLE/2)
clk = ~clk;
end
initial begin
rst_n = 1;
#2;
rst_n = 0;
#(CYCLE*RST_TIME);
rst_n = 1;
end
initial begin
#1;
din = 0;
#(CYCLE*10);
din = 1;
#(CYCLE);
din = 1;
#(CYCLE);
din = 0;
#(CYCLE);
din = 1;
#(CYCLE);
din = 0;
#(CYCLE);
din = 1;
#(CYCLE);
din = 1;
#(CYCLE);
din = 0;
#(CYCLE);
din = 1;
#(CYCLE);
din = 1;
#(CYCLE);
din = 0;
#(CYCLE);
din = 0;
#(CYCLE);
din = 0;
#(CYCLE);
din = 1;
#(CYCLE);
din = 0;
#(CYCLE);
din = 1;
#(CYCLE);
din = 0;
#(CYCLE);
end
endmodule
这里简单的进行了测试,测试了一组101011011序列。
5、VCS仿真
通过VCS仿真,我们发现,在状态S8到达,并din为1时,状态跳转为状态S0,且dout拉高为1,符合实验预期。