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

文章目录

  • 前言
  • 一、序列检测器
    • 1.1 重复序列检测
      • 1.1.1 序列缓存对比/移位寄存器法
      • 1.1.2 状态机法
    • 1.2 非重复序列检测
  • 二、序列发生器
    • 2.1 移位寄存器法
    • 2.2 反馈法
    • 2.3 计数器法


前言

2023.4.25
2023.4.26 学习打卡,天气转晴


一、序列检测器

1.1 重复序列检测

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

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

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

在这里插入图片描述

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,用移位寄存器实现
在这里插入图片描述

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相当于和序列同时输出,只要满足就输出了)

在这里插入图片描述

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”从左至右的不重叠检测。

在这里插入图片描述

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。

在这里插入图片描述

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

二、序列发生器

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输出的数据就是我们想要的序列。

Q2Q1Q0F
0010
0101
1011
0110
1100
1001

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

在这里插入图片描述

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

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

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

在这里插入图片描述

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的最简表达式。

Q2Q1Q0Z
0000
0010
0101
0111
1001
1010
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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/15274.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

等级保护、风险评估和安全测评分别是什么?

2022-06-17 15:17 迈入“等保2.0时代”以后&#xff0c;我国对于等级保护的要求更为严格和具体。等级保护、风险评估和安全测评这三个词&#xff0c;也因此总是出现在人们的视野之中&#xff0c;还总是被混淆。那这三者究竟分别是什么呢&#xff1f;如何区分它们&#xff1f;它…

【Bus】编写一个Demo虚拟的总线-设备-驱动模型

文章目录 1. 前言2. 总线驱动模型三要素2.1 总线2.2 设备2.3 驱动 3. Demo Code3.1 virt_bus_core.c3.2 virt_device.c3.3 virt_driver.c 4. 工程代码下载地址5. 参考资料 1. 前言 Linux平台为了驱动的可重用性&#xff0c;虚拟了很多的虚拟总线。很经典的就是platform总线&am…

如何编写高质量代码、提高编程效率?

一、 前言 高质量代码是指在满足功能需求的基础上&#xff0c;具备高性能、安全、可扩展、易维护、可测试等特点的代码。它不仅可以提高开发效率和代码质量&#xff0c;更能有效减少代码维护成本&#xff0c;促进团队协作和项目成功。因此&#xff0c;编写高质量代码对程序员来…

【Java】什么是SOA架构?与微服务有什么关系?

文章目录 服务化架构微服务架构 我的一个微服务项目&#xff0c;有兴趣可以一起做 服务化架构 我们知道&#xff0c;早期的项目&#xff0c;我们都是把前后端的代码放在同一个项目中&#xff0c;然后直接打包运行这个项目&#xff0c;这种项目我们称之为单体项目&#xff0c;比…

【Vue】Vue-cli,创建项目设置自定义默认配置

Vue2.0&#xff0c;Vue-cli项目配置 步骤一&#xff0c;打开文件夹&#xff0c;导航栏输入cmd&#xff0c;打开命令行窗口步骤二&#xff0c;输入命令步骤三&#xff0c;选择第三个自定义新建项目步骤四&#xff0c;选择需要的项目模块&#xff0c;空格选择完&#xff0c;回车步…

密码学|AES加密算法|学习记录

AES简介 AES加密是分组加密的一种 明文长度为固定的128位 密钥可长度为128&#xff0c;192&#xff0c;256位 128bit16字节&#xff0c;在AES中我们将数据用4x4字节的矩阵表示。&#xff08;注排列顺序为先从上到下再从左到右&#xff09; AES的一般步骤 对于上图最终轮区…

CASAIM高精度自动化三维扫描系统检测塑料件,自动检测形位公差

随着塑料工业的迅速发展&#xff0c;以及塑料制品在航空、航天、电子、机械、船舶和汽车等工业部门的推广应用&#xff0c;对塑料件的质量要求也越来越高。 为了检测塑料件的尺寸偏差以及测量关键部位的3D尺寸和形位公差&#xff0c;对影响总成零件精度的产品、工装、工艺进行精…

第十章_Redis集群(cluster)

是什么 定义 由于数据量过大&#xff0c;单个Master复制集难以承担&#xff0c;因此需要对多个复制集进行集群&#xff0c;形成水平扩展每个复制集只负责存储整个数据集的一部分&#xff0c;这就是Redis的集群&#xff0c;其作用是提供在多个Redis节点间共享数据的程序集。 官…

yield用法理解,配有代码块和解析

