verilog手撕代码3——序列检测和序列发生器

这篇具有很好参考价值的文章主要介绍了verilog手撕代码3——序列检测和序列发生器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

2023.4.25
2023.4.26 学习打卡,天气转晴


一、序列检测器

1.1 重复序列检测

1.1.1 序列缓存对比/移位寄存器法

把输入的数据缓存到数组,然后与目标进行对比

例1:检测序列0111_0001,满足序列输出为1

verilog手撕代码3——序列检测和序列发生器

module sequence_detect(
	input clk,
	input rst_n,
	input a,
	output reg match
	);

	reg [7:0] a_tem;
	
	always @(posedge clk or negedge rst_n)
		if (!rst_n) 
			match <= 1'b0;
		else    //检测到目标序列的下一个周期输出高电平
			match <= (a_tem == 8'b0111_0001) ? 1'b1 : 1'b0;   
		
	always @(posedge clk or negedge rst_n)
		if (!rst_n)
			a_tem <= 8'b0;
		else 
			a_tem <= {a_tem[6:0],a};
endmodule

例2:检测序列1101,用移位寄存器实现
verilog手撕代码3——序列检测和序列发生器

module detect_1101(
	input clk,
	input rst_n,
	input a,
	output data_out
);
	reg [3:0] a_r;
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			a_r <= 4'b0;
		else
			a_r <= {a_r[2:0], a};
	end
	
	assign data_out = a_r[3] & a_r[2] & ~a_r[1] & a_r[0];
endmodule

例3含有无关项的序列检测
检测序列001_xxx_110,中间三位不关心,这种题目的话也可以是缓存序列对比

match <= (a_r[8:6]==3'b001 && a_r[2:0]==3'b110) ? 1 : 0;

例4:输入数据使能有效,不是所有输入数据都有效,检测0110序列
data_valid=1的时候缓存数据,同理再进行比较(注意输出match为高电平的周期是什么时候,这里的match相当于和序列同时输出,只要满足就输出了)

verilog手撕代码3——序列检测和序列发生器

module sequence_detect(
	input clk,
	input rst_n,
	input data,
	input data_valid,
	output reg match
	);

	reg [3:0] data_r;

	always @(posedge clk or negedge rst_n)begin
		if (!rst_n)
			data_r <= 4'b0;
		else 
			data_r <= data_valid ? {data_r[2:0], data} : data_r;	
	end
	
	always @(posedge clk or negedge rst_n)begin
		if (!rst_n) 
			match <= 1'b0;
		else    
			match <=  ({data_r[2:0], data}==4'b0110) ? 1 : 0;
	end
endmodule

1.1.2 状态机法

一般是三段式状态机

  • Moore型:输出信号只取决于当前状态;
  • Mealy型:输出信号不仅取决于当前状态,还取决于输入;
  • 实现相同的功能时,Mealy型比Moore型能节省一个状态(大部分情况下能够节省一个触发器资源),Mealy型比Moore型输出超前一个时钟周期。

例1:用Moore型状态机实现序列“1101”从左至右的不重叠检测。

verilog手撕代码3——序列检测和序列发生器

module det_moore(
   input                clk   ,
   input                rst_n ,
   input                din   ,
 
   output	reg         Y   
);
    parameter idle=0,s0=1,s1=2,s2=3,s3=4;
    reg [2:0] state,nx;
    
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)
            state<=idle;
        else
            state<=nx;
    end
    
    always@(*)begin
        case(state)
            idle: nx=din?s0:idle;
            s0: nx=din?s1:idle;
            s1: nx=din?s1:s2;
            s2: nx=din?s3:idle;
            s3: nx=din?s0:idle;
            default: nx=idle;
        endcase
    end
    
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)
            Y <= 0;
        else 
            Y <= (state==s3) ? 1 : 0;
    end
endmodule

1.2 非重复序列检测

例1:检测输入信号(a)是否满足011100序列, 要求以每六个输入为一组,不检测重复序列,例如第一位数据不符合,则不考虑后五位。一直到第七位数据即下一组信号的第一位开始检测。当信号满足该序列,给出指示信号match。当不满足时给出指示信号not_match。(每六个数为一组进行检查)

分析:和移位寄存器有所不同,这种是缓存六个数据比较后,要清空所有的数据,然后再次缓存新的六个数据比较,所以需要用到计数器

match和not_match仅在cnt==5时才进行更新,且nm状态在cnt == 5以及data==0的时候才会跳转到新的有效状态,否则一直都会是nm。

verilog手撕代码3——序列检测和序列发生器

