第六篇 移位寄存器

实验六 移位寄存器

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.mzph.cn/diannao/22101.shtml

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

相关文章

qnx sepol 和 vmm_service

qnx/hlos_dev_qnx/apps/qnx_ap/target/hypervisor/host/build_files/init_mifs.build.tmpl:74: SECPOL_ENABLE1 编译生成 secpol.bin 打包进ifs_la.img https://download.csdn.net/blog/column/11845877/128596292 qnx/hlos_dev_qnx/apps/qnx_ap/AMSS/platform/vm/resource…

突破性技术: 大语言模型LLM量化激活outliers异常值抑制

LLM过去有两种突破性技术大大提升了量化精度&#xff0c;分别是group-wise量化和GPTQ/AWQ量化。前者相比于过去的per-tensor和per-channel/per-axis量化提出了更细粒度的对channel拆分为更小单元的量化方式&#xff0c;后者通过巧妙的算法明显提升了4bit量化的精度。 LLM量化存…

LeetCode25_K个一组翻转链表

. - 力扣&#xff08;LeetCode&#xff09; 一、题目描述 二、过程模拟 1. 第一步 2. 第二步&#xff1a;子链表分组 3. 第三步&#xff1a;断开前后两组 4. 第四步&#xff1a;翻转start到end的部分 5. 第五步&#xff1a;连接翻转好的前半部分和未翻转的后半部分&#xff…

怎么把照片转成jpg

将照片转换成JPG格式是一个相对简单的过程&#xff0c;适用于大多数设备和操作系统。以下是一些常见的方法&#xff1a; 一、在Windows系统中转换照片格式 使用画图工具 打开你想要转换的照片&#xff0c;右击选择“打开方式”里面的“画图”工具。在画图工具的界面上&#xf…

《世界很喧嚣,做自己就好》有感

仅仅只用了两个中午一个晚上就看完了《世界很喧嚣&#xff0c;做自己就好》&#xff0c;不能说看完&#xff0c;应该说浏览完。决定要看这本书&#xff0c;仅仅只是因为它的书名。前几章还认真看&#xff0c;后面越来越快&#xff0c;再后来一目十行&#xff0c;只重点关注黑色…

找回以前的视频:技术与实践3个指南

你们有没有发现现在视频已经成为我们生活中不可或缺的一部分了&#xff1f;不管是在工作场合做演示、在学习时看教学视频&#xff0c;还是在休闲娱乐时追剧看电影&#xff0c;视频都扮演着超级重要的角色。 然而误删或手机故障的发生很可能将以前的视频清除。本文将深入探讨手…

「实战应用」如何用图表控件LightningChart JS创建SQL仪表板应用(一)

LightningChart JS是Web上性能特高的图表库&#xff0c;具有出色的执行性能 - 使用高数据速率同时监控数十个数据源。 GPU加速和WebGL渲染确保您的设备的图形处理器得到有效利用&#xff0c;从而实现高刷新率和流畅的动画&#xff0c;常用于贸易&#xff0c;工程&#xff0c;航…

【递归、搜索与回溯】递归、搜索与回溯准备+递归主题

递归、搜索与回溯准备递归主题 1.递归2.搜索3.回溯与剪枝4.汉诺塔问题5.合并两个有序链表6.反转链表7.两两交换链表中的节点8.Pow(x, n)-快速幂&#xff08;medium&#xff09; 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你…

Docker基础篇之本地镜像发布到阿里云

文章目录 1. 本地镜像发布到阿里云的流程2. 阿里云开发平台3. 将自己的本地镜像推送到阿里云 1. 本地镜像发布到阿里云的流程 阿里云ECS Docker生态如下图所示&#xff1a; 2. 阿里云开发平台 在控制台找到容器和镜像服务&#xff1a; 然后创建一个个人实例&#xff1a; 下面…

深圳垣象科技golang期望19K一面挂

垣象科技是一个初创公司&#xff0c;我们看好制造业数字化这个大方向&#xff0c;希望搭建一个云平台&#xff0c;通过创新的产品和服务&#xff0c;提高电子及高科技行业产品创新的能力和研发的效率 一面&#xff08;挂&#xff09; 总体来说项目答得不好&#xff0c;h5 拖拽…

