From 5db04653b603a924404f1d4340e9ee2309410800 Mon Sep 17 00:00:00 2001 From: davide schiavone Date: Mon, 23 Feb 2026 15:05:06 +0100 Subject: [PATCH 1/5] add 3rd port for cv-x-if --- rtl/cve2_core.sv | 13 ++++++++++++- rtl/cve2_decoder.sv | 5 +++++ rtl/cve2_id_stage.sv | 16 ++++++++++++++-- rtl/cve2_pkg.sv | 2 +- rtl/cve2_register_file_ff.sv | 7 ++++++- 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/rtl/cve2_core.sv b/rtl/cve2_core.sv index 253eca38ad..fdb873e397 100644 --- a/rtl/cve2_core.sv +++ b/rtl/cve2_core.sv @@ -177,8 +177,13 @@ module cve2_core import cve2_pkg::*; #( logic [31:0] rf_rdata_a; logic [4:0] rf_raddr_b; logic [31:0] rf_rdata_b; + logic [4:0] rf_raddr_c; + logic [31:0] rf_rdata_c; logic rf_ren_a; logic rf_ren_b; + // verilator lint_off UNUSED + logic rf_ren_c; + // verilator lint_on UNUSED logic [4:0] rf_waddr_wb; logic [31:0] rf_wdata_wb; // Writeback register write data that can be used on the forwarding path (doesn't factor in memory @@ -506,8 +511,11 @@ module cve2_core import cve2_pkg::*; #( .rf_rdata_a_i (rf_rdata_a), .rf_raddr_b_o (rf_raddr_b), .rf_rdata_b_i (rf_rdata_b), + .rf_raddr_c_o (rf_raddr_c), + .rf_rdata_c_i (rf_rdata_c), .rf_ren_a_o (rf_ren_a), .rf_ren_b_o (rf_ren_b), + .rf_ren_c_o (rf_ren_c), .rf_waddr_id_o (rf_waddr_id), .rf_wdata_id_o (rf_wdata_id), .rf_we_id_o (rf_we_id), @@ -691,7 +699,8 @@ module cve2_core import cve2_pkg::*; #( cve2_register_file_ff #( .RV32E (RV32E), .DataWidth (32), - .WordZeroVal (32'h0) + .WordZeroVal (32'h0), + .XInterface (XInterface) ) register_file_i ( .clk_i (clk_i), .rst_ni(rst_ni), @@ -702,6 +711,8 @@ module cve2_core import cve2_pkg::*; #( .rdata_a_o(rf_rdata_a), .raddr_b_i(rf_raddr_b), .rdata_b_o(rf_rdata_b), + .raddr_c_i(rf_raddr_c), + .rdata_c_o(rf_rdata_c), .waddr_a_i(rf_waddr_wb), .wdata_a_i(rf_wdata_wb), .we_a_i (rf_we_wb) diff --git a/rtl/cve2_decoder.sv b/rtl/cve2_decoder.sv index 9efad2b46f..6a9e929ebd 100644 --- a/rtl/cve2_decoder.sv +++ b/rtl/cve2_decoder.sv @@ -56,9 +56,11 @@ module cve2_decoder #( output logic rf_we_o, // write enable for regfile output logic [4:0] rf_raddr_a_o, output logic [4:0] rf_raddr_b_o, + output logic [4:0] rf_raddr_c_o, output logic [4:0] rf_waddr_o, output logic rf_ren_a_o, // Instruction reads from RF addr A output logic rf_ren_b_o, // Instruction reads from RF addr B + output logic rf_ren_c_o, // Instruction reads from RF addr C (if X-IF if used) // ALU output cve2_pkg::alu_op_e alu_operator_o, // ALU operation selection @@ -168,6 +170,7 @@ module cve2_decoder #( assign instr_rs3 = instr[31:27]; assign rf_raddr_a_o = (use_rs3_q & ~instr_first_cycle_i) ? instr_rs3 : instr_rs1; // rs3 / rs1 assign rf_raddr_b_o = instr_rs2; // rs2 + assign rf_raddr_c_o = XInterface ? instr_rs3 : '0; // destination register assign instr_rd = instr[11:7]; @@ -214,6 +217,7 @@ module cve2_decoder #( rf_we = 1'b0; rf_ren_a_o = 1'b0; rf_ren_b_o = 1'b0; + rf_ren_c_o = 1'b0; csr_access_o = 1'b0; csr_illegal = 1'b0; @@ -662,6 +666,7 @@ module cve2_decoder #( if(XInterface) begin rf_ren_a_o = x_issue_resp_register_read_i[0]; rf_ren_b_o = x_issue_resp_register_read_i[1]; + rf_ren_c_o = x_issue_resp_register_read_i[2]; rf_wdata_sel_o = $bits(rf_wdata_sel_o)'({RF_WD_COPROC}); end end diff --git a/rtl/cve2_id_stage.sv b/rtl/cve2_id_stage.sv index 9fef525d00..1f39bf19d5 100644 --- a/rtl/cve2_id_stage.sv +++ b/rtl/cve2_id_stage.sv @@ -153,8 +153,11 @@ module cve2_id_stage #( input logic [31:0] rf_rdata_a_i, output logic [4:0] rf_raddr_b_o, input logic [31:0] rf_rdata_b_i, + output logic [4:0] rf_raddr_c_o, + input logic [31:0] rf_rdata_c_i, output logic rf_ren_a_o, output logic rf_ren_b_o, + output logic rf_ren_c_o, // Register file write (via writeback) output logic [4:0] rf_waddr_id_o, @@ -220,18 +223,21 @@ module cve2_id_stage #( logic [XInterface:0] rf_wdata_sel; logic rf_we_dec, rf_we_raw; - logic rf_ren_a, rf_ren_b; - logic rf_ren_a_dec, rf_ren_b_dec; + logic rf_ren_a, rf_ren_b, rf_ren_c; + logic rf_ren_a_dec, rf_ren_b_dec, rf_ren_c_dec; // Read enables should only be asserted for valid and legal instructions assign rf_ren_a = instr_valid_i & ~instr_fetch_err_i & ~illegal_insn_o & rf_ren_a_dec; assign rf_ren_b = instr_valid_i & ~instr_fetch_err_i & ~illegal_insn_o & rf_ren_b_dec; + assign rf_ren_c = instr_valid_i & ~instr_fetch_err_i & ~illegal_insn_o & rf_ren_c_dec; assign rf_ren_a_o = rf_ren_a; assign rf_ren_b_o = rf_ren_b; + assign rf_ren_c_o = XInterface ? rf_ren_c : '0; logic [31:0] rf_rdata_a_fwd; logic [31:0] rf_rdata_b_fwd; + logic [31:0] rf_rdata_c_fwd; // ALU Control alu_op_e alu_operator; @@ -352,6 +358,7 @@ module cve2_id_stage #( // Register Interface assign x_register_o.rs[0] = rf_rdata_a_fwd; assign x_register_o.rs[1] = rf_rdata_b_fwd; + assign x_register_o.rs[2] = rf_rdata_c_fwd; assign x_register_o.rs_valid = '1; assign x_register_o.id = x_instr_id_q; assign x_register_o.hartid = hart_id_i; @@ -372,8 +379,10 @@ module cve2_id_stage #( logic unused_x_result_valid; x_result_t unused_x_result; logic unused_coproc_done; + logic [31:0] unused_rf_rdata_c_fwd; assign unused_coproc_done = coproc_done; + assign unused_rf_rdata_c_fwd = rf_rdata_c_fwd; assign multicycle_done = lsu_req_dec ? lsu_resp_valid_i : ex_valid_i; assign scoreboard_busy = 1'b0; @@ -532,9 +541,11 @@ module cve2_id_stage #( .rf_raddr_a_o(rf_raddr_a_o), .rf_raddr_b_o(rf_raddr_b_o), + .rf_raddr_c_o(rf_raddr_c_o), .rf_waddr_o (rf_waddr_id_o), .rf_ren_a_o (rf_ren_a_dec), .rf_ren_b_o (rf_ren_b_dec), + .rf_ren_c_o (rf_ren_c_dec), // ALU .alu_operator_o (alu_operator), @@ -919,6 +930,7 @@ module cve2_id_stage #( // register file assign rf_rdata_a_fwd = rf_rdata_a_i; assign rf_rdata_b_fwd = rf_rdata_b_i; + assign rf_rdata_c_fwd = rf_rdata_c_i; // Unused Writeback stage only IO & wiring // Assign inputs and internal wiring to unused signals to satisfy lint checks diff --git a/rtl/cve2_pkg.sv b/rtl/cve2_pkg.sv index 50377e74a0..8db480348d 100644 --- a/rtl/cve2_pkg.sv +++ b/rtl/cve2_pkg.sv @@ -657,7 +657,7 @@ package cve2_pkg; } rvfi_csr_t; // CV-X-IF - parameter int unsigned X_NUM_RS = 2; + parameter int unsigned X_NUM_RS = 3; parameter int unsigned X_ID_WIDTH = 4; parameter int unsigned X_RFR_WIDTH = 32; parameter int unsigned X_RFW_WIDTH = 32; diff --git a/rtl/cve2_register_file_ff.sv b/rtl/cve2_register_file_ff.sv index de45f8f50c..1d51eb95e1 100644 --- a/rtl/cve2_register_file_ff.sv +++ b/rtl/cve2_register_file_ff.sv @@ -14,7 +14,8 @@ module cve2_register_file_ff #( parameter bit RV32E = 0, parameter int unsigned DataWidth = 32, - parameter logic [DataWidth-1:0] WordZeroVal = '0 + parameter logic [DataWidth-1:0] WordZeroVal = '0, + parameter bit XInterface = 1'b0 ) ( // Clock and Reset input logic clk_i, @@ -30,6 +31,9 @@ module cve2_register_file_ff #( input logic [4:0] raddr_b_i, output logic [DataWidth-1:0] rdata_b_o, + //Read port R3 -- Only when using the X-iF + input logic [4:0] raddr_c_i, + output logic [DataWidth-1:0] rdata_c_o, // Write port W1 input logic [4:0] waddr_a_i, @@ -69,6 +73,7 @@ module cve2_register_file_ff #( assign rdata_a_o = rf_reg[raddr_a_i]; assign rdata_b_o = rf_reg[raddr_b_i]; + assign rdata_c_o = XInterface ? rf_reg[raddr_c_i] : '0; // Signal not used in FF register file logic unused_test_en; From fd1af885a72f4dfcff74e1023f30561281997704 Mon Sep 17 00:00:00 2001 From: Cairo Caplan Date: Mon, 9 Mar 2026 20:43:42 +0100 Subject: [PATCH 2/5] [verilator] Add waiver to control signals that Verilator warns of 'circular combinational logic', but that are expected. --- lint/verilator_waiver.vlt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lint/verilator_waiver.vlt b/lint/verilator_waiver.vlt index e690729235..3fffd0c8c0 100644 --- a/lint/verilator_waiver.vlt +++ b/lint/verilator_waiver.vlt @@ -26,6 +26,18 @@ lint_off -rule PINCONNECTEMPTY lint_off -rule WIDTH -file "*/rtl/cve2_top_tracing.sv" -match "*expects 1 bits*Initial value's CONST '32'h1'*" +// Similar to ibex's #2355, Verilator since v5.042+ has a more +// agressive UNOPTFLAT, emitting circular combinational logic warnings +// that are expected, as the signals value do converge +lint_off -rule UNOPTFLAT -file "*/rtl/cve2_core.sv" + -match "*id_in_ready*" +lint_off -rule UNOPTFLAT -file "*/rtl/cve2_id_stage.sv" + -match "*instr_executing_spec*" +lint_off -rule UNOPTFLAT -file "*/rtl/cve2_controller.sv" + -match "*special_req*" +lint_off -rule UNOPTFLAT -file "*/rtl/cve2_controller.sv" + -match "*id_in_ready_o*" + // Operator expects 1 bit on initial value but initial value's CONST generates // 32 bits, need a specific RV32B waiver as it uses enums so the above catch-all // waiver doesn't work. From 674dafb1464864fc78e155f2131cc918e388bfc8 Mon Sep 17 00:00:00 2001 From: davide schiavone Date: Tue, 10 Mar 2026 08:56:51 +0100 Subject: [PATCH 3/5] remove verilator in code --- lint/verilator_waiver.vlt | 4 ++++ rtl/cve2_core.sv | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lint/verilator_waiver.vlt b/lint/verilator_waiver.vlt index e690729235..3d66d7c46a 100644 --- a/lint/verilator_waiver.vlt +++ b/lint/verilator_waiver.vlt @@ -73,3 +73,7 @@ lint_off -rule UNUSED -file "*/rtl/cve2_top_tracing.sv" -match "*RndCnstLfsrPerm lint_off -rule UNOPTFLAT -file "*/rtl/cve2_core.sv" -match "Signal unoptimizable: Feedback to clock or circular logic: 'cve2_top.u_cve2_core.irqs'" lint_off -rule UNUSED -file "*/rtl/cve2_wb.sv" -match "Signal is not used: 'clk_i'*" lint_off -rule UNUSED -file "*/rtl/cve2_wb.sv" -match "Signal is not used: 'rst_ni'*" + +lint_off -rule UNOPTFLAT -file "*/rtl/cve2_id_stage.sv" -match "Signal unoptimizable: Circular combinational logic:*" +lint_off -rule UNOPTFLAT -file "*/rtl/cve2_controller.sv" -match "Signal unoptimizable: Circular combinational logic:*" +lint_off -rule UNOPTFLAT -file "*/rtl/cve2_core.sv" -match "Signal unoptimizable: Circular combinational logic:*" diff --git a/rtl/cve2_core.sv b/rtl/cve2_core.sv index fdb873e397..abec8709c0 100644 --- a/rtl/cve2_core.sv +++ b/rtl/cve2_core.sv @@ -181,9 +181,7 @@ module cve2_core import cve2_pkg::*; #( logic [31:0] rf_rdata_c; logic rf_ren_a; logic rf_ren_b; - // verilator lint_off UNUSED logic rf_ren_c; - // verilator lint_on UNUSED logic [4:0] rf_waddr_wb; logic [31:0] rf_wdata_wb; // Writeback register write data that can be used on the forwarding path (doesn't factor in memory From 37743c1e71592845a6be11ed8092c92871194738 Mon Sep 17 00:00:00 2001 From: davide schiavone Date: Tue, 10 Mar 2026 08:58:21 +0100 Subject: [PATCH 4/5] Revert "remove verilator in code" This reverts commit 674dafb1464864fc78e155f2131cc918e388bfc8. --- lint/verilator_waiver.vlt | 4 ---- rtl/cve2_core.sv | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/lint/verilator_waiver.vlt b/lint/verilator_waiver.vlt index 3d66d7c46a..e690729235 100644 --- a/lint/verilator_waiver.vlt +++ b/lint/verilator_waiver.vlt @@ -73,7 +73,3 @@ lint_off -rule UNUSED -file "*/rtl/cve2_top_tracing.sv" -match "*RndCnstLfsrPerm lint_off -rule UNOPTFLAT -file "*/rtl/cve2_core.sv" -match "Signal unoptimizable: Feedback to clock or circular logic: 'cve2_top.u_cve2_core.irqs'" lint_off -rule UNUSED -file "*/rtl/cve2_wb.sv" -match "Signal is not used: 'clk_i'*" lint_off -rule UNUSED -file "*/rtl/cve2_wb.sv" -match "Signal is not used: 'rst_ni'*" - -lint_off -rule UNOPTFLAT -file "*/rtl/cve2_id_stage.sv" -match "Signal unoptimizable: Circular combinational logic:*" -lint_off -rule UNOPTFLAT -file "*/rtl/cve2_controller.sv" -match "Signal unoptimizable: Circular combinational logic:*" -lint_off -rule UNOPTFLAT -file "*/rtl/cve2_core.sv" -match "Signal unoptimizable: Circular combinational logic:*" diff --git a/rtl/cve2_core.sv b/rtl/cve2_core.sv index abec8709c0..fdb873e397 100644 --- a/rtl/cve2_core.sv +++ b/rtl/cve2_core.sv @@ -181,7 +181,9 @@ module cve2_core import cve2_pkg::*; #( logic [31:0] rf_rdata_c; logic rf_ren_a; logic rf_ren_b; + // verilator lint_off UNUSED logic rf_ren_c; + // verilator lint_on UNUSED logic [4:0] rf_waddr_wb; logic [31:0] rf_wdata_wb; // Writeback register write data that can be used on the forwarding path (doesn't factor in memory From a91796a28d987f96f8e1d1a085848416c7be750b Mon Sep 17 00:00:00 2001 From: davide schiavone Date: Tue, 10 Mar 2026 09:01:25 +0100 Subject: [PATCH 5/5] remove last lint off --- rtl/cve2_core.sv | 2 -- 1 file changed, 2 deletions(-) diff --git a/rtl/cve2_core.sv b/rtl/cve2_core.sv index fdb873e397..abec8709c0 100644 --- a/rtl/cve2_core.sv +++ b/rtl/cve2_core.sv @@ -181,9 +181,7 @@ module cve2_core import cve2_pkg::*; #( logic [31:0] rf_rdata_c; logic rf_ren_a; logic rf_ren_b; - // verilator lint_off UNUSED logic rf_ren_c; - // verilator lint_on UNUSED logic [4:0] rf_waddr_wb; logic [31:0] rf_wdata_wb; // Writeback register write data that can be used on the forwarding path (doesn't factor in memory