补全B型指令
比较立即数和 寄存器中的数
INST_BNE,INST_BEQ,INST_BLT,INST_BGE,INST_BLTU,INST_BGEU
BEQ为相等跳转,BNE为不等跳转。
BLT 产生分支小于
BGE 产生分支大于
BLTU 立即数当无符号
BGEU 立即数当有符号
其中I型指令主要是将寄存器中的数据和生成的立即数进行运算,最终将结果存入寄存器中。
单周期CPU顾名思义就是一个指令周期内只执行一条指令的CPU。
ISA
R I S U四种基本指令格式。
基于立即数处理,还有额外两种指令格式变种(SB/UJ)。
补全J型指令 JALR 指令
该指令无条件跳转到一个绝对地址。实际上,j 指令跳转到的地址并不是直接指定32位的地址。由于目的地址的最高4位无法在指令的编码中给出,32位地址的最高4位取值当前PC的最高4位。对于一般的程序而言,28位地址所支持的256MB跳转空间已经足够大了。
jal:转移到新的指令地址,新指令地址与指令j相同。指令jal还要将跳转指令后面指令的地址作为返回地址保存到寄存器$31
jalr:将地址为rs的通用寄存器的值赋值给寄存器pc,作为新的指令地址,同时将跳转指令后面指令的地址作为返回地址保存在地址为rd的通用寄存器,如果没有在指令中指明rd,那么默认将返回地址保存到$31
rs1_addr_o = 5'b0;
rs2_addr_o = 5'b0;
op1_o = {inst_i[31:12],12'b0};
op2_o = inst_addr_i;
rd_addr_o = rd;
reg_wen = 1'b1;
end
AUIPC: 回写寄存器
将立即数左移12位,和PC值相加。
LUI和AUIPC
lui将指令的20位立即数左移12位,得到一个32位数,将此数写回寄存器rd中。
AUIPC将20位立即数作为12位,将此数与PC值相加写回寄存器rd中。
优化 复用模块
复用加法器 移位 与 或 计算地址单元等,造成资源浪费。
添加ALU运算部分。
EX模块中
//ALU
wire[31:0] op1_i_add_op2_i;
wire[31:0] op1_i_and_op2_i;
wire[31:0] op1_i_xor_op2_i;
wire[31:0] op1_i_or_op2_i;
wire[31:0] op1_i_shift_letf_op2_i;
wire[31:0] op1_i_shift_right_op2_i;
wire[31:0] base_addr_add_addr_offset;
assign op1_i_add_op2_i = op1_i + op2_i; // 加法器
assign op1_i_and_op2_i = op1_i & op2_i; // 与
assign op1_i_xor_op2_i = op1_i ^ op2_i; // 异或
assign op1_i_or_op2_i = op1_i | op2_i; // 或
assign op1_i_shift_letf_op2_i = op1_i << op2_i; // 左移
assign op1_i_shift_right_op2_i = op1_i >> op2_i; // 右移
assign base_addr_add_addr_offset = base_addr_i + addr_offset_i; // 计算地址单元
地址计算: 地址输入+跳转地址(偏移地址)