单周期CPU

单周期CPU

​ 以MIPS为参考,logisim为仿真模拟器,设计一个支持addu、subu、or、andi、lui、beq、j、jal、jr、sb、sh、sw、lb、lh及lw指令的单周期CPU,共支持32条指令。若无特殊说明,涉及时钟的部件均为上升沿触发。

理论

单周期CPU的时钟周期

​ 单周期CPU意味着一条指令涉及的所有操作均在一个时钟周期内完成,而不同指令执行从开始到结束所需的时间往往是不一样的,为了保证一个程序的所有指令能够顺利地执行,单周期CPU的时钟周期取时间最大者。由于设计方式、材料等方面的不同,CPU寄存器的访问时间是最快的,而内存的访问时间相当慢。在所有的指令中,访存指令(如lw,sw)的执行时间往往是最长的,为了提高效率,人们设计出了Cache这一结构(这是后话)。当然,由于时钟周期是不变的,单周期CPU的效率是很低的,现如今多采用流水线CPU。

CPU运行机制(简化)

​ CPU中的程序计数器(Program Counter)——PC存储着指令地址,通过这些地址,获得指令寄存器(Instruction Register)中对应的指令。指令通过译码器,得到控制各个逻辑单元的控制信号。一般而言,部分编码信号及数据在算术逻辑单元(Arithmetic and Logic Unit)进行运算,运算的结果或成为最终的结果写回CPU寄存器,或成为与内存进行交换时的地址和数据。若指令对内存进行访问,写操作时,ALU结果写入内存中;读操作时,将内存中对应地址的数据写回CPU寄存器。上述操作即为单周期CPU在一个时钟周期内的相关操作。下一个时钟周期,PC+4,获得新的指令地址,执行下一条指令。

实现

​ 将所有操作大致分为取地址、取指令、译码、运算、访存及写回六个阶段。

​ 顶层模块展示:

顶层模块.png

取地址

​ 在MIPS中,指令的入口为\(12288_{(10)}\),亦即\(3000_{16}\)。当前Address+4即为下一条指令的地址。我们需要:当下一个时钟上升沿到来时,PC+4;当(异步)复位信号——Reset到来时,PC恢复至0x3000的状态。考虑到要实现的指令中有条件跳转指令(beq)及无条件跳转指令(j、jal、jr),因此,PC结构的输入是多样的,同时我们需要一个地址选择信号PCSrc(PCSource)。jal指令将PC+4写入$31号寄存器,执行jr指令时将$31号寄存器的内容作为新的PC。

PC.png

​ 此处无PCSrc,而是对Branch信号和Jump信号译码,实现对地址的选择。

取指令

​ 此处的ROM最多存储32条指令,故需要五位的二进制数才能对所有指令进行选择。而之所以选择2-6位的数据,是因为此处为PC+4,PC的低两位(二进制)恒为00。

译码

​ MIPS中,一条指令为32位的二进制数,其组成有如下几种情况:

OP(31-26) RS(25-21) RT(20-16) RD(15-11) shamt(10-6) Func(5-0)
OP(31-26) RS(25-21) RT(20-16) Imm16(15-0)
OP(31-26) base(25-21) RT(20-16) imm16(15-0)
OP(31-26) instr_index(25-0)

​ 指令经过分线器后,RD、RS及RT被传至GRF作为源寄存器和目的寄存器的地址,而OP和Func传至控制单元进行译码,imm16和imm26被传至其他逻辑单元。

​ 控制信号与指令间的关系如下:

ADDU SUBU OR LUI ANDI BEQ J JAL JR LB/LH/LW SB/SH/SW
RegDst 1 1 1 0 0 x x 2 x 0 x
RegWrite 1 1 1 1 1 x x 1 x 1 x
ALUSrc 0 0 0 1 1 0 0 0 0 1 1
ALUOP 0 1 2 3 4 1 x x x 0 0
MemWrite x x x x x x x x x 0 1
MemToReg 0 0 0 0 0 0 0 0 0 1 0
EXTOP x x x 0 0 x x x x 1 1

​ 其中对于‘x’和'0'的判定见仁见智。

​ 除此之外,为了实现LB/LH/LW及SB/SH/SW指令,还需要添加控制位宽的信号。

控制单元.png

运算

​ 运算阶段没有太多要说明的地方,需要注意的是ALUOP控制信号和多选器输入间的关系,具体的对应情况由个人决定。此处BEQ指令引入了ZERO信号,目的是与Branch信号一同作用判断是否需要跳转。

逻辑运算单元.png

访存

读指令

​ 读取的数据的位宽受BWidth信号控制,而具体选择哪部分的数据受地址的低1/2位影响。

写指令

​ 其具体机制与读指令类似,但稍显复杂。由于logisim的特性,我们需要先将给定地址的数据读取出来,然后用\(GPR[RT]_{x:0}\)代替指定字段的内容,再写入。

内存.png

写回

​ RegWrite信号控制是否将数据写回CPU寄存器中(事实上,在此ALU结果和内存数据一直都有存在,所以需要由RegWrite决定是否写回)。而MemToReg信号决定写回的数据是ALU结果还是内存数据。

一些话

不保证图示的正确性,仅供参考。

posted @ 2022-05-20 23:43  轻轻一跃  阅读(221)  评论(0)    收藏  举报