From d33c54edc8488d44f95d4b45f75e99a101a77e29 Mon Sep 17 00:00:00 2001 From: Farhan Ali Date: Fri, 22 Nov 2024 20:19:37 +0500 Subject: [PATCH 01/10] Adding support for zcmt --- core/Flist.cva6 | 1 + core/branch_unit.sv | 24 +- core/compressed_decoder.sv | 10 +- core/csr_regfile.sv | 21 +- core/cva6.sv | 38 ++- core/cva6_rvfi.sv | 1 + core/decoder.sv | 7 +- core/ex_stage.sv | 7 +- core/id_stage.sv | 83 ++++++- core/include/build_config_pkg.sv | 1 + core/include/config_pkg.sv | 4 + core/include/cv32a60x_config_pkg.sv | 3 +- core/include/cv32a65x_config_pkg.sv | 1 + .../cv32a6_embedded_config_pkg_deprecated.sv | 2 + .../cv32a6_ima_sv32_fpga_config_pkg.sv | 2 + core/include/cv32a6_imac_sv0_config_pkg.sv | 2 + core/include/cv32a6_imac_sv32_config_pkg.sv | 2 + core/include/cv32a6_imafc_sv32_config_pkg.sv | 2 + .../cv64a6_imadfcv_sv39_polara_config_pkg.sv | 2 + core/include/cv64a6_imafdc_sv39_config_pkg.sv | 2 + .../cv64a6_imafdc_sv39_hpdcache_config_pkg.sv | 2 + ...cv64a6_imafdc_sv39_openpiton_config_pkg.sv | 2 + .../cv64a6_imafdc_sv39_wb_config_pkg.sv | 2 + .../include/cv64a6_imafdch_sv39_config_pkg.sv | 2 + .../cv64a6_imafdch_sv39_wb_config_pkg.sv | 2 + .../include/cv64a6_imafdcv_sv39_config_pkg.sv | 2 + core/include/cv64a6_mmu_config_pkg.sv | 1 + core/include/riscv_pkg.sv | 13 + core/include/rvfi_types.svh | 2 + core/issue_read_operands.sv | 9 +- core/issue_stage.sv | 10 +- core/zcmt_decoder.sv | 225 ++++++++++++++++++ verif/tests/custom/zcmt/cm_jalt.S | 62 +++++ verif/tests/custom/zcmt/cm_jalt_ret.S | 62 +++++ verif/tests/custom/zcmt/cm_jt.S | 58 +++++ verif/tests/custom/zcmt/jvt_csr.S | 51 ++++ 36 files changed, 696 insertions(+), 24 deletions(-) create mode 100644 core/zcmt_decoder.sv create mode 100644 verif/tests/custom/zcmt/cm_jalt.S create mode 100644 verif/tests/custom/zcmt/cm_jalt_ret.S create mode 100644 verif/tests/custom/zcmt/cm_jt.S create mode 100644 verif/tests/custom/zcmt/jvt_csr.S diff --git a/core/Flist.cva6 b/core/Flist.cva6 index cac849e2b7..8005a35f1e 100644 --- a/core/Flist.cva6 +++ b/core/Flist.cva6 @@ -110,6 +110,7 @@ ${CVA6_REPO_DIR}/core/branch_unit.sv ${CVA6_REPO_DIR}/core/compressed_decoder.sv ${CVA6_REPO_DIR}/core/macro_decoder.sv ${CVA6_REPO_DIR}/core/controller.sv +${CVA6_REPO_DIR}/core/zcmt_decoder.sv ${CVA6_REPO_DIR}/core/csr_buffer.sv ${CVA6_REPO_DIR}/core/csr_regfile.sv ${CVA6_REPO_DIR}/core/decoder.sv diff --git a/core/branch_unit.sv b/core/branch_unit.sv index 0688836639..717bfdf3e4 100644 --- a/core/branch_unit.sv +++ b/core/branch_unit.sv @@ -46,10 +46,18 @@ module branch_unit #( // Branch is resolved, new entries can be accepted by scoreboard - ID_STAGE output logic resolve_branch_o, // Branch exception out - TO_BE_COMPLETED - output exception_t branch_exception_o + output exception_t branch_exception_o, + //zcmt + input logic is_zcmt_i ); logic [CVA6Cfg.VLEN-1:0] target_address; logic [CVA6Cfg.VLEN-1:0] next_pc; + logic is_zcmt_q; + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (~rst_ni) is_zcmt_q <= '0; + else is_zcmt_q <= is_zcmt_i; + end // here we handle the various possibilities of mis-predicts always_comb begin : mispredict_handler @@ -79,9 +87,17 @@ module branch_unit #( // 1. Branches // 2. Jumps to register addresses if (branch_valid_i) begin - // write target address which goes to PC Gen - resolved_branch_o.target_address = (branch_comp_res_i) ? target_address : next_pc; - resolved_branch_o.is_taken = branch_comp_res_i; + if (is_zcmt_q) begin + // Unconditional jump handling + resolved_branch_o.is_taken = 1'b1; + resolved_branch_o.is_mispredict = 1'b1; // miss prediction for ZCMT + resolved_branch_o.target_address = target_address; // Use calculated address directly + resolved_branch_o.cf_type = ariane_pkg::Jump; + end else begin + // write target address which goes to PC Gen + resolved_branch_o.target_address = (branch_comp_res_i) ? target_address : next_pc; + resolved_branch_o.is_taken = branch_comp_res_i; + end // check the outcome of the branch speculation if (ariane_pkg::op_is_branch(fu_data_i.operation)) begin // Set the `cf_type` of the output as `branch`, this will update the BHT. diff --git a/core/compressed_decoder.sv b/core/compressed_decoder.sv index 1f09fd1f29..5278f40a21 100644 --- a/core/compressed_decoder.sv +++ b/core/compressed_decoder.sv @@ -31,7 +31,9 @@ module compressed_decoder #( // Output instruction is macro - decoder output logic is_macro_instr_o, // Output instruction is compressed - decoder - output logic is_compressed_o + output logic is_compressed_o, + // Output instruction is macro - decoder + output logic is_zcmt_instr_o ); // ------------------- @@ -42,6 +44,7 @@ module compressed_decoder #( is_compressed_o = 1'b1; instr_o = instr_i; is_macro_instr_o = 0; + is_zcmt_instr_o = 0; // I: | imm[11:0] | rs1 | funct3 | rd | opcode | // S: | imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode | @@ -867,10 +870,13 @@ module compressed_decoder #( 3'b000, riscv::OpcodeStoreFp }; - end else if (CVA6Cfg.RVZCMP) begin + end else if (CVA6Cfg.RVZCMP || CVA6Cfg.RVZCMT) begin if (instr_i[12:10] == 3'b110 || instr_i[12:10] == 3'b111 || instr_i[12:10] == 3'b011) begin //is a push/pop instruction is_macro_instr_o = 1; instr_o = instr_i; + end else if (instr_i[12:10] == 3'b000) begin //jt/jalt instruction + is_zcmt_instr_o = 1; + instr_o = instr_i; end else begin illegal_instr_o = 1'b1; end diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 296a8d7916..cfe5f35b13 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -167,7 +167,10 @@ module csr_regfile // TO_BE_COMPLETED - PERF_COUNTERS output logic [31:0] mcountinhibit_o, // RVFI - output rvfi_probes_csr_t rvfi_csr_o + output rvfi_probes_csr_t rvfi_csr_o, + //jvt output + output logic [CVA6Cfg.XLEN-1:6] jvt_base_o, + output logic [5:0] jvt_mode_o ); localparam logic [63:0] SMODE_STATUS_READ_MASK = ariane_pkg::smode_status_read_mask(CVA6Cfg); @@ -295,6 +298,7 @@ module csr_regfile assign pmpaddr_o = pmpaddr_q[(CVA6Cfg.NrPMPEntries>0?CVA6Cfg.NrPMPEntries-1 : 0):0]; riscv::fcsr_t fcsr_q, fcsr_d; + riscv::jvt_t jvt_q, jvt_d; // ---------------- // Assignments // ---------------- @@ -350,6 +354,9 @@ module csr_regfile read_access_exception = 1'b1; end end + riscv::CSR_JVT: begin + csr_rdata = {jvt_q.base, jvt_q.mode}; + end // non-standard extension riscv::CSR_FTRAN: begin if (CVA6Cfg.FpPresent && !(mstatus_q.fs == riscv::Off || (CVA6Cfg.RVH && v_q && vsstatus_q.fs == riscv::Off))) begin @@ -908,7 +915,7 @@ module csr_regfile perf_we_o = 1'b0; perf_data_o = 'b0; - + jvt_d = jvt_q; fcsr_d = fcsr_q; priv_lvl_d = priv_lvl_q; @@ -1060,6 +1067,10 @@ module csr_regfile riscv::CSR_DSCRATCH1: if (CVA6Cfg.DebugEn) dscratch1_d = csr_wdata; else update_access_exception = 1'b1; + riscv::CSR_JVT: begin + jvt_d.base = csr_wdata[CVA6Cfg.XLEN-1:6]; + jvt_d.mode = 6'b000000; + end // trigger module CSRs riscv::CSR_TSELECT: update_access_exception = 1'b1; // not implemented riscv::CSR_TDATA1: update_access_exception = 1'b1; // not implemented @@ -2452,6 +2463,9 @@ module csr_regfile assign fflags_o = fcsr_q.fflags; assign frm_o = fcsr_q.frm; assign fprec_o = fcsr_q.fprec; + //JVT outputs + assign jvt_base_o = jvt_q.base; + assign jvt_mode_o = jvt_q.mode; // MMU outputs assign satp_ppn_o = CVA6Cfg.RVS ? satp_q.ppn : '0; assign vsatp_ppn_o = CVA6Cfg.RVH ? vsatp_q.ppn : '0; @@ -2518,6 +2532,7 @@ module csr_regfile priv_lvl_q <= riscv::PRIV_LVL_M; // floating-point registers fcsr_q <= '0; + jvt_q <= '0; // debug signals debug_mode_q <= 1'b0; if (CVA6Cfg.DebugEn) begin @@ -2601,6 +2616,7 @@ module csr_regfile priv_lvl_q <= priv_lvl_d; // floating-point registers fcsr_q <= fcsr_d; + jvt_q <= jvt_d; // debug signals if (CVA6Cfg.DebugEn) begin debug_mode_q <= debug_mode_d; @@ -2722,6 +2738,7 @@ module csr_regfile // RVFI //------------- assign rvfi_csr_o.fcsr_q = CVA6Cfg.FpPresent ? fcsr_q : '0; + assign rvfi_csr_o.jvt_q = jvt_q; assign rvfi_csr_o.dcsr_q = CVA6Cfg.DebugEn ? dcsr_q : '0; assign rvfi_csr_o.dpc_q = CVA6Cfg.DebugEn ? dpc_q : '0; assign rvfi_csr_o.dscratch0_q = CVA6Cfg.DebugEn ? dscratch0_q : '0; diff --git a/core/cva6.sv b/core/cva6.sv index ffb6d28460..c5997bd561 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -563,6 +563,10 @@ module cva6 riscv::pmpcfg_t [CVA6Cfg.NrPMPEntries-1:0] pmpcfg; logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr; logic [31:0] mcountinhibit_csr_perf; + //jvt + logic [CVA6Cfg.XLEN-1:6] jvt_base; + logic [5:0] jvt_mode; + logic is_zcmt_id_is, is_zcmt_is_ex; // ---------------------------- // Performance Counters <-> * // ---------------------------- @@ -617,6 +621,8 @@ module cva6 // ---------------- dcache_req_i_t [2:0] dcache_req_ports_ex_cache; dcache_req_o_t [2:0] dcache_req_ports_cache_ex; + dcache_req_i_t dcache_req_ports_id_cache; + dcache_req_o_t dcache_req_ports_cache_id; dcache_req_i_t [1:0] dcache_req_ports_acc_cache; dcache_req_o_t [1:0] dcache_req_ports_cache_acc; logic dcache_commit_wbuffer_empty; @@ -671,6 +677,8 @@ module cva6 id_stage #( .CVA6Cfg(CVA6Cfg), .branchpredict_sbe_t(branchpredict_sbe_t), + .dcache_req_i_t(dcache_req_i_t), + .dcache_req_o_t(dcache_req_o_t), .exception_t(exception_t), .fetch_entry_t(fetch_entry_t), .irq_ctrl_t(irq_ctrl_t), @@ -716,7 +724,13 @@ module cva6 .compressed_ready_i(x_compressed_ready), .compressed_resp_i (x_compressed_resp), .compressed_valid_o(x_compressed_valid), - .compressed_req_o (x_compressed_req) + .compressed_req_o (x_compressed_req), + .jvt_base_i (jvt_base), + .jvt_mode_i (jvt_mode), + .is_zcmt_o (is_zcmt_id_is), + // DCACHE interfaces + .dcache_req_ports_i(dcache_req_ports_cache_id), + .dcache_req_ports_o(dcache_req_ports_id_cache) ); logic [CVA6Cfg.NrWbPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] trans_id_ex_id; @@ -812,6 +826,8 @@ module cva6 .decoded_instr_valid_i (issue_entry_valid_id_issue), .is_ctrl_flow_i (is_ctrl_fow_id_issue), .decoded_instr_ack_o (issue_instr_issue_id), + .is_zcmt_i (is_zcmt_id_is), + .is_zcmt_o (is_zcmt_is_ex), // Functional Units .rs1_forwarding_o (rs1_forwarding_id_ex), .rs2_forwarding_o (rs2_forwarding_id_ex), @@ -1018,7 +1034,8 @@ module cva6 .pmpaddr_i (pmpaddr), //RVFI .rvfi_lsu_ctrl_o (rvfi_lsu_ctrl), - .rvfi_mem_paddr_o (rvfi_mem_paddr) + .rvfi_mem_paddr_o (rvfi_mem_paddr), + .is_zcmt_i (is_zcmt_is_ex) ); // --------- @@ -1154,6 +1171,8 @@ module cva6 .pmpcfg_o (pmpcfg), .pmpaddr_o (pmpaddr), .mcountinhibit_o (mcountinhibit_csr_perf), + .jvt_base_o (jvt_base), + .jvt_mode_o (jvt_mode), //RVFI .rvfi_csr_o (rvfi_csr) ); @@ -1258,15 +1277,24 @@ module cva6 dcache_req_o_t [NumPorts-1:0] dcache_req_from_cache; // D$ request - assign dcache_req_to_cache[0] = dcache_req_ports_ex_cache[0]; + // D$ request + if (CVA6Cfg.RVZCMT) begin + assign dcache_req_to_cache[0] = dcache_req_ports_id_cache; + end else begin + assign dcache_req_to_cache[0] = dcache_req_ports_ex_cache[0]; + end assign dcache_req_to_cache[1] = dcache_req_ports_ex_cache[1]; assign dcache_req_to_cache[2] = dcache_req_ports_acc_cache[0]; assign dcache_req_to_cache[3] = dcache_req_ports_ex_cache[2].data_req ? dcache_req_ports_ex_cache [2] : dcache_req_ports_acc_cache[1]; // D$ response - assign dcache_req_ports_cache_ex[0] = dcache_req_from_cache[0]; - assign dcache_req_ports_cache_ex[1] = dcache_req_from_cache[1]; + if (CVA6Cfg.RVZCMT) begin + assign dcache_req_ports_cache_id = dcache_req_from_cache[0]; + end else begin + assign dcache_req_ports_cache_ex[0] = dcache_req_from_cache[0]; + end + assign dcache_req_ports_cache_ex[1] = dcache_req_from_cache[1]; assign dcache_req_ports_cache_acc[0] = dcache_req_from_cache[2]; always_comb begin : gen_dcache_req_store_data_gnt dcache_req_ports_cache_ex[2] = dcache_req_from_cache[3]; diff --git a/core/cva6_rvfi.sv b/core/cva6_rvfi.sv index 83e197e0c5..944f5cbbd6 100644 --- a/core/cva6_rvfi.sv +++ b/core/cva6_rvfi.sv @@ -344,6 +344,7 @@ module cva6_rvfi `CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, fflags, csr.fcsr_q.fflags) `CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, frm, csr.fcsr_q.frm) `CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, fcsr, { csr.fcsr_q.frm `COMMA csr.fcsr_q.fflags}) + `CONNECT_RVFI_FULL(1, jvt, { csr.jvt_q.base `COMMA csr.jvt_q.mode}) `CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, ftran, csr.fcsr_q.fprec) `CONNECT_RVFI_SAME(CVA6Cfg.FpPresent, dcsr) diff --git a/core/decoder.sv b/core/decoder.sv index 65e7c22450..55b4de761a 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -85,7 +85,10 @@ module decoder // Instruction - ISSUE_STAGE output logic [31:0] orig_instr_o, // Is a control flow instruction - ISSUE_STAGE - output logic is_control_flow_instr_o + output logic is_control_flow_instr_o, + //zcmt instruction + input logic is_zcmt_i, + output logic is_zcmt_o ); logic illegal_instr; logic illegal_instr_bm; @@ -181,6 +184,7 @@ module decoder ecall = 1'b0; ebreak = 1'b0; check_fprm = 1'b0; + is_zcmt_o = 1'b0; if (~ex_i.valid) begin case (instr.rtype.opcode) @@ -1404,6 +1408,7 @@ module decoder imm_select = JIMM; instruction_o.rd = instr.utype.rd; is_control_flow_instr_o = 1'b1; + is_zcmt_o = is_zcmt_i; end riscv::OpcodeAuipc: begin diff --git a/core/ex_stage.sv b/core/ex_stage.sv index 115c17f1c5..4d7338586a 100644 --- a/core/ex_stage.sv +++ b/core/ex_stage.sv @@ -228,7 +228,9 @@ module ex_stage // Information dedicated to RVFI - RVFI output lsu_ctrl_t rvfi_lsu_ctrl_o, // Information dedicated to RVFI - RVFI - output [CVA6Cfg.PLEN-1:0] rvfi_mem_paddr_o + output [CVA6Cfg.PLEN-1:0] rvfi_mem_paddr_o, + //zcmt instruction + input logic is_zcmt_i ); // ------------------------- @@ -327,7 +329,8 @@ module ex_stage .branch_predict_i, .resolved_branch_o, .resolve_branch_o, - .branch_exception_o(flu_exception_o) + .branch_exception_o(flu_exception_o), + .is_zcmt_i (is_zcmt_i) ); // 3. CSR (sequential) diff --git a/core/id_stage.sv b/core/id_stage.sv index 43583bde01..b318856e98 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -16,6 +16,8 @@ module id_stage #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter type branchpredict_sbe_t = logic, + parameter type dcache_req_i_t = logic, + parameter type dcache_req_o_t = logic, parameter type exception_t = logic, parameter type fetch_entry_t = logic, parameter type irq_ctrl_t = logic, @@ -83,9 +85,17 @@ module id_stage #( // CVXIF Compressed interface input logic [CVA6Cfg.XLEN-1:0] hart_id_i, input logic compressed_ready_i, + //JVT base + input logic [CVA6Cfg.XLEN-1:6] jvt_base_i, + input logic [5:0] jvt_mode_i, + output logic is_zcmt_o, input x_compressed_resp_t compressed_resp_i, output logic compressed_valid_o, - output x_compressed_req_t compressed_req_o + output x_compressed_req_t compressed_req_o, + // Data cache request ouput - CACHE + input dcache_req_o_t dcache_req_ports_i, + // Data cache request input - CACHE + output dcache_req_i_t dcache_req_ports_o ); // ID/ISSUE register stage typedef struct packed { @@ -115,6 +125,13 @@ module id_stage #( logic stall_macro_deco; logic is_last_macro_instr_o; logic is_double_rd_macro_instr_o; + logic [CVA6Cfg.NrIssuePorts-1:0] is_zcmt_instr_i; + branchpredict_sbe_t branch_predict; + logic is_zcmt; + logic is_zcmt_q, is_zcmt_n, is_zcmt_o2; + + assign is_zcmt_n = is_zcmt_o2; + assign is_zcmt_o = is_zcmt_q; if (CVA6Cfg.RVC) begin // --------------------------------------------------------- @@ -128,7 +145,8 @@ module id_stage #( .instr_o (compressed_instr[i]), .illegal_instr_o (is_illegal[i]), .is_compressed_o (is_compressed[i]), - .is_macro_instr_o(is_macro_instr_i[i]) + .is_macro_instr_o(is_macro_instr_i[i]), + .is_zcmt_instr_o (is_zcmt_instr_i[i]) ); end if (CVA6Cfg.RVZCMP) begin @@ -176,6 +194,57 @@ module id_stage #( .compressed_valid_o(compressed_valid_o), .compressed_req_o (compressed_req_o) ); + end else if (CVA6Cfg.RVZCMT) begin + zcmt_decoder #( + .CVA6Cfg(CVA6Cfg), + .dcache_req_i_t(dcache_req_i_t), + .dcache_req_o_t(dcache_req_o_t), + .branchpredict_sbe_t(branchpredict_sbe_t) + ) zcmt_decoder_i ( + .instr_i (compressed_instr[0]), + .pc_i (fetch_entry_i[0].address), + .is_zcmt_instr_i(is_zcmt_instr_i[0]), + .clk_i (clk_i), + .rst_ni (rst_ni), + .instr_o (instruction_cvxif[0]), + .illegal_instr_i(is_illegal[0]), + .is_compressed_i(is_compressed[0]), + .issue_ack_i (issue_instr_ack_i[0]), + .illegal_instr_o(is_illegal_cvxif[0]), + .is_compressed_o(is_compressed_cvxif[0]), + .fetch_stall_o (stall_macro_deco), + .jvt_base_i (jvt_base_i), + .jvt_mode_i (jvt_mode_i), + .is_zcmt_o (is_zcmt), + .req_port_i (dcache_req_ports_i), + .req_port_o (dcache_req_ports_o) + ); + if (CVA6Cfg.SuperscalarEn) begin + assign instruction_cvxif[CVA6Cfg.NrIssuePorts-1] = '0; + assign is_illegal_cvxif[CVA6Cfg.NrIssuePorts-1] = '0; + assign is_compressed_cvxif[CVA6Cfg.NrIssuePorts-1] = '0; + end + cvxif_compressed_if_driver #( + .CVA6Cfg(CVA6Cfg), + .x_compressed_req_t(x_compressed_req_t), + .x_compressed_resp_t(x_compressed_resp_t) + ) i_cvxif_compressed_if_driver_i ( + .clk_i (clk_i), + .rst_ni (rst_ni), + .hart_id_i (hart_id_i), + .is_compressed_i (is_compressed_cvxif), + .is_illegal_i (is_illegal_cvxif), + .instruction_i (instruction_cvxif), + .is_compressed_o (is_compressed_cmp), + .is_illegal_o (is_illegal_cmp), + .instruction_o (instruction), + .stall_i (stall_macro_deco), + .stall_o (stall_instr_fetch), + .compressed_ready_i(compressed_ready_i), + .compressed_resp_i (compressed_resp_i), + .compressed_valid_o(compressed_valid_o), + .compressed_req_o (compressed_req_o) + ); end else begin cvxif_compressed_if_driver #( .CVA6Cfg(CVA6Cfg), @@ -208,6 +277,7 @@ module id_stage #( assign is_illegal_cmp = '0; assign is_compressed_cmp = '0; assign is_macro_instr_i = '0; + assign is_zcmt_instr_i = '0; assign is_last_macro_instr_o = '0; assign is_double_rd_macro_instr_o = '0; if (CVA6Cfg.CvxifEn) begin @@ -237,6 +307,8 @@ module id_stage #( .pc_i (fetch_entry_i[i].address), .is_compressed_i (is_compressed_cmp[i]), .is_macro_instr_i (is_macro_instr_i[i]), + .is_zcmt_i (is_zcmt), + .is_zcmt_o (is_zcmt_o2), .is_last_macro_instr_i (is_last_macro_instr_o), .is_double_rd_macro_instr_i(is_double_rd_macro_instr_o), .is_illegal_i (is_illegal_cmp[i]), @@ -342,9 +414,12 @@ module id_stage #( // ------------------------- always_ff @(posedge clk_i or negedge rst_ni) begin if (~rst_ni) begin - issue_q <= '0; + issue_q <= '0; + is_zcmt_q <= '0; end else begin - issue_q <= issue_n; + issue_q <= issue_n; + is_zcmt_q <= is_zcmt_n; end end endmodule + diff --git a/core/include/build_config_pkg.sv b/core/include/build_config_pkg.sv index 5d4808bb1c..7b76714a8c 100644 --- a/core/include/build_config_pkg.sv +++ b/core/include/build_config_pkg.sv @@ -69,6 +69,7 @@ package build_config_pkg; cfg.RVC = CVA6Cfg.RVC; cfg.RVH = CVA6Cfg.RVH; cfg.RVZCB = CVA6Cfg.RVZCB; + cfg.RVZCMT = CVA6Cfg.RVZCMT; cfg.RVZCMP = CVA6Cfg.RVZCMP; cfg.XFVec = CVA6Cfg.XFVec; cfg.CvxifEn = CVA6Cfg.CvxifEn; diff --git a/core/include/config_pkg.sv b/core/include/config_pkg.sv index d711d5f262..b36386ddfd 100644 --- a/core/include/config_pkg.sv +++ b/core/include/config_pkg.sv @@ -64,6 +64,8 @@ package config_pkg; bit RVZCB; // Zcmp RISC-V extension bit RVZCMP; + // Zcmt RISC-V extension + bit RVZCMT; // Zicond RISC-V extension bit RVZiCond; // Zicntr RISC-V extension @@ -245,6 +247,7 @@ package config_pkg; bit RVH; bit RVZCB; bit RVZCMP; + bit RVZCMT; bit XFVec; bit CvxifEn; bit RVZiCond; @@ -373,6 +376,7 @@ package config_pkg; assert (Cfg.NrPMPEntries <= 64); assert (!(Cfg.SuperscalarEn && Cfg.RVF)); assert (!(Cfg.SuperscalarEn && Cfg.RVZCMP)); + assert (!(Cfg.SuperscalarEn && Cfg.RVZCMT)); `endif // pragma translate_on endfunction diff --git a/core/include/cv32a60x_config_pkg.sv b/core/include/cv32a60x_config_pkg.sv index 9604b24d39..65c04bf5e5 100644 --- a/core/include/cv32a60x_config_pkg.sv +++ b/core/include/cv32a60x_config_pkg.sv @@ -42,8 +42,9 @@ package cva6_config_pkg; RVV: bit'(0), RVC: bit'(1), RVH: bit'(0), + RVZCMT: bit'(1), RVZCB: bit'(1), - RVZCMP: bit'(1), + RVZCMP: bit'(0), XFVec: bit'(0), CvxifEn: bit'(1), RVZiCond: bit'(0), diff --git a/core/include/cv32a65x_config_pkg.sv b/core/include/cv32a65x_config_pkg.sv index d9d028fa16..5d0e73c912 100644 --- a/core/include/cv32a65x_config_pkg.sv +++ b/core/include/cv32a65x_config_pkg.sv @@ -42,6 +42,7 @@ package cva6_config_pkg; RVV: bit'(0), RVC: bit'(1), RVH: bit'(0), + RVZCMT: bit'(0), RVZCB: bit'(1), RVZCMP: bit'(0), XFVec: bit'(0), diff --git a/core/include/cv32a6_embedded_config_pkg_deprecated.sv b/core/include/cv32a6_embedded_config_pkg_deprecated.sv index ff6a1fcd41..1170c75a05 100644 --- a/core/include/cv32a6_embedded_config_pkg_deprecated.sv +++ b/core/include/cv32a6_embedded_config_pkg_deprecated.sv @@ -21,6 +21,7 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; localparam CVA6ConfigZcmpExtEn = 0; + localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 0; localparam CVA6ConfigHExtEn = 0; // always disabled localparam CVA6ConfigBExtEn = 1; @@ -96,6 +97,7 @@ package cva6_config_pkg; RVZCB: bit'(CVA6ConfigZcbExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), + RVZCMT: bit'(CVA6ConfigZcmtExtEn), CvxifEn: bit'(CVA6ConfigCvxifEn), RVZiCond: bit'(CVA6ConfigRVZiCond), RVZicntr: bit'(1), diff --git a/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv b/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv index be7ff3ee14..7bf8c289f9 100644 --- a/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv +++ b/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv @@ -22,6 +22,7 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 0; localparam CVA6ConfigZcbExtEn = 0; localparam CVA6ConfigZcmpExtEn = 0; + localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigHExtEn = 0; // always disabled localparam CVA6ConfigBExtEn = 0; @@ -95,6 +96,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMT: bit'(CVA6ConfigZcmtExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv32a6_imac_sv0_config_pkg.sv b/core/include/cv32a6_imac_sv0_config_pkg.sv index 2687370b26..13800fd7c7 100644 --- a/core/include/cv32a6_imac_sv0_config_pkg.sv +++ b/core/include/cv32a6_imac_sv0_config_pkg.sv @@ -22,6 +22,7 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; localparam CVA6ConfigZcmpExtEn = 0; + localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigHExtEn = 0; // always disabled localparam CVA6ConfigBExtEn = 0; @@ -95,6 +96,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMT: bit'(CVA6ConfigZcmtExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv32a6_imac_sv32_config_pkg.sv b/core/include/cv32a6_imac_sv32_config_pkg.sv index 9c2e622947..d9863da38e 100644 --- a/core/include/cv32a6_imac_sv32_config_pkg.sv +++ b/core/include/cv32a6_imac_sv32_config_pkg.sv @@ -22,6 +22,7 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; localparam CVA6ConfigZcmpExtEn = 0; + localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigHExtEn = 0; // always disabled localparam CVA6ConfigBExtEn = 0; @@ -95,6 +96,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMT: bit'(CVA6ConfigZcmtExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv32a6_imafc_sv32_config_pkg.sv b/core/include/cv32a6_imafc_sv32_config_pkg.sv index 6ad09136e4..de5625f1be 100644 --- a/core/include/cv32a6_imafc_sv32_config_pkg.sv +++ b/core/include/cv32a6_imafc_sv32_config_pkg.sv @@ -22,6 +22,7 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; localparam CVA6ConfigZcmpExtEn = 0; + localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigHExtEn = 0; // always disabled localparam CVA6ConfigBExtEn = 0; @@ -96,6 +97,7 @@ package cva6_config_pkg; RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), + RVZCMT: bit'(CVA6ConfigZcmtExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), RVZiCond: bit'(CVA6ConfigRVZiCond), diff --git a/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv b/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv index 0422eef3bf..0f9a7f3fb3 100644 --- a/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv +++ b/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv @@ -22,6 +22,7 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; localparam CVA6ConfigZcmpExtEn = 0; + localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 0; localparam CVA6ConfigHExtEn = 0; @@ -96,6 +97,7 @@ package cva6_config_pkg; RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), + RVZCMT: bit'(CVA6ConfigZcmtExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), RVZiCond: bit'(CVA6ConfigRVZiCond), diff --git a/core/include/cv64a6_imafdc_sv39_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_config_pkg.sv index 8050e88f27..c0b3b81915 100644 --- a/core/include/cv64a6_imafdc_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_config_pkg.sv @@ -22,6 +22,7 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; localparam CVA6ConfigZcmpExtEn = 0; + localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigHExtEn = 0; // always disabled localparam CVA6ConfigBExtEn = 1; @@ -95,6 +96,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMT: bit'(CVA6ConfigZcmtExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv index 36c4397ade..97d10d2b67 100644 --- a/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv @@ -29,6 +29,7 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; localparam CVA6ConfigZcmpExtEn = 0; + localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 1; localparam CVA6ConfigVExtEn = 0; @@ -103,6 +104,7 @@ package cva6_config_pkg; RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), + RVZCMT: bit'(CVA6ConfigZcmtExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), RVZiCond: bit'(CVA6ConfigRVZiCond), diff --git a/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv index 16f329c456..66a188c267 100644 --- a/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv @@ -22,6 +22,7 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; localparam CVA6ConfigZcmpExtEn = 0; + localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigHExtEn = 0; // always disabled localparam CVA6ConfigBExtEn = 0; @@ -95,6 +96,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMT: bit'(CVA6ConfigZcmtExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv index b785da8296..6b709f89fc 100644 --- a/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv @@ -22,6 +22,7 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; localparam CVA6ConfigZcmpExtEn = 0; + localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 1; localparam CVA6ConfigVExtEn = 0; @@ -95,6 +96,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMT: bit'(CVA6ConfigZcmtExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv64a6_imafdch_sv39_config_pkg.sv b/core/include/cv64a6_imafdch_sv39_config_pkg.sv index 6e4d755ea1..d76b53420d 100644 --- a/core/include/cv64a6_imafdch_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdch_sv39_config_pkg.sv @@ -22,6 +22,7 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; localparam CVA6ConfigZcmpExtEn = 0; + localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigHExtEn = 1; localparam CVA6ConfigBExtEn = 1; @@ -95,6 +96,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMT: bit'(CVA6ConfigZcmtExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv64a6_imafdch_sv39_wb_config_pkg.sv b/core/include/cv64a6_imafdch_sv39_wb_config_pkg.sv index 49bc7693b2..23fc0e2d41 100644 --- a/core/include/cv64a6_imafdch_sv39_wb_config_pkg.sv +++ b/core/include/cv64a6_imafdch_sv39_wb_config_pkg.sv @@ -22,6 +22,7 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; localparam CVA6ConfigZcmpExtEn = 0; + localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 1; localparam CVA6ConfigVExtEn = 0; @@ -95,6 +96,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), + RVZCMT: bit'(CVA6ConfigZcmtExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv64a6_imafdcv_sv39_config_pkg.sv b/core/include/cv64a6_imafdcv_sv39_config_pkg.sv index 2c642f5345..571bd89b24 100644 --- a/core/include/cv64a6_imafdcv_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdcv_sv39_config_pkg.sv @@ -22,6 +22,7 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; localparam CVA6ConfigZcmpExtEn = 0; + localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 0; localparam CVA6ConfigHExtEn = 0; @@ -96,6 +97,7 @@ package cva6_config_pkg; RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), + RVZCMT: bit'(CVA6ConfigZcmtExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), RVZiCond: bit'(CVA6ConfigRVZiCond), diff --git a/core/include/cv64a6_mmu_config_pkg.sv b/core/include/cv64a6_mmu_config_pkg.sv index 8e0b686386..4d9d053431 100644 --- a/core/include/cv64a6_mmu_config_pkg.sv +++ b/core/include/cv64a6_mmu_config_pkg.sv @@ -51,6 +51,7 @@ package cva6_config_pkg; RVH: bit'(0), RVZCB: bit'(1), RVZCMP: bit'(0), + RVZCMT: bit'(0), XFVec: bit'(0), CvxifEn: bit'(1), RVZiCond: bit'(0), diff --git a/core/include/riscv_pkg.sv b/core/include/riscv_pkg.sv index 40499c6371..762d422e4f 100644 --- a/core/include/riscv_pkg.sv +++ b/core/include/riscv_pkg.sv @@ -385,6 +385,8 @@ package riscv; CSR_FFLAGS = 12'h001, CSR_FRM = 12'h002, CSR_FCSR = 12'h003, + //jvt + CSR_JVT = 12'h017, CSR_FTRAN = 12'h800, // Vector CSRs CSR_VSTART = 12'h008, @@ -724,6 +726,10 @@ package riscv; localparam logic [63:0] SSTATUS_MXR = 'h00080000; localparam logic [63:0] SSTATUS_UPIE = 'h00000010; localparam logic [63:0] SSTATUS_UXL = 64'h0000000300000000; + // CSR Bit Implementation Masks + // A mask bit of '1' means a flipflop is implemented. + parameter CSR_JVT_MASK = 32'hFFFFFFC0; + function automatic logic [63:0] sstatus_sd(logic IS_XLEN64); return {IS_XLEN64, 31'h00000000, ~IS_XLEN64, 31'h00000000}; endfunction @@ -859,6 +865,13 @@ package riscv; priv_lvl_t prv; } dcsr_t; + //jvt struct + typedef struct packed { + logic [XLEN-1:6] base; + logic [5:0] mode; + } jvt_t; + parameter JVT_ADDR_WIDTH = XLEN - 6; + parameter JVT_RESET_VAL = 32'd0; //32 bit // Instruction Generation *incomplete* function automatic logic [31:0] jal(logic [4:0] rd, logic [20:0] imm); // OpCode Jal diff --git a/core/include/rvfi_types.svh b/core/include/rvfi_types.svh index 68881bf0d1..8bf20f7659 100644 --- a/core/include/rvfi_types.svh +++ b/core/include/rvfi_types.svh @@ -39,6 +39,7 @@ rvfi_csr_elmt_t fflags; \ rvfi_csr_elmt_t frm; \ rvfi_csr_elmt_t fcsr; \ + rvfi_csr_elmt_t jvt; \ rvfi_csr_elmt_t ftran; \ rvfi_csr_elmt_t dcsr; \ rvfi_csr_elmt_t dpc; \ @@ -130,6 +131,7 @@ `define RVFI_PROBES_CSR_T(Cfg) struct packed { \ riscv::fcsr_t fcsr_q; \ riscv::dcsr_t dcsr_q; \ + riscv::jvt_t jvt_q; \ logic [Cfg.XLEN-1:0] dpc_q; \ logic [Cfg.XLEN-1:0] dscratch0_q; \ logic [Cfg.XLEN-1:0] dscratch1_q; \ diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index fa357f42fb..b11b2a86ba 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -121,7 +121,9 @@ module issue_read_operands input logic [CVA6Cfg.NrCommitPorts-1:0] we_fpr_i, // Issue stall - PERF_COUNTERS - output logic stall_issue_o + output logic stall_issue_o, + input logic is_zcmt_i, + output logic is_zcmt_o ); localparam OPERANDS_PER_INSTR = CVA6Cfg.NrRgprPorts / CVA6Cfg.NrIssuePorts; @@ -190,6 +192,9 @@ module issue_read_operands // forwarding signals logic [CVA6Cfg.NrIssuePorts-1:0] forward_rs1, forward_rs2, forward_rs3; + logic is_zcmt_n, is_zcmt_q; + assign is_zcmt_n = is_zcmt_i; + assign is_zcmt_o = is_zcmt_q; // original instruction riscv::instruction_t orig_instr; @@ -1104,8 +1109,10 @@ module issue_read_operands is_compressed_instr_o <= 1'b0; branch_predict_o <= {cf_t'(0), {CVA6Cfg.VLEN{1'b0}}}; x_transaction_rejected_o <= 1'b0; + is_zcmt_q <= 1'b0; end else begin fu_data_q <= fu_data_n; + is_zcmt_q <= is_zcmt_n; if (CVA6Cfg.RVH) begin tinst_q <= tinst_n; end diff --git a/core/issue_stage.sv b/core/issue_stage.sv index ea922d5ce0..f111805433 100644 --- a/core/issue_stage.sv +++ b/core/issue_stage.sv @@ -157,7 +157,10 @@ module issue_stage // Information dedicated to RVFI - RVFI output logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_issue_pointer_o, // Information dedicated to RVFI - RVFI - output logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_commit_pointer_o + output logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_commit_pointer_o, + //zcmt instruction + input logic is_zcmt_i, + output logic is_zcmt_o ); // --------------------------------------------------- // Scoreboard (SB) <-> Issue and Read Operands (IRO) @@ -186,6 +189,7 @@ module issue_stage assign issue_instr_o = issue_instr_sb_iro[0]; assign issue_instr_hs_o = issue_instr_valid_sb_iro[0] & issue_ack_iro_sb[0]; + assign is_zcmt_o = is_zcmt_i; logic x_transaction_accepted_iro_sb, x_issue_writeback_iro_sb; logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_id_iro_sb; @@ -299,7 +303,9 @@ module issue_stage .wdata_i, .we_gpr_i, .we_fpr_i, - .stall_issue_o + .stall_issue_o, + .is_zcmt_i (is_zcmt_i), + .is_zcmt_o (is_zcmt_o) ); endmodule diff --git a/core/zcmt_decoder.sv b/core/zcmt_decoder.sv new file mode 100644 index 0000000000..68ea0ffbe8 --- /dev/null +++ b/core/zcmt_decoder.sv @@ -0,0 +1,225 @@ +// Author: Farhan Ali Shah, 10xEngineers +// Date: 15.11.2024 +// Description: ZCMT Extension + +module zcmt_decoder #( + parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, + parameter type dcache_req_i_t = logic, + parameter type dcache_req_o_t = logic, + parameter type branchpredict_sbe_t = logic +) ( + input logic clk_i, // Clock + input logic rst_ni, // Synchronous reset + input logic [31:0] instr_i, // instruction + input logic [CVA6Cfg.VLEN-1:0] pc_i, // PC + input logic is_zcmt_instr_i, // Intruction is of macro extension + input logic illegal_instr_i, // From compressed decoder + input logic is_compressed_i, // is compressed instruction + input logic issue_ack_i, // Check if the intruction is acknowledged + input logic [CVA6Cfg.XLEN-1:6] jvt_base_i, // JVT CSR base + input logic [5:0] jvt_mode_i, // JVT CSR mode + input dcache_req_o_t req_port_i, // Data cache request ouput - CACHE + + output logic [31:0] instr_o, // Instruction out + output logic illegal_instr_o, // Illegel instruction + output logic is_compressed_o, // is compressed instruction + output logic fetch_stall_o, // Wait while address fetched from table + output logic is_zcmt_o, // is zcmt instruction + output dcache_req_i_t req_port_o // Data cache request input - CACHE +); + + // FSM States + enum logic [1:0] { + IDLE, // Wait for ZCMT instruction + REQ_SENT, // Request sent to fetch the entry from jump table + TABLE_FETCH, // Check the valid data from jump table and record + JUMP // Calculate the offset for jump and create jal instruction + } + state_d, state_q; + + //zcmt instruction type + enum logic [1:0] { + NOT_ZCMT, // 00: Not a ZCMT instrcution + JT, // 01: cm.jt instruction + JALT // 10: cm.jalt instruction + } zcmt_instr_type; + + // Temporary registers + logic [31:0] instr_o_reg; + logic [7:0] index; //index of instruction + logic [CVA6Cfg.XLEN-1:0] table_address; //Physical address: jvt + (index <<2) + logic [CVA6Cfg.XLEN+1:0] table_a; //Virtual address: {00,Physical address} + logic [31:0] jvt_table_add; + logic [CVA6Cfg.XLEN-1:0] data_rdata_d, data_rdata_q; //data received from instruction memory + logic [20:0] jump_add; //jump address immidiate + + assign instr_o = instr_o_reg; //instruction output assigned + + always_comb begin + state_d = state_q; + data_rdata_d = data_rdata_q; + illegal_instr_o = 1'b0; + is_compressed_o = is_zcmt_instr_i ? 1'b1 : is_compressed_i; + illegal_instr_o = 1'b0; + is_zcmt_o = 1'b0; + fetch_stall_o = is_zcmt_instr_i ? 1'b1 : 0; + + if (is_zcmt_instr_i) begin + unique case (instr_i[12:10]) + //zcmt instruction + 3'b000: begin + if (instr_i[9:2] < 32) begin //JT instruction + zcmt_instr_type = JT; + index = instr_i[9:2]; + end else if (instr_i[9:2] >= 32 & instr_i[9:2] <= 32) begin //JALT instruction + zcmt_instr_type = JALT; + index = instr_i[9:2]; + end else begin + zcmt_instr_type = NOT_ZCMT; //NOT ZCMT instruction + illegal_instr_o = 1'b1; + instr_o_reg = instr_i; + end + end + end + end + end + end + end + end + end + end + end + end + default: begin + illegal_instr_o = 1'b1; + instr_o_reg = instr_i; + zcmt_instr_type = NOT_ZCMT; + end + endcase + end else begin + illegal_instr_o = illegal_instr_i; + instr_o_reg = instr_i; + end + + unique case (state_q) + IDLE: begin + if (is_zcmt_instr_i) begin + state_d = REQ_SENT; + end else begin + state_d = IDLE; + end + end + REQ_SENT: begin + state_d = TABLE_FETCH; + case (zcmt_instr_type) + JT: begin + if (CVA6Cfg.XLEN == 32) begin + jvt_table_add = {jvt_base_i[31:6], 6'b000000}; + table_address = jvt_table_add + (index << 2); + table_a = {2'b00, table_address[CVA6Cfg.XLEN-1:0]}; + req_port_o.address_index = table_a[9:0]; + req_port_o.address_tag = table_a[33:10]; + req_port_o.data_wdata = 1'b0; + req_port_o.data_wuser = '0; + req_port_o.data_req = 1'b1; + req_port_o.data_we = 1'b0; + req_port_o.data_be = 1'b0; + req_port_o.data_size = 2'b10; + req_port_o.data_id = 1; + req_port_o.kill_req = 0; + req_port_o.tag_valid = 1; + + end else if (CVA6Cfg.XLEN == 64) begin + jvt_table_add = {jvt_base_i[31:6], 6'b000000}; + table_address = jvt_table_add + (index << 3); + table_a = {2'b00, table_address[CVA6Cfg.XLEN-1:0]}; + // will will completed in future( for 64 bit embedded core) + illegal_instr_o = 1'b1; + end else begin + illegal_instr_o = 1'b1; + instr_o_reg = instr_i; + end + end + JALT: begin + if (CVA6Cfg.XLEN == 32) begin + jvt_table_add = {jvt_base_i[31:6], 6'b000000}; + table_address = jvt_table_add + (index << 2); + table_a = {2'b00, table_address[CVA6Cfg.XLEN-1:0]}; + req_port_o.address_index = table_a[9:0]; + req_port_o.address_tag = table_a[33:10]; + req_port_o.data_wdata = 1'b0; + req_port_o.data_wuser = '0; + req_port_o.data_req = 1'b1; + req_port_o.data_we = 1'b0; + req_port_o.data_be = 1'b0; + req_port_o.data_size = 2'b10; + req_port_o.data_id = 1; + req_port_o.kill_req = 0; + req_port_o.tag_valid = 1; + + end else if (CVA6Cfg.XLEN == 64) begin + jvt_table_add = {jvt_base_i[31:6], 6'b000000}; + table_address = jvt_table_add + (index << 3); + table_a = {2'b00, table_address[CVA6Cfg.XLEN-1:0]}; + // will will completed in future( for 64 bit embedded core) + illegal_instr_o = 1'b1; + end else begin + illegal_instr_o = 1'b1; + instr_o_reg = instr_i; + end + end + default: state_d = IDLE; + endcase + end + TABLE_FETCH: begin + if (req_port_i.data_rid & req_port_i.data_rvalid) begin + data_rdata_d = req_port_i.data_rdata; + state_d = JUMP; + end else begin + state_d = TABLE_FETCH; + end + end + end + JUMP: begin + if (issue_ack_i) begin + + jump_add = $unsigned($signed(data_rdata_q) - $signed(pc_i)); + + if (zcmt_instr_type == JT) begin + instr_o_reg = { + jump_add[20], jump_add[10:1], jump_add[11], jump_add[19:12], 5'h0, riscv::OpcodeJal + }; //- jal pc_offset, x0 + end else if (zcmt_instr_type == JALT) begin + instr_o_reg = { + jump_add[20], jump_add[10:1], jump_add[11], jump_add[19:12], 5'h1, riscv::OpcodeJal + }; + end + + is_zcmt_o = 1'b1; + state_d = IDLE; + end else begin + state_d = JUMP; + end + end + default: begin + state_d = IDLE; + end + endcase + end + + always_ff @(posedge clk_i or negedge rst_ni) begin + if (~rst_ni) begin + state_q <= IDLE; + data_rdata_q <= '0; + + end else begin + state_q <= state_d; + data_rdata_q <= data_rdata_d; + + end + end + end + end + end + end +endmodule diff --git a/verif/tests/custom/zcmt/cm_jalt.S b/verif/tests/custom/zcmt/cm_jalt.S new file mode 100644 index 0000000000..46e1ff79ab --- /dev/null +++ b/verif/tests/custom/zcmt/cm_jalt.S @@ -0,0 +1,62 @@ +.globl _start +_start: + la t0, trap_handler + csrw mtvec, t0 + + la a1, target1 + la t0, __jvt_base$ + + sw a1, 128(t0) //cm.jalt entry start from index >=32 + + csrw jvt, t0 + + fence.i + # Perform jump using the index from JVT + cm.jalt 32 + + li t1, 1 + addi x20,x20, 9 + j write_tohost + + + + +exit: + j write_tohost + +write_tohost: + li x1, 1 + la t0, tohost + sw x1, 0(t0) + j write_tohost + + +# Jump Vector Table (JVT) Section +# Create a separate section for the JVT +.section .riscv.jvt, "ax" +.align 6 # Align the JVT on a 64-byte boundary (6 = 2^6 = 64) +__jvt_base$: + .word 0x80000054 + .word 0x80000800 + .word 0x80000802 + .word 0x80000804 + +# Target Addresses (Where cm.jalt will jump) +target0: + li x5, 99 + j write_tohost +target1: + li x2, 99 + j write_tohost + +target2: + addi x2,x20, 5 + j write_tohost + + +trap_handler: + j exit + + +.align 6; .global tohost; tohost: .dword 0; +.align 6; .global fromhost; fromhost: .dword 0; diff --git a/verif/tests/custom/zcmt/cm_jalt_ret.S b/verif/tests/custom/zcmt/cm_jalt_ret.S new file mode 100644 index 0000000000..f6586d60a0 --- /dev/null +++ b/verif/tests/custom/zcmt/cm_jalt_ret.S @@ -0,0 +1,62 @@ +.globl _start +_start: + la t0, trap_handler + csrw mtvec, t0 + + la a1, target1 + la t0, __jvt_base$ + + sw a1, 128(t0) //cm.jalt entry start from index >=32 + + csrw jvt, t0 + + fence.i + # Perform jump using the index from JVT + cm.jalt 32 + + li t1, 1 + addi x20,x20, 9 + j write_tohost + + + + +exit: + j write_tohost + +write_tohost: + li x1, 1 + la t0, tohost + sw x1, 0(t0) + j write_tohost + + +# Jump Vector Table (JVT) Section +# Create a separate section for the JVT +.section .riscv.jvt, "ax" +.align 6 # Align the JVT on a 64-byte boundary (6 = 2^6 = 64) +__jvt_base$: + .word 0x80000054 + .word 0x80000800 + .word 0x80000802 + .word 0x80000804 + +# Target Addresses (Where cm.jalt will jump) +target0: + li x5, 99 + j write_tohost +target1: + li x2, 99 + ret + +target2: + addi x2,x20, 5 + j write_tohost + + +trap_handler: + j exit + + +.align 6; .global tohost; tohost: .dword 0; +.align 6; .global fromhost; fromhost: .dword 0; diff --git a/verif/tests/custom/zcmt/cm_jt.S b/verif/tests/custom/zcmt/cm_jt.S new file mode 100644 index 0000000000..b2dd88a49c --- /dev/null +++ b/verif/tests/custom/zcmt/cm_jt.S @@ -0,0 +1,58 @@ +.globl _start +_start: + la t0, trap_handler + csrw mtvec, t0 + + la a1, target1 + la t0, __jvt_base$ + + sw a1, 0(t0) + + csrw jvt, t0 + + fence.i + + cm.jt 0 # Perform jump using the index 0 from JVT + + addi x18,x18, 3 + j target2 + +exit: + j write_tohost + +write_tohost: + li x1, 1 + la t0, tohost + sw x1, 0(t0) + j write_tohost + + + +# Jump Vector Table (JVT) Section +# Create a separate section for the JVT +.section .riscv.jvt, "ax" +.align 6 # Align the JVT on a 64-byte boundary (6 = 2^6 = 64) +__jvt_base$: + .word 0x80000054 + .word 0x80000800 + .word 0x80000802 + .word 0x80000804 + +# Target Addresses (Where cm.jt will jump) +target0: + j write_tohost +target1: + addi x6,x0, 7 + j write_tohost + +target2: + addi x2,x20, 5 + j write_tohost + + +trap_handler: + j exit + + +.align 6; .global tohost; tohost: .dword 0; +.align 6; .global fromhost; fromhost: .dword 0; diff --git a/verif/tests/custom/zcmt/jvt_csr.S b/verif/tests/custom/zcmt/jvt_csr.S new file mode 100644 index 0000000000..4ccd3d9fd2 --- /dev/null +++ b/verif/tests/custom/zcmt/jvt_csr.S @@ -0,0 +1,51 @@ +.globl _start +_start: + la t0, trap_handler + csrw mtvec, t0 + la t0, __jvt_base$ + + csrw jvt, t0 + fence.i + csrr x7, jvt + + j exit + +exit: + j write_tohost + +write_tohost: + li x1, 1 + la t0, tohost + sw x1, 0(t0) + j write_tohost + + + +# Jump Vector Table (JVT) Section +# Create a separate section for the JVT +.section .riscv.jvt, "ax" +.align 6 # Align the JVT on a 64-byte boundary (6 = 2^6 = 64) +__jvt_base$: + .word 0x80000054 + .word 0x80000800 + .word 0x80000802 + .word 0x80000804 + +# Target Addresses (Where cm.jt will jump) +target0: + j write_tohost +target1: + addi x6,x0, 7 + j write_tohost + +target2: + addi x2,x20, 5 + j write_tohost + + +trap_handler: + j exit + + +.align 6; .global tohost; tohost: .dword 0; +.align 6; .global fromhost; fromhost: .dword 0; From 7b0cef02b399c35f9bd2bf403f2358352ef4826b Mon Sep 17 00:00:00 2001 From: Farhan Ali Date: Tue, 10 Dec 2024 13:19:34 +0500 Subject: [PATCH 02/10] zcmt changes --- core/branch_unit.sv | 26 +-- core/cache_subsystem/wt_dcache.sv | 4 +- core/compressed_decoder.sv | 1 - core/csr_regfile.sv | 24 ++- core/cva6.sv | 32 ++-- core/cva6_rvfi.sv | 2 +- core/decoder.sv | 6 +- core/ex_stage.sv | 10 +- core/id_stage.sv | 108 +++++------- core/include/cv32a60x_config_pkg.sv | 2 +- core/include/riscv_pkg.sv | 7 +- core/issue_read_operands.sv | 14 +- core/issue_stage.sv | 13 +- core/zcmt_decoder.sv | 238 ++++++++------------------ verif/tests/custom/zcmt/cm_jalt_ret.S | 2 +- 15 files changed, 172 insertions(+), 317 deletions(-) diff --git a/core/branch_unit.sv b/core/branch_unit.sv index 717bfdf3e4..c702567725 100644 --- a/core/branch_unit.sv +++ b/core/branch_unit.sv @@ -31,6 +31,8 @@ module branch_unit #( input fu_data_t fu_data_i, // Instruction PC - ISSUE_STAGE input logic [CVA6Cfg.VLEN-1:0] pc_i, + // is zcmt instruction + input logic is_zcmt_i, // Instruction is compressed - ISSUE_STAGE input logic is_compressed_instr_i, // Branch unit instruction is valid - ISSUE_STAGE @@ -46,18 +48,10 @@ module branch_unit #( // Branch is resolved, new entries can be accepted by scoreboard - ID_STAGE output logic resolve_branch_o, // Branch exception out - TO_BE_COMPLETED - output exception_t branch_exception_o, - //zcmt - input logic is_zcmt_i + output exception_t branch_exception_o ); logic [CVA6Cfg.VLEN-1:0] target_address; logic [CVA6Cfg.VLEN-1:0] next_pc; - logic is_zcmt_q; - - always_ff @(posedge clk_i or negedge rst_ni) begin - if (~rst_ni) is_zcmt_q <= '0; - else is_zcmt_q <= is_zcmt_i; - end // here we handle the various possibilities of mis-predicts always_comb begin : mispredict_handler @@ -83,20 +77,18 @@ module branch_unit #( // we need to put the branch target address into rd, this is the result of this unit branch_result_o = next_pc; resolved_branch_o.pc = pc_i; - // There are only two sources of mispredicts: + // There are only three sources of mispredicts: // 1. Branches // 2. Jumps to register addresses + // 3. Zcmt instructions if (branch_valid_i) begin - if (is_zcmt_q) begin + // write target address which goes to PC Gen or select target address if zcmt + resolved_branch_o.target_address = (branch_comp_res_i) | is_zcmt_i ? target_address : next_pc; + resolved_branch_o.is_taken = is_zcmt_i ? 1'b1 : branch_comp_res_i; + if (is_zcmt_i) begin // Unconditional jump handling - resolved_branch_o.is_taken = 1'b1; resolved_branch_o.is_mispredict = 1'b1; // miss prediction for ZCMT - resolved_branch_o.target_address = target_address; // Use calculated address directly resolved_branch_o.cf_type = ariane_pkg::Jump; - end else begin - // write target address which goes to PC Gen - resolved_branch_o.target_address = (branch_comp_res_i) ? target_address : next_pc; - resolved_branch_o.is_taken = branch_comp_res_i; end // check the outcome of the branch speculation if (ariane_pkg::op_is_branch(fu_data_i.operation)) begin diff --git a/core/cache_subsystem/wt_dcache.sv b/core/cache_subsystem/wt_dcache.sv index a829fc48bd..5b49d957fb 100644 --- a/core/cache_subsystem/wt_dcache.sv +++ b/core/cache_subsystem/wt_dcache.sv @@ -188,10 +188,10 @@ module wt_dcache // read controllers (LD unit and PTW/MMU) /////////////////////////////////////////////////////// - // 0 is used by MMU, 1 by READ access requests + // 0 is used by MMU or implicit read by zcmt, 1 by READ access requests for (genvar k = 0; k < NumPorts - 1; k++) begin : gen_rd_ports // set these to high prio ports - if ((k == 0 && CVA6Cfg.MmuPresent) || (k == 1) || (k == 2 && CVA6Cfg.EnableAccelerator)) begin + if ((k == 0 && (CVA6Cfg.MmuPresent || CVA6Cfg.RVZCMT )) || (k == 1) || (k == 2 && CVA6Cfg.EnableAccelerator)) begin assign rd_prio[k] = 1'b1; wt_dcache_ctrl #( .CVA6Cfg(CVA6Cfg), diff --git a/core/compressed_decoder.sv b/core/compressed_decoder.sv index 5278f40a21..d8e395cb48 100644 --- a/core/compressed_decoder.sv +++ b/core/compressed_decoder.sv @@ -876,7 +876,6 @@ module compressed_decoder #( instr_o = instr_i; end else if (instr_i[12:10] == 3'b000) begin //jt/jalt instruction is_zcmt_instr_o = 1; - instr_o = instr_i; end else begin illegal_instr_o = 1'b1; end diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index cfe5f35b13..3b58ad2995 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -18,6 +18,7 @@ module csr_regfile #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter type exception_t = logic, + parameter type jvt_t = logic, parameter type irq_ctrl_t = logic, parameter type scoreboard_entry_t = logic, parameter type rvfi_probes_csr_t = logic, @@ -169,8 +170,7 @@ module csr_regfile // RVFI output rvfi_probes_csr_t rvfi_csr_o, //jvt output - output logic [CVA6Cfg.XLEN-1:6] jvt_base_o, - output logic [5:0] jvt_mode_o + output jvt_t jvt_o ); localparam logic [63:0] SMODE_STATUS_READ_MASK = ariane_pkg::smode_status_read_mask(CVA6Cfg); @@ -355,7 +355,11 @@ module csr_regfile end end riscv::CSR_JVT: begin - csr_rdata = {jvt_q.base, jvt_q.mode}; + if (CVA6Cfg.RVZCMT) begin + csr_rdata = {jvt_q.base, jvt_q.mode}; + end else begin + read_access_exception = 1'b1; + end end // non-standard extension riscv::CSR_FTRAN: begin @@ -1068,8 +1072,12 @@ module csr_regfile if (CVA6Cfg.DebugEn) dscratch1_d = csr_wdata; else update_access_exception = 1'b1; riscv::CSR_JVT: begin - jvt_d.base = csr_wdata[CVA6Cfg.XLEN-1:6]; - jvt_d.mode = 6'b000000; + if (CVA6Cfg.RVZCMT) begin + jvt_d.base = csr_wdata[CVA6Cfg.XLEN-1:6]; + jvt_d.mode = 6'b000000; + end else begin + update_access_exception = 1'b1; + end end // trigger module CSRs riscv::CSR_TSELECT: update_access_exception = 1'b1; // not implemented @@ -2464,8 +2472,8 @@ module csr_regfile assign frm_o = fcsr_q.frm; assign fprec_o = fcsr_q.fprec; //JVT outputs - assign jvt_base_o = jvt_q.base; - assign jvt_mode_o = jvt_q.mode; + assign jvt_o.base = jvt_q.base; + assign jvt_o.mode = jvt_q.mode; // MMU outputs assign satp_ppn_o = CVA6Cfg.RVS ? satp_q.ppn : '0; assign vsatp_ppn_o = CVA6Cfg.RVH ? vsatp_q.ppn : '0; @@ -2738,7 +2746,7 @@ module csr_regfile // RVFI //------------- assign rvfi_csr_o.fcsr_q = CVA6Cfg.FpPresent ? fcsr_q : '0; - assign rvfi_csr_o.jvt_q = jvt_q; + assign rvfi_csr_o.jvt_q = CVA6Cfg.RVZCMT ? jvt_q : '0; assign rvfi_csr_o.dcsr_q = CVA6Cfg.DebugEn ? dcsr_q : '0; assign rvfi_csr_o.dpc_q = CVA6Cfg.DebugEn ? dpc_q : '0; assign rvfi_csr_o.dscratch0_q = CVA6Cfg.DebugEn ? dscratch0_q : '0; diff --git a/core/cva6.sv b/core/cva6.sv index c5997bd561..160b23f55a 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -86,6 +86,11 @@ module cva6 branchpredict_sbe_t branch_predict; // this field contains branch prediction information regarding the forward branch path exception_t ex; // this field contains exceptions which might have happened earlier, e.g.: fetch exceptions }, + //JVT struct{base,mode} + localparam type jvt_t = struct packed { + logic [CVA6Cfg.XLEN-7:0] base; + logic [5:0] mode; + }, // ID/EX/WB Stage localparam type scoreboard_entry_t = struct packed { @@ -113,6 +118,7 @@ module cva6 logic is_last_macro_instr; // is last decoded 32bit instruction of macro definition logic is_double_rd_macro_instr; // is double move decoded 32bit instruction of macro definition logic vfp; // is this a vector floating-point instruction? + logic is_zcmt; //is a zcmt instruction }, localparam type writeback_t = struct packed { logic valid; // wb data is valid @@ -415,6 +421,7 @@ module cva6 fu_data_t [CVA6Cfg.NrIssuePorts-1:0] fu_data_id_ex; logic [CVA6Cfg.VLEN-1:0] pc_id_ex; + logic zcmt_id_ex; logic is_compressed_instr_id_ex; logic [CVA6Cfg.NrIssuePorts-1:0][31:0] tinst_ex; // fixed latency units @@ -564,9 +571,7 @@ module cva6 logic [CVA6Cfg.NrPMPEntries-1:0][CVA6Cfg.PLEN-3:0] pmpaddr; logic [31:0] mcountinhibit_csr_perf; //jvt - logic [CVA6Cfg.XLEN-1:6] jvt_base; - logic [5:0] jvt_mode; - logic is_zcmt_id_is, is_zcmt_is_ex; + jvt_t jvt; // ---------------------------- // Performance Counters <-> * // ---------------------------- @@ -681,6 +686,7 @@ module cva6 .dcache_req_o_t(dcache_req_o_t), .exception_t(exception_t), .fetch_entry_t(fetch_entry_t), + .jvt_t(jvt_t), .irq_ctrl_t(irq_ctrl_t), .scoreboard_entry_t(scoreboard_entry_t), .interrupts_t(interrupts_t), @@ -725,9 +731,7 @@ module cva6 .compressed_resp_i (x_compressed_resp), .compressed_valid_o(x_compressed_valid), .compressed_req_o (x_compressed_req), - .jvt_base_i (jvt_base), - .jvt_mode_i (jvt_mode), - .is_zcmt_o (is_zcmt_id_is), + .jvt_i (jvt), // DCACHE interfaces .dcache_req_ports_i(dcache_req_ports_cache_id), .dcache_req_ports_o(dcache_req_ports_id_cache) @@ -826,13 +830,12 @@ module cva6 .decoded_instr_valid_i (issue_entry_valid_id_issue), .is_ctrl_flow_i (is_ctrl_fow_id_issue), .decoded_instr_ack_o (issue_instr_issue_id), - .is_zcmt_i (is_zcmt_id_is), - .is_zcmt_o (is_zcmt_is_ex), // Functional Units .rs1_forwarding_o (rs1_forwarding_id_ex), .rs2_forwarding_o (rs2_forwarding_id_ex), .fu_data_o (fu_data_id_ex), .pc_o (pc_id_ex), + .is_zcmt_o (zcmt_id_ex), .is_compressed_instr_o (is_compressed_instr_id_ex), .tinst_o (tinst_ex), // fixed latency unit ready @@ -924,6 +927,7 @@ module cva6 .rs2_forwarding_i(rs2_forwarding_id_ex), .fu_data_i(fu_data_id_ex), .pc_i(pc_id_ex), + .is_zcmt_i(zcmt_id_ex), .is_compressed_instr_i(is_compressed_instr_id_ex), .tinst_i(tinst_ex), // fixed latency units @@ -1034,8 +1038,7 @@ module cva6 .pmpaddr_i (pmpaddr), //RVFI .rvfi_lsu_ctrl_o (rvfi_lsu_ctrl), - .rvfi_mem_paddr_o (rvfi_mem_paddr), - .is_zcmt_i (is_zcmt_is_ex) + .rvfi_mem_paddr_o (rvfi_mem_paddr) ); // --------- @@ -1095,6 +1098,7 @@ module cva6 csr_regfile #( .CVA6Cfg (CVA6Cfg), .exception_t (exception_t), + .jvt_t (jvt_t), .irq_ctrl_t (irq_ctrl_t), .scoreboard_entry_t(scoreboard_entry_t), .rvfi_probes_csr_t (rvfi_probes_csr_t), @@ -1171,8 +1175,7 @@ module cva6 .pmpcfg_o (pmpcfg), .pmpaddr_o (pmpaddr), .mcountinhibit_o (mcountinhibit_csr_perf), - .jvt_base_o (jvt_base), - .jvt_mode_o (jvt_mode), + .jvt_o (jvt), //RVFI .rvfi_csr_o (rvfi_csr) ); @@ -1277,8 +1280,7 @@ module cva6 dcache_req_o_t [NumPorts-1:0] dcache_req_from_cache; // D$ request - // D$ request - if (CVA6Cfg.RVZCMT) begin + if (CVA6Cfg.RVZCMT & ~(CVA6Cfg.MmuPresent)) begin // Cache port 0 is ultilize in implicit read access in ZCMT extension. Therefore, MMU should be turn off. assign dcache_req_to_cache[0] = dcache_req_ports_id_cache; end else begin assign dcache_req_to_cache[0] = dcache_req_ports_ex_cache[0]; @@ -1289,7 +1291,7 @@ module cva6 dcache_req_ports_acc_cache[1]; // D$ response - if (CVA6Cfg.RVZCMT) begin + if (CVA6Cfg.RVZCMT & ~(CVA6Cfg.MmuPresent)) begin // Cache port 0 is ultilize in implicit read access in ZCMT extension. Therefore, MMU should be turn off. assign dcache_req_ports_cache_id = dcache_req_from_cache[0]; end else begin assign dcache_req_ports_cache_ex[0] = dcache_req_from_cache[0]; diff --git a/core/cva6_rvfi.sv b/core/cva6_rvfi.sv index 944f5cbbd6..02bd564f76 100644 --- a/core/cva6_rvfi.sv +++ b/core/cva6_rvfi.sv @@ -344,7 +344,7 @@ module cva6_rvfi `CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, fflags, csr.fcsr_q.fflags) `CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, frm, csr.fcsr_q.frm) `CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, fcsr, { csr.fcsr_q.frm `COMMA csr.fcsr_q.fflags}) - `CONNECT_RVFI_FULL(1, jvt, { csr.jvt_q.base `COMMA csr.jvt_q.mode}) + `CONNECT_RVFI_FULL(CVA6Cfg.RVZCMT, jvt, { csr.jvt_q.base `COMMA csr.jvt_q.mode}) `CONNECT_RVFI_FULL(CVA6Cfg.FpPresent, ftran, csr.fcsr_q.fprec) `CONNECT_RVFI_SAME(CVA6Cfg.FpPresent, dcsr) diff --git a/core/decoder.sv b/core/decoder.sv index 55b4de761a..015d95c81e 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -87,8 +87,7 @@ module decoder // Is a control flow instruction - ISSUE_STAGE output logic is_control_flow_instr_o, //zcmt instruction - input logic is_zcmt_i, - output logic is_zcmt_o + input logic is_zcmt_i ); logic illegal_instr; logic illegal_instr_bm; @@ -181,10 +180,10 @@ module decoder instruction_o.use_zimm = 1'b0; instruction_o.bp = branch_predict_i; instruction_o.vfp = 1'b0; + instruction_o.is_zcmt = is_zcmt_i; ecall = 1'b0; ebreak = 1'b0; check_fprm = 1'b0; - is_zcmt_o = 1'b0; if (~ex_i.valid) begin case (instr.rtype.opcode) @@ -1408,7 +1407,6 @@ module decoder imm_select = JIMM; instruction_o.rd = instr.utype.rd; is_control_flow_instr_o = 1'b1; - is_zcmt_o = is_zcmt_i; end riscv::OpcodeAuipc: begin diff --git a/core/ex_stage.sv b/core/ex_stage.sv index 4d7338586a..6c3da27a06 100644 --- a/core/ex_stage.sv +++ b/core/ex_stage.sv @@ -47,6 +47,8 @@ module ex_stage input fu_data_t [CVA6Cfg.NrIssuePorts-1:0] fu_data_i, // PC of the current instruction - ISSUE_STAGE input logic [CVA6Cfg.VLEN-1:0] pc_i, + // is_zcmt instruction + input logic is_zcmt_i, // Report whether instruction is compressed - ISSUE_STAGE input logic is_compressed_instr_i, // Report instruction encoding - ISSUE_STAGE @@ -228,9 +230,7 @@ module ex_stage // Information dedicated to RVFI - RVFI output lsu_ctrl_t rvfi_lsu_ctrl_o, // Information dedicated to RVFI - RVFI - output [CVA6Cfg.PLEN-1:0] rvfi_mem_paddr_o, - //zcmt instruction - input logic is_zcmt_i + output [CVA6Cfg.PLEN-1:0] rvfi_mem_paddr_o ); // ------------------------- @@ -322,6 +322,7 @@ module ex_stage .debug_mode_i, .fu_data_i (one_cycle_data), .pc_i, + .is_zcmt_i, .is_compressed_instr_i, .branch_valid_i (|branch_valid_i), .branch_comp_res_i (alu_branch_res), @@ -329,8 +330,7 @@ module ex_stage .branch_predict_i, .resolved_branch_o, .resolve_branch_o, - .branch_exception_o(flu_exception_o), - .is_zcmt_i (is_zcmt_i) + .branch_exception_o(flu_exception_o) ); // 3. CSR (sequential) diff --git a/core/id_stage.sv b/core/id_stage.sv index b318856e98..3196ef76e7 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -20,6 +20,7 @@ module id_stage #( parameter type dcache_req_o_t = logic, parameter type exception_t = logic, parameter type fetch_entry_t = logic, + parameter type jvt_t = logic, parameter type irq_ctrl_t = logic, parameter type scoreboard_entry_t = logic, parameter type interrupts_t = logic, @@ -85,10 +86,8 @@ module id_stage #( // CVXIF Compressed interface input logic [CVA6Cfg.XLEN-1:0] hart_id_i, input logic compressed_ready_i, - //JVT base - input logic [CVA6Cfg.XLEN-1:6] jvt_base_i, - input logic [5:0] jvt_mode_i, - output logic is_zcmt_o, + //JVT + input jvt_t jvt_i, input x_compressed_resp_t compressed_resp_i, output logic compressed_valid_o, output x_compressed_req_t compressed_req_o, @@ -112,26 +111,24 @@ module id_stage #( logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal; logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_cmp; - logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_cvxif; - logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction; - logic [CVA6Cfg.NrIssuePorts-1:0][31:0] compressed_instr; - logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction_cvxif; - logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed; - logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_cmp; - logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_cvxif; + logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_cvxif, is_illegal_cvxif_zcmp, is_illegal_cvxif_zcmt; + logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction; + logic [CVA6Cfg.NrIssuePorts-1:0][31:0] compressed_instr; + logic [CVA6Cfg.NrIssuePorts-1:0][31:0] + instruction_cvxif, instruction_cvxif_zcmp, instruction_cvxif_zcmt; + logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed; + logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_cmp; + logic [CVA6Cfg.NrIssuePorts-1:0] + is_compressed_cvxif, is_compressed_cvxif_zcmp, is_compressed_cvxif_zcmt; - logic [CVA6Cfg.NrIssuePorts-1:0] is_macro_instr_i; - logic stall_instr_fetch; - logic stall_macro_deco; - logic is_last_macro_instr_o; - logic is_double_rd_macro_instr_o; - logic [CVA6Cfg.NrIssuePorts-1:0] is_zcmt_instr_i; - branchpredict_sbe_t branch_predict; - logic is_zcmt; - logic is_zcmt_q, is_zcmt_n, is_zcmt_o2; - - assign is_zcmt_n = is_zcmt_o2; - assign is_zcmt_o = is_zcmt_q; + logic [CVA6Cfg.NrIssuePorts-1:0] is_macro_instr_i; + logic stall_instr_fetch; + logic stall_macro_deco, stall_macro_deco_zcmp, stall_macro_deco_zcmt; + logic is_last_macro_instr_o; + logic is_double_rd_macro_instr_o; + logic [CVA6Cfg.NrIssuePorts-1:0] is_zcmt_instr_i; + branchpredict_sbe_t branch_predict; + logic is_zcmt; if (CVA6Cfg.RVC) begin // --------------------------------------------------------- @@ -149,7 +146,7 @@ module id_stage #( .is_zcmt_instr_o (is_zcmt_instr_i[i]) ); end - if (CVA6Cfg.RVZCMP) begin + if (CVA6Cfg.RVZCMP || (CVA6Cfg.RVZCMT & ~CVA6Cfg.MmuPresent)) begin //MMU should be off when using ZCMT //sequencial decoder macro_decoder #( .CVA6Cfg(CVA6Cfg) @@ -158,47 +155,21 @@ module id_stage #( .is_macro_instr_i (is_macro_instr_i[0]), .clk_i (clk_i), .rst_ni (rst_ni), - .instr_o (instruction_cvxif[0]), + .instr_o (instruction_cvxif_zcmp[0]), .illegal_instr_i (is_illegal[0]), .is_compressed_i (is_compressed[0]), .issue_ack_i (issue_instr_ack_i[0]), - .illegal_instr_o (is_illegal_cvxif[0]), - .is_compressed_o (is_compressed_cvxif[0]), - .fetch_stall_o (stall_macro_deco), + .illegal_instr_o (is_illegal_cvxif_zcmp[0]), + .is_compressed_o (is_compressed_cvxif_zcmp[0]), + .fetch_stall_o (stall_macro_deco_zcmp), .is_last_macro_instr_o (is_last_macro_instr_o), .is_double_rd_macro_instr_o(is_double_rd_macro_instr_o) ); - if (CVA6Cfg.SuperscalarEn) begin - assign instruction_cvxif[CVA6Cfg.NrIssuePorts-1] = '0; - assign is_illegal_cvxif[CVA6Cfg.NrIssuePorts-1] = '0; - assign is_compressed_cvxif[CVA6Cfg.NrIssuePorts-1] = '0; - end - cvxif_compressed_if_driver #( - .CVA6Cfg(CVA6Cfg), - .x_compressed_req_t(x_compressed_req_t), - .x_compressed_resp_t(x_compressed_resp_t) - ) i_cvxif_compressed_if_driver_i ( - .clk_i (clk_i), - .rst_ni (rst_ni), - .hart_id_i (hart_id_i), - .is_compressed_i (is_compressed_cvxif), - .is_illegal_i (is_illegal_cvxif), - .instruction_i (instruction_cvxif), - .is_compressed_o (is_compressed_cmp), - .is_illegal_o (is_illegal_cmp), - .instruction_o (instruction), - .stall_i (stall_macro_deco), - .stall_o (stall_instr_fetch), - .compressed_ready_i(compressed_ready_i), - .compressed_resp_i (compressed_resp_i), - .compressed_valid_o(compressed_valid_o), - .compressed_req_o (compressed_req_o) - ); - end else if (CVA6Cfg.RVZCMT) begin zcmt_decoder #( .CVA6Cfg(CVA6Cfg), .dcache_req_i_t(dcache_req_i_t), .dcache_req_o_t(dcache_req_o_t), + .jvt_t(jvt_t), .branchpredict_sbe_t(branchpredict_sbe_t) ) zcmt_decoder_i ( .instr_i (compressed_instr[0]), @@ -206,19 +177,21 @@ module id_stage #( .is_zcmt_instr_i(is_zcmt_instr_i[0]), .clk_i (clk_i), .rst_ni (rst_ni), - .instr_o (instruction_cvxif[0]), + .instr_o (instruction_cvxif_zcmt[0]), .illegal_instr_i(is_illegal[0]), .is_compressed_i(is_compressed[0]), - .issue_ack_i (issue_instr_ack_i[0]), - .illegal_instr_o(is_illegal_cvxif[0]), - .is_compressed_o(is_compressed_cvxif[0]), - .fetch_stall_o (stall_macro_deco), - .jvt_base_i (jvt_base_i), - .jvt_mode_i (jvt_mode_i), - .is_zcmt_o (is_zcmt), + .illegal_instr_o(is_illegal_cvxif_zcmt[0]), + .is_compressed_o(is_compressed_cvxif_zcmt[0]), + .fetch_stall_o (stall_macro_deco_zcmt), + .jvt_i (jvt_i), .req_port_i (dcache_req_ports_i), .req_port_o (dcache_req_ports_o) ); + + assign instruction_cvxif[0] = is_zcmt_instr_i[0] ? instruction_cvxif_zcmt[0] : instruction_cvxif_zcmp[0]; + assign is_illegal_cvxif[0] = is_zcmt_instr_i[0] ? is_illegal_cvxif_zcmt[0] : is_illegal_cvxif_zcmp[0]; + assign is_compressed_cvxif[0] = is_zcmt_instr_i[0] ? is_compressed_cvxif_zcmt[0] : is_compressed_cvxif_zcmp[0]; + assign stall_macro_deco = is_zcmt_instr_i[0] ? stall_macro_deco_zcmt : stall_macro_deco_zcmp; if (CVA6Cfg.SuperscalarEn) begin assign instruction_cvxif[CVA6Cfg.NrIssuePorts-1] = '0; assign is_illegal_cvxif[CVA6Cfg.NrIssuePorts-1] = '0; @@ -307,8 +280,7 @@ module id_stage #( .pc_i (fetch_entry_i[i].address), .is_compressed_i (is_compressed_cmp[i]), .is_macro_instr_i (is_macro_instr_i[i]), - .is_zcmt_i (is_zcmt), - .is_zcmt_o (is_zcmt_o2), + .is_zcmt_i (is_zcmt_instr_i[i]), .is_last_macro_instr_i (is_last_macro_instr_o), .is_double_rd_macro_instr_i(is_double_rd_macro_instr_o), .is_illegal_i (is_illegal_cmp[i]), @@ -414,11 +386,9 @@ module id_stage #( // ------------------------- always_ff @(posedge clk_i or negedge rst_ni) begin if (~rst_ni) begin - issue_q <= '0; - is_zcmt_q <= '0; + issue_q <= '0; end else begin - issue_q <= issue_n; - is_zcmt_q <= is_zcmt_n; + issue_q <= issue_n; end end endmodule diff --git a/core/include/cv32a60x_config_pkg.sv b/core/include/cv32a60x_config_pkg.sv index 65c04bf5e5..7cf0af9b43 100644 --- a/core/include/cv32a60x_config_pkg.sv +++ b/core/include/cv32a60x_config_pkg.sv @@ -44,7 +44,7 @@ package cva6_config_pkg; RVH: bit'(0), RVZCMT: bit'(1), RVZCB: bit'(1), - RVZCMP: bit'(0), + RVZCMP: bit'(1), XFVec: bit'(0), CvxifEn: bit'(1), RVZiCond: bit'(0), diff --git a/core/include/riscv_pkg.sv b/core/include/riscv_pkg.sv index 762d422e4f..5e29330277 100644 --- a/core/include/riscv_pkg.sv +++ b/core/include/riscv_pkg.sv @@ -727,8 +727,6 @@ package riscv; localparam logic [63:0] SSTATUS_UPIE = 'h00000010; localparam logic [63:0] SSTATUS_UXL = 64'h0000000300000000; // CSR Bit Implementation Masks - // A mask bit of '1' means a flipflop is implemented. - parameter CSR_JVT_MASK = 32'hFFFFFFC0; function automatic logic [63:0] sstatus_sd(logic IS_XLEN64); return {IS_XLEN64, 31'h00000000, ~IS_XLEN64, 31'h00000000}; @@ -866,12 +864,11 @@ package riscv; } dcsr_t; //jvt struct + parameter JVT_ADDR_WIDTH = XLEN - 6; typedef struct packed { - logic [XLEN-1:6] base; + logic [JVT_ADDR_WIDTH-1:0] base; logic [5:0] mode; } jvt_t; - parameter JVT_ADDR_WIDTH = XLEN - 6; - parameter JVT_RESET_VAL = 32'd0; //32 bit // Instruction Generation *incomplete* function automatic logic [31:0] jal(logic [4:0] rd, logic [20:0] imm); // OpCode Jal diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index b11b2a86ba..1c1a904719 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -56,6 +56,8 @@ module issue_read_operands output logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs2_forwarding_o, // Program Counter - EX_STAGE output logic [CVA6Cfg.VLEN-1:0] pc_o, + //is zcmt + output logic is_zcmt_o, // Is compressed instruction - EX_STAGE output logic is_compressed_instr_o, // Fixed Latency Unit is ready - EX_STAGE @@ -119,11 +121,8 @@ module issue_read_operands input logic [CVA6Cfg.NrCommitPorts-1:0] we_gpr_i, // FPR write enable - COMMIT_STAGE input logic [CVA6Cfg.NrCommitPorts-1:0] we_fpr_i, - // Issue stall - PERF_COUNTERS - output logic stall_issue_o, - input logic is_zcmt_i, - output logic is_zcmt_o + output logic stall_issue_o ); localparam OPERANDS_PER_INSTR = CVA6Cfg.NrRgprPorts / CVA6Cfg.NrIssuePorts; @@ -192,9 +191,6 @@ module issue_read_operands // forwarding signals logic [CVA6Cfg.NrIssuePorts-1:0] forward_rs1, forward_rs2, forward_rs3; - logic is_zcmt_n, is_zcmt_q; - assign is_zcmt_n = is_zcmt_i; - assign is_zcmt_o = is_zcmt_q; // original instruction riscv::instruction_t orig_instr; @@ -1106,13 +1102,13 @@ module issue_read_operands tinst_q <= '0; end pc_o <= '0; + is_zcmt_o <= '0; is_compressed_instr_o <= 1'b0; branch_predict_o <= {cf_t'(0), {CVA6Cfg.VLEN{1'b0}}}; x_transaction_rejected_o <= 1'b0; - is_zcmt_q <= 1'b0; end else begin fu_data_q <= fu_data_n; - is_zcmt_q <= is_zcmt_n; + is_zcmt_o <= issue_instr_i[0].is_zcmt; if (CVA6Cfg.RVH) begin tinst_q <= tinst_n; end diff --git a/core/issue_stage.sv b/core/issue_stage.sv index f111805433..55a8ef5622 100644 --- a/core/issue_stage.sv +++ b/core/issue_stage.sv @@ -60,6 +60,8 @@ module issue_stage output fu_data_t [CVA6Cfg.NrIssuePorts-1:0] fu_data_o, // Program Counter - EX_STAGE output logic [CVA6Cfg.VLEN-1:0] pc_o, + //is zcmt instruction + output logic is_zcmt_o, // Is compressed instruction - EX_STAGE output logic is_compressed_instr_o, // Transformed trap instruction - EX_STAGE @@ -157,10 +159,7 @@ module issue_stage // Information dedicated to RVFI - RVFI output logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_issue_pointer_o, // Information dedicated to RVFI - RVFI - output logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_commit_pointer_o, - //zcmt instruction - input logic is_zcmt_i, - output logic is_zcmt_o + output logic [CVA6Cfg.NrCommitPorts-1:0][CVA6Cfg.TRANS_ID_BITS-1:0] rvfi_commit_pointer_o ); // --------------------------------------------------- // Scoreboard (SB) <-> Issue and Read Operands (IRO) @@ -189,7 +188,6 @@ module issue_stage assign issue_instr_o = issue_instr_sb_iro[0]; assign issue_instr_hs_o = issue_instr_valid_sb_iro[0] & issue_ack_iro_sb[0]; - assign is_zcmt_o = is_zcmt_i; logic x_transaction_accepted_iro_sb, x_issue_writeback_iro_sb; logic [CVA6Cfg.TRANS_ID_BITS-1:0] x_id_iro_sb; @@ -267,6 +265,7 @@ module issue_stage .rs1_forwarding_o (rs1_forwarding_xlen), .rs2_forwarding_o (rs2_forwarding_xlen), .pc_o, + .is_zcmt_o (is_zcmt_o), .is_compressed_instr_o, .flu_ready_i (flu_ready_i), .alu_valid_o (alu_valid_o), @@ -303,9 +302,7 @@ module issue_stage .wdata_i, .we_gpr_i, .we_fpr_i, - .stall_issue_o, - .is_zcmt_i (is_zcmt_i), - .is_zcmt_o (is_zcmt_o) + .stall_issue_o ); endmodule diff --git a/core/zcmt_decoder.sv b/core/zcmt_decoder.sv index 68ea0ffbe8..9cc8e81911 100644 --- a/core/zcmt_decoder.sv +++ b/core/zcmt_decoder.sv @@ -1,204 +1,107 @@ // Author: Farhan Ali Shah, 10xEngineers // Date: 15.11.2024 -// Description: ZCMT Extension - +// Description: ZCMT extension in the CVA6 core targeting the 32-bit embedded-class platforms (CV32A60x). +// ZCMT is a code-size reduction feature that utilizes compressed table jump instructions (cm.jt and cm.jalt) to +//reduce code size for embedded systems +// module zcmt_decoder #( parameter config_pkg::cva6_cfg_t CVA6Cfg = config_pkg::cva6_cfg_empty, parameter type dcache_req_i_t = logic, parameter type dcache_req_o_t = logic, + parameter type jvt_t = logic, parameter type branchpredict_sbe_t = logic ) ( input logic clk_i, // Clock - input logic rst_ni, // Synchronous reset - input logic [31:0] instr_i, // instruction + input logic rst_ni, // Synchronous reset + input logic [31:0] instr_i, // instruction input logic [CVA6Cfg.VLEN-1:0] pc_i, // PC input logic is_zcmt_instr_i, // Intruction is of macro extension input logic illegal_instr_i, // From compressed decoder input logic is_compressed_i, // is compressed instruction - input logic issue_ack_i, // Check if the intruction is acknowledged - input logic [CVA6Cfg.XLEN-1:6] jvt_base_i, // JVT CSR base - input logic [5:0] jvt_mode_i, // JVT CSR mode + input jvt_t jvt_i, input dcache_req_o_t req_port_i, // Data cache request ouput - CACHE output logic [31:0] instr_o, // Instruction out output logic illegal_instr_o, // Illegel instruction output logic is_compressed_o, // is compressed instruction output logic fetch_stall_o, // Wait while address fetched from table - output logic is_zcmt_o, // is zcmt instruction output dcache_req_i_t req_port_o // Data cache request input - CACHE ); // FSM States - enum logic [1:0] { - IDLE, // Wait for ZCMT instruction - REQ_SENT, // Request sent to fetch the entry from jump table - TABLE_FETCH, // Check the valid data from jump table and record - JUMP // Calculate the offset for jump and create jal instruction + enum logic { + IDLE, // if ZCMT instruction then request sent to fetch the entry from jump table + TABLE_JUMP // Check the valid data from jump table and Calculate the offset for jump and create jal instruction } state_d, state_q; - - //zcmt instruction type - enum logic [1:0] { - NOT_ZCMT, // 00: Not a ZCMT instrcution - JT, // 01: cm.jt instruction - JALT // 10: cm.jalt instruction - } zcmt_instr_type; - // Temporary registers - logic [31:0] instr_o_reg; logic [7:0] index; //index of instruction - logic [CVA6Cfg.XLEN-1:0] table_address; //Physical address: jvt + (index <<2) - logic [CVA6Cfg.XLEN+1:0] table_a; //Virtual address: {00,Physical address} - logic [31:0] jvt_table_add; - logic [CVA6Cfg.XLEN-1:0] data_rdata_d, data_rdata_q; //data received from instruction memory - logic [20:0] jump_add; //jump address immidiate - - assign instr_o = instr_o_reg; //instruction output assigned + //Physical address: jvt + (index <<2) + logic [CVA6Cfg.XLEN+1:0] table_address; //Virtual address: {00,Physical address} + logic [20:0] jump_addr; //jump address immidiate always_comb begin - state_d = state_q; - data_rdata_d = data_rdata_q; - illegal_instr_o = 1'b0; - is_compressed_o = is_zcmt_instr_i ? 1'b1 : is_compressed_i; - illegal_instr_o = 1'b0; - is_zcmt_o = 1'b0; - fetch_stall_o = is_zcmt_instr_i ? 1'b1 : 0; - - if (is_zcmt_instr_i) begin - unique case (instr_i[12:10]) - //zcmt instruction - 3'b000: begin - if (instr_i[9:2] < 32) begin //JT instruction - zcmt_instr_type = JT; - index = instr_i[9:2]; - end else if (instr_i[9:2] >= 32 & instr_i[9:2] <= 32) begin //JALT instruction - zcmt_instr_type = JALT; - index = instr_i[9:2]; - end else begin - zcmt_instr_type = NOT_ZCMT; //NOT ZCMT instruction - illegal_instr_o = 1'b1; - instr_o_reg = instr_i; - end - end - end - end - end - end - end - end - end - end - end - end - default: begin - illegal_instr_o = 1'b1; - instr_o_reg = instr_i; - zcmt_instr_type = NOT_ZCMT; - end - endcase - end else begin - illegal_instr_o = illegal_instr_i; - instr_o_reg = instr_i; - end + state_d = state_q; + illegal_instr_o = 1'b0; + is_compressed_o = is_zcmt_instr_i ? 1'b1 : is_compressed_i; + fetch_stall_o = is_zcmt_instr_i ? 1'b1 : 0; + + //cache request port + req_port_o.data_wdata = 1'b0; + req_port_o.data_wuser = '0; + req_port_o.data_req = 1'b0; + req_port_o.data_we = 1'b0; + req_port_o.data_be = 1'b0; + req_port_o.data_size = 2'b10; + req_port_o.data_id = 1; + req_port_o.kill_req = 0; + req_port_o.tag_valid = 1; unique case (state_q) IDLE: begin if (is_zcmt_instr_i) begin - state_d = REQ_SENT; + if (CVA6Cfg.XLEN == 32) begin //It is only target for 32 bit targets in cva6 with No MMU + table_address = {2'b00, ({jvt_i.base, jvt_i.mode} + (instr_i[9:2] << 2))}; + req_port_o.address_index = table_address[9:0]; + req_port_o.address_tag = table_address[33:10]; + state_d = TABLE_JUMP; + req_port_o.data_req = 1'b1; + end else illegal_instr_o = 1'b1; + //Condition may be extented for 64 bits embedded targets with No MMU end else begin - state_d = IDLE; + illegal_instr_o = illegal_instr_i; + instr_o = instr_i; + state_d = IDLE; end end - REQ_SENT: begin - state_d = TABLE_FETCH; - case (zcmt_instr_type) - JT: begin - if (CVA6Cfg.XLEN == 32) begin - jvt_table_add = {jvt_base_i[31:6], 6'b000000}; - table_address = jvt_table_add + (index << 2); - table_a = {2'b00, table_address[CVA6Cfg.XLEN-1:0]}; - req_port_o.address_index = table_a[9:0]; - req_port_o.address_tag = table_a[33:10]; - req_port_o.data_wdata = 1'b0; - req_port_o.data_wuser = '0; - req_port_o.data_req = 1'b1; - req_port_o.data_we = 1'b0; - req_port_o.data_be = 1'b0; - req_port_o.data_size = 2'b10; - req_port_o.data_id = 1; - req_port_o.kill_req = 0; - req_port_o.tag_valid = 1; - - end else if (CVA6Cfg.XLEN == 64) begin - jvt_table_add = {jvt_base_i[31:6], 6'b000000}; - table_address = jvt_table_add + (index << 3); - table_a = {2'b00, table_address[CVA6Cfg.XLEN-1:0]}; - // will will completed in future( for 64 bit embedded core) - illegal_instr_o = 1'b1; - end else begin - illegal_instr_o = 1'b1; - instr_o_reg = instr_i; - end - end - JALT: begin - if (CVA6Cfg.XLEN == 32) begin - jvt_table_add = {jvt_base_i[31:6], 6'b000000}; - table_address = jvt_table_add + (index << 2); - table_a = {2'b00, table_address[CVA6Cfg.XLEN-1:0]}; - req_port_o.address_index = table_a[9:0]; - req_port_o.address_tag = table_a[33:10]; - req_port_o.data_wdata = 1'b0; - req_port_o.data_wuser = '0; - req_port_o.data_req = 1'b1; - req_port_o.data_we = 1'b0; - req_port_o.data_be = 1'b0; - req_port_o.data_size = 2'b10; - req_port_o.data_id = 1; - req_port_o.kill_req = 0; - req_port_o.tag_valid = 1; - - end else if (CVA6Cfg.XLEN == 64) begin - jvt_table_add = {jvt_base_i[31:6], 6'b000000}; - table_address = jvt_table_add + (index << 3); - table_a = {2'b00, table_address[CVA6Cfg.XLEN-1:0]}; - // will will completed in future( for 64 bit embedded core) - illegal_instr_o = 1'b1; - end else begin - illegal_instr_o = 1'b1; - instr_o_reg = instr_i; - end - end - default: state_d = IDLE; - endcase - end - TABLE_FETCH: begin - if (req_port_i.data_rid & req_port_i.data_rvalid) begin - data_rdata_d = req_port_i.data_rdata; - state_d = JUMP; - end else begin - state_d = TABLE_FETCH; - end - end - end - JUMP: begin - if (issue_ack_i) begin - - jump_add = $unsigned($signed(data_rdata_q) - $signed(pc_i)); - - if (zcmt_instr_type == JT) begin - instr_o_reg = { - jump_add[20], jump_add[10:1], jump_add[11], jump_add[19:12], 5'h0, riscv::OpcodeJal - }; //- jal pc_offset, x0 - end else if (zcmt_instr_type == JALT) begin - instr_o_reg = { - jump_add[20], jump_add[10:1], jump_add[11], jump_add[19:12], 5'h1, riscv::OpcodeJal + TABLE_JUMP: begin + if (req_port_i.data_rvalid) begin + jump_addr = $unsigned($signed(req_port_i.data_rdata) - $signed(pc_i)); + if (instr_i[9:2] < 32) begin //- jal pc_offset, x0 for no return stack + instr_o = { + jump_addr[20], + jump_addr[10:1], + jump_addr[11], + jump_addr[19:12], + 5'h0, + riscv::OpcodeJal + }; + end else if ((instr_i[9:2] >= 32) & (instr_i[9:2] <= 255)) begin //- jal pc_offset, x1 for return stack + instr_o = { + jump_addr[20], + jump_addr[10:1], + jump_addr[11], + jump_addr[19:12], + 5'h1, + riscv::OpcodeJal }; + end else begin + illegal_instr_o = 1'b1; + instr_o = instr_i; end - - is_zcmt_o = 1'b1; - state_d = IDLE; + state_d = IDLE; end else begin - state_d = JUMP; + state_d = TABLE_JUMP; end end default: begin @@ -209,17 +112,10 @@ module zcmt_decoder #( always_ff @(posedge clk_i or negedge rst_ni) begin if (~rst_ni) begin - state_q <= IDLE; - data_rdata_q <= '0; + state_q <= IDLE; end else begin - state_q <= state_d; - data_rdata_q <= data_rdata_d; - - end - end - end - end + state_q <= state_d; end end endmodule diff --git a/verif/tests/custom/zcmt/cm_jalt_ret.S b/verif/tests/custom/zcmt/cm_jalt_ret.S index f6586d60a0..82eaf36cc4 100644 --- a/verif/tests/custom/zcmt/cm_jalt_ret.S +++ b/verif/tests/custom/zcmt/cm_jalt_ret.S @@ -43,7 +43,7 @@ __jvt_base$: # Target Addresses (Where cm.jalt will jump) target0: - li x5, 99 + li x5, 9 j write_tohost target1: li x2, 99 From fba9b6ace5a3fd60714a32cc966eebbac4f73bbd Mon Sep 17 00:00:00 2001 From: Farhan Ali Date: Tue, 10 Dec 2024 14:46:58 +0500 Subject: [PATCH 03/10] lint fix and comments --- core/cva6.sv | 8 ++++++-- core/include/build_config_pkg.sv | 6 ++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/core/cva6.sv b/core/cva6.sv index 160b23f55a..c7062b217e 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -1280,7 +1280,9 @@ module cva6 dcache_req_o_t [NumPorts-1:0] dcache_req_from_cache; // D$ request - if (CVA6Cfg.RVZCMT & ~(CVA6Cfg.MmuPresent)) begin // Cache port 0 is ultilize in implicit read access in ZCMT extension. Therefore, MMU should be turn off. + // Since ZCMT is only enable for embdeed class so MMU should be disable. + // Cache port 0 is being ultilize in implicit read access in ZCMT extension. + if (CVA6Cfg.RVZCMT & ~(CVA6Cfg.MmuPresent)) begin assign dcache_req_to_cache[0] = dcache_req_ports_id_cache; end else begin assign dcache_req_to_cache[0] = dcache_req_ports_ex_cache[0]; @@ -1291,7 +1293,9 @@ module cva6 dcache_req_ports_acc_cache[1]; // D$ response - if (CVA6Cfg.RVZCMT & ~(CVA6Cfg.MmuPresent)) begin // Cache port 0 is ultilize in implicit read access in ZCMT extension. Therefore, MMU should be turn off. + // Since ZCMT is only enable for embdeed class so MMU should be disable. + // Cache port 0 is being ultilized in implicit read access in ZCMT extension. + if (CVA6Cfg.RVZCMT & ~(CVA6Cfg.MmuPresent)) begin assign dcache_req_ports_cache_id = dcache_req_from_cache[0]; end else begin assign dcache_req_ports_cache_ex[0] = dcache_req_from_cache[0]; diff --git a/core/include/build_config_pkg.sv b/core/include/build_config_pkg.sv index 7b76714a8c..dcf66275d8 100644 --- a/core/include/build_config_pkg.sv +++ b/core/include/build_config_pkg.sv @@ -124,7 +124,8 @@ package build_config_pkg; cfg.AxiBurstWriteEn = CVA6Cfg.AxiBurstWriteEn; cfg.ICACHE_SET_ASSOC = CVA6Cfg.IcacheSetAssoc; - cfg.ICACHE_SET_ASSOC_WIDTH = CVA6Cfg.IcacheSetAssoc > 1 ? $clog2(CVA6Cfg.IcacheSetAssoc) : CVA6Cfg.IcacheSetAssoc; + cfg.ICACHE_SET_ASSOC_WIDTH = CVA6Cfg.IcacheSetAssoc > 1 ? $clog2(CVA6Cfg.IcacheSetAssoc) : + CVA6Cfg.IcacheSetAssoc; cfg.ICACHE_INDEX_WIDTH = ICACHE_INDEX_WIDTH; cfg.ICACHE_TAG_WIDTH = cfg.PLEN - ICACHE_INDEX_WIDTH; cfg.ICACHE_LINE_WIDTH = CVA6Cfg.IcacheLineWidth; @@ -132,7 +133,8 @@ package build_config_pkg; cfg.DCacheType = CVA6Cfg.DCacheType; cfg.DcacheIdWidth = CVA6Cfg.DcacheIdWidth; cfg.DCACHE_SET_ASSOC = CVA6Cfg.DcacheSetAssoc; - cfg.DCACHE_SET_ASSOC_WIDTH = CVA6Cfg.DcacheSetAssoc > 1 ? $clog2(CVA6Cfg.DcacheSetAssoc) : CVA6Cfg.DcacheSetAssoc; + cfg.DCACHE_SET_ASSOC_WIDTH = CVA6Cfg.DcacheSetAssoc > 1 ? $clog2(CVA6Cfg.DcacheSetAssoc) : + CVA6Cfg.DcacheSetAssoc; cfg.DCACHE_INDEX_WIDTH = DCACHE_INDEX_WIDTH; cfg.DCACHE_TAG_WIDTH = cfg.PLEN - DCACHE_INDEX_WIDTH; cfg.DCACHE_LINE_WIDTH = CVA6Cfg.DcacheLineWidth; From 645d24f40914f5ec1792b602cffb8a0433474ca2 Mon Sep 17 00:00:00 2001 From: Farhan Ali Date: Wed, 11 Dec 2024 16:17:40 +0500 Subject: [PATCH 04/10] lint fixes --- core/compressed_decoder.sv | 4 ++-- core/cva6.sv | 2 ++ core/ex_stage.sv | 4 ++-- core/id_stage.sv | 37 ++++++++++++++++++------------------- core/issue_stage.sv | 2 +- core/zcmt_decoder.sv | 16 ++++++++-------- 6 files changed, 33 insertions(+), 32 deletions(-) diff --git a/core/compressed_decoder.sv b/core/compressed_decoder.sv index d8e395cb48..c691dfa75b 100644 --- a/core/compressed_decoder.sv +++ b/core/compressed_decoder.sv @@ -44,7 +44,7 @@ module compressed_decoder #( is_compressed_o = 1'b1; instr_o = instr_i; is_macro_instr_o = 0; - is_zcmt_instr_o = 0; + is_zcmt_instr_o = 1'b0; // I: | imm[11:0] | rs1 | funct3 | rd | opcode | // S: | imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode | @@ -875,7 +875,7 @@ module compressed_decoder #( is_macro_instr_o = 1; instr_o = instr_i; end else if (instr_i[12:10] == 3'b000) begin //jt/jalt instruction - is_zcmt_instr_o = 1; + is_zcmt_instr_o = 1'b1; end else begin illegal_instr_o = 1'b1; end diff --git a/core/cva6.sv b/core/cva6.sv index c7062b217e..3c2e576be4 100644 --- a/core/cva6.sv +++ b/core/cva6.sv @@ -1297,8 +1297,10 @@ module cva6 // Cache port 0 is being ultilized in implicit read access in ZCMT extension. if (CVA6Cfg.RVZCMT & ~(CVA6Cfg.MmuPresent)) begin assign dcache_req_ports_cache_id = dcache_req_from_cache[0]; + assign dcache_req_ports_cache_ex[0] = '0; end else begin assign dcache_req_ports_cache_ex[0] = dcache_req_from_cache[0]; + assign dcache_req_ports_cache_id = '0; end assign dcache_req_ports_cache_ex[1] = dcache_req_from_cache[1]; assign dcache_req_ports_cache_acc[0] = dcache_req_from_cache[2]; diff --git a/core/ex_stage.sv b/core/ex_stage.sv index 6c3da27a06..236583b0fd 100644 --- a/core/ex_stage.sv +++ b/core/ex_stage.sv @@ -321,8 +321,8 @@ module ex_stage .v_i, .debug_mode_i, .fu_data_i (one_cycle_data), - .pc_i, - .is_zcmt_i, + .pc_i (pc_i), + .is_zcmt_i (is_zcmt_i), .is_compressed_instr_i, .branch_valid_i (|branch_valid_i), .branch_comp_res_i (alu_branch_res), diff --git a/core/id_stage.sv b/core/id_stage.sv index 3196ef76e7..36cf1963ad 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -111,24 +111,23 @@ module id_stage #( logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal; logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_cmp; - logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_cvxif, is_illegal_cvxif_zcmp, is_illegal_cvxif_zcmt; + logic [CVA6Cfg.NrIssuePorts-1:0] is_illegal_cvxif; + logic is_illegal_cvxif_zcmp, is_illegal_cvxif_zcmt; logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction; logic [CVA6Cfg.NrIssuePorts-1:0][31:0] compressed_instr; - logic [CVA6Cfg.NrIssuePorts-1:0][31:0] - instruction_cvxif, instruction_cvxif_zcmp, instruction_cvxif_zcmt; + logic [CVA6Cfg.NrIssuePorts-1:0][31:0] instruction_cvxif; + logic [31:0] instruction_cvxif_zcmp, instruction_cvxif_zcmt; logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed; logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_cmp; - logic [CVA6Cfg.NrIssuePorts-1:0] - is_compressed_cvxif, is_compressed_cvxif_zcmp, is_compressed_cvxif_zcmt; + logic [CVA6Cfg.NrIssuePorts-1:0] is_compressed_cvxif; + logic is_compressed_cvxif_zcmp, is_compressed_cvxif_zcmt; logic [CVA6Cfg.NrIssuePorts-1:0] is_macro_instr_i; logic stall_instr_fetch; logic stall_macro_deco, stall_macro_deco_zcmp, stall_macro_deco_zcmt; - logic is_last_macro_instr_o; - logic is_double_rd_macro_instr_o; - logic [CVA6Cfg.NrIssuePorts-1:0] is_zcmt_instr_i; - branchpredict_sbe_t branch_predict; - logic is_zcmt; + logic is_last_macro_instr_o; + logic is_double_rd_macro_instr_o; + logic [CVA6Cfg.NrIssuePorts-1:0] is_zcmt_instr_i; if (CVA6Cfg.RVC) begin // --------------------------------------------------------- @@ -155,12 +154,12 @@ module id_stage #( .is_macro_instr_i (is_macro_instr_i[0]), .clk_i (clk_i), .rst_ni (rst_ni), - .instr_o (instruction_cvxif_zcmp[0]), + .instr_o (instruction_cvxif_zcmp), .illegal_instr_i (is_illegal[0]), .is_compressed_i (is_compressed[0]), .issue_ack_i (issue_instr_ack_i[0]), - .illegal_instr_o (is_illegal_cvxif_zcmp[0]), - .is_compressed_o (is_compressed_cvxif_zcmp[0]), + .illegal_instr_o (is_illegal_cvxif_zcmp), + .is_compressed_o (is_compressed_cvxif_zcmp), .fetch_stall_o (stall_macro_deco_zcmp), .is_last_macro_instr_o (is_last_macro_instr_o), .is_double_rd_macro_instr_o(is_double_rd_macro_instr_o) @@ -177,20 +176,20 @@ module id_stage #( .is_zcmt_instr_i(is_zcmt_instr_i[0]), .clk_i (clk_i), .rst_ni (rst_ni), - .instr_o (instruction_cvxif_zcmt[0]), + .instr_o (instruction_cvxif_zcmt), .illegal_instr_i(is_illegal[0]), .is_compressed_i(is_compressed[0]), - .illegal_instr_o(is_illegal_cvxif_zcmt[0]), - .is_compressed_o(is_compressed_cvxif_zcmt[0]), + .illegal_instr_o(is_illegal_cvxif_zcmt), + .is_compressed_o(is_compressed_cvxif_zcmt), .fetch_stall_o (stall_macro_deco_zcmt), .jvt_i (jvt_i), .req_port_i (dcache_req_ports_i), .req_port_o (dcache_req_ports_o) ); - assign instruction_cvxif[0] = is_zcmt_instr_i[0] ? instruction_cvxif_zcmt[0] : instruction_cvxif_zcmp[0]; - assign is_illegal_cvxif[0] = is_zcmt_instr_i[0] ? is_illegal_cvxif_zcmt[0] : is_illegal_cvxif_zcmp[0]; - assign is_compressed_cvxif[0] = is_zcmt_instr_i[0] ? is_compressed_cvxif_zcmt[0] : is_compressed_cvxif_zcmp[0]; + assign instruction_cvxif[0] = is_zcmt_instr_i[0] ? instruction_cvxif_zcmt : instruction_cvxif_zcmp; + assign is_illegal_cvxif[0] = is_zcmt_instr_i[0] ? is_illegal_cvxif_zcmt : is_illegal_cvxif_zcmp; + assign is_compressed_cvxif[0] = is_zcmt_instr_i[0] ? is_compressed_cvxif_zcmt : is_compressed_cvxif_zcmp; assign stall_macro_deco = is_zcmt_instr_i[0] ? stall_macro_deco_zcmt : stall_macro_deco_zcmp; if (CVA6Cfg.SuperscalarEn) begin assign instruction_cvxif[CVA6Cfg.NrIssuePorts-1] = '0; diff --git a/core/issue_stage.sv b/core/issue_stage.sv index 55a8ef5622..0664aa229b 100644 --- a/core/issue_stage.sv +++ b/core/issue_stage.sv @@ -264,7 +264,7 @@ module issue_stage .fu_data_o (fu_data_o), .rs1_forwarding_o (rs1_forwarding_xlen), .rs2_forwarding_o (rs2_forwarding_xlen), - .pc_o, + .pc_o (pc_o), .is_zcmt_o (is_zcmt_o), .is_compressed_instr_o, .flu_ready_i (flu_ready_i), diff --git a/core/zcmt_decoder.sv b/core/zcmt_decoder.sv index 9cc8e81911..75fd1d33b6 100644 --- a/core/zcmt_decoder.sv +++ b/core/zcmt_decoder.sv @@ -35,10 +35,9 @@ module zcmt_decoder #( } state_d, state_q; // Temporary registers - logic [7:0] index; //index of instruction //Physical address: jvt + (index <<2) logic [CVA6Cfg.XLEN+1:0] table_address; //Virtual address: {00,Physical address} - logic [20:0] jump_addr; //jump address immidiate + logic [31:0] jump_addr; //jump address immidiate always_comb begin state_d = state_q; @@ -47,21 +46,22 @@ module zcmt_decoder #( fetch_stall_o = is_zcmt_instr_i ? 1'b1 : 0; //cache request port - req_port_o.data_wdata = 1'b0; + req_port_o.data_wdata = '0; req_port_o.data_wuser = '0; req_port_o.data_req = 1'b0; req_port_o.data_we = 1'b0; - req_port_o.data_be = 1'b0; + req_port_o.data_be = '0; req_port_o.data_size = 2'b10; - req_port_o.data_id = 1; - req_port_o.kill_req = 0; - req_port_o.tag_valid = 1; + req_port_o.data_id = 1'b1; + req_port_o.kill_req = 1'b0; + req_port_o.tag_valid = 1'b1; unique case (state_q) IDLE: begin if (is_zcmt_instr_i) begin if (CVA6Cfg.XLEN == 32) begin //It is only target for 32 bit targets in cva6 with No MMU - table_address = {2'b00, ({jvt_i.base, jvt_i.mode} + (instr_i[9:2] << 2))}; + // table_address = {2'b00, ({jvt_i.base, instr_i[7:2], 2'b00})}; + table_address = {2'b00, ({jvt_i.base, jvt_i.mode} + {24'h0, instr_i[7:2], 2'b00})}; req_port_o.address_index = table_address[9:0]; req_port_o.address_tag = table_address[33:10]; state_d = TABLE_JUMP; From 1186002b690334818831115024a6b7d62b930375 Mon Sep 17 00:00:00 2001 From: Farhan Ali Date: Wed, 11 Dec 2024 20:05:51 +0500 Subject: [PATCH 05/10] gate reduction changes --- core/branch_unit.sv | 16 ++++++++++------ core/csr_regfile.sv | 21 ++++++++++++++++----- core/issue_read_operands.sv | 3 ++- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/core/branch_unit.sv b/core/branch_unit.sv index c702567725..1016ce6a18 100644 --- a/core/branch_unit.sv +++ b/core/branch_unit.sv @@ -83,12 +83,16 @@ module branch_unit #( // 3. Zcmt instructions if (branch_valid_i) begin // write target address which goes to PC Gen or select target address if zcmt - resolved_branch_o.target_address = (branch_comp_res_i) | is_zcmt_i ? target_address : next_pc; - resolved_branch_o.is_taken = is_zcmt_i ? 1'b1 : branch_comp_res_i; - if (is_zcmt_i) begin - // Unconditional jump handling - resolved_branch_o.is_mispredict = 1'b1; // miss prediction for ZCMT - resolved_branch_o.cf_type = ariane_pkg::Jump; + resolved_branch_o.target_address = (branch_comp_res_i) ? target_address : next_pc; + resolved_branch_o.is_taken = branch_comp_res_i; + if (CVA6Cfg.RVZCMT) begin + if (is_zcmt_i) begin + // Unconditional jump handling + resolved_branch_o.target_address = target_address; + resolved_branch_o.is_taken = 1'b1; + resolved_branch_o.is_mispredict = 1'b1; // miss prediction for ZCMT + resolved_branch_o.cf_type = ariane_pkg::Jump; + end end // check the outcome of the branch speculation if (ariane_pkg::op_is_branch(fu_data_i.operation)) begin diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 3b58ad2995..03ed59356c 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -919,7 +919,9 @@ module csr_regfile perf_we_o = 1'b0; perf_data_o = 'b0; - jvt_d = jvt_q; + if (CVA6Cfg.RVZCMT) begin + jvt_d = jvt_q; + end fcsr_d = fcsr_q; priv_lvl_d = priv_lvl_q; @@ -2472,8 +2474,13 @@ module csr_regfile assign frm_o = fcsr_q.frm; assign fprec_o = fcsr_q.fprec; //JVT outputs - assign jvt_o.base = jvt_q.base; - assign jvt_o.mode = jvt_q.mode; + if (CVA6Cfg.RVZCMT) begin + assign jvt_o.base = jvt_q.base; + assign jvt_o.mode = jvt_q.mode; + end else begin + assign jvt_o.base = '0; + assign jvt_o.mode = '0; + end // MMU outputs assign satp_ppn_o = CVA6Cfg.RVS ? satp_q.ppn : '0; assign vsatp_ppn_o = CVA6Cfg.RVH ? vsatp_q.ppn : '0; @@ -2540,7 +2547,9 @@ module csr_regfile priv_lvl_q <= riscv::PRIV_LVL_M; // floating-point registers fcsr_q <= '0; - jvt_q <= '0; + if (CVA6Cfg.RVZCMT) begin + jvt_q <= '0; + end // debug signals debug_mode_q <= 1'b0; if (CVA6Cfg.DebugEn) begin @@ -2624,7 +2633,9 @@ module csr_regfile priv_lvl_q <= priv_lvl_d; // floating-point registers fcsr_q <= fcsr_d; - jvt_q <= jvt_d; + if (CVA6Cfg.RVZCMT) begin + jvt_q <= jvt_d; + end // debug signals if (CVA6Cfg.DebugEn) begin debug_mode_q <= debug_mode_d; diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index 1c1a904719..874181bdbb 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -1108,7 +1108,6 @@ module issue_read_operands x_transaction_rejected_o <= 1'b0; end else begin fu_data_q <= fu_data_n; - is_zcmt_o <= issue_instr_i[0].is_zcmt; if (CVA6Cfg.RVH) begin tinst_q <= tinst_n; end @@ -1123,6 +1122,8 @@ module issue_read_operands pc_o <= issue_instr_i[0].pc; is_compressed_instr_o <= issue_instr_i[0].is_compressed; branch_predict_o <= issue_instr_i[0].bp; + if (CVA6Cfg.RVZCMT) is_zcmt_o <= issue_instr_i[0].is_zcmt; + else is_zcmt_o <= '0; end x_transaction_rejected_o <= 1'b0; if (issue_instr_i[0].fu == CVXIF) begin From 9b7e530b751510536eb7c5f2ec9483d4b02bb226 Mon Sep 17 00:00:00 2001 From: Farhan Ali Date: Wed, 11 Dec 2024 20:08:36 +0500 Subject: [PATCH 06/10] lint fixes 3 --- core/csr_regfile.sv | 20 ++++++++++---------- core/issue_read_operands.sv | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/csr_regfile.sv b/core/csr_regfile.sv index 03ed59356c..c44d84bd0a 100644 --- a/core/csr_regfile.sv +++ b/core/csr_regfile.sv @@ -920,13 +920,13 @@ module csr_regfile perf_we_o = 1'b0; perf_data_o = 'b0; if (CVA6Cfg.RVZCMT) begin - jvt_d = jvt_q; + jvt_d = jvt_q; end - fcsr_d = fcsr_q; + fcsr_d = fcsr_q; - priv_lvl_d = priv_lvl_q; - v_d = v_q; - debug_mode_d = debug_mode_q; + priv_lvl_d = priv_lvl_q; + v_d = v_q; + debug_mode_d = debug_mode_q; if (CVA6Cfg.DebugEn) begin dcsr_d = dcsr_q; @@ -2482,7 +2482,7 @@ module csr_regfile assign jvt_o.mode = '0; end // MMU outputs - assign satp_ppn_o = CVA6Cfg.RVS ? satp_q.ppn : '0; + assign satp_ppn_o = CVA6Cfg.RVS ? satp_q.ppn : '0; assign vsatp_ppn_o = CVA6Cfg.RVH ? vsatp_q.ppn : '0; assign hgatp_ppn_o = CVA6Cfg.RVH ? hgatp_q.ppn : '0; if (CVA6Cfg.RVS) begin @@ -2544,11 +2544,11 @@ module csr_regfile // sequential process always_ff @(posedge clk_i or negedge rst_ni) begin if (~rst_ni) begin - priv_lvl_q <= riscv::PRIV_LVL_M; + priv_lvl_q <= riscv::PRIV_LVL_M; // floating-point registers - fcsr_q <= '0; + fcsr_q <= '0; if (CVA6Cfg.RVZCMT) begin - jvt_q <= '0; + jvt_q <= '0; end // debug signals debug_mode_q <= 1'b0; @@ -2634,7 +2634,7 @@ module csr_regfile // floating-point registers fcsr_q <= fcsr_d; if (CVA6Cfg.RVZCMT) begin - jvt_q <= jvt_d; + jvt_q <= jvt_d; end // debug signals if (CVA6Cfg.DebugEn) begin diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index 874181bdbb..40dbd85c1c 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -1122,8 +1122,8 @@ module issue_read_operands pc_o <= issue_instr_i[0].pc; is_compressed_instr_o <= issue_instr_i[0].is_compressed; branch_predict_o <= issue_instr_i[0].bp; - if (CVA6Cfg.RVZCMT) is_zcmt_o <= issue_instr_i[0].is_zcmt; - else is_zcmt_o <= '0; + if (CVA6Cfg.RVZCMT) is_zcmt_o <= issue_instr_i[0].is_zcmt; + else is_zcmt_o <= '0; end x_transaction_rejected_o <= 1'b0; if (issue_instr_i[0].fu == CVXIF) begin From 7a86356fc1ce5951e1d404ad28dd460a0585c6ef Mon Sep 17 00:00:00 2001 From: Farhan Ali Date: Thu, 12 Dec 2024 12:39:00 +0500 Subject: [PATCH 07/10] fixing the conditions --- core/id_stage.sv | 82 ++++++++++--------- .../cv32a6_embedded_config_pkg_deprecated.sv | 3 +- .../cv32a6_ima_sv32_fpga_config_pkg.sv | 3 +- core/include/cv32a6_imac_sv0_config_pkg.sv | 3 +- core/include/cv32a6_imac_sv32_config_pkg.sv | 3 +- core/include/cv32a6_imafc_sv32_config_pkg.sv | 3 +- .../cv64a6_imadfcv_sv39_polara_config_pkg.sv | 3 +- core/include/cv64a6_imafdc_sv39_config_pkg.sv | 3 +- .../cv64a6_imafdc_sv39_hpdcache_config_pkg.sv | 3 +- ...cv64a6_imafdc_sv39_openpiton_config_pkg.sv | 3 +- .../cv64a6_imafdc_sv39_wb_config_pkg.sv | 3 +- .../include/cv64a6_imafdch_sv39_config_pkg.sv | 3 +- .../cv64a6_imafdch_sv39_wb_config_pkg.sv | 3 +- .../include/cv64a6_imafdcv_sv39_config_pkg.sv | 3 +- 14 files changed, 56 insertions(+), 65 deletions(-) diff --git a/core/id_stage.sv b/core/id_stage.sv index 36cf1963ad..2f072e5b5b 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -147,45 +147,49 @@ module id_stage #( end if (CVA6Cfg.RVZCMP || (CVA6Cfg.RVZCMT & ~CVA6Cfg.MmuPresent)) begin //MMU should be off when using ZCMT //sequencial decoder - macro_decoder #( - .CVA6Cfg(CVA6Cfg) - ) macro_decoder_i ( - .instr_i (compressed_instr[0]), - .is_macro_instr_i (is_macro_instr_i[0]), - .clk_i (clk_i), - .rst_ni (rst_ni), - .instr_o (instruction_cvxif_zcmp), - .illegal_instr_i (is_illegal[0]), - .is_compressed_i (is_compressed[0]), - .issue_ack_i (issue_instr_ack_i[0]), - .illegal_instr_o (is_illegal_cvxif_zcmp), - .is_compressed_o (is_compressed_cvxif_zcmp), - .fetch_stall_o (stall_macro_deco_zcmp), - .is_last_macro_instr_o (is_last_macro_instr_o), - .is_double_rd_macro_instr_o(is_double_rd_macro_instr_o) - ); - zcmt_decoder #( - .CVA6Cfg(CVA6Cfg), - .dcache_req_i_t(dcache_req_i_t), - .dcache_req_o_t(dcache_req_o_t), - .jvt_t(jvt_t), - .branchpredict_sbe_t(branchpredict_sbe_t) - ) zcmt_decoder_i ( - .instr_i (compressed_instr[0]), - .pc_i (fetch_entry_i[0].address), - .is_zcmt_instr_i(is_zcmt_instr_i[0]), - .clk_i (clk_i), - .rst_ni (rst_ni), - .instr_o (instruction_cvxif_zcmt), - .illegal_instr_i(is_illegal[0]), - .is_compressed_i(is_compressed[0]), - .illegal_instr_o(is_illegal_cvxif_zcmt), - .is_compressed_o(is_compressed_cvxif_zcmt), - .fetch_stall_o (stall_macro_deco_zcmt), - .jvt_i (jvt_i), - .req_port_i (dcache_req_ports_i), - .req_port_o (dcache_req_ports_o) - ); + if (CVA6Cfg.RVZCMP) begin + macro_decoder #( + .CVA6Cfg(CVA6Cfg) + ) macro_decoder_i ( + .instr_i (compressed_instr[0]), + .is_macro_instr_i (is_macro_instr_i[0]), + .clk_i (clk_i), + .rst_ni (rst_ni), + .instr_o (instruction_cvxif_zcmp), + .illegal_instr_i (is_illegal[0]), + .is_compressed_i (is_compressed[0]), + .issue_ack_i (issue_instr_ack_i[0]), + .illegal_instr_o (is_illegal_cvxif_zcmp), + .is_compressed_o (is_compressed_cvxif_zcmp), + .fetch_stall_o (stall_macro_deco_zcmp), + .is_last_macro_instr_o (is_last_macro_instr_o), + .is_double_rd_macro_instr_o(is_double_rd_macro_instr_o) + ); + end + if (CVA6Cfg.RVZCMT) begin + zcmt_decoder #( + .CVA6Cfg(CVA6Cfg), + .dcache_req_i_t(dcache_req_i_t), + .dcache_req_o_t(dcache_req_o_t), + .jvt_t(jvt_t), + .branchpredict_sbe_t(branchpredict_sbe_t) + ) zcmt_decoder_i ( + .instr_i (compressed_instr[0]), + .pc_i (fetch_entry_i[0].address), + .is_zcmt_instr_i(is_zcmt_instr_i[0]), + .clk_i (clk_i), + .rst_ni (rst_ni), + .instr_o (instruction_cvxif_zcmt), + .illegal_instr_i(is_illegal[0]), + .is_compressed_i(is_compressed[0]), + .illegal_instr_o(is_illegal_cvxif_zcmt), + .is_compressed_o(is_compressed_cvxif_zcmt), + .fetch_stall_o (stall_macro_deco_zcmt), + .jvt_i (jvt_i), + .req_port_i (dcache_req_ports_i), + .req_port_o (dcache_req_ports_o) + ); + end else assign is_zcmt_instr_i[0] = '0; assign instruction_cvxif[0] = is_zcmt_instr_i[0] ? instruction_cvxif_zcmt : instruction_cvxif_zcmp; assign is_illegal_cvxif[0] = is_zcmt_instr_i[0] ? is_illegal_cvxif_zcmt : is_illegal_cvxif_zcmp; diff --git a/core/include/cv32a6_embedded_config_pkg_deprecated.sv b/core/include/cv32a6_embedded_config_pkg_deprecated.sv index 1170c75a05..7c3e02a746 100644 --- a/core/include/cv32a6_embedded_config_pkg_deprecated.sv +++ b/core/include/cv32a6_embedded_config_pkg_deprecated.sv @@ -21,7 +21,6 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; localparam CVA6ConfigZcmpExtEn = 0; - localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 0; localparam CVA6ConfigHExtEn = 0; // always disabled localparam CVA6ConfigBExtEn = 1; @@ -97,7 +96,7 @@ package cva6_config_pkg; RVZCB: bit'(CVA6ConfigZcbExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), - RVZCMT: bit'(CVA6ConfigZcmtExtEn), + RVZCMT: bit'(0), CvxifEn: bit'(CVA6ConfigCvxifEn), RVZiCond: bit'(CVA6ConfigRVZiCond), RVZicntr: bit'(1), diff --git a/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv b/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv index 7bf8c289f9..7adff10e84 100644 --- a/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv +++ b/core/include/cv32a6_ima_sv32_fpga_config_pkg.sv @@ -22,7 +22,6 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 0; localparam CVA6ConfigZcbExtEn = 0; localparam CVA6ConfigZcmpExtEn = 0; - localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigHExtEn = 0; // always disabled localparam CVA6ConfigBExtEn = 0; @@ -96,7 +95,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), - RVZCMT: bit'(CVA6ConfigZcmtExtEn), + RVZCMT: bit'(0), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv32a6_imac_sv0_config_pkg.sv b/core/include/cv32a6_imac_sv0_config_pkg.sv index 13800fd7c7..676fcfc720 100644 --- a/core/include/cv32a6_imac_sv0_config_pkg.sv +++ b/core/include/cv32a6_imac_sv0_config_pkg.sv @@ -22,7 +22,6 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; localparam CVA6ConfigZcmpExtEn = 0; - localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigHExtEn = 0; // always disabled localparam CVA6ConfigBExtEn = 0; @@ -96,7 +95,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), - RVZCMT: bit'(CVA6ConfigZcmtExtEn), + RVZCMT: bit'(0), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv32a6_imac_sv32_config_pkg.sv b/core/include/cv32a6_imac_sv32_config_pkg.sv index d9863da38e..e28ed552b0 100644 --- a/core/include/cv32a6_imac_sv32_config_pkg.sv +++ b/core/include/cv32a6_imac_sv32_config_pkg.sv @@ -22,7 +22,6 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; localparam CVA6ConfigZcmpExtEn = 0; - localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigHExtEn = 0; // always disabled localparam CVA6ConfigBExtEn = 0; @@ -96,7 +95,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), - RVZCMT: bit'(CVA6ConfigZcmtExtEn), + RVZCMT: bit'(0), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv32a6_imafc_sv32_config_pkg.sv b/core/include/cv32a6_imafc_sv32_config_pkg.sv index de5625f1be..ea5be1d1e3 100644 --- a/core/include/cv32a6_imafc_sv32_config_pkg.sv +++ b/core/include/cv32a6_imafc_sv32_config_pkg.sv @@ -22,7 +22,6 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; localparam CVA6ConfigZcmpExtEn = 0; - localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigHExtEn = 0; // always disabled localparam CVA6ConfigBExtEn = 0; @@ -97,7 +96,7 @@ package cva6_config_pkg; RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), - RVZCMT: bit'(CVA6ConfigZcmtExtEn), + RVZCMT: bit'(0), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), RVZiCond: bit'(CVA6ConfigRVZiCond), diff --git a/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv b/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv index 0f9a7f3fb3..f252538b11 100644 --- a/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv +++ b/core/include/cv64a6_imadfcv_sv39_polara_config_pkg.sv @@ -22,7 +22,6 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; localparam CVA6ConfigZcmpExtEn = 0; - localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 0; localparam CVA6ConfigHExtEn = 0; @@ -97,7 +96,7 @@ package cva6_config_pkg; RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), - RVZCMT: bit'(CVA6ConfigZcmtExtEn), + RVZCMT: bit'(0), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), RVZiCond: bit'(CVA6ConfigRVZiCond), diff --git a/core/include/cv64a6_imafdc_sv39_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_config_pkg.sv index c0b3b81915..e01d7201f3 100644 --- a/core/include/cv64a6_imafdc_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_config_pkg.sv @@ -22,7 +22,6 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; localparam CVA6ConfigZcmpExtEn = 0; - localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigHExtEn = 0; // always disabled localparam CVA6ConfigBExtEn = 1; @@ -96,7 +95,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), - RVZCMT: bit'(CVA6ConfigZcmtExtEn), + RVZCMT: bit'(0), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv index 97d10d2b67..200c5c7f79 100644 --- a/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_hpdcache_config_pkg.sv @@ -29,7 +29,6 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; localparam CVA6ConfigZcmpExtEn = 0; - localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 1; localparam CVA6ConfigVExtEn = 0; @@ -104,7 +103,7 @@ package cva6_config_pkg; RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), - RVZCMT: bit'(CVA6ConfigZcmtExtEn), + RVZCMT: bit'(0), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), RVZiCond: bit'(CVA6ConfigRVZiCond), diff --git a/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv index 66a188c267..6e84e73a58 100644 --- a/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_openpiton_config_pkg.sv @@ -22,7 +22,6 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; localparam CVA6ConfigZcmpExtEn = 0; - localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigHExtEn = 0; // always disabled localparam CVA6ConfigBExtEn = 0; @@ -96,7 +95,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), - RVZCMT: bit'(CVA6ConfigZcmtExtEn), + RVZCMT: bit'(0), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv b/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv index 6b709f89fc..51f8a25da5 100644 --- a/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv +++ b/core/include/cv64a6_imafdc_sv39_wb_config_pkg.sv @@ -22,7 +22,6 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; localparam CVA6ConfigZcmpExtEn = 0; - localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 1; localparam CVA6ConfigVExtEn = 0; @@ -96,7 +95,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), - RVZCMT: bit'(CVA6ConfigZcmtExtEn), + RVZCMT: bit'(0), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv64a6_imafdch_sv39_config_pkg.sv b/core/include/cv64a6_imafdch_sv39_config_pkg.sv index d76b53420d..22c52b8f98 100644 --- a/core/include/cv64a6_imafdch_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdch_sv39_config_pkg.sv @@ -22,7 +22,6 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; localparam CVA6ConfigZcmpExtEn = 0; - localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigHExtEn = 1; localparam CVA6ConfigBExtEn = 1; @@ -96,7 +95,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), - RVZCMT: bit'(CVA6ConfigZcmtExtEn), + RVZCMT: bit'(0), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv64a6_imafdch_sv39_wb_config_pkg.sv b/core/include/cv64a6_imafdch_sv39_wb_config_pkg.sv index 23fc0e2d41..a832745051 100644 --- a/core/include/cv64a6_imafdch_sv39_wb_config_pkg.sv +++ b/core/include/cv64a6_imafdch_sv39_wb_config_pkg.sv @@ -22,7 +22,6 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 1; localparam CVA6ConfigZcmpExtEn = 0; - localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 1; localparam CVA6ConfigVExtEn = 0; @@ -96,7 +95,7 @@ package cva6_config_pkg; RVC: bit'(CVA6ConfigCExtEn), RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), - RVZCMT: bit'(CVA6ConfigZcmtExtEn), + RVZCMT: bit'(0), RVZCMP: bit'(CVA6ConfigZcmpExtEn), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), diff --git a/core/include/cv64a6_imafdcv_sv39_config_pkg.sv b/core/include/cv64a6_imafdcv_sv39_config_pkg.sv index 571bd89b24..a35691c5d8 100644 --- a/core/include/cv64a6_imafdcv_sv39_config_pkg.sv +++ b/core/include/cv64a6_imafdcv_sv39_config_pkg.sv @@ -22,7 +22,6 @@ package cva6_config_pkg; localparam CVA6ConfigCExtEn = 1; localparam CVA6ConfigZcbExtEn = 0; localparam CVA6ConfigZcmpExtEn = 0; - localparam CVA6ConfigZcmtExtEn = 0; localparam CVA6ConfigAExtEn = 1; localparam CVA6ConfigBExtEn = 0; localparam CVA6ConfigHExtEn = 0; @@ -97,7 +96,7 @@ package cva6_config_pkg; RVH: bit'(CVA6ConfigHExtEn), RVZCB: bit'(CVA6ConfigZcbExtEn), RVZCMP: bit'(CVA6ConfigZcmpExtEn), - RVZCMT: bit'(CVA6ConfigZcmtExtEn), + RVZCMT: bit'(0), XFVec: bit'(CVA6ConfigFVecEn), CvxifEn: bit'(CVA6ConfigCvxifEn), RVZiCond: bit'(CVA6ConfigRVZiCond), From 0934c80d863d5fcfc9002a1749458f2b37a2bffd Mon Sep 17 00:00:00 2001 From: Farhan Ali Date: Thu, 12 Dec 2024 14:03:45 +0500 Subject: [PATCH 08/10] changes in issue read --- core/id_stage.sv | 18 +++++++++++++----- core/issue_read_operands.sv | 3 +-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/core/id_stage.sv b/core/id_stage.sv index 2f072e5b5b..113af06c02 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -189,12 +189,20 @@ module id_stage #( .req_port_i (dcache_req_ports_i), .req_port_o (dcache_req_ports_o) ); - end else assign is_zcmt_instr_i[0] = '0; + end + + if (is_zcmt_instr_i[0]) begin + assign instruction_cvxif[0] = instruction_cvxif_zcmt; + assign is_illegal_cvxif[0] = is_illegal_cvxif_zcmt; + assign is_compressed_cvxif[0] = is_compressed_cvxif_zcmt; + assign stall_macro_deco = stall_macro_deco_zcmt; + end else begin + assign instruction_cvxif[0] = instruction_cvxif_zcmp; + assign is_illegal_cvxif[0] = is_illegal_cvxif_zcmp; + assign is_compressed_cvxif[0] = is_compressed_cvxif_zcmp; + assign stall_macro_deco = stall_macro_deco_zcmp; + end - assign instruction_cvxif[0] = is_zcmt_instr_i[0] ? instruction_cvxif_zcmt : instruction_cvxif_zcmp; - assign is_illegal_cvxif[0] = is_zcmt_instr_i[0] ? is_illegal_cvxif_zcmt : is_illegal_cvxif_zcmp; - assign is_compressed_cvxif[0] = is_zcmt_instr_i[0] ? is_compressed_cvxif_zcmt : is_compressed_cvxif_zcmp; - assign stall_macro_deco = is_zcmt_instr_i[0] ? stall_macro_deco_zcmt : stall_macro_deco_zcmp; if (CVA6Cfg.SuperscalarEn) begin assign instruction_cvxif[CVA6Cfg.NrIssuePorts-1] = '0; assign is_illegal_cvxif[CVA6Cfg.NrIssuePorts-1] = '0; diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index 40dbd85c1c..c512d89a01 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -1122,8 +1122,7 @@ module issue_read_operands pc_o <= issue_instr_i[0].pc; is_compressed_instr_o <= issue_instr_i[0].is_compressed; branch_predict_o <= issue_instr_i[0].bp; - if (CVA6Cfg.RVZCMT) is_zcmt_o <= issue_instr_i[0].is_zcmt; - else is_zcmt_o <= '0; + is_zcmt_o <= issue_instr_i[0].is_zcmt; end x_transaction_rejected_o <= 1'b0; if (issue_instr_i[0].fu == CVXIF) begin From e0f3c5b251daf0bd1dece82c2813c85359e5f8fd Mon Sep 17 00:00:00 2001 From: Farhan Ali Date: Thu, 12 Dec 2024 15:36:38 +0500 Subject: [PATCH 09/10] reversing changes --- core/id_stage.sv | 15 ++++----------- core/issue_read_operands.sv | 3 ++- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/core/id_stage.sv b/core/id_stage.sv index 113af06c02..2c97fa3a21 100644 --- a/core/id_stage.sv +++ b/core/id_stage.sv @@ -191,17 +191,10 @@ module id_stage #( ); end - if (is_zcmt_instr_i[0]) begin - assign instruction_cvxif[0] = instruction_cvxif_zcmt; - assign is_illegal_cvxif[0] = is_illegal_cvxif_zcmt; - assign is_compressed_cvxif[0] = is_compressed_cvxif_zcmt; - assign stall_macro_deco = stall_macro_deco_zcmt; - end else begin - assign instruction_cvxif[0] = instruction_cvxif_zcmp; - assign is_illegal_cvxif[0] = is_illegal_cvxif_zcmp; - assign is_compressed_cvxif[0] = is_compressed_cvxif_zcmp; - assign stall_macro_deco = stall_macro_deco_zcmp; - end + assign instruction_cvxif[0] = is_zcmt_instr_i[0] ? instruction_cvxif_zcmt : instruction_cvxif_zcmp; + assign is_illegal_cvxif[0] = is_zcmt_instr_i[0] ? is_illegal_cvxif_zcmt : is_illegal_cvxif_zcmp; + assign is_compressed_cvxif[0] = is_zcmt_instr_i[0] ? is_compressed_cvxif_zcmt : is_compressed_cvxif_zcmp; + assign stall_macro_deco = is_zcmt_instr_i[0] ? stall_macro_deco_zcmt : stall_macro_deco_zcmp; if (CVA6Cfg.SuperscalarEn) begin assign instruction_cvxif[CVA6Cfg.NrIssuePorts-1] = '0; diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index c512d89a01..40dbd85c1c 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -1122,7 +1122,8 @@ module issue_read_operands pc_o <= issue_instr_i[0].pc; is_compressed_instr_o <= issue_instr_i[0].is_compressed; branch_predict_o <= issue_instr_i[0].bp; - is_zcmt_o <= issue_instr_i[0].is_zcmt; + if (CVA6Cfg.RVZCMT) is_zcmt_o <= issue_instr_i[0].is_zcmt; + else is_zcmt_o <= '0; end x_transaction_rejected_o <= 1'b0; if (issue_instr_i[0].fu == CVXIF) begin From 2124fa662a27a0cf9f24a9c168a1fa85e50bddef Mon Sep 17 00:00:00 2001 From: Farhan Ali Date: Tue, 17 Dec 2024 13:57:01 +0500 Subject: [PATCH 10/10] adding suggested changes --- core/branch_unit.sv | 2 +- core/decoder.sv | 6 +++--- core/ex_stage.sv | 6 +++--- core/include/config_pkg.sv | 2 +- core/issue_read_operands.sv | 2 +- core/issue_stage.sv | 6 +++--- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/branch_unit.sv b/core/branch_unit.sv index 1016ce6a18..52ed90ba90 100644 --- a/core/branch_unit.sv +++ b/core/branch_unit.sv @@ -31,7 +31,7 @@ module branch_unit #( input fu_data_t fu_data_i, // Instruction PC - ISSUE_STAGE input logic [CVA6Cfg.VLEN-1:0] pc_i, - // is zcmt instruction + // Is zcmt instruction - ISSUE_STAGE input logic is_zcmt_i, // Instruction is compressed - ISSUE_STAGE input logic is_compressed_instr_i, diff --git a/core/decoder.sv b/core/decoder.sv index 015d95c81e..0113865204 100644 --- a/core/decoder.sv +++ b/core/decoder.sv @@ -48,6 +48,8 @@ module decoder input logic is_last_macro_instr_i, // Is mvsa01/mva01s macro instruction - macro_decoder input logic is_double_rd_macro_instr_i, + //zcmt instruction + input logic is_zcmt_i, // Is a branch predict instruction - FRONTEND input branchpredict_sbe_t branch_predict_i, // If an exception occured in fetch stage - FRONTEND @@ -85,9 +87,7 @@ module decoder // Instruction - ISSUE_STAGE output logic [31:0] orig_instr_o, // Is a control flow instruction - ISSUE_STAGE - output logic is_control_flow_instr_o, - //zcmt instruction - input logic is_zcmt_i + output logic is_control_flow_instr_o ); logic illegal_instr; logic illegal_instr_bm; diff --git a/core/ex_stage.sv b/core/ex_stage.sv index 236583b0fd..e7f2ea0d80 100644 --- a/core/ex_stage.sv +++ b/core/ex_stage.sv @@ -47,7 +47,7 @@ module ex_stage input fu_data_t [CVA6Cfg.NrIssuePorts-1:0] fu_data_i, // PC of the current instruction - ISSUE_STAGE input logic [CVA6Cfg.VLEN-1:0] pc_i, - // is_zcmt instruction + // Is_zcmt instruction - ISSUE_STAGE input logic is_zcmt_i, // Report whether instruction is compressed - ISSUE_STAGE input logic is_compressed_instr_i, @@ -321,8 +321,8 @@ module ex_stage .v_i, .debug_mode_i, .fu_data_i (one_cycle_data), - .pc_i (pc_i), - .is_zcmt_i (is_zcmt_i), + .pc_i, + .is_zcmt_i, .is_compressed_instr_i, .branch_valid_i (|branch_valid_i), .branch_comp_res_i (alu_branch_res), diff --git a/core/include/config_pkg.sv b/core/include/config_pkg.sv index b36386ddfd..cb061ee3c7 100644 --- a/core/include/config_pkg.sv +++ b/core/include/config_pkg.sv @@ -376,7 +376,7 @@ package config_pkg; assert (Cfg.NrPMPEntries <= 64); assert (!(Cfg.SuperscalarEn && Cfg.RVF)); assert (!(Cfg.SuperscalarEn && Cfg.RVZCMP)); - assert (!(Cfg.SuperscalarEn && Cfg.RVZCMT)); + assert (!(Cfg.SuperscalarEn && Cfg.RVZCMT && ~CVA6Cfg.MmuPresent)); `endif // pragma translate_on endfunction diff --git a/core/issue_read_operands.sv b/core/issue_read_operands.sv index 40dbd85c1c..82c9ea5af2 100644 --- a/core/issue_read_operands.sv +++ b/core/issue_read_operands.sv @@ -56,7 +56,7 @@ module issue_read_operands output logic [CVA6Cfg.NrIssuePorts-1:0][CVA6Cfg.XLEN-1:0] rs2_forwarding_o, // Program Counter - EX_STAGE output logic [CVA6Cfg.VLEN-1:0] pc_o, - //is zcmt + // Is zcmt - EX_STAGE output logic is_zcmt_o, // Is compressed instruction - EX_STAGE output logic is_compressed_instr_o, diff --git a/core/issue_stage.sv b/core/issue_stage.sv index 0664aa229b..eb33f6af2b 100644 --- a/core/issue_stage.sv +++ b/core/issue_stage.sv @@ -60,7 +60,7 @@ module issue_stage output fu_data_t [CVA6Cfg.NrIssuePorts-1:0] fu_data_o, // Program Counter - EX_STAGE output logic [CVA6Cfg.VLEN-1:0] pc_o, - //is zcmt instruction + // Is zcmt instruction - EX_STAGE output logic is_zcmt_o, // Is compressed instruction - EX_STAGE output logic is_compressed_instr_o, @@ -264,8 +264,8 @@ module issue_stage .fu_data_o (fu_data_o), .rs1_forwarding_o (rs1_forwarding_xlen), .rs2_forwarding_o (rs2_forwarding_xlen), - .pc_o (pc_o), - .is_zcmt_o (is_zcmt_o), + .pc_o, + .is_zcmt_o, .is_compressed_instr_o, .flu_ready_i (flu_ready_i), .alu_valid_o (alu_valid_o),