【Verilog语法007】序列检测10010 Verilog实现--moore和mealy两种三段式状态机实现对比

目录

1.状态说明

2.状态转移

3.仿真波形

4.功能代码

4.1moore型

4.2mealy型

5.test beach


主要参考【数字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)
    

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_1615549892

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值