四类九种移位寄存器总结(循环(左、右、双向)移位寄存器、逻辑和算术移位寄存器、串并转换移位寄存器、线性反馈移位寄存器LFSR|verilog代码|Testbench|仿真结果)

本文详细介绍了移位寄存器的类型,包括简单循环移位、逻辑移位与算术移位、串-并移位及并-串移位寄存器,并提供了Verilog代码示例和Testbench,展示了如何设计和仿真这些电路。此外,还探讨了线性反馈移位寄存器LFSR的斐波那契和伽罗瓦实现。

在这里插入图片描述



数字IC经典电路设计

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

快速导航链接如下:

个人主页链接

1.数字分频器设计

2.序列检测器设计

3.序列发生器设计

4.序列模三检测器设计

5.奇偶校验器设计

6.自然二进制数与格雷码转换



一、前言

什么是移位寄存器?

组成:由具有存储功能的触发器构成。另外,寄存器还应有执行数据接收和清除命令的控制电路,一般由门电路构成。
功能:移位寄存器可寄存一组二值代码,N个触发器组成的寄存器可以存储一组N位的二值代码,一般用于将二进制数据从一个位置转移到另一个位置

移位寄存器有哪些分类呢?

  • 按移位方向分类:①单向移位寄存器(包括左移、右移)②双向移位寄存器
  • 按循环方式分类:①循环移位寄存器②非循环移位寄存器
  • 按部位的不同分类:①逻辑移位寄存器②算术移位寄存器
  • 按输入输出方式分类:①串入串出②串入并出③并入串出④并入并出

二、简单循环左移/右移/双向移位寄存器

2.1 简单循环左移/右移/双向移位寄存器

(1)右移移位寄存器

在这里插入图片描述

(2)左移移位寄存器
在这里插入图片描述

(3)双向移位寄存器

在这里插入图片描述

为便于扩展逻辑功能和增加使用的灵活性,在单向移位寄存器基础上,增加由门电路组成的控制电路,便可构成双向移位寄存器。目前,在定型生产的中规模移位寄存器集成电路上除了附加左、右移控制,一般还附有数据并行输入、保持、异步置零(复位)等功能。

一般双向移位寄存器逻辑图示例:

在这里插入图片描述

2.2 verilog代码

要求:设计一个四位循环移位寄存器,包括三种移位寄存器,分别是左移移位寄存器、右移移位寄存器、双向移位寄存器。

//三个四位宽的循环移位寄存器
//左移移位寄存器、右移移位寄存器、双向移位寄存器
module sr_simple #(
    parameter WIDTH = 4	//定义数据位宽
    )(
    input    clk,
    input    rst_n,
    input    [1:0]  model,		//双向移位寄存器输出模式选择
    input    [WIDTH - 1 : 0]    data_in,
    output   [WIDTH - 1 : 0]    data_left,	//左移移位寄存器输出
    output   [WIDTH - 1 : 0]    data_right,	//右移移位寄存器输出
    output   [WIDTH - 1 : 0]    data_bidi	//双向移位寄存器输出
    );

//定义双向移位寄存器三种状态——保持、左移、右移
parameter	keep        = 2'b00;
parameter	left_shift  = 2'b01;
parameter	right_shift = 2'b10;

//左移移位寄存器工作模块
//借助拼接符实现移位
reg [WIDTH - 1 : 0] data_left_r;	//中间寄存器
always@(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
	    data_left_r <= data_in;
    end
    else begin
	    data_left_r <= {
   
   data_left_r[WIDTH - 2 : 0], data_left_r[WIDTH - 1]};
    end
end

//右移移位寄存器工作模块
//借助拼接符实现移位
reg [WIDTH - 1 : 0] data_right_r; //中间寄存器
always@(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
	    data_right_r <= data_in;
    end
    else begin
	    data_right_r <= {
   
   data_right_r[0],data_right_r[WIDTH - 1 : 1]};
    end
end

//双向移位寄存器工作模块
//借助拼接符实现移位,case语句实现状态选择
reg [WIDTH - 1 : 0] data_bidi_r;	//中间寄存器
always@(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
	    data_bidi_r <= data_in;
    end
    else begin
	    case(model)            
	        keep:	 	 data_bidi_r <= data_bidi_r;
	    	left_shift:	 data_bidi_r <= {
   
   data_bidi_r[WIDTH - 2 : 0], 			 data_bidi_r[WIDTH - 1]};   
	    	right_shift: data_bidi_r <= {
   
   data_bidi_r[0],data_bidi_r[WIDTH - 1 : 1]};
	    	default:	 data_bidi_r <= data_bidi_r;
        endcase
    end
end

//组合逻辑输出
assign data_left   = data_left_r;
assign data_right  = data_right_r;
assign data_bidi   = data_bidi_r;

endmodule




2.3 Testbench

`timescale 1ns/1ps	//仿真时间单位1ns 仿真时间精度1ps
module sr_simple_tb #(
    parameter WIDTH = 4	//定义数据位宽
    );

//信号申明
reg      clk;
reg      rst_n;
reg      [1:0]  model;
reg      [WIDTH - 1 : 0]    data_in;
wire     [WIDTH - 1 : 0]    data_left;
wire     [WIDTH - 1 : 0]    data_right;
wire     [WIDTH - 1 : 0]    data_bidi;

//模块实例化(将申明的信号连接起来即可)
sr_simple u_sr_simple(
    .clk		(clk),
    .rst_n		(rst_n),
    .model		(model),
    .data_in	(data_in),
    .data_left	(data_left),
    .data_right	(data_right),
    .data_bidi	(data_bidi)
    );

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

//调用系统命令——监视
initial begin
      $monitor ("rst_n = %b,  data_in = %b, data_left = %b, data_right = %b, model = %b,data_bidi = %b", 
       		rst_n, data_in, data_left, data_right,model,data_bidi);
end

//为输入数据赋值
initial begin
    clk   = 0;
    rst_n = 1;
    data_in   = 4'b1001;
    model 	  = 2'b00;
    #5  rst_n = 0;
    #5  rst_n = 1;
    #40
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值