diff --git a/hw/vendor/esl_epfl_cv32e40px.lock.hjson b/hw/vendor/esl_epfl_cv32e40px.lock.hjson index 39f77e7ab..7248758f0 100644 --- a/hw/vendor/esl_epfl_cv32e40px.lock.hjson +++ b/hw/vendor/esl_epfl_cv32e40px.lock.hjson @@ -9,6 +9,6 @@ upstream: { url: https://github.com/esl-epfl/cv32e40px.git - rev: acf3442b414725191fb7a2027facd0b5b4123c1c + rev: 49770e7dd5d569f440810866f4f33ce6a4f7ef1f } } diff --git a/hw/vendor/esl_epfl_cv32e40px.vendor.hjson b/hw/vendor/esl_epfl_cv32e40px.vendor.hjson index b261db045..547959fe2 100644 --- a/hw/vendor/esl_epfl_cv32e40px.vendor.hjson +++ b/hw/vendor/esl_epfl_cv32e40px.vendor.hjson @@ -7,11 +7,9 @@ upstream: { url: "https://github.com/esl-epfl/cv32e40px.git", - rev: "acf3442b414725191fb7a2027facd0b5b4123c1c", + rev: "49770e7dd5d569f440810866f4f33ce6a4f7ef1f", }, - patch_dir: "patches/esl_epfl_cv32e40px", - exclude_from_upstream: [ "ci", ".github", diff --git a/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_instr_trace.svh b/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_instr_trace.svh index 8c4ae99f3..a89ed4e45 100644 --- a/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_instr_trace.svh +++ b/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_instr_trace.svh @@ -679,22 +679,22 @@ class instr_trace_t; // decode and print instruction case (instr[11:8]) // cv.starti, cv.endi - 4'b0000, 4'b0010: str = $sformatf("%-16s %d, 0x%0x", mnemonic, rd[0], imm_iz_type); + 4'b0000, 4'b0010: str = $sformatf("%-16s %d, 0x%0x", mnemonic, instr[7], imm_iz_type); // cv.counti - 4'b0100: str = $sformatf("%-16s %d, %d", mnemonic, rd[0], imm_iz_type); + 4'b0100: str = $sformatf("%-16s %d, %d", mnemonic, instr[7], imm_iz_type); // cv.start, cv.end, cv.count 4'b0001, 4'b0011, 4'b0101: begin regs_read.push_back('{rs1, rs1_value, 0}); - str = $sformatf("%-16s %d, %s", mnemonic, rd[0], regAddrToStr(rs1)); + str = $sformatf("%-16s %d, %s", mnemonic, instr[7], regAddrToStr(rs1)); end // cv.setupi 4'b0110: begin - str = $sformatf("%-16s %d, %d, 0x%0x", mnemonic, rd[0], imm_iz_type, rs1); + str = $sformatf("%-16s %d, %d, 0x%0x", mnemonic, instr[7], imm_iz_type, rs1); end // cv.setup 4'b0111: begin regs_read.push_back('{rs1, rs1_value, 0}); - str = $sformatf("%-16s %d, %s, 0x%0x", mnemonic, rd[0], regAddrToStr(rs1), imm_iz_type); + str = $sformatf("%-16s %d, %s, 0x%0x", mnemonic, instr[7], regAddrToStr(rs1), imm_iz_type); end endcase end @@ -861,7 +861,7 @@ class instr_trace_t; endcase str_sci = ""; end - + // shuffle/pack 6'b110000: begin if (instr[14:12] == 3'b111) begin diff --git a/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_rvfi.sv b/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_rvfi.sv index 868de33c9..4effb2b86 100644 --- a/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_rvfi.sv +++ b/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_rvfi.sv @@ -73,6 +73,10 @@ module cv32e40px_rvfi input logic is_compressed_id_i, input logic ebrk_insn_dec_i, + input logic ecall_insn_dec_i, + + input logic mret_insn_dec_i, + input logic mret_dec_i, input logic [5:0] csr_cause_i, @@ -126,6 +130,9 @@ module cv32e40px_rvfi input logic [31:0] data_wdata_ex_i, input logic lsu_split_q_ex_i, + input logic mult_ready_i, + input logic alu_ready_i, + //// WB probes //// input logic [31:0] pc_wb_i, input logic wb_ready_i, @@ -202,6 +209,7 @@ module cv32e40px_rvfi input logic csr_we_i, input logic [31:0] csr_wdata_int_i, + input logic csr_fregs_we_i, input logic csr_jvt_we_i, input Status_t csr_mstatus_n_i, input Status_t csr_mstatus_q_i, @@ -617,6 +625,8 @@ module cv32e40px_rvfi logic pc_mux_interrupt; logic pc_mux_nmi; + localparam logic [31:0] MSTATUS_WRITE_MASK = 32'h0000_6088; + `include "pipe_freeze_trace.sv" `include "insn_trace.sv" @@ -633,6 +643,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; logic [2:0] saved_debug_cause; integer next_send; + event e_empty_queue; function void empty_fifo(); integer i, trace_q_size; trace_q_size = wb_bypass_trace_q.size(); @@ -648,6 +659,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; new_rvfi_trace.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; rvfi_trace_q.push_back(new_rvfi_trace); next_send = next_send + 1; + ->e_empty_queue; end else begin wb_bypass_trace_q.push_back(new_rvfi_trace); end @@ -658,6 +670,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; /* * Function used to alocate a new insn and send it to the rvfi driver */ + event e_add_to_bypass; function void send_rvfi(insn_trace_t m_wb_insn); insn_trace_t new_rvfi_trace; new_rvfi_trace = new(); @@ -667,6 +680,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; next_send = next_send + 1; end else begin wb_bypass_trace_q.push_back(new_rvfi_trace); + ->e_add_to_bypass; end empty_fifo(); endfunction @@ -837,7 +851,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; //CSR rvfi_csr_mstatus_rmask = new_rvfi_trace.m_csr.mstatus_rmask | new_rvfi_trace.m_csr.mstatus_fs_rmask; - rvfi_csr_mstatus_wmask = new_rvfi_trace.m_csr.mstatus_wmask; + rvfi_csr_mstatus_wmask = new_rvfi_trace.m_csr.mstatus_wmask & MSTATUS_WRITE_MASK; rvfi_csr_mstatus_wmask[31] = new_rvfi_trace.m_csr.mstatus_fs_wmask[31]; rvfi_csr_mstatus_wmask[14:13] = new_rvfi_trace.m_csr.mstatus_fs_wmask[14:13]; @@ -870,7 +884,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end rvfi_csr_mstatus_wdata[30:18] = '0; // MPRV is not implemented in the target configuration, writes to it are ignored - rvfi_csr_mstatus_wdata[17] = 1'b0;//new_rvfi_trace.m_csr.mstatus_wdata.mprv; + rvfi_csr_mstatus_wdata[17] = 1'b0; //new_rvfi_trace.m_csr.mstatus_wdata.mprv; rvfi_csr_mstatus_wdata[16:15] = '0; if (FPU == 1 && ZFINX == 0) begin rvfi_csr_mstatus_wdata[14:13] = new_rvfi_trace.m_csr.mstatus_fs_wdata; @@ -882,11 +896,11 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; rvfi_csr_mstatus_wdata[7] = new_rvfi_trace.m_csr.mstatus_wdata.mpie; rvfi_csr_mstatus_wdata[6:5] = '0; // UPIE is not implemented in the target configuration, writes to it are ignored - rvfi_csr_mstatus_wdata[4] = 1'b0;//new_rvfi_trace.m_csr.mstatus_wdata.upie; + rvfi_csr_mstatus_wdata[4] = 1'b0; //new_rvfi_trace.m_csr.mstatus_wdata.upie; rvfi_csr_mstatus_wdata[3] = new_rvfi_trace.m_csr.mstatus_wdata.mie; rvfi_csr_mstatus_wdata[2:1] = '0; // UIE is not implemented in the target configuration, writes to it are ignored - rvfi_csr_mstatus_wdata[0] = 1'b0;//new_rvfi_trace.m_csr.mstatus_wdata.uie; + rvfi_csr_mstatus_wdata[0] = 1'b0; //new_rvfi_trace.m_csr.mstatus_wdata.uie; `SET_RVFI_CSR_FROM_INSN(misa) `SET_RVFI_CSR_FROM_INSN(mie) @@ -1111,6 +1125,9 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; * The third updates the rvfi interface */ `define CSR_FROM_PIPE(TRACE_NAME, CSR_NAME) \ + if(!trace_``TRACE_NAME``.m_csr.``CSR_NAME``_we) begin \ + trace_``TRACE_NAME``.m_csr.``CSR_NAME``_wdata = r_pipe_freeze_trace.csr.``CSR_NAME``_n; \ + end\ if (r_pipe_freeze_trace.csr.``CSR_NAME``_we) begin \ trace_``TRACE_NAME``.m_csr.``CSR_NAME``_we = r_pipe_freeze_trace.csr.``CSR_NAME``_we; \ trace_``TRACE_NAME``.m_csr.``CSR_NAME``_wdata = r_pipe_freeze_trace.csr.``CSR_NAME``_n; \ @@ -1120,9 +1137,14 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_``TRACE_NAME``.m_csr.``CSR_NAME``_rmask = '1; event e_mstatus_to_id; + event e_fregs_dirty_1, e_fregs_dirty_2, e_fregs_dirty_3; function void mstatus_to_id(); `CSR_FROM_PIPE(id, mstatus) `CSR_FROM_PIPE(id, mstatus_fs) + if(r_pipe_freeze_trace.csr.fregs_we && !r_pipe_freeze_trace.csr.mstatus_fs_we && !(r_pipe_freeze_trace.csr.we && r_pipe_freeze_trace.csr.mstatus_fs_we)) begin //writes happening in ex that needs to be reported to id + trace_id.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; + ->e_fregs_dirty_2; + end ->e_mstatus_to_id; endfunction //those event are for debug purpose @@ -1133,10 +1155,11 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; e_dev_commit_rf_to_ex_3, e_dev_commit_rf_to_ex_4, e_dev_commit_rf_to_ex_5; - event e_if_2_id_1, e_if_2_id_2; + event e_if_2_id_1, e_if_2_id_2, e_if_2_id_3; event e_ex_to_wb_1, e_ex_to_wb_2; event e_id_to_ex_1, e_id_to_ex_2; event e_commit_dpc; + event e_csr_in_ex, e_csr_irq; event e_send_rvfi_trace_apu_resp; event @@ -1160,12 +1183,17 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; `CSR_FROM_PIPE(apu_resp, fcsr) `CSR_FROM_PIPE(apu_resp, fflags) - // `CSR_FROM_PIPE(apu_resp, mstatus) `CSR_FROM_PIPE(apu_resp, mstatus_fs) - if (r_pipe_freeze_trace.csr.mstatus_we) begin + if (r_pipe_freeze_trace.csr.mstatus_fs_we && (trace_id.m_order > trace_apu_resp.m_order)) begin + trace_id.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; + end + if (r_pipe_freeze_trace.csr.mstatus_fs_we && (trace_ex.m_order > trace_apu_resp.m_order)) begin trace_ex.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; end + if (r_pipe_freeze_trace.csr.mstatus_fs_we && (trace_wb.m_order > trace_apu_resp.m_order)) begin + trace_wb.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; + end endfunction function void csr_to_apu_req(); @@ -1243,6 +1271,15 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; bit s_is_irq_start; bit s_id_done; function void if_to_id(); + if (trace_id.m_valid) begin + minstret_to_id(); + `CSR_FROM_PIPE(id, misa) + `CSR_FROM_PIPE(id, tdata1) + `CSR_FROM_PIPE(id, tdata2) + tinfo_to_id(); + `CSR_FROM_PIPE(id, mip) + send_rvfi(trace_id); + end trace_id.init(trace_if); trace_id.m_trap = ~r_pipe_freeze_trace.minstret; trace_id.m_is_illegal = r_pipe_freeze_trace.is_illegal; @@ -1280,34 +1317,40 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; bit s_core_is_decoding; // For readability, ctrl_fsm is DECODE or DECODE_HWLOOP - trace_if = new(); - trace_id = new(); - trace_ex = new(); - trace_wb = new(); - s_new_valid_insn = 1'b0; - s_ex_valid_adjusted = 1'b0; + bit s_ex_reg_we_adjusted; //ex_reg_we + bit s_rf_we_wb_adjusted; // + + trace_if = new(); + trace_id = new(); + trace_ex = new(); + trace_wb = new(); + s_new_valid_insn = 1'b0; + s_ex_valid_adjusted = 1'b0; - s_id_done = 1'b0; - s_apu_wb_ok = 1'b0; - s_apu_0_cycle_reps = 1'b0; + s_id_done = 1'b0; + s_apu_wb_ok = 1'b0; + s_apu_0_cycle_reps = 1'b0; - next_send = 1; - cnt_data_req = 0; - cnt_data_resp = 0; - cnt_apu_req = 0; - cnt_apu_resp = 0; - csr_is_irq = '0; - is_dbg_taken = '0; - s_was_flush = 1'b0; + next_send = 1; + cnt_data_req = 0; + cnt_data_resp = 0; + cnt_apu_req = 0; + cnt_apu_resp = 0; + csr_is_irq = '0; + is_dbg_taken = '0; + s_was_flush = 1'b0; - s_is_pc_set = 1'b0; - s_is_irq_start = 1'b0; + s_is_pc_set = 1'b0; + s_is_irq_start = 1'b0; - s_is_pc_set = 1'b0; - s_is_irq_start = 1'b0; - s_skip_wb = 1'b0; + s_is_pc_set = 1'b0; + s_is_irq_start = 1'b0; + s_skip_wb = 1'b0; - s_core_is_decoding = 1'b0; + s_core_is_decoding = 1'b0; + + s_ex_reg_we_adjusted = 1'b0; + s_rf_we_wb_adjusted = 1'b0; forever begin wait(e_pipe_monitor_ok.triggered); // event triggered @@ -1387,7 +1430,9 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; s_new_valid_insn = r_pipe_freeze_trace.id_valid && r_pipe_freeze_trace.is_decoding;// && !r_pipe_freeze_trace.apu_rvalid; - s_wb_valid_adjusted = r_pipe_freeze_trace.wb_valid && (s_core_is_decoding || (r_pipe_freeze_trace.ctrl_fsm_cs == FLUSH_EX));// && !r_pipe_freeze_trace.apu_rvalid;; + s_wb_valid_adjusted = r_pipe_freeze_trace.wb_valid && (s_core_is_decoding || (r_pipe_freeze_trace.ctrl_fsm_cs == FLUSH_EX) || (r_pipe_freeze_trace.ctrl_fsm_cs == FLUSH_WB) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_FLUSH) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_ID) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_IF));// && !r_pipe_freeze_trace.apu_rvalid;; + s_ex_reg_we_adjusted = r_pipe_freeze_trace.ex_reg_we && r_pipe_freeze_trace.mult_ready && r_pipe_freeze_trace.alu_ready && r_pipe_freeze_trace.lsu_ready_ex && !s_apu_to_alu_port; + s_rf_we_wb_adjusted = r_pipe_freeze_trace.rf_we_wb && (~r_pipe_freeze_trace.data_misaligned_ex && r_pipe_freeze_trace.wb_ready) && (!s_apu_to_lsu_port || r_pipe_freeze_trace.wb_contention_lsu); s_fflags_we_non_apu = 1'b0; if (r_pipe_freeze_trace.csr.fflags_we) begin @@ -1418,40 +1463,34 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; s_skip_wb = 1'b1; end end - if (trace_wb.m_valid && !s_skip_wb) begin - if (r_pipe_freeze_trace.rf_we_wb) begin - if((trace_wb.m_rd_addr[0] == r_pipe_freeze_trace.rf_addr_wb) && (cnt_data_resp == trace_wb.m_mem_req_id[0]) && trace_wb.m_mem_req_id_valid[0]) begin - trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; - trace_wb.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; - trace_wb.m_mem_req_id_valid[0] = 1'b0; - end else if (trace_wb.m_2_rd_insn && (trace_wb.m_rd_addr[1] == r_pipe_freeze_trace.rf_addr_wb) && (cnt_data_resp == trace_wb.m_mem_req_id[1]) && trace_wb.m_mem_req_id_valid[1]) begin - trace_wb.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; - trace_wb.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; - trace_wb.m_mem_req_id_valid[1] = 1'b0; - end - end - if (!trace_wb.m_data_missaligned) begin - send_rvfi(trace_wb); - ->e_dev_send_wb_1; ->e_send_rvfi_trace_wb_2; - trace_wb.m_valid = 1'b0; + if (trace_wb.m_valid && !s_skip_wb && s_rf_we_wb_adjusted) begin + if (trace_wb.m_2_rd_insn) begin + trace_wb.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + trace_wb.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; + end else if (trace_wb.m_ex_fw) begin + trace_wb.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + trace_wb.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; + trace_wb.m_2_rd_insn = 1'b1; end else begin - if (s_wb_valid_adjusted) begin - if (r_pipe_freeze_trace.rf_we_wb) begin - if (!trace_wb.m_ex_fw) begin - trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; - trace_wb.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; - end - if (trace_wb.m_data_missaligned && !trace_wb.m_got_first_data) begin - trace_wb.m_got_first_data = 1'b1; - end else begin - send_rvfi(trace_wb); - ->e_dev_send_wb_2; ->e_send_rvfi_trace_wb_3; - trace_wb.m_valid = 1'b0; - end - end // rf_we_wb + trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; + trace_wb.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; + end + + if (r_pipe_freeze_trace.csr.fregs_we) begin + `CSR_FROM_PIPE(wb, mstatus_fs) + trace_wb.m_csr.mstatus_fs_we = 1'b1; + trace_wb.m_csr.mstatus_fs_wmask = '1; + if(r_pipe_freeze_trace.csr.we && r_pipe_freeze_trace.csr.mstatus_fs_we) begin //In this specific case, two writes to mstatus_fs happen at the same time. We need to recreate the writes caused by fregs_we + trace_wb.m_csr.mstatus_fs_wdata = FS_DIRTY; end + ->e_fregs_dirty_1; end + + send_rvfi(trace_wb); + ->e_dev_send_wb_1; ->e_send_rvfi_trace_wb_2; + trace_wb.m_valid = 1'b0; + end if (trace_ex.m_valid) begin @@ -1464,14 +1503,14 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; `CSR_FROM_PIPE(ex, tdata2) tinfo_to_ex(); - if (r_pipe_freeze_trace.regfile_we_lsu) begin + if (s_rf_we_wb_adjusted) begin ->e_dev_commit_rf_to_ex_4; - if ((cnt_data_resp == trace_ex.m_mem_req_id[0]) && !(trace_ex.m_got_ex_reg) && trace_ex.m_mem_req_id_valid[0]) begin + if (!(trace_ex.m_got_ex_reg) && trace_ex.m_mem_req_id_valid[0]) begin trace_ex.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; trace_ex.m_got_first_data = 1'b1; trace_ex.m_mem_req_id_valid[0] = 1'b0; - end else if ((cnt_data_resp == trace_ex.m_mem_req_id[1]) && trace_ex.m_mem_req_id_valid[1]) begin + end else if (trace_ex.m_mem_req_id_valid[1]) begin trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; trace_ex.m_got_first_data = 1'b1; @@ -1485,7 +1524,11 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_ex.m_valid = 1'b0; ->e_send_rvfi_trace_ex_2; end else begin - if (r_pipe_freeze_trace.rf_we_wb && !s_apu_to_lsu_port) begin + if (!s_ex_valid_adjusted & !trace_ex.m_csr.got_minstret) begin + minstret_to_ex(); + end + + if (s_rf_we_wb_adjusted) begin ->e_dev_commit_rf_to_ex_1; if (trace_ex.m_got_ex_reg) begin trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; @@ -1497,24 +1540,35 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_ex.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; trace_ex.m_got_first_data = 1'b1; end - end - if (!s_ex_valid_adjusted & !trace_ex.m_csr.got_minstret) begin - minstret_to_ex(); - end - if (trace_ex.m_is_load) begin // only move relevant instr in wb stage - ->e_ex_to_wb_1; - trace_wb.move_down_pipe(trace_ex); - end else begin - if (!trace_ex.m_csr.got_minstret) begin - minstret_to_ex(); + if (r_pipe_freeze_trace.csr.fregs_we) begin + `CSR_FROM_PIPE(ex, mstatus_fs) + trace_ex.m_csr.mstatus_fs_we = 1'b1; + trace_ex.m_csr.mstatus_fs_wmask = '1; + if(r_pipe_freeze_trace.csr.we && r_pipe_freeze_trace.csr.mstatus_fs_we) begin //In this specific case, two writes to mstatus_fs happen at the same time. We need to recreate the writes caused by fregs_we + trace_ex.m_csr.mstatus_fs_wdata = FS_DIRTY; + end + ->e_fregs_dirty_3; end + send_rvfi(trace_ex); - ->e_send_rvfi_trace_ex_6; + trace_ex.m_valid = 1'b0; + + end else begin + if (trace_ex.m_is_load) begin // only move relevant instr in wb stage + ->e_ex_to_wb_1; + trace_wb.move_down_pipe(trace_ex); + end else begin + if (!trace_ex.m_csr.got_minstret) begin + minstret_to_ex(); + end + send_rvfi(trace_ex); + ->e_send_rvfi_trace_ex_6; + end + trace_ex.m_valid = 1'b0; end - trace_ex.m_valid = 1'b0; end - end else if (r_pipe_freeze_trace.rf_we_wb && !s_apu_to_lsu_port && !s_was_flush) begin + end else if (s_rf_we_wb_adjusted && !s_was_flush) begin ->e_dev_commit_rf_to_ex_2; if (trace_ex.m_got_ex_reg) begin trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; @@ -1529,22 +1583,29 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end end - s_ex_valid_adjusted = (r_pipe_freeze_trace.ex_valid && r_pipe_freeze_trace.ex_ready) && (s_core_is_decoding || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_IF)) && (!r_pipe_freeze_trace.apu_rvalid || r_pipe_freeze_trace.data_req_ex); + // If mret, we need to keep the instruction in Id during flush_ex because mstatus update happens at that time + s_ex_valid_adjusted = (r_pipe_freeze_trace.ex_valid && r_pipe_freeze_trace.ex_ready) && (s_core_is_decoding || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_IF) || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_FLUSH) || ((r_pipe_freeze_trace.ctrl_fsm_cs == FLUSH_EX) && !r_pipe_freeze_trace.mret_insn_dec)) && (!r_pipe_freeze_trace.apu_rvalid || r_pipe_freeze_trace.data_req_ex); //EX_STAGE if (trace_id.m_valid) begin + + if(trace_id.m_sample_csr_write_in_ex && !csr_is_irq && !s_is_irq_start) begin //First cycle after id_ready, csr write is asserted in this cycle + `CSR_FROM_PIPE(id, mstatus) + `CSR_FROM_PIPE(id, mstatus_fs) + `CSR_FROM_PIPE(id, mepc) + `CSR_FROM_PIPE(id, mcause) + `CSR_FROM_PIPE(id, dscratch0) + `CSR_FROM_PIPE(id, dscratch1) + ->e_csr_in_ex; + end + + if(r_pipe_freeze_trace.is_decoding) begin + trace_id.m_sample_csr_write_in_ex = 1'b0; + end mtvec_to_id(); `CSR_FROM_PIPE(id, mip) `CSR_FROM_PIPE(id, misa) - if (!csr_is_irq && !s_is_irq_start) begin - mstatus_to_id(); - `CSR_FROM_PIPE(id, mepc) - if (trace_id.m_csr.mcause_we == '0) begin //for debug purpose - `CSR_FROM_PIPE(id, mcause) - end - end - `CSR_FROM_PIPE(id, mcountinhibit) `CSR_FROM_PIPE(id, mscratch) `CSR_FROM_PIPE(id, mie) @@ -1603,10 +1664,10 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_id.m_rd_addr[0] = r_pipe_freeze_trace.ex_reg_addr; trace_id.m_rd_wdata[0] = r_pipe_freeze_trace.ex_reg_wdata; trace_id.m_got_ex_reg = 1'b1; - end else if (!trace_ex.m_valid & r_pipe_freeze_trace.rf_we_wb & !trace_id.m_ex_fw) begin + end else if (!trace_ex.m_valid & s_rf_we_wb_adjusted & !trace_id.m_ex_fw) begin trace_id.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_id.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; - end else if (r_pipe_freeze_trace.rf_we_wb) begin + end else if (s_rf_we_wb_adjusted) begin trace_id.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; trace_id.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; trace_id.m_2_rd_insn = 1'b1; @@ -1621,19 +1682,16 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_id.m_mem.addr = r_pipe_freeze_trace.data_addr_pmp; if (r_pipe_freeze_trace.data_misaligned) begin cnt_data_req = cnt_data_req + 1; + trace_id.m_mem_req_id[0] = cnt_data_req; end + if (!r_pipe_freeze_trace.data_we_ex) begin trace_id.m_is_load = 1'b1; trace_id.m_mem.wmask = be_to_mask(r_pipe_freeze_trace.lsu_data_be); //'1; - if (r_pipe_freeze_trace.data_misaligned) begin - trace_id.m_data_missaligned = 1'b1; - trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; - trace_id.m_mem_req_id[0] = cnt_data_req; - trace_id.m_mem_req_id_valid[1] = 1'b1; - end end else begin trace_id.m_mem.rmask = be_to_mask(r_pipe_freeze_trace.lsu_data_be); //'1; end + if (trace_id.m_got_ex_reg) begin // Shift index 0 to 1 trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; trace_id.m_mem_req_id[0] = 0; @@ -1692,15 +1750,10 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_id.m_mem.addr = r_pipe_freeze_trace.data_addr_pmp; if (r_pipe_freeze_trace.data_misaligned) begin cnt_data_req = cnt_data_req + 1; + trace_id.m_mem_req_id[0] = cnt_data_req; end if (!r_pipe_freeze_trace.data_we_ex) begin trace_id.m_is_load = 1'b1; - if (r_pipe_freeze_trace.data_misaligned) begin - trace_id.m_data_missaligned = 1'b1; - trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; - trace_id.m_mem_req_id[0] = cnt_data_req; - trace_id.m_mem_req_id_valid[1] = 1'b1; - end end if (trace_id.m_got_ex_reg) begin // Shift index 0 to 1 trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; @@ -1708,7 +1761,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; trace_id.m_mem_req_id_valid[0] = 1'b0; trace_id.m_mem_req_id_valid[1] = 1'b1; end - end else if (r_pipe_freeze_trace.rf_we_wb && !r_pipe_freeze_trace.ex_reg_we) begin + end else if (s_rf_we_wb_adjusted && !r_pipe_freeze_trace.ex_reg_we) begin trace_id.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_id.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; end @@ -1734,12 +1787,21 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; //IF_STAGE if (r_pipe_freeze_trace.if_valid && r_pipe_freeze_trace.if_ready) begin - if(trace_if.m_valid && r_pipe_freeze_trace.id_valid && r_pipe_freeze_trace.id_ready && !trace_id.m_valid && r_pipe_freeze_trace.ebrk_insn_dec) begin - if_to_id(); - trace_id.m_is_ebreak = '1; //trace_if.m_is_ebreak; - ->e_if_2_id_2; + if (trace_if.m_valid) begin + if (r_pipe_freeze_trace.id_valid && r_pipe_freeze_trace.id_ready && !trace_id.m_valid && r_pipe_freeze_trace.ebrk_insn_dec) begin + if_to_id(); + trace_id.m_is_ebreak = '1; //trace_if.m_is_ebreak; + ->e_if_2_id_2; + end else if (r_pipe_freeze_trace.is_illegal) begin + if_to_id(); + trace_id.m_is_illegal = 1'b1; + ->e_if_2_id_3; + end else if (r_pipe_freeze_trace.ecall_insn_dec) begin + if_to_id(); + end end + trace_if.m_insn = r_pipe_freeze_trace.instr_if; //Instr comes from if, buffer for one cycle trace_if.m_pc_rdata = r_pipe_freeze_trace.pc_if; trace_if.m_dbg_taken = is_dbg_taken; @@ -1754,6 +1816,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; mstatus_to_id(); `CSR_FROM_PIPE(id, mepc) `CSR_FROM_PIPE(id, mcause) + ->e_csr_irq; end if (!s_id_done && r_pipe_freeze_trace.is_decoding) begin diff --git a/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_tb_wrapper.sv b/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_tb_wrapper.sv index 1b40b80ed..d4aa94dcd 100644 --- a/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_tb_wrapper.sv +++ b/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_tb_wrapper.sv @@ -272,13 +272,19 @@ module cv32e40px_tb_wrapper .rs1_addr_id_i (cv32e40px_top_i.core_i.id_stage_i.regfile_addr_ra_id), .rs2_addr_id_i (cv32e40px_top_i.core_i.id_stage_i.regfile_addr_rb_id), + .rs3_addr_id_i (cv32e40px_top_i.core_i.id_stage_i.regfile_addr_rc_id), .operand_a_fw_id_i (cv32e40px_top_i.core_i.id_stage_i.operand_a_fw_id), .operand_b_fw_id_i (cv32e40px_top_i.core_i.id_stage_i.operand_b_fw_id), + .operand_c_fw_id_i (cv32e40px_top_i.core_i.id_stage_i.operand_c_fw_id), // .instr (cv32e40px_top_i.core_i.id_stage_i.instr ), .is_compressed_id_i(cv32e40px_top_i.core_i.id_stage_i.is_compressed_i), .ebrk_insn_dec_i (cv32e40px_top_i.core_i.id_stage_i.ebrk_insn_dec), - .csr_cause_i (cv32e40px_top_i.core_i.csr_cause), - .debug_csr_save_i (cv32e40px_top_i.core_i.debug_csr_save), + .ecall_insn_dec_i (cv32e40px_top_i.core_i.id_stage_i.ecall_insn_dec), + .mret_insn_dec_i (cv32e40px_top_i.core_i.id_stage_i.mret_insn_dec), + .mret_dec_i (cv32e40px_top_i.core_i.id_stage_i.mret_dec), + + .csr_cause_i (cv32e40px_top_i.core_i.csr_cause), + .debug_csr_save_i(cv32e40px_top_i.core_i.debug_csr_save), // HWLOOP regs .hwlp_start_q_i (hwlp_start_q), @@ -298,14 +304,16 @@ module cv32e40px_tb_wrapper .apu_multicycle_i (cv32e40px_top_i.core_i.ex_stage_i.apu_multicycle), .wb_contention_lsu_i(cv32e40px_top_i.core_i.ex_stage_i.wb_contention_lsu), .wb_contention_i (cv32e40px_top_i.core_i.ex_stage_i.wb_contention), - + .regfile_we_lsu_i (cv32e40px_top_i.core_i.ex_stage_i.regfile_we_lsu), // .rf_we_alu_i (cv32e40px_top_i.core_i.id_stage_i.regfile_alu_we_fw_i), // .rf_addr_alu_i (cv32e40px_top_i.core_i.id_stage_i.regfile_alu_waddr_fw_i), // .rf_wdata_alu_i (cv32e40px_top_i.core_i.id_stage_i.regfile_alu_wdata_fw_i), + .mult_ready_i (cv32e40px_top_i.core_i.ex_stage_i.mult_ready), + .alu_ready_i (cv32e40px_top_i.core_i.ex_stage_i.alu_ready), //// WB probes //// - .wb_valid_i(cv32e40px_top_i.core_i.wb_valid), - + .wb_valid_i (cv32e40px_top_i.core_i.wb_valid), + .wb_ready_i (cv32e40px_top_i.core_i.lsu_ready_wb), //// LSU probes //// .data_we_ex_i (cv32e40px_top_i.core_i.data_we_ex), .data_atop_ex_i (cv32e40px_top_i.core_i.data_atop_ex), @@ -325,6 +333,8 @@ module cv32e40px_tb_wrapper .lsu_ready_ex_i (cv32e40px_top_i.core_i.lsu_ready_ex), .lsu_ready_wb_i (cv32e40px_top_i.core_i.lsu_ready_wb), + .lsu_data_be_i(cv32e40px_top_i.core_i.load_store_unit_i.data_be), + .data_req_pmp_i(cv32e40px_top_i.core_i.data_req_pmp), .data_gnt_pmp_i(cv32e40px_top_i.core_i.data_gnt_pmp), .data_rvalid_i(cv32e40px_top_i.core_i.data_rvalid_i), @@ -339,11 +349,12 @@ module cv32e40px_tb_wrapper .rf_we_wb_i(cv32e40px_top_i.core_i.id_stage_i.regfile_we_wb_i), .rf_addr_wb_i(cv32e40px_top_i.core_i.id_stage_i.regfile_waddr_wb_i), .rf_wdata_wb_i(cv32e40px_top_i.core_i.id_stage_i.regfile_wdata_wb_i), + .regfile_alu_we_ex_i(cv32e40px_top_i.core_i.id_stage_i.regfile_alu_we_ex_o), // APU .apu_req_i (cv32e40px_top_i.core_i.apu_req_o), .apu_gnt_i (cv32e40px_top_i.core_i.apu_gnt_i), - .apu_rvalid_i(cv32e40px_top_i.core_i.apu_rvalid_i), + .apu_rvalid_i(cv32e40px_top_i.core_i.ex_stage_i.apu_valid), // Controller FSM probes .ctrl_fsm_cs_i(cv32e40px_top_i.core_i.id_stage_i.controller_i.ctrl_fsm_cs), @@ -355,6 +366,8 @@ module cv32e40px_tb_wrapper .csr_we_i (cv32e40px_top_i.core_i.cs_registers_i.csr_we_int), .csr_wdata_int_i(cv32e40px_top_i.core_i.cs_registers_i.csr_wdata_int), + .csr_fregs_we_i(cv32e40px_top_i.core_i.cs_registers_i.fregs_we_i), + .csr_mstatus_n_i (cv32e40px_top_i.core_i.cs_registers_i.mstatus_n), .csr_mstatus_q_i (cv32e40px_top_i.core_i.cs_registers_i.mstatus_q), .csr_mstatus_fs_n_i(cv32e40px_top_i.core_i.cs_registers_i.mstatus_fs_n), @@ -367,6 +380,10 @@ module cv32e40px_tb_wrapper .csr_tdata1_q_i (cv32e40px_top_i.core_i.cs_registers_i.tmatch_control_rdata),//gen_trigger_regs.tmatch_control_exec_q ), .csr_tdata1_we_i(cv32e40px_top_i.core_i.cs_registers_i.gen_trigger_regs.tmatch_control_we), + .csr_tdata2_n_i (cv32e40px_top_i.core_i.cs_registers_i.tmatch_value_rdata),//csr_wdata_int ), + .csr_tdata2_q_i (cv32e40px_top_i.core_i.cs_registers_i.tmatch_value_rdata),//gen_trigger_regs.tmatch_control_exec_q ), + .csr_tdata2_we_i(cv32e40px_top_i.core_i.cs_registers_i.gen_trigger_regs.tmatch_value_we), + .csr_tinfo_n_i({16'h0, cv32e40px_top_i.core_i.cs_registers_i.tinfo_types}), .csr_tinfo_q_i({16'h0, cv32e40px_top_i.core_i.cs_registers_i.tinfo_types}), @@ -424,6 +441,7 @@ module cv32e40px_tb_wrapper ); `endif + `ifdef CV32E40P_RVFI_TRACE_EXECUTION bind cv32e40px_rvfi: rvfi_i cv32e40px_rvfi_trace #( .FPU (FPU), diff --git a/hw/vendor/esl_epfl_cv32e40px/bhv/include/cv32e40px_tracer_pkg.sv b/hw/vendor/esl_epfl_cv32e40px/bhv/include/cv32e40px_tracer_pkg.sv index 40edce035..90ee5be9d 100644 --- a/hw/vendor/esl_epfl_cv32e40px/bhv/include/cv32e40px_tracer_pkg.sv +++ b/hw/vendor/esl_epfl_cv32e40px/bhv/include/cv32e40px_tracer_pkg.sv @@ -196,8 +196,8 @@ package cv32e40px_tracer_pkg; parameter INSTR_CVEND0 = {12'b000000000000, 5'b?, 3'b100, 4'b0011, 1'b0, OPCODE_CUSTOM_1}; parameter INSTR_CVCOUNTI0 = {12'b?, 5'b00000, 3'b100, 4'b0100, 1'b0, OPCODE_CUSTOM_1}; parameter INSTR_CVCOUNT0 = {12'b000000000000, 5'b?, 3'b100, 4'b0101, 1'b0, OPCODE_CUSTOM_1}; - parameter INSTR_CVSETUPI0 = {12'b?, 5'b00000, 3'b100, 4'b0110, 1'b0, OPCODE_CUSTOM_1}; - parameter INSTR_CVSETUP0 = {12'b?, 5'b00000, 3'b100, 4'b0111, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUPI0 = {17'b?, 3'b100, 4'b0110, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUP0 = {12'b?, 5'b?, 3'b100, 4'b0111, 1'b0, OPCODE_CUSTOM_1}; parameter INSTR_CVSTARTI1 = {12'b?, 5'b00000, 3'b100, 4'b0000, 1'b1, OPCODE_CUSTOM_1}; parameter INSTR_CVSTART1 = {12'b000000000000, 5'b?, 3'b100, 4'b0001, 1'b1, OPCODE_CUSTOM_1}; @@ -205,8 +205,8 @@ package cv32e40px_tracer_pkg; parameter INSTR_CVEND1 = {12'b000000000000, 5'b?, 3'b100, 4'b0011, 1'b1, OPCODE_CUSTOM_1}; parameter INSTR_CVCOUNTI1 = {12'b?, 5'b00000, 3'b100, 4'b0100, 1'b1, OPCODE_CUSTOM_1}; parameter INSTR_CVCOUNT1 = {12'b000000000000, 5'b?, 3'b100, 4'b0101, 1'b1, OPCODE_CUSTOM_1}; - parameter INSTR_CVSETUPI1 = {12'b?, 5'b00000, 3'b100, 4'b0110, 1'b1, OPCODE_CUSTOM_1}; - parameter INSTR_CVSETUP1 = {12'b?, 5'b00000, 3'b100, 4'b0111, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUPI1 = {17'b?, 3'b100, 4'b0110, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUP1 = {12'b?, 5'b?, 3'b100, 4'b0111, 1'b1, OPCODE_CUSTOM_1}; parameter INSTR_FF1 = {7'b0100001, 5'b0, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; @@ -449,8 +449,8 @@ package cv32e40px_tracer_pkg; parameter INSTR_CVSHUFFLE2H = {5'b11100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; parameter INSTR_CVSHUFFLE2B = {5'b11100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; - parameter INSTR_CVPACK = {5'b11101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; - parameter INSTR_CVPACKH = {5'b11101, 1'b0, 1'b1, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVPACK = {5'b11110, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVPACKH = {5'b11110, 1'b0, 1'b1, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; parameter INSTR_CVPACKHIB = {5'b11111, 1'b0, 1'b1, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; parameter INSTR_CVPACKLOB = {5'b11111, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; diff --git a/hw/vendor/esl_epfl_cv32e40px/bhv/insn_trace.sv b/hw/vendor/esl_epfl_cv32e40px/bhv/insn_trace.sv index 3db2a7ee0..3fe7c1848 100644 --- a/hw/vendor/esl_epfl_cv32e40px/bhv/insn_trace.sv +++ b/hw/vendor/esl_epfl_cv32e40px/bhv/insn_trace.sv @@ -66,6 +66,8 @@ int m_instret_cnt; + bit m_sample_csr_write_in_ex; + struct { logic [31:0] addr ; logic [ 3:0] rmask; @@ -145,32 +147,33 @@ function new(); - this.m_order = 0; - this.m_skip_order = 1'b0; - this.m_valid = 1'b0; - this.m_move_down_pipe = 1'b0; - this.m_data_missaligned = 1'b0; - this.m_got_first_data = 1'b0; - this.m_got_ex_reg = 1'b0; - this.m_intr = '0; - this.m_dbg_taken = 1'b0; - this.m_dbg_cause = '0; - this.m_is_ebreak = '0; - this.m_is_illegal = '0; - this.m_is_irq = '0; - this.m_is_memory = 1'b0; - this.m_is_load = 1'b0; - this.m_is_apu = 1'b0; - this.m_is_apu_ok = 1'b0; - this.m_apu_req_id = 0; - this.m_mem_req_id[0] = 0; - this.m_mem_req_id[1] = 0; - this.m_mem_req_id_valid = '0; - this.m_trap = 1'b0; - this.m_fflags_we_non_apu = 1'b0; - this.m_frm_we_non_apu = 1'b0; - this.m_fcsr_we_non_apu = 1'b0; - this.m_instret_cnt = 0; + this.m_order = 0; + this.m_skip_order = 1'b0; + this.m_valid = 1'b0; + this.m_move_down_pipe = 1'b0; + this.m_data_missaligned = 1'b0; + this.m_got_first_data = 1'b0; + this.m_got_ex_reg = 1'b0; + this.m_intr = '0; + this.m_dbg_taken = 1'b0; + this.m_dbg_cause = '0; + this.m_is_ebreak = '0; + this.m_is_illegal = '0; + this.m_is_irq = '0; + this.m_is_memory = 1'b0; + this.m_is_load = 1'b0; + this.m_is_apu = 1'b0; + this.m_is_apu_ok = 1'b0; + this.m_apu_req_id = 0; + this.m_mem_req_id[0] = 0; + this.m_mem_req_id[1] = 0; + this.m_mem_req_id_valid = '0; + this.m_trap = 1'b0; + this.m_fflags_we_non_apu = 1'b0; + this.m_frm_we_non_apu = 1'b0; + this.m_fcsr_we_non_apu = 1'b0; + this.m_instret_cnt = 0; + this.m_sample_csr_write_in_ex = 1'b1; endfunction function void get_mnemonic(); @@ -875,37 +878,38 @@ if(this.m_skip_order) begin this.m_order = this.m_order + 64'h1; end - this.m_skip_order = 1'b0; - this.m_pc_rdata = r_pipe_freeze_trace.pc_id; - this.m_is_illegal = 1'b0; - this.m_is_irq = 1'b0; - this.m_is_memory = 1'b0; - this.m_is_load = 1'b0; - this.m_is_apu = 1'b0; - this.m_is_apu_ok = 1'b0; - this.m_apu_req_id = 0; - this.m_mem_req_id[0] = 0; - this.m_mem_req_id[1] = 0; - this.m_mem_req_id_valid = '0; - this.m_data_missaligned = 1'b0; - this.m_got_first_data = 1'b0; - this.m_got_ex_reg = 1'b0; - this.m_got_regs_write = 1'b0; - this.m_move_down_pipe = 1'b0; - this.m_instret_cnt = 0; - this.m_rd_addr[0] = '0; - this.m_rd_addr[1] = '0; - this.m_2_rd_insn = 1'b0; - this.m_rs1_addr = '0; - this.m_rs2_addr = '0; - this.m_rs3_addr = '0; - this.m_ex_fw = '0; - this.m_csr.got_minstret = '0; - this.m_dbg_taken = '0; - this.m_trap = 1'b0; - this.m_fflags_we_non_apu = 1'b0; - this.m_frm_we_non_apu = 1'b0; - this.m_fcsr_we_non_apu = 1'b0; + this.m_skip_order = 1'b0; + this.m_pc_rdata = r_pipe_freeze_trace.pc_id; + this.m_is_illegal = 1'b0; + this.m_is_irq = 1'b0; + this.m_is_memory = 1'b0; + this.m_is_load = 1'b0; + this.m_is_apu = 1'b0; + this.m_is_apu_ok = 1'b0; + this.m_apu_req_id = 0; + this.m_mem_req_id[0] = 0; + this.m_mem_req_id[1] = 0; + this.m_mem_req_id_valid = '0; + this.m_data_missaligned = 1'b0; + this.m_got_first_data = 1'b0; + this.m_got_ex_reg = 1'b0; + this.m_got_regs_write = 1'b0; + this.m_move_down_pipe = 1'b0; + this.m_instret_cnt = 0; + this.m_sample_csr_write_in_ex = 1'b1; + this.m_rd_addr[0] = '0; + this.m_rd_addr[1] = '0; + this.m_2_rd_insn = 1'b0; + this.m_rs1_addr = '0; + this.m_rs2_addr = '0; + this.m_rs3_addr = '0; + this.m_ex_fw = '0; + this.m_csr.got_minstret = '0; + this.m_dbg_taken = '0; + this.m_trap = 1'b0; + this.m_fflags_we_non_apu = 1'b0; + this.m_frm_we_non_apu = 1'b0; + this.m_fcsr_we_non_apu = 1'b0; this.m_csr.mcause_we = '0; if (is_compressed_id_i) begin this.m_insn[31:16] = '0; @@ -944,47 +948,48 @@ endfunction function void copy_full(insn_trace_t m_source); - this.m_valid = m_source.m_valid; - this.m_stage = m_source.m_stage; - this.m_order = m_source.m_order; - this.m_pc_rdata = m_source.m_pc_rdata; - this.m_insn = m_source.m_insn; - this.m_mnemonic = m_source.m_mnemonic; - this.m_is_memory = m_source.m_is_memory; - this.m_is_load = m_source.m_is_load; - this.m_is_apu = m_source.m_is_apu; - this.m_is_apu_ok = m_source.m_is_apu_ok; - this.m_apu_req_id = m_source.m_apu_req_id; - this.m_mem_req_id = m_source.m_mem_req_id; - this.m_mem_req_id_valid = m_source.m_mem_req_id_valid; - this.m_data_missaligned = m_source.m_data_missaligned; - this.m_got_first_data = m_source.m_got_first_data; - this.m_got_ex_reg = m_source.m_got_ex_reg; - this.m_dbg_taken = m_source.m_dbg_taken; - this.m_dbg_cause = m_source.m_dbg_cause; - this.m_is_ebreak = m_source.m_is_ebreak; - this.m_is_illegal = m_source.m_is_illegal; - this.m_is_irq = m_source.m_is_irq; - this.m_instret_cnt = m_source.m_instret_cnt; - this.m_rs1_addr = m_source.m_rs1_addr; - this.m_rs2_addr = m_source.m_rs2_addr; - this.m_rs3_addr = m_source.m_rs3_addr; - this.m_rs1_rdata = m_source.m_rs1_rdata; - this.m_rs2_rdata = m_source.m_rs2_rdata; - this.m_rs3_rdata = m_source.m_rs3_rdata; - - this.m_ex_fw = m_source.m_ex_fw; - this.m_rd_addr = m_source.m_rd_addr; - this.m_2_rd_insn = m_source.m_2_rd_insn; - this.m_rd_wdata = m_source.m_rd_wdata; - - this.m_intr = m_source.m_intr; - this.m_trap = m_source.m_trap; - this.m_fflags_we_non_apu = m_source.m_fflags_we_non_apu; - this.m_frm_we_non_apu = m_source.m_frm_we_non_apu ; - this.m_fcsr_we_non_apu = m_source.m_fcsr_we_non_apu; - - this.m_mem = m_source.m_mem; + this.m_valid = m_source.m_valid; + this.m_stage = m_source.m_stage; + this.m_order = m_source.m_order; + this.m_pc_rdata = m_source.m_pc_rdata; + this.m_insn = m_source.m_insn; + this.m_mnemonic = m_source.m_mnemonic; + this.m_is_memory = m_source.m_is_memory; + this.m_is_load = m_source.m_is_load; + this.m_is_apu = m_source.m_is_apu; + this.m_is_apu_ok = m_source.m_is_apu_ok; + this.m_apu_req_id = m_source.m_apu_req_id; + this.m_mem_req_id = m_source.m_mem_req_id; + this.m_mem_req_id_valid = m_source.m_mem_req_id_valid; + this.m_data_missaligned = m_source.m_data_missaligned; + this.m_got_first_data = m_source.m_got_first_data; + this.m_got_ex_reg = m_source.m_got_ex_reg; + this.m_dbg_taken = m_source.m_dbg_taken; + this.m_dbg_cause = m_source.m_dbg_cause; + this.m_is_ebreak = m_source.m_is_ebreak; + this.m_is_illegal = m_source.m_is_illegal; + this.m_is_irq = m_source.m_is_irq; + this.m_instret_cnt = m_source.m_instret_cnt; + this.m_sample_csr_write_in_ex = m_source.m_sample_csr_write_in_ex; + this.m_rs1_addr = m_source.m_rs1_addr; + this.m_rs2_addr = m_source.m_rs2_addr; + this.m_rs3_addr = m_source.m_rs3_addr; + this.m_rs1_rdata = m_source.m_rs1_rdata; + this.m_rs2_rdata = m_source.m_rs2_rdata; + this.m_rs3_rdata = m_source.m_rs3_rdata; + + this.m_ex_fw = m_source.m_ex_fw; + this.m_rd_addr = m_source.m_rd_addr; + this.m_2_rd_insn = m_source.m_2_rd_insn; + this.m_rd_wdata = m_source.m_rd_wdata; + + this.m_intr = m_source.m_intr; + this.m_trap = m_source.m_trap; + this.m_fflags_we_non_apu = m_source.m_fflags_we_non_apu; + this.m_frm_we_non_apu = m_source.m_frm_we_non_apu ; + this.m_fcsr_we_non_apu = m_source.m_fcsr_we_non_apu; + + this.m_mem = m_source.m_mem; //CRS `ASSIGN_CSR(mstatus) `ASSIGN_CSR(mstatus_fs) diff --git a/hw/vendor/esl_epfl_cv32e40px/bhv/pipe_freeze_trace.sv b/hw/vendor/esl_epfl_cv32e40px/bhv/pipe_freeze_trace.sv index 58051ab8e..88d65d0b0 100644 --- a/hw/vendor/esl_epfl_cv32e40px/bhv/pipe_freeze_trace.sv +++ b/hw/vendor/esl_epfl_cv32e40px/bhv/pipe_freeze_trace.sv @@ -64,6 +64,9 @@ typedef struct { logic is_compressed_id; logic ebrk_insn_dec; + logic ecall_insn_dec; + logic mret_insn_dec; + logic mret_dec; logic [5:0] csr_cause; @@ -112,6 +115,9 @@ typedef struct { logic [31:0] data_wdata_ex; logic lsu_split_q_ex; + logic mult_ready; + logic alu_ready; + //// WB probes //// logic [31:0] pc_wb; logic wb_ready; @@ -198,6 +204,8 @@ typedef struct { logic mcause_we; logic dcsr_we; + logic fregs_we; + logic jvt_we; Status_t mstatus_n; Status_t mstatus_q; @@ -348,16 +356,24 @@ function compute_csr_we(); r_pipe_freeze_trace.csr.mstatus_we = 1'b1; r_pipe_freeze_trace.csr.mstatus_fs_we = 1'b1; end - CSR_MISA: r_pipe_freeze_trace.csr.misa_we = 1'b1; - CSR_MTVEC: r_pipe_freeze_trace.csr.mtvec_we = 1'b1; - CSR_MSCRATCH: r_pipe_freeze_trace.csr.mscratch_we = 1'b1; - CSR_MEPC: r_pipe_freeze_trace.csr.mepc_we = 1'b1; - CSR_MCAUSE: r_pipe_freeze_trace.csr.mcause_we = 1'b1; - CSR_DCSR: r_pipe_freeze_trace.csr.dcsr_we = 1'b1; - CSR_FFLAGS: r_pipe_freeze_trace.csr.fflags_we = 1'b1; - CSR_FRM: r_pipe_freeze_trace.csr.frm_we = 1'b1; - CSR_FCSR: r_pipe_freeze_trace.csr.fcsr_we = 1'b1; - CSR_DPC: r_pipe_freeze_trace.csr.dpc_we = 1'b1; + CSR_MISA: r_pipe_freeze_trace.csr.misa_we = 1'b1; + CSR_MTVEC: r_pipe_freeze_trace.csr.mtvec_we = 1'b1; + CSR_MSCRATCH: r_pipe_freeze_trace.csr.mscratch_we = 1'b1; + CSR_MEPC: r_pipe_freeze_trace.csr.mepc_we = 1'b1; + CSR_MCAUSE: r_pipe_freeze_trace.csr.mcause_we = 1'b1; + CSR_DCSR: r_pipe_freeze_trace.csr.dcsr_we = 1'b1; + CSR_FFLAGS: begin + r_pipe_freeze_trace.csr.fflags_we = 1'b1; + r_pipe_freeze_trace.csr.mstatus_fs_we = 1'b1; + end + CSR_FRM: r_pipe_freeze_trace.csr.frm_we = 1'b1; + CSR_FCSR: begin + r_pipe_freeze_trace.csr.fcsr_we = 1'b1; + r_pipe_freeze_trace.csr.mstatus_fs_we = 1'b1; + end + CSR_DPC: r_pipe_freeze_trace.csr.dpc_we = 1'b1; + CSR_DSCRATCH0: r_pipe_freeze_trace.csr.dscratch0_we = 1'b1; + CSR_DSCRATCH1: r_pipe_freeze_trace.csr.dscratch1_we = 1'b1; endcase end // CSR_MCAUSE: r_pipe_freeze_trace.csr.mcause_we = r_pipe_freeze_trace.csr.mcause_n != r_pipe_freeze_trace.csr.mcause_q; //for debug purpose @@ -416,6 +432,9 @@ task monitor_pipeline(); r_pipe_freeze_trace.jump_target_id = jump_target_id_i; r_pipe_freeze_trace.is_compressed_id = is_compressed_id_i; r_pipe_freeze_trace.ebrk_insn_dec = ebrk_insn_dec_i; + r_pipe_freeze_trace.ecall_insn_dec = ecall_insn_dec_i; + r_pipe_freeze_trace.mret_insn_dec = mret_insn_dec_i; + r_pipe_freeze_trace.mret_dec = mret_dec_i; r_pipe_freeze_trace.csr_cause = csr_cause_i; r_pipe_freeze_trace.debug_csr_save = debug_csr_save_i; r_pipe_freeze_trace.minstret = minstret_i; @@ -462,6 +481,8 @@ task monitor_pipeline(); r_pipe_freeze_trace.data_wdata_ex = data_wdata_ex_i; r_pipe_freeze_trace.lsu_split_q_ex = lsu_split_q_ex_i; + r_pipe_freeze_trace.mult_ready = mult_ready_i; + r_pipe_freeze_trace.alu_ready = alu_ready_i; //// WB probes //// r_pipe_freeze_trace.pc_wb = pc_wb_i; r_pipe_freeze_trace.wb_ready = wb_ready_i; @@ -526,6 +547,8 @@ task monitor_pipeline(); r_pipe_freeze_trace.csr.we = csr_we_i; r_pipe_freeze_trace.csr.wdata_int = csr_wdata_int_i; + r_pipe_freeze_trace.csr.fregs_we = csr_fregs_we_i; + r_pipe_freeze_trace.csr.jvt_we = csr_jvt_we_i; r_pipe_freeze_trace.csr.mstatus_n = csr_mstatus_n_i; r_pipe_freeze_trace.csr.mstatus_q = csr_mstatus_q_i; @@ -650,10 +673,6 @@ task monitor_pipeline(); if (r_pipe_freeze_trace.csr.fcsr_we) begin r_pipe_freeze_trace.csr.fflags_we = 1'b1; r_pipe_freeze_trace.csr.frm_we = 1'b1; - end else begin - if (r_pipe_freeze_trace.csr.fflags_we || r_pipe_freeze_trace.csr.frm_we) begin - r_pipe_freeze_trace.csr.fcsr_we = 1'b1; - end end if (csr_fcsr_fflags_we_i) begin diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_controller.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_controller.sv index 6516f9321..a3e3bac9c 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_controller.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_controller.sv @@ -491,6 +491,7 @@ module cv32e40px_controller import cv32e40px_pkg::*; if ( (debug_req_pending || trigger_match_i) & ~debug_mode_q ) begin //Serving the debug + is_decoding_o = COREV_PULP ? 1'b0 : 1'b1; halt_if_o = 1'b1; halt_id_o = 1'b1; ctrl_fsm_ns = DBG_FLUSH; @@ -712,6 +713,7 @@ module cv32e40px_controller import cv32e40px_pkg::*; if ( (debug_req_pending || trigger_match_i) & ~debug_mode_q ) begin //Serving the debug + is_decoding_o = COREV_PULP ? 1'b0 : 1'b1; halt_if_o = 1'b1; halt_id_o = 1'b1; ctrl_fsm_ns = DBG_FLUSH; @@ -764,7 +766,7 @@ module cv32e40px_controller import cv32e40px_pkg::*; ebrk_insn_i: begin halt_if_o = 1'b1; - halt_id_o = 1'b1; + halt_id_o = 1'b0; if (debug_mode_q) // we got back to the park loop in the debug rom @@ -776,15 +778,15 @@ module cv32e40px_controller import cv32e40px_pkg::*; else begin // otherwise just a normal ebreak exception - ctrl_fsm_ns = FLUSH_EX; + ctrl_fsm_ns = id_ready_i ? FLUSH_EX : DECODE_HWLOOP; end end ecall_insn_i: begin halt_if_o = 1'b1; - halt_id_o = 1'b1; - ctrl_fsm_ns = FLUSH_EX; + halt_id_o = 1'b0; + ctrl_fsm_ns = id_ready_i ? FLUSH_EX : DECODE_HWLOOP; end csr_status_i: begin diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_core.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_core.sv index fc301b914..25aa6cc98 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_core.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_core.sv @@ -194,6 +194,7 @@ module cv32e40px_core logic [31:0] jump_target_id, jump_target_ex; logic branch_in_ex; logic branch_decision; + logic [ 1:0] ctrl_transfer_insn_in_dec; logic ctrl_busy; logic if_busy; @@ -237,6 +238,7 @@ module cv32e40px_core logic [ C_RM-1:0] frm_csr; logic [ C_FFLAG-1:0] fflags_csr; logic fflags_we; + logic fregs_we; // APU logic apu_en_ex; @@ -272,6 +274,7 @@ module cv32e40px_core logic regfile_we_ex; logic [ 5:0] regfile_waddr_fw_wb_o; // From WB to ID logic regfile_we_wb; + logic regfile_we_wb_power; logic [ 31:0] regfile_wdata; logic [ 5:0] regfile_alu_waddr_ex; @@ -279,6 +282,7 @@ module cv32e40px_core logic [ 5:0] regfile_alu_waddr_fw; logic regfile_alu_we_fw; + logic regfile_alu_we_fw_power; logic [ 31:0] regfile_alu_wdata_fw; // CSR control @@ -596,9 +600,10 @@ module cv32e40px_core .instr_req_o (instr_req_int), // Jumps and branches - .branch_in_ex_o (branch_in_ex), - .branch_decision_i(branch_decision), - .jump_target_o (jump_target_id), + .branch_in_ex_o (branch_in_ex), + .branch_decision_i (branch_decision), + .jump_target_o (jump_target_id), + .ctrl_transfer_insn_in_dec_o(ctrl_transfer_insn_in_dec), // IF and ID control signals .clear_instr_valid_o(clear_instr_valid), @@ -790,13 +795,15 @@ module cv32e40px_core .wake_from_sleep_o(wake_from_sleep), // Forward Signals - .regfile_waddr_wb_i(regfile_waddr_fw_wb_o), // Write address ex-wb pipeline - .regfile_we_wb_i (regfile_we_wb), // write enable for the register file - .regfile_wdata_wb_i(regfile_wdata), // write data to commit in the register file + .regfile_waddr_wb_i (regfile_waddr_fw_wb_o), // Write address ex-wb pipeline + .regfile_we_wb_i (regfile_we_wb), // write enable for the register file + .regfile_we_wb_power_i(regfile_we_wb_power), + .regfile_wdata_wb_i (regfile_wdata), // write data to commit in the register file - .regfile_alu_waddr_fw_i(regfile_alu_waddr_fw), - .regfile_alu_we_fw_i (regfile_alu_we_fw), - .regfile_alu_wdata_fw_i(regfile_alu_wdata_fw), + .regfile_alu_waddr_fw_i (regfile_alu_waddr_fw), + .regfile_alu_we_fw_i (regfile_alu_we_fw), + .regfile_alu_we_fw_power_i(regfile_alu_we_fw_power), + .regfile_alu_wdata_fw_i (regfile_alu_wdata_fw), // from ALU .mult_multicycle_i(mult_multicycle), @@ -828,6 +835,7 @@ module cv32e40px_core // // ///////////////////////////////////////////////////// cv32e40px_ex_stage #( + .COREV_PULP (COREV_PULP), .FPU (FPU), .APU_NARGS_CPU (APU_NARGS_CPU), .APU_WOP_CPU (APU_WOP_CPU), @@ -876,6 +884,8 @@ module cv32e40px_core .data_misaligned_ex_i(data_misaligned_ex), // from ID/EX pipeline .data_misaligned_i (data_misaligned), + .ctrl_transfer_insn_in_dec_i(ctrl_transfer_insn_in_dec), + // FPU .fpu_fflags_we_o(fflags_we), .fpu_fflags_o (fflags_csr), @@ -941,18 +951,20 @@ module cv32e40px_core .regfile_we_i (regfile_we_ex), // Output of ex stage pipeline - .regfile_waddr_wb_o(regfile_waddr_fw_wb_o), - .regfile_we_wb_o (regfile_we_wb), - .regfile_wdata_wb_o(regfile_wdata), + .regfile_waddr_wb_o (regfile_waddr_fw_wb_o), + .regfile_we_wb_o (regfile_we_wb), + .regfile_we_wb_power_o(regfile_we_wb_power), + .regfile_wdata_wb_o (regfile_wdata), // To IF: Jump and branch target and decision .jump_target_o (jump_target_ex), .branch_decision_o(branch_decision), // To ID stage: Forwarding signals - .regfile_alu_waddr_fw_o(regfile_alu_waddr_fw), - .regfile_alu_we_fw_o (regfile_alu_we_fw), - .regfile_alu_wdata_fw_o(regfile_alu_wdata_fw), + .regfile_alu_waddr_fw_o (regfile_alu_waddr_fw), + .regfile_alu_we_fw_o (regfile_alu_we_fw), + .regfile_alu_we_fw_power_o(regfile_alu_we_fw_power), + .regfile_alu_wdata_fw_o (regfile_alu_wdata_fw), // stall control .is_decoding_i (is_decoding), @@ -1072,6 +1084,7 @@ module cv32e40px_core .frm_o (frm_csr), .fflags_i (fflags_csr), .fflags_we_i(fflags_we), + .fregs_we_i (fregs_we), // Interrupt related control signals .mie_bypass_o (mie_bypass), @@ -1140,13 +1153,16 @@ module cv32e40px_core ); // CSR access - assign csr_addr = csr_addr_int; - assign csr_wdata = alu_operand_a_ex; - assign csr_op = csr_op_ex; + assign csr_addr = csr_addr_int; + assign csr_wdata = alu_operand_a_ex; + assign csr_op = csr_op_ex; assign csr_addr_int = csr_num_e'(csr_access_ex ? alu_operand_b_ex[11:0] : '0); - + // Floating-Point registers write + assign fregs_we = (FPU & !ZFINX) ? ((regfile_alu_we_fw && regfile_alu_waddr_fw[5]) || + (regfile_we_wb && regfile_waddr_fw_wb_o[5])) + : 1'b0; /////////////////////////// // ____ __ __ ____ // diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_cs_registers.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_cs_registers.sv index 2d8734527..f24b3bf9b 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_cs_registers.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_cs_registers.sv @@ -68,6 +68,7 @@ module cv32e40px_cs_registers output logic [ 2:0] frm_o, input logic [C_FFLAG-1:0] fflags_i, input logic fflags_we_i, + input logic fregs_we_i, // Interrupts output logic [31:0] mie_bypass_o, @@ -212,6 +213,7 @@ module cv32e40px_cs_registers logic [31:0] exception_pc; Status_t mstatus_q, mstatus_n; + logic mstatus_we_int; FS_t mstatus_fs_q, mstatus_fs_n; logic [5:0] mcause_q, mcause_n; logic [5:0] ucause_q, ucause_n; @@ -897,6 +899,7 @@ module cv32e40px_cs_registers dscratch0_n = dscratch0_q; dscratch1_n = dscratch1_q; + mstatus_we_int = 1'b0; mstatus_n = mstatus_q; mcause_n = mcause_q; ucause_n = '0; // Not used if PULP_SECURE == 0 @@ -957,7 +960,8 @@ module cv32e40px_cs_registers mprv: csr_wdata_int[MSTATUS_MPRV_BIT] }; if (FPU == 1 && ZFINX == 0) begin - mstatus_fs_n = FS_t'(csr_wdata_int[MSTATUS_FS_BIT_HIGH:MSTATUS_FS_BIT_LOW]); + mstatus_we_int = 1'b1; + mstatus_fs_n = FS_t'(csr_wdata_int[MSTATUS_FS_BIT_HIGH:MSTATUS_FS_BIT_LOW]); end end // mie: machine interrupt enable @@ -1027,7 +1031,7 @@ module cv32e40px_cs_registers if (ZFINX == 0) begin // FPU Register File/Flags implicit update or modified by CSR instructions - if (fflags_we_i || fcsr_update) begin + if ((fregs_we_i && !(mstatus_we_int && mstatus_fs_n != FS_DIRTY)) || fflags_we_i || fcsr_update) begin mstatus_fs_n = FS_DIRTY; end end diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_ex_stage.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_ex_stage.sv index 6ab1b01b3..3beaf0227 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_ex_stage.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_ex_stage.sv @@ -34,6 +34,7 @@ module cv32e40px_ex_stage import cv32e40px_apu_core_pkg::*; import cv32e40px_core_v_xif_pkg::*; #( + parameter COREV_PULP = 0, parameter FPU = 0, parameter APU_NARGS_CPU = 3, parameter APU_WOP_CPU = 6, @@ -82,6 +83,8 @@ module cv32e40px_ex_stage input logic data_misaligned_ex_i, input logic data_misaligned_i, + input logic [1:0] ctrl_transfer_insn_in_dec_i, + // FPU signals output logic fpu_fflags_we_o, output logic [APU_NUSFLAGS_CPU-1:0] fpu_fflags_o, @@ -152,11 +155,13 @@ module cv32e40px_ex_stage // Output of EX stage pipeline output logic [ 5:0] regfile_waddr_wb_o, output logic regfile_we_wb_o, + output logic regfile_we_wb_power_o, output logic [31:0] regfile_wdata_wb_o, // Forwarding ports : to ID stage output logic [ 5:0] regfile_alu_waddr_fw_o, output logic regfile_alu_we_fw_o, + output logic regfile_alu_we_fw_power_o, output logic [31:0] regfile_alu_wdata_fw_o, // forward to RF and ID/EX pipe, ALU & MUL // To IF: Jump and branch target and decision @@ -204,30 +209,36 @@ module cv32e40px_ex_stage // ALU write port mux always_comb begin - regfile_alu_wdata_fw_o = '0; - regfile_alu_waddr_fw_o = '0; - regfile_alu_we_fw_o = '0; - wb_contention = 1'b0; - result_fw_to_x_o = '0; + regfile_alu_wdata_fw_o = '0; + regfile_alu_waddr_fw_o = '0; + regfile_alu_we_fw_o = '0; + wb_contention = 1'b0; + result_fw_to_x_o = '0; + regfile_alu_we_fw_power_o = 1'b0; if (x_result_valid_assigned_i & x_result_we_i & (x_result_rd_i != 5'b00000)) begin - regfile_alu_we_fw_o = 1'b1; - regfile_alu_waddr_fw_o = {1'b0, x_result_rd_i}; - regfile_alu_wdata_fw_o = x_result_data_i; + regfile_alu_we_fw_o = 1'b1; + regfile_alu_we_fw_power_o = 1'b1; + regfile_alu_waddr_fw_o = {1'b0, x_result_rd_i}; + regfile_alu_wdata_fw_o = x_result_data_i; if (regfile_alu_we_i) begin wb_contention = 1'b1; end end else begin // APU single cycle operations, and multicycle operations (>2cycles) are written back on ALU port if (apu_valid & (apu_singlecycle | apu_multicycle)) begin - regfile_alu_we_fw_o = 1'b1; - regfile_alu_waddr_fw_o = apu_waddr; - regfile_alu_wdata_fw_o = apu_result; - result_fw_to_x_o = apu_result; + regfile_alu_we_fw_o = 1'b1; + regfile_alu_we_fw_power_o = 1'b1; + regfile_alu_waddr_fw_o = apu_waddr; + regfile_alu_wdata_fw_o = apu_result; + result_fw_to_x_o = apu_result; if (regfile_alu_we_i & ~apu_en_i) begin wb_contention = 1'b1; end end else begin - regfile_alu_we_fw_o = regfile_alu_we_i & ~apu_en_i; // private fpu incomplete? + regfile_alu_we_fw_o = regfile_alu_we_i & ~apu_en_i; // private fpu incomplete? + regfile_alu_we_fw_power_o = !COREV_PULP ? regfile_alu_we_i & ~apu_en_i : + regfile_alu_we_i & ~apu_en_i & + mult_ready & alu_ready & lsu_ready_ex_i; regfile_alu_waddr_fw_o = regfile_alu_waddr_i; if (alu_en_i) begin regfile_alu_wdata_fw_o = alu_result; @@ -247,21 +258,24 @@ module cv32e40px_ex_stage // LSU write port mux always_comb begin - regfile_we_wb_o = 1'b0; - regfile_waddr_wb_o = regfile_waddr_lsu; - regfile_wdata_wb_o = lsu_rdata_i; - wb_contention_lsu = 1'b0; + regfile_we_wb_o = 1'b0; + regfile_we_wb_power_o = 1'b0; + regfile_waddr_wb_o = regfile_waddr_lsu; + regfile_wdata_wb_o = lsu_rdata_i; + wb_contention_lsu = 1'b0; if (regfile_we_lsu) begin - regfile_we_wb_o = 1'b1; + regfile_we_wb_o = 1'b1; + regfile_we_wb_power_o = !COREV_PULP ? 1'b1 : ~data_misaligned_ex_i & wb_ready_i; if (apu_valid & (!apu_singlecycle & !apu_multicycle)) begin wb_contention_lsu = 1'b1; end // APU two-cycle operations are written back on LSU port end else if (apu_valid & (!apu_singlecycle & !apu_multicycle)) begin - regfile_we_wb_o = 1'b1; - regfile_waddr_wb_o = apu_waddr; - regfile_wdata_wb_o = apu_result; + regfile_we_wb_o = 1'b1; + regfile_we_wb_power_o = 1'b1; + regfile_waddr_wb_o = apu_waddr; + regfile_wdata_wb_o = apu_result; end end @@ -406,11 +420,20 @@ module cv32e40px_ex_stage apu_result_q <= 'b0; apu_flags_q <= 'b0; end else begin - if (apu_rvalid_i && apu_multicycle && (data_misaligned_i || data_misaligned_ex_i || (data_req_i && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)))) begin + if (apu_rvalid_i && apu_multicycle && + (data_misaligned_i || data_misaligned_ex_i || + ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || + (mulh_active && (mult_operator_i == MUL_H)) || + ((ctrl_transfer_insn_in_dec_i == BRANCH_JALR) && + regfile_alu_we_i && ~apu_read_dep_for_jalr_o))) begin apu_rvalid_q <= 1'b1; apu_result_q <= apu_result_i; apu_flags_q <= apu_flags_i; - end else if (apu_rvalid_q && !(data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)))) begin + end else if (apu_rvalid_q && !(data_misaligned_i || data_misaligned_ex_i || + ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || + (mulh_active && (mult_operator_i == MUL_H)) || + ((ctrl_transfer_insn_in_dec_i == BRANCH_JALR) && + regfile_alu_we_i && ~apu_read_dep_for_jalr_o))) begin apu_rvalid_q <= 1'b0; end end @@ -418,7 +441,12 @@ module cv32e40px_ex_stage assign apu_req_o = apu_req; assign apu_gnt = apu_gnt_i; - assign apu_valid = (apu_multicycle && (data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)))) ? 1'b0 : (apu_rvalid_i || apu_rvalid_q); + assign apu_valid = (apu_multicycle && (data_misaligned_i || data_misaligned_ex_i || + ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || + (mulh_active && (mult_operator_i == MUL_H)) || + ((ctrl_transfer_insn_in_dec_i == BRANCH_JALR) && + regfile_alu_we_i && ~apu_read_dep_for_jalr_o))) + ? 1'b0 : (apu_rvalid_i || apu_rvalid_q); assign apu_operands_o = apu_operands_i; assign apu_op_o = apu_op_i; assign apu_result = apu_rvalid_q ? apu_result_q : apu_result_i; diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_fp_wrapper.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_fp_wrapper.sv index 8502e3418..54add99df 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_fp_wrapper.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_fp_wrapper.sv @@ -111,7 +111,7 @@ module cv32e40px_fp_wrapper .int_fmt_i (fpnew_pkg::int_format_e'(fpu_int_fmt)), .vectorial_op_i(fpu_vec_op), .tag_i (1'b0), - .simd_mask_i ('b0), + .simd_mask_i (1'b0), .in_valid_i (apu_req_i), .in_ready_o (apu_gnt_o), .flush_i (1'b0), diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_id_stage.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_id_stage.sv index 4c513d272..6e996c32f 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_id_stage.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_id_stage.sv @@ -72,6 +72,7 @@ module cv32e40px_id_stage output logic branch_in_ex_o, input logic branch_decision_i, output logic [31:0] jump_target_o, + output logic [ 1:0] ctrl_transfer_insn_in_dec_o, // IF and ID stage signals output logic clear_instr_valid_o, @@ -263,10 +264,12 @@ module cv32e40px_id_stage // Forward Signals input logic [5:0] regfile_waddr_wb_i, input logic regfile_we_wb_i, + input logic regfile_we_wb_power_i, input logic [31:0] regfile_wdata_wb_i, // From wb_stage: selects data from data memory, ex_stage result and sp rdata input logic [ 5:0] regfile_alu_waddr_fw_i, input logic regfile_alu_we_fw_i, + input logic regfile_alu_we_fw_power_i, input logic [31:0] regfile_alu_wdata_fw_i, // from ALU @@ -302,6 +305,9 @@ module cv32e40px_id_stage localparam REG_D_MSB = 11; localparam REG_D_LSB = 7; + + localparam REGFILE_NUM_READ_PORTS = ((COREV_X_IF == 1) & (X_DUALREAD == 1)) ? 2 : 1; + logic [31:0] instr; @@ -381,9 +387,9 @@ module cv32e40px_id_stage logic [ 5:0] regfile_alu_waddr_id; logic regfile_alu_we_id, regfile_alu_we_dec_id; - logic [31:0] regfile_data_ra_id; - logic [31:0] regfile_data_rb_id; - logic [31:0] regfile_data_rc_id; + logic [REGFILE_NUM_READ_PORTS-1:0][31:0] regfile_data_ra_id; + logic [REGFILE_NUM_READ_PORTS-1:0][31:0] regfile_data_rb_id; + logic [REGFILE_NUM_READ_PORTS-1:0][31:0] regfile_data_rc_id; // ALU Control logic alu_en; @@ -438,8 +444,8 @@ module cv32e40px_id_stage logic [2:0][4:0] x_rs_addr; logic x_mem_data_req; logic x_mem_valid; - logic [2:0] x_ex_fwd; - logic [2:0] x_wb_fwd; + logic [RF_READ_PORTS-1:0] x_ex_fwd; + logic [RF_READ_PORTS-1:0] x_wb_fwd; // Register Write Control logic regfile_we_id; @@ -622,17 +628,18 @@ module cv32e40px_id_stage // \___/ \__,_|_| |_| |_| .__/ |_|\__,_|_| \__, |\___|\__| // // |_| |___/ // ////////////////////////////////////////////////////////////////// - - always_comb begin : jump_target_mux - unique case (ctrl_transfer_target_mux_sel) - JT_JAL: jump_target = pc_id_i + imm_uj_type; - JT_COND: jump_target = pc_id_i + imm_sb_type; - - // JALR: Cannot forward RS1, since the path is too long - JT_JALR: jump_target = regfile_data_ra_id + imm_i_type; - default: jump_target = regfile_data_ra_id + imm_i_type; - endcase - end + generate + always_comb begin : jump_target_mux + unique case (ctrl_transfer_target_mux_sel) + JT_JAL: jump_target = pc_id_i + imm_uj_type; + JT_COND: jump_target = pc_id_i + imm_sb_type; + + // JALR: Cannot forward RS1, since the path is too long + JT_JALR: jump_target = regfile_data_ra_id[0] + imm_i_type; + default: jump_target = regfile_data_ra_id[0] + imm_i_type; + endcase + end + endgenerate assign jump_target_o = jump_target; @@ -666,16 +673,18 @@ module cv32e40px_id_stage endcase end - // Operand a forwarding mux - always_comb begin : operand_a_fw_mux - case (operand_a_fw_mux_sel) - SEL_FW_EX: operand_a_fw_id = regfile_alu_wdata_fw_i; - SEL_FW_WB: operand_a_fw_id = regfile_wdata_wb_i; - SEL_REGFILE: operand_a_fw_id = regfile_data_ra_id; - default: operand_a_fw_id = regfile_data_ra_id; - endcase - ; // case (operand_a_fw_mux_sel) - end + generate + // Operand a forwarding mux + always_comb begin : operand_a_fw_mux + case (operand_a_fw_mux_sel) + SEL_FW_EX: operand_a_fw_id = regfile_alu_wdata_fw_i; + SEL_FW_WB: operand_a_fw_id = regfile_wdata_wb_i; + SEL_REGFILE: operand_a_fw_id = regfile_data_ra_id[0]; + default: operand_a_fw_id = regfile_data_ra_id[0]; + endcase + ; // case (operand_a_fw_mux_sel) + end + endgenerate ////////////////////////////////////////////////////// // ___ _ ____ // @@ -732,16 +741,31 @@ module cv32e40px_id_stage assign alu_operand_b = (scalar_replication == 1'b1) ? operand_b_vec : operand_b; - // Operand b forwarding mux - always_comb begin : operand_b_fw_mux - case (operand_b_fw_mux_sel) - SEL_FW_EX: operand_b_fw_id = regfile_alu_wdata_fw_i; - SEL_FW_WB: operand_b_fw_id = regfile_wdata_wb_i; - SEL_REGFILE: operand_b_fw_id = regfile_data_rb_id; - default: operand_b_fw_id = regfile_data_rb_id; - endcase - ; // case (operand_b_fw_mux_sel) - end + generate + if (X_DUALREAD == 0) begin : no_dualread_fw_b + // Operand b forwarding mux + always_comb begin : operand_b_fw_mux + case (operand_b_fw_mux_sel) + SEL_FW_EX: operand_b_fw_id = regfile_alu_wdata_fw_i; + SEL_FW_WB: operand_b_fw_id = regfile_wdata_wb_i; + SEL_REGFILE: operand_b_fw_id = regfile_data_rb_id; + default: operand_b_fw_id = regfile_data_rb_id; + endcase + ; // case (operand_b_fw_mux_sel) + end + end else begin : dualread_fw_b + // Operand b forwarding mux + always_comb begin : operand_b_fw_mux + case (operand_b_fw_mux_sel) + SEL_FW_EX: operand_b_fw_id = regfile_alu_wdata_fw_i; + SEL_FW_WB: operand_b_fw_id = regfile_wdata_wb_i; + SEL_REGFILE: operand_b_fw_id = regfile_data_rb_id[0]; + default: operand_b_fw_id = regfile_data_rb_id[0]; + endcase + ; // case (operand_b_fw_mux_sel) + end + end + endgenerate ////////////////////////////////////////////////////// @@ -777,17 +801,31 @@ module cv32e40px_id_stage assign alu_operand_c = (scalar_replication_c == 1'b1) ? operand_c_vec : operand_c; - // Operand c forwarding mux - always_comb begin : operand_c_fw_mux - case (operand_c_fw_mux_sel) - SEL_FW_EX: operand_c_fw_id = regfile_alu_wdata_fw_i; - SEL_FW_WB: operand_c_fw_id = regfile_wdata_wb_i; - SEL_REGFILE: operand_c_fw_id = regfile_data_rc_id; - default: operand_c_fw_id = regfile_data_rc_id; - endcase - ; // case (operand_c_fw_mux_sel) - end - + generate + if (X_DUALREAD == 0) begin : no_dualread_fw_c + // Operand c forwarding mux + always_comb begin : operand_c_fw_mux + case (operand_c_fw_mux_sel) + SEL_FW_EX: operand_c_fw_id = regfile_alu_wdata_fw_i; + SEL_FW_WB: operand_c_fw_id = regfile_wdata_wb_i; + SEL_REGFILE: operand_c_fw_id = regfile_data_rc_id; + default: operand_c_fw_id = regfile_data_rc_id; + endcase + ; // case (operand_c_fw_mux_sel) + end + end else begin : dualread_fw_c + // Operand c forwarding mux + always_comb begin : operand_c_fw_mux + case (operand_c_fw_mux_sel) + SEL_FW_EX: operand_c_fw_id = regfile_alu_wdata_fw_i; + SEL_FW_WB: operand_c_fw_id = regfile_wdata_wb_i; + SEL_REGFILE: operand_c_fw_id = regfile_data_rc_id[0]; + default: operand_c_fw_id = regfile_data_rc_id[0]; + endcase + ; // case (operand_c_fw_mux_sel) + end + end + endgenerate /////////////////////////////////////////////////////////////////////////// // ___ _ _ _ ___ ____ // @@ -865,6 +903,9 @@ module cv32e40px_id_stage if (ctrl_transfer_target_mux_sel == JT_JALR) begin apu_read_regs[0] = regfile_addr_ra_id; apu_read_regs_valid[0] = 1'b1; + end else begin + apu_read_regs[0] = regfile_addr_ra_id; + apu_read_regs_valid[0] = 1'b0; end end // OP_A_CURRPC: OP_A_REGA_OR_FWD: begin @@ -982,13 +1023,17 @@ module cv32e40px_id_stage .ADDR_WIDTH(6), .DATA_WIDTH(32), .FPU (FPU), - .ZFINX (ZFINX) + .ZFINX (ZFINX), + .COREV_X_IF(COREV_X_IF), + .X_DUALREAD(X_DUALREAD) ) register_file_i ( .clk (clk), .rst_n(rst_n), .scan_cg_en_i(scan_cg_en_i), + .dualread_i(x_issue_resp_i.dualread), + // Read port a .raddr_a_i(regfile_addr_ra_id), .rdata_a_o(regfile_data_ra_id), @@ -1004,12 +1049,12 @@ module cv32e40px_id_stage // Write port a .waddr_a_i(regfile_waddr_wb_i), .wdata_a_i(regfile_wdata_wb_i), - .we_a_i (regfile_we_wb_i), + .we_a_i (regfile_we_wb_power_i), // Write port b .waddr_b_i(regfile_alu_waddr_fw_i), .wdata_b_i(regfile_alu_wdata_fw_i), - .we_b_i (regfile_alu_we_fw_i) + .we_b_i (regfile_alu_we_fw_power_i) ); logic [1:0] x_mem_data_type_id; @@ -1037,6 +1082,7 @@ module cv32e40px_id_stage .x_issue_valid_o (x_issue_valid_o), .x_issue_ready_i (x_issue_ready_i), .x_issue_resp_writeback_i(x_issue_resp_i.writeback), + .x_issue_resp_dualread_i (x_issue_resp_i.dualread), .x_issue_resp_accept_i (x_issue_resp_i.accept), .x_issue_resp_loadstore_i(x_issue_resp_i.loadstore), .x_issue_req_rs_valid_o (x_issue_req_o.rs_valid), @@ -1118,22 +1164,25 @@ module cv32e40px_id_stage assign x_mem_valid = x_mem_valid_i; // xif integer souce operand selection - for (genvar i = 0; i < 3; i++) begin : xif_operand_assignment - always_comb begin - if (i == 0) begin - x_issue_req_o.rs[i] = regfile_data_ra_id; - end else if (i == 1) begin - x_issue_req_o.rs[i] = regfile_data_rb_id; - end else begin - x_issue_req_o.rs[i] = regfile_data_rc_id; - end - if (x_ex_fwd[i]) begin - x_issue_req_o.rs[i] = result_fw_to_x_i; - end else if (x_wb_fwd[i]) begin - x_issue_req_o.rs[i] = regfile_wdata_wb_i; + for (genvar j = 0; j < REGFILE_NUM_READ_PORTS; j++) begin : xif_operand_assignment_dualread + for (genvar i = 0; i < 3; i++) begin : xif_operand_assignment + always_comb begin + if (i == 0) begin + x_issue_req_o.rs[i+3*j] = regfile_data_ra_id[j]; + end else if (i == 1) begin + x_issue_req_o.rs[i+3*j] = regfile_data_rb_id[j]; + end else begin + x_issue_req_o.rs[i+3*j] = regfile_data_rc_id[j]; + end + if (x_ex_fwd[i+3*j]) begin + x_issue_req_o.rs[i+3*j] = result_fw_to_x_i; + end else if (x_wb_fwd[i+3*j]) begin + x_issue_req_o.rs[i+3*j] = regfile_wdata_wb_i; + end end end end + // LSU signal assignment/MUX always_comb begin x_mem_data_type_id = 2'b00; @@ -1300,7 +1349,7 @@ module cv32e40px_id_stage .debug_wfi_no_sleep_i(debug_wfi_no_sleep), // jump/branches - .ctrl_transfer_insn_in_dec_o (ctrl_transfer_insn_in_dec), + .ctrl_transfer_insn_in_dec_o (ctrl_transfer_insn_in_dec_o), .ctrl_transfer_insn_in_id_o (ctrl_transfer_insn_in_id), .ctrl_transfer_target_mux_sel_o(ctrl_transfer_target_mux_sel), @@ -1400,7 +1449,7 @@ module cv32e40px_id_stage // jump/branch control .branch_taken_ex_i (branch_taken_ex), .ctrl_transfer_insn_in_id_i (ctrl_transfer_insn_in_id), - .ctrl_transfer_insn_in_dec_i(ctrl_transfer_insn_in_dec), + .ctrl_transfer_insn_in_dec_i(ctrl_transfer_insn_in_dec_o), // Interrupt signals .irq_wu_ctrl_i (irq_wu_ctrl), diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_register_file_ff.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_register_file_ff.sv index 1543f6e95..d0aad5838 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_register_file_ff.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_register_file_ff.sv @@ -31,7 +31,9 @@ module cv32e40px_register_file #( parameter ADDR_WIDTH = 5, parameter DATA_WIDTH = 32, parameter FPU = 0, - parameter ZFINX = 0 + parameter ZFINX = 0, + parameter COREV_X_IF = 0, + parameter X_DUALREAD = 0 ) ( // Clock and Reset input logic clk, @@ -39,17 +41,19 @@ module cv32e40px_register_file #( input logic scan_cg_en_i, + input logic [2:0] dualread_i, + //Read port R1 - input logic [ADDR_WIDTH-1:0] raddr_a_i, - output logic [DATA_WIDTH-1:0] rdata_a_o, + input logic [ADDR_WIDTH-1:0] raddr_a_i, + output logic [X_DUALREAD:0][DATA_WIDTH-1:0] rdata_a_o, //Read port R2 - input logic [ADDR_WIDTH-1:0] raddr_b_i, - output logic [DATA_WIDTH-1:0] rdata_b_o, + input logic [ADDR_WIDTH-1:0] raddr_b_i, + output logic [X_DUALREAD:0][DATA_WIDTH-1:0] rdata_b_o, //Read port R3 - input logic [ADDR_WIDTH-1:0] raddr_c_i, - output logic [DATA_WIDTH-1:0] rdata_c_o, + input logic [ADDR_WIDTH-1:0] raddr_c_i, + output logic [X_DUALREAD:0][DATA_WIDTH-1:0] rdata_c_o, // Write port W1 input logic [ADDR_WIDTH-1:0] waddr_a_i, @@ -86,17 +90,53 @@ module cv32e40px_register_file #( //----------------------------------------------------------------------------- //-- READ : Read address decoder RAD //----------------------------------------------------------------------------- - assign rdata_a_o = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]]; - assign rdata_b_o = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]]; - assign rdata_c_o = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4:0]]; - + generate + if (COREV_X_IF != 0) begin + if (X_DUALREAD) begin + always_comb begin + rdata_a_o[0] = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]]; + rdata_b_o[0] = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]]; + rdata_c_o[0] = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4:0]]; + if (dualread_i[0] == 1) + rdata_a_o[1] = raddr_a_i[5] ? (mem_fp[{ + raddr_a_i[4:1], raddr_a_i[0]|1'b1 + }]) : (mem[{ + raddr_a_i[4:1], raddr_a_i[0]|1'b1 + }]); + else rdata_a_o[1] = '0; + if (dualread_i[1] == 1) + rdata_b_o[1] = raddr_b_i[5] ? (mem_fp[{ + raddr_b_i[4:1], raddr_b_i[0]|1'b1 + }]) : (mem[{ + raddr_b_i[4:1], raddr_b_i[0]|1'b1 + }]); + else rdata_b_o[1] = '0; + if (dualread_i[2] == 1) + rdata_c_o[1] = raddr_c_i[5] ? (mem_fp[{ + raddr_c_i[4:1], raddr_c_i[0]|1'b1 + }]) : (mem[{ + raddr_c_i[4:1], raddr_c_i[0]|1'b1 + }]); + else rdata_c_o[1] = '0; + end + end else begin + assign rdata_a_o = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]]; + assign rdata_b_o = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]]; + assign rdata_c_o = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4:0]]; + end + end else begin + assign rdata_a_o = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]]; + assign rdata_b_o = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]]; + assign rdata_c_o = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4:0]]; + end + endgenerate //----------------------------------------------------------------------------- //-- WRITE : Write Address Decoder (WAD), combinatorial process //----------------------------------------------------------------------------- // Mask top bit of write address to disable fp regfile - assign waddr_a = waddr_a_i; - assign waddr_b = waddr_b_i; + assign waddr_a = waddr_a_i; + assign waddr_b = waddr_b_i; genvar gidx; generate diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_register_file_latch.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_register_file_latch.sv index 037db7c46..217150c04 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_register_file_latch.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_register_file_latch.sv @@ -33,7 +33,9 @@ module cv32e40px_register_file #( parameter ADDR_WIDTH = 5, parameter DATA_WIDTH = 32, parameter FPU = 0, - parameter ZFINX = 0 + parameter ZFINX = 0, + parameter COREV_X_IF = 0, + parameter X_DUALREAD = 0 ) ( // Clock and Reset input logic clk, @@ -41,17 +43,19 @@ module cv32e40px_register_file #( input logic scan_cg_en_i, + input logic dualread_i, + //Read port R1 - input logic [ADDR_WIDTH-1:0] raddr_a_i, - output logic [DATA_WIDTH-1:0] rdata_a_o, + input logic [ADDR_WIDTH-1:0] raddr_a_i, + output logic [X_DUALREAD:0][DATA_WIDTH-1:0] rdata_a_o, //Read port R2 - input logic [ADDR_WIDTH-1:0] raddr_b_i, - output logic [DATA_WIDTH-1:0] rdata_b_o, + input logic [ADDR_WIDTH-1:0] raddr_b_i, + output logic [X_DUALREAD:0][DATA_WIDTH-1:0] rdata_b_o, //Read port R3 - input logic [ADDR_WIDTH-1:0] raddr_c_i, - output logic [DATA_WIDTH-1:0] rdata_c_o, + input logic [ADDR_WIDTH-1:0] raddr_c_i, + output logic [X_DUALREAD:0][DATA_WIDTH-1:0] rdata_c_o, // Write port W1 input logic [ADDR_WIDTH-1:0] waddr_a_i, @@ -98,10 +102,37 @@ module cv32e40px_register_file #( //----------------------------------------------------------------------------- //-- READ : Read address decoder RAD //----------------------------------------------------------------------------- - assign rdata_a_o = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]]; - assign rdata_b_o = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]]; - assign rdata_c_o = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4:0]]; - + generate + if (COREV_X_IF != 0) begin + if (X_DUALREAD) begin + always_comb begin + if (dualread_i) begin + rdata_a_o[0] = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]]; + rdata_b_o[0] = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]]; + rdata_c_o[0] = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4:0]]; + rdata_a_o[1] = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0] | 5'b00001] : mem[raddr_a_i[4:0] | 5'b00001]; + rdata_b_o[1] = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0] | 5'b00001] : mem[raddr_b_i[4:0] | 5'b00001]; + rdata_c_o[1] = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0] | 5'b00001] : mem[raddr_c_i[4:0] | 5'b00001]; + end else begin + rdata_a_o[0] = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]]; + rdata_b_o[0] = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]]; + rdata_c_o[0] = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4:0]]; + rdata_b_o[1] = '0; + rdata_a_o[1] = '0; + rdata_c_o[1] = '0; + end + end + end else begin + assign rdata_a_o = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]]; + assign rdata_b_o = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]]; + assign rdata_c_o = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4:0]]; + end + end else begin + assign rdata_a_o = raddr_a_i[5] ? mem_fp[raddr_a_i[4:0]] : mem[raddr_a_i[4:0]]; + assign rdata_b_o = raddr_b_i[5] ? mem_fp[raddr_b_i[4:0]] : mem[raddr_b_i[4:0]]; + assign rdata_c_o = raddr_c_i[5] ? mem_fp[raddr_c_i[4:0]] : mem[raddr_c_i[4:0]]; + end + endgenerate //----------------------------------------------------------------------------- // WRITE : SAMPLE INPUT DATA //--------------------------------------------------------------------------- diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_x_disp.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_x_disp.sv index 71bbf665f..fe1471241 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_x_disp.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_x_disp.sv @@ -33,11 +33,13 @@ module cv32e40px_x_disp input logic x_issue_ready_i, input logic x_issue_resp_accept_i, input logic x_issue_resp_writeback_i, - input logic x_issue_resp_loadstore_i, // unused - output logic [2:0] x_issue_req_rs_valid_o, - output logic [3:0] x_issue_req_id_o, - output logic [1:0] x_issue_req_mode_o, - output logic x_issue_req_ecs_valid, + + input logic [ 2:0] x_issue_resp_dualread_i, + input logic x_issue_resp_loadstore_i, // unused + output logic [RF_READ_PORTS-1:0] x_issue_req_rs_valid_o, + output logic [ 3:0] x_issue_req_id_o, + output logic [ 1:0] x_issue_req_mode_o, + output logic x_issue_req_ecs_valid, // commit interface output logic x_commit_valid_o, @@ -65,19 +67,19 @@ module cv32e40px_x_disp input logic x_result_we_i, // scoreboard, dependency check, stall, forwarding - input logic [4:0] waddr_id_i, - input logic [4:0] waddr_ex_i, - input logic [4:0] waddr_wb_i, - input logic we_ex_i, - input logic we_wb_i, - input logic [4:0] mem_instr_waddr_ex_i, - input logic mem_instr_we_ex_i, - input logic [2:0] regs_used_i, - input logic branch_or_jump_i, - input logic instr_valid_i, - input logic [2:0][4:0] x_rs_addr_i, - output logic [2:0] x_ex_fwd_o, - output logic [2:0] x_wb_fwd_o, + input logic [ 4:0] waddr_id_i, + input logic [ 4:0] waddr_ex_i, + input logic [ 4:0] waddr_wb_i, + input logic we_ex_i, + input logic we_wb_i, + input logic [ 4:0] mem_instr_waddr_ex_i, + input logic mem_instr_we_ex_i, + input logic [ 2:0] regs_used_i, + input logic branch_or_jump_i, + input logic instr_valid_i, + input logic [ 2:0][4:0] x_rs_addr_i, + output logic [RF_READ_PORTS-1:0] x_ex_fwd_o, + output logic [RF_READ_PORTS-1:0] x_wb_fwd_o, // memory request core-internal status signals output logic x_mem_data_req_o, @@ -109,14 +111,31 @@ module cv32e40px_x_disp // issue interface assign x_issue_valid_o = x_illegal_insn_dec_i & ~branch_or_jump_i & ~instr_offloaded_q & instr_valid_i & ~illegal_forwarding_prevention; assign x_issue_req_id_o = id_q; - assign x_issue_req_rs_valid_o[0] = (~scoreboard_q[x_rs_addr_i[0]] | x_ex_fwd_o[0] | x_wb_fwd_o[0]) - & ~(x_rs_addr_i[0] == mem_instr_waddr_ex_i & mem_instr_we_ex_i) & ~(x_rs_addr_i[0] == waddr_wb_i & ~ex_valid_i); - assign x_issue_req_rs_valid_o[1] = (~scoreboard_q[x_rs_addr_i[1]] | x_ex_fwd_o[1] | x_wb_fwd_o[1]) - & ~(x_rs_addr_i[1] == mem_instr_waddr_ex_i & mem_instr_we_ex_i) & ~(x_rs_addr_i[1] == waddr_wb_i & ~ex_valid_i); - assign x_issue_req_rs_valid_o[2] = (~scoreboard_q[x_rs_addr_i[2]] | x_ex_fwd_o[2] | x_wb_fwd_o[2]) - & ~(x_rs_addr_i[2] == mem_instr_waddr_ex_i & mem_instr_we_ex_i) & ~(x_rs_addr_i[2] == waddr_wb_i & ~ex_valid_i); - assign x_issue_req_ecs_valid = 1'b1; // extension context status is not implemented in cv32e40px - + generate + if (X_DUALREAD != 0) begin + assign x_issue_req_rs_valid_o[0] = (~scoreboard_q[x_rs_addr_i[0]] | x_ex_fwd_o[0] | x_wb_fwd_o[0]) + & ~(x_rs_addr_i[0] == mem_instr_waddr_ex_i & mem_instr_we_ex_i) & ~(x_rs_addr_i[0] == waddr_wb_i & ~ex_valid_i); + assign x_issue_req_rs_valid_o[1] = (~scoreboard_q[x_rs_addr_i[1]] | x_ex_fwd_o[1] | x_wb_fwd_o[1]) + & ~(x_rs_addr_i[1] == mem_instr_waddr_ex_i & mem_instr_we_ex_i) & ~(x_rs_addr_i[1] == waddr_wb_i & ~ex_valid_i); + assign x_issue_req_rs_valid_o[2] = (~scoreboard_q[x_rs_addr_i[2]] | x_ex_fwd_o[2] | x_wb_fwd_o[2]) + & ~(x_rs_addr_i[2] == mem_instr_waddr_ex_i & mem_instr_we_ex_i) & ~(x_rs_addr_i[2] == waddr_wb_i & ~ex_valid_i); + assign x_issue_req_rs_valid_o[3] = (~scoreboard_q[x_rs_addr_i[0] | 5'b00001] | x_ex_fwd_o[3] | x_wb_fwd_o[3]) + & ~((x_rs_addr_i[0] | 5'b00001) == mem_instr_waddr_ex_i & mem_instr_we_ex_i) & ~((x_rs_addr_i[0] | 5'b00001) == waddr_wb_i & ~ex_valid_i); + assign x_issue_req_rs_valid_o[4] = (~scoreboard_q[x_rs_addr_i[1] | 5'b00001] | x_ex_fwd_o[4] | x_wb_fwd_o[4]) + & ~((x_rs_addr_i[1] | 5'b00001) == mem_instr_waddr_ex_i & mem_instr_we_ex_i) & ~((x_rs_addr_i[1] | 5'b00001) == waddr_wb_i & ~ex_valid_i); + assign x_issue_req_rs_valid_o[5] = (~scoreboard_q[x_rs_addr_i[2] | 5'b00001] | x_ex_fwd_o[5] | x_wb_fwd_o[5]) + & ~((x_rs_addr_i[2] | 5'b00001) == mem_instr_waddr_ex_i & mem_instr_we_ex_i) & ~((x_rs_addr_i[2] | 5'b00001) == waddr_wb_i & ~ex_valid_i); + assign x_issue_req_ecs_valid = 1'b1; // extension context status is not implemented in cv32e40px + end else begin + assign x_issue_req_rs_valid_o[0] = (~scoreboard_q[x_rs_addr_i[0]] | x_ex_fwd_o[0] | x_wb_fwd_o[0]) + & ~(x_rs_addr_i[0] == mem_instr_waddr_ex_i & mem_instr_we_ex_i) & ~(x_rs_addr_i[0] == waddr_wb_i & ~ex_valid_i); + assign x_issue_req_rs_valid_o[1] = (~scoreboard_q[x_rs_addr_i[1]] | x_ex_fwd_o[1] | x_wb_fwd_o[1]) + & ~(x_rs_addr_i[1] == mem_instr_waddr_ex_i & mem_instr_we_ex_i) & ~(x_rs_addr_i[1] == waddr_wb_i & ~ex_valid_i); + assign x_issue_req_rs_valid_o[2] = (~scoreboard_q[x_rs_addr_i[2]] | x_ex_fwd_o[2] | x_wb_fwd_o[2]) + & ~(x_rs_addr_i[2] == mem_instr_waddr_ex_i & mem_instr_we_ex_i) & ~(x_rs_addr_i[2] == waddr_wb_i & ~ex_valid_i); + assign x_issue_req_ecs_valid = 1'b1; // extension context status is not implemented in cv32e40px + end + endgenerate // commit interface assign x_commit_valid_o = x_issue_valid_o; assign x_commit_id_o = id_q; @@ -140,22 +159,46 @@ module cv32e40px_x_disp // core stall signal assign x_stall_o = dep | outstanding_mem | x_if_not_ready | x_if_memory_instr | illegal_forwarding_prevention; - assign dep = ~x_illegal_insn_o & ((regs_used_i[0] & scoreboard_q[x_rs_addr_i[0]] & (x_result_rd_i != x_rs_addr_i[0])) - | (regs_used_i[1] & scoreboard_q[x_rs_addr_i[1]] & (x_result_rd_i != x_rs_addr_i[1])) - | (regs_used_i[2] & scoreboard_q[x_rs_addr_i[2]] & (x_result_rd_i != x_rs_addr_i[2]))); + assign outstanding_mem = data_req_dec_i & (mem_counter_q != '0); assign x_if_memory_instr = x_mem_data_req_o & ~(x_issue_valid_o & x_issue_ready_i); assign x_if_not_ready = x_issue_valid_o & ~x_issue_ready_i; - assign illegal_forwarding_prevention = x_result_valid_i & (x_ex_fwd_o[0] | x_ex_fwd_o[1] | x_ex_fwd_o[2]); + assign illegal_forwarding_prevention = x_result_valid_i & (|x_ex_fwd_o); // forwarding - assign x_ex_fwd_o[0] = x_rs_addr_i[0] == waddr_ex_i & we_ex_i & ex_valid_i; - assign x_ex_fwd_o[1] = x_rs_addr_i[1] == waddr_ex_i & we_ex_i & ex_valid_i; - assign x_ex_fwd_o[2] = x_rs_addr_i[2] == waddr_ex_i & we_ex_i & ex_valid_i; - assign x_wb_fwd_o[0] = x_rs_addr_i[0] == waddr_wb_i & we_wb_i & ex_valid_i; - assign x_wb_fwd_o[1] = x_rs_addr_i[1] == waddr_wb_i & we_wb_i & ex_valid_i; - assign x_wb_fwd_o[2] = x_rs_addr_i[2] == waddr_wb_i & we_wb_i & ex_valid_i; + generate + if (X_DUALREAD != 0) begin + assign x_ex_fwd_o[0] = x_rs_addr_i[0] == waddr_ex_i & we_ex_i & ex_valid_i; + assign x_ex_fwd_o[1] = x_rs_addr_i[1] == waddr_ex_i & we_ex_i & ex_valid_i; + assign x_ex_fwd_o[2] = x_rs_addr_i[2] == waddr_ex_i & we_ex_i & ex_valid_i; + assign x_ex_fwd_o[3] = (x_rs_addr_i[0] | 5'b00001) == waddr_ex_i & we_ex_i & ex_valid_i & x_issue_resp_dualread_i[0]; + assign x_ex_fwd_o[4] = (x_rs_addr_i[1] | 5'b00001) == waddr_ex_i & we_ex_i & ex_valid_i & x_issue_resp_dualread_i[1]; + assign x_ex_fwd_o[5] = (x_rs_addr_i[2] | 5'b00001) == waddr_ex_i & we_ex_i & ex_valid_i & x_issue_resp_dualread_i[2]; + assign x_wb_fwd_o[0] = x_rs_addr_i[0] == waddr_wb_i & we_wb_i & ex_valid_i; + assign x_wb_fwd_o[1] = x_rs_addr_i[1] == waddr_wb_i & we_wb_i & ex_valid_i; + assign x_wb_fwd_o[2] = x_rs_addr_i[2] == waddr_wb_i & we_wb_i & ex_valid_i; + assign x_wb_fwd_o[3] = (x_rs_addr_i[0] | 5'b00001) == waddr_wb_i & we_wb_i & ex_valid_i & x_issue_resp_dualread_i[0]; + assign x_wb_fwd_o[4] = (x_rs_addr_i[1] | 5'b00001) == waddr_wb_i & we_wb_i & ex_valid_i & x_issue_resp_dualread_i[1]; + assign x_wb_fwd_o[5] = (x_rs_addr_i[2] | 5'b00001) == waddr_wb_i & we_wb_i & ex_valid_i & x_issue_resp_dualread_i[2]; + assign dep = ~x_illegal_insn_o & ((regs_used_i[0] & scoreboard_q[x_rs_addr_i[0]] & (x_result_rd_i != x_rs_addr_i[0])) + | (regs_used_i[1] & scoreboard_q[x_rs_addr_i[1]] & (x_result_rd_i != x_rs_addr_i[1])) + | (regs_used_i[2] & scoreboard_q[x_rs_addr_i[2]] & (x_result_rd_i != x_rs_addr_i[2])) + | (((regs_used_i[0] & x_issue_resp_dualread_i[0]) & scoreboard_q[x_rs_addr_i[0] | 5'b00001] & (x_result_rd_i != (x_rs_addr_i[0] | 5'b00001))) & x_issue_resp_dualread_i[0]) + | (((regs_used_i[1] & x_issue_resp_dualread_i[1]) & scoreboard_q[x_rs_addr_i[1] | 5'b00001] & (x_result_rd_i != (x_rs_addr_i[1] | 5'b00001))) & x_issue_resp_dualread_i[1]) + | (((regs_used_i[2] & x_issue_resp_dualread_i[2]) & scoreboard_q[x_rs_addr_i[2] | 5'b00001] & (x_result_rd_i != (x_rs_addr_i[2] | 5'b00001))) & x_issue_resp_dualread_i[2])); + end else begin + assign x_ex_fwd_o[0] = x_rs_addr_i[0] == waddr_ex_i & we_ex_i & ex_valid_i; + assign x_ex_fwd_o[1] = x_rs_addr_i[1] == waddr_ex_i & we_ex_i & ex_valid_i; + assign x_ex_fwd_o[2] = x_rs_addr_i[2] == waddr_ex_i & we_ex_i & ex_valid_i; + assign x_wb_fwd_o[0] = x_rs_addr_i[0] == waddr_wb_i & we_wb_i & ex_valid_i; + assign x_wb_fwd_o[1] = x_rs_addr_i[1] == waddr_wb_i & we_wb_i & ex_valid_i; + assign x_wb_fwd_o[2] = x_rs_addr_i[2] == waddr_wb_i & we_wb_i & ex_valid_i; + assign dep = ~x_illegal_insn_o & ((regs_used_i[0] & scoreboard_q[x_rs_addr_i[0]] & (x_result_rd_i != x_rs_addr_i[0])) + | (regs_used_i[1] & scoreboard_q[x_rs_addr_i[1]] & (x_result_rd_i != x_rs_addr_i[1])) + | (regs_used_i[2] & scoreboard_q[x_rs_addr_i[2]] & (x_result_rd_i != x_rs_addr_i[2]))); + end + endgenerate // id generation assign x_compressed_id_o = id_d; diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/include/cv32e40px_core_v_xif_pkg.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/include/cv32e40px_core_v_xif_pkg.sv index 499fec318..678635d05 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/include/cv32e40px_core_v_xif_pkg.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/include/cv32e40px_core_v_xif_pkg.sv @@ -15,6 +15,7 @@ package cv32e40px_core_v_xif_pkg; // cv-x-if parameters parameter int X_NUM_RS = 3; + parameter int X_DUALREAD = 0; // 0: single read, 1: dual read parameter int X_ID_WIDTH = 4; parameter int X_MEM_WIDTH = 32; parameter int X_RFR_WIDTH = 32; @@ -23,6 +24,8 @@ package cv32e40px_core_v_xif_pkg; parameter logic [1:0] X_ECS_XS = '0; localparam int XLEN = 32; + localparam int RF_READ_PORTS = (X_DUALREAD == 1) ? 2 * X_NUM_RS : X_NUM_RS; + typedef struct packed { logic [15:0] instr; // Offloaded compressed instruction @@ -39,8 +42,8 @@ package cv32e40px_core_v_xif_pkg; logic [31:0] instr; // Offloaded instruction logic [1:0] mode; // Privilege level logic [X_ID_WIDTH-1:0] id; // Identification of the offloaded instruction - logic [X_NUM_RS -1:0][X_RFR_WIDTH-1:0] rs; // Register file source operands for the offloaded instruction - logic [X_NUM_RS -1:0] rs_valid; // Validity of the register file source operand(s) + logic [RF_READ_PORTS-1:0][X_RFR_WIDTH-1:0] rs; // Register file source operands for the offloaded instruction + logic [RF_READ_PORTS-1:0] rs_valid; // Validity of the register file source operand(s) logic [5:0] ecs; // Extension Context Status ({mstatus.xs, mstatus.fs, mstatus.vs}) logic ecs_valid; // Validity of the Extension Context Status } x_issue_req_t; diff --git a/hw/vendor/patches/esl_epfl_cv32e40px/0001-vendor-cv32e40px-Re-vendor.patch b/hw/vendor/patches/esl_epfl_cv32e40px/0001-vendor-cv32e40px-Re-vendor.patch deleted file mode 100644 index 28ab47b19..000000000 --- a/hw/vendor/patches/esl_epfl_cv32e40px/0001-vendor-cv32e40px-Re-vendor.patch +++ /dev/null @@ -1,44 +0,0 @@ -diff --git a/rtl/cv32e40px_cs_registers.sv b/rtl/cv32e40px_cs_registers.sv -index 1f1d56b..cdc6433 100644 ---- a/rtl/cv32e40px_cs_registers.sv -+++ b/rtl/cv32e40px_cs_registers.sv -@@ -1450,7 +1450,7 @@ module cv32e40px_cs_registers - // minstret is located at index 2 - // Programable HPM counters start at index 3 - if ((cnt_gidx == 1) || (cnt_gidx >= (NUM_MHPMCOUNTERS + 3))) begin : gen_non_implemented -- assign mhpmcounter_q[cnt_gidx] = 'b0; -+ always_ff @(posedge clk) mhpmcounter_q[cnt_gidx] <= 'b0; - end else begin : gen_implemented - always_ff @(posedge clk, negedge rst_n) - if (!rst_n) begin -@@ -1478,10 +1478,10 @@ module cv32e40px_cs_registers - for (evt_gidx = 0; evt_gidx < 32; evt_gidx++) begin : gen_mhpmevent - // programable HPM events start at index3 - if ((evt_gidx < 3) || (evt_gidx >= (NUM_MHPMCOUNTERS + 3))) begin : gen_non_implemented -- assign mhpmevent_q[evt_gidx] = 'b0; -+ always_ff @(posedge clk) mhpmevent_q[evt_gidx] <= 'b0; - end else begin : gen_implemented - if (NUM_HPM_EVENTS < 32) begin : gen_tie_off -- assign mhpmevent_q[evt_gidx][31:NUM_HPM_EVENTS] = 'b0; -+ always_ff @(posedge clk) mhpmevent_q[evt_gidx][31:NUM_HPM_EVENTS] <= 'b0; - end - always_ff @(posedge clk, negedge rst_n) - if (!rst_n) mhpmevent_q[evt_gidx][NUM_HPM_EVENTS-1:0] <= 'b0; -@@ -1499,7 +1499,7 @@ module cv32e40px_cs_registers - (en_gidx == 1) || - (en_gidx >= (NUM_MHPMCOUNTERS+3) ) ) - begin : gen_non_implemented -- assign mcounteren_q[en_gidx] = 'b0; -+ always_ff @(posedge clk) mcounteren_q[en_gidx] <= 'b0; - end else begin : gen_implemented - always_ff @(posedge clk, negedge rst_n) - if (!rst_n) mcounteren_q[en_gidx] <= 'b0; // default disable -@@ -1514,7 +1514,7 @@ module cv32e40px_cs_registers - generate - for (inh_gidx = 0; inh_gidx < 32; inh_gidx++) begin : gen_mcountinhibit - if ((inh_gidx == 1) || (inh_gidx >= (NUM_MHPMCOUNTERS + 3))) begin : gen_non_implemented -- assign mcountinhibit_q[inh_gidx] = 'b0; -+ always_ff @(posedge clk) mcountinhibit_q[inh_gidx] <= 'b0; - end else begin : gen_implemented - always_ff @(posedge clk, negedge rst_n) - if (!rst_n) mcountinhibit_q[inh_gidx] <= 'b1; // default disable