diff --git a/dv/dv/tb_x0_protection.sv b/dv/dv/tb_x0_protection.sv new file mode 100644 index 000000000..3d2f92914 --- /dev/null +++ b/dv/dv/tb_x0_protection.sv @@ -0,0 +1,33 @@ +module tb_x0_protection; + + logic [4:0] rf_waddr_o; + logic rf_we; + logic illegal_reg_rv32e; + logic rf_we_o; + + assign rf_we_o = rf_we & ~illegal_reg_rv32e & (rf_waddr_o != 5'd0); + + initial begin + $display("Testing x0 protection..."); + + rf_we = 1'b1; + illegal_reg_rv32e = 1'b0; + + // x0 write + rf_waddr_o = 5'd0; + #1; + if (rf_we_o !== 0) + $error("FAIL: x0 write not blocked"); + + // ✅ valid write + rf_waddr_o = 5'd5; + #1; + if (rf_we_o !== 1) + $error("FAIL: valid write blocked"); + + $display("✅ PASS: x0 protection works"); + + $finish; + end + +endmodule \ No newline at end of file diff --git a/rtl/ibex_decoder.sv b/rtl/ibex_decoder.sv index 843eb05f0..6d85b71b4 100644 --- a/rtl/ibex_decoder.sv +++ b/rtl/ibex_decoder.sv @@ -1197,7 +1197,7 @@ module ibex_decoder #( assign illegal_insn_o = illegal_insn | illegal_reg_rv32e; // do not propagate regfile write enable if non-available registers are accessed in RV32E - assign rf_we_o = rf_we & ~illegal_reg_rv32e; + assign rf_we_o = rf_we & ~illegal_reg_rv32e & (rf_waddr_o != 5'd0) ; // Not all bits are used assign unused_instr_alu = {instr_alu[19:15],instr_alu[11:7]};