【Verilog HDL实践】序列检测实现

【Verilog HDL实践】序列检测实现

使用芯片:Altera Cyclone® IV EP4CE22F17C6N FPGA
开发工具:Quartus Ⅱ
开发项目:六、设计一个“10010”串行数据检测器。当检测到数据串时,Y输出高电平,其余时间Y输出低电平。输入X:000101010010011101001010100010101001001110100101010101。

序列检测分析

使用状态机思想
共5种状态:

  • state_d:初始状态,当第一个输入非1 或 检测到1000等数据时的状态。
  • 状态1:检测到‘1’,当前输入为0时跳转到状态2,否则保持原状态。
  • 状态2:检测到‘10’,当前输入为0时跳转到状态3,否则跳转到状态1。
  • 状态3:检测到‘100’,当前输入为1时跳转到状态4,否则跳转到state_d。
  • 状态4:检测到‘1001’,当前输入为0时跳转到状态2,并输出高电平;否则跳转到状态1。
    这里没有引入状态’10010‘,因为个人觉得不是很有必要,状态4检测到0时已经输出为高,切换到状态5后貌似存在冗余。
代码展示
/*
Sequence Detection
功能描述:
	序列检测 ‘10010’串行数据检测器
引脚描述:
	输入:50MHz时钟
	输出:led[0]切换代表序列值切换、led[1]亮代表检测到‘10010’
状态分析:
	‘1’、’10‘、’100‘、’1001‘、‘等待状态’
*/
module Sequence_detection(led, clk);
	input clk;
	output reg[1:0] led = 2'b00;
	
	parameter state1=3'b000, state2=3'b001, state3=3'b010, state4=3'b011, state_d=3'b111;//状态定义
	parameter[31:0] duration = 32'd12500000; //timer:500ms
	
	reg[1:0] current_state = state_d, next_state = state_d;
	reg[31:0] counter = 32'b0;
	reg delay_flag = 1'b0;
	
	reg[53:0] checking_value = 54'b00010101_00100111_01001010_10001010_10010011_10100101_010101;
	reg[5:0] checking_position=6'b0;
	parameter sequence_length = 54;

	//状态切换
	always@(posedge clk) begin
		current_state <= next_state;
		counter <= counter + 1'b1;
		if(counter >= duration-1) begin
			counter <= 0;
			led[0] <= ~led[0];
			delay_flag <= ~delay_flag;
		end
	end
	
	//下个状态变换
	always@(posedge delay_flag) begin
		
		led[1] <= 1'b0;
		checking_position <= checking_position + 1;
		if(checking_position >= sequence_length-1)
			checking_position <= 0;
		case(current_state)
			state_d: begin
				if(checking_value[checking_position])
					next_state <= state1;
			end
			state1: begin //1->10 / 11
				if(!checking_value[checking_position])
					next_state <= state2;
			end
			state2: begin //10->100 / 101
				if(!checking_value[checking_position])
					next_state <= state3;
				else
					next_state <= state1;
			end
			state3: begin //100->1001 / 1000
				if(checking_value[checking_position])
					next_state <= state4;
				else 
					next_state <= state_d;
			end
			state4: begin //1001->10010 / 10011
				if(!checking_value[checking_position]) begin
					next_state <= state2;
					led[1] <= 1'b1;
				end
				else
					next_state <= state1;
			end
			
		endcase
	end
endmodule

代码中引入一个500ms的定时器是为了确定代码移植到开发板后正常,通过观察灯的变换可以检测是否正确。
代码中检测到序列后使用非阻塞赋值,导致输出为高的时刻有所滞后,可以修改赋值方式实现输出时刻调整。

时序测试

序列检测时序测试
这里将duration,即定时器改为4倍频,查看输出情况,可以看到,检测完第12个序列值后输出变为1(前12个值:000101010010)
这里我第一次直接将第二个always的触发源换为clk后时序输出不对,感觉应该是和第一个冲突了?(有时候老是有些莫名其妙的问题)
烧到板子上也是没有问题的

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值