目录
主要参考【数字IC工程师】数据流序列检测Verilog实现 - 知乎,链接中有点小错误,本文已修正。
1.状态说明
A: 来过1
B:来过10
C:来过100
D:来过1001
E:来过10010
2.状态转移
3.仿真波形
结论:仿真波形可以看出mealy型可以提前一个周期出结果。
4.功能代码
tb可以公用,下面分别给出moore和mealy型的写法
4.1moore型
module SEQ_CHK(//moore型
input clk ,
input rst_n,
input [1:0] seq ,
output reg hit
);
//定义设计中使用到的参数
parameter DLY = 1;
`ifdef SIM_OPEN
parameter IDLE = "IDLE",
A = "A",
B = "B",
C = "C",
D = "D",
E = "E";
reg[127:0] cur_state,next_state;
`else
parameter IDLE = "IDLE",
A = "A",
B = "B",
C = "C",
D = "D",
E = "E";
reg[31:0] cur_state,next_state;
`endif
//第一段状态转移
always@(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)begin
cur_state <= #DLY IDLE;
end else begin
cur_state <= #DLY next_state;
end
end
//第二段产生下一状态 数据流检测序列状态变化
always@(*)begin
case(cur_state)
IDLE:begin
if(seq == 2'b1)
next_state = A;
else
next_state = IDLE;
end
A:begin
if(seq == 2'b1)
next_state = A;
else
next_state = B;
end
B:begin
if(seq == 2'b1)
next_state = A;
else
next_state = C;
end
C:begin
if(seq == 2'b1)
next_state = D;
else
next_state = IDLE;
end
D:begin
if(seq == 2'b1)
next_state = A;
else
next_state = E;
// next_state = B;
end
E:begin
if(seq == 2'b1)
next_state = A;
else
next_state = C;
end
default:begin
next_state = IDLE;
end
endcase
end
end
//第三段输出 在数据流中检测到序列"10010"输出检测命中标志
always@(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)begin
hit <= #DLY 1'b0;
end else begin
hit <= #DLY (cur_state == E ) ? 1'b1 : 1'b0;
end
end
//debug
wire [31:0] state_debug;
assign state_debug[0] = (cur_state==s_idle )?1'b1:1'b0;
assign state_debug[1] = (cur_state==s_send_start )?1'b1:1'b0;
assign state_debug[2] = (cur_state==s_send_byte )?1'b1:1'b0;
assign state_debug[3] = (cur_state==s_send_parity )?1'b1:1'b0;
assign state_debug[4] = (cur_state==s_send_stop )?1'b1:1'b0;
endmodule
4.2mealy型
module SEQ_CHK(//mealy
input clk ,
input rst_n,
input [1:0] seq ,
output reg hit
);
//定义设计中使用到的参数
parameter DLY = 1;
parameter IDLE = "IDLE",
A = "A",
B = "B",
C = "C",
D = "D",
E = "E";
//状态寄存器定义
reg[31:0] cur_state,next_state;
//第一段状态转移
always@(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)begin
cur_state <= #DLY IDLE;
end else begin
cur_state <= #DLY next_state;
end
end
//第二段产生下一状态 数据流检测序列状态变化
always@(*)begin
case(cur_state)
IDLE:begin
if(seq == 2'b1)
next_state = A;
else
next_state = IDLE;
end
A:begin
if(seq == 2'b1)
next_state = A;
else
next_state = B;
end
B:begin
if(seq == 2'b1)
next_state = A;
else
next_state = C;
end
C:begin
if(seq == 2'b1)
next_state = D;
else
next_state = IDLE;
end
D:begin
if(seq == 2'b1)
next_state = A;
else
// next_state = E;
next_state = B;
end
// E:begin
// if(seq == 2'b1)
// next_state = A;
// else
// next_state = B;
// end
default:begin
next_state = IDLE;
end
endcase
end
end
//第三段输出 在数据流中检测到序列"10010"输出检测命中标志
always@(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)begin
hit <= #DLY 1'b0;
end else begin
hit <= #DLY (cur_state == D && seq == 2'b0) ? 1'b1 : 1'b0;
end
end
//debug
wire [31:0] state_debug;
assign state_debug[0] = (cur_state==s_idle )?1'b1:1'b0;
assign state_debug[1] = (cur_state==s_send_start )?1'b1:1'b0;
assign state_debug[2] = (cur_state==s_send_byte )?1'b1:1'b0;
assign state_debug[3] = (cur_state==s_send_parity )?1'b1:1'b0;
assign state_debug[4] = (cur_state==s_send_stop )?1'b1:1'b0;
endmodule
5.test beach
tb可以公用
module tb();
reg clk, rst_n, seq;
wire hit;
SEQ_CHK U_SEQ_CHK(
.clk (clk ),
.rst_n (rst_n),
.seq ({1'b0,seq} ),
.hit (hit )
);
initial begin
clk = 1'b0;
rst_n = 1'b0;
seq = 1'b0;
#30ns;
rst_n = 1'b1;
end
initial begin
forever begin
#5ns;
clk = ~clk;
end
end
//10010
initial begin
#20ns;
@(posedge clk) #1ns; seq = 1'b1;
@(posedge clk) #1ns; seq = 1'b1;
@(posedge clk) #1ns; seq = 1'b0;
@(posedge clk) #1ns; seq = 1'b0;
@(posedge clk) #1ns; seq = 1'b1;
@(posedge clk) #1ns; seq = 1'b0;//hit
@(posedge clk) #1ns; seq = 1'b0;
@(posedge clk) #1ns; seq = 1'b1;
@(posedge clk) #1ns; seq = 1'b0;
@(posedge clk) #1ns; seq = 1'b0;
@(posedge clk) #1ns; seq = 1'b0;
@(posedge clk) #1ns; seq = 1'b0;
@(posedge clk) #1ns; seq = 1'b1;
@(posedge clk) #1ns; seq = 1'b0;
@(posedge clk) #1ns; seq = 1'b0;
@(posedge clk) #1ns; seq = 1'b1;
@(posedge clk) #1ns; seq = 1'b0;//hit
@(posedge clk) #1ns; seq = 1'b1;
@(posedge clk) #1ns; seq = 1'b0;
@(posedge clk) #1ns; seq = 1'b0;
@(posedge clk) #1ns; seq = 1'b1;
end
endmodule
仿真工程
https://www.jianguoyun.com/p/Db1cgpsQupbwCBiCm8ID (访问密码 : csdn)