手撕Verilog面试题专题——(4)序列检测

4 序列检测,当输入序列中出现“10010”时输出一个脉冲信号

状态转移图:
在这里插入图片描述

Verilog代码:

module seq_Detect_state(
	input		clk,
	input		rst,
	input		din,
	output		dout
);

	reg		[2:0]	state;
	reg		[2:0]	nextstate;
	// 采用格雷码进行状态编码
	parameter	s0	= 3'b000;
	parameter	s1	= 3'b001;
	parameter	s2	= 3'b011;
	parameter	s3	= 3'b010;
	parameter	s4	= 3'b110;
	parameter	s5	= 3'b111;
	// 三段式状态机
	// 第一段 描述状态转移
	always @(posedge clk, negedge rst)	begin
		if(rst)
			state	<= s0;
		else
			state	<= nextstate;
	end 
	// 第二段 描述状态转移条件
	always @(*)	begin
		case(state)
			s0:	begin
				if(din == 1'b1)
					nextstate	<= s1;
				else
					nextstate	<= s0;
			end 
			s1	: 	begin
				if(din == 1'b0)
					nextstate	<= s2;
				else
					nextstate	<= s1;
			end
			s2	: 	begin
				if(din == 1'b0)
					nextstate	<= s3;
				else
					nextstate	<= s1;
			end
			s3	: 	begin
				if(din == 1'b1)
					nextstate	<= s4;
				else
					nextstate	<= s0;
			end
			s4	: 	begin
				if(din == 1'b0)
					nextstate	<= s5;
				else
					nextstate	<= s1;
			end
			s5	: 	begin
				if(din == 1'b1)
					nextstate	<= s1;
				else
					nextstate	<= s3;
			end
			default:
				nextstate		<= s0;
		endcase
	end 
	// 第三段 描述输出
	assign dout = (state == s5) ? 1'b1 : 1'b0;

endmodule

testbench仿真文件:

module seq_Detect_state_tb(
);

    reg         clk;
	reg         rst;
	wire   		din;
	wire		dout;
	reg	[23:0]	data;
	
	initial	begin
		clk = 0;
		rst = 1;
		data = 24'b0011_1100_1001_0000_1001_0100;
		#10 rst = 0;
		forever #5 clk = ~clk;
	end
		
	always @(posedge clk)  begin
       #2 data    <= {data[22:0], data[23]};
	end
	assign din = data[23];
	
	seq_Detect_state testone(
	.clk(clk),
	.rst(rst),
	.din(din),
	.dout(dout)
	);

endmodule

仿真波形:
在这里插入图片描述

©️2020 CSDN 皮肤主题: 精致技术 设计师:CSDN官方博客 返回首页