第六篇 移位寄存器

2024-06-04 11:52
文章标签 移位 寄存器 第六篇

本文主要是介绍第六篇 移位寄存器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

实验六 移位寄存器

6.1实验目的

  1. 掌握移位寄存器的工作原理;

  2. 掌握利用移位寄存器实现串行与并行的相互转换;

  3. 掌握使用移位寄存器实现乘除法运算;

6.2 原理介绍

6.2.1 基本移位寄存器

在实验四中,我们主要介绍了寄存器的结构及功能,一个N位的寄存器可以存储N位二进制数,即寄存器具有存储数据的功能。移位寄存器(Shift Register)除了具有存储数据的功能以外,还具有移位功能。它们在同一时钟脉冲作用下,可将寄存的二进制数据依次移位,用来实现数据的串行/并行或并行/串行的转换、数值运算以及其他数据处理功能。

将若干个D触发器串接级联在一起构成的具有移位功能的寄存器叫移位寄存器。图6.1是由四个D触发器构成的一个4位移位寄存器的逻辑电路。串行二进制数据从输入端D_{SI}输入,左边触发器的输出作为右邻触发器的数据输入。

图6.1 用D触发器构成的4位移位寄存器

若将串行数据D_3D_2D_1D_0从高位(D_3)至低位(D_0)按时钟序列依次送到D_{SI}端,经过第一个时钟脉冲后,Q_0=D_3。由于跟随D_3后面的是D_2,因此经过第二个时钟脉冲后,触发器FF0的状态移入触发器FF1,而FF0转变为新的状态,即Q_1=D_3、Q_0=D_2,以此类推,可得到该移位寄存器的状态,如表6.1所示(x表示不确定状态)。由表6.1可知,经过四个时钟脉冲后,四个触发器的输出状态Q_3Q_2Q_1Q_0与输入数据D_3D_2D_1D_0相对应。此时,串行输入数据可以从并行数据输出端D_{PO}送出去。可见,数据可以串行输入并行读取,因此,该电路也叫做串-并转换器

如果继续移位,则第七个时钟脉冲作用之后,从D_{SI}逐位输入的数据就能够从输出端D_{SO}(即Q_3端)逐位输出寄存器。可见,该电路串行输入的数据是从左向右移位的。如果将图6.1所示电路中各触发器的连接顺序调换一下,让右边触发器的输出作为左邻触发器的数据输入,则可以构成从右向左移位的寄存器。

表6.1 图6.1电路的状态表

CLK脉冲个数DSIQ0Q1Q2Q3
第一个CLK脉冲之前D3xxxx
1D2D3xxx
2D1D2D3xx
3D0D1D2D3x
40D0D1D2D3
500D0D1D2
6000D0D1
70000D0

为了加深理解,在图6.2中画出了数据1101在寄存器中移位的波形,在经过四个时钟脉冲后,1101出现在触发器的输出端Q_3Q_2Q_1Q_0。在第八个时钟脉冲作用后,数据已从Q_3端(即串行数据输出端D_{SO})全部移出寄存器。随着时钟信号的推移,D_{SO}输出端得到1101的串行输出序列。可以看到,如果首先将4位数据并行地置入移位寄存器的四个触发器中,然后连续加入四个移位脉冲,则移位寄存器里的4位数据将从串行输出端D_{SO}依次送出,因此,该电路叫并-串转换器

image-20210630093719243

图6.2 图6.1电路的时序图

我们来看如何使用Verilog HDL来实现图6.1所示的4位移位寄存器。

对于移位功能,我们可由代码6.1所示的四条语句来实现。

q[0] <= dsi;
q[1] <= q[0];
q[2] <= q[1];
q[3] <= q[2]

代码6.1 4位移位寄存器移位功能的实现方法一

我们可以将上述四条语句简化,如代码6.2所示,这与代码6.1是等价的。

q[0]   <= dsi;
q[3:1] <= q[2:0];

代码6.2 4位移位寄存器移位功能的实现方法二

根据图6.1可以写出4位移位寄存器的Verilog HDL实现,如代码6.3所示。

module shift_reg_4bit(input               clk,        // 时钟信号input               clr_n,      // 异步清零信号,低电平有效input               dsi,        // 串行数据输入output  reg [3:0]   q,          // 并行数据输出output              dso         // 串行数据输出
);
​
​
always@(posedge clk, negedge clr_n)
beginif(~clr_n)                      // clk_n为0,寄存器清零beginq   <= 4'b0000;endelsebegin                           // 数据从低位触发器向高位触发器移位q[0]    <= dsi;q[3:1]  <= q[2:0];end
end
assign  dso =   q[3];               // 串行数据输出endmodule

代码6.3 4位移位寄存器Verilog HDL实现

图6.3是代码6.3对应的4位移位寄存器的RTL Viewer。

image-20210630101523866

图6.3 4位移位寄存器的RTL Viewer