包含 yield 关键字的函数&#xff0c;是一个生成器 yield和return的区别 1、return是返回return关键字的值&#xff0c;被调用一次就返回一次&#xff0c;return只能放在一个函数代码块的最后面&#xff0c;运行到return的时候&#xff0c;就结束循环&#xff0c;结束这个函数…

用户画像系列——HBase 在画像标签过期策略中的应用

一、背景 前面系列文章介绍了用户画像的概念、用户画像的标签加工、用户画像的应用。本篇文章主要介绍一些画像的技术细节&#xff0c;让大家更加详细的了解画像数据存储和处理的逻辑 举个现实中的例子&#xff1a; 例子1&#xff1a;因为疫情原因&#xff0c;上线一个平台(…

没有U盘电脑如何使用本地硬盘安装Ubuntu20.04(双系统)

环境: DELL7080台式机 Ubuntu20.04 两块硬盘 问题描述: 没有U盘电脑如何使用本地硬盘安装Ubuntu20.04(双系统) 解决方案: 一、下载镜像文件 1.上线自行下载安装镜像文件 二、分区 1.win10下磁盘管理压缩2个分区一个10G左右制作安装盘,一个几百G安装系统使用 10…

辞了外包,上岸字节我落泪了,400多个日夜没人知道我付出了多少....

前言&#xff1a; 没有绝对的天才&#xff0c;只有持续不断的付出。对于我们每一个平凡人来说&#xff0c;改变命运只能依靠努力幸运&#xff0c;但如果你不够幸运&#xff0c;那就只能拉高努力的占比。 2023年3月&#xff0c;我有幸成为了字节跳动的一名自动化测试工程师&am…

Node.js的简介

一、什么是node.js Node.js是JavaScript语言的服务器运行环境。 Node.js 就是运行在服务端的 JavaScript。 Node.js 是一个基于Chrome JavaScript 运行时建立的一个平台。 Node.js是一个事件驱动I/O服务端JavaScript环境&#xff0c;基于Google的V8引擎&#xff0c;V8引擎执行…

基于 SpringBoot+Vue+Java 的留守儿童系统的研究与实现(附源码,教程)

文章目录 1.研究背景2. 技术栈3.系统分析4系统设计5系统的详细设计与实现5.1系统功能模块5.2管理员功能模块 1.研究背景 以往的留守儿童爱心的管理&#xff0c;一般都是纸质文件来管理留守儿童爱心信息&#xff0c;传统的管理方式已经无法满足现代人们的需求&#xff1b;使用留…

PCL学习二:PCL基础应用教程

参考引用 PCL Basic UsagePCL 点云库官网教程 1. pcl_viewer 基本使用 1.1 pcl_viewer 安装测试 pcl_data 源码克隆$ git clone https://github.com/PointCloudLibrary/data.git进入 /pcl_data/tutorials&#xff08;如下图&#xff09;$ cd ~/pcl_data/tutorials # 此处为重…

Chapter 4 :Constraining I/O Delay(ug903)

4.1 About Constraining I/O Delay 要在设计中准确地建模外部时序上下文&#xff0c;必须为输入和输出端口提供时序信息。由于XilinxVivado集成设计环境&#xff08;IDE&#xff09;只能识别FPGA边界内的时序&#xff0c;因此必须使用以下命令来指定超出这些边界的延迟…

200人 500人 园区网设计

实验要求&#xff1a; ① 设置合理的STP优先级、边缘端口、Eth-trunk ② 企业内网划分多个vlan &#xff0c;减少广播域大小&#xff0c;提高网络稳定性 ③ 所有设备&#xff0c;在任何位置都可以telnet远程管理 ④ 出口配置NAT ⑤ 所有用户均为自动获取ip地址 ⑥ 在企业…

Matlab高光谱遥感、数据处理与混合像元分解及典型案例

站在学员的角度去理解“高光谱”&#xff0c;用大家能听的懂的语言去讲述高光谱的基本概念和理论&#xff0c;帮助学员深入理解这项技术的底层科学机理。方法篇&#xff0c;将高光谱技术与MATLAB工具结合起来&#xff0c;采用MATLAB丰富的工具箱&#xff0c;快速复现高光谱数据…

Java 重写(Override)与重载(Overload)

重写(Override) 重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变&#xff0c;核心重写&#xff01; 重写的好处在于子类可以根据需要&#xff0c;定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。 重写方法不…

【MySQL自学之路】第4天——模式、表、视图、索引(数据定义详细版)

目录 前言 数据库 数据库的建立 数据库的使用 数据库的查看 数据库的删除 模式 查看所有的模式 模式和数据库之间的关系 ​编辑建立模式 删除模式 表 数据类型 查看一个数据库下面的所有表(必须进入要查看的数据库) 创建基本表 查看表结构&#xff08;查看表建…