适用于 Windows 10 的 5 个最佳数据恢复工具

很多时候&#xff0c;由于存储设备故障或意外删除数据&#xff0c;有时您需要在Windows 10操作系统中恢复数据。大多数人不熟悉在Windows 10下恢复数据的过程。由于这个原因&#xff0c;他们经常认为这是不可能的。事实是&#xff0c;有很多工具可用于Windows 10数据恢复。今天…

Clickhouse 的分布式架构说明——Clickhouse 架构篇(五)

文章目录 前言架构特点及对比ClickHouse分布式架构的优点ClickHouse分布式架构的缺点ClickHouse与Hadoop的分布式架构对比 基本概念集群副本分片 ClickHouse的复制表引擎创建复制表复制表复制复制表查询 ClickHouse分布式表引擎分布式表查询原理分布式表的数据写入方案分布式表…

Plotting World Map in Python

1. 方法一 pygal Plotting World Map Using Pygal in Python import pygal # create a world map worldmap pygal.maps.world.SupranationalWorld() # set the title of map worldmap.title Continents# adding the continents worldmap.add(Africa, [(africa)]) worl…

PyTorch深度学习实战(44)——基于 DETR 实现目标检测

PyTorch深度学习实战&#xff08;44&#xff09;——基于 DETR 实现目标检测 0. 前言1. Transformer1.1 Transformer 基础1.2 Transformer 架构 2. DETR2.1 DETR 架构2.2 实现 DETR 模型 3. 基于 DETR 实现目标检测3.1 数据加载与模型构建3.2 模型训练与测试 小结系列链接 0. 前…

自动驾驶---Control之LQR控制

1 前言 在前面的系列博客文章中为读者阐述了很多规划相关的知识&#xff08;可参考下面专栏&#xff09;&#xff0c;本篇博客带领读者朋友们了解控制相关的知识&#xff0c;后续仍会撰写规控相关文档。 在控制理论的发展过程中&#xff0c;人们逐渐认识到对于线性动态系统的控…

视频封面:如何用前端实现视频帧截图

在这样一个图像化极其重要的时代&#xff0c;从视频中提取精彩瞬间&#xff0c;即视频帧截图的技术&#xff0c;已成为前端开发中的一个亮点。JavaScript作为网页动态效果和交互的主力军&#xff0c;其在视频处理领域能力逐渐被挖掘和重视&#xff0c;尤其是视频帧截图技术的应…

一键实现文件重命名:巧妙运用随机大写字母命名,复制新文件名,轻松管理文件库!

我们的电脑里总是堆积着各种各样的文件。无论是工作文档、生活照片还是学习资料&#xff0c;这些文件都承载着我们的回忆和辛勤努力。然而&#xff0c;随着时间的推移&#xff0c;文件名的混乱和重复逐渐成为我们管理文件的难题。为了解决这一困扰&#xff0c;我们推出了一款创…

09.爬虫---正则解析爬取数据

09.正则解析爬取数据 1.目标网站2.具体实现3.正则表达式分析4.完整代码并存入表格 1.目标网站 直达目标网站 https://movie.douban.com/chart 2.具体实现 我们来拿取一下上面网页的代码如下: from urllib import requesturl https://movie.douban.com/chart headers {Us…

解决 DBeaver 查询时不刷新数据,需要重新连接才会刷新,有缓存一样

DBeaver 查询时总是第一次有数据&#xff0c;再次执行查询数据不会刷新&#xff0c;像是有缓存一样&#xff0c;需要重新连接再查询才会刷新&#xff0c;知道肯定是哪里设置的不对&#xff0c;但是一直没找到&#xff0c;实在是重连太烦了&#xff0c;多次尝试终于找到了设置。…

【数据结构】从前序与中序遍历,或中序与后序遍历序列,构造二叉树

欢迎浏览高耳机的博客 希望我们彼此都有更好的收获 感谢三连支持&#xff01; 首先&#xff0c;根据先序遍历可以确定根节点E&#xff0c;再在中序遍历中通过E确定左树和右数 &#xff1b; 设立inBegin和inEnd&#xff0c;通过这两个参数的游走&#xff0c;来进行子树的创建&a…