module sequence_detect(
	input clk,
	input rst_n,
	input data,
	output reg match,
	output reg not_match
	);

	reg [2:0] state,nx;
	reg [2:0] cnt;
	parameter s0=0,s1=1,s2=2,s3=3,s4=4,s5=5,s6=6,nm=7;

	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)begin
			cnt<=0;
		end
		else if(cnt==5)
			cnt<=0;
		else
			cnt<=cnt+1;
	end


	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)begin
			state<=0;
		end
		else 
			state<=nx;
	end

	always@(*)begin
		case(state)
			s0:nx<=data?nm:s1;
			s1:nx<=data?s2:nm;
			s2:nx<=data?s3:nm;
			s3:nx<=data?s4:nm;
			s4:nx<=data?nm:s5;
			s5:nx<=data?nm:s6;
			s6:nx<=data?s0:nm;
			nm:nx<=(cnt==5 && data==0)?s1:nm;  //只有同时满足两个条件才会跳转,否则一直是nm
			default:nx<=s0;
		endcase
	end

	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)begin
			match<=0;
			not_match<=0;
		end
		else if(cnt==5)begin
			if(nx==s6)begin
				match<=1;
				not_match<=0;
			end
			else begin
				match<=0;
				not_match<=1;
			end
		end
		else begin
			match<=0;
			not_match<=0;
		end
	end
endmodule

1.3 两种序列检测方法优缺点比较

状态机法优点:

  • 逻辑清晰,写起来方便,检测模式灵活,可以应对不同的输入情况

状态机法缺点:

  • 设计复杂,不易扩展,需要重新设计状态转移图和代码来检测不同的序列,状态数量和转移条件可能较多

寄存器法优点:

  • 设计简单,易于扩展,只需要修改寄存器的长度和比较的序列即可检测不同的序列,状态数量和转移条件较少

寄存器法缺点:

  • 逻辑较为固定,检测模式较为单一,只能检测连续的序列,不能应对重复或间隔的序列

二、序列发生器

2.1 移位寄存器法

例1:循环输出序列001011

module sequence_generator(
	input clk,
	input rst_n,
	output reg data
	);
    
    reg [5:0] q;
    
    always@(posedge clk or negedge rst_n)
        if (!rst_n)
            q <= 6'b001011;
        else
            q <= {q[4:0],q[5]};  //序列左移
    
    always@(posedge clk or negedge rst_n)
        if (!rst_n)
            data <= 1'd0;
        else 
            data <= q[5];
endmodule

2.2 反馈法

移位寄存器组合逻辑生成,也是寄存器的某一位输出端输出循环序列,但是使用到的寄存器数目减少了。

  • 根据给定序列信号的循环周期M,确定移位寄存器位数n,2^ (n-1) < M ≤ 2^n。如果发现序列中有状态重复的话,就把n加一。
  • 根据M个不同的状态列出移位寄存器的态序表和反馈函数表,求出反馈函数F的表达式。
  • 各个寄存器的输出需要经过反馈网络,然后才连接到移位寄存器的输入端
  • 检查自启动:电路能从无效状态进入有效状态

序列001011:至少需要3位,列出状态,001-010-101-011-110-100,可以看到寄存器高位Q2输出的数据就是我们想要的序列。

Q2 Q1 Q0 F
0 0 1 0
0 1 0 1
1 0 1 1
0 1 1 0
1 1 0 0
1 0 0 1

根据上面的反馈函数表,画出卡诺图,可以写出F的表达式如下。然后把这些组合逻辑接到Q0的输入端即可。

verilog手撕代码3——序列检测和序列发生器

F = Q2 & ~Q1 | ~Q2 & Q1 & ~Q0;

可以看到,上面000和111的状态是无关项,可以把其设置为1和0,这样F的表达式可以进一步化简。同时画出状态转移图,是可以自启动的。

F = Q2 & ~Q1 | ~Q2 & ~Q0;

verilog手撕代码3——序列检测和序列发生器

module generate_001110(
	input clk, 
	input rst_n,
	input [2:0] D,
	output q
	);
	
	reg [2:0] q_r;
	wire Din;
	
	always@(posedge clk or negedge rst_n)begin
		if(!rst_n)
			q_r <= D;
		else
			q_r <= {q_r[1:0], Din};
	end
	
	assign q = q_r[2];
	assign Din = q_r[2] & ~q_r[1] | ~q_r[2] & ~q_r[0];
endmodule	

2.3 计数器法

产生序列:001110,计数器范围为0-5,分别对应输出序列各个值。
由卡诺图化简可以得到Z的最简表达式。文章来源地址https://www.toymoban.com/news/detail-449758.html

