【IC设计】移位寄存器

news2024/9/28 7:26:52

目录

    • 理论讲解
      • 背景介绍
      • 什么是移位寄存器
      • 按工作模式分类
      • verilog语法注意事项
    • 设计实例
      • 循环移位寄存器
      • 算术双向移位寄存器
      • 5位线性反馈移位寄存器
      • 伪随机码发生器
      • 3位线性反馈移位寄存器
      • 32位线性反馈移位寄存器
      • 串行移位寄存器(打4拍)
      • 双向移位寄存器:二选一+移位寄存器
      • 3 输入查找表 (LUT)
    • 参考链接

在这里插入图片描述

图片来源:寒武纪魔道电子【移位寄存器是如何工作的,为什么它能把串行信号转成并行】

理论讲解

背景介绍

 早期的硬盘为IDE并行接口,如今的电子设备多以串行接口接收信号,如温度传感器DS18B20为串行总线、采用串行接口AD采样芯片会极大节省CPU的I/O口。那具体的串行数据是如何被读入CPU内部呢?
答案就是通过移位寄存器实现!
在这里插入图片描述

什么是移位寄存器

 移位寄存器是一种时序逻辑电路,能够存储和传输数据。它们由触发器组成,这些触发器的连接方式使得一个触发器的输出可以作为另一个触发器的输入,具体取决于所创建的移位寄存器的类型。移位寄存器基本上是一种能够传输(“移位”)数据的寄存器。寄存器通常是存储设备,它们是通过将特定数量的触发器串联在一起而创建的,并且寄存器可以存储的数据量(位数)始终与触发器的数量成正比,因为每个触发器一次只能存储一个bit。当寄存器中的触发器以这样的方式连接时,一个触发器的输出成为另一个触发器的输入,就会创建一个移位寄存器。
 触发器是具有类似于闩锁操作的设备,被称为双稳态电路,有两个稳定的状态,即0或1,并且能够以bit为单位存储数据。每当D触发器的时钟发生变化时(上升沿或下降沿,取决于触发器的规格)。输出“Q”处的数据与输入“D”处的数据相同。触发器的输出“Q”将保持在该值,直到下一个时钟周期,然后它将再次更改为输入处的值(1或0)。
有关触发器的具体介绍请进入传送门: 【IC设计】时序逻辑的基础—锁存器、触发器

按工作模式分类

 移位寄存器主要根据其工作模式(串行或并行)分为几类。下面列出了几种基本移位寄存器,尽管其中一些可以根据数据流的方向进一步划分,右移或者左移。
传送门:[PDF]移位寄存器及其应用 - 中国科学技术大学

  1. 串口输入—串口移位寄存器 (SISO)
  2. 串行输入—并行输出移位寄存器 (SIPO)
  3. 并联输入—并联输出移位寄存器 (PIPO)
  4. 并联输入—串行移位寄存器 (PISO)
  5. 双向移位寄存器
    在这里插入图片描述

verilog语法注意事项

如果在赋值语句中需要左右移位,尽量不要用语法中提供的左移“<<”和右移“>>”符号

因为不同的综合工具对他们的处理方式不同,导致逻辑综合的结果不可控,即使代码通过了功能仿真和FPGA验证,也有可能在ASIC实现时出问题。最稳妥的移位方法要把每位的移动具体写出来.
例如,向右循环移位可写为(a[6:0]<=a[7:1];a[7]<=a[0]),由于这种写法落实到具体的位,所以逻辑综合的结果将不依赖于EDA工具,这样命运就会掌握在自己的手里,不用去关心EDA工具如何处理左右移位。

------ 引用自《CMOS模拟集成电路全流程设计》 李金城 机械工业出版社

设计实例

循环移位寄存器

构建一个100位的左右旋转器,同步load,左右旋转需使能。旋转器从另一端输入移位的位元,不像移位器那样丢弃移位的位元而以零位移位。如果启用,旋转器就会旋转这些位,而不会修改或丢弃它们。

load:加载100位的移位寄存器数据
ena[1:0]:2’b01 右转1bit; 2’b10 左转1bit;其他情况不转
q:旋转器内容

  • 代码实现
