Verilog 实现101序列检测器——Moore和Mealy型状态机实现可重叠和不可重叠

1. 可重叠和不可重叠区分

  • 可重叠的序列检测器检测到一个目标串后可以不用回到初始状态,该目标串的元素的可作为下一个目标串的子串继续进行判断。
    0 1 1 0 1 0 1 0 1 1 1 0
  • 不可重叠的序列检测器一次检测完成后必须回到初始状态。
    0 1 1 0 1 0 1 0 1 1 1 0
输入011010101110
可重叠检测输出000010101000
不可重叠检测输出000010001000

2. 可重叠序列检测器实现

2.1. 米利机

1

  • 输出由当前状态和输入共同决定
module	mealy_overlap	(
	output		reg		dout,
	
	input		wire	clk,
	input		wire	rst,
	input		wire	din
);

	reg	[1:0]	curr_state;
	reg	[1:0]	next_state;
	
	parameter	IDLE	=	2'b 00;
	parameter	S1		=	2'b 01;
	parameter	S2		=	2'b 10;
	
	always @ (posedge clk or negedge rst)	begin
		if (!rst)	begin
			curr_state	<=	IDLE;
		end else	begin
			curr_state	<=	next_state;
		end
	end
	
	always @ (*)	begin
		case	(curr_state)
			IDLE:	begin
				if (din == 1)	begin		next_state <= S1;	dout <= 0;	end
				else			begin		next_state <= IDLE;	dout <= 0;	end
			end
			S1:		begin
				if (din == 0)	begin		next_state <= S2;	dout <= 0;	end
				else			begin		next_state <= S1;	dout <= 0;	end
			end
			S2:		begin
				if (din == 1)	begin		next_state <= S1;	dout <= 1;	end
				else			begin		next_state <= IDLE;	dout <= 0;	end
			end
			default:	begin				next_state <= IDLE;	dout <= 0;	end
		endcase
	end
	
endmodule

在这里插入图片描述

2.2. 摩尔机

2

  • 输出由当前状态决定
module	moore_overlap	(
	output	reg		dout,
	
	input	wire	clk,
	input	wire	rst,
	input	wire	din
);

	reg	[1:0]	curr_state;
	reg	[1:0]	next_state;
	
	parameter	IDLE	=	2'b 00;
	parameter	S1		=	2'b 01;
	parameter	S2		=	2'b 10;
	parameter	S3		=	2'b 11;
	
	always@ (posedge clk or negedge rst)	begin
		if (!rst)	begin
			curr_state	<=	IDLE;
		end	else	begin
			curr_state	<=	next_state;
		end
	end
	
	always @ (*)	begin
		case	(curr_state)
			IDLE:	begin
				if (din == 1)		next_state	<=	S1;
				else				next_state	<=	IDLE;
			end
			S1:		begin
				if (din == 0)		next_state	<=	S2;
				else				next_state	<=	S1;
			end
			S2:		begin
				if (din == 1)		next_state	<=	S3;
				else				next_state	<=	IDLE;
			end
			S3:		begin
				if (din == 1)		next_state	<=	S1;
				else				next_state	<=	S2;
			end
			default:	begin		next_state	<=	IDLE;
			end
		endcase
	end
	
	always @ (*)	begin
		if (curr_state == S3)		dout	<=	1;
		else						dout	<=	0;
	end
	
endmodule

在这里插入图片描述

3. 不可重叠序列检测器实现

3.1. 米利机

3

module	mealy_not_overlap	(
	output		reg		dout,
	
	input		wire	clk,
	input		wire	rst,
	input		wire	din
);

	reg	[1:0]	curr_state;
	reg	[1:0]	next_state;
	
	parameter	IDLE	=	2'b 00;
	parameter	S1		=	2'b 01;
	parameter	S2		=	2'b 10;
	
	always @ (posedge clk or negedge rst)	begin
		if (!rst)	begin
			curr_state	<=	IDLE;
		end else	begin
			curr_state	<=	next_state;
		end
	end
	
	always @ (*)	begin
		case	(curr_state)
			IDLE:	begin
				if (din == 1)	begin		next_state <= S1;		dout <= 0;	end
				else			begin		next_state <= IDLE;		dout <= 0;	end
			end
			S1:		begin
				if (din == 0)	begin		next_state <= S2;		dout <= 0;	end
				else			begin		next_state <= S1;		dout <= 0;	end
			end
			S2:		begin
				if (din == 1)	begin		next_state <= IDLE;		dout <= 1;	end
				else			begin		next_state <= IDLE;		dout <= 0;	end
			end
			default:	begin				next_state <= IDLE;		dout <= 0;	end
		endcase
	end
	
endmodule

在这里插入图片描述

3.2. 摩尔机

在这里插入图片描述

module	moore_not_overlap	(
	output	reg		dout,
	
	input	wire	clk,
	input	wire	rst,
	input	wire	din
);

	reg	[1:0]	curr_state;
	reg	[1:0]	next_state;
	
	parameter	IDLE	=	2'b 00;
	parameter	S1		=	2'b 01;
	parameter	S2		=	2'b 10;
	parameter	S3		=	2'b 11;
	
	always@ (posedge clk or negedge rst)	begin
		if (!rst)	begin
			curr_state	<=	IDLE;
		end	else	begin
			curr_state	<=	next_state;
		end
	end
	
	always @ (*)	begin
		case	(curr_state)
			IDLE:	begin
				if (din == 1)		next_state	<=	S1;
				else				next_state	<=	IDLE;
			end
			S1:		begin
				if (din == 0)		next_state	<=	S2;
				else				next_state	<=	S1;
			end
			S2:		begin
				if (din == 1)		next_state	<=	S3;
				else				next_state	<=	IDLE;
			end
			S3:		begin
				if (din == 1)		next_state	<=	S1;
				else				next_state	<=	IDLE;
			end
			default:	begin		next_state	<=	IDLE;
			end
		endcase
	end
	
	always @ (*)	begin
		if (curr_state == S3)		dout	<=	1;
		else						dout	<=	0;
	end
	
