设为首页 加入收藏

TOP

序列检测器(两种设计方法和四种检测模式|verilog代码|Testbench|仿真结果)(三)
2023-07-23 13:25:05 】 浏览:123
Tags:计方法 verilog 代码 Testbench
,但1是1001的第一个数,所以进入S1状态。

S3:代表目前已经有了3个匹配的数据。
seq_in = 1时,当前序列为1001,与要求序列匹配,进入S4状态;

seq_in = 0时,当前序列为1000,与要求序列不配,0与初始状态匹配,所以进入IDLE状态。

S4:最终状态,代表目前已经得到了匹配的序列,输出信号翻转。
seq_in = 1时,当前序列为10011,1与要求序列的第一个数匹配,所以进入S1状态;

seq_in = 0时,当前序列为10010,10与要求的前两个数匹配,所以进入S2状态。

第二步:根据流程转换分析画出状态机的状态转移图,如下图所示:

image

第三步:根据状态机转移图用经典三段式(或者二段式)写出verilog代码

3.12verilog代码

//使用状态机设计检测“1001”的序列检测器
//可重叠检测序列“1001”
module sequence_detect03(
    input			clk ,
    input			rst_n,
    input			seq_in,
    output reg 		mismatch		//检验序列是否匹配,匹配输出0,不匹配输出0
    );

//采用独热码编译五个状态,初始IDLE状态为待机状态
//独热码相比二进制码和格雷码,方便电路设计判断、状态转移,且逻辑更简单  
parameter		IDLE = 5'b00001;
parameter 	 	S1 	 = 5'b00010;
parameter  		S2 	 = 5'b00100;
parameter  		S3   = 5'b01000;
parameter  		S4   = 5'b10000;

//定义两个寄存器表示状态机的目前状态和下一状态
reg [4:0] curr_state;
reg [4:0] next_state;

//第一段使用时序逻辑描述状态转移
always@(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
	    curr_state <= IDLE;
    end
    else begin
	    curr_state <= next_state;
    end
end

//第二段使用组合逻辑判断状态转移条件
always@(*) begin
    if(!rst_n) begin
	    next_state <= IDLE;
    end
    else begin
	    case(curr_state)
	        IDLE  :next_state = seq_in?S1:IDLE;
	        S1	  :next_state = seq_in?S1:S2;
	        S2	  :next_state = seq_in?S1:S3;
	        S3	  :next_state = seq_in?S4:IDLE;
	        S4	  :next_state = seq_in?S1:S2;
	        default:next_state = IDLE;		//养成良好代码风格,不能遗漏,防生成latch,也可以通过赋初值避免
	endcase
    end
end

//第三段描述状态输出(可以使用组合逻辑,也可以用时序逻辑)
//此处采用时序逻辑,同时也提供组合逻辑代码示例
always@(posedge clk or negedge rst_n) begin			//时序逻辑描述输出
    if(!rst_n) begin
	    mismatch <= 1'b1;
    end
    else if(next_state == S4) begin
	    mismatch <= 1'b0;
    end
    else begin
	    mismatch <= 1'b1;
    end
end

//assign mismatch = (curr_state ==S4) ? 1'b0 : 1'b1;	//组合逻辑描述输出

endmodule

3.13Testbench

`timescale 1ns/1ps		//仿真时间单位1ns 仿真时间精度1ps
module sequence_detect03_tb();

//信号申明
reg		clk;
reg		rst_n;
reg		seq_in;
wire	mismatch;

//复位信号生成
//输入信号生成,输入信号为“1001001001001”
//时钟信号与复位信号赋初值
initial begin 
    clk = 0;
    rst_n = 1;
    #5  rst_n = 0;
    #10 rst_n = 1;
    seq_in = 1;#10;
    seq_in = 0;#10;
    seq_in = 0;#10;
    seq_in = 1;#10;
    seq_in = 0;#10;
    seq_in = 0;#10;
    seq_in = 1;#10;
    seq_in = 0;#10;
    seq_in = 0;#10;
    seq_in = 1;#10;
    seq_in = 0;#10;
    seq_in = 0;#10;
    seq_in = 1;#10;
end 

//时钟信号生成
always #5 clk = ~clk;

//模块实例化(将申明的信号连接起来即可)
sequence_detect03 u_sequence_detect03(
    .clk			(clk),
    .rst_n			(rst_n),
    .seq_in			(seq_in),
    .mismatch		(mismatch)
    );

endmodule

3.14仿真结果

image

输入序列1001001001001,根据可重复检测理论上可检测四次信号翻转,从仿真结果可以看到mismatch发生四次翻转,且第二次翻转的1001中的第一个1来自第一组1001中最后一个1,即发生重叠亦可检测。

3.2非重叠检测

3.21 非重叠检测方法

题目:设计一个序列检测器,用来检测序列 1001,用状态机完成电路,可重复检测序列1001

第一步,分析状态机状态转移,分析如下:

IDLE: 初始状态,代表目前没有接收到满足要求的数据。
seq_in = 1时,等于1001中的第一个数,进入S1状态;

seq_in = 0时,保持状态。

S1:代表目前已经有了1个匹配的数据。

seq_in = 0时,当前序列为10,等于1001中的前两个数,进入S2状态;

seq_in = 1时,当前序列为11,不是1001的前两个数,但1是1001的第一个数,所以保持S1状态。

S2:代表目前已经有了2个匹配的数据。
seq_in = 0时,当前序列为100,等于1001中的前三个数,进入S3状态;

seq_in = 1时,当前序列为101,不是1001的前三个数,但1是1001的第一个数,所以进入S1状态。

S3:代表目前已经有了3个匹配的数据。
seq_in = 1时,当前序列为1001,与要求序列匹配,进入S4状态;

seq_in = 0时,当前序列为1000,与要求序列不配,0与初始状态匹配,所以进入IDLE状态。

S4:最终状态,代表目前已经得到了匹配的序列,输出信号翻转。
seq_in = 1时,当前序列为10011,1与要求序列的第一个数匹配,所以进入S1状态;

seq_in = 0时,当前序列为10010,10与要求的前两个数匹配,但是要求非重叠检测,所以进入IDLE状态。

第二步:根据流程转换分析画出状态机的状态转移图,如下图所示

image

第三步:根据状态机转移图用经典三段式(或者二段式)写出verilog代码

3.22verilog代码

//使用状态机设计检测“10
首页 上一页 1 2 3 4 下一页 尾页 3/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇Xilinx GTH 简介 ,CoaXpress FPG.. 下一篇FPGA 开发详细流程你了解吗?

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目