不枉初心,砥砺前行

皮皮祥的博客

欢迎留言,评论

导航

状态机例子序列检测

简介:
Verilog描述一个可综合的序列检测器用于检测输入数据码流中的特定序列(本次检测序列为10010,只要修改状态转移关系即可实现其他目标序列的检测)。当检测到10010序列(包括重叠的情况)时,序列检测器输出1,否则输出0。
经状态分析化简可得序列检测器的状态转移图如下:
在这里插入图片描述
代码实现:

/*----------------------------------------------
Filename: sequential_detector.v
Function: 检测输入数据中的存在的10010序列
Date: 2019-10-13 13:55:58
----------------------------------------------*/
module sequential_detector(clk, reset, d, y);
	//输入输出端口定义
	input clk, reset, d;
	output y;
	
	//内部寄存器及连线定义
	reg [2 : 0] state;
	wire y;
	
	//状态编码
	parameter idle = 3'b000, s1 = 3'b001, s2 = 3'b010, s3 = 3'b011,
			  s4 = 3'b100, s5 = 3'b101, s6 = 3'b110, s7 = 3'b111;

	//状态机实现
	always@(posedge clk or posedge reset)
	begin
		if(reset) state <= idle;
		else
		begin
			casex(state)
				idle: begin
						if(d == 1) state <= s1;
						else state <= idle;
					  end
				s1: begin
						if(d == 0) state <= s2;
						else state <= s1;
					end
				s2: begin
						if(d == 0) state <= s3;
						else state <= s7;
					end
				s3: begin
						if(d == 1) state <= s4;
						else state <= s6;
					end
				s4:	begin
						if(d == 0) state <= s5;
						else state <= s1;
					end
				s5: begin
						if(d == 1) state <= s1;
						else state <= s3;
					end
				s6: begin
						if(d == 1) state <= s7;
						else state <= s6;
					end
				s7: begin
						if(d == 1) state <= s1;
						else state <= s2;
					end
				default: state <= idle;
			endcase
		end
	end
	
	//用组合逻辑实现输出
	assign y = (state == s4 && d == 0) ? 1 : 0;
endmodule			
/*---------------------------------------------
Filename: sequential_detector_t.v
Function: 测试sequential_detector模块逻辑功能
Date: 2019-10-13 13:56:05
---------------------------------------------*/
`timescale 1ns/1ns
`define halfperiod 10
module sequential_detector_t(clk, reset, d, y);
	//定义要观察的的信号
	output clk, reset, d, y;
	
	//定义内部连线及寄存器
	reg clk, reset;
	reg [23 : 0] data; //定义一个24位的寄存器用于存放待测数据码
	wire d, y;
	
	//生成测试信号逻辑
	initial
	begin
		clk = 0; reset = 0;
		#5 reset = 1;
		#20 reset = 0; data = 24'b0011_1100_1001_0000_1001_0100;
		#(`halfperiod * 200) $stop; //执行100个时钟周期
	end
	
	//产生是时钟信号
	always #`halfperiod clk = ~clk;
	
	//用循环移位的方式待测数据码流
	always@(negedge clk) #5 data = {data[22 : 0], data[23]};
	assign d = data[23]; //将最高位输入到序列检测器中
	
	//实例化调用序列检测器模块
	sequential_detector m0(.clk(clk), .reset(reset), .d(d), .y(y));
endmodule

ModelSim仿真结果如下:
在这里插入图片描述
总结:
由上面的仿真波形图可知,10010序列检测器的逻辑功能已实现,满足了设计预期。

posted on 2023-02-03 13:22  皮皮祥  阅读(87)  评论(0编辑  收藏  举报