三端口寄存器堆实验

实验目的

  1. 理解寄存器堆的电路结构和功能特性。

  2. 学会使用Digital仿真软件的层次化设计方法。

  3. 学会使用Digital仿真软件的探测器、分线器、常量等组件。

实验原理

CPU内部包含若干个通用寄存器,用于暂存参加运算的数据和中间结果,这些寄存器的集合就称为通用寄存器组(Genral Register Set)。 寄存器组可以设计为单端口、双端口或三端口。单端口是指读出和写入共用同一组地址或数据端口,所以读出和写入不能同时进行,通常应用于多周期的数据通路。而双端口的读、写端口各自独立,在一个周期中可以同时读出和写入。三端口则有两个读端口和一个写端口可以同时操作,通常应用于单周期和流水线数据通路。和早期的处理器相比,现代处理器的通用寄存器的数量更多,一般称为寄存器堆(Register File),也有译为寄存器文件。

图 1是双端口寄存器堆的电路结构。其中RA(Read Address)表示读端口地址,RD(Read Data)表示读端口数据;WA(Write Address)表示写端口地址,WD(Write Data)表示写端口数据;WE(Write Enable)是写使能,Clk是写时钟。

双端口寄存器堆
图 1. 双端口寄存器堆的框图

寄存器堆的写入

触发器和寄存器实验中已经学习了单个寄存器组件的写入。 图 1寄存器堆有4个寄存器,这4个寄存器共用一个数据输入端(WD),时钟输入端(Clk)也是共用的,但这并不意味着4个寄存器同时写入相同的数据;相反,一次只能写入其中一个寄存器,这是由寄存器的使能端(en)控制的。 4个寄存器的使能端(en)分别连接到2-4译码器的4个输出Y0~Y3,从译码器实验可知,Y0~Y3最多只可能有一个为1,也就是最多只有一个寄存器被允许写入。写入哪个寄存器由2-4译码器的输入端A1、A0即寄存器堆的写地址WA决定。 2-4译码器的En作为寄存器堆的写使能(WE),起到一个总体控制的作用。若WE=0,Y0~Y3均为0,任何一个寄存器都不会被写入;只有当WE=1时,才会由WA选择一个寄存器被允许写入。 此时,若Clk端输入一个时钟上升沿,WD端的输入数据将会被存储到指定的寄存器,同时反映在该寄存器的Q端。

寄存器堆的读出

单个寄存器组件内部存储的值始终反映在它的Q输出端,所以并不需要额外的读出操作。 寄存器堆内部有多个寄存器,共用一个读数据端口(RD),因此需要选择其中一个寄存器,将它的值输出到RD端口,即“读出”操作。 由图 1可见,4个寄存器的Q端连接到4选1多路器的4个输入,多路器的输出连接到RD端口;RA作为多路器的选择信号,决定哪一个寄存器的Q输出到RD。 和写入不同,读出并没有使能控制,在任何时刻都会有一个寄存器的值被读出。 读出也不受时钟控制,只要RA改变,立刻改变选择读出的寄存器,无需等待时钟上升沿到来。

可见,寄存器堆的读写操作是独立的。在写入一个寄存器的时候,可以读出另一个寄存器。如果要写入的寄存器地址和读地址相同,在时钟上升沿到来之前,读出的是该寄存器之前存储的值;时钟上升沿之后,读出新写入的值。

图 2是具有2个读端口和1个写端口的三端口寄存器堆的电路结构。

三端口寄存器堆
图 2. 三端口寄存器堆的框图

图 1相比,有两个区别:

  1. 增加了一组读端口

    RA1、RD1为读端口1,RA2、RD2为读端口2。

    读端口1和读端口2均可读出R0~R3四个寄存器中的某一个寄存器的值。 不要误解为RD1只能输出R1的值,RD2只能输出R2的值。

  2. R0寄存器的值恒为0

    在RISC指令系统中,通常要求R0恒为0。为了实现这一要求,用常数“0”代替R0寄存器作为4选1多路选择器0通道的输入,图 2中R0寄存器的虚线表示其实际并不存在。

    虽然Digital仿真软件提供了一个寄存器堆组件,但是它的R0寄存器是可写入的,不具备恒为零的特性。

参考设计

下面给出双端口寄存器堆的设计实例。 根据图 1用Digital仿真软件设计的双端口寄存器堆电路如图 3所示。

双端口寄存器堆电路图
图 3. 双端口寄存器堆电路图

电路组成说明如下。

  1. 四个4位的寄存器

    R0~R3寄存器使用曾在触发器和寄存器实验学习过的寄存器组件,可从菜单「组件 ➤ 存储器 ➤ 寄存器」(Components ➤ Memory ➤ Register)找到该组件,将数据位数设置为4。

    由于寄存器的输出不是电路的输出,默认不会出现在仿真结果记录中。 为便于观察、记录寄存器的值,在寄存器的Q输出端放置了探测器组件,该组件的介绍见几个有用的组件。 另一种方法是设置寄存器组件的「作为测量值」属性

  2. 2-4译码器

    使用译码器实验完成的2-4译码器作为子电路。 有关添加子电路的方法,请参考层次化设计

    图 3写端口地址WA使用一个2位的输入组件,需要用分线器组件将2位的WA拆分为两个1位的导线,再连接到译码器的A1、A0。分线器组件的介绍见几个有用的组件

  3. 多路选择器

    多路器组件在多路选择器实验中练习过,这里需要4选1多路器,应将选择位的位数设置为2。

  4. 时钟输入组件

    使用时钟输入组件作为Clk输入。时钟输入组件及其用法见时序电路的仿真

实验任务

设计任务

理解图 2结构,按照该结构设计字长为4位的三端口寄存器堆。

常数“0”可以用常量组件产生,位数与寄存器的字长相同,即4位。常量组件的介绍见几个有用的组件

验证任务

通过仿真验证寄存器堆的功能,并保存仿真过程数据文件。 为了能够在数据文件中记录每个寄存器的值,电路设计时应在每个寄存器的Q输出端连接探测器组件(默认已勾选「在测量图中显示」属性),或者勾选寄存器组件的「作为测量值」(Use as measurement value)属性。

  1. 数据写入寄存器堆

    尝试将不同的非零数据存入R0、R1、R2、R3寄存器。

    写入的数据应有助于检验寄存器堆的功能和特性。 例如,如果使用“1”作为写入数据,则无法测试寄存器堆的数据位数是不是4位。 再如,如果4个寄存器写入相同的数据,则无法分辨地址译码是否正确。

  2. 从寄存器堆读出数据

    同时从RD1和RD2读出不同寄存器的值。

    需特别注意R0是否恒为0。