endmodule

在这里插入图片描述

摩尔机和米利机的区别

Moore状态机的输出仅依赖于当前状态而与输入无关。想要输出dout = 1,状态S3必须形成。

Mealy状态机的输出与当前状态和输入有关。想要输出dout = 1,状态S2下输入din = 1就可以了,不需要状态S3。根据波形可对比反应更快。

<think>嗯,用户的问题是关于如何设计一个“110”序列检测器,并且编写测试激励进行Modelsim仿真。首先,我需要回忆一下有限状态机(FSM)的基本原理。序列检测器通常使用FSM来实现,状态转移取决于输入信号。之前的例子是检测“101”,现在需要改成“110”,所以需要调整状态转移的条件。 首先,我需要理解“101检测器的参考代码。用户可能提供的代码中,状态机可能有几个状态,比如初始状态、检测到第一个1、检测到10、检测到101等。现在要改为检测“110”,状态转移应该不同。比如,初始状态S0,当输入1时进入S1,在S1时再次输入1则进入S2,然后在S2输入0则触发输出,并回到初始状态或适当的状态。 接下来要考虑状态定义是否正确。可能的状态转移路径是:S0→S1(输入1),S1→S2(输入1),S2→S0(输入0)并输出。如果中间有输入不符合的情况,需要回到相应的状态。比如,在S1时输入0的话,应该回到S0,因为序列中断了。同样,在S2时输入1的话,可能需要保持在S2,因为可能有连续的1,比如输入“1110”,第三个1之后遇到0才会触发。 然后,测试激励部分需要生成输入序列,这里用户之前的测试激励可能是一个固定的序列,比如“01011001110010100101100101001111”循环输入。对于“110”检测器,同样的输入序列的输出波形需要分析。比如,当输入序列中有“110”出现时,输出一个高电平。需要找出所有“110”的位置,并确定输出是否正确。 编写测试激励时,需要将输入信号按时钟周期逐个比特输入。在Verilog中,可以使用initial块时钟边沿来驱动输入变化。可能需要将输入序列存储在一个数组中,然后循环遍历每个比特,每个时钟周期赋值一次。 还需要注意MealyMoore状态机的区别。参考代码可能使用的是Moore,输出仅依赖于当前状态,而Mealy输出依赖于状态输入。需要确定参考代码的类,并保持一致。例如,在检测到“110”时,如果是Moore,输出会在状态转移到特定状态时(如S3)持续一个周期;如果是Mealy,可能在状态S2时遇到输入0就立即输出。 可能遇到的问题包括状态转移错误,比如没有正确处理非连续输入后的状态回归,或者在输出后没有正确复位状态。需要仔细检查每个状态的条件,并确保覆盖所有可能的输入情况。 最后,进行仿真验证时,需要观察输入序列中的每一个“110”实例,并确认输出信号在正确的时钟周期拉高。同时,检查是否有误报的情况,比如在非连续的“110”位置输出高电平。 总结步骤:1. 修改状态转移逻辑,将检测目标从“101”改为“110”;2. 调整每个状态下的输入条件下一个状态;3. 编写测试激励,生成包含“110”的输入序列;4. 运行仿真,检查输出是否符合预期。</think>我将以清晰的步骤指导您完成"110"序列检测器的设计与仿真验证: 一、有限状态机设计分析(状态转移图) $$ \begin{aligned} & S0:\ \text{初始状态}\\ & \xrightarrow{1} S1 \quad \xrightarrow{1} S2 \quad \xrightarrow{0} \text{输出1}\\ & \text{其他输入均返回S0} \end{aligned} $$ 二、Verilog代码改写(SystemVerilog实现) ```verilog module detector_110( input clk, rst_n, input din, output reg dout ); typedef enum {S0, S1, S2} state_t; state_t current_state, next_state; always @(posedge clk or negedge rst_n) begin if(!rst_n) current_state <= S0; else current_state <= next_state; end always @(*) begin case(current_state) S0: next_state = (din) ? S1 : S0; S1: next_state = (din) ? S2 : S0; S2: next_state = (din) ? S2 : S0; default: next_state = S0; endcase end always @(posedge clk) begin dout <= (current_state == S2) && (din == 0); end endmodule ``` 三、测试激励改写要点 1. 输入序列生成逻辑: ```verilog bit [31:0] test_pattern = 32'b01011001110010100101100101001111; int index = 0; always #10 din = test_pattern[index++%32]; ``` 2. 预期输出计算示例(原输入序列中的110位置): 输入序列循环段:0 1 0 1 1 0 0 1 1 1 0 0 1 0 1 0... 对应输出波形应在以下位置出现高电平: - 第5-7周期(1-1-0) - 第9-11周期(1-1-0) - 第21-23周期(1-1-0) 四、仿真验证步骤 1. 编译修改后的设计文件测试激励 2. 在ModelSim中运行仿真 3. 观察信号波形,验证输出脉冲: - 当连续出现110时,dout产生单周期高电平 - 其他组合不触发输出 - 重叠检测处理正确(如110110应触发两次) 五、设计优化建议 1. 添加流水线寄存器提升时序性能 2. 参数化设计支持不同序列检测 3. 增加错误计数器进行可靠性监控 修改后的代码保留了原始检测器的架构优势,同时通过调整状态转移逻辑实现新功能。建议仿真时使用覆盖率分析确保所有状态转移路径都被充分验证。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值