ISA 扩展:sltiu、bge/bgeu、mulh/mulhsu/mulhu(并回归 xor/sll/srl/sra/bltu/mul)
cpu21_riscv_alu.v
- 新增 ALU_MULH(4'd13)、ALU_MULHSU(4'd14):用 64 位有符号乘积
mult_ss = $signed(a)*$signed(b)、mult_su = $signed(a)*$signed({32'b0,b})
取高 32 位;mulhu 复用 ALU_MUL 的 result2(无符号乘积高 32 位),
与课程约定的 remu 共用 wb_sel=3 通道,因此 ALU 操作码仍为 4 位。
cpu21_riscv_decoder.v
- OP_I 新增 funct3=011 -> sltiu(立即数符号扩展后无符号比较);
- OP_R 的 funct7=0000001 分支改为完整 M 扩展译码:
000=mul、001=mulh、010=mulhsu、011=mulhu,并保留 111=remu(wb_sel=3);
- OP_BRANCH 新增 funct3=101(bge)、111(bgeu),新增 bge_o/bgeu_o 输出,
ALU_OP 仍按比较类型给出 SLT/SLTU/SUB。
cpu21_riscv_branch_unit.v
- 新增 bge_i、bgeu_i;把四种比较预计算成短 wire(有符号 <、>= 与无符号 <、>=)
再组合出 branch_taken,顺带修掉之前被自动换行拆散的 $signed 表达式。
cpu21_riscv_redirect_int_bpb.v
- 新增 d_bge/d_bgeu 连线与 idex_bge_q/idex_bgeu_q 流水寄存器(含复位与捕获);
- IF 级 f_is_branch 纳入 funct3=101/111,使 bge/bgeu 也参与 BPB 预测。
说明文档
- 功能列表与编码表补充 sltiu、bge/bgeu 与 M 扩展乘法。
验证(xsim + tb_no_intr;测试程序由临时小汇编器生成,共 24 项 LED 输出逐项比对)
- sltiu:1 <u 0xffffffff = 00000001;0xffffffff <u 1 = 00000000
- xor:0xff ^ 0xffffffff = ffffff00
- sll:1 << 31 = 80000000;srl:0xffffffff >> 28 = 0000000f;sra:同左 = ffffffff
- mul:1234*567 = 000aad1e;mulh:(-1)*(-1) 高 = 00000000
mulhu:0xffffffff^2 高 = fffffffe;mulhsu:(-1)*2 高 = ffffffff
- bltu:0 <u 0xffffffff 成立(取跳转分支);bge:(-1) >= 0 不成立(走 fall-through);
bgeu:0xffffffff >=u 0 成立
- bge / bgeu / bltu 三个循环计数正确(fffffffd..00000000 / 3..1 / 4..1),最后 halt 停机
(143 周期,halted=1)
- 回归:中断测试程序 6003 周期统计与改动前逐项一致
(stalls=11 bubbles=297 cond_taken=648 pred_ok=663 pred_fail=102,
IRQ1@cyc85、IRQ2@cyc266、IRQ3@cyc447);
benchmark 的 BLT 段落仍连续输出 fffffff1..ffffffff,
60000 周期统计与改动前完全一致(stalls=3195 bubbles=6955 cond_taken=8857
pred_ok=9455 pred_fail=1050)。
This commit is contained in:
+34
-13
@@ -29,7 +29,9 @@ module cpu21_riscv_decoder (
|
||||
output reg beq_o,
|
||||
output reg bne_o,
|
||||
output reg blt_o,
|
||||
output reg bge_o,
|
||||
output reg bltu_o,
|
||||
output reg bgeu_o,
|
||||
output reg jal_o,
|
||||
output reg jalr_o,
|
||||
output reg ecall_o,
|
||||
@@ -62,6 +64,8 @@ module cpu21_riscv_decoder (
|
||||
localparam ALU_XOR = 4'd9;
|
||||
localparam ALU_SLT = 4'd11;
|
||||
localparam ALU_SLTU = 4'd12;
|
||||
localparam ALU_MULH = 4'd13;
|
||||
localparam ALU_MULHSU = 4'd14;
|
||||
localparam ALU_PASSB = 4'd15; // LUI:直接输出 B 端(立即数)
|
||||
|
||||
wire [4:0] opcode = ir_i[6:2];
|
||||
@@ -90,7 +94,9 @@ module cpu21_riscv_decoder (
|
||||
beq_o = 1'b0;
|
||||
bne_o = 1'b0;
|
||||
blt_o = 1'b0;
|
||||
bge_o = 1'b0;
|
||||
bltu_o = 1'b0;
|
||||
bgeu_o = 1'b0;
|
||||
jal_o = 1'b0;
|
||||
jalr_o = 1'b0;
|
||||
ecall_o = 1'b0;
|
||||
@@ -105,13 +111,23 @@ module cpu21_riscv_decoder (
|
||||
uses_rs1_o = 1'b1;
|
||||
uses_rs2_o = 1'b1;
|
||||
reg_write_o = 1'b1;
|
||||
// 电路中额外的 REMU 控制对应标准 R 型的 funct7=1/funct3=111
|
||||
// 形式;此时 ALU 的 result2 即为余数。
|
||||
if ((funct7 == 7'b0000001) && (funct3 == 3'b111)) begin
|
||||
alu_op_o = ALU_DIVU;
|
||||
wb_sel_o = 3'd3;
|
||||
end else if ((funct7 == 7'b0000001) && (funct3 == 3'b000)) begin
|
||||
alu_op_o = ALU_MUL;
|
||||
// M 扩展(funct7=0000001):mul/mulh/mulhsu/mulhu,外加课程约定的 remu
|
||||
// (funct3=111 形式)。mulhu 与 remu 都取 ALU 的 result2(wb_sel=3)。
|
||||
if (funct7 == 7'b0000001) begin
|
||||
case (funct3)
|
||||
3'b000: alu_op_o = ALU_MUL; // mul:无符号乘积低 32 位
|
||||
3'b001: alu_op_o = ALU_MULH; // mulh:有符号乘积高 32 位
|
||||
3'b010: alu_op_o = ALU_MULHSU; // mulhsu:有符号 x 无符号高 32 位
|
||||
3'b011: begin // mulhu:无符号乘积高 32 位
|
||||
alu_op_o = ALU_MUL;
|
||||
wb_sel_o = 3'd3;
|
||||
end
|
||||
3'b111: begin // remu(课程约定):取余数
|
||||
alu_op_o = ALU_DIVU;
|
||||
wb_sel_o = 3'd3;
|
||||
end
|
||||
default: reg_write_o = 1'b0;
|
||||
endcase
|
||||
end else begin
|
||||
// 标准 R 型 funct3 译码;add/sub 与 sra/srl 由 funct7[5] 区分。
|
||||
case (funct3)
|
||||
@@ -128,7 +144,7 @@ module cpu21_riscv_decoder (
|
||||
end
|
||||
end
|
||||
|
||||
// I 型运算(addi/slli/slti/xori/srai/srli/ori/andi)。
|
||||
// I 型运算(addi/slli/slti/sltiu/xori/srai/srli/ori/andi)。
|
||||
OP_I: begin
|
||||
uses_rs1_o = 1'b1;
|
||||
alu_src_o = 1'b1;
|
||||
@@ -137,6 +153,7 @@ module cpu21_riscv_decoder (
|
||||
3'b000: alu_op_o = ALU_ADD; // addi:立即数加
|
||||
3'b001: alu_op_o = ALU_SLL; // slli:立即数逻辑左移
|
||||
3'b010: alu_op_o = ALU_SLT; // slti:有符号小于置 1
|
||||
3'b011: alu_op_o = ALU_SLTU; // sltiu:无符号小于置 1(立即数符号扩展)
|
||||
3'b100: alu_op_o = ALU_XOR; // xori:立即数异或
|
||||
3'b101:
|
||||
alu_op_o = (funct7[5] ? ALU_SRA : ALU_SRL); // srai/srli:立即数算术/逻辑右移
|
||||
@@ -181,19 +198,23 @@ module cpu21_riscv_decoder (
|
||||
end
|
||||
end
|
||||
|
||||
// 条件分支:beq(000)/bne(001)/blt(100,有符号小于)/bltu(110,无符号小于)。
|
||||
// 条件分支:beq(000)/bne(001)/blt(100)/bge(101)/bltu(110)/bgeu(111)。
|
||||
OP_BRANCH: begin
|
||||
if ((funct3 == 3'b000) || (funct3 == 3'b001) ||
|
||||
(funct3 == 3'b100) || (funct3 == 3'b110)) begin
|
||||
if ((funct3 == 3'b000) || (funct3 == 3'b001) || (funct3 == 3'b100) ||
|
||||
(funct3 == 3'b101) || (funct3 == 3'b110) || (funct3 == 3'b111)) begin
|
||||
uses_rs1_o = 1'b1;
|
||||
uses_rs2_o = 1'b1;
|
||||
branch_o = 1'b1;
|
||||
beq_o = (funct3 == 3'b000);
|
||||
bne_o = (funct3 == 3'b001);
|
||||
blt_o = (funct3 == 3'b100);
|
||||
bge_o = (funct3 == 3'b101);
|
||||
bltu_o = (funct3 == 3'b110);
|
||||
// 真值表:beq/bne 用减法比较,blt 用 ALU_SLT,bltu 用 ALU_SLTU。
|
||||
alu_op_o = blt_o ? ALU_SLT : (bltu_o ? ALU_SLTU : ALU_SUB);
|
||||
bgeu_o = (funct3 == 3'b111);
|
||||
// 有符号比较用 ALU_SLT、无符号比较用 ALU_SLTU,相等/不等用减法;
|
||||
// 分支是否成立由 EX 级的分支裁决单元决定,这里只与真值表保持一致。
|
||||
alu_op_o = (blt_o || bge_o) ? ALU_SLT :
|
||||
((bltu_o || bgeu_o) ? ALU_SLTU : ALU_SUB);
|
||||
imm_o = {{19{ir_i[31]}}, ir_i[31], ir_i[7], ir_i[30:25], ir_i[11:8], 1'b0};
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user