module top_module(
    input clk,
    input load,
    input [1:0] ena,
    input [99:0] data,
    output reg [99:0] q); 

    always@(posedge clk)begin
        if(load == 1'b1)begin
            q <= data;
        end else begin
/*            if(ena == 2'b01)begin
                q <= {q[0], q[99:1]};
        	end 
            if(ena == 2'b10)begin
                q <= {q[98:0], q[99]};
            end
            if(ena == 2'b00 && ena == 2'b11)begin
                q <= q;                
            end
        end
 */
            case(ena)
            2'b01:   q <= {q[0], q[99:1]};
            2'b10:	 q <= {q[98:0], q[99]}; 
            default: q <= q;   
            endcase
        end
    end
endmodule

算术双向移位寄存器

  • 4位双向移位寄存器真值表
    在这里插入图片描述

  • 建立一个64位算术移位寄存器,同步加载。移位器可以左右移位,并按数量选择1位或8位的移位。

1、算术右移将移位移位寄存器中数字(在本例中为q[63])的符号位,而不是逻辑右移所做的零。
2、另一种考虑算术右移的方法是它假设被移的数是有符号的并保留符号,所以算术右移可以将一个有符号的数除以2的幂。

load:加载数据
ena:决定是否移位
amount:决定移位方向与数量:2’b00:左移1位;2’b01:左移8位;2’b10:右移1位;2’b11:右移8位
q:寄存器内容(输出)

  • 代码实现
module top_module(
    input clk,
    input load,
    input ena,
    input [1:0] amount,
    input [63:0] data,
    output reg [63:0] q); 

    always@(posedge clk)begin
        if(load == 1'b1)begin
            q <= data;
        end else begin
            if(ena == 1'b1)begin
            	case(amount)
            	2'b00: //shift left by 1 bit
                    q <= {q[62:0], 1'b0};
				2'b01: //shift left by 8 bits
                    q <= {q[55:0], 8'b0};
				2'b10: //shift right by 1 bit
                	q <= {q[63], q[63:1]};                
				2'b11: //shift right by 8 bits
                	q <= {{8{q[63]}}, q[63:8]};                   
            	//default:    
            	endcase
        	end else begin
            	q <= q;
        	end
        end
    end
endmodule
  • 验证结果
    在这里插入图片描述
    在这里插入图片描述

5位线性反馈移位寄存器

线性反馈移位寄存器(LFSR)主要包括:

  • Galois(内部LFSR),又称one-to-many
    在这里插入图片描述
  • 斐波那契(外部LFSR),又称many-to-one
    在这里插入图片描述

1、其中,gn为反馈系数,取值只能为0或1,取为0时表明不存在该反馈之路,取为1时表明存在该反馈之路;
2、这里的反馈系数决定了产生随机数的算法的不同。
3、用反馈函数表示成y = a0x^0 + a1x + a2x^2…
4、反馈函数为线性的叫线性移位反馈序列,否则叫非线性反馈移位序列。
5、Q1、Q2、Q3、Qn为LFSR的输出,M(x)是输入的码字多项式,如M(x)=x^4+ x^1+ 1,表示输入端的输入顺序为11001,同样,LFSR的结构也可以表示为多项式G(x),称为生成多项式:G(x) = gn * x^n+ …+g1 * x^1+ g0

练习:
构造线性移位寄存器,reset应当使LFSR归1。
在这里插入图片描述

  • 代码实现
module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 5'h1
    output [4:0] q
); 
    always@(posedge clk)begin
        if(reset == 1'b1)begin
            q <= 5'h1;
        end else begin
            q[4] <= q[0] ^ 1'b0;
            q[3] <= q[4];
            q[2] <= q[3] ^ q[0];
            q[1] <= q[2];
            q[0] <= q[1];
        end
    end
endmodule
  • 验证结果
    在这里插入图片描述

伪随机码发生器

在这里插入图片描述
同样,异名例化,用计数器的方法定义时钟
在这里插入图片描述

3位线性反馈移位寄存器

为这个序列电路编写Verilog代码。假设你要在DE1-SoC板上实现这个电路。将R输入连接到SW开关,将时钟连接到密钥[0],将L连接到密钥[1],将Q输出连接到红灯LEDR上。
在这里插入图片描述

注:该电路是线性反馈移位寄存器(LFSR) 的一个示例。最大周期 LFSR 可用于生成伪随机数,因为它在重复之前循环 2 n -1 个组合。全零组合不会出现在此序列中。

  • 代码实现
//方法1:RTL级描述
module top_module (
	input [2:0] SW,      // R
	input [1:0] KEY,     // L and clk
	output reg [2:0] LEDR);  // Q

    wire D0,D1,D2;
    assign D0 = KEY[1] ? SW[0] : LEDR[2];
    assign D1 = KEY[1] ? SW[1] : LEDR[0];
    assign D2 = KEY[1] ? SW[2] : (LEDR[2]^LEDR[1]);
    always@(posedge KEY[0])begin
        LEDR[0] <= D0;
        LEDR[1] <= D1;
        LEDR[2] <= D2;
    end      
endmodule
//方法2:RTL级描述,例化子模块
module top_module (
	input [2:0] SW,      // R
	input [1:0] KEY,     // L and clk
	output [2:0] LEDR);  // Q
    wire w1,w2,w3;
    assign w1 = KEY[1] ? SW[0] : LEDR[2];
    assign w2 = KEY[1] ? SW[1] : LEDR[0];
    assign w3 = KEY[1] ? SW[2] : LEDR[1]^LEDR[2];
    D_flipflop ins0(w1, KEY[0], LEDR[0]);
    D_flipflop ins1(w2, KEY[0], LEDR[1]);
    D_flipflop ins2(w3, KEY[0], LEDR[2]);
endmodule

//构建D触发器模块
module D_flipflop(input D, input clk, output Q);
    always @(posedge clk)
        begin
            Q <= D;
        end
endmodule
//二路选择器很简单,用三目运算符即可
//方法3:行为级描述,用if-else代替多路选择器
module top_module (
	input [2:0] SW,      // R
	input [1:0] KEY,     // L and clk
	output [2:0] LEDR);  // Q

    always@(posedge KEY[0]) begin
        if(KEY[1]) begin
            LEDR[0] <= SW[0]; 
            LEDR[1] <= SW[1];
            LEDR[2] <= SW[2];
        end
        else begin
            LEDR[0] <= LEDR[2]; 
            LEDR[1] <= LEDR[0];
            LEDR[2] <= LEDR[1] ^ LEDR[2]; 
        end
    end

endmodule

32位线性反馈移位寄存器

构建一个32位的Galois LFSR,其taps位置为32、22、2和1。

当移位寄存器位数较多,需要使用向量,而不是一一写出32个DFF

  • 代码实现
module top_module(
    input clk,
    input reset,    // Active-high synchronous reset to 32'h1
    output reg [31:0] q
); 

    integer i;
    always@(posedge clk)begin
        if(reset == 1'b1)begin
            q <= 32'h1;
        end else begin
            for(i=0; i<32; i=i+1)begin
                if(i==21 || i==1 || i==0)begin
                    q[i] <= q[i+1] ^ q[0];
                end else if(i==31)begin
                    q[i] <= 1'b0 ^ q[0];
                end else begin
                    q[i] <= q[i+1];//q[i] <= q[i+1];
                end
            end
        end
    end
endmodule

串行移位寄存器(打4拍)

在这里插入图片描述

  • 代码实现
module top_module (
    input clk,
    input resetn,   // synchronous reset
    input in,
    output out);
	
    reg [2:0] q;
    always@(posedge clk)begin
        if(!resetn)begin
            {q,out} <= 4'd0;
        end else begin
            {q,out} <= {in,q};
        end
    end
  
endmodule

双向移位寄存器:二选一+移位寄存器

在这里插入图片描述

  • 子模块代码设计
module MUXDFF (
    input clk,
    input w, R, E, L,
    output Q
);
    always@(posedge clk)begin
        Q <= L ? R :
             E ? w :
             	 Q ;
    end
endmodule
  • 顶层模块代码设计
module top_module (
    input [3:0] SW,
    input [3:0] KEY,
    output [3:0] LEDR
); 
  //MUXDFF u_n(.clk(KEY[0]), .w(KEY[3]/LEDR[n]), .E(KEY[1]), .R(SW[n]), .L(KEY[2]), .q(LEDR[n]));
    MUXDFF u_3(.clk(KEY[0]), .w(KEY[3] ), .E(KEY[1]), .R(SW[3]), .L(KEY[2]), .q(LEDR[3]));
    MUXDFF u_2(.clk(KEY[0]), .w(LEDR[3]), .E(KEY[1]), .R(SW[2]), .L(KEY[2]), .q(LEDR[2]));
    MUXDFF u_1(.clk(KEY[0]), .w(LEDR[2]), .E(KEY[1]), .R(SW[1]), .L(KEY[2]), .q(LEDR[1]));
    MUXDFF u_0(.clk(KEY[0]), .w(LEDR[1]), .E(KEY[1]), .R(SW[0]), .L(KEY[2]), .q(LEDR[0]));
    
endmodule

3 输入查找表 (LUT)

在这个问题中,你将为一个8x1存储器设计一个电路,在这个电路中,写入到存储器是通过移位来完成的,而读取是“随机访问”,就像在一个典型的RAM中一样。然后您将使用该电路实现一个3输入逻辑功能。

首先,用8个d类型触发器创建一个8位移位寄存器。标记为Q[0]到Q[7]。移位寄存器输入称为S,输入Q[0] (MSB先移位)。使能输入enable控制是否移位,扩展电路使其有3个额外的输入A,B,C和一个输出Z。电路的行为应该如下:当ABC为000时,Z=Q[0],当ABC为001时,Z=Q[1],以此类推。你的电路应该只包含8位移位寄存器和多路选择器。(这个电路称为3输入查找表(LUT))。

module top_module (
    input clk,
    input enable,
    input S,
    input A, B, C,
    output Z ); 
// The final circuit is a shift register attached to a 8-to-1 mux.
    reg [7:0] q;
    
// Create a 8-to-1 mux that chooses one of the bits of q based on the three-bit number {A,B,C}:
    assign Z = q[{A,B,C}];
    
// Edge-triggered always block: This is a standard shift register (named q) with enable.
// When enabled, shift to the left by 1 (discarding q[7] and and shifting in S).
    always@(posedge clk)begin
        if(enable == 1'b1)begin
            q <= {q[6:0], S};
        end else begin
            q <= q;
        end
    end
        
endmodule
  • 验证结果
    在这里插入图片描述

参考链接

  1. HDLBits第十章
  2. 《CMOS模拟集成电路全流程设计》 李金城 机械工业出版社
  3. 移位寄存器

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

设置输入法默认为英文

1、进入语言首选项 2、添加首选的语言&#xff0c;选英文 3、 选择始终默认使用的输入法 4、选择默认语言 5、输入语言热键

LeetCode刷题:面试题 02.01. 移除重复节点

题目&#xff1a; 是否独立完成&#xff1a;算是&#xff0c;但是使用自己的办法时间复杂度会超标 解题思路&#xff1a; 1.双循环嵌套&#xff0c;定义快慢节点&#xff0c;双层嵌套循环&#xff0c;如果值一样则剔除&#xff0c;但是时间复杂度为O&#xff08;n&#xff09;…

数据交互系列:认识 cookie

cookie的原理 http本身是一个无状态的请求&#xff0c;cookie最初的原始目的是为了维持状态而产生的。在首次访问网站时&#xff0c;浏览发送请求中并未携带cookie&#xff0c;即发送无状态请求服务器接受请求之后会在请求上的respond header上加入cookie相关信息并返回给浏览…

【计算机组成原理】通过带符号整数的减法运算中加法器的溢出标志 OF 和符号标志 SF 对两个带符号整数的大小进行比较

对于带符号整数的减法运算&#xff0c;能否直接根据 CF 的值对两个带符号整数的大小进行比较&#xff1f; 对于带符号整数的减法运算&#xff0c;不能直接根据CF&#xff08;进/借位标志&#xff09;的值对两个带符号整数的大小进行比较。 CF标志位在带符号整数运算中主要用于…

使用Python+selenium3.0实现第一个自动化测试脚本

这篇文章主要介绍了使用Pythonselenium实现第一个自动化测试脚本&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧 最近在学web自动化&#xff0c;记录一下学习过程。…

冬天夺去的清爽,可爱,春天都会还给你

这款外套上身可太时尚好看了 春天日常穿着或者出行游玩 应对早晚温差&#xff0c;兼具时尚和温度两不误 干净率性闲适的洒脱范整件衣服干净不失细节 下摆有橡筋收紧更加保暖了工艺方面也毫不逊色&#xff0c;防水拉链 四合扣、猪鼻扣一应俱全简直就是一件实用与时尚并存的…

Spring Boot实现数据加密脱敏:注解 + 反射 + AOP

文章目录 1. 引言2. 数据加密和脱敏的需求3. Spring Boot项目初始化4. 敏感数据加密注解设计5. 实现加密和脱敏的工具类6. 实体类和加密脱敏注解的使用7. 利用AOP实现加密和脱敏8. 完善AOP切面9. 测试10. 拓展功能与未来展望10.1 加密算法的选择10.2 动态注解配置 11. 总结 &am…

ReentrantLock底层原理学习一

J.U.C 简介 Java.util.concurrent 是在并发编程中比较常用的工具类&#xff0c;里面包含很多用来在并发场景中使用的组件。比如线程池、阻塞队列、计时器、同步器、并发集合等等。并发包的作者是大名鼎鼎的 Doug Lea。我们在接下来的课程中&#xff0c;回去剖析一些经典的比较…

【Docker基础三】Docker安装Redis

下载镜像 根据自己需要下载指定版本镜像&#xff0c;所有版本看这&#xff1a;Index of /releases/ (redis.io) 或 https://hub.docker.com/_/redis # 下载指定版本redis镜像 docker pull redis:7.2.0 # 查看镜像是否下载成功 docker images 创建挂载目录 # 宿主机上创建挂…

AQS 抽象队列同步器

AQS AQS &#xff08;抽象队列同步器&#xff09;&#xff1a; AbstractQueuedSynchronizer 是什么 来自jdk1.5&#xff0c;是用来实现锁或者其他同步器组件的公共基础部分的抽象实现&#xff0c;是重量级基础框架以及JUC的基石&#xff0c;主要用于解决锁分配给谁的问题整体…

vue2中vuex详细使用

1.安装 说明&#xff1a;也就是版本号&#xff0c;一般vue2安装vuex3。 npm i vuex3.6.2 2.搭建架子 执行流程如下&#xff1a; 初始化状态&#xff1a;在state对象中定义了一个名为message的属性&#xff0c;并将其初始值设置为"启动"。 定义变更函数&#xff08…

【算法专题】FloodFill 算法

FloodFill 算法 1. 图像渲染 题目链接 -> Leetcode -773.图像渲染 Leetcode -773.图像渲染 题目&#xff1a;有一幅以 m x n 的二维整数数组表示的图画 image &#xff0c;其中 image[i][j] 表示该图画的像素值大小。 你也被给予三个整数 sr, sc 和 newColor 。你应该从…

jumpServer-02-安装与配置

jumpServer-02-安装与配置 文章目录 jumpServer-02-安装与配置一、什么是jumpServer&#xff1f;二、jumpServer安装配置①&#xff1a;初始化配置01&#xff1a;Linux服务器准备02&#xff1a;环境准备&#xff0c;关闭防火墙03: 配置yum源04&#xff1a;安装系统初始化所需的…

Python 入门练习

练习1&#xff1a;打印“hello world” print(hello world) 练习2&#xff1a;用户输入一个三位自然数&#xff0c;计算并输出其百位&#xff0c;十位和个位上的数字。 x input(请输入一个三位自然数&#xff1a;) print(*map(int,x)) 运行结果&#xff1a; 练习3&#x…

学习JavaEE的日子 day10 一维数组的深入,二维数组

day10 1.eclipse的使用 Eclipse是一款功能强大的集成开发环境&#xff08;IDE&#xff09;&#xff0c;主要用于开发Java应用程序。 1.项目&#xff08;Project&#xff09;&#xff1a;项目是为满足特定需求而创建的代码文件集合。一个工作区可以包含多个项目&#xff0c;而您…

超维空间M1无人机使用说明书——01、ROS机载电脑使用说明——远程连接

引言&#xff1a;远程连接通常采用两种方式&#xff0c;一种是通过可视化软件&#xff0c;如VNC、Nomachine等&#xff0c;另外一种是使用SSH。各有优缺点&#xff0c;两种远程登录方式的优缺点做一个简单的对比&#xff1a; 1、SSH优缺点 优点:1、消耗网络资源 2、运行稳定 …

基于SSM的网上购物平台设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

JavaScript常用事件演示

文章目录 一、在JavaScript中什么是事件&#xff1f;二、什么是JavaScript 常用事件&#xff1f;三、常用JS事件代码示例:四、事件总结 一、在JavaScript中什么是事件&#xff1f; JavaScript 使我们有能力创建动态页面。事件是可以被 JavaScript 侦测到的行为。 网页中的每个…

基于Vue开发的一个仿京东电商购物平台系统(附源码下载)

电商购物平台项目 项目完整源码下载 基于Vue开发的一个仿京东电商购物平台系统 Build Setup # csdn下载该项目源码压缩包 解压重命名为sangpinghui_project# 进入项目目录 cd sangpinghui_project# 安装依赖 npm install# 建议不要直接使用 cnpm 安装以来&#xff0c;会有各…

Python异常捕获和处理语句 try-except-else-finally

目录 try-except-else-finally语句 1. 基本用法 2. 多个异常处理 3. 处理所有其他异常 4. 多个except子句 5. 使用else子句 6. 使用finally子句 7. 使用as关键字 实例 例1 例2 例3 例4 例5 例6 例7 例8 结论 try-except-finally语句 在Python中&#xff0c;try-e…