6.2.2 双向移位寄存器

有时需要对移位寄存器的数据流向加以控制,实现数据的双向移动,其中一个方向称为右移,另一个方向称为左移,这种移位寄存器称为双向移位寄存器。

注:这里需要注意的是,由于国家标准规定,逻辑图中的最低有效位(LSB)到最高有效位(MSB)的电路排列顺序应从上到下,从左到右。因此定义移位寄存器中的数据从低位触发器移向高位为右移,移向低位为左移。这一点与通常计算机程序中的规定相反,后者从二进制数的自然排列考虑,将数据移向高位定义为左移,反之为右移。

图6.4是双向移位寄存器的一种方案,与普通移位寄存器的连接不同,每个触发器的输入端D连接两个不同的数据源,一个是前级的输出,用于右移操作;另外一个数后一级的输出,用于左移操作。控制信号S用来选择操作的模式,当S=0时,FF0的D_0端与右移串行输入端D_{IR}连通,FF1的D_1端与Q_0连通,FF2的D_2端与Q_1连通,FF3的D_3端与Q_3连通,在时钟脉冲CLK的作用下,D_{IR}端输入的数据将向右移位,并从右移串行输出端D_{OR}输出,电路实现右移操作;当S=1时,FF3的D_3端与左移串行输入端D_{IL}连通,FF2的D_2端与Q_3连通,FF1的D_1端与Q_2连通,FF0的D_0端与Q_1连通,在时钟脉冲CLK的作用下,D_{IL}端输入的数据将向左移位,并从左移串行输出端D_{OL}输出,电路实现左移操作。

image-20210630102106310

图6.4 用D触发器构成的双向移位寄存器

由此可见,图6.4所示电路可作双向移位,当S=0时,数据向右移位;当S=1时,数据向左移位,可实现串行输入-串行输出(由D_{OR}或D_{OL}输出)、串行输入-并行输出(由Q3 \sim Q0输出)的工作方式。

代码6.4是图6.4所示的4位双向移位寄存器的Verilog HDL实现。

module bidir_shift_reg_4bit(input               clk,        // 时钟信号input               clr_n,      // 异步清零信号,低电平有效input               dir,        // 右移串行输入input               dil,        // 左移串行输入input               s,          // 控制信号output  reg [3:0]   q,          // 并行数据输出output              dor,        // 右移串行输出output              dol         // 左移串行输出
);
​
always@(posedge clk, negedge clr_n)
beginif(~clr_n)                      // clk_n为0,寄存器清零beginq   <= 4'b0000;endelsebegin                           if(s == 1'b0)               // 右移q   <=  {q[2:0], dir};else                        // 左移q   <=  {dil, q[3:1]};end
end
assign  dor =   q[3];               // 右移串行输出
assign  dol =   q[0];               // 左移串行输出endmodule

代码6.4 4位双向移位寄存器Verilog HDL实现

图6.5是代码6.4对应的4位双向移位寄存器的RTL Viewer。

image-20210630104321406

图6.5 4位双向移位寄存器的RTL Viewer

6.2.3 并行存取的移位寄存器

并行存取的移位寄存器如图6.6所示,它与双向移位寄存器的连接有些类似,但又有不同。并行存取的移位寄存器的每个触发器的输入端D也是连接两个不同的数据源,一个数据源是前级的输出,用于移位寄存器的右移操作,这与双向移位寄存器是一样的;另外一个数据来自于外部的输入,作为并行操作的一部分,这部分与双向移位寄存器不同。控制信号S用来选择操作的模式,当S=0时,电路实现右移操作;当S=1时,并行数据DI_3 \sim DI_0送到各自的寄存器进行寄存,由此便可实现并行输入(由DI_3 \sim DI_0输入)、并行输出(由Q3 \sim Q0输出)。

image-20210630105252445

图6.6 4位并行存取的移位寄存器

代码6.5是图6.6所示的4位并行存取的移位寄存器的Verilog HDL实现。

module parallel_shift_reg_4bit(input               clk,        // 时钟信号input               clr_n,      // 异步清零信号,低电平有效input               dir,        // 右移串行输入input       [3:0]   di,         // 并行数据输入input               s,          // 控制信号output  reg [3:0]   q,          // 并行数据输出output              dor         // 右移串行输出
);
​
always@(posedge clk, negedge clr_n)
beginif(~clr_n)                      // clk_n为0,寄存器清零beginq   <= 4'b0000;endelsebegin                           if(s == 1'b0)               // 右移q   <=  {q[2:0], dir};else                        // 并行存取q   <=  di;end
end
assign  dor =   q[3];               // 右移串行输出endmodule

代码6.5 4位并行存取移位寄存器Verilog HDL实现

图6.7是代码6.5对应的4位并行存取移位寄存器的RTL Viewer。

image-20210630105618233

图6.7 4位并行存取移位寄存器的RTL Viewer