Q2 Q1 Q0 Z
0 0 0 0
0 0 1 0
0 1 0 1
0 1 1 1
1 0 0 1
1 0 1 0
module seq_gen_count(
    input clk,
    input rst_n,
    output seq
    );

	reg [2:0]count;
	always@(posedge clk or negedge rst_n)begin
	    if(!rst_n)
	        count <= 0;
	    else
	        count <= (count == 5) ? 0 : count + 1;
	end

	assign seq = (!count[2] & count[1]) | (count[2] & !count[1] & !count[0]);
endmodule

到了这里,关于verilog手撕代码3——序列检测和序列发生器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【FPGA/verilog -入门学习10】verilog 查表法实现正弦波形发生器

    用查找表设计实现一个正弦波形发生器 寻址的位宽是10位,数据量是1024个,输出的数据是16位 数据量是1024个: x = linspace(0,2*pi,1024) 输出数据是16位: y范围:0~2^16 -1 = 0~65535 y =( sin(x)+1)*65535/2 寻址的位宽是10位 输入是0~1023 1023 占用10位 操作步骤 1,使用matlab 生成数据,制作

    2024年02月05日
    浏览(66)
  • 多路波形发生器的控制

            本次波形发生器,主要使用运算放大器、NE555以及一些其他的电阻电容器件来实现。整体电路图如下所示: 产生的三角波如下: 正弦波如下 方波如下: 运算放大器(Operational Amplifier,简称OP-AMP)是一种重要的电子放大器,常用于模拟电路和信号处理电路中。它是

    2024年02月09日
    浏览(40)
  • proteus——555 PWM 发生器

    什么是 PWM 信号? 脉宽调制(PWM)是一种数字信号,最常用于控制电路。该信号在预定义的时间和速度内设置为高(5v)和低(0v)。信号保持高电平的时间称为\\\"导通时间\\\",信号保持低电平的时间称为\\\"关断时间\\\"。PWM 有两个重要参数,如下所述: PWM 的占空比: PWM信号保持高

    2024年02月07日
    浏览(35)
  • 单片机课程设计波形发生器

    怎么说呢,前面半个月被这个单片机课程设计搞得焦头烂额的,再加上运气属实有点“好”,就脾气有点“暴躁”,好的,也就骂了半天的脏话。有一说一,没有素质确实舒服。 好了,事情目前是过去了,那就好好回顾一下遇到的问题,以及找到了怎样的解决方案,和最后仍

    2024年02月09日
    浏览(48)
  • 基于uA741 PWM发生器

    一、实验要求 二、设计任务与要求 三、设计实验报告要求 一、实验要求 查阅资料,确定方案 用 Multisim 进行验证,并 打印电路、输出波形、元器件参数表 电路基于 uA741 集成运算放大器构成 要求电路 震荡频率为300Hz , 输出电压峰峰值为14v 二、设计任务与要求 设计一个占

    2024年02月11日
    浏览(44)
  • 单片机实验——简易波形发生器设计

    波形发生器广泛地应用于电子和通信等领域,是应用最广泛的电子仪器之一,本设计用51单片机以及DAC0832实现基本波形的输出,参考电路如下: 可以产生方波、三角波、正弦波、锯齿波等波形,用仿真的示波器查看。 用4个按键分别控制输出相应波形。 利用C51设计程序完成以

    2024年02月12日
    浏览(47)
  • 定长指令周期---时序发生器FSM设计

    定长指令周期—时序发生器FSM设计 实验目的 帮助学生理解传统三级时序系统中时序发生器的基本原理,学生能设计定长指令周期的时序发生器状态机以及输出函数。 实验内容 利用数字逻辑电路相关知识设计定长指令周期的三级时序系统,时序发生器包括状态机和输出函数两

    2024年02月12日
    浏览(40)
  • Multisim14.0仿真(五)三角波发生器

    一、仿真原理图: 二、仿真效果:

    2024年02月10日
    浏览(38)
  • 波形发生器设计(频率、占空比、幅值可调)

    1.电路原理图: 2.原理: 采用了文氏电桥的方法,通过自激振荡的方式出波。 其中R 6 ,C 1 ,R 2 ,C 2 构成正反馈支路,令R 1 =R 2 =R,C 1 =C 2 =C,可以计算出正弦波的振荡频率f=1/2πRC。将文氏电路的电容值固定,电阻替换为可调电位器,这样我们就可以控制产生的正弦波的频率。注意

    2024年02月09日
    浏览(43)
  • 13 STM32-随机数发生器 (RNG)

    RNG 处理器是一个以连续模拟噪声为基础的随机数发生器,在主机读数时提供一个 32 位的随机数. RNG 提供由模拟量发生器产生的 32 位随机数,两个连续随机数的间隔为 40 个 PLL48CLK 时钟信号周期 随机数发生器采用模拟电路实现。模拟电路会源源不断的产生随机数的种子,并放入

    2024年01月23日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包