RISC-V 译码级设计
RISC-V 译码级设计
RISCV ID Stage 各个功能部件设计
压缩指令译码(compress decoder)
用于将压缩指令恢复成 32 bits 的正常指令,再送往 decoder 进行译码,压缩指令详细说明见压缩指令
译码控制(Decoder)
输入接口
Name Source Description instruction[31:0] IR 待译码的指令 输出接口
Name Target Description immType[2:0] EU 立即数类型 rs1[4:0] RF register source1 index rs2[4:0] RF register source2 index branchType[2:0] SBP, ID/EXE pipeline 分支类型 rd[4:0] ID/EXE pipeline register destination index aluOp[4:0] ID/EXE pipeline ALU 执行的操作 dMemWriteEn ID/EXE pipeline ALU 执行的操作 dMemType[3:0] ID/EXE pipeline ALU 执行的操作 regWBEn ID/EXE pipeline 写使能 regWBSrc[1:0] ID/EXE pipeline 一直传递到 WB stage,用于选择写回的数据来源 模块功能
Decoder 对输入的指令进行译码,生成流水线上其它模块的控制信号
根据 instruction 的 opcode, funct3 和 funct7 得到指令的类型:opcode -> funct3 -> funct7
opcode=instr[6:2], funct3=instr[14:12], funct7=instr[30]
opcode 一共 7bits,其中低 2bits 恒为 11,只有高 5bits 不同
\(opcode_{[6:0]}\) Instruction Opcode Type Instruction Amount Relative Instructions 0000011 OPCODE_LOAD 5 LB, BH, LW, LBU, LHU 0010011 OPCODE_OP_IMM 9 ADDI, SLTI, SLTIU, XORI, ORI, ANDI, SLLI, SRLI, SRAI 0010111 OPCODE_AUIPC 1 AUIPC 0100011 OPCODE_STORE 3 SB, SH, SW 0110011 OPCODE_RTYPE 18 ADD, SUB, SLT, SLTU, XOR, OR, AND, SLL, SRL, SRA, MUL, MULH, MULHSU, MULHU, DIV, DIVU, REM, REMU 0110111 OPCODE_LUI 1 LUI 1100011 OPCODE_BRANCH 6 BEQ, BNE, BLT, BGE, BLTU, BGEU 1100111 OPCODE_JALR 1 JALR 1101111 OPCODE_JAL 1 JAL 由指令类型得到 immType, branchType, aluOp, dMemType, dMemWriteEn, regWBEn, regWBSrc
immType:
immType Amount Instruction opcode IMM_U 2 OPCODE_LUI, OPCODE_AUIPC IMM_J 1 OPCODE_JAL IMM_I 15 OPCODE_OP_IMM, OPCODE_LOAD, OPCODE_JALR IMM_B 6 OPCODE_BRANCH IMM_S 3 OPCODE_STORE IMM_NO 18 OPCODE_RTYPE dMemType, dMemWriteEn
Instructions opcode funct3 dMemType dMemWriteEn 01000 000
001
010MEM_SB
MEM_SH
MEM_SW1 00000 000
001
010
100
101MEM_LH
MEM_LB
MEM_LW
MEM_LBU
MEM_LHU0 others xxx MEM_NO 0 regWBEn
regWBEn Amount Instruction opcode 0 9 01000, 11000 1 36 others regWBSrc
regWBSrc Amount Instruction opcode WBSrc_aluResult 37 others WBSrc_dMemReadData 5 00000 WBSrc_extendedImm 1 01101 WBSrc_pcPlus4 2 11001, 11011 branchType
- branchBType: OPCODE_BRANCH
- branchJAL: OPCODE_JAL
- branchJALR: OPCODE_JALR
aluOp
Instruction Opcode Type funct3(funct7) Relative Instructions aluOp OPCODE_LOAD 000
001
010
100
101LB
BH
LW
LBU
LHUALUOP_ADD OPCODE_OP_IMM 000
010
011
100
110
111
001
101(0)
101(1)ADDI
SLTI
SLTIU
XORI
ORI
ANDI
SLLI
SRLI
SRAIALUOP_ADD
ALUOP_SLT
ALUOP_SLTU
ALUOP_XOR
ALUOP_OR
ALUOP_AND
ALUOP_SLL
ALUOP_SRL
ALUOP_SRAOPCODE_AUIPC rs1=pcAUIPC ALUOP_ADD OPCODE_STORE 000
001
010SB
SH
SWALUOP_ADD OPCODE_RTYPE(instr[25]==0)
rd2=register file000(0)
000(1)
001
010
011
100
101(0)
101(1)
110
111ADD
SUB
SLL
SLT
SLTU
XOR
SRL
SRA
OR
ANDALUOP_ADD
ALUOP_SUB
ALUOP_SLL
ALUOP_SLT
ALUOP_SLTU
ALUOP_XOR
ALUOP_SRL
ALUOP_SRA
ALUOP_OR
ALUOP_ANDOPCODE_RTYPE(instr[25]==1)
rd2=register file000
001
010
011
100
101
110
111MUL
MULH
MULHSU
MULHU
DIV
DIVU
REM
REMUALUOP_MUL
ALUOP_MULH
ALUOP_MULHSU
ALUOP_MULHU
ALUOP_DIV
ALUOP_DIVU
ALUOP_REM
ALUOP_REMUOPCODE_LUI LUI ALUOP_ADD OPCODE_BRANCH rs2=register file000
001
100
101
110
111BEQ
BNE
BLT
BGE
BLTU
BGEUALUOP_SUB
ALUOP_SUB
ALUOP_SLT
ALUOP_SLT
ALUOP_SLTU
ALUOP_SLTUOPCODE_JALR JALR ALUOP_ADD OPCODE_JAL JAL ALUOP_ADD JAL, JALR, Branch 设计到的计算部件
跳转预测 跳转确认 跳转 PC 计算 pc=pc+4 JAL SBP 不需要确认 SBP IF->ID->EXE JALR SBP 不需要确认 PC=alu_result & ~1 IF->ID->EXE Branch SBP ALU 确认跳转方向 SBP IF->ID->EXE - JAL 指令: SBP 可以 100%预测其跳转的方向和 PC,ALU 不需要做额外的计算
- JALR 指令: 当 rd 为 x0、x1 或者是没有数据依赖时,SBP 可以 100%判断跳转方向和 PC;若 rd 存在数据依赖,则 SBP 知道 JALR 跳转,但是不会判断它跳转,也不会计算目的 PC,需要由 ALU 计算跳转的 PC 和判断跳转,发送给 IF。
- Branch 指令: SBP 不可以 100%预测跳转方向,但是可以 100%计算出重定向 PC,需要 ALU 判断跳转方向是否正确
根据 instruction 得到 rs1, rs2 和 rd:
rs2=instr[24:20], rs1=[19:15], rd=instr[11:7]
静态分支预测 SBP(Static Branch Predictor)
RF(register File)异步读出、同步写入
静态分支预测 SBP(static branch prediction)
JAL: SBP 预测taken=1,且pc=pc+offset,ID 需要输出 flush 信号来清楚 prefetch 的 2 条指令,具体表现为设置 IF/ID, ID/EXE pipeline register flush=1b-type: 采取 BTFN(backward taken, forward not taken), 且pc=pc+offsetJALR: 分情况讨论- 如果 rs1 是 x0,或者 rs1 没有数据依赖:SBP
预测
taken=1,且pc=(rd+offset)&~1 - 如果 rs1 有数据依赖:SBP 预测
taken=0
- 如果 rs1 是 x0,或者 rs1 没有数据依赖:SBP
预测
bypass: ID 级根据 Hazard 的信号,在需要 bypass 的时候,选择合适的 bypass 信号取代 RF 里读出去的运算数
输入接口
Name Source Description PC[31:0] IF/ID pipeline 用于计算重定向 PC rs1[31:0] 4x1 Mux 用于计算重定向 PC offset[31:0] EU 用于计算重定向 PC branchType[2:0] Decoder branchType[0]==1 -> JALbranchType[1]==1 -> JALRbranchType[2]==1 -> B-Type输出接口
Name Target Description RPC[31:0] IF Stage Redirection PC taken IF Stage, ID/EXE pipeline 预测跳转是否发生, ALU 会计算实际跳转是否发生并且与此预测结果比较 模块功能
若 decoder 译码之后判断指令是分支指令,则 SBP 需要根据静态分支预测的规则,生成重定向 PC,发送给 IF 级。SBP 具体做了如下两个任务:
判断是否需要跳转 prediction
- JAL, JALR:
taken=1 - B-TYpe: forward not taken, backward taken, 根据 offset 正负号来判断,
taken=offset[31]
- JAL, JALR:
计算跳转的方向 calculation
- JAL, B-Type:
RPC=PC+offset - JALR:
RPC=(rs1+offset) & 0xfffffffe
- JAL, B-Type:
** 在计算 JARL 指令的新的 pc 地址的时候,需要访问寄存器,但是寄存器的值可能会跟前面的指令存在数据依赖,此时有两种方法**来解决:
- 利用 bypass 来结局数据依赖问题之后,再在 SBP 中计算目的 pc,该方法可能会导致 ID 关键路径太长
- 仅在 rs1=x0, x1 的时候计算 JALR 的目的 pc,其余情况下若存在数据依赖,则预判 JALR 不跳转,在 EXE 中计算正确的目的 pc
前者 JALR 指令预测准确率 100%,但是 ID 级关键路径长;后者 JALR 指令预测率稍低但是 ID 关键路径短
RF(Register File)
输入接口
Name Source Description rs1[4:0] Decoder register source1 index rs2[4:0] Decoder register source2 index rd[4:0] WB pipeline register destination index regWBData[31:0] WB pipeline 待写回到 RF 的数据 regWBEn WB pipeline 写使能 输出接口
Name Target Description rs1 4x1 Mux 从 RF 中读出的操作数 1 RD2 4x1 Mux 从 RF 中读出的操作数 2 模块功能
RF 支持在任意时刻读出数据,它有两个读端口,一个写端口(写数据的时候必须在 clk 上升沿且写使能)
立即数扩展单元 EU(Extending Unit)
输入接口
Name Source Description instruction[31:0] IF/ID pipeline 取值得到的 32bits 指令 immType[2:0] Decoder 立即数种类| 输出接口
Name Target Description imm[31:0] SBP, ID/EXE pipeline 32bits 的立即数,送给 SBP 和下一级流水线 模块功能
该模块是纯组合电路,其根据输入的 immType 字段从 instruction 中摘取对应字段生成 32bits 的扩展立即数
- IMM_U:
imm_o={instr_i[31:12], 12'h000}; - IMM_J:
imm_o={{11{instr_i[31]}}, instr_i[31], instr_i[19:12], instr_i[20], instr_i[30:21], 1'b0}; - IMM_I:
imm_o={{20{instr_i[31]}}, instr_i[31:20]}; - IMM_B:
imm_o={{19{instr_i[31]}}, instr_i[31], instr_i[7], instr_i[30:25], instr_i[11:8], 1'b0}; - IMM_S:
imm_o={{20{instr_i[31]}}, instr_i[31:25], instr_i[11:7]}; - IMM_NO: no immediate ==>
imm_o = 32'h00000000;
- IMM_U:
4x1 Mux
- 输入接口
1 | | Name | Source | Description | |