6.2.4 多功能双向移位寄存器

为便于扩展逻辑功能和增加使用的灵活性,我们将并行输入、并行输出、左移、右移、保持、异步复位等功能集合到同一个电路中,组成多功能双向移位寄存器。

图6.8所示是实现一个4位的具有数据保持、右移、左移、并行输入和并行输出功能的多功能双向移位寄存器的一种电路方案。该电路主要由四个D触发器和四个四选一数据选择器构成,每个D触发器的数据输入端都插入一个四选一数据选择器MUX,并用2位的输入S1、S0控制MUX,来选择D触发器输入信号D的来源。当S1=S0=0时,选择该D触发器自身的输出Q,使D触发器保持状态不变;当S1=0、S0=1时,前一级D触发器的输出被选中,所以当时钟信号上升沿到来时,D触发器存入前一级D触发器的逻辑值,从而实现右移功能;类似地,当S1=1、S0=0时,实现左移功能;而当S1=S0=1时,选择并行输入数据DI3 \sim DI0,即实现并行输入的功能。表6.2列出了该多功能双向移位寄存器的四种操作。

image-20210630110557264

图6.8 实现多功能双向移位寄存器的一种方案

​​

表6.2 图6.8电路的功能表

控制信号功能
S1S0
00保持
01右移
10左移
11并行输入

代码6.6是图6.8所示的4位多功能双向的移位寄存器的Verilog HDL实现。

module multi_func_shift_reg_4bit(input               clk,        // 时钟信号input               clr_n,      // 异步清零信号,低电平有效input               dir,        // 右移串行输入input               dil,        // 左移串行输入input       [3:0]   di,         // 并行数据输入input       [1:0]   s,          // 控制信号output  reg [3:0]   q,          // 并行数据输出output              dor,        // 右移串行输出output              dol         // 左移串行输出
);
​
always@(posedge clk, negedge clr_n)
beginif(~clr_n)                      // clk_n为0,寄存器清零beginq   <= 4'b0000;endelsebegincase(s[1:0])2'b00:  q   <=  q;              // 保持2'b01:  q   <=  {q[2:0], dir};  // 右移2'b10:  q   <=  {dil, q[3:1]};  // 左移2'b11:  q   <=  di;             // 并行存取endcaseend
end
assign  dor =   q[3];               // 右移串行输出
assign  dol =   q[0];               // 左移串行输出endmodule

代码6.6 4位多功能双向移位寄存器Verilog HDL实现

图6.9是代码6.6对应的4位多功能双向移位寄存器的RTL Viewer。

image-20210630111344065

图6.9 4位多功能双向移位寄存器的RTL Viewer

6.3 实验目标

  • 使用移位寄存器来实现乘以2和除以2的运算;

  • 并将乘以2和除以2的运算加入到实验五实现的计算器中,即计算器可实现与运算、或运算、异或运算、非运算、加(减)法运算、乘以2、除以2运算;

6.4 设计实现

6.4.1 设计思路

图6.10是本实验的系统框图,我们增加了如红色框所示的部分,它们分别实现乘以2、除以2的运算。使用SW3 ~ SW0作为乘法和除法的第一个操作数A,第二个操作数固定为常数2。经过乘法运算后,结果可能会超过16,所以使用两个数码管来显示运算的结果。

image-20240520165005303

图6.10 实验六系统框图

我们再来看乘法、除法运算的实现。

二进制数A乘以2,这相当于在A最低有效位的右边添加一个0,或者说把A的所有位左移1位,如图6.11(a)所示。因此A乘以2可以用左移的移位寄存器来实现。

二进制数A除以2,这相当于在A最高有效位添加一个0,即把A的所有位右移1位,如图6.11(b)所示。因此A除以2可以用右移的移位寄存器来实现。

注:上文中讨论的乘法和除法,都是考虑无符号二进制数A。

image-20210630094009622

图6.11 左移(a)和右移(b)运算示例

图6.12为4位移位寄存器的框图,rst_n为异步清零信号,a为4位输入数据,进行左移1位或右移1位后,输出数据f。该框图可以表示4位左移移位寄存器,也可以表示4位右移移位寄存器,因为它们对外的接口信号都是一样的,进行左移还是右移是在内部实现的,即框图内部实现时会不同。

image-20210630094040193

图6.12 4位移位寄存器的框图

表6.3是4位移位寄存器的输入输出信号描述。

表6.3 4位移位寄存器信号描述

信号名称位宽方向功能描述
clk1-bitInput4位移位寄存器的时钟信号
rst_n1-bitInput4位移位寄存器的异步复位信号
a4-bitInput4位移位寄存器的输入信号
f4-bitOutput4位移位寄存器的输出信号

