当前位置: 代码迷 >> 综合 >> 【原创】Verilog编写 “1101” 序列检测器
  详细解决方案

【原创】Verilog编写 “1101” 序列检测器

热度:16   发布时间:2024-03-06 01:09:13.0

序列检测器是时序数字电路中非常常见的设计之一。它的主要功能是将一个指定的序列从数字码流中识别出来。这里给出一个“1101”序列检测器的Verilog实现和Testbench代码。

★设计目标:“1101”序列检测器

★EDA:Quartus 15.0

★仿真软件:Modelsim 10.1c

本序列检测器共有4个bit位,每个bit占用一个状态,再加上开始和结束状态,故使用格雷码定义6个状态:

// 序列检测器 状态编码(格雷码)
localparam	SEQ_IDLE	=	3'b000;
localparam	SEQ_STATE1	=	3'b001;
localparam	SEQ_STATE2	=	3'b011;
localparam	SEQ_STATE3	=	3'b010;
localparam	SEQ_STATE4	=	3'b110;
localparam	SEQ_STOP	=	3'b111;

 采用一段式状态机,状态转移图如下:

 SEQ_IDLE:检测bit流中是否出现 “1” ,出现则跳转到下一状态。

SEQ_STATE1:检测bit流中是否出现 “1” ,出现则跳转到下一状态,若出现 "0" 则跳转回 SEQ_IDLE 重新等待第一个 “1” bit位。

SEQ_STATE2:检测bit流中是否出现 “1” ,出现则跳转到下一状态,若出现 "0" 则跳转回 SEQ_IDLE 重新等待第一个 “1” bit位。 

SEQ_STATE3:检测bit流中是否出现 “0” ,出现则跳转到下一状态,若出现 "1" 则跳转回 SEQ_IDLE 重新等待第一个 “1” bit位。

SEQ_STATE4:检测bit流中是否出现 “1” ,出现则跳转到下一状态,若出现 "0" 则跳转回 SEQ_IDLE 重新等待第一个 “1” bit位,  同时拉高输出标志位 。

SEQ_STOP:拉低输出标志位,同时跳转回 SEQ_IDLE 开始下一轮检测。

 

“1101”序列检测器完整Verilog代码如下:

module	seq_detector(
// 输入端口input			clk100M,		// 输入时钟:100MHzinput			rst_n,			// 异步复位:低电平复位input			data_in,		// 输入串行数据
// 输出端口	output reg  data_out				// 输出标志
);// 序列检测器 状态编码(格雷码)
localparam	SEQ_IDLE	=	3'b000;
localparam	SEQ_STATE1	=	3'b001;
localparam	SEQ_STATE2	=	3'b011;
localparam	SEQ_STATE3	=	3'b010;
localparam	SEQ_STATE4	=	3'b110;
localparam	SEQ_STOP	=	3'b111;reg[2:0]	seq_state;				// 状态寄存器// 序列检测器 一段式状态机
always@(posedge clk100M or negedge rst_n)beginif(!rst_n)begindata_out	<=	1'b0;seq_state	<= SEQ_IDLE;endelse begincase(seq_state)// IDLESEQ_IDLE: begindata_out		<=	1'b0;if(data_in)seq_state	<= SEQ_STATE1;elseseq_state	<= SEQ_IDLE;end// 检测bit1SEQ_STATE1: beginif(data_in)seq_state	<= SEQ_STATE2;elseseq_state	<= SEQ_IDLE;end// 检测bit2SEQ_STATE2: beginif(~data_in)seq_state	<= SEQ_STATE3;elseseq_state	<= SEQ_IDLE;end// 检测bit3SEQ_STATE3: beginif(data_in)seq_state	<= SEQ_STATE4;elseseq_state	<= SEQ_IDLE;end// 检测bit4SEQ_STATE4: beginif(data_in)beginseq_state	<= SEQ_STOP;data_out	<=	1'b1;endelseseq_state	<= SEQ_IDLE;end// STOPSEQ_STOP: beginseq_state	<= SEQ_IDLE;data_out	<=	1'b0;endendcaseend
endendmodule

 

Testbench代码如下: 

`timescale 1ns/1ps
module	seq_detector_tb;reg			clk100M;
reg			rst_n;
reg[15:0]	        data;
wire			data_in;
wire			data_out;// 信号初始化
initial beginclk100M   = 0;rst_n	  = 1;#10 rst_n = 0;#10 rst_n = 1;// 生成序列data = 15'b1101_0010_1101_1001;
end// 生成100MHz时钟
always#5 clk100M = ~clk100M;// 序列在下降沿移位,在相邻的上升沿采样	
always@(negedge clk100M)data = { data[14:0] , data[15] };// 串行输出
assign	data_in = data[15];	// RTL例化
seq_detector seq_detector_inst(.clk100M(clk100M),.rst_n(rst_n),.data_in(data_in),.data_out(data_out)
);endmodule

testbench中使用16位环形移位寄存器将既定的4组4bit序列从MSB开始,依次一位一位地从 data 移出到 data_in 上并循环输出,若检测到序列 “1101“ 则将data_out拉高一个时钟周期。