当前位置:   article > 正文

序列模三检测器(状态机法设计原理|verilog代码|Testbench|仿真结果)_verilog如何设计一个对3取模的电路

verilog如何设计一个对3取模的电路



数字IC经典电路设计
经典电路设计是数字IC设计里基础中的基础,盖大房子的第一部是打造结实可靠的地基,每一篇笔者都会分门别类给出设计原理、设计方法、verilog代码、Testbench、仿真波形。然而实际的数字IC设计过程中考虑的问题远多于此,通过本系列希望大家对数字IC中一些经典电路的设计有初步入门了解。能力有限,纰漏难免,欢迎大家交流指正。

快速导航链接如下:

个人主页链接
1.数字分频器设计
2.序列检测器设计
3.序列发生器设计
4.序列模三检测器设计
5.奇偶校验器设计
6.自然二进制数与格雷码转换



一、前言

序列模三检测器是一种用于检测输入序列中是否存在模三等于零的子序列的数字电路。它通常由三个状态构成,分别对应于输入序列模三余数为0、1和2的情况。当输入序列中存在模三余数为0的子序列时,检测器会输出一个逻辑“1”信号;否则,输出逻辑“0”信号。这种检测器可以应用于数字通信、计算机网络等领域,用于实现数据传输和错误检测等功能。

例如,序列模三检测器在数字信号处理和通信系统中,用于检测和纠正传输中的错误。在数字通信中,发送方可以使用序列模三检测器来计算传输数据的模三余数,并将其附加到数据中。接收方可以使用相同的序列模三检测器来检测传输中是否出现错误,并纠正数据。

在数字IC中,序列模三检测器还可以作为基础模块,与其他数字电路组合使用,实现包括序列分析、数据去噪、加密解密等复杂功能。另外,在数字IC设计中,还需要考虑电路面积、功耗、工作温度等因素,并进行针对性优化,以满足不同应用场景下的需求。

二、模三检测器

2.1 模三检测器

题目:设计一个序列模三检测器,当序列可以被3整除,则立即输出1,否则输出0。

  1. 对于模三检测器有三种余数分别是0、1、2。当序列每次新增1bit数据时,其实相当于逻辑左移运算,就是在原来的数据上×2,再根据新增的1bit数据与之相加确定下一个状态的余数。例如,即100到1001的过程(即十进制数4到9的过程):当前数据模三余数为1,在数据右端新增1bit数据1,最后会发现下一状态的余数变为0!

下面分类讨论:

  1. 余数为0的情况:
    输入为0,则有0×2+0,次数余数为0,被整除输出为1;
    输入为1,则有0×2+1,此时余数为1,不被整除输出为0;
  2. 余数为1的情况:
    输入为0,则有1×2+0,此时余数为2,不被整除输出为0;
    输入为1,则有1×2+1,此时余数为0,被整除输出为1;
  3. 余数为2的情况:
    输入为0,则有2×2+0,此时余数为1,不被整除输出为0;
    输入为1,则有2×2+1,此时余数为2,不被整除输出为0;
当前状态余数输入下一状态余数输出
0001
0110
1020
1101
2010
2120
  1. 此题可以借用万能的状态机进行设计,但是必须首先得弄清楚其中的状态转移。
    那么凭借什么编译状态机的状态呢?答案是余数! 通过上面的分析可以发现,余数的三种情况可以作为状态机的三种状态,当前的状态以及输出只跟之前的状态和当前的输入有关,因此可以使用Mearly型状态机描述。

S1:此状态代表余数为1;
S2:此状态代表余数为2;
S3:此状态代表余数为0;

在这里插入图片描述

  1. 根据状态转移图写出对应的verilog代码

2.2 verilog代码

//使用状态机设计模三序列检测器
module sequence_modulus3_detector(
    input		clk,
    input		rst_n,
    input		seq_in,	//输入新增的1bit数据
    output reg	mod3	//是否可以被3整除,是输出1,否输出0
    );

//采用独热码编译四个状态,初始IDLE状态为待机状态
//独热码相比二进制码和格雷码,方便电路设计判断、状态转移,且逻辑更简单 
parameter	IDLE = 4'b0001;
parameter	S1 = 4'b0010;
parameter	S2 = 4'b0100;
parameter	S3 = 4'b1000;

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

//第一段使用时序逻辑描述状态转移
always@(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
	    curr_state <= 4'b0;
    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:S3;
	        S1    :next_state = seq_in?S3:S2;
	        S2    :next_state = seq_in?S2:S1;
			S3    :next_state = seq_in?S1:S3;
	        default:next_state = IDLE;	//养成良好代码风格,不能遗漏,防生成latch,也可以通过赋初值避免	
        endcase
    end
end

//第三段使用时序逻辑描述状态输出
always@(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
	    mod3 <= 1'b0;
    end
    else if(next_state == S3) begin
	    mod3 <= 1'b1;
    end
    else begin
	    mod3 <= 1'b0;
    end
end

endmodule


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

2.3 Testbench

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

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

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

//生成复位信号
//为时钟信号和复位信号赋初值
initial begin
    clk 	   = 1;
    rst_n      = 1;
    #5  rst_n <= 0;
    #5  rst_n <= 1;
    repeat(20) begin
	    #8 seq_in = $random%2;	//生成随机数
    end
end

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

endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

2.4 仿真结果

在这里插入图片描述

仿真结果如上图所示,分析标记的几组数据:
输入序列1,十进制为1,无法被3整除,输出mod3等于0;
输入序列11,十进制为3,可被3整除,输出mod3等于1;
输入序列111,十进制为7,无法被3整除,输出mod3等于0;
输入序列1111,十进制为15,无法被3整除,输出mod3等于1;
输入序列11111,十进制为31,无法被3整除,输出mod3等于0;
输入序列111110,十进制为62,无法被3整除,输出mod3等于0;

三、总结

模三检测器主要设计思路是围绕状态机进行设计,弄清楚状态机的状态转移并且画出状态转移图有利于加深对模三检测器的理解。除此,理解余数在模三检测器中的作用是十分必要的。首先,它作为判断输出是否为“1”的依据;其次,它也是连接状态机的枢纽,状态机的状态是根据当前余数的值进行编译的。



不定期检查、补充、纠错,欢迎随时交流纠错
最后修改日期:2023.4.29

软件版本:

仿真软件:Modelsim 10.6c
绘图软件:亿图图示
描述语言:verilog

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/945088
推荐阅读
相关标签
  

闽ICP备14008679号