6.4.2 代码实现
  • 乘以2运算

    代码6.7是乘以2运算的代码实现。

    module c6(input               clk,        // 时钟信号input               rst_n,      // 异步复位信号input       [ 3: 0] a,          // 输入信号output  reg [ 4: 0] f           // 输出信号
    );
    ​
    always@(posedge clk, negedge rst_n)
    beginif(~rst_n)beginf <= 5'b00000;endelsebeginf[4:1]  <= a[3:0];          // 右移1位f[0]    <= 1'b0;            // 右移1位,最低位填0end
    end
    ​
    endmodule

    代码6.7 c6.v

    如下图是乘以2运算的RTL Viewer。

    image-20210630094433063

    图6.13 乘以2运算的RTL Viewer

  • 除以2运算

    代码6.8是除以2运算的代码实现。

    module c7(input               clk,        // 时钟信号input               rst_n,      // 异步复位信号input       [ 3: 0] a,          // 输入信号output  reg [ 3: 0] f           // 输出信号
    );
    ​
    always@(posedge clk, negedge rst_n)
    beginif(~rst_n)beginf   <= 4'b0000;endelsebeginf[2:0]  <= a[3:1];          // 左移1位f[3]    <= 1'b0;            // 左移1位,最高位填0end
    end
    ​
    endmodule

    代码6.8 c7.v

    图6.14是除以2运算的RTL Viewer。

    image-20210630094543369

    图6.14 除以2运算的RTL Viewer

  • 计算器模块

    计算器模块是在实验五实现的计算器的基础上增加了乘以2、除以2运算,需要修改calculator.v文件,其中第72行 ~ 98行为主要的修改部分,主要是添加了c6、c7模块以及与mux8x1模块之间的连接。

    module calculator(input           clk,        // 时钟信号,50MHzinput           rst_n,      // 异步复位信号input           en,         // 寄存器使能信号input           carry_in,   // 加法的进位输入input   [3:0]   a,          // 计算器的第一个操作数//input   [3:0]   b,          // 计算器的第二个操作数input   [2:0]   sel,        // 计算器的功能选择信号output  [5:0]   ledr_out,   // 寄存器的数据输出output  [6:0]   hex0_out,   // 七段数码管译码器的输出HEX0output  [6:0]   hex1_out    // 七段数码管译码器的输出HEX1
    );// 变量声明
    wire [3:0]  operator_a;
    wire [3:0]  operator_b;
    wire        operator_cin;
    wire [2:0]  operation_s;wire [3:0]  f1;
    wire [3:0]  f2;
    wire [3:0]  f3;
    wire [3:0]  f4;
    wire [5:0]  f5;
    wire [4:0]  f6;
    wire [3:0]  f7;
    wire [5:0]  f;
    wire [5:0]  g;
    wire [6:0]  hex0dec_output;
    wire [6:0]  hex1dec_output;// 输入信号赋值
    assign  operator_a      =   a;
    //assign  operator_b      =   b;
    assign  operator_cin    =   carry_in;
    assign  operation_s     =   sel;// 将输入a存入寄存器中reg4bits reg4bits_inst (.clk(clk), .rst_n(rst_n), .en(~en), .d(a), .q(operator_b));    // 与运算
    c1  c1_inst(.a  (operator_a),.b  (operator_b),.f  (f1)
    );
    // 或运算
    c2  c2_inst(.a  (operator_a),.b  (operator_b),.f  (f2)
    );
    // 异或运算
    c3  c3_inst(.a  (operator_a),.b  (operator_b),.f  (f3)
    );
    // 非运算
    c4  c4_inst(.a  (operator_a),.f  (f4)
    );
    // 加(减)运算
    c5 c5_inst (.a  (operator_a), .b  (operator_b), .ci (operator_cin), .f  (f5)
    );
    // 乘以2
    c6 c6_inst (.clk    (clk),.rst_n  (rst_n),.a      (operator_a),.f      (f6)
    );
    // 除以2
    c7 c7_inst (.clk    (clk),.rst_n  (rst_n),.a      (operator_a),.f      (f7)
    );
    // 在f1,f2,f3,f4,f5,f6,f7七种运算结果中,选择一个运算结果f
    mux8x1 mux8x1_inst(.r  ({2'd0, f1}),.t  ({2'd0, f2}),.u  ({2'd0, f3}),.v  ({2'd0, f4}),.w  (f5),.x  ({1'd0, f6}), .y  ({2'd0, f7}), .z  (6'd0),.s  (operation_s),.m  (f)
    );
    // 将选出的运算结果f存入寄存器中
    reg6bits reg6bits_inst(.clk    (clk),.rst_n  (rst_n),.en     (~en),.d      (f),.q      (g)
    );
    // 寄存器的输出数据g输入至数码管译码器,经译码后显示至两个七段数码管上
    decod7seg decod7seg_inst0(.hex        (g[3:0]),.display    (hex0dec_output)
    );
    decod7seg decod7seg_inst1(.hex        ({2'd0, g[5:4]}),.display    (hex1dec_output)
    );// 寄存器的输出数据g直接显示在LED上
    assign  ledr_out    = g;
    assign  hex0_out    = hex0dec_output;
    assign  hex1_out    = hex1dec_output;endmodule

    代码6.9 calculator.v

    calculator模块的RTL Viewer如图6.15所示,可以看出和6.3.1节画的系统框图是一致的。

    image-20240520170238619

    图6.15 calculator模块的RTL Viewer

6.5 实验步骤

6.5.1 创建工程和代码输入
  1. 点击电脑右下角的开始菜单找到Quartus软件,双击Quartus (Quartus Prime 17.1)打开Quartus Prime软件。

  2. 点击菜单File-->New Project Wizard弹出工程创建的对话框。在弹出的对话框中点击Next。

  3. 在您的DE1-SOC 工作文件夹下创建一个lab7的文件夹,并将工程路径指向该文件夹,且工程的名称也命名calculator。如图6.16-1所示。

image-20240520145247493

图6.16-1 创建Quartus工程

image-20240520145425656

图6.16-2

image-20240520145514303

图6.17

完成创建工程后,打开后的工程Quartus Prime工程界面如图6.18所示。

image-20240520145535274

图6.18 Quartus打开的工程窗口

在lab6工程文件夹下新建名为v的文件夹。点击Quartus软件工具栏的File --> New --> Verilog HDL File,创建c6.v、c7.v文件保存到v文件夹,并依次添加代码6.7、代码6.8中的代码。

image-20240520165319356

图6.19 c6.v

image-20240520165417025

图6.20 c7.v

实验五 加法器中的c1.v、c2.v、c3.v、c4.v、c5.v、decod7seg.v、fa.v、mux2x1.v、mux8x1.v、reg6bits.v、calculator.v文件复制到本实验工程文件夹下,如图6.21所示。

image-20240520165634751

图6.21 复制文件至本实验的工程路径下

点击Quartus软件工具栏的Assignments --> Settings --> Files,将前面拷贝的文件添加至本实验的Quartus工程,如图6.22所示。

image-20240520165745111

图6.22 添加文件至Quartus工程

修改calculator.v文件,参考代码6.9。

image-20240520170327952

图6.23 修改calculator.v文件

  1. 点击Quartus软件工具栏的Processing --> Start --> Start Analysis & Synthesis或点击

    image-20210603145513555

    按钮对Verilog HDL代码执行语法检查和综合。如果在该过程中提示有错误,请检查Verilog HDL代码语法,确保与上述代码块完全一致。

    image-20240520170410592

    图6.25 执行语法检查和综合

6.5.2 仿真
  1. 点击Quartus工具栏File --> New --> Verilog HDL File,点击OK,添加如下仿真代码,点击File --> Save保存,并命名为calculator_tb.v,保存在v文件夹中。

`timescale 1ns/1ns
module calculator_tb();// 产生50MHz时钟信号
reg clk;
localparam  PERIOD = 20;                // 20ns = 50MHz
initial 
beginclk     =   1'b0;forever #(PERIOD/2) clk = ~clk;     // 每隔10ns,clk翻转一次
end// 产生复位信号,用作6位寄存器的异步复位
reg rst_n;
initial 
beginrst_n = 1'b0;#(PERIOD)   rst_n = 1'b1;
end// 产生计算器的操作数a、运算操作选择sel和4位寄存器的使能信号en
reg [3:0] a;
//reg [3:0] b;
reg       ci;
reg [2:0] sel;
reg       en;
initial 
begin#0a   = 4'd0;//  b   = 4'd0;ci  = 1'b0;sel = 3'b000;en  = 1'b0;#(PERIOD)a   = 4'd3;sel = 3'b101;       // a=2, 乘以2#(PERIOD)a   = 4'd8;sel = 3'b101;       // a=8, 乘以2#(PERIOD)a   = 4'd12;sel = 3'b101;       // a=12, 乘以2#(2 * PERIOD)a   = 4'd14;sel = 3'b110;       // a=14, 除以2#(PERIOD)a   = 4'd7;sel = 3'b110;       // a=7, 除以2#(PERIOD)a   = 4'd4;sel = 3'b110;       // a=4, 除以2#(3 * PERIOD)$stop();
end// 例化 calculator
wire    [5:0]   ledr_out;
wire    [6:0]   hex0_out;
wire    [6:0]   hex1_out;
calculator calculator_inst(.clk        (clk),.rst_n      (rst_n),.en         (en),.carry_in   (ci),.a          (a),// .b          (b),.sel        (sel),.ledr_out   (ledr_out),.hex0_out   (hex0_out),.hex1_out   (hex1_out)
);endmodule

代码6.11 calculator_tb.v

  1. 点击Quartus工具栏Assignments --> Settings --> EDA Tool Settings --> Simulation,设置Quartus自动调用ModelSim仿真软件,并设置test bench为calculator_tb,设置完成后如图6.26所示。

image-20240520172125103

图6.26 设置test bech为calculator_tb

  1. 其中,添加Compile test bench的具体步骤如下。

image-20240520172026817

图6.27 设置test bech的具体步骤

点击Quartus工具栏Tools --> Run Simulation Tool --> RTL Simulation启动ModelSim仿真,再点击Wave切换到仿真波形窗口,并点击Zoom Full按钮,如图6.28所示。

image-20240521142320987

图6.28 打开的初始仿真波形

点击上图左侧的Calculator_inst旁的"+"按钮,再单击选中c6_inst,将c6模块的输出信号f添加到wave中,如下图6.29所示。依此再将reg4bits_inst的输出信号q、c7模块的输出信号f和mux8x1模块的输出信号m添加到wave中。

image-20240520173148390

图6.29 添加c6、c7和mux8x1模块的输出信号

右键选中下图中的a、q(其实就是操作数b)、c6、c7和mux8x1,点击Radix-->Hexadecimal,以十六进制数显示。

image-20240520174853712

图6.30 更改十六进制显示

点击ModelSim工具栏的Simulate-->Restart,在弹出的Restart窗口,保持默认选择并点击OK按钮,然后再点击Run -All图标进行仿真。

image-20240520175018139

图6.31 开始仿真

仿真波形如下图6.32所示。

image-20240521142757841

图6.32 calculator仿真波形

仿真波形分析

  • 0 ~ 20ns,复位信号rst_n=0,c6、c7处于复位状态,ledr_out=(00)16,hex0_out=hex1_out=(1000000)2,即数码管HEX1、HEX0都显示十六进制数“0”;

  • 20ns,复位信号rst_n=1,移位寄存器c6、c7恢复正常状态,a=(3)16,sel=(101)2,但此时clk上升沿还没有到来,所以ledr_out=(00)16,hex0_out=hex1_out=(1000000)2,即数码管HEX1、HEX0都显示十六进制数“0”;

  • 30ns,clk上升沿到来,数据选择器选择乘以2运算的结果输出m=(06)16;

  • 50ns,clk上升沿时刻,寄存器的输出ledr_out=(06)16,hex1_out=(1000000)2,hex0_out=(0000010)2,即数码管HEX1、HEX0分别显示显示十六进制数“0”、“6”;

  • 同样是在50ns,clk上升沿时刻,a=(8)16,sel=(101)2,m=(10)16;

  • 70ns,clk上升沿时刻,寄存器的输出ledr_out=(10)16,hex1_out=(1111001)2,hex0_out=(1000000)2,即数码管HEX1、HEX0分别显示显示十六进制数“1”、“0”;

  • 同样是在70ns,clk上升沿时刻,a=(c)16,sel=(101)2,m=(18)16;

  • 90ns,clk上升沿时刻,寄存器的输出ledr_out=(18)16,hex1_out=(1111001)2,hex0_out=(0000000)2,即数码管HEX1、HEX0分别显示显示十六进制数“1”、“8”;

  • 100ns,sel由(101)2变为(110)2,但此时处于clk下降沿,数码管HEX1、HEX0保持不变;

  • 110ns,clk上升沿时刻,a=(e)16,sel=(110)2,数据选择器选择除以2运算的结果输出m=(7)16;

  • 130ns,clk上升沿时刻,寄存器的输出ledr_out=(07)16,hex1_out=(1000000)2,hex0_out=(1111000)2,即数码管HEX1、HEX0分别显示显示十六进制数“0”、“7”;

  • 同样是在130ns,clk上升沿时刻,a=(7)16,sel=(110)2,m=(3)16;

  • 150ns,clk上升沿时刻,寄存器的输出ledr_out=(03)16,hex1_out=(1000000)2,hex0_out=(0110000)2,即数码管HEX1、HEX0分别显示显示十六进制数“0”、“3”;

  • 同样是在150ns,clk上升沿时刻,a=(4)16,sel=(110)2,m=(2)16;

  • 170ns,clk上升沿时刻,寄存器的输出ledr_out=(02)16,hex1_out=(1000000)2,hex0_out=(0100100)2,即数码管HEX1、HEX0分别显示显示十六进制数“0”、“2”;

6.5.3 引脚分配、全编译与烧录

这个实验的操作数a及sel可以通过拨码开关SW0~SW3以及SW7~SW9来控制,carry_in从SW6输入。out信号分别输出到LEDR0到LEDR5,hex0_out输出到数码管0,hex1_out输出到数码管1,en和rst_n连接到按键key1和key0。

  1. 点击Quartus菜单Assignments——Pin Planner进行引脚分配。

img

图4.41

关于引脚分配信息可以查看DE1-SoC_v.5.1.3_HWrevF.revG_SystemCD\UserManual\DE1-SoC_User_manual.pdf第 22、25、26、28页或者E:\CD_Package\01-DE1-SoC\DE1-SoC_v.5.1.3_HWrevF.revG_SystemCD\Schematic\DE1-SoC.pdf的第3页。

img

image-20240517165745573

img

image-20240517165857589

image-20240521091242725

image-20240521092456466

image-20240521092534583

  1. 点击Quartus软件工具栏的Processing --> Start Compilation或点击

    image-20210603145755433

    按钮编译lab6工程,并检查是否生成calculator.sof。

    image-20240521093008816

    图6.33 编译lab6工程

  2. 连接DE1-SOC开发板到PC, 给开发板上电开机。

  3. 点击Quartus软件工具栏的Tools --> Programmer

    image-20210603150014201

    按钮打开Programmer窗口,点击Hardware Setup选择USB-Blaster设备,点击Auto Detect选择5CSEBA6器件,左键单击选中5CSEBA6器件再点击Change File,选择lab6.sof,勾选Program/configure,点击Start下载calculator.sof。

    image-20240521093339274

    图6.34 烧录lab6.sof

6.5.4 实验现象观察
  1. 拨动界面上的滑动开关,并观察实验现象:

  • 先按一次KEY0,寄存器异步复位,c6、c7模块和6位寄存器中的数据被清0,LEDR5 ~ LEDR0全部熄灭,HEX1HEX0都显示十六进制数字“0”;

    IMG_20240521_093536(1)

    图6.38 实验现象1

  • 拨动SW10 ~ SW8为“up、down、up”,SW3 ~ SW0为“down、down、up、up”,按一次KEY1LEDR5 ~ LEDR0显示为“熄灭、熄灭、熄灭、点亮、点亮、熄灭”,HEX1、HEX0分别显示十六进制数字“0”、“6”;

    即:a=(3)_{16},sel=(101)_2,计算器作乘以2运算,a*2=(6)_{16}。

    IMG_20240521_093716(1)

    图6.39 实验现象2

  • 拨动SW10 ~ SW8为“up、down、up”,SW3 ~ SW0为“up、down、down、down”,SW7 ~ SW4为“down、down、down、down”;按一次KEY1LEDR5 ~ LEDR0显示为“熄灭、点亮、熄灭、熄灭、熄灭、熄灭”,HEX1、HEX0分别显示十六进制数字“1”、“0”;

    即:a=(8)_{16},sel=(101)_2,计算器作乘以2运算,a*2=(10)_{16}。

    IMG_20240521_135759(1)

    图6.40 实验现象3

  • 拨动SW10 ~ SW8为“up、down、up”,SW3 ~ SW0为“up、up、down、down”,SW7 ~ SW4为“down、down、down、down”;按一次KEY1LEDR5 ~ LEDR0显示为“熄灭、点亮、点亮、熄灭、熄灭、熄灭”,HEX1、HEX0分别显示十六进制数字“1”、“8”;

    即:a=(c)_{16},sel=(101)_2,计算器作乘以2运算,a*2=(18)_{16}。

    IMG_20240521_135826(1)

    图6.41 实验现象4

  • 拨动SW10 ~ SW8为“up、up、down”,SW3 ~ SW0为“up、up、up、down”,SW7 ~ SW4为“down、down、down、down”;按一次KEY1LEDR5 ~ LEDR0显示为“熄灭、熄灭、熄灭、点亮、点亮、点亮”,HEX1、HEX0分别显示十六进制数字“0”、“7”;

    即:a=(e)_{16},sel=(110)_2,计算器作除以2运算,a/2=(7)_{16}。

    IMG_20240521_135900(1)

    图6.42 实验现象5

  • 拨动SW10 ~ SW8为“up、up、down”,SW3 ~ SW0为“down、up、up、up”,SW7 ~ SW4为“down、down、down、down”;按一次KEY1LEDR5 ~ LEDR0显示为“熄灭、熄灭、熄灭、熄灭、点亮、点亮”,HEX1、HEX0分别显示十六进制数字“0”、“3”;

    即:a=(7)_{16},sel=(110)_2,计算器作除以2运算,a/2=(3)_{16}。

    IMG_20240521_135916(1)

    图6.43 实验现象6

  • 拨动SW10 ~ SW8为“up、up、down”,SW3 ~ SW0为“down、up、down、down”,SW7 ~ SW4为“down、down、down、down”;按一次KEY1LEDR5 ~ LEDR0显示为“熄灭、熄灭、熄灭、熄灭、点亮、熄灭”,HEX1、HEX0分别显示十六进制数字“0”、“2”;

    即:a=(4)_{16},sel=(110)_2,计算器作除以2运算,a/2=(2)_{16}。

    IMG_20240521_135933(1)

    图6.44 实验现象7

6.6 实验小结

本章我们学习了如何使用寄存器组成移位寄存器,移位寄存器不仅可以存储数据,还可以用来实现数据的串-并转换、数据处理以及数值的运算,像我们在实验中使用移位寄存器来实现了乘以2、除以2运算。

使用移位寄存器还可以实现环形计数器和扭环形计数器,由于这不是我们本章的主旨,没有做过多的介绍,有兴趣的同学可查阅相关资料学习。

这篇关于第六篇 移位寄存器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1030006

相关文章

寄存器B

MCS-51单片机的中央处理器包含运算部件和控制部件两部分。         1. 运算部件         运算部件以算术逻辑运算单元ALU为核心,包含累加器ACC、B寄存器、暂存器、标志寄存器PSW等许多部件,它能实现算术运算、逻辑运算、位运算、数据传输等处理。         算术逻辑运算单元ALU是一个8位的运算器,它不仅可以完成8位二进制数据加、减、乘、除等基本的算

士兰微 SC32F5432 通过配置寄存器方式 将管脚配成开漏输出模式和TTL输入模式

目录 前言: 士兰微电子介绍 士兰微 SC32F5432介绍 士兰微 SC32F5432 通过配置寄存器方式 将管脚配成开漏输出模式和TTL输入模式 开漏输出模式 TTL输入模式 前言: 下面是对我在工作时公司所使用的一款国产芯片(士兰微 SC32F5432)开发过程所遇到的一些问题的记录与解决。 士兰微电子介绍 杭州士兰微电子股份有限公司(600460)坐落于杭州

笔记 14 : 彭老师课本第 8 章, UART : 寄存器介绍 ,

(99) 继续介绍 uart 的关于通道的 一整套 寄存器, UCON 等: ++ 接着介绍寄存器 UTRSTAT : ++ 接着介绍读写数据的寄存器: ++ 设置 uart 的波特率,有关的寄存器: ++ (100) (101) 谢谢

AUXR-特殊功能寄存器(只写)

AUXR : Auxiliary Register(只写) MnemonicAddbitB7B6B5B4B3B2B1B0Reset ValueAUXR8EHname -  -  - - - -EXTRAMALEOFFxxxx,xx00 禁止ALE信号输出(应用示例供参考,C语言):sfr AUXR = 0x8e; //声明AUXR寄存器的地址AUXR = 0x01;//ALEOFF位置1

[编程之美] 2.17 字符串循环移位

题目 将字符串向右循环移动 k 位 s = "abcd123" k = 3Return "123abcd" 思路 方法一 翻转法 将子串 s[0:str.length() - k)] 翻转,子串s[str.length() - k,str.length()] 翻转。然后将整个字符翻转可以到最终结果。 eg: 将 abcd123 中的 abcd 和 123 单独翻转,得到 dcba3

[编程之美] 3.1 字符串循环移位包含

题目 s1 = AABCD, s2 = CDAA Return : true 给定两个字符串 s1 和 s2,要求判定 s2 是否能够被 s1 做循环移位得到的字符串包含。 思路 以S1 = ABCD 为例,对其循环移位的后果为: ABCD -> BCDA -> CDAB -> DABC -> ABCD S1S1 = ABCDABCD 看出对S1做循环移位所得到的字符串都将是字符串S1S1的

第六篇——黄金分割:毕达哥拉斯如何连接数学和美学?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么? 四、总结五、升华 一、背景介绍 人眼看到的美的东西,都可以从数学这个抽象的学科中得到明确的逻辑论证;这就是数学学科神奇的地方之一 二、思路&方案 1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇

FPGA编程基础(一)--参数传递与寄存器使用

一、参数映射 参数映射的功能就是实现参数化元件。所谓的”参数化元件“就是指元件的某些参数是可调的,通过调整这些参数从而可实现一类结构类似而功能不同的电路。在应用中,很多电路都可采用参数映射来达到统一设计,如计数器、分频器、不同位宽的加法器以及不同刷新频率的VGA视频接口驱动电路等。 参数传递 参数传递就是在编译时对参数重新赋值而改变其值。传递的参数是子模块中定义的parameter,其传递方

日系编曲:日系架子鼓写作思路 支点音符 幽灵音 抢拍(重音移位)半速与倍速

分子大于3的拍子都是由若干个二拍子和三拍子组成的,且在组成时要保证三拍子的最大数量,且在排列时三拍子尽可能在前。 二拍子与三拍子 分子大于3的拍子都是由若干个二拍子和三拍子组成的,且在组成时要保证三拍子的最大数量,且在排列时三拍子尽可能在前。 比如8/4拍就是3+3+2形式,7/4拍则是3+2+2形式 二拍子:强、弱 三拍子:强、弱、弱 当复合时,除了第一个强拍,后面的强拍都成

Java:位运算符,移位运算

一 位运算符 1.按位与------ & 运算法则: 2.按位或------ | 运算法则: 3.按位异或------ ^ 运算法则: 4.按位取反------ ~ 运算法则: 如果该位为 0 则转为 1, 如果该位为 1 则转为 0 二  移位运算 1.左移  << 运算法则: 2.右移  >> 运算法则: 3.无符号右移  >>>