增加简单控制单元
ALU控制线:
0000 AND
0001 OR
0010 add
0110 subtract
对于不同的指令类型,ALU需执行以上功能中的一种。 对于load和store指令,ALU做加法计算存储器地址。对于R型指令的7位funct7字段 和3位funct3字段,ALU需要执行四种操作中的一种。
对于条件分支指令,ALU将两个操作数做减法检测结果是否为0.
4位ALU输入控制信号可由小型控制单元产生,输入位funct7和funct3以及两位的ALUOp操作码字段。ALUOp知名需要操作的时load和store指令要做的加法,还是beq指令要做的减法并检测是否为0,或者由funct和funct3字段决定。
该控制单元输出4位信号,来控制ALU。
操作码 -- 区分R型指令和分支指令 和R型指令
funct7和funct3字段来区分R型指令,不同指令。
多级译码方式 - ---主控制单元生成ALUOp作用ALU的输入控制信号,再生成实际信号控制ALU是一种常见的方式。 多级控制减小主控制单元的规模。多个小的控制单元可能潜在地减小控制单元的延迟。
只有少数funct字段有意义,且仅在ALUOp信号等于10才使用funct字段,因此可以使用一个小逻辑单元来识别可能的取值并生成恰当的控制信号。
funct字段和ALUOp组成一张真值表,来设计这个逻辑单元。
设计主控制单元
RISCV指令格式遵循以下规则:
操作码字段总是0-6位。根据操作码,funct3字段和funct7字段作为扩展的操作码字段。
对于R型指令和分支指令,第一个寄存器操作数一直是15-19位。对于R型和分支指令,第二个寄存器操作数始终是20-24位。
对于分支指令,载入指令和存储指令,另一个操作数可以是12位立即数。
I型载入指令,寄存器rs1是基址寄存器,它与12位立即数字段相加得到存储器地址。rd是目标寄存器。 它存放从存储器中取出的值。
S型存储指令,寄存器rs1是基址寄存器,与12位立即数相加得到存储器读地址,字段rs2为源寄存器,它的值存入存储器。
SB条件分支指令,寄存器rs1和rs2比较。将12位立即数地址字段进行符号位扩展,再u左移一位,与PC相加得到分支目标地址。
数据通路操作
add x1,x2,x3
1 取出指令,PC自增
2 从寄存器堆读出两个寄存器x2,x3.同时主控制单元在此步骤计算控制信号。
3 根据部分操作码确定ALU的功能,对从寄存器读出的数据进行操作。
4 将ALU的结果写入寄存器堆中的目标寄存器。
load指令的执行,ld x1 offset(x2)
将load指令划分为5个步骤:
1 从指令存储器取出指令,PC自增
2 从寄存器堆读出寄存器rs1的值
3 ALU将寄存器堆读出的值与符号位扩展后的指令中的12位偏移量相加
4 将ALU结果用作存储器的地址
5 将存储器读出的数据写入寄存器堆 rd
beq 分支指令,beq x1,x2,offset。 与R型指令相似,但ALU的结果被用来确定PC由PC+4还是分支目标地址写入。
1 从指令存储器取出指令,PC自增。
2 从寄存器中读出两个寄存器x1,x2.
3 ALU将从寄存器堆读出的两数相减。 PC与左移一位。符号位扩展的指令的12位相加,得到分支目标地址。
4 ALU的零输出据欸的那个将哪个加法器的结果写入PC。
控制的结束
为什么不使用单周期实现。因为在单周期设计中时钟周期对于每条指令必须等长。这样处理器最长的路径决定了时钟周期,这条路径可能是一条load指令。它连续使用五个功能单元,指令存储器,寄存器堆,ALU,数据存储器和寄存器堆。虽然CPI为1,但由于时钟周期太长,单周期实现的整体性可能很差。