diff --git a/Makefile b/Makefile index 0b80c28fb..fa6e81ef5 100644 --- a/Makefile +++ b/Makefile @@ -94,12 +94,12 @@ mcu-gen: $(PYTHON) util/mcu_gen.py --cfg $(MCU_CFG) --pads_cfg $(PAD_CFG) --outdir hw/ip/power_manager/rtl --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --external_domains $(EXTERNAL_DOMAINS) --pkg-sv hw/ip/power_manager/data/power_manager.sv.tpl $(PYTHON) util/mcu_gen.py --cfg $(MCU_CFG) --pads_cfg $(PAD_CFG) --outdir hw/ip/power_manager/data --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --external_domains $(EXTERNAL_DOMAINS) --pkg-sv hw/ip/power_manager/data/power_manager.hjson.tpl bash -c "cd hw/ip/power_manager; source power_manager_gen.sh; cd ../../../" - $(PYTHON) util/mcu_gen.py --cfg mcu_cfg.hjson --pads_cfg $(PAD_CFG) --outdir sw/device/lib/drivers/power_manager --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --external_domains $(EXTERNAL_DOMAINS) --pkg-sv sw/device/lib/drivers/power_manager/data/power_manager.h.tpl - $(PYTHON) util/mcu_gen.py --cfg mcu_cfg.hjson --pads_cfg $(PAD_CFG) --outdir hw/system/pad_control/data --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --external_pads $(EXT_PAD_CFG) --pkg-sv hw/system/pad_control/data/pad_control.hjson.tpl - $(PYTHON) util/mcu_gen.py --cfg mcu_cfg.hjson --pads_cfg $(PAD_CFG) --outdir hw/system/pad_control/rtl --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --external_pads $(EXT_PAD_CFG) --pkg-sv hw/system/pad_control/rtl/pad_control.sv.tpl + $(PYTHON) util/mcu_gen.py --cfg $(MCU_CFG) --pads_cfg $(PAD_CFG) --outdir sw/device/lib/drivers/power_manager --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --external_domains $(EXTERNAL_DOMAINS) --pkg-sv sw/device/lib/drivers/power_manager/data/power_manager.h.tpl + $(PYTHON) util/mcu_gen.py --cfg $(MCU_CFG) --pads_cfg $(PAD_CFG) --outdir hw/system/pad_control/data --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --external_pads $(EXT_PAD_CFG) --pkg-sv hw/system/pad_control/data/pad_control.hjson.tpl + $(PYTHON) util/mcu_gen.py --cfg $(MCU_CFG) --pads_cfg $(PAD_CFG) --outdir hw/system/pad_control/rtl --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --external_pads $(EXT_PAD_CFG) --pkg-sv hw/system/pad_control/rtl/pad_control.sv.tpl bash -c "cd hw/system/pad_control; source pad_control_gen.sh; cd ../../../" - $(PYTHON) util/mcu_gen.py --cfg mcu_cfg.hjson --pads_cfg $(PAD_CFG) --outdir sw/linker --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --linker_script sw/linker/link_flash_exec.ld.tpl - $(PYTHON) util/mcu_gen.py --cfg mcu_cfg.hjson --pads_cfg $(PAD_CFG) --outdir sw/linker --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --linker_script sw/linker/link_flash_load.ld.tpl + $(PYTHON) util/mcu_gen.py --cfg $(MCU_CFG) --pads_cfg $(PAD_CFG) --outdir sw/linker --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --linker_script sw/linker/link_flash_exec.ld.tpl + $(PYTHON) util/mcu_gen.py --cfg $(MCU_CFG) --pads_cfg $(PAD_CFG) --outdir sw/linker --bus $(BUS) --memorybanks $(MEMORY_BANKS) --memorybanks_il $(MEMORY_BANKS_IL) --linker_script sw/linker/link_flash_load.ld.tpl $(PYTHON) ./util/structs_periph_gen.py $(MAKE) verible diff --git a/README.md b/README.md index d837edac6..6b48f089b 100644 --- a/README.md +++ b/README.md @@ -192,6 +192,16 @@ make mcu-gen CPU=cv32e40p BUS=NtoM MEMORY_BANKS=12 MEMORY_BANKS_IL=4 The last command generates x-heep with the cv32e40p core, with a parallel bus, and 16 memory banks (12 continuous and 4 interleaved), each 32KB, for a total memory of 512KB. +If you are using `X-HEEP` just as a controller for your own system and you do not need any peripheral, you can use the `minimal` configuration file +when generating the MCU as: + +``` +make mcu-gen MCU_CFG=mcu_cfg_minimal.hjson +``` + +The `minimal` configuration is a work-in-progress, thus not all the APPs have been tested. + + ## Compiling Software Don't forget to set the `RISCV` env variable to the compiler folder (without the `/bin` included). diff --git a/docs/source/How_to/eXtendingHEEP.md b/docs/source/How_to/eXtendingHEEP.md index 882ea191d..c71c6c3af 100644 --- a/docs/source/How_to/eXtendingHEEP.md +++ b/docs/source/How_to/eXtendingHEEP.md @@ -233,7 +233,10 @@ The following is an example repository folder structure. │ │ ├── your_copro.h │ │ └── your_copro_defs.h -> ../../../../hw/vendor/your_copro/sw/your_copro_defs.h │ └── extensions - │ └── your_copro_x_heep.h + │ │ └── your_copro_x_heep.h + │ └── lib + │ └── crt + │ └── external_crt0.S ├── hw │ └── vendor │ ├── your_copro @@ -276,8 +279,9 @@ In the `external` folder you can add whatever is necessary for software to work * Sources and header files * Soft links to folders or files. +* A `lib/crt/` directory with and `exteral_crt0.S` file (will be included inside `BASW/sw/device/lib/crt/crt0.S`). -The external folder or any of its subdirectories cannot contain neither a `device` nor a `applications` folder as it would collide with the respective folders inside `BASE/sw/`. It should also not contain a `main.c` file. +The external folder or any of its subdirectories cannot contain neither a `device` nor an `applications` folder as it would collide with the respective folders inside `BASE/sw/`. It should also not contain a `main.c` file. ### The BASE/Makefile The `BASE/Makefile` is your own custom Makefile. You can use it as a bridge to access the Makefile from `X-HEEP`. diff --git a/hw/core-v-mini-mcu/peripheral_subsystem.sv.tpl b/hw/core-v-mini-mcu/peripheral_subsystem.sv.tpl index d83ed350e..71215d048 100644 --- a/hw/core-v-mini-mcu/peripheral_subsystem.sv.tpl +++ b/hw/core-v-mini-mcu/peripheral_subsystem.sv.tpl @@ -295,7 +295,11 @@ module peripheral_subsystem ); % else: assign msip_o = '0; - assign irq_id = '0; + + for(genvar i=0; i 40) begin + if (trace_q_size > 50) begin $fatal("Reorder queue too long\n"); end if (trace_q_size != 0) begin @@ -634,6 +645,7 @@ module cv32e40px_rvfi new_rvfi_trace = new(); new_rvfi_trace.copy_full(wb_bypass_trace_q.pop_front()); if (next_send == new_rvfi_trace.m_order) begin + new_rvfi_trace.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; rvfi_trace_q.push_back(new_rvfi_trace); next_send = next_send + 1; end else begin @@ -641,6 +653,7 @@ module cv32e40px_rvfi end end end + trace_q_size = wb_bypass_trace_q.size(); //Re-calculate here for accurate status endfunction /* * Function used to alocate a new insn and send it to the rvfi driver @@ -652,32 +665,12 @@ module cv32e40px_rvfi if (next_send == new_rvfi_trace.m_order) begin rvfi_trace_q.push_back(new_rvfi_trace); next_send = next_send + 1; - // empty_fifo(); end else begin wb_bypass_trace_q.push_back(new_rvfi_trace); end empty_fifo(); endfunction - /* - * - */ - function void f_bypass_wb(insn_trace_t m_ex_insn); - insn_trace_t new_rvfi_trace; - new_rvfi_trace = new(); - new_rvfi_trace.copy_full(m_ex_insn); - if (m_ex_insn.m_ex_fw) begin - new_rvfi_trace.m_rd_addr = m_ex_insn.m_rd_addr; - new_rvfi_trace.m_rd_wdata = m_ex_insn.m_rd_wdata; - end else begin - new_rvfi_trace.m_rd_addr[0] = '0; - new_rvfi_trace.m_rd_wdata[0] = '0; - new_rvfi_trace.m_rd_addr[1] = '0; - new_rvfi_trace.m_rd_wdata[1] = '0; - end - wb_bypass_trace_q.push_back(new_rvfi_trace); - endfunction - /* * Assing rvfi signals once the instruction is completed */ @@ -690,7 +683,6 @@ module cv32e40px_rvfi logic [31:0] s_fflags_mirror; logic [31:0] s_frm_mirror; logic [31:0] s_fcsr_mirror; - logic [31:0] r_previous_minstret; function void set_rvfi(); insn_trace_t new_rvfi_trace; @@ -717,6 +709,7 @@ module cv32e40px_rvfi new_rvfi_trace.m_csr.fflags_rdata = s_fflags_mirror; new_rvfi_trace.m_csr.frm_rdata = s_frm_mirror; new_rvfi_trace.m_csr.fcsr_rdata = s_fcsr_mirror; + if (new_rvfi_trace.m_fflags_we_non_apu) begin s_fflags_mirror = new_rvfi_trace.m_csr.fflags_wdata; s_fcsr_mirror = new_rvfi_trace.m_csr.fcsr_wdata; @@ -729,44 +722,35 @@ module cv32e40px_rvfi new_rvfi_trace.m_csr.frm_wmask = 32'hFFFF_FFFF; new_rvfi_trace.m_csr.fcsr_wmask = 32'hFFFF_FFFF; end + if (new_rvfi_trace.m_fcsr_we_non_apu) begin + s_fcsr_mirror = new_rvfi_trace.m_csr.fcsr_wdata; + s_fflags_mirror = new_rvfi_trace.m_csr.fflags_wdata; + s_frm_mirror = new_rvfi_trace.m_csr.frm_wdata; + new_rvfi_trace.m_csr.fcsr_wmask = 32'hFFFF_FFFF; + new_rvfi_trace.m_csr.fflags_wmask = 32'hFFFF_FFFF; + new_rvfi_trace.m_csr.frm_wmask = 32'hFFFF_FFFF; + end end - - //FOR DEBUG!!!!!!!!!!!!!!!!!!!!!! - // if(new_rvfi_trace.m_order == 64'h0000_0000_0000_4423) begin - // new_rvfi_trace.m_csr.mcause_rdata = 32'h8000_0010; - // new_rvfi_trace.m_csr.mcause_wdata = 32'h8000_0010; - // new_rvfi_trace.m_csr.mstatus_rdata = 32'h0000_1888; - // new_rvfi_trace.m_csr.mstatus_wdata = 32'h0000_1888; - // new_rvfi_trace.m_csr.mepc_rdata = 32'h0000_554E; - // new_rvfi_trace.m_csr.mepc_wdata = 32'h0000_554E; - // end - - rvfi_order = new_rvfi_trace.m_order; - rvfi_pc_rdata = new_rvfi_trace.m_pc_rdata; - rvfi_insn = new_rvfi_trace.m_insn; - - //Trying something here - //Flag as trap everytime minstret is not incremented - - if (new_rvfi_trace.m_instret_cnt == r_previous_minstret) begin - // new_rvfi_trace.m_trap = 1'b0; - new_rvfi_trace.m_trap = 1'b1; - end else begin - r_previous_minstret = new_rvfi_trace.m_instret_cnt; - new_rvfi_trace.m_trap = 1'b0; - end + rvfi_order = new_rvfi_trace.m_order; + rvfi_pc_rdata = new_rvfi_trace.m_pc_rdata; + rvfi_insn = new_rvfi_trace.m_insn; rvfi_rs1_addr = '0; rvfi_rs1_rdata = '0; rvfi_rs2_addr = '0; rvfi_rs2_rdata = '0; + rvfi_rs3_addr = '0; + rvfi_rs3_rdata = '0; rvfi_frs1_rvalid = '0; rvfi_frs1_addr = '0; rvfi_frs1_rdata = '0; rvfi_frs2_rvalid = '0; rvfi_frs2_addr = '0; rvfi_frs2_rdata = '0; + rvfi_frs3_rvalid = '0; + rvfi_frs3_addr = '0; + rvfi_frs3_rdata = '0; if (new_rvfi_trace.m_rs1_addr[5]) begin rvfi_frs1_rvalid = 1'b1; @@ -786,6 +770,15 @@ module cv32e40px_rvfi rvfi_rs2_rdata = new_rvfi_trace.m_rs2_rdata; end + if (new_rvfi_trace.m_rs3_addr[5]) begin + rvfi_frs3_rvalid = 1'b1; + rvfi_frs3_addr = new_rvfi_trace.m_rs3_addr[4:0]; + rvfi_frs3_rdata = new_rvfi_trace.m_rs3_rdata; + end else begin + rvfi_rs3_addr = new_rvfi_trace.m_rs3_addr[4:0]; + rvfi_rs3_rdata = new_rvfi_trace.m_rs3_rdata; + end + rvfi_frd_wvalid[0] = '0; rvfi_frd_addr[0] = '0; rvfi_frd_wdata[0] = '0; @@ -843,7 +836,58 @@ module cv32e40px_rvfi end //CSR - `SET_RVFI_CSR_FROM_INSN(mstatus) + rvfi_csr_mstatus_rmask = new_rvfi_trace.m_csr.mstatus_rmask | new_rvfi_trace.m_csr.mstatus_fs_rmask; + rvfi_csr_mstatus_wmask = new_rvfi_trace.m_csr.mstatus_wmask; + rvfi_csr_mstatus_wmask[31] = new_rvfi_trace.m_csr.mstatus_fs_wmask[31]; + rvfi_csr_mstatus_wmask[14:13] = new_rvfi_trace.m_csr.mstatus_fs_wmask[14:13]; + + if (FPU == 1 && ZFINX == 0) begin + rvfi_csr_mstatus_rdata[31] = (new_rvfi_trace.m_csr.mstatus_fs_rdata == FS_DIRTY) ? 1'b1 : 1'b0; + end else begin + rvfi_csr_mstatus_rdata[31] = '0; + end + rvfi_csr_mstatus_rdata[30:18] = '0; + rvfi_csr_mstatus_rdata[17] = new_rvfi_trace.m_csr.mstatus_rdata.mprv; + rvfi_csr_mstatus_rdata[16:15] = '0; + if (FPU == 1 && ZFINX == 0) begin + rvfi_csr_mstatus_rdata[14:13] = new_rvfi_trace.m_csr.mstatus_fs_rdata; + end else begin + rvfi_csr_mstatus_rdata[14:13] = '0; + end + rvfi_csr_mstatus_rdata[12:11] = new_rvfi_trace.m_csr.mstatus_rdata.mpp; + rvfi_csr_mstatus_rdata[10:8] = '0; + rvfi_csr_mstatus_rdata[7] = new_rvfi_trace.m_csr.mstatus_rdata.mpie; + rvfi_csr_mstatus_rdata[6:5] = '0; + rvfi_csr_mstatus_rdata[4] = new_rvfi_trace.m_csr.mstatus_rdata.upie; + rvfi_csr_mstatus_rdata[3] = new_rvfi_trace.m_csr.mstatus_rdata.mie; + rvfi_csr_mstatus_rdata[2:1] = '0; + rvfi_csr_mstatus_rdata[0] = new_rvfi_trace.m_csr.mstatus_rdata.uie; + + if (FPU == 1 && ZFINX == 0) begin + rvfi_csr_mstatus_wdata[31] = (new_rvfi_trace.m_csr.mstatus_fs_wdata == FS_DIRTY) ? 1'b1 : 1'b0; + end else begin + rvfi_csr_mstatus_wdata[31] = '0; + end + rvfi_csr_mstatus_wdata[30:18] = '0; + // MPRV is not implemented in the target configuration, writes to it are ignored + rvfi_csr_mstatus_wdata[17] = 1'b0;//new_rvfi_trace.m_csr.mstatus_wdata.mprv; + rvfi_csr_mstatus_wdata[16:15] = '0; + if (FPU == 1 && ZFINX == 0) begin + rvfi_csr_mstatus_wdata[14:13] = new_rvfi_trace.m_csr.mstatus_fs_wdata; + end else begin + rvfi_csr_mstatus_wdata[14:13] = '0; + end + rvfi_csr_mstatus_wdata[12:11] = new_rvfi_trace.m_csr.mstatus_wdata.mpp; + rvfi_csr_mstatus_wdata[10:8] = '0; + rvfi_csr_mstatus_wdata[7] = new_rvfi_trace.m_csr.mstatus_wdata.mpie; + rvfi_csr_mstatus_wdata[6:5] = '0; + // UPIE is not implemented in the target configuration, writes to it are ignored + rvfi_csr_mstatus_wdata[4] = 1'b0;//new_rvfi_trace.m_csr.mstatus_wdata.upie; + rvfi_csr_mstatus_wdata[3] = new_rvfi_trace.m_csr.mstatus_wdata.mie; + rvfi_csr_mstatus_wdata[2:1] = '0; + // UIE is not implemented in the target configuration, writes to it are ignored + rvfi_csr_mstatus_wdata[0] = 1'b0;//new_rvfi_trace.m_csr.mstatus_wdata.uie; + `SET_RVFI_CSR_FROM_INSN(misa) `SET_RVFI_CSR_FROM_INSN(mie) `SET_RVFI_CSR_FROM_INSN(mtvec) @@ -853,18 +897,25 @@ module cv32e40px_rvfi `SET_RVFI_CSR_FROM_INSN(mcause) `SET_RVFI_CSR_FROM_INSN(minstret) `SET_RVFI_CSR_FROM_INSN(mip) + // if(rvfi_order == 64'h00000000_00000167) begin + // rvfi_csr_mip_rdata = 32'h0010_0000; + // end + rvfi_csr_tdata_rdata[0] = 'Z; + rvfi_csr_tdata_rmask[0] = '0; // Does not exist + rvfi_csr_tdata_wdata[0] = 'Z; // Does not exist + rvfi_csr_tdata_wmask[0] = '0; - rvfi_csr_tdata_rdata[0] = 'Z; - rvfi_csr_tdata_rmask[0] = '0; // Does not exist - rvfi_csr_tdata_wdata[0] = 'Z; // Does not exist - rvfi_csr_tdata_wmask[0] = '0; + rvfi_csr_tdata_rdata[1] = new_rvfi_trace.m_csr.tdata1_rdata; + rvfi_csr_tdata_rmask[1] = new_rvfi_trace.m_csr.tdata1_rmask; //'1 + rvfi_csr_tdata_wdata[1] = new_rvfi_trace.m_csr.tdata1_wdata; + rvfi_csr_tdata_wmask[1] = new_rvfi_trace.m_csr.tdata1_wmask; - rvfi_csr_tdata_rdata[1] = new_rvfi_trace.m_csr.tdata1_rdata; - rvfi_csr_tdata_rmask[1] = new_rvfi_trace.m_csr.tdata1_rmask; //'1 - rvfi_csr_tdata_wdata[1] = new_rvfi_trace.m_csr.tdata1_wdata; - rvfi_csr_tdata_wmask[1] = new_rvfi_trace.m_csr.tdata1_wmask; + rvfi_csr_tdata_rdata[2] = new_rvfi_trace.m_csr.tdata2_rdata; + rvfi_csr_tdata_rmask[2] = new_rvfi_trace.m_csr.tdata2_rmask; //'1 + rvfi_csr_tdata_wdata[2] = new_rvfi_trace.m_csr.tdata2_wdata; + rvfi_csr_tdata_wmask[2] = new_rvfi_trace.m_csr.tdata2_wmask; - rvfi_csr_tdata_rmask[3:2] = '1; + rvfi_csr_tdata_rmask[3] = '1; `SET_RVFI_CSR_FROM_INSN(tinfo) `SET_RVFI_CSR_FROM_INSN(dcsr) @@ -892,16 +943,14 @@ module cv32e40px_rvfi `SET_RVFI_CSR_FROM_INSN(lpend1) `SET_RVFI_CSR_FROM_INSN(lpcount1) - endfunction // set_rvfi + endfunction // set_rvfi - int r_instret_cnt; function void minstret_to_id(); trace_id.m_csr.minstret_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]; trace_id.m_csr.minstret_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2]; trace_id.m_csr.minstret_rmask = '1; trace_id.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.mhpmcounter_q; trace_id.m_csr.minstret_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2] ? '1 : '0; - trace_id.m_instret_cnt = r_instret_cnt; endfunction function void minstret_to_ex(); @@ -910,7 +959,6 @@ module cv32e40px_rvfi trace_ex.m_csr.minstret_rmask = '1; trace_ex.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.mhpmcounter_q; trace_ex.m_csr.minstret_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2] ? '1 : '0; - trace_ex.m_instret_cnt = r_instret_cnt; endfunction function void tinfo_to_id(); @@ -942,16 +990,9 @@ module cv32e40px_rvfi trace_id.m_csr.mtvec_wmask = r_pipe_freeze_trace.csr.mtvec_we ? '1 : '0; endfunction - function void mstatus_to_id(); - trace_id.m_csr.mstatus_we = r_pipe_freeze_trace.csr.mstatus_we; - trace_id.m_csr.mstatus_rdata = r_pipe_freeze_trace.csr.mstatus_full_q; - trace_id.m_csr.mstatus_rmask = '1; - trace_id.m_csr.mstatus_wdata = r_pipe_freeze_trace.csr.mstatus_full_n; - trace_id.m_csr.mstatus_wmask = r_pipe_freeze_trace.csr.mstatus_we ? '1 : '0; - endfunction - function void dcsr_to_id(); - trace_id.m_csr.dcsr_we = r_pipe_freeze_trace.csr.dcsr_we; + trace_id.m_csr.dcsr_wdata = trace_id.m_csr.dcsr_we ? trace_id.m_csr.dcsr_wdata : r_pipe_freeze_trace.csr.dcsr_n; + trace_id.m_csr.dcsr_we = r_pipe_freeze_trace.csr.dcsr_we | trace_id.m_csr.dcsr_we; trace_id.m_csr.dcsr_rdata = r_pipe_freeze_trace.csr.dcsr_q; trace_id.m_csr.dcsr_rmask = '1; trace_id.m_csr.dcsr_wdata = r_pipe_freeze_trace.csr.dcsr_n; @@ -1052,7 +1093,6 @@ module cv32e40px_rvfi if (r_pipe_freeze_trace.exc_pc_mux == EXC_PC_IRQ) begin s_irq = 1'b1; trace_if.m_is_irq = 1'b1; - trace_if.m_trap = 1'b1; end end @@ -1060,30 +1100,6 @@ module cv32e40px_rvfi s_dbg_exception = 1'b0; end - if (r_pipe_freeze_trace.pc_id == trace_if.m_pc_rdata) begin - if (trace_if.m_valid && (s_dbg_exception || s_exception)) begin - trace_if.m_trap = 1'b1; - end - end - - if (r_pipe_freeze_trace.pc_id == trace_ex.m_pc_rdata) begin - if (trace_ex.m_valid && (s_dbg_exception || s_exception)) begin - trace_ex.m_trap = 1'b1; - end - end - - if (r_pipe_freeze_trace.pc_id == trace_wb.m_pc_rdata) begin - if (trace_wb.m_valid && (s_dbg_exception || s_exception)) begin - trace_wb.m_trap = 1'b1; - end - end - - if (r_pipe_freeze_trace.pc_id == trace_id.m_pc_rdata) begin - if (trace_id.m_valid && (s_dbg_exception || s_exception)) begin - trace_id.m_trap = 1'b1; - end - end - endfunction /* * This tracer works with three process, @@ -1094,24 +1110,42 @@ module cv32e40px_rvfi * * The third updates the rvfi interface */ - `define CSR_FROM_PIPE(TRACE_NAME, - CSR_NAME) \ - trace_``TRACE_NAME``.m_csr.``CSR_NAME``_we = r_pipe_freeze_trace.csr.``CSR_NAME``_we; \ + `define CSR_FROM_PIPE(TRACE_NAME, CSR_NAME) \ + if (r_pipe_freeze_trace.csr.``CSR_NAME``_we) begin \ + trace_``TRACE_NAME``.m_csr.``CSR_NAME``_we = r_pipe_freeze_trace.csr.``CSR_NAME``_we; \ + trace_``TRACE_NAME``.m_csr.``CSR_NAME``_wdata = r_pipe_freeze_trace.csr.``CSR_NAME``_n; \ + trace_``TRACE_NAME``.m_csr.``CSR_NAME``_wmask = '1; \ + end \ trace_``TRACE_NAME``.m_csr.``CSR_NAME``_rdata = r_pipe_freeze_trace.csr.``CSR_NAME``_q; \ - trace_``TRACE_NAME``.m_csr.``CSR_NAME``_rmask = '1; \ - trace_``TRACE_NAME``.m_csr.``CSR_NAME``_wdata = r_pipe_freeze_trace.csr.``CSR_NAME``_n; \ - trace_``TRACE_NAME``.m_csr.``CSR_NAME``_wmask = r_pipe_freeze_trace.csr.``CSR_NAME``_we ? '1 : '0; + trace_``TRACE_NAME``.m_csr.``CSR_NAME``_rmask = '1; + event e_mstatus_to_id; + function void mstatus_to_id(); + `CSR_FROM_PIPE(id, mstatus) + `CSR_FROM_PIPE(id, mstatus_fs) + ->e_mstatus_to_id; + endfunction //those event are for debug purpose event e_dev_send_wb_1, e_dev_send_wb_2; - event e_dev_commit_rf_to_ex_1, e_dev_commit_rf_to_ex_2, e_dev_commit_rf_to_ex_3; + event + e_dev_commit_rf_to_ex_1, + e_dev_commit_rf_to_ex_2, + e_dev_commit_rf_to_ex_3, + e_dev_commit_rf_to_ex_4, + e_dev_commit_rf_to_ex_5; event e_if_2_id_1, e_if_2_id_2; event e_ex_to_wb_1, e_ex_to_wb_2; event e_id_to_ex_1, e_id_to_ex_2; event e_commit_dpc; event e_send_rvfi_trace_apu_resp; - event e_send_rvfi_trace_ex_1, e_send_rvfi_trace_ex_2, e_send_rvfi_trace_ex_3, e_send_rvfi_trace_ex_4; + event + e_send_rvfi_trace_ex_1, + e_send_rvfi_trace_ex_2, + e_send_rvfi_trace_ex_3, + e_send_rvfi_trace_ex_4, + e_send_rvfi_trace_ex_5, + e_send_rvfi_trace_ex_6; event e_send_rvfi_trace_wb_1, e_send_rvfi_trace_wb_2, e_send_rvfi_trace_wb_3; event e_send_rvfi_trace_id_1; @@ -1126,22 +1160,41 @@ module cv32e40px_rvfi `CSR_FROM_PIPE(apu_resp, fcsr) `CSR_FROM_PIPE(apu_resp, fflags) - trace_apu_resp.m_csr.mstatus_we = r_pipe_freeze_trace.csr.mstatus_we; - trace_apu_resp.m_csr.mstatus_rdata = r_pipe_freeze_trace.csr.mstatus_full_q; - trace_apu_resp.m_csr.mstatus_rmask = '1; - trace_apu_resp.m_csr.mstatus_wdata = r_pipe_freeze_trace.csr.mstatus_full_n; - trace_apu_resp.m_csr.mstatus_wmask = r_pipe_freeze_trace.csr.mstatus_we ? '1 : '0; + // `CSR_FROM_PIPE(apu_resp, mstatus) + `CSR_FROM_PIPE(apu_resp, mstatus_fs) + + if (r_pipe_freeze_trace.csr.mstatus_we) begin + trace_ex.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; + end endfunction function void csr_to_apu_req(); `CSR_FROM_PIPE(apu_req, misa) `CSR_FROM_PIPE(apu_req, tdata1) - trace_apu_req.m_csr.tinfo_we = '0; // READ ONLY csr_tinfo_we_i; + `CSR_FROM_PIPE(apu_req, tdata2) + trace_apu_req.m_csr.tinfo_we = '0; // READ ONLY csr_tinfo_we_i; trace_apu_req.m_csr.tinfo_rdata = r_pipe_freeze_trace.csr.tinfo_q; trace_apu_req.m_csr.tinfo_rmask = '1; trace_apu_req.m_csr.tinfo_wdata = r_pipe_freeze_trace.csr.tinfo_n; trace_apu_req.m_csr.tinfo_wmask = '0; + trace_apu_req.m_csr.minstret_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]; + trace_apu_req.m_csr.minstret_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2]; + trace_apu_req.m_csr.minstret_rmask = '1; + trace_apu_req.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.mhpmcounter_q; + trace_apu_req.m_csr.minstret_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2] ? '1 : '0; + + trace_apu_req.m_csr.lpcount0_we = '0; + trace_apu_req.m_csr.lpcount0_rdata = r_pipe_freeze_trace.hwloop.counter_q[0]; + trace_apu_req.m_csr.lpcount0_rmask = '1; + trace_apu_req.m_csr.lpcount0_wdata = '0; + trace_apu_req.m_csr.lpcount0_wmask = '0; + + trace_apu_req.m_csr.lpcount1_we = '0; + trace_apu_req.m_csr.lpcount1_rdata = r_pipe_freeze_trace.hwloop.counter_q[1]; + trace_apu_req.m_csr.lpcount1_rmask = '1; + trace_apu_req.m_csr.lpcount1_wdata = '0; + trace_apu_req.m_csr.lpcount1_wmask = '0; `CSR_FROM_PIPE(apu_req, frm) @@ -1182,75 +1235,87 @@ module cv32e40px_rvfi end endfunction + /* + * Decoding is complete and instruction enters execute stage + * If at that time, minstret is not asserted it means we have a trap + */ + bit s_is_pc_set; //If pc_set, wait until next trace_id to commit csr changes + bit s_is_irq_start; + bit s_id_done; + function void if_to_id(); + trace_id.init(trace_if); + trace_id.m_trap = ~r_pipe_freeze_trace.minstret; + trace_id.m_is_illegal = r_pipe_freeze_trace.is_illegal; + s_is_pc_set = 1'b0; + s_is_irq_start = 1'b0; + trace_if.m_valid = 1'b0; + s_id_done = 1'b0; + `CSR_FROM_PIPE(id, dpc) + endfunction + + function logic [31:0] be_to_mask(logic [3:0] be); + logic [31:0] mask; + mask[7:0] = be[0] ? 8'hFF : 8'h00; + mask[15:8] = be[0] ? 8'hFF : 8'h00; + mask[23:16] = be[0] ? 8'hFF : 8'h00; + mask[31:24] = be[0] ? 8'hFF : 8'h00; + + be_to_mask = mask; + return mask; + endfunction + task compute_pipeline(); bit s_new_valid_insn; bit s_ex_valid_adjusted; bit s_wb_valid_adjusted; - bit s_id_done; - bit s_apu_wb_ok; bit s_apu_0_cycle_reps; bit s_fflags_we_non_apu; bit s_frm_we_non_apu; - bit s_is_pc_set; //If pc_set, wait until next trace_id to commit csr changes - bit s_is_irq_start; + bit s_fcsr_we_non_apu; bit s_skip_wb; // used to skip wb monitoring when apu resp and not lsu - bit s_increase_instret_1; - bit s_increase_instret_2; - - bit s_test_for_dret; - - trace_if = new(); - trace_id = new(); - trace_ex = new(); - trace_wb = new(); - s_new_valid_insn = 1'b0; - s_ex_valid_adjusted = 1'b0; - s_id_done = 1'b0; - s_apu_wb_ok = 1'b0; - s_apu_0_cycle_reps = 1'b0; + bit s_core_is_decoding; // For readability, ctrl_fsm is DECODE or DECODE_HWLOOP - next_send = 1; - cnt_data_req = 0; - cnt_data_resp = 0; - cnt_apu_req = 0; - cnt_apu_resp = 0; - csr_is_irq = '0; - is_dbg_taken = '0; - s_was_flush = 1'b0; + trace_if = new(); + trace_id = new(); + trace_ex = new(); + trace_wb = new(); + s_new_valid_insn = 1'b0; + s_ex_valid_adjusted = 1'b0; - r_previous_minstret = -1; + s_id_done = 1'b0; + s_apu_wb_ok = 1'b0; + s_apu_0_cycle_reps = 1'b0; - s_is_pc_set = 1'b0; - s_is_irq_start = 1'b0; + next_send = 1; + cnt_data_req = 0; + cnt_data_resp = 0; + cnt_apu_req = 0; + cnt_apu_resp = 0; + csr_is_irq = '0; + is_dbg_taken = '0; + s_was_flush = 1'b0; - s_is_pc_set = 1'b0; - s_is_irq_start = 1'b0; - s_skip_wb = 1'b0; + s_is_pc_set = 1'b0; + s_is_irq_start = 1'b0; - r_instret_cnt = 0; - s_increase_instret_1 = 1'b0; - s_increase_instret_2 = 1'b0; + s_is_pc_set = 1'b0; + s_is_irq_start = 1'b0; + s_skip_wb = 1'b0; - s_test_for_dret = 1'b0; + s_core_is_decoding = 1'b0; - $display("*****Starting pipeline computing*****\n"); forever begin - wait(e_pipe_monitor_ok.triggered); // event triggered + wait(e_pipe_monitor_ok.triggered); // event triggered #1; + s_core_is_decoding = (r_pipe_freeze_trace.ctrl_fsm_cs == DECODE) || (r_pipe_freeze_trace.ctrl_fsm_cs == DECODE_HWLOOP); check_trap(); - if (s_increase_instret_2) begin - r_instret_cnt = r_instret_cnt + 1; - end - s_increase_instret_2 = s_increase_instret_1; - s_increase_instret_1 = r_pipe_freeze_trace.minstret; - pc_mux_interrupt = 1'b0; if (r_pipe_freeze_trace.pc_mux == 4'b0100) begin if (r_pipe_freeze_trace.exc_pc_mux == 3'b001) begin @@ -1275,11 +1340,9 @@ module cv32e40px_rvfi minstret_to_id(); `CSR_FROM_PIPE(id, misa) `CSR_FROM_PIPE(id, tdata1) + `CSR_FROM_PIPE(id, tdata2) tinfo_to_id(); `CSR_FROM_PIPE(id, mip) - send_rvfi(trace_id); - trace_id.m_valid = 1'b0; - ->e_send_rvfi_trace_id_1; end end @@ -1324,7 +1387,7 @@ module cv32e40px_rvfi s_new_valid_insn = r_pipe_freeze_trace.id_valid && r_pipe_freeze_trace.is_decoding;// && !r_pipe_freeze_trace.apu_rvalid; - s_wb_valid_adjusted = r_pipe_freeze_trace.wb_valid && ((r_pipe_freeze_trace.ctrl_fsm_cs == DECODE) || (r_pipe_freeze_trace.ctrl_fsm_cs == FLUSH_EX) || (r_pipe_freeze_trace.ctrl_fsm_cs == DECODE_HWLOOP));// && !r_pipe_freeze_trace.apu_rvalid;; + s_wb_valid_adjusted = r_pipe_freeze_trace.wb_valid && (s_core_is_decoding || (r_pipe_freeze_trace.ctrl_fsm_cs == FLUSH_EX));// && !r_pipe_freeze_trace.apu_rvalid;; s_fflags_we_non_apu = 1'b0; if (r_pipe_freeze_trace.csr.fflags_we) begin @@ -1340,6 +1403,13 @@ module cv32e40px_rvfi end end + s_fcsr_we_non_apu = 1'b0; + if (r_pipe_freeze_trace.csr.fcsr_we) begin + if (cnt_apu_resp == cnt_apu_req) begin //No ongoing apu instruction + s_fcsr_we_non_apu = 1'b1; + end + end + //WB_STAGE s_skip_wb = 1'b0; if (r_pipe_freeze_trace.apu_rvalid && (apu_trace_q.size() > 0)) begin @@ -1350,19 +1420,20 @@ module cv32e40px_rvfi end if (trace_wb.m_valid && !s_skip_wb) begin if (r_pipe_freeze_trace.rf_we_wb) begin - if((trace_wb.m_rd_addr[0] == r_pipe_freeze_trace.rf_addr_wb) && (cnt_data_resp == trace_wb.m_mem_req_id[0])) begin - trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; + if((trace_wb.m_rd_addr[0] == r_pipe_freeze_trace.rf_addr_wb) && (cnt_data_resp == trace_wb.m_mem_req_id[0]) && trace_wb.m_mem_req_id_valid[0]) begin + trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_wb.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; - end else if (trace_wb.m_2_rd_insn && (trace_wb.m_rd_addr[1] == r_pipe_freeze_trace.rf_addr_wb) && (cnt_data_resp == trace_wb.m_mem_req_id[0])) begin - trace_wb.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + trace_wb.m_mem_req_id_valid[0] = 1'b0; + end else if (trace_wb.m_2_rd_insn && (trace_wb.m_rd_addr[1] == r_pipe_freeze_trace.rf_addr_wb) && (cnt_data_resp == trace_wb.m_mem_req_id[1]) && trace_wb.m_mem_req_id_valid[1]) begin + trace_wb.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; trace_wb.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; + trace_wb.m_mem_req_id_valid[1] = 1'b0; end end if (!trace_wb.m_data_missaligned) begin send_rvfi(trace_wb); - ->e_dev_send_wb_1; - ->e_send_rvfi_trace_wb_2; + ->e_dev_send_wb_1; ->e_send_rvfi_trace_wb_2; trace_wb.m_valid = 1'b0; end else begin if (s_wb_valid_adjusted) begin @@ -1375,29 +1446,36 @@ module cv32e40px_rvfi trace_wb.m_got_first_data = 1'b1; end else begin send_rvfi(trace_wb); - ->e_dev_send_wb_2; - ->e_send_rvfi_trace_wb_3; + ->e_dev_send_wb_2; ->e_send_rvfi_trace_wb_3; trace_wb.m_valid = 1'b0; end - end // rf_we_wb + end // rf_we_wb end end end if (trace_ex.m_valid) begin + if (!trace_ex.m_csr.got_minstret) begin + minstret_to_ex(); + end `CSR_FROM_PIPE(ex, misa) `CSR_FROM_PIPE(ex, tdata1) + `CSR_FROM_PIPE(ex, tdata2) tinfo_to_ex(); - if(r_pipe_freeze_trace.rf_we_wb) begin - if(cnt_data_resp == trace_ex.m_mem_req_id[0]) begin - trace_ex.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; + if (r_pipe_freeze_trace.regfile_we_lsu) begin + ->e_dev_commit_rf_to_ex_4; + if ((cnt_data_resp == trace_ex.m_mem_req_id[0]) && !(trace_ex.m_got_ex_reg) && trace_ex.m_mem_req_id_valid[0]) begin + trace_ex.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; - end else if (cnt_data_resp == trace_ex.m_mem_req_id[1]) begin - trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + trace_ex.m_got_first_data = 1'b1; + trace_ex.m_mem_req_id_valid[0] = 1'b0; + end else if ((cnt_data_resp == trace_ex.m_mem_req_id[1]) && trace_ex.m_mem_req_id_valid[1]) begin + trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; trace_ex.m_got_first_data = 1'b1; + trace_ex.m_mem_req_id_valid[1] = 1'b0; end end @@ -1407,12 +1485,13 @@ module cv32e40px_rvfi trace_ex.m_valid = 1'b0; ->e_send_rvfi_trace_ex_2; end else begin - if (r_pipe_freeze_trace.rf_we_wb) begin + if (r_pipe_freeze_trace.rf_we_wb && !s_apu_to_lsu_port) begin ->e_dev_commit_rf_to_ex_1; if (trace_ex.m_got_ex_reg) begin - trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; - trace_ex.m_2_rd_insn = 1'b1; + trace_ex.m_2_rd_insn = 1'b1; + trace_ex.m_got_first_data = 1'b1; end else begin trace_ex.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; @@ -1423,16 +1502,25 @@ module cv32e40px_rvfi if (!s_ex_valid_adjusted & !trace_ex.m_csr.got_minstret) begin minstret_to_ex(); end - ->e_ex_to_wb_1; - trace_wb.move_down_pipe(trace_ex); + if (trace_ex.m_is_load) begin // only move relevant instr in wb stage + ->e_ex_to_wb_1; + trace_wb.move_down_pipe(trace_ex); + end else begin + if (!trace_ex.m_csr.got_minstret) begin + minstret_to_ex(); + end + send_rvfi(trace_ex); + ->e_send_rvfi_trace_ex_6; + end trace_ex.m_valid = 1'b0; end - end else if (r_pipe_freeze_trace.rf_we_wb) begin + end else if (r_pipe_freeze_trace.rf_we_wb && !s_apu_to_lsu_port && !s_was_flush) begin ->e_dev_commit_rf_to_ex_2; if (trace_ex.m_got_ex_reg) begin - trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; - trace_ex.m_2_rd_insn = 1'b1; + trace_ex.m_2_rd_insn = 1'b1; + trace_ex.m_got_first_data = 1'b1; end else begin trace_ex.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; @@ -1441,13 +1529,13 @@ module cv32e40px_rvfi end end - s_ex_valid_adjusted = (r_pipe_freeze_trace.ex_valid || s_test_for_dret) && ((r_pipe_freeze_trace.ctrl_fsm_cs == DECODE) || (r_pipe_freeze_trace.ctrl_fsm_cs == DECODE_HWLOOP)) && (!r_pipe_freeze_trace.apu_rvalid || r_pipe_freeze_trace.data_req_ex); - s_test_for_dret = r_pipe_freeze_trace.ex_valid && r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_IF; + s_ex_valid_adjusted = (r_pipe_freeze_trace.ex_valid && r_pipe_freeze_trace.ex_ready) && (s_core_is_decoding || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_IF)) && (!r_pipe_freeze_trace.apu_rvalid || r_pipe_freeze_trace.data_req_ex); //EX_STAGE if (trace_id.m_valid) begin mtvec_to_id(); `CSR_FROM_PIPE(id, mip) + `CSR_FROM_PIPE(id, misa) if (!csr_is_irq && !s_is_irq_start) begin mstatus_to_id(); @@ -1466,8 +1554,13 @@ module cv32e40px_rvfi `CSR_FROM_PIPE(id, fcsr) if (r_pipe_freeze_trace.csr.we) begin - `CSR_FROM_PIPE(id, dpc) + `CSR_FROM_PIPE(id, dpc) + end + + if (r_pipe_freeze_trace.csr.dcsr_we) begin + dcsr_to_id(); end + if (s_fflags_we_non_apu) begin trace_id.m_fflags_we_non_apu = 1'b1; end @@ -1475,21 +1568,21 @@ module cv32e40px_rvfi if (s_frm_we_non_apu) begin trace_id.m_frm_we_non_apu = 1'b1; end + + if (s_fcsr_we_non_apu) begin + trace_id.m_fcsr_we_non_apu = 1'b1; + end + trace_ex.m_csr.fflags_wmask = '0; trace_ex.m_csr.frm_wmask = '0; trace_ex.m_csr.fcsr_wmask = '0; - if (r_pipe_freeze_trace.apu_req) begin + if (r_pipe_freeze_trace.apu_req && r_pipe_freeze_trace.apu_gnt) begin trace_id.m_is_apu = 1'b1; trace_id.m_apu_req_id = cnt_apu_req; trace_apu_req = new(); trace_apu_req.copy_full(trace_id); csr_to_apu_req(); - if(s_increase_instret_2) begin - trace_apu_req.m_instret_cnt = r_instret_cnt + 1; - end else begin - trace_apu_req.m_instret_cnt = r_instret_cnt; - end trace_apu_req.set_to_apu(); apu_trace_q.push_back(trace_apu_req); trace_id.m_valid = 1'b0; @@ -1505,7 +1598,7 @@ module cv32e40px_rvfi trace_ex.m_valid = 1'b0; ->e_send_rvfi_trace_ex_3; end - if (r_pipe_freeze_trace.ex_reg_we && !r_pipe_freeze_trace.apu_rvalid) begin + if (r_pipe_freeze_trace.ex_reg_we && !s_apu_to_alu_port) begin trace_id.m_ex_fw = 1'b1; trace_id.m_rd_addr[0] = r_pipe_freeze_trace.ex_reg_addr; trace_id.m_rd_wdata[0] = r_pipe_freeze_trace.ex_reg_wdata; @@ -1513,52 +1606,81 @@ module cv32e40px_rvfi end else if (!trace_ex.m_valid & r_pipe_freeze_trace.rf_we_wb & !trace_id.m_ex_fw) begin trace_id.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_id.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; + end else if (r_pipe_freeze_trace.rf_we_wb) begin + trace_id.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + trace_id.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; + trace_id.m_2_rd_insn = 1'b1; end if (r_pipe_freeze_trace.data_req_ex) begin cnt_data_req = cnt_data_req + 1; trace_id.m_is_memory = 1'b1; trace_id.m_mem_req_id[0] = cnt_data_req; + trace_id.m_mem_req_id_valid[0] = 1'b1; trace_id.m_mem.addr = r_pipe_freeze_trace.data_addr_pmp; if (r_pipe_freeze_trace.data_misaligned) begin cnt_data_req = cnt_data_req + 1; end if (!r_pipe_freeze_trace.data_we_ex) begin - trace_id.m_is_load = 1'b1; + trace_id.m_is_load = 1'b1; + trace_id.m_mem.wmask = be_to_mask(r_pipe_freeze_trace.lsu_data_be); //'1; if (r_pipe_freeze_trace.data_misaligned) begin trace_id.m_data_missaligned = 1'b1; trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; trace_id.m_mem_req_id[0] = cnt_data_req; + trace_id.m_mem_req_id_valid[1] = 1'b1; end + end else begin + trace_id.m_mem.rmask = be_to_mask(r_pipe_freeze_trace.lsu_data_be); //'1; + end + if (trace_id.m_got_ex_reg) begin // Shift index 0 to 1 + trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; + trace_id.m_mem_req_id[0] = 0; + trace_id.m_mem_req_id_valid[1] = 1'b1; + trace_id.m_mem_req_id_valid[0] = 1'b0; end end - ->e_id_to_ex_1; hwloop_to_id(); trace_ex.move_down_pipe(trace_id); // The instruction moves forward from ID to EX trace_id.m_valid = 1'b0; ->e_id_to_ex_1; - end else if (r_pipe_freeze_trace.ex_reg_we) begin + end else if (r_pipe_freeze_trace.ex_reg_we && r_pipe_freeze_trace.rf_alu_we_ex) begin trace_id.m_ex_fw = 1'b1; trace_id.m_rd_addr[0] = r_pipe_freeze_trace.ex_reg_addr; trace_id.m_rd_wdata[0] = r_pipe_freeze_trace.ex_reg_wdata; trace_id.m_got_ex_reg = 1'b1; trace_id.m_got_regs_write = 1'b1; + // mem_req_id[0] already set here indicates req_id was set before rf write from EX + // Hence adjust the req_id again here for such cases + if (trace_id.m_mem_req_id[0] != 0) begin + trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; + trace_id.m_mem_req_id[0] = 0; + trace_id.m_mem_req_id_valid[0] = 1'b0; + trace_id.m_mem_req_id_valid[1] = 1'b1; + end end - end + end //trace_if.m_valid //ID_STAGE if (s_new_valid_insn) begin // There is a new valid instruction if (trace_id.m_valid) begin if (trace_ex.m_valid) begin - minstret_to_ex(); + if (!trace_ex.m_csr.got_minstret) begin + minstret_to_ex(); + end if (trace_wb.m_valid) begin send_rvfi(trace_ex); ->e_send_rvfi_trace_ex_4; end else begin - ->e_ex_to_wb_2; - trace_wb.move_down_pipe(trace_ex); + if (trace_ex.m_is_load) begin // only move relevant instr in wb stage + ->e_ex_to_wb_2; + trace_wb.move_down_pipe(trace_ex); + end else begin + send_rvfi(trace_ex); + ->e_send_rvfi_trace_ex_5; + end end trace_ex.m_valid = 1'b0; end @@ -1566,7 +1688,7 @@ module cv32e40px_rvfi cnt_data_req = cnt_data_req + 1; trace_id.m_is_memory = 1'b1; trace_id.m_mem_req_id[0] = cnt_data_req; - + trace_id.m_mem_req_id_valid[0] = 1'b1; trace_id.m_mem.addr = r_pipe_freeze_trace.data_addr_pmp; if (r_pipe_freeze_trace.data_misaligned) begin cnt_data_req = cnt_data_req + 1; @@ -1577,8 +1699,15 @@ module cv32e40px_rvfi trace_id.m_data_missaligned = 1'b1; trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; trace_id.m_mem_req_id[0] = cnt_data_req; + trace_id.m_mem_req_id_valid[1] = 1'b1; end end + if (trace_id.m_got_ex_reg) begin // Shift index 0 to 1 + trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; + trace_id.m_mem_req_id[0] = 0; + trace_id.m_mem_req_id_valid[0] = 1'b0; + trace_id.m_mem_req_id_valid[1] = 1'b1; + end end else if (r_pipe_freeze_trace.rf_we_wb && !r_pipe_freeze_trace.ex_reg_we) begin trace_id.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_id.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; @@ -1589,21 +1718,12 @@ module cv32e40px_rvfi trace_id.m_valid = 1'b0; ->e_id_to_ex_2; end - trace_id.init(trace_if); - trace_id.m_is_ebreak = trace_if.m_is_ebreak; - trace_id.m_is_illegal = r_pipe_freeze_trace.is_illegal; - s_is_pc_set = 1'b0; - s_is_irq_start = 1'b0; - trace_if.m_valid = 1'b0; - s_id_done = 1'b0; - + if_to_id(); + trace_id.m_is_ebreak = trace_if.m_is_ebreak; csrId_to_id(); - `CSR_FROM_PIPE(id, dscratch0) `CSR_FROM_PIPE(id, dscratch1) mstatus_to_id(); - - `CSR_FROM_PIPE(id, dpc) ->e_if_2_id_1; end else begin if (trace_id.m_valid) begin @@ -1613,17 +1733,10 @@ module cv32e40px_rvfi end //IF_STAGE - if (r_pipe_freeze_trace.if_valid && r_pipe_freeze_trace.if_ready) begin if(trace_if.m_valid && r_pipe_freeze_trace.id_valid && r_pipe_freeze_trace.id_ready && !trace_id.m_valid && r_pipe_freeze_trace.ebrk_insn_dec) begin - trace_id.init(trace_if); - trace_id.m_is_ebreak = '1; //trace_if.m_is_ebreak; - trace_id.m_is_illegal = r_pipe_freeze_trace.is_illegal; - s_is_pc_set = 1'b0; - s_is_irq_start = 1'b0; - trace_if.m_valid = 1'b0; - s_id_done = 1'b0; - `CSR_FROM_PIPE(id, dpc) + if_to_id(); + trace_id.m_is_ebreak = '1; //trace_if.m_is_ebreak; ->e_if_2_id_2; end @@ -1643,7 +1756,7 @@ module cv32e40px_rvfi `CSR_FROM_PIPE(id, mcause) end - if (!s_id_done) begin + if (!s_id_done && r_pipe_freeze_trace.is_decoding) begin dcsr_to_id(); ->e_commit_dpc; end @@ -1652,7 +1765,6 @@ module cv32e40px_rvfi s_is_pc_set = 1'b1; end - csr_is_irq = r_pipe_freeze_trace.csr_cause[5]; is_dbg_taken = ((r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_ID) | (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_IF)) ? 1'b1 : 1'b0; saved_debug_cause = r_pipe_freeze_trace.debug_cause; @@ -1677,8 +1789,10 @@ module cv32e40px_rvfi rvfi_rd_wdata[1] = '0; rvfi_rs1_addr = '0; rvfi_rs2_addr = '0; + rvfi_rs3_addr = '0; rvfi_rs1_rdata = '0; rvfi_rs2_rdata = '0; + rvfi_rs3_rdata = '0; rvfi_mem_addr = '0; rvfi_mem_rmask = '0; rvfi_mem_wmask = '0; diff --git a/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_rvfi_trace.sv b/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_rvfi_trace.sv index a77cd0b38..bfb025796 100644 --- a/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_rvfi_trace.sv +++ b/hw/vendor/esl_epfl_cv32e40px/bhv/cv32e40px_rvfi_trace.sv @@ -45,15 +45,26 @@ module cv32e40px_rvfi_trace input logic [ 4:0] rvfi_rs1_addr, input logic [ 4:0] rvfi_rs2_addr, + input logic [ 4:0] rvfi_rs3_addr, input logic [31:0] rvfi_rs1_rdata, input logic [31:0] rvfi_rs2_rdata, + input logic [31:0] rvfi_rs3_rdata, input logic [ 4:0] rvfi_frs1_addr, input logic [ 4:0] rvfi_frs2_addr, + input logic [ 4:0] rvfi_frs3_addr, input logic rvfi_frs1_rvalid, input logic rvfi_frs2_rvalid, + input logic rvfi_frs3_rvalid, input logic [31:0] rvfi_frs1_rdata, - input logic [31:0] rvfi_frs2_rdata + input logic [31:0] rvfi_frs2_rdata, + input logic [31:0] rvfi_frs3_rdata, + + input logic [31:0] rvfi_mem_addr, + input logic [ 3:0] rvfi_mem_rmask, + input logic [ 3:0] rvfi_mem_wmask, + input logic [31:0] rvfi_mem_rdata, + input logic [31:0] rvfi_mem_wdata ); import cv32e40px_tracer_pkg::*; @@ -106,6 +117,14 @@ module cv32e40px_rvfi_trace rs2_value = rvfi_rs2_rdata; end + if (rvfi_frs3_rvalid) begin + rs3 = {1'b1, rvfi_frs3_addr}; + rs3_value = rvfi_frs3_rdata; + end else begin + rs3 = {1'b0, rvfi_rs3_addr}; + rs3_value = rvfi_rs3_rdata; + end + if (rvfi_frd_wvalid[0]) begin rd = {1'b1, rvfi_frd_addr[0]}; end else begin @@ -113,9 +132,7 @@ module cv32e40px_rvfi_trace end end - assign rs3 = '0; - assign rs4 = '0; - assign rs3_value = rvfi_rd_wdata[0]; + assign rs4 = rs3; assign imm_i_type = {{20{rvfi_insn[31]}}, rvfi_insn[31:20]}; assign imm_iz_type = {20'b0, rvfi_insn[31:20]}; @@ -157,15 +174,34 @@ instr_trace_t trace_retire; function void apply_reg_write(); foreach (trace_retire.regs_write[i]) begin - if (trace_retire.regs_write[i].addr == rvfi_rd_addr[0]) begin + if (rvfi_frd_wvalid[0] && (trace_retire.regs_write[i].addr == {1'b1, rvfi_frd_addr[0]})) begin + trace_retire.regs_write[i].value = rvfi_frd_wdata[0]; + end else if (trace_retire.regs_write[i].addr == rvfi_rd_addr[0]) begin trace_retire.regs_write[i].value = rvfi_rd_wdata[0]; end - if (trace_retire.regs_write[i].addr == rvfi_rd_addr[1]) begin + if (rvfi_frd_wvalid[1] && (trace_retire.regs_write[i].addr == {1'b1, rvfi_frd_addr[1]})) begin + trace_retire.regs_write[i].value = rvfi_frd_wdata[1]; + end else if (trace_retire.regs_write[i].addr == rvfi_rd_addr[1]) begin trace_retire.regs_write[i].value = rvfi_rd_wdata[1]; end end endfunction : apply_reg_write + function void apply_mem_access(); + mem_acc_t mem_acc; + + mem_acc.addr = rvfi_mem_addr; + if (rvfi_mem_wmask) begin + mem_acc.we = 1'b1; + mem_acc.wdata = rvfi_mem_wdata; + trace_retire.mem_access.push_back(mem_acc); + end else if (rvfi_mem_rmask) begin + mem_acc.we = 1'b0; + mem_acc.wdata = 'x; + trace_retire.mem_access.push_back(mem_acc); + end + endfunction : apply_mem_access + // cycle counter always_ff @(posedge clk_i, negedge rst_ni) begin if (rst_ni == 1'b0) cycles <= 0; @@ -176,6 +212,7 @@ instr_trace_t trace_retire; if (rvfi_valid) begin trace_retire = trace_new_instr(); apply_reg_write(); + apply_mem_access(); trace_retire.printInstrTrace(); end end diff --git a/hw/vendor/esl_epfl_cv32e40px/bhv/include/cv32e40px_tracer_pkg.sv b/hw/vendor/esl_epfl_cv32e40px/bhv/include/cv32e40px_tracer_pkg.sv index e1a2a641a..40edce035 100644 --- a/hw/vendor/esl_epfl_cv32e40px/bhv/include/cv32e40px_tracer_pkg.sv +++ b/hw/vendor/esl_epfl_cv32e40px/bhv/include/cv32e40px_tracer_pkg.sv @@ -130,11 +130,85 @@ package cv32e40px_tracer_pkg; parameter INSTR_AMOMINU = {AMO_MINU, 2'b?, 5'b?, 5'b?, 3'b010, 5'b?, OPCODE_AMO}; parameter INSTR_AMOMAXU = {AMO_MAXU, 2'b?, 5'b?, 5'b?, 3'b010, 5'b?, OPCODE_AMO}; + + // LOAD STORE + parameter INSTR_LB = {17'b?, 3'b000, 5'b?, OPCODE_LOAD}; + parameter INSTR_LH = {17'b?, 3'b001, 5'b?, OPCODE_LOAD}; + parameter INSTR_LW = {17'b?, 3'b010, 5'b?, OPCODE_LOAD}; + parameter INSTR_LBU = {17'b?, 3'b100, 5'b?, OPCODE_LOAD}; + parameter INSTR_LHU = {17'b?, 3'b101, 5'b?, OPCODE_LOAD}; + + parameter INSTR_SB = {17'b?, 3'b000, 5'b?, OPCODE_STORE}; + parameter INSTR_SH = {17'b?, 3'b001, 5'b?, OPCODE_STORE}; + parameter INSTR_SW = {17'b?, 3'b010, 5'b?, OPCODE_STORE}; + + // parameter INSTR_FL = {OPCODE_LOAD_FP}; + // parameter INSTR_FS = {OPCODE_STORE_FP} + // CUSTOM_0 parameter INSTR_BEQIMM = {17'b?, 3'b110, 5'b?, OPCODE_CUSTOM_0}; parameter INSTR_BNEIMM = {17'b?, 3'b111, 5'b?, OPCODE_CUSTOM_0}; + // Post-Increment Register-Immediate Load + parameter INSTR_CVLBI = {17'b?, 3'b000, 5'b?, OPCODE_CUSTOM_0}; + parameter INSTR_CVLBUI = {17'b?, 3'b100, 5'b?, OPCODE_CUSTOM_0}; + parameter INSTR_CVLHI = {17'b?, 3'b001, 5'b?, OPCODE_CUSTOM_0}; + parameter INSTR_CVLHUI = {17'b?, 3'b101, 5'b?, OPCODE_CUSTOM_0}; + parameter INSTR_CVLWI = {17'b?, 3'b010, 5'b?, OPCODE_CUSTOM_0}; + + // Event Load + parameter INSTR_CVELW = {17'b?, 3'b011, 5'b?, OPCODE_CUSTOM_0}; + // CUSTOM_1 + // Post-Increment Register-Register Load + parameter INSTR_CVLBR = {7'b0000000, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLBUR = {7'b0001000, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLHR = {7'b0000001, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLHUR = {7'b0001001, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLWR = {7'b0000010, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + + // Register-Register Load + parameter INSTR_CVLBRR = {7'b0000100, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLBURR = {7'b0001100, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLHRR = {7'b0000101, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLHURR = {7'b0001101, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLWRR = {7'b0000110, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + + // Post-Increment Register-Immediate Store + parameter INSTR_CVSBI = {17'b?, 3'b000, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVSHI = {17'b?, 3'b001, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVSWI = {17'b?, 3'b010, 5'b?, OPCODE_CUSTOM_1}; + + // Post-Increment Register-Register Store operations encoding + parameter INSTR_CVSBR = {7'b0010000, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVSHR = {7'b0010001, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVSWR = {7'b0010010, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + + // Register-Register Store operations + parameter INSTR_CVSBRR = {7'b0010100, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVSHRR = {7'b0010101, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVSWRR = {7'b0010110, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + + // Hardware Loops + parameter INSTR_CVSTARTI0 = {12'b?, 5'b00000, 3'b100, 4'b0000, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVSTART0 = {12'b000000000000, 5'b?, 3'b100, 4'b0001, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVSENDI0 = {12'b?, 5'b00000, 3'b100, 4'b0010, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVEND0 = {12'b000000000000, 5'b?, 3'b100, 4'b0011, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVCOUNTI0 = {12'b?, 5'b00000, 3'b100, 4'b0100, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVCOUNT0 = {12'b000000000000, 5'b?, 3'b100, 4'b0101, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUPI0 = {12'b?, 5'b00000, 3'b100, 4'b0110, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUP0 = {12'b?, 5'b00000, 3'b100, 4'b0111, 1'b0, OPCODE_CUSTOM_1}; + + parameter INSTR_CVSTARTI1 = {12'b?, 5'b00000, 3'b100, 4'b0000, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVSTART1 = {12'b000000000000, 5'b?, 3'b100, 4'b0001, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVSENDI1 = {12'b?, 5'b00000, 3'b100, 4'b0010, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVEND1 = {12'b000000000000, 5'b?, 3'b100, 4'b0011, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVCOUNTI1 = {12'b?, 5'b00000, 3'b100, 4'b0100, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVCOUNT1 = {12'b000000000000, 5'b?, 3'b100, 4'b0101, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUPI1 = {12'b?, 5'b00000, 3'b100, 4'b0110, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUP1 = {12'b?, 5'b00000, 3'b100, 4'b0111, 1'b1, OPCODE_CUSTOM_1}; + + parameter INSTR_FF1 = {7'b0100001, 5'b0, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; parameter INSTR_FL1 = {7'b0100010, 5'b0, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; parameter INSTR_CLB = {7'b0100011, 5'b0, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; @@ -213,6 +287,290 @@ package cv32e40px_tracer_pkg; // CUSTOM_3 + // SIMD ALU + parameter INSTR_CVADDH = {5'b00000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVADDSCH = {5'b00000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVADDSCIH = {5'b00000, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVADDB = {5'b00000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVADDSCB = {5'b00000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVADDSCIB = {5'b00000, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSUBH = {5'b00001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBSCH = {5'b00001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBSCIH = {5'b00001, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBB = {5'b00001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBSCB = {5'b00001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBSCIB = {5'b00001, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVAVGH = {5'b00010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGSCH = {5'b00010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGSCIH = {5'b00010, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGB = {5'b00010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGSCB = {5'b00010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGSCIB = {5'b00010, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVAVGUH = {5'b00011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGUSCH = {5'b00011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGUSCIH = {5'b00011, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGUB = {5'b00011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGUSCB = {5'b00011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGUSCIB = {5'b00011, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVMINH = {5'b00100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINSCH = {5'b00100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINSCIH = {5'b00100, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINB = {5'b00100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINSCB = {5'b00100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINSCIB = {5'b00100, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVMINUH = {5'b00101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINUSCH = {5'b00101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINUSCIH = {5'b00101, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINUB = {5'b00101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINUSCB = {5'b00101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINUSCIB = {5'b00101, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVMAXH = {5'b00110, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXSCH = {5'b00110, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXSCIH = {5'b00110, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXB = {5'b00110, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXSCB = {5'b00110, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXSCIB = {5'b00110, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVMAXUH = {5'b00111, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXUSCH = {5'b00111, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXUSCIH = {5'b00111, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXUB = {5'b00111, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXUSCB = {5'b00111, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXUSCIB = {5'b00111, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSRLH = {5'b01000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRLSCH = {5'b01000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRLSCIH = {5'b01000, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRLB = {5'b01000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRLSCB = {5'b01000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRLSCIB = {5'b01000, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSRAH = {5'b01001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRASCH = {5'b01001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRASCIH = {5'b01001, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRAB = {5'b01001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRASCB = {5'b01001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRASCIB = {5'b01001, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSLLH = {5'b01010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSLLSCH = {5'b01010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSLLSCIH = {5'b01010, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSLLB = {5'b01010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSLLSCB = {5'b01010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSLLSCIB = {5'b01010, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVORH = {5'b01011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVORSCH = {5'b01011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVORSCIH = {5'b01011, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVORB = {5'b01011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVORSCB = {5'b01011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVORSCIB = {5'b01011, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVXORH = {5'b01100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVXORSCH = {5'b01100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVXORSCIH = {5'b01100, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVXORB = {5'b01100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVXORSCB = {5'b01100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVXORSCIB = {5'b01100, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVANDH = {5'b01101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVANDSCH = {5'b01101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVANDSCIH = {5'b01101, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVANDB = {5'b01101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVANDSCB = {5'b01101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVANDSCIB = {5'b01101, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVABSH = {5'b01110, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVABSB = {5'b01110, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVEXTRACTH = {5'b10111, 1'b0, 6'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVEXTRACTB = {5'b10111, 1'b0, 6'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVEXTRACTUH = {5'b10111, 1'b0, 6'b?, 5'b?, 3'b010, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVEXTRACTUB = {5'b10111, 1'b0, 6'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVINSERTH = {5'b10111, 1'b0, 6'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVINSERTB = {5'b10111, 1'b0, 6'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVDOTUPH = {5'b10000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUPSCH = {5'b10000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUPSCIH = {5'b10000, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUPB = {5'b10000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUPSCB = {5'b10000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUPSCIB = {5'b10000, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVDOTUSPH = {5'b10001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUSPSCH = {5'b10001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUSPSCIH = {5'b10001, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUSPB = {5'b10001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUSPSCB = {5'b10001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUSPSCIB = {5'b10001, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVDOTSPH = {5'b10010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTSPSCH = {5'b10010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTSPSCIH = {5'b10010, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTSPB = {5'b10010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTSPSCB = {5'b10010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTSPSCIB = {5'b10010, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSDOTUPH = {5'b10011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUPSCH = {5'b10011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUPSCIH = {5'b10011, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUPB = {5'b10011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUPSCB = {5'b10011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUPSCIB = {5'b10011, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSDOTUSPH = {5'b10100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUSPSCH = {5'b10100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUSPSCIH = {5'b10100, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUSPB = {5'b10100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUSPSCB = {5'b10100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUSPSCIB = {5'b10100, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSDOTSPH = {5'b10101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTSPSCH = {5'b10101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTSPSCIH = {5'b10101, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTSPB = {5'b10101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTSPSCB = {5'b10101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTSPSCIB = {5'b10101, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSHUFFLEH = {5'b11000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSHUFFLESCIH = {5'b11000, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSHUFFLEB = {5'b11000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSHUFFLEL0SCIB = {5'b11000, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSHUFFLEL1SCIB = {5'b11001, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSHUFFLEL2SCIB = {5'b11010, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSHUFFLEL3SCIB = {5'b11011, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSHUFFLE2H = {5'b11100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSHUFFLE2B = {5'b11100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVPACK = {5'b11101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVPACKH = {5'b11101, 1'b0, 1'b1, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVPACKHIB = {5'b11111, 1'b0, 1'b1, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVPACKLOB = {5'b11111, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + + // SIMD COMPARISON + parameter INSTR_CVCMPEQH = {5'b00000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPEQSCH = {5'b00000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPEQSCIH = {5'b00000, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPEQB = {5'b00000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPEQSCB = {5'b00000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPEQSCIB = {5'b00000, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPNEH = {5'b00001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPNESCH = {5'b00001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPNESCIH = {5'b00001, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPNEB = {5'b00001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPNESCB = {5'b00001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPNESCIB = {5'b00001, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPGTH = {5'b00010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTSCH = {5'b00010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTSCIH = {5'b00010, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTB = {5'b00010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTSCB = {5'b00010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTSCIB = {5'b00010, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPGEH = {5'b00011, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGESCH = {5'b00011, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGESCIH = {5'b00011, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGEB = {5'b00011, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGESCB = {5'b00011, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGESCIB = {5'b00011, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPLTH = {5'b00100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTSCH = {5'b00100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTSCIH = {5'b00100, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTB = {5'b00100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTSCB = {5'b00100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTSCIB = {5'b00100, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPLEH = {5'b00101, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLESCH = {5'b00101, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLESCIH = {5'b00101, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLEB = {5'b00101, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLESCB = {5'b00101, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLESCIB = {5'b00101, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPGTUH = {5'b00110, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTUSCH = {5'b00110, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTUSCIH = {5'b00110, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTUB = {5'b00110, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTUSCB = {5'b00110, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTUSCIB = {5'b00110, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPGEUH = {5'b00111, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGEUSCH = {5'b00111, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGEUSCIH = {5'b00111, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGEUB = {5'b00111, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGEUSCB = {5'b00111, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGEUSCIB = {5'b00111, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPLTUH = {5'b01000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTUSCH = {5'b01000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTUSCIH = {5'b01000, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTUB = {5'b01000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTUSCB = {5'b01000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTUSCIB = {5'b01000, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPLEUH = {5'b01001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLEUSCH = {5'b01001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLEUSCIH = {5'b01001, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLEUB = {5'b01001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLEUSCB = {5'b01001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLEUSCIB = {5'b01001, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + // SIMD CPLX + parameter INSTR_CVCPLXMULR = {5'b01010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCPLXMULRDIV2 = { + 5'b01010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b010, 5'b?, OPCODE_CUSTOM_3 + }; + parameter INSTR_CVCPLXMULRDIV4 = { + 5'b01010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3 + }; + parameter INSTR_CVCPLXMULRDIV8 = { + 5'b01010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3 + }; + + parameter INSTR_CVCPLXMULI = {5'b01010, 1'b1, 1'b1, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCPLXMULIDIV2 = { + 5'b01010, 1'b1, 1'b1, 5'b?, 5'b?, 3'b010, 5'b?, OPCODE_CUSTOM_3 + }; + parameter INSTR_CVCPLXMULIDIV4 = { + 5'b01010, 1'b1, 1'b1, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3 + }; + parameter INSTR_CVCPLXMULIDIV8 = { + 5'b01010, 1'b1, 1'b1, 5'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3 + }; + + parameter INSTR_CVCPLXCONJ = { + 5'b01011, 1'b1, 1'b0, 5'b00000, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3 + }; + + parameter INSTR_CVSUBROTMJ = {5'b01100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBROTMJDIV2 = { + 5'b01100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b010, 5'b?, OPCODE_CUSTOM_3 + }; + parameter INSTR_CVSUBROTMJDIV4 = { + 5'b01100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3 + }; + parameter INSTR_CVSUBROTMJDIV8 = { + 5'b01100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3 + }; + + parameter INSTR_CVADDIV2 = {5'b01101, 1'b1, 1'b0, 5'b?, 5'b?, 3'b010, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVADDIV4 = {5'b01101, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVADDIV8 = {5'b01101, 1'b1, 1'b0, 5'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSUBIV2 = {5'b01110, 1'b1, 1'b0, 5'b?, 5'b?, 3'b010, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBIV4 = {5'b01110, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBIV8 = {5'b01110, 1'b1, 1'b0, 5'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; // to be used in tracer! diff --git a/hw/vendor/esl_epfl_cv32e40px/bhv/insn_trace.sv b/hw/vendor/esl_epfl_cv32e40px/bhv/insn_trace.sv index cb766fc7e..3db2a7ee0 100644 --- a/hw/vendor/esl_epfl_cv32e40px/bhv/insn_trace.sv +++ b/hw/vendor/esl_epfl_cv32e40px/bhv/insn_trace.sv @@ -15,12 +15,18 @@ this.m_csr.``CSR_NAME``_wdata = m_source.m_csr.``CSR_NAME``_wdata; \ this.m_csr.``CSR_NAME``_wmask = m_source.m_csr.``CSR_NAME``_wmask; + `define INIT_CSR(CSR_NAME) \ + this.m_csr.``CSR_NAME``_we = '0; \ + this.m_csr.``CSR_NAME``_wmask = '0; + + import cv32e40p_tracer_pkg::*; class insn_trace_t; bit m_valid; logic [63:0] m_order; bit m_skip_order; //next order was used by trap; logic [31:0] m_pc_rdata; logic [31:0] m_insn; + string m_mnemonic; logic m_is_ebreak; logic m_is_illegal; logic m_is_irq; @@ -30,6 +36,7 @@ logic m_is_apu_ok; integer m_apu_req_id; integer m_mem_req_id[1:0]; + logic [ 1:0] m_mem_req_id_valid; logic m_data_missaligned; logic m_got_first_data; logic m_got_ex_reg; @@ -38,10 +45,13 @@ logic m_fflags_we_non_apu; logic m_frm_we_non_apu; + logic m_fcsr_we_non_apu; logic [5:0] m_rs1_addr; logic [5:0] m_rs2_addr; + logic [5:0] m_rs3_addr; logic [31:0] m_rs1_rdata; logic [31:0] m_rs2_rdata; + logic [31:0] m_rs3_rdata; bit m_trap; @@ -65,7 +75,17 @@ } m_mem; struct { - `DEFINE_CSR(mstatus) + logic mstatus_we; + logic [31:0] mstatus_rmask; + Status_t mstatus_wdata; + logic [31:0] mstatus_wmask; + Status_t mstatus_rdata; + + logic mstatus_fs_we; + FS_t mstatus_fs_rdata; + logic [31:0] mstatus_fs_rmask; + FS_t mstatus_fs_wdata; + logic [31:0] mstatus_fs_wmask; // mstatush @@ -145,12 +165,706 @@ this.m_apu_req_id = 0; this.m_mem_req_id[0] = 0; this.m_mem_req_id[1] = 0; + this.m_mem_req_id_valid = '0; this.m_trap = 1'b0; this.m_fflags_we_non_apu = 1'b0; this.m_frm_we_non_apu = 1'b0; + this.m_fcsr_we_non_apu = 1'b0; this.m_instret_cnt = 0; endfunction + function void get_mnemonic(); + + this.m_mnemonic = "INVALID"; + + if(!is_compressed_id_i) begin + // use casex instead of case inside due to ModelSim bug + casex (this.m_insn) + // Aliases + 32'h00_00_00_13: this.m_mnemonic = "nop"; + // Regular opcodes + INSTR_LUI: this.m_mnemonic = "lui"; + INSTR_AUIPC: this.m_mnemonic = "auipc"; + INSTR_JAL: this.m_mnemonic = "jal"; + INSTR_JALR: this.m_mnemonic = "jalr"; + // BRANCH + INSTR_BEQ: this.m_mnemonic = "beq"; + INSTR_BNE: this.m_mnemonic = "bne"; + INSTR_BLT: this.m_mnemonic = "blt"; + INSTR_BGE: this.m_mnemonic = "bge"; + INSTR_BLTU: this.m_mnemonic = "bltu"; + INSTR_BGEU: this.m_mnemonic = "bgeu"; + INSTR_BEQIMM: this.m_mnemonic = "cv.beqimm"; + INSTR_BNEIMM: this.m_mnemonic = "cv.bneimm"; + // OPIMM + INSTR_ADDI: this.m_mnemonic = "addi"; + INSTR_SLTI: this.m_mnemonic = "slti"; + INSTR_SLTIU: this.m_mnemonic = "sltiu"; + INSTR_XORI: this.m_mnemonic = "xori"; + INSTR_ORI: this.m_mnemonic = "ori"; + INSTR_ANDI: this.m_mnemonic = "andi"; + INSTR_SLLI: this.m_mnemonic = "slli"; + INSTR_SRLI: this.m_mnemonic = "srli"; + INSTR_SRAI: this.m_mnemonic = "srai"; + // OP + INSTR_ADD: this.m_mnemonic = "add"; + INSTR_SUB: this.m_mnemonic = "sub"; + INSTR_SLL: this.m_mnemonic = "sll"; + INSTR_SLT: this.m_mnemonic = "slt"; + INSTR_SLTU: this.m_mnemonic = "sltu"; + INSTR_XOR: this.m_mnemonic = "xor"; + INSTR_SRL: this.m_mnemonic = "srl"; + INSTR_SRA: this.m_mnemonic = "sra"; + INSTR_OR: this.m_mnemonic = "or"; + INSTR_AND: this.m_mnemonic = "and"; + INSTR_EXTHS: this.m_mnemonic = "cv.exths"; + INSTR_EXTHZ: this.m_mnemonic = "cv.exthz"; + INSTR_EXTBS: this.m_mnemonic = "cv.extbs"; + INSTR_EXTBZ: this.m_mnemonic = "cv.extbz"; + INSTR_PAVG: this.m_mnemonic = "cv.avg"; + INSTR_PAVGU: this.m_mnemonic = "cv.avgu"; + + INSTR_PADDN: this.m_mnemonic = "cv.addN"; + INSTR_PADDUN: this.m_mnemonic = "cv.adduN"; + INSTR_PADDRN: this.m_mnemonic = "cv.addRN"; + INSTR_PADDURN: this.m_mnemonic = "cv.adduRN"; + INSTR_PSUBN: this.m_mnemonic = "cv.subN"; + INSTR_PSUBUN: this.m_mnemonic = "cv.subuN"; + INSTR_PSUBRN: this.m_mnemonic = "cv.subRN"; + INSTR_PSUBURN: this.m_mnemonic = "cv.subuRN"; + + INSTR_PADDNR: this.m_mnemonic = "cv.addNr"; + INSTR_PADDUNR: this.m_mnemonic = "cv.adduNr"; + INSTR_PADDRNR: this.m_mnemonic = "cv.addRNr"; + INSTR_PADDURNR: this.m_mnemonic = "cv.adduRNr"; + INSTR_PSUBNR: this.m_mnemonic = "cv.subNr"; + INSTR_PSUBUNR: this.m_mnemonic = "cv.subuNr"; + INSTR_PSUBRNR: this.m_mnemonic = "cv.subRNr"; + INSTR_PSUBURNR: this.m_mnemonic = "cv.subuRNr"; + + INSTR_PSLET: this.m_mnemonic = "cv.slet"; + INSTR_PSLETU: this.m_mnemonic = "cv.sletu"; + INSTR_PMIN: this.m_mnemonic = "cv.min"; + INSTR_PMINU: this.m_mnemonic = "cv.minu"; + INSTR_PMAX: this.m_mnemonic = "cv.max"; + INSTR_PMAXU: this.m_mnemonic = "cv.maxu"; + INSTR_PABS: this.m_mnemonic = "cv.abs"; + INSTR_PCLIP: this.m_mnemonic = "cv.clip"; + INSTR_PCLIPU: this.m_mnemonic = "cv.clipu"; + INSTR_PBEXT: this.m_mnemonic = "cv.extract"; + INSTR_PBEXTU: this.m_mnemonic = "cv.extractu"; + INSTR_PBINS: this.m_mnemonic = "cv.insert"; + INSTR_PBCLR: this.m_mnemonic = "cv.bclr"; + INSTR_PBSET: this.m_mnemonic = "cv.bset"; + INSTR_PBREV: this.m_mnemonic = "cv.bitrev"; + + INSTR_PCLIPR: this.m_mnemonic = "cv.clipr"; + INSTR_PCLIPUR: this.m_mnemonic = "cv.clipur"; + INSTR_PBEXTR: this.m_mnemonic = "cv.extractr"; + INSTR_PBEXTUR: this.m_mnemonic = "cv.extractur"; + INSTR_PBINSR: this.m_mnemonic = "cv.insertr"; + INSTR_PBCLRR: this.m_mnemonic = "cv.bclrr"; + INSTR_PBSETR: this.m_mnemonic = "cv.bsetr"; + + + INSTR_FF1: this.m_mnemonic = "cv.ff1"; + INSTR_FL1: this.m_mnemonic = "cv.fl1"; + INSTR_CLB: this.m_mnemonic = "cv.clb"; + INSTR_CNT: this.m_mnemonic = "cv.cnt"; + INSTR_ROR: this.m_mnemonic = "cv.ror"; + + // FENCE + INSTR_FENCE: this.m_mnemonic = "fence"; + INSTR_FENCEI: this.m_mnemonic = "fencei"; + // SYSTEM (CSR manipulation) + INSTR_CSRRW: this.m_mnemonic = "csrrw"; + INSTR_CSRRS: this.m_mnemonic = "csrrs"; + INSTR_CSRRC: this.m_mnemonic = "csrrc"; + INSTR_CSRRWI: this.m_mnemonic = "csrrwi"; + INSTR_CSRRSI: this.m_mnemonic = "csrrsi"; + INSTR_CSRRCI: this.m_mnemonic = "csrrci"; + // SYSTEM (others) + INSTR_ECALL: this.m_mnemonic = "ecall"; + INSTR_EBREAK: this.m_mnemonic = "ebreak"; + INSTR_URET: this.m_mnemonic = "uret"; + INSTR_MRET: this.m_mnemonic = "mret"; + INSTR_WFI: this.m_mnemonic = "wfi"; + + INSTR_DRET: this.m_mnemonic = "dret"; + + // RV32M + INSTR_PMUL: this.m_mnemonic = "mul"; + INSTR_PMUH: this.m_mnemonic = "mulh"; + INSTR_PMULHSU: this.m_mnemonic = "mulhsu"; + INSTR_PMULHU: this.m_mnemonic = "mulhu"; + INSTR_DIV: this.m_mnemonic = "div"; + INSTR_DIVU: this.m_mnemonic = "divu"; + INSTR_REM: this.m_mnemonic = "rem"; + INSTR_REMU: this.m_mnemonic = "remu"; + // PULP MULTIPLIER + INSTR_PMAC: this.m_mnemonic = "cv.mac"; + INSTR_PMSU: this.m_mnemonic = "cv.msu"; + INSTR_PMULSN: this.m_mnemonic = "cv.mulsN"; + INSTR_PMULHHSN: this.m_mnemonic = "cv.mulhhsN"; + INSTR_PMULSRN: this.m_mnemonic = "cv.mulsRN"; + INSTR_PMULHHSRN: this.m_mnemonic = "cv.mulhhsRN"; + INSTR_PMULUN: this.m_mnemonic = "cv.muluN"; + INSTR_PMULHHUN: this.m_mnemonic = "cv.mulhhuN"; + INSTR_PMULURN: this.m_mnemonic = "cv.muluRN"; + INSTR_PMULHHURN: this.m_mnemonic = "cv.mulhhuRN"; + INSTR_PMACSN: this.m_mnemonic = "cv.macsN"; + INSTR_PMACHHSN: this.m_mnemonic = "cv.machhsN"; + INSTR_PMACSRN: this.m_mnemonic = "cv.macsRN"; + INSTR_PMACHHSRN: this.m_mnemonic = "cv.machhsRN"; + INSTR_PMACUN: this.m_mnemonic = "cv.macuN"; + INSTR_PMACHHUN: this.m_mnemonic = "cv.machhuN"; + INSTR_PMACURN: this.m_mnemonic = "cv.macuRN"; + INSTR_PMACHHURN: this.m_mnemonic = "cv.machhuRN"; + + // FP-OP + INSTR_FMADD: this.m_mnemonic = "fmadd.s"; + INSTR_FMSUB: this.m_mnemonic = "fmsub.s"; + INSTR_FNMADD: this.m_mnemonic = "fnmadd.s"; + INSTR_FNMSUB: this.m_mnemonic = "fnmsub.s"; + INSTR_FADD: this.m_mnemonic = "fadd.s"; + INSTR_FSUB: this.m_mnemonic = "fsub.s"; + INSTR_FMUL: this.m_mnemonic = "fmul.s"; + INSTR_FDIV: this.m_mnemonic = "fdiv.s"; + INSTR_FSQRT: this.m_mnemonic = "fsqrt.s"; + INSTR_FSGNJS: this.m_mnemonic = "fsgnj.s"; + INSTR_FSGNJNS: this.m_mnemonic = "fsgnjn.s"; + INSTR_FSGNJXS: this.m_mnemonic = "fsgnjx.s"; + INSTR_FMIN: this.m_mnemonic = "fmin.s"; + INSTR_FMAX: this.m_mnemonic = "fmax.s"; + INSTR_FCVTWS: this.m_mnemonic = "fcvt.w.s"; + INSTR_FCVTWUS: this.m_mnemonic = "fcvt.wu.s"; + INSTR_FMVXS: this.m_mnemonic = "fmv.x.s"; + INSTR_FEQS: this.m_mnemonic = "feq.s"; + INSTR_FLTS: this.m_mnemonic = "flt.s"; + INSTR_FLES: this.m_mnemonic = "fle.s"; + INSTR_FCLASS: this.m_mnemonic = "fclass.s"; + INSTR_FCVTSW: this.m_mnemonic = "fcvt.s.w"; + INSTR_FCVTSWU: this.m_mnemonic = "fcvt.s.wu"; + INSTR_FMVSX: this.m_mnemonic = "fmv.s.x"; + + // RV32A + INSTR_LR : this.m_mnemonic = "lr.w"; + INSTR_SC : this.m_mnemonic = "sc.w"; + INSTR_AMOSWAP : this.m_mnemonic = "amoswap.w"; + INSTR_AMOADD : this.m_mnemonic = "amoadd.w"; + INSTR_AMOXOR : this.m_mnemonic = "amoxor.w"; + INSTR_AMOAND : this.m_mnemonic = "amoand.w"; + INSTR_AMOOR : this.m_mnemonic = "amoor.w"; + INSTR_AMOMIN : this.m_mnemonic = "amomin.w"; + INSTR_AMOMAX : this.m_mnemonic = "amomax.w"; + INSTR_AMOMINU : this.m_mnemonic = "amominu.w"; + INSTR_AMOMAXU : this.m_mnemonic = "amomaxu.w"; + + // LOAD STORE + INSTR_LB : this.m_mnemonic = "lb"; + INSTR_LH : this.m_mnemonic = "lh"; + INSTR_LW : this.m_mnemonic = "lw"; + INSTR_LBU : this.m_mnemonic = "lbu"; + INSTR_LHU : this.m_mnemonic = "lhu"; + INSTR_SB : this.m_mnemonic = "sb"; + INSTR_SH : this.m_mnemonic = "sh"; + INSTR_SW : this.m_mnemonic = "sw"; + + // CUSTOM 0 + // Post-Increment Register-Immediate Load + INSTR_CVLBI : this.m_mnemonic = "cv.lb"; + INSTR_CVLBUI : this.m_mnemonic = "cv.lbu"; + INSTR_CVLHI : this.m_mnemonic = "cv.lh"; + INSTR_CVLHUI : this.m_mnemonic = "cv.lhu"; + INSTR_CVLWI : this.m_mnemonic = "cv.lw"; + + // Event Load + INSTR_CVELW : this.m_mnemonic = "cv.elw"; + + // CUSTOM_1 + // Post-Increment Register-Register Load + INSTR_CVLBR : this.m_mnemonic = "cv.lb"; + INSTR_CVLBUR : this.m_mnemonic = "cv.lbu"; + INSTR_CVLHR : this.m_mnemonic = "cv.lh"; + INSTR_CVLHUR : this.m_mnemonic = "cv.lhu"; + INSTR_CVLWR : this.m_mnemonic = "cv.lw"; + + // Register-Register Load + INSTR_CVLBRR : this.m_mnemonic = "cv.lb"; + INSTR_CVLBURR : this.m_mnemonic = "cv.lbu"; + INSTR_CVLHRR : this.m_mnemonic = "cv.lh"; + INSTR_CVLHURR : this.m_mnemonic = "cv.lhu"; + INSTR_CVLWRR : this.m_mnemonic = "cv.lw"; + + // Post-Increment Register-Immediate Store + INSTR_CVSBI : this.m_mnemonic = "cv.sb"; + INSTR_CVSHI : this.m_mnemonic = "cv.sh"; + INSTR_CVSWI : this.m_mnemonic = "cv.sw"; + + // Post-Increment Register-Register Store operations encoding + INSTR_CVSBR : this.m_mnemonic = "cv.sb"; + INSTR_CVSHR : this.m_mnemonic = "cv.sh"; + INSTR_CVSWR : this.m_mnemonic = "cv.sw"; + + // Register-Register Store operations + INSTR_CVSBRR : this.m_mnemonic = "cv.sb"; + INSTR_CVSHRR : this.m_mnemonic = "cv.sh"; + INSTR_CVSWRR : this.m_mnemonic = "cv.sw"; + + // Hardware Loops + INSTR_CVSTARTI0 : this.m_mnemonic = "cv.starti 0"; + INSTR_CVSTART0 : this.m_mnemonic = "cv.start 0"; + INSTR_CVSENDI0 : this.m_mnemonic = "cv.endi 0"; + INSTR_CVEND0 : this.m_mnemonic = "cv.end 0"; + INSTR_CVCOUNTI0 : this.m_mnemonic = "cv.counti 0"; + INSTR_CVCOUNT0 : this.m_mnemonic = "cv.count 0"; + INSTR_CVSETUPI0 : this.m_mnemonic = "cv.setupi 0"; + INSTR_CVSETUP0 : this.m_mnemonic = "cv.setup 0"; + INSTR_CVSTARTI1 : this.m_mnemonic = "cv..starti 1"; + INSTR_CVSTART1 : this.m_mnemonic = "cv..start 1"; + INSTR_CVSENDI1 : this.m_mnemonic = "cv..endi 1"; + INSTR_CVEND1 : this.m_mnemonic = "cv..end 1"; + INSTR_CVCOUNTI1 : this.m_mnemonic = "cv..counti 1"; + INSTR_CVCOUNT1 : this.m_mnemonic = "cv..count 1"; + INSTR_CVSETUPI1 : this.m_mnemonic = "cv..setupi 1"; + INSTR_CVSETUP1 : this.m_mnemonic = "cv..setup 1"; + + // CUSTOM 3 + // SIMD ALU + INSTR_CVADDH : this.m_mnemonic = "cv.add.h"; + INSTR_CVADDSCH : this.m_mnemonic = "cv.add.sc.h"; + INSTR_CVADDSCIH : this.m_mnemonic = "cv.add.sci.h"; + INSTR_CVADDB : this.m_mnemonic = "cv.add.b"; + INSTR_CVADDSCB : this.m_mnemonic = "cv.add.sc.b"; + INSTR_CVADDSCIB : this.m_mnemonic = "cv.add.sci.b"; + INSTR_CVSUBH : this.m_mnemonic = "cv.sub.h"; + INSTR_CVSUBSCH : this.m_mnemonic = "cv.sub.sc.h"; + INSTR_CVSUBSCIH : this.m_mnemonic = "cv.sub.sci.h"; + INSTR_CVSUBB : this.m_mnemonic = "cv.sub.b"; + INSTR_CVSUBSCB : this.m_mnemonic = "cv.sub.sc.b"; + INSTR_CVSUBSCIB : this.m_mnemonic = "cv.sub.sci.b"; + INSTR_CVAVGH : this.m_mnemonic = "cv.avg.h"; + INSTR_CVAVGSCH : this.m_mnemonic = "cv.avg.sc.h"; + INSTR_CVAVGSCIH : this.m_mnemonic = "cv.avg.sci.h"; + INSTR_CVAVGB : this.m_mnemonic = "cv.avg.b"; + INSTR_CVAVGSCB : this.m_mnemonic = "cv.avg.sc.b"; + INSTR_CVAVGSCIB : this.m_mnemonic = "cv.avg.sci.b"; + INSTR_CVAVGUH : this.m_mnemonic = "cv.avgu.h"; + INSTR_CVAVGUSCH : this.m_mnemonic = "cv.avgu.sc.h"; + INSTR_CVAVGUSCIH : this.m_mnemonic = "cv.avgu.sci.h"; + INSTR_CVAVGUB : this.m_mnemonic = "cv.avgu.b"; + INSTR_CVAVGUSCB : this.m_mnemonic = "cv.avgu.sc.b"; + INSTR_CVAVGUSCIB : this.m_mnemonic = "cv.avgu.sci.b"; + INSTR_CVMINH : this.m_mnemonic = "cv.min.h"; + INSTR_CVMINSCH : this.m_mnemonic = "cv.min.sc.h"; + INSTR_CVMINSCIH : this.m_mnemonic = "cv.min.sci.h"; + INSTR_CVMINB : this.m_mnemonic = "cv.min.b"; + INSTR_CVMINSCB : this.m_mnemonic = "cv.min.sc.b"; + INSTR_CVMINSCIB : this.m_mnemonic = "cv.min.sci.b"; + INSTR_CVMINUH : this.m_mnemonic = "cv.minu.h"; + INSTR_CVMINUSCH : this.m_mnemonic = "cv.minu.sc.h"; + INSTR_CVMINUSCIH : this.m_mnemonic = "cv.minu.sci.h"; + INSTR_CVMINUB : this.m_mnemonic = "cv.minu.b"; + INSTR_CVMINUSCB : this.m_mnemonic = "cv.minu.sc.b"; + INSTR_CVMINUSCIB : this.m_mnemonic = "cv.minu.sci.b"; + INSTR_CVMAXH : this.m_mnemonic = "cv.max.h"; + INSTR_CVMAXSCH : this.m_mnemonic = "cv.max.sc.h"; + INSTR_CVMAXSCIH : this.m_mnemonic = "cv.max.sci.h"; + INSTR_CVMAXB : this.m_mnemonic = "cv.max.b"; + INSTR_CVMAXSCB : this.m_mnemonic = "cv.max.sc.b"; + INSTR_CVMAXSCIB : this.m_mnemonic = "cv.max.sci.b"; + INSTR_CVMAXUH : this.m_mnemonic = "cv.maxu.h"; + INSTR_CVMAXUSCH : this.m_mnemonic = "cv.maxu.sc.h"; + INSTR_CVMAXUSCIH : this.m_mnemonic = "cv.maxu.sci.h"; + INSTR_CVMAXUB : this.m_mnemonic = "cv.maxu.b"; + INSTR_CVMAXUSCB : this.m_mnemonic = "cv.maxu.sc.b"; + INSTR_CVMAXUSCIB : this.m_mnemonic = "cv.maxu.sci.b"; + INSTR_CVSRLH : this.m_mnemonic = "cv.srl.h"; + INSTR_CVSRLSCH : this.m_mnemonic = "cv.srl.sc.h"; + INSTR_CVSRLSCIH : this.m_mnemonic = "cv.srl.sci.h"; + INSTR_CVSRLB : this.m_mnemonic = "cv.srl.b"; + INSTR_CVSRLSCB : this.m_mnemonic = "cv.srl.sc.b"; + INSTR_CVSRLSCIB : this.m_mnemonic = "cv.srl.sci.b"; + INSTR_CVSRAH : this.m_mnemonic = "cv.sra.h"; + INSTR_CVSRASCH : this.m_mnemonic = "cv.sra.sc.h"; + INSTR_CVSRASCIH : this.m_mnemonic = "cv.sra.sci.h"; + INSTR_CVSRAB : this.m_mnemonic = "cv.sra.b"; + INSTR_CVSRASCB : this.m_mnemonic = "cv.sra.sc.b"; + INSTR_CVSRASCIB : this.m_mnemonic = "cv.sra.sci.b"; + INSTR_CVSLLH : this.m_mnemonic = "cv.sll.h"; + INSTR_CVSLLSCH : this.m_mnemonic = "cv.sll.sc.h"; + INSTR_CVSLLSCIH : this.m_mnemonic = "cv.sll.sci.h"; + INSTR_CVSLLB : this.m_mnemonic = "cv.sll.b"; + INSTR_CVSLLSCB : this.m_mnemonic = "cv.sll.sc.b"; + INSTR_CVSLLSCIB : this.m_mnemonic = "cv.sll.sci.b"; + INSTR_CVORH : this.m_mnemonic = "cv.or.h"; + INSTR_CVORSCH : this.m_mnemonic = "cv.or.sc.h"; + INSTR_CVORSCIH : this.m_mnemonic = "cv.or.sci.h"; + INSTR_CVORB : this.m_mnemonic = "cv.or.b"; + INSTR_CVORSCB : this.m_mnemonic = "cv.or.sc.b"; + INSTR_CVORSCIB : this.m_mnemonic = "cv.or.sci.b"; + INSTR_CVXORH : this.m_mnemonic = "cv.xor.h"; + INSTR_CVXORSCH : this.m_mnemonic = "cv.xor.sc.h"; + INSTR_CVXORSCIH : this.m_mnemonic = "cv.xor.sci.h"; + INSTR_CVXORB : this.m_mnemonic = "cv.xor.b"; + INSTR_CVXORSCB : this.m_mnemonic = "cv.xor.sc.b"; + INSTR_CVXORSCIB : this.m_mnemonic = "cv.xor.sci.b"; + INSTR_CVANDH : this.m_mnemonic = "cv.and.h"; + INSTR_CVANDSCH : this.m_mnemonic = "cv.and.sc.h"; + INSTR_CVANDSCIH : this.m_mnemonic = "cv.and.sci.h"; + INSTR_CVANDB : this.m_mnemonic = "cv.and.b"; + INSTR_CVANDSCB : this.m_mnemonic = "cv.and.sc.b"; + INSTR_CVANDSCIB : this.m_mnemonic = "cv.and.sci.b"; + INSTR_CVABSH : this.m_mnemonic = "cv.abs.h"; + INSTR_CVABSB : this.m_mnemonic = "cv.abs.b"; + INSTR_CVEXTRACTH : this.m_mnemonic = "cv.extract.h"; + INSTR_CVEXTRACTB : this.m_mnemonic = "cv.extract.b"; + INSTR_CVEXTRACTUH : this.m_mnemonic = "cv.extractu.h"; + INSTR_CVEXTRACTUB : this.m_mnemonic = "cv.extractu.b"; + INSTR_CVINSERTH : this.m_mnemonic = "cv.insert.h"; + INSTR_CVINSERTB : this.m_mnemonic = "cv.insert.b"; + INSTR_CVDOTUPH : this.m_mnemonic = "cv.dotup.h"; + INSTR_CVDOTUPSCH : this.m_mnemonic = "cv.dotup.sc.h"; + INSTR_CVDOTUPSCIH : this.m_mnemonic = "cv.dotup.sci.h"; + INSTR_CVDOTUPB : this.m_mnemonic = "cv.dotup.b"; + INSTR_CVDOTUPSCB : this.m_mnemonic = "cv.dotup.sc.b"; + INSTR_CVDOTUPSCIB : this.m_mnemonic = "cv.dotup.sci.b"; + INSTR_CVDOTUSPH : this.m_mnemonic = "cv.dotusp.h.h"; + INSTR_CVDOTUSPSCH : this.m_mnemonic = "cv.dotusp.sc.h.sc.h"; + INSTR_CVDOTUSPSCIH : this.m_mnemonic = "cv.dotusp.sci.h.sci.h"; + INSTR_CVDOTUSPB : this.m_mnemonic = "cv.dotusp.b.b"; + INSTR_CVDOTUSPSCB : this.m_mnemonic = "cv.dotusp.sc.b.sc.b"; + INSTR_CVDOTUSPSCIB : this.m_mnemonic = "cv.dotusp.sci.b.sci.b"; + INSTR_CVDOTSPH : this.m_mnemonic = "cv.dotsp.h"; + INSTR_CVDOTSPSCH : this.m_mnemonic = "cv.dotsp.sc.h"; + INSTR_CVDOTSPSCIH : this.m_mnemonic = "cv.dotsp.sci.h"; + INSTR_CVDOTSPB : this.m_mnemonic = "cv.dotsp.b"; + INSTR_CVDOTSPSCB : this.m_mnemonic = "cv.dotsp.sc.b"; + INSTR_CVDOTSPSCIB : this.m_mnemonic = "cv.dotsp.sci.b"; + INSTR_CVSDOTUPH : this.m_mnemonic = "cv.sdotup.h"; + INSTR_CVSDOTUPSCH : this.m_mnemonic = "cv.sdotup.sc.h"; + INSTR_CVSDOTUPSCIH : this.m_mnemonic = "cv.sdotup.sci.h"; + INSTR_CVSDOTUPB : this.m_mnemonic = "cv.sdotup.b"; + INSTR_CVSDOTUPSCB : this.m_mnemonic = "cv.sdotup.sc.b"; + INSTR_CVSDOTUPSCIB : this.m_mnemonic = "cv.sdotup.sci.b"; + INSTR_CVSDOTUSPH : this.m_mnemonic = "cv.sdotusp.h"; + INSTR_CVSDOTUSPSCH : this.m_mnemonic = "cv.sdotusp.sc.h"; + INSTR_CVSDOTUSPSCIH : this.m_mnemonic = "cv.sdotusp.sci.h"; + INSTR_CVSDOTUSPB : this.m_mnemonic = "cv.sdotusp.b"; + INSTR_CVSDOTUSPSCB : this.m_mnemonic = "cv.sdotusp.sc.b"; + INSTR_CVSDOTUSPSCIB : this.m_mnemonic = "cv.sdotusp.sci.b"; + INSTR_CVSDOTSPH : this.m_mnemonic = "cv.sdotsp.h"; + INSTR_CVSDOTSPSCH : this.m_mnemonic = "cv.sdotsp.sc.h"; + INSTR_CVSDOTSPSCIH : this.m_mnemonic = "cv.sdotsp.sci.h"; + INSTR_CVSDOTSPB : this.m_mnemonic = "cv.sdotsp.b"; + INSTR_CVSDOTSPSCB : this.m_mnemonic = "cv.sdotsp.sc.b"; + INSTR_CVSDOTSPSCIB : this.m_mnemonic = "cv.sdotsp.sci.b"; + INSTR_CVSHUFFLEH : this.m_mnemonic = "cv.shuffle.h"; + INSTR_CVSHUFFLESCIH : this.m_mnemonic = "cv.shuffle.sci.h"; + INSTR_CVSHUFFLEB : this.m_mnemonic = "cv.shuffle.b"; + INSTR_CVSHUFFLEL0SCIB : this.m_mnemonic = "cv.shufflel0.sci.b"; + INSTR_CVSHUFFLEL1SCIB : this.m_mnemonic = "cv.shufflel1.sci.b"; + INSTR_CVSHUFFLEL2SCIB : this.m_mnemonic = "cv.shufflel2.sci.b"; + INSTR_CVSHUFFLEL3SCIB : this.m_mnemonic = "cv.shufflel3.sci.b"; + INSTR_CVSHUFFLE2H : this.m_mnemonic = "cv.shuffle2.h"; + INSTR_CVSHUFFLE2B : this.m_mnemonic = "cv.shuffle2.b"; + INSTR_CVPACK : this.m_mnemonic = "cv.pack"; + INSTR_CVPACKH : this.m_mnemonic = "cv.pack.h"; + INSTR_CVPACKHIB : this.m_mnemonic = "cv.packhi.b"; + INSTR_CVPACKLOB : this.m_mnemonic = "cv.packlo.b"; + + // SIMD COMPARISON + INSTR_CVCMPEQH : this.m_mnemonic = "cv.cmpeq.h"; + INSTR_CVCMPEQSCH : this.m_mnemonic = "cv.cmpeq.sc.h"; + INSTR_CVCMPEQSCIH : this.m_mnemonic = "cv.cmpeq.sci.h"; + INSTR_CVCMPEQB : this.m_mnemonic = "cv.cmpeq.b"; + INSTR_CVCMPEQSCB : this.m_mnemonic = "cv.cmpeq.sc.b"; + INSTR_CVCMPEQSCIB : this.m_mnemonic = "cv.cmpeq.sci.b"; + INSTR_CVCMPNEH : this.m_mnemonic = "cv.cmpne.h"; + INSTR_CVCMPNESCH : this.m_mnemonic = "cv.cmpne.sc.h"; + INSTR_CVCMPNESCIH : this.m_mnemonic = "cv.cmpne.sci.h"; + INSTR_CVCMPNEB : this.m_mnemonic = "cv.cmpne.b"; + INSTR_CVCMPNESCB : this.m_mnemonic = "cv.cmpne.sc.b"; + INSTR_CVCMPNESCIB : this.m_mnemonic = "cv.cmpne.sci.b"; + INSTR_CVCMPGTH : this.m_mnemonic = "cv.cmpgt.h"; + INSTR_CVCMPGTSCH : this.m_mnemonic = "cv.cmpgt.sc.h"; + INSTR_CVCMPGTSCIH : this.m_mnemonic = "cv.cmpgt.sci.h"; + INSTR_CVCMPGTB : this.m_mnemonic = "cv.cmpgt.b"; + INSTR_CVCMPGTSCB : this.m_mnemonic = "cv.cmpgt.sc.b"; + INSTR_CVCMPGTSCIB : this.m_mnemonic = "cv.cmpgt.sci.b"; + INSTR_CVCMPGEH : this.m_mnemonic = "cv.cmpge.h"; + INSTR_CVCMPGESCH : this.m_mnemonic = "cv.cmpge.sc.h"; + INSTR_CVCMPGESCIH : this.m_mnemonic = "cv.cmpge.sci.h"; + INSTR_CVCMPGEB : this.m_mnemonic = "cv.cmpge.b"; + INSTR_CVCMPGESCB : this.m_mnemonic = "cv.cmpge.sc.b"; + INSTR_CVCMPGESCIB : this.m_mnemonic = "cv.cmpge.sci.b"; + INSTR_CVCMPLTH : this.m_mnemonic = "cv.cmplt.h"; + INSTR_CVCMPLTSCH : this.m_mnemonic = "cv.cmplt.sc.h"; + INSTR_CVCMPLTSCIH : this.m_mnemonic = "cv.cmplt.sci.h"; + INSTR_CVCMPLTB : this.m_mnemonic = "cv.cmplt.b"; + INSTR_CVCMPLTSCB : this.m_mnemonic = "cv.cmplt.sc.b"; + INSTR_CVCMPLTSCIB : this.m_mnemonic = "cv.cmplt.sci.b"; + INSTR_CVCMPLEH : this.m_mnemonic = "cv.cmple.h"; + INSTR_CVCMPLESCH : this.m_mnemonic = "cv.cmple.sc.h"; + INSTR_CVCMPLESCIH : this.m_mnemonic = "cv.cmple.sci.h"; + INSTR_CVCMPLEB : this.m_mnemonic = "cv.cmple.b"; + INSTR_CVCMPLESCB : this.m_mnemonic = "cv.cmple.sc.b"; + INSTR_CVCMPLESCIB : this.m_mnemonic = "cv.cmple.sci.b"; + INSTR_CVCMPGTUH : this.m_mnemonic = "cv.cmptu.h"; + INSTR_CVCMPGTUSCH : this.m_mnemonic = "cv.cmptu.sc.h"; + INSTR_CVCMPGTUSCIH : this.m_mnemonic = "cv.cmptu.sci.h"; + INSTR_CVCMPGTUB : this.m_mnemonic = "cv.cmptu.b"; + INSTR_CVCMPGTUSCB : this.m_mnemonic = "cv.cmptu.sc.b"; + INSTR_CVCMPGTUSCIB : this.m_mnemonic = "cv.cmptu.sci.b"; + INSTR_CVCMPGEUH : this.m_mnemonic = "cv.cmpgeu.h"; + INSTR_CVCMPGEUSCH : this.m_mnemonic = "cv.cmpgeu.sc.h"; + INSTR_CVCMPGEUSCIH : this.m_mnemonic = "cv.cmpgeu.sci.h"; + INSTR_CVCMPGEUB : this.m_mnemonic = "cv.cmpgeu.b"; + INSTR_CVCMPGEUSCB : this.m_mnemonic = "cv.cmpgeu.sc.b"; + INSTR_CVCMPGEUSCIB : this.m_mnemonic = "cv.cmpgeu.sci.b"; + INSTR_CVCMPLTUH : this.m_mnemonic = "cv.cmpltu.h"; + INSTR_CVCMPLTUSCH : this.m_mnemonic = "cv.cmpltu.sc.h"; + INSTR_CVCMPLTUSCIH : this.m_mnemonic = "cv.cmpltu.sci.h"; + INSTR_CVCMPLTUB : this.m_mnemonic = "cv.cmpltu.b"; + INSTR_CVCMPLTUSCB : this.m_mnemonic = "cv.cmpltu.sc.b"; + INSTR_CVCMPLTUSCIB : this.m_mnemonic = "cv.cmpltu.sci.b"; + INSTR_CVCMPLEUH : this.m_mnemonic = "cv.cmpleu.h"; + INSTR_CVCMPLEUSCH : this.m_mnemonic = "cv.cmpleu.sc.h"; + INSTR_CVCMPLEUSCIH : this.m_mnemonic = "cv.cmpleu.sci.h"; + INSTR_CVCMPLEUB : this.m_mnemonic = "cv.cmpleu.b"; + INSTR_CVCMPLEUSCB : this.m_mnemonic = "cv.cmpleu.sc.b"; + INSTR_CVCMPLEUSCIB : this.m_mnemonic = "cv.cmpleu.sci.b"; + + // SIMD CPLX + INSTR_CVCPLXMULR : this.m_mnemonic = "cv.cplxmul.r"; + INSTR_CVCPLXMULRDIV2 : this.m_mnemonic = "cv.cplxmul.r.div2"; + INSTR_CVCPLXMULRDIV4 : this.m_mnemonic = "cv.cplxmul.r.div4"; + INSTR_CVCPLXMULRDIV8 : this.m_mnemonic = "cv.cplxmul.r.div8"; + INSTR_CVCPLXMULI : this.m_mnemonic = "cv.cplxmul.i"; + INSTR_CVCPLXMULIDIV2 : this.m_mnemonic = "cv.cplxmul.i.div2"; + INSTR_CVCPLXMULIDIV4 : this.m_mnemonic = "cv.cplxmul.i.div4"; + INSTR_CVCPLXMULIDIV8 : this.m_mnemonic = "cv.cplxmul.i.div8"; + INSTR_CVCPLXCONJ : this.m_mnemonic = "cv.cplxconj"; + INSTR_CVSUBROTMJ : this.m_mnemonic = "cv.subrotmj"; + INSTR_CVSUBROTMJDIV2 : this.m_mnemonic = "cv.subrotmj.div2"; + INSTR_CVSUBROTMJDIV4 : this.m_mnemonic = "cv.subrotmj.div4"; + INSTR_CVSUBROTMJDIV8 : this.m_mnemonic = "cv.subrotmj.div8"; + INSTR_CVADDIV2 : this.m_mnemonic = "cv.add.div2"; + INSTR_CVADDIV4 : this.m_mnemonic = "cv.add.div4"; + INSTR_CVADDIV8 : this.m_mnemonic = "cv.add.div8"; + INSTR_CVSUBIV2 : this.m_mnemonic = "cv.sub.div2"; + INSTR_CVSUBIV4 : this.m_mnemonic = "cv.sub.div4"; + INSTR_CVSUBIV8 : this.m_mnemonic = "cv.sub.div8"; + + default : this.m_mnemonic = "INVALID"; + endcase // unique case (instr) + end else begin //Compressed instruction + unique case (this.m_insn[1:0]) + // C0 + 2'b00: begin + unique case (this.m_insn[15:13]) + 3'b000: begin + // c.addi4spn -> addi rd', x2, imm + this.m_mnemonic = "c.addi4spn"; + end + + 3'b001: begin this.m_mnemonic = "c.fld"; end + 3'b010: begin this.m_mnemonic = "c.lw"; end + 3'b011: begin this.m_mnemonic = "c.flw"; end + 3'b101: begin this.m_mnemonic = "c.fsd"; end + 3'b110: begin this.m_mnemonic = "c.sw"; end + 3'b111: begin this.m_mnemonic = "c.fsw"; end + default: begin this.m_mnemonic = "INVALID"; end + endcase + end + + // C1 + 2'b01: begin + unique case (this.m_insn[15:13]) + 3'b000: begin + // c.addi -> addi rd, rd, nzimm + // c.nop + if(this.m_insn[11:7] == '0) begin + this.m_mnemonic = "c.nop"; + end else begin + this.m_mnemonic = "c.addi"; + end + end + 3'b001: this.m_mnemonic = "c.jal"; + 3'b101: this.m_mnemonic = "c.j"; + + 3'b010: begin + if (this.m_insn[11:7] == 5'b0) begin + // Hint -> addi x0, x0, nzimm + this.m_mnemonic = "HINT"; + end else begin + this.m_mnemonic = "c.li"; + end + end + + 3'b011: begin + if ({this.m_insn[12], this.m_insn[6:2]} == 6'b0) begin + this.m_mnemonic = "INVALID"; + end else begin + if (this.m_insn[11:7] == 5'h02) begin + // c.addi16sp -> addi x2, x2, nzimm + this.m_mnemonic = "c.addi16sp"; + end else if (this.m_insn[11:7] == 5'b0) begin + // Hint -> lui x0, imm + this.m_mnemonic = "HINT"; + end else begin + this.m_mnemonic = "c.lui"; + end + end + end + + 3'b100: begin + unique case (this.m_insn[11:10]) + 2'b00 : begin + // 00: c.srli -> srli rd, rd, shamt + // 01: c.srai -> srai rd, rd, shamt + if (this.m_insn[12] == 1'b1) begin + // Reserved for future custom extensions (instr_o don't care) + this.m_mnemonic = "INVALID"; + end else begin + if (this.m_insn[6:2] == 5'b0) begin + // Hint + this.m_mnemonic = "HINT"; + end else begin + this.m_mnemonic = "c.srli"; + end + end + end + 2'b01 : begin + if (this.m_insn[12] == 1'b1) begin + // Reserved for future custom extensions (instr_o don't care) + this.m_mnemonic = "INVALID"; + end else begin + if (this.m_insn[6:2] == 5'b0) begin + // Hint + this.m_mnemonic = "HINT"; + end else begin + this.m_mnemonic = "c.srai"; + end + end + end + + 2'b10: begin this.m_mnemonic = "c.andi"; end + + 2'b11: begin + unique case ({ this.m_insn[12], this.m_insn[6:5] }) + 3'b000: begin this.m_mnemonic = "c.sub"; end + 3'b001: begin this.m_mnemonic = "c.xor"; end + 3'b010: begin this.m_mnemonic = "c.or"; end + 3'b011: begin this.m_mnemonic = "c.and"; end + 3'b100 : this.m_mnemonic = "c.subw"; + 3'b101 : this.m_mnemonic = "c.addw"; + + 3'b110, 3'b111: begin + this.m_mnemonic = "INVALID"; + end + + endcase + end + endcase + end + + 3'b110: begin this.m_mnemonic = "c.beqz"; end + 3'b111: begin this.m_mnemonic = "c.bnez"; end + endcase + end + + // C2 + 2'b10: begin + unique case (this.m_insn[15:13]) + 3'b000: begin + if (this.m_insn[12] == 1'b1) begin + // Reserved for future extensions (instr_o don't care) + this.m_mnemonic = "TODO"; + end else begin + if ((this.m_insn[6:2] == 5'b0) || (this.m_insn[11:7] == 5'b0)) begin + // Hint -> slli rd, rd, shamt + this.m_mnemonic = "HINT"; + end else begin + this.m_mnemonic = "c.slli"; + end + end + end + + 3'b001: begin this.m_mnemonic = "c.fldsp"; end + 3'b010: begin this.m_mnemonic = "c.lwsp"; end + 3'b011: begin this.m_mnemonic = "c.flwsp"; end + + 3'b100: begin + if (this.m_insn[12] == 1'b0) begin + if (this.m_insn[6:2] == 5'b0) begin + this.m_mnemonic = "c.jr"; + end else begin + if (this.m_insn[11:7] == 5'b0) begin + // Hint -> add x0, x0, rs2 + this.m_mnemonic = "HINT"; + end else begin + this.m_mnemonic = "c.mv"; + end + end + end else begin + if (this.m_insn[6:2] == 5'b0) begin + if (this.m_insn[11:7] == 5'b0) begin + this.m_mnemonic = "c.ebreak"; + end else begin + this.m_mnemonic = "c.jalr"; + end + end else begin + if (this.m_insn[11:7] == 5'b0) begin + // Hint -> add x0, x0, rs2 + this.m_mnemonic = "HINT"; + end else begin + this.m_mnemonic = "c.add"; + end + end + end + end + + 3'b101: begin this.m_mnemonic = "c.fsdsp"; end + 3'b110: begin this.m_mnemonic = "c.swsp"; end + 3'b111: begin this.m_mnemonic = "c.fswsp"; end + endcase + end + endcase + end + endfunction + + function void init_csr(); + `INIT_CSR(mstatus) + `INIT_CSR(mstatus_fs) + `INIT_CSR(misa) + `INIT_CSR(mie) + `INIT_CSR(mtvec) + `INIT_CSR(mcountinhibit) + `INIT_CSR(mscratch) + `INIT_CSR(mepc) + `INIT_CSR(mcause) + `INIT_CSR(minstret) + `INIT_CSR(mip) + `INIT_CSR(tdata1) + `INIT_CSR(tdata2) + `INIT_CSR(tinfo) + `INIT_CSR(dcsr) + `INIT_CSR(dpc) + `INIT_CSR(dscratch0) + `INIT_CSR(dscratch1) + `INIT_CSR(mvendorid) + `INIT_CSR(marchid) + `INIT_CSR(fflags) + `INIT_CSR(frm ) + `INIT_CSR(fcsr ) + `INIT_CSR(lpstart0 ) + `INIT_CSR(lpend0 ) + `INIT_CSR(lpcount0 ) + `INIT_CSR(lpstart1 ) + `INIT_CSR(lpend1 ) + `INIT_CSR(lpcount1 ) + endfunction /* * */ @@ -172,6 +886,7 @@ this.m_apu_req_id = 0; this.m_mem_req_id[0] = 0; this.m_mem_req_id[1] = 0; + this.m_mem_req_id_valid = '0; this.m_data_missaligned = 1'b0; this.m_got_first_data = 1'b0; this.m_got_ex_reg = 1'b0; @@ -183,12 +898,14 @@ this.m_2_rd_insn = 1'b0; this.m_rs1_addr = '0; this.m_rs2_addr = '0; + this.m_rs3_addr = '0; this.m_ex_fw = '0; this.m_csr.got_minstret = '0; this.m_dbg_taken = '0; this.m_trap = 1'b0; this.m_fflags_we_non_apu = 1'b0; this.m_frm_we_non_apu = 1'b0; + this.m_fcsr_we_non_apu = 1'b0; this.m_csr.mcause_we = '0; if (is_compressed_id_i) begin this.m_insn[31:16] = '0; @@ -196,6 +913,7 @@ end else begin this.m_insn = m_source.m_insn; end + this.get_mnemonic(); this.m_intr = m_source.m_intr; this.m_dbg_taken = m_source.m_dbg_taken; @@ -205,14 +923,18 @@ this.m_rs1_addr = r_pipe_freeze_trace.rs1_addr_id; this.m_rs2_addr = r_pipe_freeze_trace.rs2_addr_id; + this.m_rs3_addr = r_pipe_freeze_trace.rs3_addr_id; this.m_rs1_rdata = r_pipe_freeze_trace.operand_a_fw_id; this.m_rs2_rdata = r_pipe_freeze_trace.operand_b_fw_id; + this.m_rs3_rdata = r_pipe_freeze_trace.operand_c_fw_id; this.m_mem.addr = '0; this.m_mem.rmask = '0; this.m_mem.wmask = '0; this.m_mem.rdata = '0; this.m_mem.wdata = '0; + + init_csr(); endfunction function logic [63:0] get_order_for_trap(); @@ -227,12 +949,14 @@ this.m_order = m_source.m_order; this.m_pc_rdata = m_source.m_pc_rdata; this.m_insn = m_source.m_insn; + this.m_mnemonic = m_source.m_mnemonic; this.m_is_memory = m_source.m_is_memory; this.m_is_load = m_source.m_is_load; this.m_is_apu = m_source.m_is_apu; this.m_is_apu_ok = m_source.m_is_apu_ok; this.m_apu_req_id = m_source.m_apu_req_id; this.m_mem_req_id = m_source.m_mem_req_id; + this.m_mem_req_id_valid = m_source.m_mem_req_id_valid; this.m_data_missaligned = m_source.m_data_missaligned; this.m_got_first_data = m_source.m_got_first_data; this.m_got_ex_reg = m_source.m_got_ex_reg; @@ -244,8 +968,10 @@ this.m_instret_cnt = m_source.m_instret_cnt; this.m_rs1_addr = m_source.m_rs1_addr; this.m_rs2_addr = m_source.m_rs2_addr; + this.m_rs3_addr = m_source.m_rs3_addr; this.m_rs1_rdata = m_source.m_rs1_rdata; this.m_rs2_rdata = m_source.m_rs2_rdata; + this.m_rs3_rdata = m_source.m_rs3_rdata; this.m_ex_fw = m_source.m_ex_fw; this.m_rd_addr = m_source.m_rd_addr; @@ -256,10 +982,12 @@ this.m_trap = m_source.m_trap; this.m_fflags_we_non_apu = m_source.m_fflags_we_non_apu; this.m_frm_we_non_apu = m_source.m_frm_we_non_apu ; + this.m_fcsr_we_non_apu = m_source.m_fcsr_we_non_apu; this.m_mem = m_source.m_mem; //CRS `ASSIGN_CSR(mstatus) + `ASSIGN_CSR(mstatus_fs) `ASSIGN_CSR(misa) `ASSIGN_CSR(mie) `ASSIGN_CSR(mtvec) diff --git a/hw/vendor/esl_epfl_cv32e40px/bhv/pipe_freeze_trace.sv b/hw/vendor/esl_epfl_cv32e40px/bhv/pipe_freeze_trace.sv index b5d433df1..58051ab8e 100644 --- a/hw/vendor/esl_epfl_cv32e40px/bhv/pipe_freeze_trace.sv +++ b/hw/vendor/esl_epfl_cv32e40px/bhv/pipe_freeze_trace.sv @@ -76,8 +76,10 @@ typedef struct { // Register reads logic [5:0] rs1_addr_id; logic [5:0] rs2_addr_id; + logic [5:0] rs3_addr_id; logic [31:0] operand_a_fw_id; logic [31:0] operand_b_fw_id; + logic [31:0] operand_c_fw_id; //// EX probes //// @@ -94,6 +96,7 @@ typedef struct { logic apu_multicycle; logic wb_contention_lsu; logic wb_contention; + logic regfile_we_lsu; logic branch_in_ex; logic branch_decision_ex; @@ -121,6 +124,7 @@ typedef struct { logic rf_we_wb; logic [5:0] rf_addr_wb; logic [31:0] rf_wdata_wb; + logic rf_alu_we_ex; // LSU logic [31:0] lsu_rdata_wb; @@ -141,6 +145,7 @@ typedef struct { logic p_elw_finish; logic lsu_ready_ex; logic lsu_ready_wb; + logic [3:0] lsu_data_be; logic data_req_pmp; logic data_gnt_pmp; logic data_rvalid; @@ -185,6 +190,7 @@ typedef struct { logic [31:0] wdata_int; logic mstatus_we; + logic mstatus_fs_we; logic misa_we; logic mtvec_we; logic mscratch_we; @@ -197,8 +203,6 @@ typedef struct { Status_t mstatus_q; FS_t mstatus_fs_n; FS_t mstatus_fs_q; - logic [31:0] mstatus_full_n; - logic [31:0] mstatus_full_q; logic mstatush_we; logic [31:0] misa_n; @@ -326,20 +330,24 @@ pipe_trace_t r_pipe_freeze_trace; // Compute each CSR write enable function compute_csr_we(); - r_pipe_freeze_trace.csr.mstatus_we = 1'b0; - r_pipe_freeze_trace.csr.misa_we = 1'b0; - r_pipe_freeze_trace.csr.mtvec_we = 1'b0; - r_pipe_freeze_trace.csr.mscratch_we = 1'b0; - r_pipe_freeze_trace.csr.mepc_we = 1'b0; - r_pipe_freeze_trace.csr.mcause_we = 1'b0; - r_pipe_freeze_trace.csr.dcsr_we = 1'b0; - r_pipe_freeze_trace.csr.fflags_we = 1'b0; - r_pipe_freeze_trace.csr.frm_we = 1'b0; - r_pipe_freeze_trace.csr.fcsr_we = 1'b0; - r_pipe_freeze_trace.csr.dpc_we = csr_dpc_we_i; + r_pipe_freeze_trace.csr.mstatus_we = 1'b0; + r_pipe_freeze_trace.csr.mstatus_fs_we = 1'b0; + r_pipe_freeze_trace.csr.misa_we = 1'b0; + r_pipe_freeze_trace.csr.mtvec_we = 1'b0; + r_pipe_freeze_trace.csr.mscratch_we = 1'b0; + r_pipe_freeze_trace.csr.mepc_we = 1'b0; + r_pipe_freeze_trace.csr.mcause_we = 1'b0; + r_pipe_freeze_trace.csr.dcsr_we = 1'b0; + r_pipe_freeze_trace.csr.fflags_we = 1'b0; + r_pipe_freeze_trace.csr.frm_we = 1'b0; + r_pipe_freeze_trace.csr.fcsr_we = 1'b0; + r_pipe_freeze_trace.csr.dpc_we = csr_dpc_we_i; if (r_pipe_freeze_trace.csr.we) begin case (r_pipe_freeze_trace.csr.addr) - CSR_MSTATUS: r_pipe_freeze_trace.csr.mstatus_we = 1'b1; + CSR_MSTATUS: begin + r_pipe_freeze_trace.csr.mstatus_we = 1'b1; + r_pipe_freeze_trace.csr.mstatus_fs_we = 1'b1; + end CSR_MISA: r_pipe_freeze_trace.csr.misa_we = 1'b1; CSR_MTVEC: r_pipe_freeze_trace.csr.mtvec_we = 1'b1; CSR_MSCRATCH: r_pipe_freeze_trace.csr.mscratch_we = 1'b1; @@ -397,171 +405,132 @@ task monitor_pipeline(); //// IF probes //// if_probes(); //// ID probes //// - r_pipe_freeze_trace.pc_id = pc_id_i; - r_pipe_freeze_trace.id_valid = id_valid_i; - - r_pipe_freeze_trace.id_ready = id_ready_i; - r_pipe_freeze_trace.rf_re_id = rf_re_id_i; - r_pipe_freeze_trace.sys_en_id = sys_en_id_i; - r_pipe_freeze_trace.sys_mret_insn_id = sys_mret_insn_id_i; - r_pipe_freeze_trace.jump_in_id = jump_in_id_i; - r_pipe_freeze_trace.jump_target_id = jump_target_id_i; - r_pipe_freeze_trace.is_compressed_id = is_compressed_id_i; - r_pipe_freeze_trace.ebrk_insn_dec = ebrk_insn_dec_i; - r_pipe_freeze_trace.csr_cause = csr_cause_i; - r_pipe_freeze_trace.debug_csr_save = debug_csr_save_i; - r_pipe_freeze_trace.minstret = minstret_i; + r_pipe_freeze_trace.pc_id = pc_id_i; + r_pipe_freeze_trace.id_valid = id_valid_i; + + r_pipe_freeze_trace.id_ready = id_ready_i; + r_pipe_freeze_trace.rf_re_id = rf_re_id_i; + r_pipe_freeze_trace.sys_en_id = sys_en_id_i; + r_pipe_freeze_trace.sys_mret_insn_id = sys_mret_insn_id_i; + r_pipe_freeze_trace.jump_in_id = jump_in_id_i; + r_pipe_freeze_trace.jump_target_id = jump_target_id_i; + r_pipe_freeze_trace.is_compressed_id = is_compressed_id_i; + r_pipe_freeze_trace.ebrk_insn_dec = ebrk_insn_dec_i; + r_pipe_freeze_trace.csr_cause = csr_cause_i; + r_pipe_freeze_trace.debug_csr_save = debug_csr_save_i; + r_pipe_freeze_trace.minstret = minstret_i; // LSU - r_pipe_freeze_trace.lsu_en_id = lsu_en_id_i; - r_pipe_freeze_trace.lsu_we_id = lsu_we_id_i; - r_pipe_freeze_trace.lsu_size_id = lsu_size_id_i; + r_pipe_freeze_trace.lsu_en_id = lsu_en_id_i; + r_pipe_freeze_trace.lsu_we_id = lsu_we_id_i; + r_pipe_freeze_trace.lsu_size_id = lsu_size_id_i; // Register reads - r_pipe_freeze_trace.rs1_addr_id = rs1_addr_id_i; - r_pipe_freeze_trace.rs2_addr_id = rs2_addr_id_i; - r_pipe_freeze_trace.operand_a_fw_id = operand_a_fw_id_i; - r_pipe_freeze_trace.operand_b_fw_id = operand_b_fw_id_i; + r_pipe_freeze_trace.rs1_addr_id = rs1_addr_id_i; + r_pipe_freeze_trace.rs2_addr_id = rs2_addr_id_i; + r_pipe_freeze_trace.rs3_addr_id = rs3_addr_id_i; + r_pipe_freeze_trace.operand_a_fw_id = operand_a_fw_id_i; + r_pipe_freeze_trace.operand_b_fw_id = operand_b_fw_id_i; + r_pipe_freeze_trace.operand_c_fw_id = operand_c_fw_id_i; //// EX probes //// // Register writes in EX - r_pipe_freeze_trace.ex_ready = ex_ready_i; - r_pipe_freeze_trace.ex_valid = ex_valid_i; - - r_pipe_freeze_trace.ex_reg_we = ex_reg_we_i; - r_pipe_freeze_trace.ex_reg_addr = ex_reg_addr_i; - r_pipe_freeze_trace.ex_reg_wdata = ex_reg_wdata_i; - - r_pipe_freeze_trace.apu_en_ex = apu_en_ex_i; - r_pipe_freeze_trace.apu_singlecycle = apu_singlecycle_i; - r_pipe_freeze_trace.apu_multicycle = apu_multicycle_i; - r_pipe_freeze_trace.wb_contention_lsu = wb_contention_lsu_i; - r_pipe_freeze_trace.wb_contention = wb_contention_i; - - r_pipe_freeze_trace.branch_in_ex = branch_in_ex_i; - r_pipe_freeze_trace.branch_decision_ex = branch_decision_ex_i; - r_pipe_freeze_trace.dret_in_ex = dret_in_ex_i; + r_pipe_freeze_trace.ex_ready = ex_ready_i; + r_pipe_freeze_trace.ex_valid = ex_valid_i; + + r_pipe_freeze_trace.ex_reg_we = ex_reg_we_i; + r_pipe_freeze_trace.ex_reg_addr = ex_reg_addr_i; + r_pipe_freeze_trace.ex_reg_wdata = ex_reg_wdata_i; + + r_pipe_freeze_trace.apu_en_ex = apu_en_ex_i; + r_pipe_freeze_trace.apu_singlecycle = apu_singlecycle_i; + r_pipe_freeze_trace.apu_multicycle = apu_multicycle_i; + r_pipe_freeze_trace.wb_contention_lsu = wb_contention_lsu_i; + r_pipe_freeze_trace.wb_contention = wb_contention_i; + r_pipe_freeze_trace.regfile_we_lsu = regfile_we_lsu_i; + + r_pipe_freeze_trace.branch_in_ex = branch_in_ex_i; + r_pipe_freeze_trace.branch_decision_ex = branch_decision_ex_i; + r_pipe_freeze_trace.dret_in_ex = dret_in_ex_i; // LSU - r_pipe_freeze_trace.lsu_en_ex = lsu_en_ex_i; - r_pipe_freeze_trace.lsu_pmp_err_ex = lsu_pmp_err_ex_i; + r_pipe_freeze_trace.lsu_en_ex = lsu_en_ex_i; + r_pipe_freeze_trace.lsu_pmp_err_ex = lsu_pmp_err_ex_i; r_pipe_freeze_trace.lsu_pma_err_atomic_ex = lsu_pma_err_atomic_ex_i; - r_pipe_freeze_trace.branch_target_ex = branch_target_ex_i; + r_pipe_freeze_trace.branch_target_ex = branch_target_ex_i; - r_pipe_freeze_trace.data_addr_ex = data_addr_ex_i; - r_pipe_freeze_trace.data_wdata_ex = data_wdata_ex_i; - r_pipe_freeze_trace.lsu_split_q_ex = lsu_split_q_ex_i; + r_pipe_freeze_trace.data_addr_ex = data_addr_ex_i; + r_pipe_freeze_trace.data_wdata_ex = data_wdata_ex_i; + r_pipe_freeze_trace.lsu_split_q_ex = lsu_split_q_ex_i; //// WB probes //// - r_pipe_freeze_trace.pc_wb = pc_wb_i; - r_pipe_freeze_trace.wb_ready = wb_ready_i; - r_pipe_freeze_trace.wb_valid = wb_valid_i; - r_pipe_freeze_trace.ebreak_in_wb = ebreak_in_wb_i; - r_pipe_freeze_trace.instr_rdata_wb = instr_rdata_wb_i; - r_pipe_freeze_trace.csr_en_wb = csr_en_wb_i; - r_pipe_freeze_trace.sys_wfi_insn_wb = sys_wfi_insn_wb_i; + r_pipe_freeze_trace.pc_wb = pc_wb_i; + r_pipe_freeze_trace.wb_ready = wb_ready_i; + r_pipe_freeze_trace.wb_valid = wb_valid_i; + r_pipe_freeze_trace.ebreak_in_wb = ebreak_in_wb_i; + r_pipe_freeze_trace.instr_rdata_wb = instr_rdata_wb_i; + r_pipe_freeze_trace.csr_en_wb = csr_en_wb_i; + r_pipe_freeze_trace.sys_wfi_insn_wb = sys_wfi_insn_wb_i; // Register writes - r_pipe_freeze_trace.rf_we_wb = rf_we_wb_i; - r_pipe_freeze_trace.rf_addr_wb = rf_addr_wb_i; - r_pipe_freeze_trace.rf_wdata_wb = rf_wdata_wb_i; + r_pipe_freeze_trace.rf_we_wb = rf_we_wb_i; + r_pipe_freeze_trace.rf_addr_wb = rf_addr_wb_i; + r_pipe_freeze_trace.rf_wdata_wb = rf_wdata_wb_i; + r_pipe_freeze_trace.rf_alu_we_ex = regfile_alu_we_ex_i; // LSU - r_pipe_freeze_trace.lsu_rdata_wb = lsu_rdata_wb_i; - - r_pipe_freeze_trace.data_we_ex = data_we_ex_i; - r_pipe_freeze_trace.data_atop_ex = data_atop_ex_i; - r_pipe_freeze_trace.data_type_ex = data_type_ex_i; - r_pipe_freeze_trace.alu_operand_c_ex = alu_operand_c_ex_i; - r_pipe_freeze_trace.data_reg_offset_ex = data_reg_offset_ex_i; - r_pipe_freeze_trace.data_load_event_ex = data_load_event_ex_i; - r_pipe_freeze_trace.data_sign_ext_ex = data_sign_ext_ex_i; - r_pipe_freeze_trace.lsu_rdata = lsu_rdata_i; - r_pipe_freeze_trace.data_req_ex = data_req_ex_i; - r_pipe_freeze_trace.alu_operand_a_ex = alu_operand_a_ex_i; - r_pipe_freeze_trace.alu_operand_b_ex = alu_operand_b_ex_i; - r_pipe_freeze_trace.useincr_addr_ex = useincr_addr_ex_i; - r_pipe_freeze_trace.data_misaligned_ex = data_misaligned_ex_i; - r_pipe_freeze_trace.p_elw_start = p_elw_start_i; - r_pipe_freeze_trace.p_elw_finish = p_elw_finish_i; - r_pipe_freeze_trace.lsu_ready_ex = lsu_ready_ex_i; - r_pipe_freeze_trace.lsu_ready_wb = lsu_ready_wb_i; - - r_pipe_freeze_trace.data_req_pmp = data_req_pmp_i; - r_pipe_freeze_trace.data_gnt_pmp = data_gnt_pmp_i; - r_pipe_freeze_trace.data_rvalid = data_rvalid_i; - r_pipe_freeze_trace.data_err_pmp = data_err_pmp_i; - r_pipe_freeze_trace.data_addr_pmp = data_addr_pmp_i; - r_pipe_freeze_trace.data_we = data_we_i; - r_pipe_freeze_trace.data_atop = data_atop_i; - r_pipe_freeze_trace.data_be = data_be_i; - r_pipe_freeze_trace.data_wdata = data_wdata_i; - r_pipe_freeze_trace.data_rdata = data_rdata_i; + r_pipe_freeze_trace.lsu_rdata_wb = lsu_rdata_wb_i; + + r_pipe_freeze_trace.data_we_ex = data_we_ex_i; + r_pipe_freeze_trace.data_atop_ex = data_atop_ex_i; + r_pipe_freeze_trace.data_type_ex = data_type_ex_i; + r_pipe_freeze_trace.alu_operand_c_ex = alu_operand_c_ex_i; + r_pipe_freeze_trace.data_reg_offset_ex = data_reg_offset_ex_i; + r_pipe_freeze_trace.data_load_event_ex = data_load_event_ex_i; + r_pipe_freeze_trace.data_sign_ext_ex = data_sign_ext_ex_i; + r_pipe_freeze_trace.lsu_rdata = lsu_rdata_i; + r_pipe_freeze_trace.data_req_ex = data_req_ex_i; + r_pipe_freeze_trace.alu_operand_a_ex = alu_operand_a_ex_i; + r_pipe_freeze_trace.alu_operand_b_ex = alu_operand_b_ex_i; + r_pipe_freeze_trace.useincr_addr_ex = useincr_addr_ex_i; + r_pipe_freeze_trace.data_misaligned_ex = data_misaligned_ex_i; + r_pipe_freeze_trace.p_elw_start = p_elw_start_i; + r_pipe_freeze_trace.p_elw_finish = p_elw_finish_i; + r_pipe_freeze_trace.lsu_ready_ex = lsu_ready_ex_i; + r_pipe_freeze_trace.lsu_ready_wb = lsu_ready_wb_i; + r_pipe_freeze_trace.lsu_data_be = lsu_data_be_i; + + r_pipe_freeze_trace.data_req_pmp = data_req_pmp_i; + r_pipe_freeze_trace.data_gnt_pmp = data_gnt_pmp_i; + r_pipe_freeze_trace.data_rvalid = data_rvalid_i; + r_pipe_freeze_trace.data_err_pmp = data_err_pmp_i; + r_pipe_freeze_trace.data_addr_pmp = data_addr_pmp_i; + r_pipe_freeze_trace.data_we = data_we_i; + r_pipe_freeze_trace.data_atop = data_atop_i; + r_pipe_freeze_trace.data_be = data_be_i; + r_pipe_freeze_trace.data_wdata = data_wdata_i; + r_pipe_freeze_trace.data_rdata = data_rdata_i; //// APU //// - r_pipe_freeze_trace.apu_req = apu_req_i; - r_pipe_freeze_trace.apu_gnt = apu_gnt_i; - r_pipe_freeze_trace.apu_rvalid = apu_rvalid_i; + r_pipe_freeze_trace.apu_req = apu_req_i; + r_pipe_freeze_trace.apu_gnt = apu_gnt_i; + r_pipe_freeze_trace.apu_rvalid = apu_rvalid_i; // PC // - r_pipe_freeze_trace.branch_addr_n = branch_addr_n_i; + r_pipe_freeze_trace.branch_addr_n = branch_addr_n_i; // Controller FSM probes - r_pipe_freeze_trace.ctrl_fsm_cs = ctrl_fsm_cs_i; - r_pipe_freeze_trace.pc_mux = pc_mux_i; - r_pipe_freeze_trace.exc_pc_mux = exc_pc_mux_i; + r_pipe_freeze_trace.ctrl_fsm_cs = ctrl_fsm_cs_i; + r_pipe_freeze_trace.pc_mux = pc_mux_i; + r_pipe_freeze_trace.exc_pc_mux = exc_pc_mux_i; // CSR - r_pipe_freeze_trace.csr.addr = csr_addr_i; - r_pipe_freeze_trace.csr.we = csr_we_i; - r_pipe_freeze_trace.csr.wdata_int = csr_wdata_int_i; - - r_pipe_freeze_trace.csr.jvt_we = csr_jvt_we_i; - r_pipe_freeze_trace.csr.mstatus_n = csr_mstatus_n_i; - r_pipe_freeze_trace.csr.mstatus_q = csr_mstatus_q_i; - r_pipe_freeze_trace.csr.mstatus_fs_n = csr_mstatus_fs_n_i; - r_pipe_freeze_trace.csr.mstatus_fs_q = csr_mstatus_fs_q_i; - - if (FPU == 1 && ZFINX == 0) begin - r_pipe_freeze_trace.csr.mstatus_full_q[31] = (r_pipe_freeze_trace.csr.mstatus_fs_q == FS_DIRTY) ? 1'b1 : 1'b0; - end else begin - r_pipe_freeze_trace.csr.mstatus_full_q[31] = '0; - end - r_pipe_freeze_trace.csr.mstatus_full_q[30:18] = '0; - r_pipe_freeze_trace.csr.mstatus_full_q[17] = r_pipe_freeze_trace.csr.mstatus_q.mprv; - r_pipe_freeze_trace.csr.mstatus_full_q[16:15] = '0; - if (FPU == 1 && ZFINX == 0) begin - r_pipe_freeze_trace.csr.mstatus_full_q[14:13] = r_pipe_freeze_trace.csr.mstatus_fs_q; - end else begin - r_pipe_freeze_trace.csr.mstatus_full_q[14:13] = '0; - end - r_pipe_freeze_trace.csr.mstatus_full_q[12:11] = r_pipe_freeze_trace.csr.mstatus_q.mpp; - r_pipe_freeze_trace.csr.mstatus_full_q[10:8] = '0; - r_pipe_freeze_trace.csr.mstatus_full_q[7] = r_pipe_freeze_trace.csr.mstatus_q.mpie; - r_pipe_freeze_trace.csr.mstatus_full_q[6:5] = '0; - r_pipe_freeze_trace.csr.mstatus_full_q[4] = r_pipe_freeze_trace.csr.mstatus_q.upie; - r_pipe_freeze_trace.csr.mstatus_full_q[3] = r_pipe_freeze_trace.csr.mstatus_q.mie; - r_pipe_freeze_trace.csr.mstatus_full_q[2:1] = '0; - r_pipe_freeze_trace.csr.mstatus_full_q[0] = r_pipe_freeze_trace.csr.mstatus_q.uie; - - if (FPU == 1 && ZFINX == 0) begin - r_pipe_freeze_trace.csr.mstatus_full_n[31] = (r_pipe_freeze_trace.csr.mstatus_fs_n == FS_DIRTY) ? 1'b1 : 1'b0; - end else begin - r_pipe_freeze_trace.csr.mstatus_full_n[31] = '0; - end - r_pipe_freeze_trace.csr.mstatus_full_n[30:18] = '0; - r_pipe_freeze_trace.csr.mstatus_full_n[17] = r_pipe_freeze_trace.csr.mstatus_n.mprv; - r_pipe_freeze_trace.csr.mstatus_full_n[16:15] = '0; - if (FPU == 1 && ZFINX == 0) begin - r_pipe_freeze_trace.csr.mstatus_full_n[14:13] = r_pipe_freeze_trace.csr.mstatus_fs_n; - end else begin - r_pipe_freeze_trace.csr.mstatus_full_n[14:13] = '0; - end - r_pipe_freeze_trace.csr.mstatus_full_n[12:11] = r_pipe_freeze_trace.csr.mstatus_n.mpp; - r_pipe_freeze_trace.csr.mstatus_full_n[10:8] = '0; - r_pipe_freeze_trace.csr.mstatus_full_n[7] = r_pipe_freeze_trace.csr.mstatus_n.mpie; - r_pipe_freeze_trace.csr.mstatus_full_n[6:5] = '0; - r_pipe_freeze_trace.csr.mstatus_full_n[4] = r_pipe_freeze_trace.csr.mstatus_n.upie; - r_pipe_freeze_trace.csr.mstatus_full_n[3] = r_pipe_freeze_trace.csr.mstatus_n.mie; - r_pipe_freeze_trace.csr.mstatus_full_n[2:1] = '0; - r_pipe_freeze_trace.csr.mstatus_full_n[0] = r_pipe_freeze_trace.csr.mstatus_n.uie; + r_pipe_freeze_trace.csr.addr = csr_addr_i; + r_pipe_freeze_trace.csr.we = csr_we_i; + r_pipe_freeze_trace.csr.wdata_int = csr_wdata_int_i; + + r_pipe_freeze_trace.csr.jvt_we = csr_jvt_we_i; + r_pipe_freeze_trace.csr.mstatus_n = csr_mstatus_n_i; + r_pipe_freeze_trace.csr.mstatus_q = csr_mstatus_q_i; + r_pipe_freeze_trace.csr.mstatus_fs_n = csr_mstatus_fs_n_i; + r_pipe_freeze_trace.csr.mstatus_fs_q = csr_mstatus_fs_q_i; r_pipe_freeze_trace.csr.mstatush_we = csr_mstatush_we_i; r_pipe_freeze_trace.csr.misa_n = csr_misa_n_i; @@ -676,10 +645,21 @@ task monitor_pipeline(); r_pipe_freeze_trace.hwloop.counter_n = hwlp_counter_n_i; compute_csr_we(); + + //If fcsr_we has triggered, then fflags_we and frm_we should also be triggered + if (r_pipe_freeze_trace.csr.fcsr_we) begin + r_pipe_freeze_trace.csr.fflags_we = 1'b1; + r_pipe_freeze_trace.csr.frm_we = 1'b1; + end else begin + if (r_pipe_freeze_trace.csr.fflags_we || r_pipe_freeze_trace.csr.frm_we) begin + r_pipe_freeze_trace.csr.fcsr_we = 1'b1; + end + end + if (csr_fcsr_fflags_we_i) begin - r_pipe_freeze_trace.csr.fflags_we = 1'b1; - r_pipe_freeze_trace.csr.fcsr_we = 1'b1; - r_pipe_freeze_trace.csr.mstatus_we = 1'b1; + r_pipe_freeze_trace.csr.fflags_we = 1'b1; + r_pipe_freeze_trace.csr.fcsr_we = 1'b1; + r_pipe_freeze_trace.csr.mstatus_fs_we = 1'b1; end ->e_pipe_monitor_ok; diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_apu_disp.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_apu_disp.sv index 51d323781..a94df1aad 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_apu_disp.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_apu_disp.sv @@ -47,6 +47,7 @@ module cv32e40px_apu_disp ( input logic [2:0][5:0] read_regs_i, input logic [2:0] read_regs_valid_i, output logic read_dep_o, + output logic read_dep_for_jalr_o, input logic [1:0][5:0] write_regs_i, input logic [1:0] write_regs_valid_i, @@ -189,6 +190,10 @@ module cv32e40px_apu_disp ( assign read_dep_o = (read_dep_req | read_dep_inflight | read_dep_waiting) & is_decoding_i; assign write_dep_o = (write_dep_req | write_dep_inflight | write_dep_waiting) & is_decoding_i; + assign read_dep_for_jalr_o = is_decoding_i & ((|read_deps_req & enable_i) | + (|read_deps_inflight & valid_inflight) | + (|read_deps_waiting & valid_waiting)); + // // Stall signals // diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_controller.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_controller.sv index a5b611d16..6516f9321 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_controller.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_controller.sv @@ -31,7 +31,8 @@ module cv32e40px_controller import cv32e40px_pkg::*; #( parameter COREV_CLUSTER = 0, - parameter COREV_PULP = 1 + parameter COREV_PULP = 0, + parameter FPU = 0 ) ( input logic clk, // Gated clock @@ -47,7 +48,6 @@ module cv32e40px_controller import cv32e40px_pkg::*; output logic deassert_we_o, // deassert write enable for next instruction input logic illegal_insn_i, // xif confirmed the invalid instruction - input logic illegal_insn_dec_i, // decoder encountered an invalid instruction input logic ecall_insn_i, // decoder encountered an ecall instruction input logic mret_insn_i, // decoder encountered an mret instruction input logic uret_insn_i, // decoder encountered an uret instruction @@ -79,7 +79,6 @@ module cv32e40px_controller import cv32e40px_pkg::*; // HWLoop signls input logic [31:0] pc_id_i, - input logic is_compressed_i, // from hwloop_regs input logic [1:0] [31:0] hwlp_start_addr_i, @@ -106,6 +105,7 @@ module cv32e40px_controller import cv32e40px_pkg::*; // APU dependency checks input logic apu_en_i, input logic apu_read_dep_i, + input logic apu_read_dep_for_jalr_i, input logic apu_write_dep_i, output logic apu_stall_o, @@ -209,13 +209,13 @@ module cv32e40px_controller import cv32e40px_pkg::*; // Debug state debug_state_e debug_fsm_cs, debug_fsm_ns; - logic jump_done, jump_done_q, jump_in_dec, branch_in_id_dec, branch_in_id; + logic jump_done, jump_done_q, jump_in_dec, branch_in_id; logic data_err_q; logic debug_mode_q, debug_mode_n; logic ebrk_force_debug_mode; - logic is_hwlp_illegal, is_hwlp_body; + logic is_hwlp_body; logic illegal_insn_q, illegal_insn_n; logic debug_req_entry_q, debug_req_entry_n; logic debug_force_wakeup_q, debug_force_wakeup_n; @@ -224,6 +224,10 @@ module cv32e40px_controller import cv32e40px_pkg::*; logic hwlp_end1_eq_pc; logic hwlp_counter0_gt_1; logic hwlp_counter1_gt_1; + logic hwlp_counter0_eq_1; + logic hwlp_counter1_eq_1; + logic hwlp_counter0_eq_0; + logic hwlp_counter1_eq_0; logic hwlp_end0_eq_pc_plus4; logic hwlp_end1_eq_pc_plus4; logic hwlp_start0_leq_pc; @@ -291,7 +295,6 @@ module cv32e40px_controller import cv32e40px_pkg::*; jump_in_dec = ctrl_transfer_insn_in_dec_i == BRANCH_JALR || ctrl_transfer_insn_in_dec_i == BRANCH_JAL; branch_in_id = ctrl_transfer_insn_in_id_i == BRANCH_COND; - branch_in_id_dec = ctrl_transfer_insn_in_dec_i == BRANCH_COND; ebrk_force_debug_mode = (debug_ebreakm_i && current_priv_lvl_i == PRIV_LVL_M) || (debug_ebreaku_i && current_priv_lvl_i == PRIV_LVL_U); @@ -316,8 +319,6 @@ module cv32e40px_controller import cv32e40px_pkg::*; hwlp_mask_o = 1'b0; - is_hwlp_illegal = 1'b0; - hwlp_dec_cnt_o = '0; hwlp_end_4_id_d = 1'b0; @@ -526,15 +527,13 @@ module cv32e40px_controller import cv32e40px_pkg::*; else begin - is_hwlp_illegal = is_hwlp_body & (jump_in_dec || branch_in_id_dec || mret_insn_i || uret_insn_i || dret_insn_i || is_compressed_i || fencei_insn_i || wfi_active); + if (illegal_insn_i) begin + + halt_if_o = 1'b1; + halt_id_o = 1'b0; + ctrl_fsm_ns = id_ready_i ? FLUSH_EX : DECODE; + illegal_insn_n = 1'b1; - if(illegal_insn_dec_i || is_hwlp_illegal) begin - if(illegal_insn_i) begin - halt_if_o = 1'b1; - halt_id_o = 1'b0; - ctrl_fsm_ns = id_ready_i ? FLUSH_EX : DECODE; - illegal_insn_n = 1'b1; - end end else begin //decoding block @@ -618,26 +617,34 @@ module cv32e40px_controller import cv32e40px_pkg::*; // we can be at the end of HWloop due to a return from interrupt or ecall or ebreak or exceptions if(hwlp_end0_eq_pc && hwlp_counter0_gt_1) begin - pc_mux_o = PC_HWLOOP; - if (~jump_done_q) begin - pc_set_o = 1'b1; - // Keep the instruction and the related address in the Aligner if - // ID is stalled during a jump - jump_done = 1'b1; - hwlp_dec_cnt_o[0] = 1'b1; - end - end - if(hwlp_end1_eq_pc && hwlp_counter1_gt_1) begin - pc_mux_o = PC_HWLOOP; - if (~jump_done_q) begin - pc_set_o = 1'b1; - // Keep the instruction and the related address in the Aligner if - // ID is stalled during a jump - jump_done = 1'b1; - hwlp_dec_cnt_o[1] = 1'b1; - end - end + pc_mux_o = PC_HWLOOP; + if (~jump_done_q) begin + pc_set_o = 1'b1; + // Keep the instruction and the related address in the Aligner if + // ID is stalled during a jump + jump_done = 1'b1; + hwlp_dec_cnt_o[0] = 1'b1; + end + end + if (hwlp_end1_eq_pc && hwlp_counter1_gt_1) begin + pc_mux_o = PC_HWLOOP; + if (~jump_done_q) begin + pc_set_o = 1'b1; + // Keep the instruction and the related address in the Aligner if + // ID is stalled during a jump + jump_done = 1'b1; + hwlp_dec_cnt_o[1] = 1'b1; + end end + end + + if (hwlp_end0_eq_pc && hwlp_counter0_eq_1) begin + hwlp_dec_cnt_o[0] = 1'b1; + end + if (hwlp_end1_eq_pc && hwlp_counter1_eq_1) begin + hwlp_dec_cnt_o[1] = 1'b1; + end + end endcase // unique case (1'b1) @@ -743,9 +750,7 @@ module cv32e40px_controller import cv32e40px_pkg::*; else begin - is_hwlp_illegal = (jump_in_dec || branch_in_id_dec || mret_insn_i || uret_insn_i || dret_insn_i || is_compressed_i || fencei_insn_i || wfi_active); - - if(illegal_insn_i || is_hwlp_illegal) begin + if (illegal_insn_i) begin halt_if_o = 1'b1; halt_id_o = 1'b1; @@ -813,8 +818,8 @@ module cv32e40px_controller import cv32e40px_pkg::*; ctrl_fsm_ns = is_hwlp_body ? DECODE_HWLOOP : DECODE; end - hwlp_dec_cnt_o[0] = hwlp_end0_eq_pc; - hwlp_dec_cnt_o[1] = hwlp_end1_eq_pc; + hwlp_dec_cnt_o[0] = hwlp_end0_eq_pc && !hwlp_counter0_eq_0; + hwlp_dec_cnt_o[1] = hwlp_end1_eq_pc && !hwlp_counter1_eq_0; end endcase // unique case (1'b1) @@ -1270,6 +1275,10 @@ generate assign hwlp_end1_eq_pc = hwlp_end_addr_i[1] == pc_id_i + 4; // Equivalent to hwlp_end_addr_i[1] - 4 == pc_id_i assign hwlp_counter0_gt_1 = hwlp_counter_i[0] > 1; assign hwlp_counter1_gt_1 = hwlp_counter_i[1] > 1; + assign hwlp_counter0_eq_1 = hwlp_counter_i[0] == 1; + assign hwlp_counter1_eq_1 = hwlp_counter_i[1] == 1; + assign hwlp_counter0_eq_0 = hwlp_counter_i[0] == 0; + assign hwlp_counter1_eq_0 = hwlp_counter_i[1] == 0; assign hwlp_end0_eq_pc_plus4 = hwlp_end_addr_i[0] == pc_id_i + 8; // Equivalent to hwlp_end_addr_i[0] - 4 == pc_id_i + 4 assign hwlp_end1_eq_pc_plus4 = hwlp_end_addr_i[1] == pc_id_i + 8; // Equivalent to hwlp_end_addr_i[1] - 4 == pc_id_i + 4 assign hwlp_start0_leq_pc = hwlp_start_addr_i[0] <= pc_id_i; @@ -1286,6 +1295,10 @@ generate assign hwlp_end1_eq_pc = 1'b0; assign hwlp_counter0_gt_1 = 1'b0; assign hwlp_counter1_gt_1 = 1'b0; + assign hwlp_counter0_eq_1 = 1'b0; + assign hwlp_counter1_eq_1 = 1'b0; + assign hwlp_counter0_eq_0 = 1'b0; + assign hwlp_counter1_eq_0 = 1'b0; assign hwlp_end0_eq_pc_plus4 = 1'b0; assign hwlp_end1_eq_pc_plus4 = 1'b0; assign hwlp_start0_leq_pc = 1'b0; @@ -1339,7 +1352,10 @@ endgenerate if ((ctrl_transfer_insn_in_dec_i == BRANCH_JALR) && (((regfile_we_wb_i == 1'b1) && (reg_d_wb_is_reg_a_i == 1'b1)) || ((regfile_we_ex_i == 1'b1) && (reg_d_ex_is_reg_a_i == 1'b1)) || - ((regfile_alu_we_fw_i == 1'b1) && (reg_d_alu_is_reg_a_i == 1'b1))) ) + ((regfile_alu_we_fw_i == 1'b1) && (reg_d_alu_is_reg_a_i == 1'b1)) || + (FPU && (apu_read_dep_for_jalr_i == 1'b1)) + ) + ) begin jr_stall_o = 1'b1; deassert_we_o = 1'b1; @@ -1552,10 +1568,11 @@ endgenerate property p_no_hwlp; @(posedge clk) (1'b1) |-> ((pc_mux_o != PC_HWLOOP) && (ctrl_fsm_cs != DECODE_HWLOOP) && - (hwlp_mask_o == 1'b0) && (is_hwlp_illegal == 'b0) && (is_hwlp_body == 'b0) && + (hwlp_mask_o == 1'b0) && (is_hwlp_body == 'b0) && (hwlp_start_addr_i == 'b0) && (hwlp_end_addr_i == 'b0) && (hwlp_counter_i[1] == 32'b0) && (hwlp_counter_i[0] == 32'b0) && (hwlp_dec_cnt_o == 2'b0) && (hwlp_jump_o == 1'b0) && (hwlp_targ_addr_o == 32'b0) && (hwlp_end0_eq_pc == 1'b0) && (hwlp_end1_eq_pc == 1'b0) && (hwlp_counter0_gt_1 == 1'b0) && (hwlp_counter1_gt_1 == 1'b0) && + (hwlp_counter0_eq_1 == 1'b0) && (hwlp_counter1_eq_1 == 1'b0) && (hwlp_end0_eq_pc_plus4 == 1'b0) && (hwlp_end1_eq_pc_plus4 == 1'b0) && (hwlp_start0_leq_pc == 0) && (hwlp_start1_leq_pc == 0) && (hwlp_end0_geq_pc == 1'b0) && (hwlp_end1_geq_pc == 1'b0) && (hwlp_end_4_id_d == 1'b0) && (hwlp_end_4_id_q == 1'b0)); endproperty diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_core.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_core.sv index 05da683c5..f0fc87967 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_core.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_core.sv @@ -249,6 +249,7 @@ module cv32e40px_core logic [ 2:0][ 5:0] apu_read_regs; logic [ 2:0] apu_read_regs_valid; logic apu_read_dep; + logic apu_read_dep_for_jalr; logic [ 1:0][ 5:0] apu_write_regs; logic [ 1:0] apu_write_regs_valid; logic apu_write_dep; @@ -405,7 +406,6 @@ module cv32e40px_core // APU master signals assign apu_flags_o = apu_flags_ex; - assign fflags_csr = apu_flags_i; assign x_mem_result_o.dbg = '0; @@ -676,14 +676,15 @@ module cv32e40px_core .apu_flags_ex_o (apu_flags_ex), .apu_waddr_ex_o (apu_waddr_ex), - .apu_read_regs_o (apu_read_regs), - .apu_read_regs_valid_o (apu_read_regs_valid), - .apu_read_dep_i (apu_read_dep), - .apu_write_regs_o (apu_write_regs), - .apu_write_regs_valid_o(apu_write_regs_valid), - .apu_write_dep_i (apu_write_dep), - .apu_perf_dep_o (perf_apu_dep), - .apu_busy_i (apu_busy), + .apu_read_regs_o (apu_read_regs), + .apu_read_regs_valid_o (apu_read_regs_valid), + .apu_read_dep_i (apu_read_dep), + .apu_read_dep_for_jalr_i(apu_read_dep_for_jalr), + .apu_write_regs_o (apu_write_regs), + .apu_write_regs_valid_o (apu_write_regs_valid), + .apu_write_dep_i (apu_write_dep), + .apu_perf_dep_o (perf_apu_dep), + .apu_busy_i (apu_busy), // CORE-V-XIF // Compressed Interface @@ -869,8 +870,14 @@ module cv32e40px_core .mult_multicycle_o(mult_multicycle), // to ID/EX pipe registers + .data_req_i (data_req_o), // from ID/EX pipeline + .data_rvalid_i (data_rvalid_i), // from ID/EX pipeline + .data_misaligned_ex_i(data_misaligned_ex), // from ID/EX pipeline + .data_misaligned_i (data_misaligned), + // FPU .fpu_fflags_we_o(fflags_we), + .fpu_fflags_o (fflags_csr), // APU .apu_en_i (apu_en_ex), @@ -878,14 +885,14 @@ module cv32e40px_core .apu_lat_i (apu_lat_ex), .apu_operands_i(apu_operands_ex), .apu_waddr_i (apu_waddr_ex), - .apu_flags_i (apu_flags_ex), - .apu_read_regs_i (apu_read_regs), - .apu_read_regs_valid_i (apu_read_regs_valid), - .apu_read_dep_o (apu_read_dep), - .apu_write_regs_i (apu_write_regs), - .apu_write_regs_valid_i(apu_write_regs_valid), - .apu_write_dep_o (apu_write_dep), + .apu_read_regs_i (apu_read_regs), + .apu_read_regs_valid_i (apu_read_regs_valid), + .apu_read_dep_o (apu_read_dep), + .apu_read_dep_for_jalr_o(apu_read_dep_for_jalr), + .apu_write_regs_i (apu_write_regs), + .apu_write_regs_valid_i (apu_write_regs_valid), + .apu_write_dep_o (apu_write_dep), .apu_perf_type_o(perf_apu_type), .apu_perf_cont_o(perf_apu_cont), @@ -903,6 +910,7 @@ module cv32e40px_core // response channel .apu_rvalid_i (apu_rvalid_i), .apu_result_i (apu_result_i), + .apu_flags_i (apu_flags_i), // X-Interface .x_result_valid_assigned_i(x_result_valid_assigned), @@ -1003,8 +1011,6 @@ module cv32e40px_core .data_misaligned_ex_i(data_misaligned_ex), // from ID/EX pipeline .data_misaligned_o (data_misaligned), - .apu_busy_i(apu_busy), - .p_elw_start_o (p_elw_start), .p_elw_finish_o(p_elw_finish), diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_cs_registers.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_cs_registers.sv index cdc64338b..2d8734527 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_cs_registers.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_cs_registers.sv @@ -505,8 +505,13 @@ module cv32e40px_cs_registers // marchid: Machine Architecture ID CSR_MARCHID: csr_rdata_int = MARCHID; + // mimpid, Machine Implementation ID + CSR_MIMPID: begin + csr_rdata_int = (FPU || COREV_PULP || COREV_CLUSTER) ? 32'h1 : 'b0; + end + // unimplemented, read 0 CSRs - CSR_MIMPID, CSR_MTVAL: csr_rdata_int = 'b0; + CSR_MTVAL: csr_rdata_int = 'b0; CSR_TSELECT, CSR_TDATA3, CSR_MCONTEXT, CSR_SCONTEXT: csr_rdata_int = 'b0; // Always read 0 CSR_TDATA1: csr_rdata_int = tmatch_control_rdata; diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_ex_stage.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_ex_stage.sv index 0ec00997e..6ab1b01b3 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_ex_stage.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_ex_stage.sv @@ -77,8 +77,14 @@ module cv32e40px_ex_stage output logic mult_multicycle_o, + input logic data_req_i, + input logic data_rvalid_i, + input logic data_misaligned_ex_i, + input logic data_misaligned_i, + // FPU signals output logic fpu_fflags_we_o, + output logic [APU_NUSFLAGS_CPU-1:0] fpu_fflags_o, // APU signals input logic apu_en_i, @@ -86,11 +92,12 @@ module cv32e40px_ex_stage input logic [ 1:0] apu_lat_i, input logic [ APU_NARGS_CPU-1:0][31:0] apu_operands_i, input logic [ 5:0] apu_waddr_i, - input logic [APU_NDSFLAGS_CPU-1:0] apu_flags_i, + input logic [APU_NUSFLAGS_CPU-1:0] apu_flags_i, input logic [2:0][5:0] apu_read_regs_i, input logic [2:0] apu_read_regs_valid_i, output logic apu_read_dep_o, + output logic apu_read_dep_for_jalr_o, input logic [1:0][5:0] apu_write_regs_i, input logic [1:0] apu_write_regs_valid_i, output logic apu_write_dep_o, @@ -157,7 +164,7 @@ module cv32e40px_ex_stage output logic branch_decision_o, // Stall Control - input logic is_decoding_i, // Used to mask data Dependency inside the APU dispatcher in case of an istruction non valid + input logic is_decoding_i, // Used to mask data Dependency inside the APU dispatcher in case of an istruction non valid input logic lsu_ready_ex_i, // EX part of LSU is done input logic lsu_err_i, @@ -166,29 +173,34 @@ module cv32e40px_ex_stage input logic wb_ready_i // WB stage ready for new data ); - logic [31:0] alu_result; - logic [31:0] mult_result; - logic alu_cmp_result; + logic [ 31:0] alu_result; + logic [ 31:0] mult_result; + logic alu_cmp_result; - logic regfile_we_lsu; - logic [ 5:0] regfile_waddr_lsu; + logic regfile_we_lsu; + logic [ 5:0] regfile_waddr_lsu; - logic wb_contention; - logic wb_contention_lsu; + logic wb_contention; + logic wb_contention_lsu; - logic alu_ready; - logic mult_ready; + logic alu_ready; + logic mulh_active; + logic mult_ready; // APU signals - logic apu_valid; - logic [ 5:0] apu_waddr; - logic [31:0] apu_result; - logic apu_stall; - logic apu_active; - logic apu_singlecycle; - logic apu_multicycle; - logic apu_req; - logic apu_gnt; + logic apu_valid; + logic [ 5:0] apu_waddr; + logic [ 31:0] apu_result; + logic apu_stall; + logic apu_active; + logic apu_singlecycle; + logic apu_multicycle; + logic apu_req; + logic apu_gnt; + + logic apu_rvalid_q; + logic [ 31:0] apu_result_q; + logic [APU_NUSFLAGS_CPU-1:0] apu_flags_q; // ALU write port mux always_comb begin @@ -330,9 +342,10 @@ module cv32e40px_ex_stage .result_o(mult_result), - .multicycle_o(mult_multicycle_o), - .ready_o (mult_ready), - .ex_ready_i (ex_ready_o) + .multicycle_o (mult_multicycle_o), + .mulh_active_o(mulh_active), + .ready_o (mult_ready), + .ex_ready_i (ex_ready_o) ); generate @@ -361,13 +374,14 @@ module cv32e40px_ex_stage .active_o(apu_active), .stall_o (apu_stall), - .is_decoding_i (is_decoding_i), - .read_regs_i (apu_read_regs_i), - .read_regs_valid_i (apu_read_regs_valid_i), - .read_dep_o (apu_read_dep_o), - .write_regs_i (apu_write_regs_i), - .write_regs_valid_i(apu_write_regs_valid_i), - .write_dep_o (apu_write_dep_o), + .is_decoding_i (is_decoding_i), + .read_regs_i (apu_read_regs_i), + .read_regs_valid_i (apu_read_regs_valid_i), + .read_dep_o (apu_read_dep_o), + .read_dep_for_jalr_o(apu_read_dep_for_jalr_o), + .write_regs_i (apu_write_regs_i), + .write_regs_valid_i (apu_write_regs_valid_i), + .write_dep_o (apu_write_dep_o), .perf_type_o(apu_perf_type_o), .perf_cont_o(apu_perf_cont_o), @@ -380,40 +394,61 @@ module cv32e40px_ex_stage .apu_rvalid_i(apu_valid) ); - assign apu_perf_wb_o = wb_contention | wb_contention_lsu; - assign apu_ready_wb_o = ~(apu_active | apu_en_i | apu_stall) | apu_valid; + assign apu_perf_wb_o = wb_contention | wb_contention_lsu; + assign apu_ready_wb_o = ~(apu_active | apu_en_i | apu_stall) | apu_valid; + + /////////////////////////////////////// + // APU result memorization Register // + /////////////////////////////////////// + always_ff @(posedge clk, negedge rst_n) begin : APU_Result_Memorization + if (~rst_n) begin + apu_rvalid_q <= 1'b0; + apu_result_q <= 'b0; + apu_flags_q <= 'b0; + end else begin + if (apu_rvalid_i && apu_multicycle && (data_misaligned_i || data_misaligned_ex_i || (data_req_i && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)))) begin + apu_rvalid_q <= 1'b1; + apu_result_q <= apu_result_i; + apu_flags_q <= apu_flags_i; + end else if (apu_rvalid_q && !(data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)))) begin + apu_rvalid_q <= 1'b0; + end + end + end - assign apu_req_o = apu_req; - assign apu_gnt = apu_gnt_i; - assign apu_valid = apu_rvalid_i; - assign apu_operands_o = apu_operands_i; - assign apu_op_o = apu_op_i; - assign apu_result = apu_result_i; + assign apu_req_o = apu_req; + assign apu_gnt = apu_gnt_i; + assign apu_valid = (apu_multicycle && (data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)))) ? 1'b0 : (apu_rvalid_i || apu_rvalid_q); + assign apu_operands_o = apu_operands_i; + assign apu_op_o = apu_op_i; + assign apu_result = apu_rvalid_q ? apu_result_q : apu_result_i; assign fpu_fflags_we_o = apu_valid; + assign fpu_fflags_o = apu_rvalid_q ? apu_flags_q : apu_flags_i; end else begin : gen_no_apu // default assignements for the case when no FPU/APU is attached. - assign apu_req_o = '0; - assign apu_operands_o[0] = '0; - assign apu_operands_o[1] = '0; - assign apu_operands_o[2] = '0; - assign apu_op_o = '0; - assign apu_req = 1'b0; - assign apu_gnt = 1'b0; - assign apu_result = 32'b0; - assign apu_valid = 1'b0; - assign apu_waddr = 6'b0; - assign apu_stall = 1'b0; - assign apu_active = 1'b0; - assign apu_ready_wb_o = 1'b1; - assign apu_perf_wb_o = 1'b0; - assign apu_perf_cont_o = 1'b0; - assign apu_perf_type_o = 1'b0; - assign apu_singlecycle = 1'b0; - assign apu_multicycle = 1'b0; - assign apu_read_dep_o = 1'b0; - assign apu_write_dep_o = 1'b0; - assign fpu_fflags_we_o = 1'b0; - + assign apu_req_o = '0; + assign apu_operands_o[0] = '0; + assign apu_operands_o[1] = '0; + assign apu_operands_o[2] = '0; + assign apu_op_o = '0; + assign apu_req = 1'b0; + assign apu_gnt = 1'b0; + assign apu_result = 32'b0; + assign apu_valid = 1'b0; + assign apu_waddr = 6'b0; + assign apu_stall = 1'b0; + assign apu_active = 1'b0; + assign apu_ready_wb_o = 1'b1; + assign apu_perf_wb_o = 1'b0; + assign apu_perf_cont_o = 1'b0; + assign apu_perf_type_o = 1'b0; + assign apu_singlecycle = 1'b0; + assign apu_multicycle = 1'b0; + assign apu_read_dep_o = 1'b0; + assign apu_read_dep_for_jalr_o = 1'b0; + assign apu_write_dep_o = 1'b0; + assign fpu_fflags_o = '0; + assign fpu_fflags_we_o = '0; end endgenerate diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_id_stage.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_id_stage.sv index e3b6640d9..50df28a0b 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_id_stage.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_id_stage.sv @@ -148,6 +148,7 @@ module cv32e40px_id_stage output logic [2:0][5:0] apu_read_regs_o, output logic [2:0] apu_read_regs_valid_o, input logic apu_read_dep_i, + input logic apu_read_dep_for_jalr_i, output logic [1:0][5:0] apu_write_regs_o, output logic [1:0] apu_write_regs_valid_o, input logic apu_write_dep_i, @@ -860,11 +861,17 @@ module cv32e40px_id_stage // dependency checks always_comb begin unique case (alu_op_a_mux_sel) + OP_A_CURRPC: begin + if (ctrl_transfer_target_mux_sel == JT_JALR) begin + apu_read_regs[0] = regfile_addr_ra_id; + apu_read_regs_valid[0] = 1'b1; + end + end // OP_A_CURRPC: OP_A_REGA_OR_FWD: begin apu_read_regs[0] = regfile_addr_ra_id; apu_read_regs_valid[0] = 1'b1; end // OP_A_REGA_OR_FWD: - OP_A_REGB_OR_FWD: begin + OP_A_REGB_OR_FWD, OP_A_REGC_OR_FWD: begin apu_read_regs[0] = regfile_addr_rb_id; apu_read_regs_valid[0] = 1'b1; end @@ -881,7 +888,7 @@ module cv32e40px_id_stage apu_read_regs[1] = regfile_addr_ra_id; apu_read_regs_valid[1] = 1'b1; end - OP_B_REGB_OR_FWD: begin + OP_B_REGB_OR_FWD, OP_B_BMASK: begin apu_read_regs[1] = regfile_addr_rb_id; apu_read_regs_valid[1] = 1'b1; end @@ -889,6 +896,15 @@ module cv32e40px_id_stage apu_read_regs[1] = regfile_addr_rc_id; apu_read_regs_valid[1] = 1'b1; end + OP_B_IMM: begin + if (alu_bmask_b_mux_sel == BMASK_B_REG) begin + apu_read_regs[1] = regfile_addr_rb_id; + apu_read_regs_valid[1] = 1'b1; + end else begin + apu_read_regs[1] = regfile_addr_rb_id; + apu_read_regs_valid[1] = 1'b0; + end + end default: begin apu_read_regs[1] = regfile_addr_rb_id; apu_read_regs_valid[1] = 1'b0; @@ -903,8 +919,15 @@ module cv32e40px_id_stage apu_read_regs_valid[2] = 1'b1; end OP_C_REGC_OR_FWD: begin - apu_read_regs[2] = regfile_addr_rc_id; - apu_read_regs_valid[2] = 1'b1; + if ((alu_op_a_mux_sel != OP_A_REGC_OR_FWD) && (ctrl_transfer_target_mux_sel != JT_JALR) && + !((alu_op_b_mux_sel == OP_B_IMM) && (alu_bmask_b_mux_sel == BMASK_B_REG)) && + !(alu_op_b_mux_sel == OP_B_BMASK)) begin + apu_read_regs[2] = regfile_addr_rc_id; + apu_read_regs_valid[2] = 1'b1; + end else begin + apu_read_regs[2] = regfile_addr_rc_id; + apu_read_regs_valid[2] = 1'b0; + end end default: begin apu_read_regs[2] = regfile_addr_rc_id; @@ -1297,7 +1320,8 @@ module cv32e40px_id_stage cv32e40px_controller #( .COREV_CLUSTER(COREV_CLUSTER), - .COREV_PULP (COREV_PULP) + .COREV_PULP (COREV_PULP), + .FPU (FPU) ) controller_i ( .clk (clk), // Gated clock .clk_ungated_i(clk_ungated_i), // Ungated clock @@ -1312,7 +1336,6 @@ module cv32e40px_id_stage .deassert_we_o(deassert_we), .illegal_insn_i(illegal_insn), - .illegal_insn_dec_i(illegal_insn_dec), .ecall_insn_i (ecall_insn_dec), .mret_insn_i (mret_insn_dec), .uret_insn_i (uret_insn_dec), @@ -1345,8 +1368,7 @@ module cv32e40px_id_stage .trap_addr_mux_o(trap_addr_mux_o), // HWLoop signls - .pc_id_i (pc_id_i), - .is_compressed_i(is_compressed_i), + .pc_id_i(pc_id_i), .hwlp_start_addr_i(hwlp_start_o), .hwlp_end_addr_i (hwlp_end_o), @@ -1368,9 +1390,10 @@ module cv32e40px_id_stage .mult_multicycle_i(mult_multicycle_i), // APU - .apu_en_i (apu_en), - .apu_read_dep_i (apu_read_dep_i), - .apu_write_dep_i(apu_write_dep_i), + .apu_en_i (apu_en), + .apu_read_dep_i (apu_read_dep_i), + .apu_read_dep_for_jalr_i(apu_read_dep_for_jalr_i), + .apu_write_dep_i (apu_write_dep_i), .apu_stall_o(apu_stall), diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_load_store_unit.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_load_store_unit.sv index eea0f05f9..674da6647 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_load_store_unit.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_load_store_unit.sv @@ -59,8 +59,6 @@ module cv32e40px_load_store_unit #( input logic data_misaligned_ex_i, // misaligned access in last ld/st -> from ID/EX pipeline output logic data_misaligned_o, // misaligned access was detected -> to controller - input logic apu_busy_i, - input logic [5:0] data_atop_ex_i, // atomic instructions signal -> from ex stage output logic [5:0] data_atop_o, // atomic instruction signal -> core output @@ -76,8 +74,6 @@ module cv32e40px_load_store_unit #( localparam DEPTH = 2; // Maximum number of outstanding transactions - logic data_req_ex_filtered; // data request from ex stage filtered when it is misaligned and there is an on-going APU instruction - // Transaction request (to cv32e40px_obi_interface) logic trans_valid; logic trans_ready; @@ -352,14 +348,12 @@ module cv32e40px_load_store_unit #( // Busy if there are ongoing (or potentially outstanding) transfers assign busy_o = (cnt_q != 2'b00) || trans_valid; - assign data_req_ex_filtered = data_req_ex_i & !(apu_busy_i & (data_misaligned_o | data_misaligned_ex_i)); - ////////////////////////////////////////////////////////////////////////////// // Transaction request generation // // Assumes that corresponding response is at least 1 cycle after request // - // - Only request transaction when EX stage requires data transfer (data_req_ex_filtered), and + // - Only request transaction when EX stage requires data transfer (data_req_ex_i), and // - maximum number of outstanding transactions will not be exceeded (cnt_q < DEPTH) ////////////////////////////////////////////////////////////////////////////// @@ -376,12 +370,12 @@ module cv32e40px_load_store_unit #( // OBI compatible (avoids combinatorial path from data_rvalid_i to data_req_o). // Multiple trans_* transactions can be issued (and accepted) before a response // (resp_*) is received. - assign trans_valid = data_req_ex_filtered && (cnt_q < DEPTH); + assign trans_valid = data_req_ex_i && (cnt_q < DEPTH); end else begin : gen_pulp_obi // Legacy PULP OBI behavior, i.e. only issue subsequent transaction if preceding transfer // is about to finish (re-introducing timing critical path from data_rvalid_i to data_req_o) - assign trans_valid = (cnt_q == 2'b00) ? data_req_ex_filtered && (cnt_q < DEPTH) : - data_req_ex_filtered && (cnt_q < DEPTH) && resp_valid; + assign trans_valid = (cnt_q == 2'b00) ? data_req_ex_i && (cnt_q < DEPTH) : + data_req_ex_i && (cnt_q < DEPTH) && resp_valid; end endgenerate @@ -391,7 +385,7 @@ module cv32e40px_load_store_unit #( // LSU EX stage readyness requires two criteria to be met: // - // - A data request (data_req_ex_filtered) has been forwarded/accepted (trans_valid && trans_ready) + // - A data request (data_req_ex_i) has been forwarded/accepted (trans_valid && trans_ready) // - The LSU WB stage is available such that EX and WB can be updated in lock step // // Default (if there is not even a data request) LSU EX is signaled to be ready, else @@ -400,11 +394,10 @@ module cv32e40px_load_store_unit #( // in case there is already at least one outstanding transaction (so WB is full) the EX // and WB stage can only signal readiness in lock step (so resp_valid is used as well). - assign lsu_ready_ex_o = !(apu_busy_i & (data_misaligned_o | data_misaligned_ex_i)) & - ((data_req_ex_i == 1'b0) ? 1'b1 : - (cnt_q == 2'b00) ? ( trans_valid && trans_ready) : - (cnt_q == 2'b01) ? (resp_valid && trans_valid && trans_ready) : - resp_valid); + assign lsu_ready_ex_o = (data_req_ex_i == 1'b0) ? 1'b1 : + (cnt_q == 2'b00) ? ( trans_valid && trans_ready) : + (cnt_q == 2'b01) ? (resp_valid && trans_valid && trans_ready) : + resp_valid; // Update signals for EX/WB registers (when EX has valid data itself and is ready for next) assign ctrl_update = lsu_ready_ex_o && data_req_ex_i; diff --git a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_mult.sv b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_mult.sv index 4929ccb49..8006c95e7 100644 --- a/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_mult.sv +++ b/hw/vendor/esl_epfl_cv32e40px/rtl/cv32e40px_mult.sv @@ -55,6 +55,7 @@ module cv32e40px_mult output logic [31:0] result_o, output logic multicycle_o, + output logic mulh_active_o, output logic ready_o, input logic ex_ready_i ); @@ -87,7 +88,6 @@ module cv32e40px_mult logic [ 1:0] mulh_signed; logic mulh_shift_arith; logic mulh_carry_q; - logic mulh_active; logic mulh_save; logic mulh_clearcarry; logic mulh_ready; @@ -105,7 +105,7 @@ module cv32e40px_mult assign short_op_a[16] = short_signed[0] & short_op_a[15]; assign short_op_b[16] = short_signed[1] & short_op_b[15]; - assign short_op_c = mulh_active ? $signed({mulh_carry_q, op_c_i}) : $signed(op_c_i); + assign short_op_c = mulh_active_o ? $signed({mulh_carry_q, op_c_i}) : $signed(op_c_i); assign short_mul = $signed(short_op_a) * $signed(short_op_b); assign short_mac = $signed(short_op_c) + $signed(short_mul) + $signed(short_round); @@ -116,13 +116,13 @@ module cv32e40px_mult ) >>> short_imm; // choose between normal short multiplication operation and mulh operation - assign short_imm = mulh_active ? mulh_imm : imm_i; - assign short_subword = mulh_active ? mulh_subword : {2{short_subword_i}}; - assign short_signed = mulh_active ? mulh_signed : short_signed_i; - assign short_shift_arith = mulh_active ? mulh_shift_arith : short_signed_i[0]; + assign short_imm = mulh_active_o ? mulh_imm : imm_i; + assign short_subword = mulh_active_o ? mulh_subword : {2{short_subword_i}}; + assign short_signed = mulh_active_o ? mulh_signed : short_signed_i; + assign short_shift_arith = mulh_active_o ? mulh_shift_arith : short_signed_i[0]; - assign short_mac_msb1 = mulh_active ? short_mac[33] : short_mac[31]; - assign short_mac_msb0 = mulh_active ? short_mac[32] : short_mac[31]; + assign short_mac_msb1 = mulh_active_o ? short_mac[33] : short_mac[31]; + assign short_mac_msb0 = mulh_active_o ? short_mac[32] : short_mac[31]; always_comb begin @@ -132,16 +132,16 @@ module cv32e40px_mult mulh_signed = 2'b00; mulh_shift_arith = 1'b0; mulh_ready = 1'b0; - mulh_active = 1'b1; + mulh_active_o = 1'b1; mulh_save = 1'b0; mulh_clearcarry = 1'b0; multicycle_o = 1'b0; case (mulh_CS) IDLE_MULT: begin - mulh_active = 1'b0; - mulh_ready = 1'b1; - mulh_save = 1'b0; + mulh_active_o = 1'b0; + mulh_ready = 1'b1; + mulh_save = 1'b0; if ((operator_i == MUL_H) && enable_i) begin mulh_ready = 1'b0; mulh_NS = STEP0; @@ -149,12 +149,12 @@ module cv32e40px_mult end STEP0: begin - multicycle_o = 1'b1; - mulh_imm = 5'd16; - mulh_active = 1'b1; + multicycle_o = 1'b1; + mulh_imm = 5'd16; + mulh_active_o = 1'b1; //AL*BL never overflows - mulh_save = 1'b0; - mulh_NS = STEP1; + mulh_save = 1'b0; + mulh_NS = STEP1; //Here always a 32'b unsigned result (no carry) end diff --git a/hw/vendor/esl_epfl_cv32e40px/util/format-verible b/hw/vendor/esl_epfl_cv32e40px/util/format-verible index 69a46a0a4..974ecce81 100755 --- a/hw/vendor/esl_epfl_cv32e40px/util/format-verible +++ b/hw/vendor/esl_epfl_cv32e40px/util/format-verible @@ -11,4 +11,6 @@ then find rtl/ bhv/ -not -path "*rtl/vendor*" \ -name '*.sv' | \ xargs verible-verilog-format --inplace 2> /dev/zero -fi \ No newline at end of file +else +echo "verible-verilog-format not available!" +fi diff --git a/hw/vendor/openhwgroup_cv32e40p.lock.hjson b/hw/vendor/openhwgroup_cv32e40p.lock.hjson index e5ef62d7b..00ea518e8 100644 --- a/hw/vendor/openhwgroup_cv32e40p.lock.hjson +++ b/hw/vendor/openhwgroup_cv32e40p.lock.hjson @@ -9,6 +9,6 @@ upstream: { url: https://github.com/openhwgroup/cv32e40p.git - rev: b14f1adafdd55fcdab7349cc858216f702b7ad0e + rev: c8d65849ec060c6f7bc62325b46ba0ab7eae8805 } } diff --git a/hw/vendor/openhwgroup_cv32e40p.vendor.hjson b/hw/vendor/openhwgroup_cv32e40p.vendor.hjson index 81d2db674..462a2848b 100644 --- a/hw/vendor/openhwgroup_cv32e40p.vendor.hjson +++ b/hw/vendor/openhwgroup_cv32e40p.vendor.hjson @@ -7,7 +7,7 @@ upstream: { url: "https://github.com/openhwgroup/cv32e40p.git", - rev: "b14f1adafdd55fcdab7349cc858216f702b7ad0e", + rev: "c8d65849ec060c6f7bc62325b46ba0ab7eae8805", }, patch_dir: "patches/openhwgroup_cv32e40p", diff --git a/hw/vendor/openhwgroup_cv32e40p/.readthedocs.yaml b/hw/vendor/openhwgroup_cv32e40p/.readthedocs.yaml index 77f889197..e54859cec 100644 --- a/hw/vendor/openhwgroup_cv32e40p/.readthedocs.yaml +++ b/hw/vendor/openhwgroup_cv32e40p/.readthedocs.yaml @@ -4,15 +4,20 @@ version: 2 -#build: -# os: "ubuntu-20.04" -# tools: -# python: "3.9" +build: + os: "ubuntu-20.04" + tools: + python: "3.9" # Build from the docs/source directory with Sphinx sphinx: configuration: docs/source/conf.py +formats: + - htmlzip + - pdf + - epub + # Explicitly set the Python requirements python: install: diff --git a/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_instr_trace.svh b/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_instr_trace.svh index 6ad54a064..8c4ae99f3 100644 --- a/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_instr_trace.svh +++ b/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_instr_trace.svh @@ -356,7 +356,7 @@ class instr_trace_t; regs_read.push_back('{rs2, rs2_value, 0}); regs_write.push_back('{rd, 'x, 0}); str = $sformatf( - "%-16s %s, %s, %s, 0x%0d", mnemonic, regAddrToStr(rd), regAddrToStr(rs1), regAddrToStr(rs2), $unsigned(imm_s3_type[4:0]) + "%-16s %s, %s, %s, 0x%0h", mnemonic, regAddrToStr(rd), regAddrToStr(rs1), regAddrToStr(rs2), $unsigned(imm_s3_type[4:0]) ); end endfunction // printAddNInstr @@ -760,103 +760,103 @@ class instr_trace_t; case (instr[31:26]) 6'b000000: begin mnemonic = "cv.add"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b000010: begin mnemonic = "cv.sub"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b000100: begin mnemonic = "cv.avg"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b000110: begin mnemonic = "cv.avgu"; - str_imm = $sformatf("0x%0d", imm_vu_type); + str_imm = $sformatf("0x%0h", imm_vu_type); end 6'b001000: begin mnemonic = "cv.min"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b001010: begin mnemonic = "cv.minu"; - str_imm = $sformatf("0x%0d", imm_vu_type); + str_imm = $sformatf("0x%0h", imm_vu_type); end 6'b001100: begin mnemonic = "cv.max"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b001110: begin mnemonic = "cv.maxu"; - str_imm = $sformatf("0x%0d", imm_vu_type); + str_imm = $sformatf("0x%0h", imm_vu_type); end 6'b010000: begin mnemonic = "cv.srl"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b010010: begin mnemonic = "cv.sra"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b010100: begin mnemonic = "cv.sll"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b010110: begin mnemonic = "cv.or"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b011000: begin mnemonic = "cv.xor"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b011010: begin mnemonic = "cv.and"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b011100: begin mnemonic = "cv.abs"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end // dot products 6'b100000: begin mnemonic = "cv.dotup"; - str_imm = $sformatf("0x%0d", imm_vu_type); + str_imm = $sformatf("0x%0h", imm_vu_type); end 6'b100010: begin mnemonic = "cv.dotusp"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b100100: begin mnemonic = "cv.dotsp"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b100110: begin mnemonic = "cv.sdotup"; - str_imm = $sformatf("0x%0d", imm_vu_type); + str_imm = $sformatf("0x%0h", imm_vu_type); end 6'b101000: begin mnemonic = "cv.sdotusp"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b101010: begin mnemonic = "cv.sdotsp"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b101110: begin case (instr[14:13]) 2'b00 : begin mnemonic = "cv.extract"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 2'b01 : begin mnemonic = "cv.extractu"; - str_imm = $sformatf("0x%0d", imm_vu_type); + str_imm = $sformatf("0x%0h", imm_vu_type); end 2'b10 : begin mnemonic = "cv.insert"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end endcase str_sci = ""; @@ -866,25 +866,25 @@ class instr_trace_t; 6'b110000: begin if (instr[14:12] == 3'b111) begin mnemonic = "cv.shuffleI0"; - str_imm = $sformatf("0x%0d", imm_shuffle_type); + str_imm = $sformatf("0x%8h", imm_shuffle_type); end else begin mnemonic = "cv.shuffle"; if (instr[14:12] == 3'b110) begin - str_imm = $sformatf("0x%0d", imm_shuffle_type); + str_imm = $sformatf("0x%8h", imm_shuffle_type); end end end 6'b110010: begin mnemonic = "cv.shuffleI1"; - str_imm = $sformatf("0x%0d", imm_shuffle_type); + str_imm = $sformatf("0x%8h", imm_shuffle_type); end 6'b110100: begin mnemonic = "cv.shuffleI2"; - str_imm = $sformatf("0x%0d", imm_shuffle_type); + str_imm = $sformatf("0x%8h", imm_shuffle_type); end 6'b110110: begin mnemonic = "cv.shuffleI3"; - str_imm = $sformatf("0x%0d", imm_shuffle_type); + str_imm = $sformatf("0x%8h", imm_shuffle_type); end 6'b111000: begin mnemonic = "cv.shuffle2"; @@ -902,43 +902,43 @@ class instr_trace_t; // comparisons 6'b000001: begin mnemonic = "cv.cmpeq"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b000011: begin mnemonic = "cv.cmpne"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b000101: begin mnemonic = "cv.cmpgt"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b000111: begin mnemonic = "cv.cmpge"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b001001: begin mnemonic = "cv.cmplt"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b001011: begin mnemonic = "cv.cmple"; - str_imm = $sformatf("0x%0d", imm_vs_type); + str_imm = $sformatf("0x%0h", imm_vs_type); end 6'b001101: begin mnemonic = "cv.cmpgtu"; - str_imm = $sformatf("0x%0d", imm_vu_type); + str_imm = $sformatf("0x%0h", imm_vu_type); end 6'b001111: begin mnemonic = "cv.cmpgeu"; - str_imm = $sformatf("0x%0d", imm_vu_type); + str_imm = $sformatf("0x%0h", imm_vu_type); end 6'b010001: begin mnemonic = "cv.cmpltu"; - str_imm = $sformatf("0x%0d", imm_vu_type); + str_imm = $sformatf("0x%0h", imm_vu_type); end 6'b010011: begin mnemonic = "cv.cmpleu"; - str_imm = $sformatf("0x%0d", imm_vu_type); + str_imm = $sformatf("0x%0h", imm_vu_type); end 6'b010101: begin diff --git a/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_rvfi.sv b/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_rvfi.sv index 7bdb5245d..ca158f969 100644 --- a/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_rvfi.sv +++ b/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_rvfi.sv @@ -90,8 +90,10 @@ module cv32e40p_rvfi // Register reads input logic [ 5:0] rs1_addr_id_i, input logic [ 5:0] rs2_addr_id_i, + input logic [ 5:0] rs3_addr_id_i, input logic [31:0] operand_a_fw_id_i, input logic [31:0] operand_b_fw_id_i, + input logic [31:0] operand_c_fw_id_i, //// EX probes //// @@ -108,6 +110,7 @@ module cv32e40p_rvfi input logic apu_multicycle_i, input logic wb_contention_lsu_i, input logic wb_contention_i, + input logic regfile_we_lsu_i, input logic branch_in_ex_i, input logic branch_decision_ex_i, @@ -135,6 +138,7 @@ module cv32e40p_rvfi input logic rf_we_wb_i, input logic [ 5:0] rf_addr_wb_i, input logic [31:0] rf_wdata_wb_i, + input logic regfile_alu_we_ex_i, // LSU input logic [31:0] lsu_rdata_wb_i, @@ -156,6 +160,8 @@ module cv32e40p_rvfi input logic lsu_ready_ex_i, input logic lsu_ready_wb_i, + input logic [3:0] lsu_data_be_i, + input logic data_req_pmp_i, input logic data_gnt_pmp_i, input logic data_rvalid_i, @@ -334,14 +340,19 @@ module cv32e40p_rvfi output logic [31:0] rvfi_frd_wdata [1:0], output logic [ 4:0] rvfi_rs1_addr, output logic [ 4:0] rvfi_rs2_addr, + output logic [ 4:0] rvfi_rs3_addr, output logic [31:0] rvfi_rs1_rdata, output logic [31:0] rvfi_rs2_rdata, + output logic [31:0] rvfi_rs3_rdata, output logic [ 4:0] rvfi_frs1_addr, output logic [ 4:0] rvfi_frs2_addr, + output logic [ 4:0] rvfi_frs3_addr, output logic rvfi_frs1_rvalid, output logic rvfi_frs2_rvalid, + output logic rvfi_frs3_rvalid, output logic [31:0] rvfi_frs1_rdata, output logic [31:0] rvfi_frs2_rdata, + output logic [31:0] rvfi_frs3_rdata, output logic [31:0] rvfi_pc_rdata, output logic [31:0] rvfi_pc_wdata, @@ -610,7 +621,7 @@ module cv32e40p_rvfi `include "insn_trace.sv" - insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; +insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; insn_trace_t tmp_trace_wb; insn_trace_t rvfi_trace_q[$], wb_bypass_trace_q[$]; @@ -625,7 +636,7 @@ module cv32e40p_rvfi function void empty_fifo(); integer i, trace_q_size; trace_q_size = wb_bypass_trace_q.size(); - if (trace_q_size > 40) begin + if (trace_q_size > 50) begin $fatal("Reorder queue too long\n"); end if (trace_q_size != 0) begin @@ -634,6 +645,7 @@ module cv32e40p_rvfi new_rvfi_trace = new(); new_rvfi_trace.copy_full(wb_bypass_trace_q.pop_front()); if (next_send == new_rvfi_trace.m_order) begin + new_rvfi_trace.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; rvfi_trace_q.push_back(new_rvfi_trace); next_send = next_send + 1; end else begin @@ -641,6 +653,7 @@ module cv32e40p_rvfi end end end + trace_q_size = wb_bypass_trace_q.size(); //Re-calculate here for accurate status endfunction /* * Function used to alocate a new insn and send it to the rvfi driver @@ -652,32 +665,12 @@ module cv32e40p_rvfi if (next_send == new_rvfi_trace.m_order) begin rvfi_trace_q.push_back(new_rvfi_trace); next_send = next_send + 1; - // empty_fifo(); end else begin wb_bypass_trace_q.push_back(new_rvfi_trace); end empty_fifo(); endfunction - /* - * - */ - function void f_bypass_wb(insn_trace_t m_ex_insn); - insn_trace_t new_rvfi_trace; - new_rvfi_trace = new(); - new_rvfi_trace.copy_full(m_ex_insn); - if (m_ex_insn.m_ex_fw) begin - new_rvfi_trace.m_rd_addr = m_ex_insn.m_rd_addr; - new_rvfi_trace.m_rd_wdata = m_ex_insn.m_rd_wdata; - end else begin - new_rvfi_trace.m_rd_addr[0] = '0; - new_rvfi_trace.m_rd_wdata[0] = '0; - new_rvfi_trace.m_rd_addr[1] = '0; - new_rvfi_trace.m_rd_wdata[1] = '0; - end - wb_bypass_trace_q.push_back(new_rvfi_trace); - endfunction - /* * Assing rvfi signals once the instruction is completed */ @@ -690,7 +683,6 @@ module cv32e40p_rvfi logic [31:0] s_fflags_mirror; logic [31:0] s_frm_mirror; logic [31:0] s_fcsr_mirror; - logic [31:0] r_previous_minstret; function void set_rvfi(); insn_trace_t new_rvfi_trace; @@ -717,6 +709,7 @@ module cv32e40p_rvfi new_rvfi_trace.m_csr.fflags_rdata = s_fflags_mirror; new_rvfi_trace.m_csr.frm_rdata = s_frm_mirror; new_rvfi_trace.m_csr.fcsr_rdata = s_fcsr_mirror; + if (new_rvfi_trace.m_fflags_we_non_apu) begin s_fflags_mirror = new_rvfi_trace.m_csr.fflags_wdata; s_fcsr_mirror = new_rvfi_trace.m_csr.fcsr_wdata; @@ -729,44 +722,35 @@ module cv32e40p_rvfi new_rvfi_trace.m_csr.frm_wmask = 32'hFFFF_FFFF; new_rvfi_trace.m_csr.fcsr_wmask = 32'hFFFF_FFFF; end + if (new_rvfi_trace.m_fcsr_we_non_apu) begin + s_fcsr_mirror = new_rvfi_trace.m_csr.fcsr_wdata; + s_fflags_mirror = new_rvfi_trace.m_csr.fflags_wdata; + s_frm_mirror = new_rvfi_trace.m_csr.frm_wdata; + new_rvfi_trace.m_csr.fcsr_wmask = 32'hFFFF_FFFF; + new_rvfi_trace.m_csr.fflags_wmask = 32'hFFFF_FFFF; + new_rvfi_trace.m_csr.frm_wmask = 32'hFFFF_FFFF; + end end - - //FOR DEBUG!!!!!!!!!!!!!!!!!!!!!! - // if(new_rvfi_trace.m_order == 64'h0000_0000_0000_4423) begin - // new_rvfi_trace.m_csr.mcause_rdata = 32'h8000_0010; - // new_rvfi_trace.m_csr.mcause_wdata = 32'h8000_0010; - // new_rvfi_trace.m_csr.mstatus_rdata = 32'h0000_1888; - // new_rvfi_trace.m_csr.mstatus_wdata = 32'h0000_1888; - // new_rvfi_trace.m_csr.mepc_rdata = 32'h0000_554E; - // new_rvfi_trace.m_csr.mepc_wdata = 32'h0000_554E; - // end - - rvfi_order = new_rvfi_trace.m_order; - rvfi_pc_rdata = new_rvfi_trace.m_pc_rdata; - rvfi_insn = new_rvfi_trace.m_insn; - - //Trying something here - //Flag as trap everytime minstret is not incremented - - if (new_rvfi_trace.m_instret_cnt == r_previous_minstret) begin - // new_rvfi_trace.m_trap = 1'b0; - new_rvfi_trace.m_trap = 1'b1; - end else begin - r_previous_minstret = new_rvfi_trace.m_instret_cnt; - new_rvfi_trace.m_trap = 1'b0; - end + rvfi_order = new_rvfi_trace.m_order; + rvfi_pc_rdata = new_rvfi_trace.m_pc_rdata; + rvfi_insn = new_rvfi_trace.m_insn; rvfi_rs1_addr = '0; rvfi_rs1_rdata = '0; rvfi_rs2_addr = '0; rvfi_rs2_rdata = '0; + rvfi_rs3_addr = '0; + rvfi_rs3_rdata = '0; rvfi_frs1_rvalid = '0; rvfi_frs1_addr = '0; rvfi_frs1_rdata = '0; rvfi_frs2_rvalid = '0; rvfi_frs2_addr = '0; rvfi_frs2_rdata = '0; + rvfi_frs3_rvalid = '0; + rvfi_frs3_addr = '0; + rvfi_frs3_rdata = '0; if (new_rvfi_trace.m_rs1_addr[5]) begin rvfi_frs1_rvalid = 1'b1; @@ -786,6 +770,15 @@ module cv32e40p_rvfi rvfi_rs2_rdata = new_rvfi_trace.m_rs2_rdata; end + if (new_rvfi_trace.m_rs3_addr[5]) begin + rvfi_frs3_rvalid = 1'b1; + rvfi_frs3_addr = new_rvfi_trace.m_rs3_addr[4:0]; + rvfi_frs3_rdata = new_rvfi_trace.m_rs3_rdata; + end else begin + rvfi_rs3_addr = new_rvfi_trace.m_rs3_addr[4:0]; + rvfi_rs3_rdata = new_rvfi_trace.m_rs3_rdata; + end + rvfi_frd_wvalid[0] = '0; rvfi_frd_addr[0] = '0; rvfi_frd_wdata[0] = '0; @@ -843,7 +836,58 @@ module cv32e40p_rvfi end //CSR - `SET_RVFI_CSR_FROM_INSN(mstatus) + rvfi_csr_mstatus_rmask = new_rvfi_trace.m_csr.mstatus_rmask | new_rvfi_trace.m_csr.mstatus_fs_rmask; + rvfi_csr_mstatus_wmask = new_rvfi_trace.m_csr.mstatus_wmask; + rvfi_csr_mstatus_wmask[31] = new_rvfi_trace.m_csr.mstatus_fs_wmask[31]; + rvfi_csr_mstatus_wmask[14:13] = new_rvfi_trace.m_csr.mstatus_fs_wmask[14:13]; + + if (FPU == 1 && ZFINX == 0) begin + rvfi_csr_mstatus_rdata[31] = (new_rvfi_trace.m_csr.mstatus_fs_rdata == FS_DIRTY) ? 1'b1 : 1'b0; + end else begin + rvfi_csr_mstatus_rdata[31] = '0; + end + rvfi_csr_mstatus_rdata[30:18] = '0; + rvfi_csr_mstatus_rdata[17] = new_rvfi_trace.m_csr.mstatus_rdata.mprv; + rvfi_csr_mstatus_rdata[16:15] = '0; + if (FPU == 1 && ZFINX == 0) begin + rvfi_csr_mstatus_rdata[14:13] = new_rvfi_trace.m_csr.mstatus_fs_rdata; + end else begin + rvfi_csr_mstatus_rdata[14:13] = '0; + end + rvfi_csr_mstatus_rdata[12:11] = new_rvfi_trace.m_csr.mstatus_rdata.mpp; + rvfi_csr_mstatus_rdata[10:8] = '0; + rvfi_csr_mstatus_rdata[7] = new_rvfi_trace.m_csr.mstatus_rdata.mpie; + rvfi_csr_mstatus_rdata[6:5] = '0; + rvfi_csr_mstatus_rdata[4] = new_rvfi_trace.m_csr.mstatus_rdata.upie; + rvfi_csr_mstatus_rdata[3] = new_rvfi_trace.m_csr.mstatus_rdata.mie; + rvfi_csr_mstatus_rdata[2:1] = '0; + rvfi_csr_mstatus_rdata[0] = new_rvfi_trace.m_csr.mstatus_rdata.uie; + + if (FPU == 1 && ZFINX == 0) begin + rvfi_csr_mstatus_wdata[31] = (new_rvfi_trace.m_csr.mstatus_fs_wdata == FS_DIRTY) ? 1'b1 : 1'b0; + end else begin + rvfi_csr_mstatus_wdata[31] = '0; + end + rvfi_csr_mstatus_wdata[30:18] = '0; + // MPRV is not implemented in the target configuration, writes to it are ignored + rvfi_csr_mstatus_wdata[17] = 1'b0;//new_rvfi_trace.m_csr.mstatus_wdata.mprv; + rvfi_csr_mstatus_wdata[16:15] = '0; + if (FPU == 1 && ZFINX == 0) begin + rvfi_csr_mstatus_wdata[14:13] = new_rvfi_trace.m_csr.mstatus_fs_wdata; + end else begin + rvfi_csr_mstatus_wdata[14:13] = '0; + end + rvfi_csr_mstatus_wdata[12:11] = new_rvfi_trace.m_csr.mstatus_wdata.mpp; + rvfi_csr_mstatus_wdata[10:8] = '0; + rvfi_csr_mstatus_wdata[7] = new_rvfi_trace.m_csr.mstatus_wdata.mpie; + rvfi_csr_mstatus_wdata[6:5] = '0; + // UPIE is not implemented in the target configuration, writes to it are ignored + rvfi_csr_mstatus_wdata[4] = 1'b0;//new_rvfi_trace.m_csr.mstatus_wdata.upie; + rvfi_csr_mstatus_wdata[3] = new_rvfi_trace.m_csr.mstatus_wdata.mie; + rvfi_csr_mstatus_wdata[2:1] = '0; + // UIE is not implemented in the target configuration, writes to it are ignored + rvfi_csr_mstatus_wdata[0] = 1'b0;//new_rvfi_trace.m_csr.mstatus_wdata.uie; + `SET_RVFI_CSR_FROM_INSN(misa) `SET_RVFI_CSR_FROM_INSN(mie) `SET_RVFI_CSR_FROM_INSN(mtvec) @@ -853,18 +897,25 @@ module cv32e40p_rvfi `SET_RVFI_CSR_FROM_INSN(mcause) `SET_RVFI_CSR_FROM_INSN(minstret) `SET_RVFI_CSR_FROM_INSN(mip) + // if(rvfi_order == 64'h00000000_00000167) begin + // rvfi_csr_mip_rdata = 32'h0010_0000; + // end + rvfi_csr_tdata_rdata[0] = 'Z; + rvfi_csr_tdata_rmask[0] = '0; // Does not exist + rvfi_csr_tdata_wdata[0] = 'Z; // Does not exist + rvfi_csr_tdata_wmask[0] = '0; - rvfi_csr_tdata_rdata[0] = 'Z; - rvfi_csr_tdata_rmask[0] = '0; // Does not exist - rvfi_csr_tdata_wdata[0] = 'Z; // Does not exist - rvfi_csr_tdata_wmask[0] = '0; + rvfi_csr_tdata_rdata[1] = new_rvfi_trace.m_csr.tdata1_rdata; + rvfi_csr_tdata_rmask[1] = new_rvfi_trace.m_csr.tdata1_rmask; //'1 + rvfi_csr_tdata_wdata[1] = new_rvfi_trace.m_csr.tdata1_wdata; + rvfi_csr_tdata_wmask[1] = new_rvfi_trace.m_csr.tdata1_wmask; - rvfi_csr_tdata_rdata[1] = new_rvfi_trace.m_csr.tdata1_rdata; - rvfi_csr_tdata_rmask[1] = new_rvfi_trace.m_csr.tdata1_rmask; //'1 - rvfi_csr_tdata_wdata[1] = new_rvfi_trace.m_csr.tdata1_wdata; - rvfi_csr_tdata_wmask[1] = new_rvfi_trace.m_csr.tdata1_wmask; + rvfi_csr_tdata_rdata[2] = new_rvfi_trace.m_csr.tdata2_rdata; + rvfi_csr_tdata_rmask[2] = new_rvfi_trace.m_csr.tdata2_rmask; //'1 + rvfi_csr_tdata_wdata[2] = new_rvfi_trace.m_csr.tdata2_wdata; + rvfi_csr_tdata_wmask[2] = new_rvfi_trace.m_csr.tdata2_wmask; - rvfi_csr_tdata_rmask[3:2] = '1; + rvfi_csr_tdata_rmask[3] = '1; `SET_RVFI_CSR_FROM_INSN(tinfo) `SET_RVFI_CSR_FROM_INSN(dcsr) @@ -892,16 +943,14 @@ module cv32e40p_rvfi `SET_RVFI_CSR_FROM_INSN(lpend1) `SET_RVFI_CSR_FROM_INSN(lpcount1) - endfunction // set_rvfi + endfunction // set_rvfi - int r_instret_cnt; function void minstret_to_id(); trace_id.m_csr.minstret_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]; trace_id.m_csr.minstret_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2]; trace_id.m_csr.minstret_rmask = '1; trace_id.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.mhpmcounter_q; trace_id.m_csr.minstret_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2] ? '1 : '0; - trace_id.m_instret_cnt = r_instret_cnt; endfunction function void minstret_to_ex(); @@ -910,7 +959,6 @@ module cv32e40p_rvfi trace_ex.m_csr.minstret_rmask = '1; trace_ex.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.mhpmcounter_q; trace_ex.m_csr.minstret_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2] ? '1 : '0; - trace_ex.m_instret_cnt = r_instret_cnt; endfunction function void tinfo_to_id(); @@ -942,16 +990,9 @@ module cv32e40p_rvfi trace_id.m_csr.mtvec_wmask = r_pipe_freeze_trace.csr.mtvec_we ? '1 : '0; endfunction - function void mstatus_to_id(); - trace_id.m_csr.mstatus_we = r_pipe_freeze_trace.csr.mstatus_we; - trace_id.m_csr.mstatus_rdata = r_pipe_freeze_trace.csr.mstatus_full_q; - trace_id.m_csr.mstatus_rmask = '1; - trace_id.m_csr.mstatus_wdata = r_pipe_freeze_trace.csr.mstatus_full_n; - trace_id.m_csr.mstatus_wmask = r_pipe_freeze_trace.csr.mstatus_we ? '1 : '0; - endfunction - function void dcsr_to_id(); - trace_id.m_csr.dcsr_we = r_pipe_freeze_trace.csr.dcsr_we; + trace_id.m_csr.dcsr_wdata = trace_id.m_csr.dcsr_we ? trace_id.m_csr.dcsr_wdata : r_pipe_freeze_trace.csr.dcsr_n; + trace_id.m_csr.dcsr_we = r_pipe_freeze_trace.csr.dcsr_we | trace_id.m_csr.dcsr_we; trace_id.m_csr.dcsr_rdata = r_pipe_freeze_trace.csr.dcsr_q; trace_id.m_csr.dcsr_rmask = '1; trace_id.m_csr.dcsr_wdata = r_pipe_freeze_trace.csr.dcsr_n; @@ -1052,7 +1093,6 @@ module cv32e40p_rvfi if (r_pipe_freeze_trace.exc_pc_mux == EXC_PC_IRQ) begin s_irq = 1'b1; trace_if.m_is_irq = 1'b1; - trace_if.m_trap = 1'b1; end end @@ -1060,30 +1100,6 @@ module cv32e40p_rvfi s_dbg_exception = 1'b0; end - if (r_pipe_freeze_trace.pc_id == trace_if.m_pc_rdata) begin - if (trace_if.m_valid && (s_dbg_exception || s_exception)) begin - trace_if.m_trap = 1'b1; - end - end - - if (r_pipe_freeze_trace.pc_id == trace_ex.m_pc_rdata) begin - if (trace_ex.m_valid && (s_dbg_exception || s_exception)) begin - trace_ex.m_trap = 1'b1; - end - end - - if (r_pipe_freeze_trace.pc_id == trace_wb.m_pc_rdata) begin - if (trace_wb.m_valid && (s_dbg_exception || s_exception)) begin - trace_wb.m_trap = 1'b1; - end - end - - if (r_pipe_freeze_trace.pc_id == trace_id.m_pc_rdata) begin - if (trace_id.m_valid && (s_dbg_exception || s_exception)) begin - trace_id.m_trap = 1'b1; - end - end - endfunction /* * This tracer works with three process, @@ -1094,24 +1110,42 @@ module cv32e40p_rvfi * * The third updates the rvfi interface */ - `define CSR_FROM_PIPE(TRACE_NAME, - CSR_NAME) \ - trace_``TRACE_NAME``.m_csr.``CSR_NAME``_we = r_pipe_freeze_trace.csr.``CSR_NAME``_we; \ + `define CSR_FROM_PIPE(TRACE_NAME, CSR_NAME) \ + if (r_pipe_freeze_trace.csr.``CSR_NAME``_we) begin \ + trace_``TRACE_NAME``.m_csr.``CSR_NAME``_we = r_pipe_freeze_trace.csr.``CSR_NAME``_we; \ + trace_``TRACE_NAME``.m_csr.``CSR_NAME``_wdata = r_pipe_freeze_trace.csr.``CSR_NAME``_n; \ + trace_``TRACE_NAME``.m_csr.``CSR_NAME``_wmask = '1; \ + end \ trace_``TRACE_NAME``.m_csr.``CSR_NAME``_rdata = r_pipe_freeze_trace.csr.``CSR_NAME``_q; \ - trace_``TRACE_NAME``.m_csr.``CSR_NAME``_rmask = '1; \ - trace_``TRACE_NAME``.m_csr.``CSR_NAME``_wdata = r_pipe_freeze_trace.csr.``CSR_NAME``_n; \ - trace_``TRACE_NAME``.m_csr.``CSR_NAME``_wmask = r_pipe_freeze_trace.csr.``CSR_NAME``_we ? '1 : '0; + trace_``TRACE_NAME``.m_csr.``CSR_NAME``_rmask = '1; + event e_mstatus_to_id; + function void mstatus_to_id(); + `CSR_FROM_PIPE(id, mstatus) + `CSR_FROM_PIPE(id, mstatus_fs) + ->e_mstatus_to_id; + endfunction //those event are for debug purpose event e_dev_send_wb_1, e_dev_send_wb_2; - event e_dev_commit_rf_to_ex_1, e_dev_commit_rf_to_ex_2, e_dev_commit_rf_to_ex_3; + event + e_dev_commit_rf_to_ex_1, + e_dev_commit_rf_to_ex_2, + e_dev_commit_rf_to_ex_3, + e_dev_commit_rf_to_ex_4, + e_dev_commit_rf_to_ex_5; event e_if_2_id_1, e_if_2_id_2; event e_ex_to_wb_1, e_ex_to_wb_2; event e_id_to_ex_1, e_id_to_ex_2; event e_commit_dpc; event e_send_rvfi_trace_apu_resp; - event e_send_rvfi_trace_ex_1, e_send_rvfi_trace_ex_2, e_send_rvfi_trace_ex_3, e_send_rvfi_trace_ex_4; + event + e_send_rvfi_trace_ex_1, + e_send_rvfi_trace_ex_2, + e_send_rvfi_trace_ex_3, + e_send_rvfi_trace_ex_4, + e_send_rvfi_trace_ex_5, + e_send_rvfi_trace_ex_6; event e_send_rvfi_trace_wb_1, e_send_rvfi_trace_wb_2, e_send_rvfi_trace_wb_3; event e_send_rvfi_trace_id_1; @@ -1126,22 +1160,41 @@ module cv32e40p_rvfi `CSR_FROM_PIPE(apu_resp, fcsr) `CSR_FROM_PIPE(apu_resp, fflags) - trace_apu_resp.m_csr.mstatus_we = r_pipe_freeze_trace.csr.mstatus_we; - trace_apu_resp.m_csr.mstatus_rdata = r_pipe_freeze_trace.csr.mstatus_full_q; - trace_apu_resp.m_csr.mstatus_rmask = '1; - trace_apu_resp.m_csr.mstatus_wdata = r_pipe_freeze_trace.csr.mstatus_full_n; - trace_apu_resp.m_csr.mstatus_wmask = r_pipe_freeze_trace.csr.mstatus_we ? '1 : '0; + // `CSR_FROM_PIPE(apu_resp, mstatus) + `CSR_FROM_PIPE(apu_resp, mstatus_fs) + + if (r_pipe_freeze_trace.csr.mstatus_we) begin + trace_ex.m_csr.mstatus_fs_rdata = r_pipe_freeze_trace.csr.mstatus_fs_n; + end endfunction function void csr_to_apu_req(); `CSR_FROM_PIPE(apu_req, misa) `CSR_FROM_PIPE(apu_req, tdata1) - trace_apu_req.m_csr.tinfo_we = '0; // READ ONLY csr_tinfo_we_i; + `CSR_FROM_PIPE(apu_req, tdata2) + trace_apu_req.m_csr.tinfo_we = '0; // READ ONLY csr_tinfo_we_i; trace_apu_req.m_csr.tinfo_rdata = r_pipe_freeze_trace.csr.tinfo_q; trace_apu_req.m_csr.tinfo_rmask = '1; trace_apu_req.m_csr.tinfo_wdata = r_pipe_freeze_trace.csr.tinfo_n; trace_apu_req.m_csr.tinfo_wmask = '0; + trace_apu_req.m_csr.minstret_we = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2]; + trace_apu_req.m_csr.minstret_rdata = r_pipe_freeze_trace.csr.mhpmcounter_q[2]; + trace_apu_req.m_csr.minstret_rmask = '1; + trace_apu_req.m_csr.minstret_wdata = r_pipe_freeze_trace.csr.mhpmcounter_q; + trace_apu_req.m_csr.minstret_wmask = r_pipe_freeze_trace.csr.mhpmcounter_write_lower[2] ? '1 : '0; + + trace_apu_req.m_csr.lpcount0_we = '0; + trace_apu_req.m_csr.lpcount0_rdata = r_pipe_freeze_trace.hwloop.counter_q[0]; + trace_apu_req.m_csr.lpcount0_rmask = '1; + trace_apu_req.m_csr.lpcount0_wdata = '0; + trace_apu_req.m_csr.lpcount0_wmask = '0; + + trace_apu_req.m_csr.lpcount1_we = '0; + trace_apu_req.m_csr.lpcount1_rdata = r_pipe_freeze_trace.hwloop.counter_q[1]; + trace_apu_req.m_csr.lpcount1_rmask = '1; + trace_apu_req.m_csr.lpcount1_wdata = '0; + trace_apu_req.m_csr.lpcount1_wmask = '0; `CSR_FROM_PIPE(apu_req, frm) @@ -1182,75 +1235,87 @@ module cv32e40p_rvfi end endfunction + /* + * Decoding is complete and instruction enters execute stage + * If at that time, minstret is not asserted it means we have a trap + */ + bit s_is_pc_set; //If pc_set, wait until next trace_id to commit csr changes + bit s_is_irq_start; + bit s_id_done; + function void if_to_id(); + trace_id.init(trace_if); + trace_id.m_trap = ~r_pipe_freeze_trace.minstret; + trace_id.m_is_illegal = r_pipe_freeze_trace.is_illegal; + s_is_pc_set = 1'b0; + s_is_irq_start = 1'b0; + trace_if.m_valid = 1'b0; + s_id_done = 1'b0; + `CSR_FROM_PIPE(id, dpc) + endfunction + + function logic [31:0] be_to_mask(logic [3:0] be); + logic [31:0] mask; + mask[7:0] = be[0] ? 8'hFF : 8'h00; + mask[15:8] = be[0] ? 8'hFF : 8'h00; + mask[23:16] = be[0] ? 8'hFF : 8'h00; + mask[31:24] = be[0] ? 8'hFF : 8'h00; + + be_to_mask = mask; + return mask; + endfunction + task compute_pipeline(); bit s_new_valid_insn; bit s_ex_valid_adjusted; bit s_wb_valid_adjusted; - bit s_id_done; - bit s_apu_wb_ok; bit s_apu_0_cycle_reps; bit s_fflags_we_non_apu; bit s_frm_we_non_apu; - bit s_is_pc_set; //If pc_set, wait until next trace_id to commit csr changes - bit s_is_irq_start; + bit s_fcsr_we_non_apu; bit s_skip_wb; // used to skip wb monitoring when apu resp and not lsu - bit s_increase_instret_1; - bit s_increase_instret_2; - - bit s_test_for_dret; - - trace_if = new(); - trace_id = new(); - trace_ex = new(); - trace_wb = new(); - s_new_valid_insn = 1'b0; - s_ex_valid_adjusted = 1'b0; - s_id_done = 1'b0; - s_apu_wb_ok = 1'b0; - s_apu_0_cycle_reps = 1'b0; + bit s_core_is_decoding; // For readability, ctrl_fsm is DECODE or DECODE_HWLOOP - next_send = 1; - cnt_data_req = 0; - cnt_data_resp = 0; - cnt_apu_req = 0; - cnt_apu_resp = 0; - csr_is_irq = '0; - is_dbg_taken = '0; - s_was_flush = 1'b0; + trace_if = new(); + trace_id = new(); + trace_ex = new(); + trace_wb = new(); + s_new_valid_insn = 1'b0; + s_ex_valid_adjusted = 1'b0; - r_previous_minstret = -1; + s_id_done = 1'b0; + s_apu_wb_ok = 1'b0; + s_apu_0_cycle_reps = 1'b0; - s_is_pc_set = 1'b0; - s_is_irq_start = 1'b0; + next_send = 1; + cnt_data_req = 0; + cnt_data_resp = 0; + cnt_apu_req = 0; + cnt_apu_resp = 0; + csr_is_irq = '0; + is_dbg_taken = '0; + s_was_flush = 1'b0; - s_is_pc_set = 1'b0; - s_is_irq_start = 1'b0; - s_skip_wb = 1'b0; + s_is_pc_set = 1'b0; + s_is_irq_start = 1'b0; - r_instret_cnt = 0; - s_increase_instret_1 = 1'b0; - s_increase_instret_2 = 1'b0; + s_is_pc_set = 1'b0; + s_is_irq_start = 1'b0; + s_skip_wb = 1'b0; - s_test_for_dret = 1'b0; + s_core_is_decoding = 1'b0; - $display("*****Starting pipeline computing*****\n"); forever begin - wait(e_pipe_monitor_ok.triggered); // event triggered + wait(e_pipe_monitor_ok.triggered); // event triggered #1; + s_core_is_decoding = (r_pipe_freeze_trace.ctrl_fsm_cs == DECODE) || (r_pipe_freeze_trace.ctrl_fsm_cs == DECODE_HWLOOP); check_trap(); - if (s_increase_instret_2) begin - r_instret_cnt = r_instret_cnt + 1; - end - s_increase_instret_2 = s_increase_instret_1; - s_increase_instret_1 = r_pipe_freeze_trace.minstret; - pc_mux_interrupt = 1'b0; if (r_pipe_freeze_trace.pc_mux == 4'b0100) begin if (r_pipe_freeze_trace.exc_pc_mux == 3'b001) begin @@ -1275,11 +1340,9 @@ module cv32e40p_rvfi minstret_to_id(); `CSR_FROM_PIPE(id, misa) `CSR_FROM_PIPE(id, tdata1) + `CSR_FROM_PIPE(id, tdata2) tinfo_to_id(); `CSR_FROM_PIPE(id, mip) - send_rvfi(trace_id); - trace_id.m_valid = 1'b0; - ->e_send_rvfi_trace_id_1; end end @@ -1324,7 +1387,7 @@ module cv32e40p_rvfi s_new_valid_insn = r_pipe_freeze_trace.id_valid && r_pipe_freeze_trace.is_decoding;// && !r_pipe_freeze_trace.apu_rvalid; - s_wb_valid_adjusted = r_pipe_freeze_trace.wb_valid && ((r_pipe_freeze_trace.ctrl_fsm_cs == DECODE) || (r_pipe_freeze_trace.ctrl_fsm_cs == FLUSH_EX) || (r_pipe_freeze_trace.ctrl_fsm_cs == DECODE_HWLOOP));// && !r_pipe_freeze_trace.apu_rvalid;; + s_wb_valid_adjusted = r_pipe_freeze_trace.wb_valid && (s_core_is_decoding || (r_pipe_freeze_trace.ctrl_fsm_cs == FLUSH_EX));// && !r_pipe_freeze_trace.apu_rvalid;; s_fflags_we_non_apu = 1'b0; if (r_pipe_freeze_trace.csr.fflags_we) begin @@ -1340,6 +1403,13 @@ module cv32e40p_rvfi end end + s_fcsr_we_non_apu = 1'b0; + if (r_pipe_freeze_trace.csr.fcsr_we) begin + if (cnt_apu_resp == cnt_apu_req) begin //No ongoing apu instruction + s_fcsr_we_non_apu = 1'b1; + end + end + //WB_STAGE s_skip_wb = 1'b0; if (r_pipe_freeze_trace.apu_rvalid && (apu_trace_q.size() > 0)) begin @@ -1350,19 +1420,20 @@ module cv32e40p_rvfi end if (trace_wb.m_valid && !s_skip_wb) begin if (r_pipe_freeze_trace.rf_we_wb) begin - if((trace_wb.m_rd_addr[0] == r_pipe_freeze_trace.rf_addr_wb) && (cnt_data_resp == trace_wb.m_mem_req_id[0])) begin - trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; + if((trace_wb.m_rd_addr[0] == r_pipe_freeze_trace.rf_addr_wb) && (cnt_data_resp == trace_wb.m_mem_req_id[0]) && trace_wb.m_mem_req_id_valid[0]) begin + trace_wb.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_wb.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; - end else if (trace_wb.m_2_rd_insn && (trace_wb.m_rd_addr[1] == r_pipe_freeze_trace.rf_addr_wb) && (cnt_data_resp == trace_wb.m_mem_req_id[0])) begin - trace_wb.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + trace_wb.m_mem_req_id_valid[0] = 1'b0; + end else if (trace_wb.m_2_rd_insn && (trace_wb.m_rd_addr[1] == r_pipe_freeze_trace.rf_addr_wb) && (cnt_data_resp == trace_wb.m_mem_req_id[1]) && trace_wb.m_mem_req_id_valid[1]) begin + trace_wb.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; trace_wb.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; + trace_wb.m_mem_req_id_valid[1] = 1'b0; end end if (!trace_wb.m_data_missaligned) begin send_rvfi(trace_wb); - ->e_dev_send_wb_1; - ->e_send_rvfi_trace_wb_2; + ->e_dev_send_wb_1; ->e_send_rvfi_trace_wb_2; trace_wb.m_valid = 1'b0; end else begin if (s_wb_valid_adjusted) begin @@ -1375,29 +1446,36 @@ module cv32e40p_rvfi trace_wb.m_got_first_data = 1'b1; end else begin send_rvfi(trace_wb); - ->e_dev_send_wb_2; - ->e_send_rvfi_trace_wb_3; + ->e_dev_send_wb_2; ->e_send_rvfi_trace_wb_3; trace_wb.m_valid = 1'b0; end - end // rf_we_wb + end // rf_we_wb end end end if (trace_ex.m_valid) begin + if (!trace_ex.m_csr.got_minstret) begin + minstret_to_ex(); + end `CSR_FROM_PIPE(ex, misa) `CSR_FROM_PIPE(ex, tdata1) + `CSR_FROM_PIPE(ex, tdata2) tinfo_to_ex(); - if(r_pipe_freeze_trace.rf_we_wb) begin - if(cnt_data_resp == trace_ex.m_mem_req_id[0]) begin - trace_ex.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; + if (r_pipe_freeze_trace.regfile_we_lsu) begin + ->e_dev_commit_rf_to_ex_4; + if ((cnt_data_resp == trace_ex.m_mem_req_id[0]) && !(trace_ex.m_got_ex_reg) && trace_ex.m_mem_req_id_valid[0]) begin + trace_ex.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; - end else if (cnt_data_resp == trace_ex.m_mem_req_id[1]) begin - trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + trace_ex.m_got_first_data = 1'b1; + trace_ex.m_mem_req_id_valid[0] = 1'b0; + end else if ((cnt_data_resp == trace_ex.m_mem_req_id[1]) && trace_ex.m_mem_req_id_valid[1]) begin + trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; trace_ex.m_got_first_data = 1'b1; + trace_ex.m_mem_req_id_valid[1] = 1'b0; end end @@ -1407,12 +1485,13 @@ module cv32e40p_rvfi trace_ex.m_valid = 1'b0; ->e_send_rvfi_trace_ex_2; end else begin - if (r_pipe_freeze_trace.rf_we_wb) begin + if (r_pipe_freeze_trace.rf_we_wb && !s_apu_to_lsu_port) begin ->e_dev_commit_rf_to_ex_1; if (trace_ex.m_got_ex_reg) begin - trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; - trace_ex.m_2_rd_insn = 1'b1; + trace_ex.m_2_rd_insn = 1'b1; + trace_ex.m_got_first_data = 1'b1; end else begin trace_ex.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; @@ -1423,16 +1502,25 @@ module cv32e40p_rvfi if (!s_ex_valid_adjusted & !trace_ex.m_csr.got_minstret) begin minstret_to_ex(); end - ->e_ex_to_wb_1; - trace_wb.move_down_pipe(trace_ex); + if (trace_ex.m_is_load) begin // only move relevant instr in wb stage + ->e_ex_to_wb_1; + trace_wb.move_down_pipe(trace_ex); + end else begin + if (!trace_ex.m_csr.got_minstret) begin + minstret_to_ex(); + end + send_rvfi(trace_ex); + ->e_send_rvfi_trace_ex_6; + end trace_ex.m_valid = 1'b0; end - end else if (r_pipe_freeze_trace.rf_we_wb) begin + end else if (r_pipe_freeze_trace.rf_we_wb && !s_apu_to_lsu_port && !s_was_flush) begin ->e_dev_commit_rf_to_ex_2; if (trace_ex.m_got_ex_reg) begin - trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + trace_ex.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; - trace_ex.m_2_rd_insn = 1'b1; + trace_ex.m_2_rd_insn = 1'b1; + trace_ex.m_got_first_data = 1'b1; end else begin trace_ex.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_ex.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; @@ -1441,13 +1529,13 @@ module cv32e40p_rvfi end end - s_ex_valid_adjusted = (r_pipe_freeze_trace.ex_valid || s_test_for_dret) && ((r_pipe_freeze_trace.ctrl_fsm_cs == DECODE) || (r_pipe_freeze_trace.ctrl_fsm_cs == DECODE_HWLOOP)) && (!r_pipe_freeze_trace.apu_rvalid || r_pipe_freeze_trace.data_req_ex); - s_test_for_dret = r_pipe_freeze_trace.ex_valid && r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_IF; + s_ex_valid_adjusted = (r_pipe_freeze_trace.ex_valid && r_pipe_freeze_trace.ex_ready) && (s_core_is_decoding || (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_IF)) && (!r_pipe_freeze_trace.apu_rvalid || r_pipe_freeze_trace.data_req_ex); //EX_STAGE if (trace_id.m_valid) begin mtvec_to_id(); `CSR_FROM_PIPE(id, mip) + `CSR_FROM_PIPE(id, misa) if (!csr_is_irq && !s_is_irq_start) begin mstatus_to_id(); @@ -1466,8 +1554,13 @@ module cv32e40p_rvfi `CSR_FROM_PIPE(id, fcsr) if (r_pipe_freeze_trace.csr.we) begin - `CSR_FROM_PIPE(id, dpc) + `CSR_FROM_PIPE(id, dpc) + end + + if (r_pipe_freeze_trace.csr.dcsr_we) begin + dcsr_to_id(); end + if (s_fflags_we_non_apu) begin trace_id.m_fflags_we_non_apu = 1'b1; end @@ -1475,21 +1568,21 @@ module cv32e40p_rvfi if (s_frm_we_non_apu) begin trace_id.m_frm_we_non_apu = 1'b1; end + + if (s_fcsr_we_non_apu) begin + trace_id.m_fcsr_we_non_apu = 1'b1; + end + trace_ex.m_csr.fflags_wmask = '0; trace_ex.m_csr.frm_wmask = '0; trace_ex.m_csr.fcsr_wmask = '0; - if (r_pipe_freeze_trace.apu_req) begin + if (r_pipe_freeze_trace.apu_req && r_pipe_freeze_trace.apu_gnt) begin trace_id.m_is_apu = 1'b1; trace_id.m_apu_req_id = cnt_apu_req; trace_apu_req = new(); trace_apu_req.copy_full(trace_id); csr_to_apu_req(); - if(s_increase_instret_2) begin - trace_apu_req.m_instret_cnt = r_instret_cnt + 1; - end else begin - trace_apu_req.m_instret_cnt = r_instret_cnt; - end trace_apu_req.set_to_apu(); apu_trace_q.push_back(trace_apu_req); trace_id.m_valid = 1'b0; @@ -1505,7 +1598,7 @@ module cv32e40p_rvfi trace_ex.m_valid = 1'b0; ->e_send_rvfi_trace_ex_3; end - if (r_pipe_freeze_trace.ex_reg_we && !r_pipe_freeze_trace.apu_rvalid) begin + if (r_pipe_freeze_trace.ex_reg_we && !s_apu_to_alu_port) begin trace_id.m_ex_fw = 1'b1; trace_id.m_rd_addr[0] = r_pipe_freeze_trace.ex_reg_addr; trace_id.m_rd_wdata[0] = r_pipe_freeze_trace.ex_reg_wdata; @@ -1513,52 +1606,81 @@ module cv32e40p_rvfi end else if (!trace_ex.m_valid & r_pipe_freeze_trace.rf_we_wb & !trace_id.m_ex_fw) begin trace_id.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_id.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; + end else if (r_pipe_freeze_trace.rf_we_wb) begin + trace_id.m_rd_addr[1] = r_pipe_freeze_trace.rf_addr_wb; + trace_id.m_rd_wdata[1] = r_pipe_freeze_trace.rf_wdata_wb; + trace_id.m_2_rd_insn = 1'b1; end if (r_pipe_freeze_trace.data_req_ex) begin cnt_data_req = cnt_data_req + 1; trace_id.m_is_memory = 1'b1; trace_id.m_mem_req_id[0] = cnt_data_req; + trace_id.m_mem_req_id_valid[0] = 1'b1; trace_id.m_mem.addr = r_pipe_freeze_trace.data_addr_pmp; if (r_pipe_freeze_trace.data_misaligned) begin cnt_data_req = cnt_data_req + 1; end if (!r_pipe_freeze_trace.data_we_ex) begin - trace_id.m_is_load = 1'b1; + trace_id.m_is_load = 1'b1; + trace_id.m_mem.wmask = be_to_mask(r_pipe_freeze_trace.lsu_data_be); //'1; if (r_pipe_freeze_trace.data_misaligned) begin trace_id.m_data_missaligned = 1'b1; trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; trace_id.m_mem_req_id[0] = cnt_data_req; + trace_id.m_mem_req_id_valid[1] = 1'b1; end + end else begin + trace_id.m_mem.rmask = be_to_mask(r_pipe_freeze_trace.lsu_data_be); //'1; + end + if (trace_id.m_got_ex_reg) begin // Shift index 0 to 1 + trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; + trace_id.m_mem_req_id[0] = 0; + trace_id.m_mem_req_id_valid[1] = 1'b1; + trace_id.m_mem_req_id_valid[0] = 1'b0; end end - ->e_id_to_ex_1; hwloop_to_id(); trace_ex.move_down_pipe(trace_id); // The instruction moves forward from ID to EX trace_id.m_valid = 1'b0; ->e_id_to_ex_1; - end else if (r_pipe_freeze_trace.ex_reg_we) begin + end else if (r_pipe_freeze_trace.ex_reg_we && r_pipe_freeze_trace.rf_alu_we_ex) begin trace_id.m_ex_fw = 1'b1; trace_id.m_rd_addr[0] = r_pipe_freeze_trace.ex_reg_addr; trace_id.m_rd_wdata[0] = r_pipe_freeze_trace.ex_reg_wdata; trace_id.m_got_ex_reg = 1'b1; trace_id.m_got_regs_write = 1'b1; + // mem_req_id[0] already set here indicates req_id was set before rf write from EX + // Hence adjust the req_id again here for such cases + if (trace_id.m_mem_req_id[0] != 0) begin + trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; + trace_id.m_mem_req_id[0] = 0; + trace_id.m_mem_req_id_valid[0] = 1'b0; + trace_id.m_mem_req_id_valid[1] = 1'b1; + end end - end + end //trace_if.m_valid //ID_STAGE if (s_new_valid_insn) begin // There is a new valid instruction if (trace_id.m_valid) begin if (trace_ex.m_valid) begin - minstret_to_ex(); + if (!trace_ex.m_csr.got_minstret) begin + minstret_to_ex(); + end if (trace_wb.m_valid) begin send_rvfi(trace_ex); ->e_send_rvfi_trace_ex_4; end else begin - ->e_ex_to_wb_2; - trace_wb.move_down_pipe(trace_ex); + if (trace_ex.m_is_load) begin // only move relevant instr in wb stage + ->e_ex_to_wb_2; + trace_wb.move_down_pipe(trace_ex); + end else begin + send_rvfi(trace_ex); + ->e_send_rvfi_trace_ex_5; + end end trace_ex.m_valid = 1'b0; end @@ -1566,7 +1688,7 @@ module cv32e40p_rvfi cnt_data_req = cnt_data_req + 1; trace_id.m_is_memory = 1'b1; trace_id.m_mem_req_id[0] = cnt_data_req; - + trace_id.m_mem_req_id_valid[0] = 1'b1; trace_id.m_mem.addr = r_pipe_freeze_trace.data_addr_pmp; if (r_pipe_freeze_trace.data_misaligned) begin cnt_data_req = cnt_data_req + 1; @@ -1577,8 +1699,15 @@ module cv32e40p_rvfi trace_id.m_data_missaligned = 1'b1; trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; trace_id.m_mem_req_id[0] = cnt_data_req; + trace_id.m_mem_req_id_valid[1] = 1'b1; end end + if (trace_id.m_got_ex_reg) begin // Shift index 0 to 1 + trace_id.m_mem_req_id[1] = trace_id.m_mem_req_id[0]; + trace_id.m_mem_req_id[0] = 0; + trace_id.m_mem_req_id_valid[0] = 1'b0; + trace_id.m_mem_req_id_valid[1] = 1'b1; + end end else if (r_pipe_freeze_trace.rf_we_wb && !r_pipe_freeze_trace.ex_reg_we) begin trace_id.m_rd_addr[0] = r_pipe_freeze_trace.rf_addr_wb; trace_id.m_rd_wdata[0] = r_pipe_freeze_trace.rf_wdata_wb; @@ -1589,21 +1718,12 @@ module cv32e40p_rvfi trace_id.m_valid = 1'b0; ->e_id_to_ex_2; end - trace_id.init(trace_if); - trace_id.m_is_ebreak = trace_if.m_is_ebreak; - trace_id.m_is_illegal = r_pipe_freeze_trace.is_illegal; - s_is_pc_set = 1'b0; - s_is_irq_start = 1'b0; - trace_if.m_valid = 1'b0; - s_id_done = 1'b0; - + if_to_id(); + trace_id.m_is_ebreak = trace_if.m_is_ebreak; csrId_to_id(); - `CSR_FROM_PIPE(id, dscratch0) `CSR_FROM_PIPE(id, dscratch1) mstatus_to_id(); - - `CSR_FROM_PIPE(id, dpc) ->e_if_2_id_1; end else begin if (trace_id.m_valid) begin @@ -1613,17 +1733,10 @@ module cv32e40p_rvfi end //IF_STAGE - if (r_pipe_freeze_trace.if_valid && r_pipe_freeze_trace.if_ready) begin if(trace_if.m_valid && r_pipe_freeze_trace.id_valid && r_pipe_freeze_trace.id_ready && !trace_id.m_valid && r_pipe_freeze_trace.ebrk_insn_dec) begin - trace_id.init(trace_if); - trace_id.m_is_ebreak = '1; //trace_if.m_is_ebreak; - trace_id.m_is_illegal = r_pipe_freeze_trace.is_illegal; - s_is_pc_set = 1'b0; - s_is_irq_start = 1'b0; - trace_if.m_valid = 1'b0; - s_id_done = 1'b0; - `CSR_FROM_PIPE(id, dpc) + if_to_id(); + trace_id.m_is_ebreak = '1; //trace_if.m_is_ebreak; ->e_if_2_id_2; end @@ -1643,7 +1756,7 @@ module cv32e40p_rvfi `CSR_FROM_PIPE(id, mcause) end - if (!s_id_done) begin + if (!s_id_done && r_pipe_freeze_trace.is_decoding) begin dcsr_to_id(); ->e_commit_dpc; end @@ -1652,7 +1765,6 @@ module cv32e40p_rvfi s_is_pc_set = 1'b1; end - csr_is_irq = r_pipe_freeze_trace.csr_cause[5]; is_dbg_taken = ((r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_ID) | (r_pipe_freeze_trace.ctrl_fsm_cs == DBG_TAKEN_IF)) ? 1'b1 : 1'b0; saved_debug_cause = r_pipe_freeze_trace.debug_cause; @@ -1677,8 +1789,10 @@ module cv32e40p_rvfi rvfi_rd_wdata[1] = '0; rvfi_rs1_addr = '0; rvfi_rs2_addr = '0; + rvfi_rs3_addr = '0; rvfi_rs1_rdata = '0; rvfi_rs2_rdata = '0; + rvfi_rs3_rdata = '0; rvfi_mem_addr = '0; rvfi_mem_rmask = '0; rvfi_mem_wmask = '0; diff --git a/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_rvfi_trace.sv b/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_rvfi_trace.sv index 6ed4b773e..417f562a2 100644 --- a/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_rvfi_trace.sv +++ b/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_rvfi_trace.sv @@ -45,15 +45,26 @@ module cv32e40p_rvfi_trace input logic [ 4:0] rvfi_rs1_addr, input logic [ 4:0] rvfi_rs2_addr, + input logic [ 4:0] rvfi_rs3_addr, input logic [31:0] rvfi_rs1_rdata, input logic [31:0] rvfi_rs2_rdata, + input logic [31:0] rvfi_rs3_rdata, input logic [ 4:0] rvfi_frs1_addr, input logic [ 4:0] rvfi_frs2_addr, + input logic [ 4:0] rvfi_frs3_addr, input logic rvfi_frs1_rvalid, input logic rvfi_frs2_rvalid, + input logic rvfi_frs3_rvalid, input logic [31:0] rvfi_frs1_rdata, - input logic [31:0] rvfi_frs2_rdata + input logic [31:0] rvfi_frs2_rdata, + input logic [31:0] rvfi_frs3_rdata, + + input logic [31:0] rvfi_mem_addr, + input logic [ 3:0] rvfi_mem_rmask, + input logic [ 3:0] rvfi_mem_wmask, + input logic [31:0] rvfi_mem_rdata, + input logic [31:0] rvfi_mem_wdata ); import cv32e40p_tracer_pkg::*; @@ -106,6 +117,14 @@ module cv32e40p_rvfi_trace rs2_value = rvfi_rs2_rdata; end + if (rvfi_frs3_rvalid) begin + rs3 = {1'b1, rvfi_frs3_addr}; + rs3_value = rvfi_frs3_rdata; + end else begin + rs3 = {1'b0, rvfi_rs3_addr}; + rs3_value = rvfi_rs3_rdata; + end + if (rvfi_frd_wvalid[0]) begin rd = {1'b1, rvfi_frd_addr[0]}; end else begin @@ -113,9 +132,7 @@ module cv32e40p_rvfi_trace end end - assign rs3 = '0; - assign rs4 = '0; - assign rs3_value = rvfi_rd_wdata[0]; + assign rs4 = rs3; assign imm_i_type = {{20{rvfi_insn[31]}}, rvfi_insn[31:20]}; assign imm_iz_type = {20'b0, rvfi_insn[31:20]}; @@ -157,15 +174,34 @@ instr_trace_t trace_retire; function void apply_reg_write(); foreach (trace_retire.regs_write[i]) begin - if (trace_retire.regs_write[i].addr == rvfi_rd_addr[0]) begin + if (rvfi_frd_wvalid[0] && (trace_retire.regs_write[i].addr == {1'b1, rvfi_frd_addr[0]})) begin + trace_retire.regs_write[i].value = rvfi_frd_wdata[0]; + end else if (trace_retire.regs_write[i].addr == rvfi_rd_addr[0]) begin trace_retire.regs_write[i].value = rvfi_rd_wdata[0]; end - if (trace_retire.regs_write[i].addr == rvfi_rd_addr[1]) begin + if (rvfi_frd_wvalid[1] && (trace_retire.regs_write[i].addr == {1'b1, rvfi_frd_addr[1]})) begin + trace_retire.regs_write[i].value = rvfi_frd_wdata[1]; + end else if (trace_retire.regs_write[i].addr == rvfi_rd_addr[1]) begin trace_retire.regs_write[i].value = rvfi_rd_wdata[1]; end end endfunction : apply_reg_write + function void apply_mem_access(); + mem_acc_t mem_acc; + + mem_acc.addr = rvfi_mem_addr; + if (rvfi_mem_wmask) begin + mem_acc.we = 1'b1; + mem_acc.wdata = rvfi_mem_wdata; + trace_retire.mem_access.push_back(mem_acc); + end else if (rvfi_mem_rmask) begin + mem_acc.we = 1'b0; + mem_acc.wdata = 'x; + trace_retire.mem_access.push_back(mem_acc); + end + endfunction : apply_mem_access + // cycle counter always_ff @(posedge clk_i, negedge rst_ni) begin if (rst_ni == 1'b0) cycles <= 0; @@ -176,6 +212,7 @@ instr_trace_t trace_retire; if (rvfi_valid) begin trace_retire = trace_new_instr(); apply_reg_write(); + apply_mem_access(); trace_retire.printInstrTrace(); end end diff --git a/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_tb_wrapper.sv b/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_tb_wrapper.sv index 14de3b607..725ed4f05 100644 --- a/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_tb_wrapper.sv +++ b/hw/vendor/openhwgroup_cv32e40p/bhv/cv32e40p_tb_wrapper.sv @@ -210,7 +210,7 @@ module cv32e40p_tb_wrapper .apu_en_i (cv32e40p_top_i.apu_req), .apu_singlecycle_i(cv32e40p_top_i.core_i.ex_stage_i.apu_singlecycle), .apu_multicycle_i (cv32e40p_top_i.core_i.ex_stage_i.apu_multicycle), - .apu_rvalid_i (cv32e40p_top_i.apu_rvalid) + .apu_rvalid_i (cv32e40p_top_i.core_i.ex_stage_i.apu_valid) ); `endif @@ -272,8 +272,10 @@ module cv32e40p_tb_wrapper .rs1_addr_id_i (cv32e40p_top_i.core_i.id_stage_i.regfile_addr_ra_id), .rs2_addr_id_i (cv32e40p_top_i.core_i.id_stage_i.regfile_addr_rb_id), + .rs3_addr_id_i (cv32e40p_top_i.core_i.id_stage_i.regfile_addr_rc_id), .operand_a_fw_id_i (cv32e40p_top_i.core_i.id_stage_i.operand_a_fw_id), .operand_b_fw_id_i (cv32e40p_top_i.core_i.id_stage_i.operand_b_fw_id), + .operand_c_fw_id_i (cv32e40p_top_i.core_i.id_stage_i.operand_c_fw_id), // .instr (cv32e40p_top_i.core_i.id_stage_i.instr ), .is_compressed_id_i(cv32e40p_top_i.core_i.id_stage_i.is_compressed_i), .ebrk_insn_dec_i (cv32e40p_top_i.core_i.id_stage_i.ebrk_insn_dec), @@ -298,7 +300,7 @@ module cv32e40p_tb_wrapper .apu_multicycle_i (cv32e40p_top_i.core_i.ex_stage_i.apu_multicycle), .wb_contention_lsu_i(cv32e40p_top_i.core_i.ex_stage_i.wb_contention_lsu), .wb_contention_i (cv32e40p_top_i.core_i.ex_stage_i.wb_contention), - + .regfile_we_lsu_i (cv32e40p_top_i.core_i.ex_stage_i.regfile_we_lsu), // .rf_we_alu_i (cv32e40p_top_i.core_i.id_stage_i.regfile_alu_we_fw_i), // .rf_addr_alu_i (cv32e40p_top_i.core_i.id_stage_i.regfile_alu_waddr_fw_i), // .rf_wdata_alu_i (cv32e40p_top_i.core_i.id_stage_i.regfile_alu_wdata_fw_i), @@ -325,6 +327,8 @@ module cv32e40p_tb_wrapper .lsu_ready_ex_i (cv32e40p_top_i.core_i.lsu_ready_ex), .lsu_ready_wb_i (cv32e40p_top_i.core_i.lsu_ready_wb), + .lsu_data_be_i(cv32e40p_top_i.core_i.load_store_unit_i.data_be), + .data_req_pmp_i(cv32e40p_top_i.core_i.data_req_pmp), .data_gnt_pmp_i(cv32e40p_top_i.core_i.data_gnt_pmp), .data_rvalid_i(cv32e40p_top_i.core_i.data_rvalid_i), @@ -339,11 +343,12 @@ module cv32e40p_tb_wrapper .rf_we_wb_i(cv32e40p_top_i.core_i.id_stage_i.regfile_we_wb_i), .rf_addr_wb_i(cv32e40p_top_i.core_i.id_stage_i.regfile_waddr_wb_i), .rf_wdata_wb_i(cv32e40p_top_i.core_i.id_stage_i.regfile_wdata_wb_i), + .regfile_alu_we_ex_i(cv32e40p_top_i.core_i.id_stage_i.regfile_alu_we_ex_o), // APU .apu_req_i (cv32e40p_top_i.core_i.apu_req_o), .apu_gnt_i (cv32e40p_top_i.core_i.apu_gnt_i), - .apu_rvalid_i(cv32e40p_top_i.core_i.apu_rvalid_i), + .apu_rvalid_i(cv32e40p_top_i.core_i.ex_stage_i.apu_valid), // Controller FSM probes .ctrl_fsm_cs_i(cv32e40p_top_i.core_i.id_stage_i.controller_i.ctrl_fsm_cs), @@ -367,6 +372,10 @@ module cv32e40p_tb_wrapper .csr_tdata1_q_i (cv32e40p_top_i.core_i.cs_registers_i.tmatch_control_rdata),//gen_trigger_regs.tmatch_control_exec_q ), .csr_tdata1_we_i(cv32e40p_top_i.core_i.cs_registers_i.gen_trigger_regs.tmatch_control_we), + .csr_tdata2_n_i (cv32e40p_top_i.core_i.cs_registers_i.tmatch_value_rdata),//csr_wdata_int ), + .csr_tdata2_q_i (cv32e40p_top_i.core_i.cs_registers_i.tmatch_value_rdata),//gen_trigger_regs.tmatch_control_exec_q ), + .csr_tdata2_we_i(cv32e40p_top_i.core_i.cs_registers_i.gen_trigger_regs.tmatch_value_we), + .csr_tinfo_n_i({16'h0, cv32e40p_top_i.core_i.cs_registers_i.tinfo_types}), .csr_tinfo_q_i({16'h0, cv32e40p_top_i.core_i.cs_registers_i.tinfo_types}), @@ -445,14 +454,24 @@ module cv32e40p_tb_wrapper .rvfi_frd_wdata(rvfi_frd_wdata), .rvfi_rs1_addr(rvfi_rs1_addr), .rvfi_rs2_addr(rvfi_rs2_addr), + .rvfi_rs3_addr(rvfi_rs3_addr), .rvfi_rs1_rdata(rvfi_rs1_rdata), .rvfi_rs2_rdata(rvfi_rs2_rdata), + .rvfi_rs3_rdata(rvfi_rs3_rdata), .rvfi_frs1_addr(rvfi_frs1_addr), .rvfi_frs2_addr(rvfi_frs2_addr), + .rvfi_frs3_addr(rvfi_frs3_addr), .rvfi_frs1_rvalid(rvfi_frs1_rvalid), .rvfi_frs2_rvalid(rvfi_frs2_rvalid), + .rvfi_frs3_rvalid(rvfi_frs3_rvalid), .rvfi_frs1_rdata(rvfi_frs1_rdata), - .rvfi_frs2_rdata(rvfi_frs2_rdata) + .rvfi_frs2_rdata(rvfi_frs2_rdata), + .rvfi_frs3_rdata(rvfi_frs3_rdata), + .rvfi_mem_addr(rvfi_mem_addr), + .rvfi_mem_rmask(rvfi_mem_rmask), + .rvfi_mem_wmask(rvfi_mem_wmask), + .rvfi_mem_rdata(rvfi_mem_rdata), + .rvfi_mem_wdata(rvfi_mem_wdata) ); `endif // Instantiate the Core and the optinal FPU diff --git a/hw/vendor/openhwgroup_cv32e40p/bhv/include/cv32e40p_tracer_pkg.sv b/hw/vendor/openhwgroup_cv32e40p/bhv/include/cv32e40p_tracer_pkg.sv index 18e503f3b..c099ff4f4 100644 --- a/hw/vendor/openhwgroup_cv32e40p/bhv/include/cv32e40p_tracer_pkg.sv +++ b/hw/vendor/openhwgroup_cv32e40p/bhv/include/cv32e40p_tracer_pkg.sv @@ -130,11 +130,85 @@ package cv32e40p_tracer_pkg; parameter INSTR_AMOMINU = {AMO_MINU, 2'b?, 5'b?, 5'b?, 3'b010, 5'b?, OPCODE_AMO}; parameter INSTR_AMOMAXU = {AMO_MAXU, 2'b?, 5'b?, 5'b?, 3'b010, 5'b?, OPCODE_AMO}; + + // LOAD STORE + parameter INSTR_LB = {17'b?, 3'b000, 5'b?, OPCODE_LOAD}; + parameter INSTR_LH = {17'b?, 3'b001, 5'b?, OPCODE_LOAD}; + parameter INSTR_LW = {17'b?, 3'b010, 5'b?, OPCODE_LOAD}; + parameter INSTR_LBU = {17'b?, 3'b100, 5'b?, OPCODE_LOAD}; + parameter INSTR_LHU = {17'b?, 3'b101, 5'b?, OPCODE_LOAD}; + + parameter INSTR_SB = {17'b?, 3'b000, 5'b?, OPCODE_STORE}; + parameter INSTR_SH = {17'b?, 3'b001, 5'b?, OPCODE_STORE}; + parameter INSTR_SW = {17'b?, 3'b010, 5'b?, OPCODE_STORE}; + + // parameter INSTR_FL = {OPCODE_LOAD_FP}; + // parameter INSTR_FS = {OPCODE_STORE_FP} + // CUSTOM_0 parameter INSTR_BEQIMM = {17'b?, 3'b110, 5'b?, OPCODE_CUSTOM_0}; parameter INSTR_BNEIMM = {17'b?, 3'b111, 5'b?, OPCODE_CUSTOM_0}; + // Post-Increment Register-Immediate Load + parameter INSTR_CVLBI = {17'b?, 3'b000, 5'b?, OPCODE_CUSTOM_0}; + parameter INSTR_CVLBUI = {17'b?, 3'b100, 5'b?, OPCODE_CUSTOM_0}; + parameter INSTR_CVLHI = {17'b?, 3'b001, 5'b?, OPCODE_CUSTOM_0}; + parameter INSTR_CVLHUI = {17'b?, 3'b101, 5'b?, OPCODE_CUSTOM_0}; + parameter INSTR_CVLWI = {17'b?, 3'b010, 5'b?, OPCODE_CUSTOM_0}; + + // Event Load + parameter INSTR_CVELW = {17'b?, 3'b011, 5'b?, OPCODE_CUSTOM_0}; + // CUSTOM_1 + // Post-Increment Register-Register Load + parameter INSTR_CVLBR = {7'b0000000, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLBUR = {7'b0001000, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLHR = {7'b0000001, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLHUR = {7'b0001001, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLWR = {7'b0000010, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + + // Register-Register Load + parameter INSTR_CVLBRR = {7'b0000100, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLBURR = {7'b0001100, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLHRR = {7'b0000101, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLHURR = {7'b0001101, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVLWRR = {7'b0000110, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + + // Post-Increment Register-Immediate Store + parameter INSTR_CVSBI = {17'b?, 3'b000, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVSHI = {17'b?, 3'b001, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVSWI = {17'b?, 3'b010, 5'b?, OPCODE_CUSTOM_1}; + + // Post-Increment Register-Register Store operations encoding + parameter INSTR_CVSBR = {7'b0010000, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVSHR = {7'b0010001, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVSWR = {7'b0010010, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + + // Register-Register Store operations + parameter INSTR_CVSBRR = {7'b0010100, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVSHRR = {7'b0010101, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + parameter INSTR_CVSWRR = {7'b0010110, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; + + // Hardware Loops + parameter INSTR_CVSTARTI0 = {12'b?, 5'b00000, 3'b100, 4'b0000, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVSTART0 = {12'b000000000000, 5'b?, 3'b100, 4'b0001, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVSENDI0 = {12'b?, 5'b00000, 3'b100, 4'b0010, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVEND0 = {12'b000000000000, 5'b?, 3'b100, 4'b0011, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVCOUNTI0 = {12'b?, 5'b00000, 3'b100, 4'b0100, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVCOUNT0 = {12'b000000000000, 5'b?, 3'b100, 4'b0101, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUPI0 = {12'b?, 5'b00000, 3'b100, 4'b0110, 1'b0, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUP0 = {12'b?, 5'b00000, 3'b100, 4'b0111, 1'b0, OPCODE_CUSTOM_1}; + + parameter INSTR_CVSTARTI1 = {12'b?, 5'b00000, 3'b100, 4'b0000, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVSTART1 = {12'b000000000000, 5'b?, 3'b100, 4'b0001, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVSENDI1 = {12'b?, 5'b00000, 3'b100, 4'b0010, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVEND1 = {12'b000000000000, 5'b?, 3'b100, 4'b0011, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVCOUNTI1 = {12'b?, 5'b00000, 3'b100, 4'b0100, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVCOUNT1 = {12'b000000000000, 5'b?, 3'b100, 4'b0101, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUPI1 = {12'b?, 5'b00000, 3'b100, 4'b0110, 1'b1, OPCODE_CUSTOM_1}; + parameter INSTR_CVSETUP1 = {12'b?, 5'b00000, 3'b100, 4'b0111, 1'b1, OPCODE_CUSTOM_1}; + + parameter INSTR_FF1 = {7'b0100001, 5'b0, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; parameter INSTR_FL1 = {7'b0100010, 5'b0, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; parameter INSTR_CLB = {7'b0100011, 5'b0, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_1}; @@ -213,6 +287,290 @@ package cv32e40p_tracer_pkg; // CUSTOM_3 + // SIMD ALU + parameter INSTR_CVADDH = {5'b00000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVADDSCH = {5'b00000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVADDSCIH = {5'b00000, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVADDB = {5'b00000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVADDSCB = {5'b00000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVADDSCIB = {5'b00000, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSUBH = {5'b00001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBSCH = {5'b00001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBSCIH = {5'b00001, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBB = {5'b00001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBSCB = {5'b00001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBSCIB = {5'b00001, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVAVGH = {5'b00010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGSCH = {5'b00010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGSCIH = {5'b00010, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGB = {5'b00010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGSCB = {5'b00010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGSCIB = {5'b00010, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVAVGUH = {5'b00011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGUSCH = {5'b00011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGUSCIH = {5'b00011, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGUB = {5'b00011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGUSCB = {5'b00011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVAVGUSCIB = {5'b00011, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVMINH = {5'b00100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINSCH = {5'b00100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINSCIH = {5'b00100, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINB = {5'b00100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINSCB = {5'b00100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINSCIB = {5'b00100, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVMINUH = {5'b00101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINUSCH = {5'b00101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINUSCIH = {5'b00101, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINUB = {5'b00101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINUSCB = {5'b00101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMINUSCIB = {5'b00101, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVMAXH = {5'b00110, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXSCH = {5'b00110, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXSCIH = {5'b00110, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXB = {5'b00110, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXSCB = {5'b00110, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXSCIB = {5'b00110, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVMAXUH = {5'b00111, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXUSCH = {5'b00111, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXUSCIH = {5'b00111, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXUB = {5'b00111, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXUSCB = {5'b00111, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVMAXUSCIB = {5'b00111, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSRLH = {5'b01000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRLSCH = {5'b01000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRLSCIH = {5'b01000, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRLB = {5'b01000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRLSCB = {5'b01000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRLSCIB = {5'b01000, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSRAH = {5'b01001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRASCH = {5'b01001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRASCIH = {5'b01001, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRAB = {5'b01001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRASCB = {5'b01001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSRASCIB = {5'b01001, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSLLH = {5'b01010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSLLSCH = {5'b01010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSLLSCIH = {5'b01010, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSLLB = {5'b01010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSLLSCB = {5'b01010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSLLSCIB = {5'b01010, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVORH = {5'b01011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVORSCH = {5'b01011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVORSCIH = {5'b01011, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVORB = {5'b01011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVORSCB = {5'b01011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVORSCIB = {5'b01011, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVXORH = {5'b01100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVXORSCH = {5'b01100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVXORSCIH = {5'b01100, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVXORB = {5'b01100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVXORSCB = {5'b01100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVXORSCIB = {5'b01100, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVANDH = {5'b01101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVANDSCH = {5'b01101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVANDSCIH = {5'b01101, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVANDB = {5'b01101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVANDSCB = {5'b01101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVANDSCIB = {5'b01101, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVABSH = {5'b01110, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVABSB = {5'b01110, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVEXTRACTH = {5'b10111, 1'b0, 6'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVEXTRACTB = {5'b10111, 1'b0, 6'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVEXTRACTUH = {5'b10111, 1'b0, 6'b?, 5'b?, 3'b010, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVEXTRACTUB = {5'b10111, 1'b0, 6'b?, 5'b?, 3'b011, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVINSERTH = {5'b10111, 1'b0, 6'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVINSERTB = {5'b10111, 1'b0, 6'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVDOTUPH = {5'b10000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUPSCH = {5'b10000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUPSCIH = {5'b10000, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUPB = {5'b10000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUPSCB = {5'b10000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUPSCIB = {5'b10000, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVDOTUSPH = {5'b10001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUSPSCH = {5'b10001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUSPSCIH = {5'b10001, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUSPB = {5'b10001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUSPSCB = {5'b10001, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTUSPSCIB = {5'b10001, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVDOTSPH = {5'b10010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTSPSCH = {5'b10010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTSPSCIH = {5'b10010, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTSPB = {5'b10010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTSPSCB = {5'b10010, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVDOTSPSCIB = {5'b10010, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSDOTUPH = {5'b10011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUPSCH = {5'b10011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUPSCIH = {5'b10011, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUPB = {5'b10011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUPSCB = {5'b10011, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUPSCIB = {5'b10011, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSDOTUSPH = {5'b10100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUSPSCH = {5'b10100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUSPSCIH = {5'b10100, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUSPB = {5'b10100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUSPSCB = {5'b10100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTUSPSCIB = {5'b10100, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSDOTSPH = {5'b10101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTSPSCH = {5'b10101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTSPSCIH = {5'b10101, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTSPB = {5'b10101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTSPSCB = {5'b10101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSDOTSPSCIB = {5'b10101, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSHUFFLEH = {5'b11000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSHUFFLESCIH = {5'b11000, 1'b0, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSHUFFLEB = {5'b11000, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSHUFFLEL0SCIB = {5'b11000, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSHUFFLEL1SCIB = {5'b11001, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSHUFFLEL2SCIB = {5'b11010, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSHUFFLEL3SCIB = {5'b11011, 1'b0, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSHUFFLE2H = {5'b11100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSHUFFLE2B = {5'b11100, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVPACK = {5'b11101, 1'b0, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVPACKH = {5'b11101, 1'b0, 1'b1, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVPACKHIB = {5'b11111, 1'b0, 1'b1, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVPACKLOB = {5'b11111, 1'b0, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + + // SIMD COMPARISON + parameter INSTR_CVCMPEQH = {5'b00000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPEQSCH = {5'b00000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPEQSCIH = {5'b00000, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPEQB = {5'b00000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPEQSCB = {5'b00000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPEQSCIB = {5'b00000, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPNEH = {5'b00001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPNESCH = {5'b00001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPNESCIH = {5'b00001, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPNEB = {5'b00001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPNESCB = {5'b00001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPNESCIB = {5'b00001, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPGTH = {5'b00010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTSCH = {5'b00010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTSCIH = {5'b00010, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTB = {5'b00010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTSCB = {5'b00010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTSCIB = {5'b00010, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPGEH = {5'b00011, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGESCH = {5'b00011, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGESCIH = {5'b00011, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGEB = {5'b00011, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGESCB = {5'b00011, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGESCIB = {5'b00011, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPLTH = {5'b00100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTSCH = {5'b00100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTSCIH = {5'b00100, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTB = {5'b00100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTSCB = {5'b00100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTSCIB = {5'b00100, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPLEH = {5'b00101, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLESCH = {5'b00101, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLESCIH = {5'b00101, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLEB = {5'b00101, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLESCB = {5'b00101, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLESCIB = {5'b00101, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPGTUH = {5'b00110, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTUSCH = {5'b00110, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTUSCIH = {5'b00110, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTUB = {5'b00110, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTUSCB = {5'b00110, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGTUSCIB = {5'b00110, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPGEUH = {5'b00111, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGEUSCH = {5'b00111, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGEUSCIH = {5'b00111, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGEUB = {5'b00111, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGEUSCB = {5'b00111, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPGEUSCIB = {5'b00111, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPLTUH = {5'b01000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTUSCH = {5'b01000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTUSCIH = {5'b01000, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTUB = {5'b01000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTUSCB = {5'b01000, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLTUSCIB = {5'b01000, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVCMPLEUH = {5'b01001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLEUSCH = {5'b01001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLEUSCIH = {5'b01001, 1'b1, 6'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLEUB = {5'b01001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLEUSCB = {5'b01001, 1'b1, 1'b0, 5'b?, 5'b?, 3'b101, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCMPLEUSCIB = {5'b01001, 1'b1, 6'b?, 5'b?, 3'b111, 5'b?, OPCODE_CUSTOM_3}; + + // SIMD CPLX + parameter INSTR_CVCPLXMULR = {5'b01010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCPLXMULRDIV2 = { + 5'b01010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b010, 5'b?, OPCODE_CUSTOM_3 + }; + parameter INSTR_CVCPLXMULRDIV4 = { + 5'b01010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3 + }; + parameter INSTR_CVCPLXMULRDIV8 = { + 5'b01010, 1'b1, 1'b0, 5'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3 + }; + + parameter INSTR_CVCPLXMULI = {5'b01010, 1'b1, 1'b1, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVCPLXMULIDIV2 = { + 5'b01010, 1'b1, 1'b1, 5'b?, 5'b?, 3'b010, 5'b?, OPCODE_CUSTOM_3 + }; + parameter INSTR_CVCPLXMULIDIV4 = { + 5'b01010, 1'b1, 1'b1, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3 + }; + parameter INSTR_CVCPLXMULIDIV8 = { + 5'b01010, 1'b1, 1'b1, 5'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3 + }; + + parameter INSTR_CVCPLXCONJ = { + 5'b01011, 1'b1, 1'b0, 5'b00000, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3 + }; + + parameter INSTR_CVSUBROTMJ = {5'b01100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBROTMJDIV2 = { + 5'b01100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b010, 5'b?, OPCODE_CUSTOM_3 + }; + parameter INSTR_CVSUBROTMJDIV4 = { + 5'b01100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3 + }; + parameter INSTR_CVSUBROTMJDIV8 = { + 5'b01100, 1'b1, 1'b0, 5'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3 + }; + + parameter INSTR_CVADDIV2 = {5'b01101, 1'b1, 1'b0, 5'b?, 5'b?, 3'b010, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVADDIV4 = {5'b01101, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVADDIV8 = {5'b01101, 1'b1, 1'b0, 5'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; + + parameter INSTR_CVSUBIV2 = {5'b01110, 1'b1, 1'b0, 5'b?, 5'b?, 3'b010, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBIV4 = {5'b01110, 1'b1, 1'b0, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_CUSTOM_3}; + parameter INSTR_CVSUBIV8 = {5'b01110, 1'b1, 1'b0, 5'b?, 5'b?, 3'b110, 5'b?, OPCODE_CUSTOM_3}; // to be used in tracer! diff --git a/hw/vendor/openhwgroup_cv32e40p/bhv/insn_trace.sv b/hw/vendor/openhwgroup_cv32e40p/bhv/insn_trace.sv index cb766fc7e..3db2a7ee0 100644 --- a/hw/vendor/openhwgroup_cv32e40p/bhv/insn_trace.sv +++ b/hw/vendor/openhwgroup_cv32e40p/bhv/insn_trace.sv @@ -15,12 +15,18 @@ this.m_csr.``CSR_NAME``_wdata = m_source.m_csr.``CSR_NAME``_wdata; \ this.m_csr.``CSR_NAME``_wmask = m_source.m_csr.``CSR_NAME``_wmask; + `define INIT_CSR(CSR_NAME) \ + this.m_csr.``CSR_NAME``_we = '0; \ + this.m_csr.``CSR_NAME``_wmask = '0; + + import cv32e40p_tracer_pkg::*; class insn_trace_t; bit m_valid; logic [63:0] m_order; bit m_skip_order; //next order was used by trap; logic [31:0] m_pc_rdata; logic [31:0] m_insn; + string m_mnemonic; logic m_is_ebreak; logic m_is_illegal; logic m_is_irq; @@ -30,6 +36,7 @@ logic m_is_apu_ok; integer m_apu_req_id; integer m_mem_req_id[1:0]; + logic [ 1:0] m_mem_req_id_valid; logic m_data_missaligned; logic m_got_first_data; logic m_got_ex_reg; @@ -38,10 +45,13 @@ logic m_fflags_we_non_apu; logic m_frm_we_non_apu; + logic m_fcsr_we_non_apu; logic [5:0] m_rs1_addr; logic [5:0] m_rs2_addr; + logic [5:0] m_rs3_addr; logic [31:0] m_rs1_rdata; logic [31:0] m_rs2_rdata; + logic [31:0] m_rs3_rdata; bit m_trap; @@ -65,7 +75,17 @@ } m_mem; struct { - `DEFINE_CSR(mstatus) + logic mstatus_we; + logic [31:0] mstatus_rmask; + Status_t mstatus_wdata; + logic [31:0] mstatus_wmask; + Status_t mstatus_rdata; + + logic mstatus_fs_we; + FS_t mstatus_fs_rdata; + logic [31:0] mstatus_fs_rmask; + FS_t mstatus_fs_wdata; + logic [31:0] mstatus_fs_wmask; // mstatush @@ -145,12 +165,706 @@ this.m_apu_req_id = 0; this.m_mem_req_id[0] = 0; this.m_mem_req_id[1] = 0; + this.m_mem_req_id_valid = '0; this.m_trap = 1'b0; this.m_fflags_we_non_apu = 1'b0; this.m_frm_we_non_apu = 1'b0; + this.m_fcsr_we_non_apu = 1'b0; this.m_instret_cnt = 0; endfunction + function void get_mnemonic(); + + this.m_mnemonic = "INVALID"; + + if(!is_compressed_id_i) begin + // use casex instead of case inside due to ModelSim bug + casex (this.m_insn) + // Aliases + 32'h00_00_00_13: this.m_mnemonic = "nop"; + // Regular opcodes + INSTR_LUI: this.m_mnemonic = "lui"; + INSTR_AUIPC: this.m_mnemonic = "auipc"; + INSTR_JAL: this.m_mnemonic = "jal"; + INSTR_JALR: this.m_mnemonic = "jalr"; + // BRANCH + INSTR_BEQ: this.m_mnemonic = "beq"; + INSTR_BNE: this.m_mnemonic = "bne"; + INSTR_BLT: this.m_mnemonic = "blt"; + INSTR_BGE: this.m_mnemonic = "bge"; + INSTR_BLTU: this.m_mnemonic = "bltu"; + INSTR_BGEU: this.m_mnemonic = "bgeu"; + INSTR_BEQIMM: this.m_mnemonic = "cv.beqimm"; + INSTR_BNEIMM: this.m_mnemonic = "cv.bneimm"; + // OPIMM + INSTR_ADDI: this.m_mnemonic = "addi"; + INSTR_SLTI: this.m_mnemonic = "slti"; + INSTR_SLTIU: this.m_mnemonic = "sltiu"; + INSTR_XORI: this.m_mnemonic = "xori"; + INSTR_ORI: this.m_mnemonic = "ori"; + INSTR_ANDI: this.m_mnemonic = "andi"; + INSTR_SLLI: this.m_mnemonic = "slli"; + INSTR_SRLI: this.m_mnemonic = "srli"; + INSTR_SRAI: this.m_mnemonic = "srai"; + // OP + INSTR_ADD: this.m_mnemonic = "add"; + INSTR_SUB: this.m_mnemonic = "sub"; + INSTR_SLL: this.m_mnemonic = "sll"; + INSTR_SLT: this.m_mnemonic = "slt"; + INSTR_SLTU: this.m_mnemonic = "sltu"; + INSTR_XOR: this.m_mnemonic = "xor"; + INSTR_SRL: this.m_mnemonic = "srl"; + INSTR_SRA: this.m_mnemonic = "sra"; + INSTR_OR: this.m_mnemonic = "or"; + INSTR_AND: this.m_mnemonic = "and"; + INSTR_EXTHS: this.m_mnemonic = "cv.exths"; + INSTR_EXTHZ: this.m_mnemonic = "cv.exthz"; + INSTR_EXTBS: this.m_mnemonic = "cv.extbs"; + INSTR_EXTBZ: this.m_mnemonic = "cv.extbz"; + INSTR_PAVG: this.m_mnemonic = "cv.avg"; + INSTR_PAVGU: this.m_mnemonic = "cv.avgu"; + + INSTR_PADDN: this.m_mnemonic = "cv.addN"; + INSTR_PADDUN: this.m_mnemonic = "cv.adduN"; + INSTR_PADDRN: this.m_mnemonic = "cv.addRN"; + INSTR_PADDURN: this.m_mnemonic = "cv.adduRN"; + INSTR_PSUBN: this.m_mnemonic = "cv.subN"; + INSTR_PSUBUN: this.m_mnemonic = "cv.subuN"; + INSTR_PSUBRN: this.m_mnemonic = "cv.subRN"; + INSTR_PSUBURN: this.m_mnemonic = "cv.subuRN"; + + INSTR_PADDNR: this.m_mnemonic = "cv.addNr"; + INSTR_PADDUNR: this.m_mnemonic = "cv.adduNr"; + INSTR_PADDRNR: this.m_mnemonic = "cv.addRNr"; + INSTR_PADDURNR: this.m_mnemonic = "cv.adduRNr"; + INSTR_PSUBNR: this.m_mnemonic = "cv.subNr"; + INSTR_PSUBUNR: this.m_mnemonic = "cv.subuNr"; + INSTR_PSUBRNR: this.m_mnemonic = "cv.subRNr"; + INSTR_PSUBURNR: this.m_mnemonic = "cv.subuRNr"; + + INSTR_PSLET: this.m_mnemonic = "cv.slet"; + INSTR_PSLETU: this.m_mnemonic = "cv.sletu"; + INSTR_PMIN: this.m_mnemonic = "cv.min"; + INSTR_PMINU: this.m_mnemonic = "cv.minu"; + INSTR_PMAX: this.m_mnemonic = "cv.max"; + INSTR_PMAXU: this.m_mnemonic = "cv.maxu"; + INSTR_PABS: this.m_mnemonic = "cv.abs"; + INSTR_PCLIP: this.m_mnemonic = "cv.clip"; + INSTR_PCLIPU: this.m_mnemonic = "cv.clipu"; + INSTR_PBEXT: this.m_mnemonic = "cv.extract"; + INSTR_PBEXTU: this.m_mnemonic = "cv.extractu"; + INSTR_PBINS: this.m_mnemonic = "cv.insert"; + INSTR_PBCLR: this.m_mnemonic = "cv.bclr"; + INSTR_PBSET: this.m_mnemonic = "cv.bset"; + INSTR_PBREV: this.m_mnemonic = "cv.bitrev"; + + INSTR_PCLIPR: this.m_mnemonic = "cv.clipr"; + INSTR_PCLIPUR: this.m_mnemonic = "cv.clipur"; + INSTR_PBEXTR: this.m_mnemonic = "cv.extractr"; + INSTR_PBEXTUR: this.m_mnemonic = "cv.extractur"; + INSTR_PBINSR: this.m_mnemonic = "cv.insertr"; + INSTR_PBCLRR: this.m_mnemonic = "cv.bclrr"; + INSTR_PBSETR: this.m_mnemonic = "cv.bsetr"; + + + INSTR_FF1: this.m_mnemonic = "cv.ff1"; + INSTR_FL1: this.m_mnemonic = "cv.fl1"; + INSTR_CLB: this.m_mnemonic = "cv.clb"; + INSTR_CNT: this.m_mnemonic = "cv.cnt"; + INSTR_ROR: this.m_mnemonic = "cv.ror"; + + // FENCE + INSTR_FENCE: this.m_mnemonic = "fence"; + INSTR_FENCEI: this.m_mnemonic = "fencei"; + // SYSTEM (CSR manipulation) + INSTR_CSRRW: this.m_mnemonic = "csrrw"; + INSTR_CSRRS: this.m_mnemonic = "csrrs"; + INSTR_CSRRC: this.m_mnemonic = "csrrc"; + INSTR_CSRRWI: this.m_mnemonic = "csrrwi"; + INSTR_CSRRSI: this.m_mnemonic = "csrrsi"; + INSTR_CSRRCI: this.m_mnemonic = "csrrci"; + // SYSTEM (others) + INSTR_ECALL: this.m_mnemonic = "ecall"; + INSTR_EBREAK: this.m_mnemonic = "ebreak"; + INSTR_URET: this.m_mnemonic = "uret"; + INSTR_MRET: this.m_mnemonic = "mret"; + INSTR_WFI: this.m_mnemonic = "wfi"; + + INSTR_DRET: this.m_mnemonic = "dret"; + + // RV32M + INSTR_PMUL: this.m_mnemonic = "mul"; + INSTR_PMUH: this.m_mnemonic = "mulh"; + INSTR_PMULHSU: this.m_mnemonic = "mulhsu"; + INSTR_PMULHU: this.m_mnemonic = "mulhu"; + INSTR_DIV: this.m_mnemonic = "div"; + INSTR_DIVU: this.m_mnemonic = "divu"; + INSTR_REM: this.m_mnemonic = "rem"; + INSTR_REMU: this.m_mnemonic = "remu"; + // PULP MULTIPLIER + INSTR_PMAC: this.m_mnemonic = "cv.mac"; + INSTR_PMSU: this.m_mnemonic = "cv.msu"; + INSTR_PMULSN: this.m_mnemonic = "cv.mulsN"; + INSTR_PMULHHSN: this.m_mnemonic = "cv.mulhhsN"; + INSTR_PMULSRN: this.m_mnemonic = "cv.mulsRN"; + INSTR_PMULHHSRN: this.m_mnemonic = "cv.mulhhsRN"; + INSTR_PMULUN: this.m_mnemonic = "cv.muluN"; + INSTR_PMULHHUN: this.m_mnemonic = "cv.mulhhuN"; + INSTR_PMULURN: this.m_mnemonic = "cv.muluRN"; + INSTR_PMULHHURN: this.m_mnemonic = "cv.mulhhuRN"; + INSTR_PMACSN: this.m_mnemonic = "cv.macsN"; + INSTR_PMACHHSN: this.m_mnemonic = "cv.machhsN"; + INSTR_PMACSRN: this.m_mnemonic = "cv.macsRN"; + INSTR_PMACHHSRN: this.m_mnemonic = "cv.machhsRN"; + INSTR_PMACUN: this.m_mnemonic = "cv.macuN"; + INSTR_PMACHHUN: this.m_mnemonic = "cv.machhuN"; + INSTR_PMACURN: this.m_mnemonic = "cv.macuRN"; + INSTR_PMACHHURN: this.m_mnemonic = "cv.machhuRN"; + + // FP-OP + INSTR_FMADD: this.m_mnemonic = "fmadd.s"; + INSTR_FMSUB: this.m_mnemonic = "fmsub.s"; + INSTR_FNMADD: this.m_mnemonic = "fnmadd.s"; + INSTR_FNMSUB: this.m_mnemonic = "fnmsub.s"; + INSTR_FADD: this.m_mnemonic = "fadd.s"; + INSTR_FSUB: this.m_mnemonic = "fsub.s"; + INSTR_FMUL: this.m_mnemonic = "fmul.s"; + INSTR_FDIV: this.m_mnemonic = "fdiv.s"; + INSTR_FSQRT: this.m_mnemonic = "fsqrt.s"; + INSTR_FSGNJS: this.m_mnemonic = "fsgnj.s"; + INSTR_FSGNJNS: this.m_mnemonic = "fsgnjn.s"; + INSTR_FSGNJXS: this.m_mnemonic = "fsgnjx.s"; + INSTR_FMIN: this.m_mnemonic = "fmin.s"; + INSTR_FMAX: this.m_mnemonic = "fmax.s"; + INSTR_FCVTWS: this.m_mnemonic = "fcvt.w.s"; + INSTR_FCVTWUS: this.m_mnemonic = "fcvt.wu.s"; + INSTR_FMVXS: this.m_mnemonic = "fmv.x.s"; + INSTR_FEQS: this.m_mnemonic = "feq.s"; + INSTR_FLTS: this.m_mnemonic = "flt.s"; + INSTR_FLES: this.m_mnemonic = "fle.s"; + INSTR_FCLASS: this.m_mnemonic = "fclass.s"; + INSTR_FCVTSW: this.m_mnemonic = "fcvt.s.w"; + INSTR_FCVTSWU: this.m_mnemonic = "fcvt.s.wu"; + INSTR_FMVSX: this.m_mnemonic = "fmv.s.x"; + + // RV32A + INSTR_LR : this.m_mnemonic = "lr.w"; + INSTR_SC : this.m_mnemonic = "sc.w"; + INSTR_AMOSWAP : this.m_mnemonic = "amoswap.w"; + INSTR_AMOADD : this.m_mnemonic = "amoadd.w"; + INSTR_AMOXOR : this.m_mnemonic = "amoxor.w"; + INSTR_AMOAND : this.m_mnemonic = "amoand.w"; + INSTR_AMOOR : this.m_mnemonic = "amoor.w"; + INSTR_AMOMIN : this.m_mnemonic = "amomin.w"; + INSTR_AMOMAX : this.m_mnemonic = "amomax.w"; + INSTR_AMOMINU : this.m_mnemonic = "amominu.w"; + INSTR_AMOMAXU : this.m_mnemonic = "amomaxu.w"; + + // LOAD STORE + INSTR_LB : this.m_mnemonic = "lb"; + INSTR_LH : this.m_mnemonic = "lh"; + INSTR_LW : this.m_mnemonic = "lw"; + INSTR_LBU : this.m_mnemonic = "lbu"; + INSTR_LHU : this.m_mnemonic = "lhu"; + INSTR_SB : this.m_mnemonic = "sb"; + INSTR_SH : this.m_mnemonic = "sh"; + INSTR_SW : this.m_mnemonic = "sw"; + + // CUSTOM 0 + // Post-Increment Register-Immediate Load + INSTR_CVLBI : this.m_mnemonic = "cv.lb"; + INSTR_CVLBUI : this.m_mnemonic = "cv.lbu"; + INSTR_CVLHI : this.m_mnemonic = "cv.lh"; + INSTR_CVLHUI : this.m_mnemonic = "cv.lhu"; + INSTR_CVLWI : this.m_mnemonic = "cv.lw"; + + // Event Load + INSTR_CVELW : this.m_mnemonic = "cv.elw"; + + // CUSTOM_1 + // Post-Increment Register-Register Load + INSTR_CVLBR : this.m_mnemonic = "cv.lb"; + INSTR_CVLBUR : this.m_mnemonic = "cv.lbu"; + INSTR_CVLHR : this.m_mnemonic = "cv.lh"; + INSTR_CVLHUR : this.m_mnemonic = "cv.lhu"; + INSTR_CVLWR : this.m_mnemonic = "cv.lw"; + + // Register-Register Load + INSTR_CVLBRR : this.m_mnemonic = "cv.lb"; + INSTR_CVLBURR : this.m_mnemonic = "cv.lbu"; + INSTR_CVLHRR : this.m_mnemonic = "cv.lh"; + INSTR_CVLHURR : this.m_mnemonic = "cv.lhu"; + INSTR_CVLWRR : this.m_mnemonic = "cv.lw"; + + // Post-Increment Register-Immediate Store + INSTR_CVSBI : this.m_mnemonic = "cv.sb"; + INSTR_CVSHI : this.m_mnemonic = "cv.sh"; + INSTR_CVSWI : this.m_mnemonic = "cv.sw"; + + // Post-Increment Register-Register Store operations encoding + INSTR_CVSBR : this.m_mnemonic = "cv.sb"; + INSTR_CVSHR : this.m_mnemonic = "cv.sh"; + INSTR_CVSWR : this.m_mnemonic = "cv.sw"; + + // Register-Register Store operations + INSTR_CVSBRR : this.m_mnemonic = "cv.sb"; + INSTR_CVSHRR : this.m_mnemonic = "cv.sh"; + INSTR_CVSWRR : this.m_mnemonic = "cv.sw"; + + // Hardware Loops + INSTR_CVSTARTI0 : this.m_mnemonic = "cv.starti 0"; + INSTR_CVSTART0 : this.m_mnemonic = "cv.start 0"; + INSTR_CVSENDI0 : this.m_mnemonic = "cv.endi 0"; + INSTR_CVEND0 : this.m_mnemonic = "cv.end 0"; + INSTR_CVCOUNTI0 : this.m_mnemonic = "cv.counti 0"; + INSTR_CVCOUNT0 : this.m_mnemonic = "cv.count 0"; + INSTR_CVSETUPI0 : this.m_mnemonic = "cv.setupi 0"; + INSTR_CVSETUP0 : this.m_mnemonic = "cv.setup 0"; + INSTR_CVSTARTI1 : this.m_mnemonic = "cv..starti 1"; + INSTR_CVSTART1 : this.m_mnemonic = "cv..start 1"; + INSTR_CVSENDI1 : this.m_mnemonic = "cv..endi 1"; + INSTR_CVEND1 : this.m_mnemonic = "cv..end 1"; + INSTR_CVCOUNTI1 : this.m_mnemonic = "cv..counti 1"; + INSTR_CVCOUNT1 : this.m_mnemonic = "cv..count 1"; + INSTR_CVSETUPI1 : this.m_mnemonic = "cv..setupi 1"; + INSTR_CVSETUP1 : this.m_mnemonic = "cv..setup 1"; + + // CUSTOM 3 + // SIMD ALU + INSTR_CVADDH : this.m_mnemonic = "cv.add.h"; + INSTR_CVADDSCH : this.m_mnemonic = "cv.add.sc.h"; + INSTR_CVADDSCIH : this.m_mnemonic = "cv.add.sci.h"; + INSTR_CVADDB : this.m_mnemonic = "cv.add.b"; + INSTR_CVADDSCB : this.m_mnemonic = "cv.add.sc.b"; + INSTR_CVADDSCIB : this.m_mnemonic = "cv.add.sci.b"; + INSTR_CVSUBH : this.m_mnemonic = "cv.sub.h"; + INSTR_CVSUBSCH : this.m_mnemonic = "cv.sub.sc.h"; + INSTR_CVSUBSCIH : this.m_mnemonic = "cv.sub.sci.h"; + INSTR_CVSUBB : this.m_mnemonic = "cv.sub.b"; + INSTR_CVSUBSCB : this.m_mnemonic = "cv.sub.sc.b"; + INSTR_CVSUBSCIB : this.m_mnemonic = "cv.sub.sci.b"; + INSTR_CVAVGH : this.m_mnemonic = "cv.avg.h"; + INSTR_CVAVGSCH : this.m_mnemonic = "cv.avg.sc.h"; + INSTR_CVAVGSCIH : this.m_mnemonic = "cv.avg.sci.h"; + INSTR_CVAVGB : this.m_mnemonic = "cv.avg.b"; + INSTR_CVAVGSCB : this.m_mnemonic = "cv.avg.sc.b"; + INSTR_CVAVGSCIB : this.m_mnemonic = "cv.avg.sci.b"; + INSTR_CVAVGUH : this.m_mnemonic = "cv.avgu.h"; + INSTR_CVAVGUSCH : this.m_mnemonic = "cv.avgu.sc.h"; + INSTR_CVAVGUSCIH : this.m_mnemonic = "cv.avgu.sci.h"; + INSTR_CVAVGUB : this.m_mnemonic = "cv.avgu.b"; + INSTR_CVAVGUSCB : this.m_mnemonic = "cv.avgu.sc.b"; + INSTR_CVAVGUSCIB : this.m_mnemonic = "cv.avgu.sci.b"; + INSTR_CVMINH : this.m_mnemonic = "cv.min.h"; + INSTR_CVMINSCH : this.m_mnemonic = "cv.min.sc.h"; + INSTR_CVMINSCIH : this.m_mnemonic = "cv.min.sci.h"; + INSTR_CVMINB : this.m_mnemonic = "cv.min.b"; + INSTR_CVMINSCB : this.m_mnemonic = "cv.min.sc.b"; + INSTR_CVMINSCIB : this.m_mnemonic = "cv.min.sci.b"; + INSTR_CVMINUH : this.m_mnemonic = "cv.minu.h"; + INSTR_CVMINUSCH : this.m_mnemonic = "cv.minu.sc.h"; + INSTR_CVMINUSCIH : this.m_mnemonic = "cv.minu.sci.h"; + INSTR_CVMINUB : this.m_mnemonic = "cv.minu.b"; + INSTR_CVMINUSCB : this.m_mnemonic = "cv.minu.sc.b"; + INSTR_CVMINUSCIB : this.m_mnemonic = "cv.minu.sci.b"; + INSTR_CVMAXH : this.m_mnemonic = "cv.max.h"; + INSTR_CVMAXSCH : this.m_mnemonic = "cv.max.sc.h"; + INSTR_CVMAXSCIH : this.m_mnemonic = "cv.max.sci.h"; + INSTR_CVMAXB : this.m_mnemonic = "cv.max.b"; + INSTR_CVMAXSCB : this.m_mnemonic = "cv.max.sc.b"; + INSTR_CVMAXSCIB : this.m_mnemonic = "cv.max.sci.b"; + INSTR_CVMAXUH : this.m_mnemonic = "cv.maxu.h"; + INSTR_CVMAXUSCH : this.m_mnemonic = "cv.maxu.sc.h"; + INSTR_CVMAXUSCIH : this.m_mnemonic = "cv.maxu.sci.h"; + INSTR_CVMAXUB : this.m_mnemonic = "cv.maxu.b"; + INSTR_CVMAXUSCB : this.m_mnemonic = "cv.maxu.sc.b"; + INSTR_CVMAXUSCIB : this.m_mnemonic = "cv.maxu.sci.b"; + INSTR_CVSRLH : this.m_mnemonic = "cv.srl.h"; + INSTR_CVSRLSCH : this.m_mnemonic = "cv.srl.sc.h"; + INSTR_CVSRLSCIH : this.m_mnemonic = "cv.srl.sci.h"; + INSTR_CVSRLB : this.m_mnemonic = "cv.srl.b"; + INSTR_CVSRLSCB : this.m_mnemonic = "cv.srl.sc.b"; + INSTR_CVSRLSCIB : this.m_mnemonic = "cv.srl.sci.b"; + INSTR_CVSRAH : this.m_mnemonic = "cv.sra.h"; + INSTR_CVSRASCH : this.m_mnemonic = "cv.sra.sc.h"; + INSTR_CVSRASCIH : this.m_mnemonic = "cv.sra.sci.h"; + INSTR_CVSRAB : this.m_mnemonic = "cv.sra.b"; + INSTR_CVSRASCB : this.m_mnemonic = "cv.sra.sc.b"; + INSTR_CVSRASCIB : this.m_mnemonic = "cv.sra.sci.b"; + INSTR_CVSLLH : this.m_mnemonic = "cv.sll.h"; + INSTR_CVSLLSCH : this.m_mnemonic = "cv.sll.sc.h"; + INSTR_CVSLLSCIH : this.m_mnemonic = "cv.sll.sci.h"; + INSTR_CVSLLB : this.m_mnemonic = "cv.sll.b"; + INSTR_CVSLLSCB : this.m_mnemonic = "cv.sll.sc.b"; + INSTR_CVSLLSCIB : this.m_mnemonic = "cv.sll.sci.b"; + INSTR_CVORH : this.m_mnemonic = "cv.or.h"; + INSTR_CVORSCH : this.m_mnemonic = "cv.or.sc.h"; + INSTR_CVORSCIH : this.m_mnemonic = "cv.or.sci.h"; + INSTR_CVORB : this.m_mnemonic = "cv.or.b"; + INSTR_CVORSCB : this.m_mnemonic = "cv.or.sc.b"; + INSTR_CVORSCIB : this.m_mnemonic = "cv.or.sci.b"; + INSTR_CVXORH : this.m_mnemonic = "cv.xor.h"; + INSTR_CVXORSCH : this.m_mnemonic = "cv.xor.sc.h"; + INSTR_CVXORSCIH : this.m_mnemonic = "cv.xor.sci.h"; + INSTR_CVXORB : this.m_mnemonic = "cv.xor.b"; + INSTR_CVXORSCB : this.m_mnemonic = "cv.xor.sc.b"; + INSTR_CVXORSCIB : this.m_mnemonic = "cv.xor.sci.b"; + INSTR_CVANDH : this.m_mnemonic = "cv.and.h"; + INSTR_CVANDSCH : this.m_mnemonic = "cv.and.sc.h"; + INSTR_CVANDSCIH : this.m_mnemonic = "cv.and.sci.h"; + INSTR_CVANDB : this.m_mnemonic = "cv.and.b"; + INSTR_CVANDSCB : this.m_mnemonic = "cv.and.sc.b"; + INSTR_CVANDSCIB : this.m_mnemonic = "cv.and.sci.b"; + INSTR_CVABSH : this.m_mnemonic = "cv.abs.h"; + INSTR_CVABSB : this.m_mnemonic = "cv.abs.b"; + INSTR_CVEXTRACTH : this.m_mnemonic = "cv.extract.h"; + INSTR_CVEXTRACTB : this.m_mnemonic = "cv.extract.b"; + INSTR_CVEXTRACTUH : this.m_mnemonic = "cv.extractu.h"; + INSTR_CVEXTRACTUB : this.m_mnemonic = "cv.extractu.b"; + INSTR_CVINSERTH : this.m_mnemonic = "cv.insert.h"; + INSTR_CVINSERTB : this.m_mnemonic = "cv.insert.b"; + INSTR_CVDOTUPH : this.m_mnemonic = "cv.dotup.h"; + INSTR_CVDOTUPSCH : this.m_mnemonic = "cv.dotup.sc.h"; + INSTR_CVDOTUPSCIH : this.m_mnemonic = "cv.dotup.sci.h"; + INSTR_CVDOTUPB : this.m_mnemonic = "cv.dotup.b"; + INSTR_CVDOTUPSCB : this.m_mnemonic = "cv.dotup.sc.b"; + INSTR_CVDOTUPSCIB : this.m_mnemonic = "cv.dotup.sci.b"; + INSTR_CVDOTUSPH : this.m_mnemonic = "cv.dotusp.h.h"; + INSTR_CVDOTUSPSCH : this.m_mnemonic = "cv.dotusp.sc.h.sc.h"; + INSTR_CVDOTUSPSCIH : this.m_mnemonic = "cv.dotusp.sci.h.sci.h"; + INSTR_CVDOTUSPB : this.m_mnemonic = "cv.dotusp.b.b"; + INSTR_CVDOTUSPSCB : this.m_mnemonic = "cv.dotusp.sc.b.sc.b"; + INSTR_CVDOTUSPSCIB : this.m_mnemonic = "cv.dotusp.sci.b.sci.b"; + INSTR_CVDOTSPH : this.m_mnemonic = "cv.dotsp.h"; + INSTR_CVDOTSPSCH : this.m_mnemonic = "cv.dotsp.sc.h"; + INSTR_CVDOTSPSCIH : this.m_mnemonic = "cv.dotsp.sci.h"; + INSTR_CVDOTSPB : this.m_mnemonic = "cv.dotsp.b"; + INSTR_CVDOTSPSCB : this.m_mnemonic = "cv.dotsp.sc.b"; + INSTR_CVDOTSPSCIB : this.m_mnemonic = "cv.dotsp.sci.b"; + INSTR_CVSDOTUPH : this.m_mnemonic = "cv.sdotup.h"; + INSTR_CVSDOTUPSCH : this.m_mnemonic = "cv.sdotup.sc.h"; + INSTR_CVSDOTUPSCIH : this.m_mnemonic = "cv.sdotup.sci.h"; + INSTR_CVSDOTUPB : this.m_mnemonic = "cv.sdotup.b"; + INSTR_CVSDOTUPSCB : this.m_mnemonic = "cv.sdotup.sc.b"; + INSTR_CVSDOTUPSCIB : this.m_mnemonic = "cv.sdotup.sci.b"; + INSTR_CVSDOTUSPH : this.m_mnemonic = "cv.sdotusp.h"; + INSTR_CVSDOTUSPSCH : this.m_mnemonic = "cv.sdotusp.sc.h"; + INSTR_CVSDOTUSPSCIH : this.m_mnemonic = "cv.sdotusp.sci.h"; + INSTR_CVSDOTUSPB : this.m_mnemonic = "cv.sdotusp.b"; + INSTR_CVSDOTUSPSCB : this.m_mnemonic = "cv.sdotusp.sc.b"; + INSTR_CVSDOTUSPSCIB : this.m_mnemonic = "cv.sdotusp.sci.b"; + INSTR_CVSDOTSPH : this.m_mnemonic = "cv.sdotsp.h"; + INSTR_CVSDOTSPSCH : this.m_mnemonic = "cv.sdotsp.sc.h"; + INSTR_CVSDOTSPSCIH : this.m_mnemonic = "cv.sdotsp.sci.h"; + INSTR_CVSDOTSPB : this.m_mnemonic = "cv.sdotsp.b"; + INSTR_CVSDOTSPSCB : this.m_mnemonic = "cv.sdotsp.sc.b"; + INSTR_CVSDOTSPSCIB : this.m_mnemonic = "cv.sdotsp.sci.b"; + INSTR_CVSHUFFLEH : this.m_mnemonic = "cv.shuffle.h"; + INSTR_CVSHUFFLESCIH : this.m_mnemonic = "cv.shuffle.sci.h"; + INSTR_CVSHUFFLEB : this.m_mnemonic = "cv.shuffle.b"; + INSTR_CVSHUFFLEL0SCIB : this.m_mnemonic = "cv.shufflel0.sci.b"; + INSTR_CVSHUFFLEL1SCIB : this.m_mnemonic = "cv.shufflel1.sci.b"; + INSTR_CVSHUFFLEL2SCIB : this.m_mnemonic = "cv.shufflel2.sci.b"; + INSTR_CVSHUFFLEL3SCIB : this.m_mnemonic = "cv.shufflel3.sci.b"; + INSTR_CVSHUFFLE2H : this.m_mnemonic = "cv.shuffle2.h"; + INSTR_CVSHUFFLE2B : this.m_mnemonic = "cv.shuffle2.b"; + INSTR_CVPACK : this.m_mnemonic = "cv.pack"; + INSTR_CVPACKH : this.m_mnemonic = "cv.pack.h"; + INSTR_CVPACKHIB : this.m_mnemonic = "cv.packhi.b"; + INSTR_CVPACKLOB : this.m_mnemonic = "cv.packlo.b"; + + // SIMD COMPARISON + INSTR_CVCMPEQH : this.m_mnemonic = "cv.cmpeq.h"; + INSTR_CVCMPEQSCH : this.m_mnemonic = "cv.cmpeq.sc.h"; + INSTR_CVCMPEQSCIH : this.m_mnemonic = "cv.cmpeq.sci.h"; + INSTR_CVCMPEQB : this.m_mnemonic = "cv.cmpeq.b"; + INSTR_CVCMPEQSCB : this.m_mnemonic = "cv.cmpeq.sc.b"; + INSTR_CVCMPEQSCIB : this.m_mnemonic = "cv.cmpeq.sci.b"; + INSTR_CVCMPNEH : this.m_mnemonic = "cv.cmpne.h"; + INSTR_CVCMPNESCH : this.m_mnemonic = "cv.cmpne.sc.h"; + INSTR_CVCMPNESCIH : this.m_mnemonic = "cv.cmpne.sci.h"; + INSTR_CVCMPNEB : this.m_mnemonic = "cv.cmpne.b"; + INSTR_CVCMPNESCB : this.m_mnemonic = "cv.cmpne.sc.b"; + INSTR_CVCMPNESCIB : this.m_mnemonic = "cv.cmpne.sci.b"; + INSTR_CVCMPGTH : this.m_mnemonic = "cv.cmpgt.h"; + INSTR_CVCMPGTSCH : this.m_mnemonic = "cv.cmpgt.sc.h"; + INSTR_CVCMPGTSCIH : this.m_mnemonic = "cv.cmpgt.sci.h"; + INSTR_CVCMPGTB : this.m_mnemonic = "cv.cmpgt.b"; + INSTR_CVCMPGTSCB : this.m_mnemonic = "cv.cmpgt.sc.b"; + INSTR_CVCMPGTSCIB : this.m_mnemonic = "cv.cmpgt.sci.b"; + INSTR_CVCMPGEH : this.m_mnemonic = "cv.cmpge.h"; + INSTR_CVCMPGESCH : this.m_mnemonic = "cv.cmpge.sc.h"; + INSTR_CVCMPGESCIH : this.m_mnemonic = "cv.cmpge.sci.h"; + INSTR_CVCMPGEB : this.m_mnemonic = "cv.cmpge.b"; + INSTR_CVCMPGESCB : this.m_mnemonic = "cv.cmpge.sc.b"; + INSTR_CVCMPGESCIB : this.m_mnemonic = "cv.cmpge.sci.b"; + INSTR_CVCMPLTH : this.m_mnemonic = "cv.cmplt.h"; + INSTR_CVCMPLTSCH : this.m_mnemonic = "cv.cmplt.sc.h"; + INSTR_CVCMPLTSCIH : this.m_mnemonic = "cv.cmplt.sci.h"; + INSTR_CVCMPLTB : this.m_mnemonic = "cv.cmplt.b"; + INSTR_CVCMPLTSCB : this.m_mnemonic = "cv.cmplt.sc.b"; + INSTR_CVCMPLTSCIB : this.m_mnemonic = "cv.cmplt.sci.b"; + INSTR_CVCMPLEH : this.m_mnemonic = "cv.cmple.h"; + INSTR_CVCMPLESCH : this.m_mnemonic = "cv.cmple.sc.h"; + INSTR_CVCMPLESCIH : this.m_mnemonic = "cv.cmple.sci.h"; + INSTR_CVCMPLEB : this.m_mnemonic = "cv.cmple.b"; + INSTR_CVCMPLESCB : this.m_mnemonic = "cv.cmple.sc.b"; + INSTR_CVCMPLESCIB : this.m_mnemonic = "cv.cmple.sci.b"; + INSTR_CVCMPGTUH : this.m_mnemonic = "cv.cmptu.h"; + INSTR_CVCMPGTUSCH : this.m_mnemonic = "cv.cmptu.sc.h"; + INSTR_CVCMPGTUSCIH : this.m_mnemonic = "cv.cmptu.sci.h"; + INSTR_CVCMPGTUB : this.m_mnemonic = "cv.cmptu.b"; + INSTR_CVCMPGTUSCB : this.m_mnemonic = "cv.cmptu.sc.b"; + INSTR_CVCMPGTUSCIB : this.m_mnemonic = "cv.cmptu.sci.b"; + INSTR_CVCMPGEUH : this.m_mnemonic = "cv.cmpgeu.h"; + INSTR_CVCMPGEUSCH : this.m_mnemonic = "cv.cmpgeu.sc.h"; + INSTR_CVCMPGEUSCIH : this.m_mnemonic = "cv.cmpgeu.sci.h"; + INSTR_CVCMPGEUB : this.m_mnemonic = "cv.cmpgeu.b"; + INSTR_CVCMPGEUSCB : this.m_mnemonic = "cv.cmpgeu.sc.b"; + INSTR_CVCMPGEUSCIB : this.m_mnemonic = "cv.cmpgeu.sci.b"; + INSTR_CVCMPLTUH : this.m_mnemonic = "cv.cmpltu.h"; + INSTR_CVCMPLTUSCH : this.m_mnemonic = "cv.cmpltu.sc.h"; + INSTR_CVCMPLTUSCIH : this.m_mnemonic = "cv.cmpltu.sci.h"; + INSTR_CVCMPLTUB : this.m_mnemonic = "cv.cmpltu.b"; + INSTR_CVCMPLTUSCB : this.m_mnemonic = "cv.cmpltu.sc.b"; + INSTR_CVCMPLTUSCIB : this.m_mnemonic = "cv.cmpltu.sci.b"; + INSTR_CVCMPLEUH : this.m_mnemonic = "cv.cmpleu.h"; + INSTR_CVCMPLEUSCH : this.m_mnemonic = "cv.cmpleu.sc.h"; + INSTR_CVCMPLEUSCIH : this.m_mnemonic = "cv.cmpleu.sci.h"; + INSTR_CVCMPLEUB : this.m_mnemonic = "cv.cmpleu.b"; + INSTR_CVCMPLEUSCB : this.m_mnemonic = "cv.cmpleu.sc.b"; + INSTR_CVCMPLEUSCIB : this.m_mnemonic = "cv.cmpleu.sci.b"; + + // SIMD CPLX + INSTR_CVCPLXMULR : this.m_mnemonic = "cv.cplxmul.r"; + INSTR_CVCPLXMULRDIV2 : this.m_mnemonic = "cv.cplxmul.r.div2"; + INSTR_CVCPLXMULRDIV4 : this.m_mnemonic = "cv.cplxmul.r.div4"; + INSTR_CVCPLXMULRDIV8 : this.m_mnemonic = "cv.cplxmul.r.div8"; + INSTR_CVCPLXMULI : this.m_mnemonic = "cv.cplxmul.i"; + INSTR_CVCPLXMULIDIV2 : this.m_mnemonic = "cv.cplxmul.i.div2"; + INSTR_CVCPLXMULIDIV4 : this.m_mnemonic = "cv.cplxmul.i.div4"; + INSTR_CVCPLXMULIDIV8 : this.m_mnemonic = "cv.cplxmul.i.div8"; + INSTR_CVCPLXCONJ : this.m_mnemonic = "cv.cplxconj"; + INSTR_CVSUBROTMJ : this.m_mnemonic = "cv.subrotmj"; + INSTR_CVSUBROTMJDIV2 : this.m_mnemonic = "cv.subrotmj.div2"; + INSTR_CVSUBROTMJDIV4 : this.m_mnemonic = "cv.subrotmj.div4"; + INSTR_CVSUBROTMJDIV8 : this.m_mnemonic = "cv.subrotmj.div8"; + INSTR_CVADDIV2 : this.m_mnemonic = "cv.add.div2"; + INSTR_CVADDIV4 : this.m_mnemonic = "cv.add.div4"; + INSTR_CVADDIV8 : this.m_mnemonic = "cv.add.div8"; + INSTR_CVSUBIV2 : this.m_mnemonic = "cv.sub.div2"; + INSTR_CVSUBIV4 : this.m_mnemonic = "cv.sub.div4"; + INSTR_CVSUBIV8 : this.m_mnemonic = "cv.sub.div8"; + + default : this.m_mnemonic = "INVALID"; + endcase // unique case (instr) + end else begin //Compressed instruction + unique case (this.m_insn[1:0]) + // C0 + 2'b00: begin + unique case (this.m_insn[15:13]) + 3'b000: begin + // c.addi4spn -> addi rd', x2, imm + this.m_mnemonic = "c.addi4spn"; + end + + 3'b001: begin this.m_mnemonic = "c.fld"; end + 3'b010: begin this.m_mnemonic = "c.lw"; end + 3'b011: begin this.m_mnemonic = "c.flw"; end + 3'b101: begin this.m_mnemonic = "c.fsd"; end + 3'b110: begin this.m_mnemonic = "c.sw"; end + 3'b111: begin this.m_mnemonic = "c.fsw"; end + default: begin this.m_mnemonic = "INVALID"; end + endcase + end + + // C1 + 2'b01: begin + unique case (this.m_insn[15:13]) + 3'b000: begin + // c.addi -> addi rd, rd, nzimm + // c.nop + if(this.m_insn[11:7] == '0) begin + this.m_mnemonic = "c.nop"; + end else begin + this.m_mnemonic = "c.addi"; + end + end + 3'b001: this.m_mnemonic = "c.jal"; + 3'b101: this.m_mnemonic = "c.j"; + + 3'b010: begin + if (this.m_insn[11:7] == 5'b0) begin + // Hint -> addi x0, x0, nzimm + this.m_mnemonic = "HINT"; + end else begin + this.m_mnemonic = "c.li"; + end + end + + 3'b011: begin + if ({this.m_insn[12], this.m_insn[6:2]} == 6'b0) begin + this.m_mnemonic = "INVALID"; + end else begin + if (this.m_insn[11:7] == 5'h02) begin + // c.addi16sp -> addi x2, x2, nzimm + this.m_mnemonic = "c.addi16sp"; + end else if (this.m_insn[11:7] == 5'b0) begin + // Hint -> lui x0, imm + this.m_mnemonic = "HINT"; + end else begin + this.m_mnemonic = "c.lui"; + end + end + end + + 3'b100: begin + unique case (this.m_insn[11:10]) + 2'b00 : begin + // 00: c.srli -> srli rd, rd, shamt + // 01: c.srai -> srai rd, rd, shamt + if (this.m_insn[12] == 1'b1) begin + // Reserved for future custom extensions (instr_o don't care) + this.m_mnemonic = "INVALID"; + end else begin + if (this.m_insn[6:2] == 5'b0) begin + // Hint + this.m_mnemonic = "HINT"; + end else begin + this.m_mnemonic = "c.srli"; + end + end + end + 2'b01 : begin + if (this.m_insn[12] == 1'b1) begin + // Reserved for future custom extensions (instr_o don't care) + this.m_mnemonic = "INVALID"; + end else begin + if (this.m_insn[6:2] == 5'b0) begin + // Hint + this.m_mnemonic = "HINT"; + end else begin + this.m_mnemonic = "c.srai"; + end + end + end + + 2'b10: begin this.m_mnemonic = "c.andi"; end + + 2'b11: begin + unique case ({ this.m_insn[12], this.m_insn[6:5] }) + 3'b000: begin this.m_mnemonic = "c.sub"; end + 3'b001: begin this.m_mnemonic = "c.xor"; end + 3'b010: begin this.m_mnemonic = "c.or"; end + 3'b011: begin this.m_mnemonic = "c.and"; end + 3'b100 : this.m_mnemonic = "c.subw"; + 3'b101 : this.m_mnemonic = "c.addw"; + + 3'b110, 3'b111: begin + this.m_mnemonic = "INVALID"; + end + + endcase + end + endcase + end + + 3'b110: begin this.m_mnemonic = "c.beqz"; end + 3'b111: begin this.m_mnemonic = "c.bnez"; end + endcase + end + + // C2 + 2'b10: begin + unique case (this.m_insn[15:13]) + 3'b000: begin + if (this.m_insn[12] == 1'b1) begin + // Reserved for future extensions (instr_o don't care) + this.m_mnemonic = "TODO"; + end else begin + if ((this.m_insn[6:2] == 5'b0) || (this.m_insn[11:7] == 5'b0)) begin + // Hint -> slli rd, rd, shamt + this.m_mnemonic = "HINT"; + end else begin + this.m_mnemonic = "c.slli"; + end + end + end + + 3'b001: begin this.m_mnemonic = "c.fldsp"; end + 3'b010: begin this.m_mnemonic = "c.lwsp"; end + 3'b011: begin this.m_mnemonic = "c.flwsp"; end + + 3'b100: begin + if (this.m_insn[12] == 1'b0) begin + if (this.m_insn[6:2] == 5'b0) begin + this.m_mnemonic = "c.jr"; + end else begin + if (this.m_insn[11:7] == 5'b0) begin + // Hint -> add x0, x0, rs2 + this.m_mnemonic = "HINT"; + end else begin + this.m_mnemonic = "c.mv"; + end + end + end else begin + if (this.m_insn[6:2] == 5'b0) begin + if (this.m_insn[11:7] == 5'b0) begin + this.m_mnemonic = "c.ebreak"; + end else begin + this.m_mnemonic = "c.jalr"; + end + end else begin + if (this.m_insn[11:7] == 5'b0) begin + // Hint -> add x0, x0, rs2 + this.m_mnemonic = "HINT"; + end else begin + this.m_mnemonic = "c.add"; + end + end + end + end + + 3'b101: begin this.m_mnemonic = "c.fsdsp"; end + 3'b110: begin this.m_mnemonic = "c.swsp"; end + 3'b111: begin this.m_mnemonic = "c.fswsp"; end + endcase + end + endcase + end + endfunction + + function void init_csr(); + `INIT_CSR(mstatus) + `INIT_CSR(mstatus_fs) + `INIT_CSR(misa) + `INIT_CSR(mie) + `INIT_CSR(mtvec) + `INIT_CSR(mcountinhibit) + `INIT_CSR(mscratch) + `INIT_CSR(mepc) + `INIT_CSR(mcause) + `INIT_CSR(minstret) + `INIT_CSR(mip) + `INIT_CSR(tdata1) + `INIT_CSR(tdata2) + `INIT_CSR(tinfo) + `INIT_CSR(dcsr) + `INIT_CSR(dpc) + `INIT_CSR(dscratch0) + `INIT_CSR(dscratch1) + `INIT_CSR(mvendorid) + `INIT_CSR(marchid) + `INIT_CSR(fflags) + `INIT_CSR(frm ) + `INIT_CSR(fcsr ) + `INIT_CSR(lpstart0 ) + `INIT_CSR(lpend0 ) + `INIT_CSR(lpcount0 ) + `INIT_CSR(lpstart1 ) + `INIT_CSR(lpend1 ) + `INIT_CSR(lpcount1 ) + endfunction /* * */ @@ -172,6 +886,7 @@ this.m_apu_req_id = 0; this.m_mem_req_id[0] = 0; this.m_mem_req_id[1] = 0; + this.m_mem_req_id_valid = '0; this.m_data_missaligned = 1'b0; this.m_got_first_data = 1'b0; this.m_got_ex_reg = 1'b0; @@ -183,12 +898,14 @@ this.m_2_rd_insn = 1'b0; this.m_rs1_addr = '0; this.m_rs2_addr = '0; + this.m_rs3_addr = '0; this.m_ex_fw = '0; this.m_csr.got_minstret = '0; this.m_dbg_taken = '0; this.m_trap = 1'b0; this.m_fflags_we_non_apu = 1'b0; this.m_frm_we_non_apu = 1'b0; + this.m_fcsr_we_non_apu = 1'b0; this.m_csr.mcause_we = '0; if (is_compressed_id_i) begin this.m_insn[31:16] = '0; @@ -196,6 +913,7 @@ end else begin this.m_insn = m_source.m_insn; end + this.get_mnemonic(); this.m_intr = m_source.m_intr; this.m_dbg_taken = m_source.m_dbg_taken; @@ -205,14 +923,18 @@ this.m_rs1_addr = r_pipe_freeze_trace.rs1_addr_id; this.m_rs2_addr = r_pipe_freeze_trace.rs2_addr_id; + this.m_rs3_addr = r_pipe_freeze_trace.rs3_addr_id; this.m_rs1_rdata = r_pipe_freeze_trace.operand_a_fw_id; this.m_rs2_rdata = r_pipe_freeze_trace.operand_b_fw_id; + this.m_rs3_rdata = r_pipe_freeze_trace.operand_c_fw_id; this.m_mem.addr = '0; this.m_mem.rmask = '0; this.m_mem.wmask = '0; this.m_mem.rdata = '0; this.m_mem.wdata = '0; + + init_csr(); endfunction function logic [63:0] get_order_for_trap(); @@ -227,12 +949,14 @@ this.m_order = m_source.m_order; this.m_pc_rdata = m_source.m_pc_rdata; this.m_insn = m_source.m_insn; + this.m_mnemonic = m_source.m_mnemonic; this.m_is_memory = m_source.m_is_memory; this.m_is_load = m_source.m_is_load; this.m_is_apu = m_source.m_is_apu; this.m_is_apu_ok = m_source.m_is_apu_ok; this.m_apu_req_id = m_source.m_apu_req_id; this.m_mem_req_id = m_source.m_mem_req_id; + this.m_mem_req_id_valid = m_source.m_mem_req_id_valid; this.m_data_missaligned = m_source.m_data_missaligned; this.m_got_first_data = m_source.m_got_first_data; this.m_got_ex_reg = m_source.m_got_ex_reg; @@ -244,8 +968,10 @@ this.m_instret_cnt = m_source.m_instret_cnt; this.m_rs1_addr = m_source.m_rs1_addr; this.m_rs2_addr = m_source.m_rs2_addr; + this.m_rs3_addr = m_source.m_rs3_addr; this.m_rs1_rdata = m_source.m_rs1_rdata; this.m_rs2_rdata = m_source.m_rs2_rdata; + this.m_rs3_rdata = m_source.m_rs3_rdata; this.m_ex_fw = m_source.m_ex_fw; this.m_rd_addr = m_source.m_rd_addr; @@ -256,10 +982,12 @@ this.m_trap = m_source.m_trap; this.m_fflags_we_non_apu = m_source.m_fflags_we_non_apu; this.m_frm_we_non_apu = m_source.m_frm_we_non_apu ; + this.m_fcsr_we_non_apu = m_source.m_fcsr_we_non_apu; this.m_mem = m_source.m_mem; //CRS `ASSIGN_CSR(mstatus) + `ASSIGN_CSR(mstatus_fs) `ASSIGN_CSR(misa) `ASSIGN_CSR(mie) `ASSIGN_CSR(mtvec) diff --git a/hw/vendor/openhwgroup_cv32e40p/bhv/pipe_freeze_trace.sv b/hw/vendor/openhwgroup_cv32e40p/bhv/pipe_freeze_trace.sv index b5d433df1..58051ab8e 100644 --- a/hw/vendor/openhwgroup_cv32e40p/bhv/pipe_freeze_trace.sv +++ b/hw/vendor/openhwgroup_cv32e40p/bhv/pipe_freeze_trace.sv @@ -76,8 +76,10 @@ typedef struct { // Register reads logic [5:0] rs1_addr_id; logic [5:0] rs2_addr_id; + logic [5:0] rs3_addr_id; logic [31:0] operand_a_fw_id; logic [31:0] operand_b_fw_id; + logic [31:0] operand_c_fw_id; //// EX probes //// @@ -94,6 +96,7 @@ typedef struct { logic apu_multicycle; logic wb_contention_lsu; logic wb_contention; + logic regfile_we_lsu; logic branch_in_ex; logic branch_decision_ex; @@ -121,6 +124,7 @@ typedef struct { logic rf_we_wb; logic [5:0] rf_addr_wb; logic [31:0] rf_wdata_wb; + logic rf_alu_we_ex; // LSU logic [31:0] lsu_rdata_wb; @@ -141,6 +145,7 @@ typedef struct { logic p_elw_finish; logic lsu_ready_ex; logic lsu_ready_wb; + logic [3:0] lsu_data_be; logic data_req_pmp; logic data_gnt_pmp; logic data_rvalid; @@ -185,6 +190,7 @@ typedef struct { logic [31:0] wdata_int; logic mstatus_we; + logic mstatus_fs_we; logic misa_we; logic mtvec_we; logic mscratch_we; @@ -197,8 +203,6 @@ typedef struct { Status_t mstatus_q; FS_t mstatus_fs_n; FS_t mstatus_fs_q; - logic [31:0] mstatus_full_n; - logic [31:0] mstatus_full_q; logic mstatush_we; logic [31:0] misa_n; @@ -326,20 +330,24 @@ pipe_trace_t r_pipe_freeze_trace; // Compute each CSR write enable function compute_csr_we(); - r_pipe_freeze_trace.csr.mstatus_we = 1'b0; - r_pipe_freeze_trace.csr.misa_we = 1'b0; - r_pipe_freeze_trace.csr.mtvec_we = 1'b0; - r_pipe_freeze_trace.csr.mscratch_we = 1'b0; - r_pipe_freeze_trace.csr.mepc_we = 1'b0; - r_pipe_freeze_trace.csr.mcause_we = 1'b0; - r_pipe_freeze_trace.csr.dcsr_we = 1'b0; - r_pipe_freeze_trace.csr.fflags_we = 1'b0; - r_pipe_freeze_trace.csr.frm_we = 1'b0; - r_pipe_freeze_trace.csr.fcsr_we = 1'b0; - r_pipe_freeze_trace.csr.dpc_we = csr_dpc_we_i; + r_pipe_freeze_trace.csr.mstatus_we = 1'b0; + r_pipe_freeze_trace.csr.mstatus_fs_we = 1'b0; + r_pipe_freeze_trace.csr.misa_we = 1'b0; + r_pipe_freeze_trace.csr.mtvec_we = 1'b0; + r_pipe_freeze_trace.csr.mscratch_we = 1'b0; + r_pipe_freeze_trace.csr.mepc_we = 1'b0; + r_pipe_freeze_trace.csr.mcause_we = 1'b0; + r_pipe_freeze_trace.csr.dcsr_we = 1'b0; + r_pipe_freeze_trace.csr.fflags_we = 1'b0; + r_pipe_freeze_trace.csr.frm_we = 1'b0; + r_pipe_freeze_trace.csr.fcsr_we = 1'b0; + r_pipe_freeze_trace.csr.dpc_we = csr_dpc_we_i; if (r_pipe_freeze_trace.csr.we) begin case (r_pipe_freeze_trace.csr.addr) - CSR_MSTATUS: r_pipe_freeze_trace.csr.mstatus_we = 1'b1; + CSR_MSTATUS: begin + r_pipe_freeze_trace.csr.mstatus_we = 1'b1; + r_pipe_freeze_trace.csr.mstatus_fs_we = 1'b1; + end CSR_MISA: r_pipe_freeze_trace.csr.misa_we = 1'b1; CSR_MTVEC: r_pipe_freeze_trace.csr.mtvec_we = 1'b1; CSR_MSCRATCH: r_pipe_freeze_trace.csr.mscratch_we = 1'b1; @@ -397,171 +405,132 @@ task monitor_pipeline(); //// IF probes //// if_probes(); //// ID probes //// - r_pipe_freeze_trace.pc_id = pc_id_i; - r_pipe_freeze_trace.id_valid = id_valid_i; - - r_pipe_freeze_trace.id_ready = id_ready_i; - r_pipe_freeze_trace.rf_re_id = rf_re_id_i; - r_pipe_freeze_trace.sys_en_id = sys_en_id_i; - r_pipe_freeze_trace.sys_mret_insn_id = sys_mret_insn_id_i; - r_pipe_freeze_trace.jump_in_id = jump_in_id_i; - r_pipe_freeze_trace.jump_target_id = jump_target_id_i; - r_pipe_freeze_trace.is_compressed_id = is_compressed_id_i; - r_pipe_freeze_trace.ebrk_insn_dec = ebrk_insn_dec_i; - r_pipe_freeze_trace.csr_cause = csr_cause_i; - r_pipe_freeze_trace.debug_csr_save = debug_csr_save_i; - r_pipe_freeze_trace.minstret = minstret_i; + r_pipe_freeze_trace.pc_id = pc_id_i; + r_pipe_freeze_trace.id_valid = id_valid_i; + + r_pipe_freeze_trace.id_ready = id_ready_i; + r_pipe_freeze_trace.rf_re_id = rf_re_id_i; + r_pipe_freeze_trace.sys_en_id = sys_en_id_i; + r_pipe_freeze_trace.sys_mret_insn_id = sys_mret_insn_id_i; + r_pipe_freeze_trace.jump_in_id = jump_in_id_i; + r_pipe_freeze_trace.jump_target_id = jump_target_id_i; + r_pipe_freeze_trace.is_compressed_id = is_compressed_id_i; + r_pipe_freeze_trace.ebrk_insn_dec = ebrk_insn_dec_i; + r_pipe_freeze_trace.csr_cause = csr_cause_i; + r_pipe_freeze_trace.debug_csr_save = debug_csr_save_i; + r_pipe_freeze_trace.minstret = minstret_i; // LSU - r_pipe_freeze_trace.lsu_en_id = lsu_en_id_i; - r_pipe_freeze_trace.lsu_we_id = lsu_we_id_i; - r_pipe_freeze_trace.lsu_size_id = lsu_size_id_i; + r_pipe_freeze_trace.lsu_en_id = lsu_en_id_i; + r_pipe_freeze_trace.lsu_we_id = lsu_we_id_i; + r_pipe_freeze_trace.lsu_size_id = lsu_size_id_i; // Register reads - r_pipe_freeze_trace.rs1_addr_id = rs1_addr_id_i; - r_pipe_freeze_trace.rs2_addr_id = rs2_addr_id_i; - r_pipe_freeze_trace.operand_a_fw_id = operand_a_fw_id_i; - r_pipe_freeze_trace.operand_b_fw_id = operand_b_fw_id_i; + r_pipe_freeze_trace.rs1_addr_id = rs1_addr_id_i; + r_pipe_freeze_trace.rs2_addr_id = rs2_addr_id_i; + r_pipe_freeze_trace.rs3_addr_id = rs3_addr_id_i; + r_pipe_freeze_trace.operand_a_fw_id = operand_a_fw_id_i; + r_pipe_freeze_trace.operand_b_fw_id = operand_b_fw_id_i; + r_pipe_freeze_trace.operand_c_fw_id = operand_c_fw_id_i; //// EX probes //// // Register writes in EX - r_pipe_freeze_trace.ex_ready = ex_ready_i; - r_pipe_freeze_trace.ex_valid = ex_valid_i; - - r_pipe_freeze_trace.ex_reg_we = ex_reg_we_i; - r_pipe_freeze_trace.ex_reg_addr = ex_reg_addr_i; - r_pipe_freeze_trace.ex_reg_wdata = ex_reg_wdata_i; - - r_pipe_freeze_trace.apu_en_ex = apu_en_ex_i; - r_pipe_freeze_trace.apu_singlecycle = apu_singlecycle_i; - r_pipe_freeze_trace.apu_multicycle = apu_multicycle_i; - r_pipe_freeze_trace.wb_contention_lsu = wb_contention_lsu_i; - r_pipe_freeze_trace.wb_contention = wb_contention_i; - - r_pipe_freeze_trace.branch_in_ex = branch_in_ex_i; - r_pipe_freeze_trace.branch_decision_ex = branch_decision_ex_i; - r_pipe_freeze_trace.dret_in_ex = dret_in_ex_i; + r_pipe_freeze_trace.ex_ready = ex_ready_i; + r_pipe_freeze_trace.ex_valid = ex_valid_i; + + r_pipe_freeze_trace.ex_reg_we = ex_reg_we_i; + r_pipe_freeze_trace.ex_reg_addr = ex_reg_addr_i; + r_pipe_freeze_trace.ex_reg_wdata = ex_reg_wdata_i; + + r_pipe_freeze_trace.apu_en_ex = apu_en_ex_i; + r_pipe_freeze_trace.apu_singlecycle = apu_singlecycle_i; + r_pipe_freeze_trace.apu_multicycle = apu_multicycle_i; + r_pipe_freeze_trace.wb_contention_lsu = wb_contention_lsu_i; + r_pipe_freeze_trace.wb_contention = wb_contention_i; + r_pipe_freeze_trace.regfile_we_lsu = regfile_we_lsu_i; + + r_pipe_freeze_trace.branch_in_ex = branch_in_ex_i; + r_pipe_freeze_trace.branch_decision_ex = branch_decision_ex_i; + r_pipe_freeze_trace.dret_in_ex = dret_in_ex_i; // LSU - r_pipe_freeze_trace.lsu_en_ex = lsu_en_ex_i; - r_pipe_freeze_trace.lsu_pmp_err_ex = lsu_pmp_err_ex_i; + r_pipe_freeze_trace.lsu_en_ex = lsu_en_ex_i; + r_pipe_freeze_trace.lsu_pmp_err_ex = lsu_pmp_err_ex_i; r_pipe_freeze_trace.lsu_pma_err_atomic_ex = lsu_pma_err_atomic_ex_i; - r_pipe_freeze_trace.branch_target_ex = branch_target_ex_i; + r_pipe_freeze_trace.branch_target_ex = branch_target_ex_i; - r_pipe_freeze_trace.data_addr_ex = data_addr_ex_i; - r_pipe_freeze_trace.data_wdata_ex = data_wdata_ex_i; - r_pipe_freeze_trace.lsu_split_q_ex = lsu_split_q_ex_i; + r_pipe_freeze_trace.data_addr_ex = data_addr_ex_i; + r_pipe_freeze_trace.data_wdata_ex = data_wdata_ex_i; + r_pipe_freeze_trace.lsu_split_q_ex = lsu_split_q_ex_i; //// WB probes //// - r_pipe_freeze_trace.pc_wb = pc_wb_i; - r_pipe_freeze_trace.wb_ready = wb_ready_i; - r_pipe_freeze_trace.wb_valid = wb_valid_i; - r_pipe_freeze_trace.ebreak_in_wb = ebreak_in_wb_i; - r_pipe_freeze_trace.instr_rdata_wb = instr_rdata_wb_i; - r_pipe_freeze_trace.csr_en_wb = csr_en_wb_i; - r_pipe_freeze_trace.sys_wfi_insn_wb = sys_wfi_insn_wb_i; + r_pipe_freeze_trace.pc_wb = pc_wb_i; + r_pipe_freeze_trace.wb_ready = wb_ready_i; + r_pipe_freeze_trace.wb_valid = wb_valid_i; + r_pipe_freeze_trace.ebreak_in_wb = ebreak_in_wb_i; + r_pipe_freeze_trace.instr_rdata_wb = instr_rdata_wb_i; + r_pipe_freeze_trace.csr_en_wb = csr_en_wb_i; + r_pipe_freeze_trace.sys_wfi_insn_wb = sys_wfi_insn_wb_i; // Register writes - r_pipe_freeze_trace.rf_we_wb = rf_we_wb_i; - r_pipe_freeze_trace.rf_addr_wb = rf_addr_wb_i; - r_pipe_freeze_trace.rf_wdata_wb = rf_wdata_wb_i; + r_pipe_freeze_trace.rf_we_wb = rf_we_wb_i; + r_pipe_freeze_trace.rf_addr_wb = rf_addr_wb_i; + r_pipe_freeze_trace.rf_wdata_wb = rf_wdata_wb_i; + r_pipe_freeze_trace.rf_alu_we_ex = regfile_alu_we_ex_i; // LSU - r_pipe_freeze_trace.lsu_rdata_wb = lsu_rdata_wb_i; - - r_pipe_freeze_trace.data_we_ex = data_we_ex_i; - r_pipe_freeze_trace.data_atop_ex = data_atop_ex_i; - r_pipe_freeze_trace.data_type_ex = data_type_ex_i; - r_pipe_freeze_trace.alu_operand_c_ex = alu_operand_c_ex_i; - r_pipe_freeze_trace.data_reg_offset_ex = data_reg_offset_ex_i; - r_pipe_freeze_trace.data_load_event_ex = data_load_event_ex_i; - r_pipe_freeze_trace.data_sign_ext_ex = data_sign_ext_ex_i; - r_pipe_freeze_trace.lsu_rdata = lsu_rdata_i; - r_pipe_freeze_trace.data_req_ex = data_req_ex_i; - r_pipe_freeze_trace.alu_operand_a_ex = alu_operand_a_ex_i; - r_pipe_freeze_trace.alu_operand_b_ex = alu_operand_b_ex_i; - r_pipe_freeze_trace.useincr_addr_ex = useincr_addr_ex_i; - r_pipe_freeze_trace.data_misaligned_ex = data_misaligned_ex_i; - r_pipe_freeze_trace.p_elw_start = p_elw_start_i; - r_pipe_freeze_trace.p_elw_finish = p_elw_finish_i; - r_pipe_freeze_trace.lsu_ready_ex = lsu_ready_ex_i; - r_pipe_freeze_trace.lsu_ready_wb = lsu_ready_wb_i; - - r_pipe_freeze_trace.data_req_pmp = data_req_pmp_i; - r_pipe_freeze_trace.data_gnt_pmp = data_gnt_pmp_i; - r_pipe_freeze_trace.data_rvalid = data_rvalid_i; - r_pipe_freeze_trace.data_err_pmp = data_err_pmp_i; - r_pipe_freeze_trace.data_addr_pmp = data_addr_pmp_i; - r_pipe_freeze_trace.data_we = data_we_i; - r_pipe_freeze_trace.data_atop = data_atop_i; - r_pipe_freeze_trace.data_be = data_be_i; - r_pipe_freeze_trace.data_wdata = data_wdata_i; - r_pipe_freeze_trace.data_rdata = data_rdata_i; + r_pipe_freeze_trace.lsu_rdata_wb = lsu_rdata_wb_i; + + r_pipe_freeze_trace.data_we_ex = data_we_ex_i; + r_pipe_freeze_trace.data_atop_ex = data_atop_ex_i; + r_pipe_freeze_trace.data_type_ex = data_type_ex_i; + r_pipe_freeze_trace.alu_operand_c_ex = alu_operand_c_ex_i; + r_pipe_freeze_trace.data_reg_offset_ex = data_reg_offset_ex_i; + r_pipe_freeze_trace.data_load_event_ex = data_load_event_ex_i; + r_pipe_freeze_trace.data_sign_ext_ex = data_sign_ext_ex_i; + r_pipe_freeze_trace.lsu_rdata = lsu_rdata_i; + r_pipe_freeze_trace.data_req_ex = data_req_ex_i; + r_pipe_freeze_trace.alu_operand_a_ex = alu_operand_a_ex_i; + r_pipe_freeze_trace.alu_operand_b_ex = alu_operand_b_ex_i; + r_pipe_freeze_trace.useincr_addr_ex = useincr_addr_ex_i; + r_pipe_freeze_trace.data_misaligned_ex = data_misaligned_ex_i; + r_pipe_freeze_trace.p_elw_start = p_elw_start_i; + r_pipe_freeze_trace.p_elw_finish = p_elw_finish_i; + r_pipe_freeze_trace.lsu_ready_ex = lsu_ready_ex_i; + r_pipe_freeze_trace.lsu_ready_wb = lsu_ready_wb_i; + r_pipe_freeze_trace.lsu_data_be = lsu_data_be_i; + + r_pipe_freeze_trace.data_req_pmp = data_req_pmp_i; + r_pipe_freeze_trace.data_gnt_pmp = data_gnt_pmp_i; + r_pipe_freeze_trace.data_rvalid = data_rvalid_i; + r_pipe_freeze_trace.data_err_pmp = data_err_pmp_i; + r_pipe_freeze_trace.data_addr_pmp = data_addr_pmp_i; + r_pipe_freeze_trace.data_we = data_we_i; + r_pipe_freeze_trace.data_atop = data_atop_i; + r_pipe_freeze_trace.data_be = data_be_i; + r_pipe_freeze_trace.data_wdata = data_wdata_i; + r_pipe_freeze_trace.data_rdata = data_rdata_i; //// APU //// - r_pipe_freeze_trace.apu_req = apu_req_i; - r_pipe_freeze_trace.apu_gnt = apu_gnt_i; - r_pipe_freeze_trace.apu_rvalid = apu_rvalid_i; + r_pipe_freeze_trace.apu_req = apu_req_i; + r_pipe_freeze_trace.apu_gnt = apu_gnt_i; + r_pipe_freeze_trace.apu_rvalid = apu_rvalid_i; // PC // - r_pipe_freeze_trace.branch_addr_n = branch_addr_n_i; + r_pipe_freeze_trace.branch_addr_n = branch_addr_n_i; // Controller FSM probes - r_pipe_freeze_trace.ctrl_fsm_cs = ctrl_fsm_cs_i; - r_pipe_freeze_trace.pc_mux = pc_mux_i; - r_pipe_freeze_trace.exc_pc_mux = exc_pc_mux_i; + r_pipe_freeze_trace.ctrl_fsm_cs = ctrl_fsm_cs_i; + r_pipe_freeze_trace.pc_mux = pc_mux_i; + r_pipe_freeze_trace.exc_pc_mux = exc_pc_mux_i; // CSR - r_pipe_freeze_trace.csr.addr = csr_addr_i; - r_pipe_freeze_trace.csr.we = csr_we_i; - r_pipe_freeze_trace.csr.wdata_int = csr_wdata_int_i; - - r_pipe_freeze_trace.csr.jvt_we = csr_jvt_we_i; - r_pipe_freeze_trace.csr.mstatus_n = csr_mstatus_n_i; - r_pipe_freeze_trace.csr.mstatus_q = csr_mstatus_q_i; - r_pipe_freeze_trace.csr.mstatus_fs_n = csr_mstatus_fs_n_i; - r_pipe_freeze_trace.csr.mstatus_fs_q = csr_mstatus_fs_q_i; - - if (FPU == 1 && ZFINX == 0) begin - r_pipe_freeze_trace.csr.mstatus_full_q[31] = (r_pipe_freeze_trace.csr.mstatus_fs_q == FS_DIRTY) ? 1'b1 : 1'b0; - end else begin - r_pipe_freeze_trace.csr.mstatus_full_q[31] = '0; - end - r_pipe_freeze_trace.csr.mstatus_full_q[30:18] = '0; - r_pipe_freeze_trace.csr.mstatus_full_q[17] = r_pipe_freeze_trace.csr.mstatus_q.mprv; - r_pipe_freeze_trace.csr.mstatus_full_q[16:15] = '0; - if (FPU == 1 && ZFINX == 0) begin - r_pipe_freeze_trace.csr.mstatus_full_q[14:13] = r_pipe_freeze_trace.csr.mstatus_fs_q; - end else begin - r_pipe_freeze_trace.csr.mstatus_full_q[14:13] = '0; - end - r_pipe_freeze_trace.csr.mstatus_full_q[12:11] = r_pipe_freeze_trace.csr.mstatus_q.mpp; - r_pipe_freeze_trace.csr.mstatus_full_q[10:8] = '0; - r_pipe_freeze_trace.csr.mstatus_full_q[7] = r_pipe_freeze_trace.csr.mstatus_q.mpie; - r_pipe_freeze_trace.csr.mstatus_full_q[6:5] = '0; - r_pipe_freeze_trace.csr.mstatus_full_q[4] = r_pipe_freeze_trace.csr.mstatus_q.upie; - r_pipe_freeze_trace.csr.mstatus_full_q[3] = r_pipe_freeze_trace.csr.mstatus_q.mie; - r_pipe_freeze_trace.csr.mstatus_full_q[2:1] = '0; - r_pipe_freeze_trace.csr.mstatus_full_q[0] = r_pipe_freeze_trace.csr.mstatus_q.uie; - - if (FPU == 1 && ZFINX == 0) begin - r_pipe_freeze_trace.csr.mstatus_full_n[31] = (r_pipe_freeze_trace.csr.mstatus_fs_n == FS_DIRTY) ? 1'b1 : 1'b0; - end else begin - r_pipe_freeze_trace.csr.mstatus_full_n[31] = '0; - end - r_pipe_freeze_trace.csr.mstatus_full_n[30:18] = '0; - r_pipe_freeze_trace.csr.mstatus_full_n[17] = r_pipe_freeze_trace.csr.mstatus_n.mprv; - r_pipe_freeze_trace.csr.mstatus_full_n[16:15] = '0; - if (FPU == 1 && ZFINX == 0) begin - r_pipe_freeze_trace.csr.mstatus_full_n[14:13] = r_pipe_freeze_trace.csr.mstatus_fs_n; - end else begin - r_pipe_freeze_trace.csr.mstatus_full_n[14:13] = '0; - end - r_pipe_freeze_trace.csr.mstatus_full_n[12:11] = r_pipe_freeze_trace.csr.mstatus_n.mpp; - r_pipe_freeze_trace.csr.mstatus_full_n[10:8] = '0; - r_pipe_freeze_trace.csr.mstatus_full_n[7] = r_pipe_freeze_trace.csr.mstatus_n.mpie; - r_pipe_freeze_trace.csr.mstatus_full_n[6:5] = '0; - r_pipe_freeze_trace.csr.mstatus_full_n[4] = r_pipe_freeze_trace.csr.mstatus_n.upie; - r_pipe_freeze_trace.csr.mstatus_full_n[3] = r_pipe_freeze_trace.csr.mstatus_n.mie; - r_pipe_freeze_trace.csr.mstatus_full_n[2:1] = '0; - r_pipe_freeze_trace.csr.mstatus_full_n[0] = r_pipe_freeze_trace.csr.mstatus_n.uie; + r_pipe_freeze_trace.csr.addr = csr_addr_i; + r_pipe_freeze_trace.csr.we = csr_we_i; + r_pipe_freeze_trace.csr.wdata_int = csr_wdata_int_i; + + r_pipe_freeze_trace.csr.jvt_we = csr_jvt_we_i; + r_pipe_freeze_trace.csr.mstatus_n = csr_mstatus_n_i; + r_pipe_freeze_trace.csr.mstatus_q = csr_mstatus_q_i; + r_pipe_freeze_trace.csr.mstatus_fs_n = csr_mstatus_fs_n_i; + r_pipe_freeze_trace.csr.mstatus_fs_q = csr_mstatus_fs_q_i; r_pipe_freeze_trace.csr.mstatush_we = csr_mstatush_we_i; r_pipe_freeze_trace.csr.misa_n = csr_misa_n_i; @@ -676,10 +645,21 @@ task monitor_pipeline(); r_pipe_freeze_trace.hwloop.counter_n = hwlp_counter_n_i; compute_csr_we(); + + //If fcsr_we has triggered, then fflags_we and frm_we should also be triggered + if (r_pipe_freeze_trace.csr.fcsr_we) begin + r_pipe_freeze_trace.csr.fflags_we = 1'b1; + r_pipe_freeze_trace.csr.frm_we = 1'b1; + end else begin + if (r_pipe_freeze_trace.csr.fflags_we || r_pipe_freeze_trace.csr.frm_we) begin + r_pipe_freeze_trace.csr.fcsr_we = 1'b1; + end + end + if (csr_fcsr_fflags_we_i) begin - r_pipe_freeze_trace.csr.fflags_we = 1'b1; - r_pipe_freeze_trace.csr.fcsr_we = 1'b1; - r_pipe_freeze_trace.csr.mstatus_we = 1'b1; + r_pipe_freeze_trace.csr.fflags_we = 1'b1; + r_pipe_freeze_trace.csr.fcsr_we = 1'b1; + r_pipe_freeze_trace.csr.mstatus_fs_we = 1'b1; end ->e_pipe_monitor_ok; diff --git a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_apu_disp.sv b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_apu_disp.sv index adc9a3485..94ca9bcbd 100644 --- a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_apu_disp.sv +++ b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_apu_disp.sv @@ -47,6 +47,7 @@ module cv32e40p_apu_disp ( input logic [2:0][5:0] read_regs_i, input logic [2:0] read_regs_valid_i, output logic read_dep_o, + output logic read_dep_for_jalr_o, input logic [1:0][5:0] write_regs_i, input logic [1:0] write_regs_valid_i, @@ -189,6 +190,10 @@ module cv32e40p_apu_disp ( assign read_dep_o = (read_dep_req | read_dep_inflight | read_dep_waiting) & is_decoding_i; assign write_dep_o = (write_dep_req | write_dep_inflight | write_dep_waiting) & is_decoding_i; + assign read_dep_for_jalr_o = is_decoding_i & ((|read_deps_req & enable_i) | + (|read_deps_inflight & valid_inflight) | + (|read_deps_waiting & valid_waiting)); + // // Stall signals // diff --git a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_controller.sv b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_controller.sv index 56cce6281..549802690 100644 --- a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_controller.sv +++ b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_controller.sv @@ -31,7 +31,8 @@ module cv32e40p_controller import cv32e40p_pkg::*; #( parameter COREV_CLUSTER = 0, - parameter COREV_PULP = 1 + parameter COREV_PULP = 0, + parameter FPU = 0 ) ( input logic clk, // Gated clock @@ -78,7 +79,6 @@ module cv32e40p_controller import cv32e40p_pkg::*; // HWLoop signls input logic [31:0] pc_id_i, - input logic is_compressed_i, // from hwloop_regs input logic [1:0] [31:0] hwlp_start_addr_i, @@ -105,6 +105,7 @@ module cv32e40p_controller import cv32e40p_pkg::*; // APU dependency checks input logic apu_en_i, input logic apu_read_dep_i, + input logic apu_read_dep_for_jalr_i, input logic apu_write_dep_i, output logic apu_stall_o, @@ -208,13 +209,13 @@ module cv32e40p_controller import cv32e40p_pkg::*; // Debug state debug_state_e debug_fsm_cs, debug_fsm_ns; - logic jump_done, jump_done_q, jump_in_dec, branch_in_id_dec, branch_in_id; + logic jump_done, jump_done_q, jump_in_dec, branch_in_id; logic data_err_q; logic debug_mode_q, debug_mode_n; logic ebrk_force_debug_mode; - logic is_hwlp_illegal, is_hwlp_body; + logic is_hwlp_body; logic illegal_insn_q, illegal_insn_n; logic debug_req_entry_q, debug_req_entry_n; logic debug_force_wakeup_q, debug_force_wakeup_n; @@ -223,6 +224,10 @@ module cv32e40p_controller import cv32e40p_pkg::*; logic hwlp_end1_eq_pc; logic hwlp_counter0_gt_1; logic hwlp_counter1_gt_1; + logic hwlp_counter0_eq_1; + logic hwlp_counter1_eq_1; + logic hwlp_counter0_eq_0; + logic hwlp_counter1_eq_0; logic hwlp_end0_eq_pc_plus4; logic hwlp_end1_eq_pc_plus4; logic hwlp_start0_leq_pc; @@ -290,7 +295,6 @@ module cv32e40p_controller import cv32e40p_pkg::*; jump_in_dec = ctrl_transfer_insn_in_dec_i == BRANCH_JALR || ctrl_transfer_insn_in_dec_i == BRANCH_JAL; branch_in_id = ctrl_transfer_insn_in_id_i == BRANCH_COND; - branch_in_id_dec = ctrl_transfer_insn_in_dec_i == BRANCH_COND; ebrk_force_debug_mode = (debug_ebreakm_i && current_priv_lvl_i == PRIV_LVL_M) || (debug_ebreaku_i && current_priv_lvl_i == PRIV_LVL_U); @@ -315,8 +319,6 @@ module cv32e40p_controller import cv32e40p_pkg::*; hwlp_mask_o = 1'b0; - is_hwlp_illegal = 1'b0; - hwlp_dec_cnt_o = '0; hwlp_end_4_id_d = 1'b0; @@ -525,9 +527,7 @@ module cv32e40p_controller import cv32e40p_pkg::*; else begin - is_hwlp_illegal = is_hwlp_body & (jump_in_dec || branch_in_id_dec || mret_insn_i || uret_insn_i || dret_insn_i || is_compressed_i || fencei_insn_i || wfi_active); - - if(illegal_insn_i || is_hwlp_illegal) begin + if (illegal_insn_i) begin halt_if_o = 1'b1; halt_id_o = 1'b0; @@ -617,26 +617,34 @@ module cv32e40p_controller import cv32e40p_pkg::*; // we can be at the end of HWloop due to a return from interrupt or ecall or ebreak or exceptions if(hwlp_end0_eq_pc && hwlp_counter0_gt_1) begin - pc_mux_o = PC_HWLOOP; - if (~jump_done_q) begin - pc_set_o = 1'b1; - // Keep the instruction and the related address in the Aligner if - // ID is stalled during a jump - jump_done = 1'b1; - hwlp_dec_cnt_o[0] = 1'b1; - end - end - if(hwlp_end1_eq_pc && hwlp_counter1_gt_1) begin - pc_mux_o = PC_HWLOOP; - if (~jump_done_q) begin - pc_set_o = 1'b1; - // Keep the instruction and the related address in the Aligner if - // ID is stalled during a jump - jump_done = 1'b1; - hwlp_dec_cnt_o[1] = 1'b1; - end - end + pc_mux_o = PC_HWLOOP; + if (~jump_done_q) begin + pc_set_o = 1'b1; + // Keep the instruction and the related address in the Aligner if + // ID is stalled during a jump + jump_done = 1'b1; + hwlp_dec_cnt_o[0] = 1'b1; + end + end + if (hwlp_end1_eq_pc && hwlp_counter1_gt_1) begin + pc_mux_o = PC_HWLOOP; + if (~jump_done_q) begin + pc_set_o = 1'b1; + // Keep the instruction and the related address in the Aligner if + // ID is stalled during a jump + jump_done = 1'b1; + hwlp_dec_cnt_o[1] = 1'b1; + end end + end + + if (hwlp_end0_eq_pc && hwlp_counter0_eq_1) begin + hwlp_dec_cnt_o[0] = 1'b1; + end + if (hwlp_end1_eq_pc && hwlp_counter1_eq_1) begin + hwlp_dec_cnt_o[1] = 1'b1; + end + end endcase // unique case (1'b1) @@ -742,9 +750,7 @@ module cv32e40p_controller import cv32e40p_pkg::*; else begin - is_hwlp_illegal = (jump_in_dec || branch_in_id_dec || mret_insn_i || uret_insn_i || dret_insn_i || is_compressed_i || fencei_insn_i || wfi_active); - - if(illegal_insn_i || is_hwlp_illegal) begin + if (illegal_insn_i) begin halt_if_o = 1'b1; halt_id_o = 1'b1; @@ -812,8 +818,8 @@ module cv32e40p_controller import cv32e40p_pkg::*; ctrl_fsm_ns = is_hwlp_body ? DECODE_HWLOOP : DECODE; end - hwlp_dec_cnt_o[0] = hwlp_end0_eq_pc; - hwlp_dec_cnt_o[1] = hwlp_end1_eq_pc; + hwlp_dec_cnt_o[0] = hwlp_end0_eq_pc && !hwlp_counter0_eq_0; + hwlp_dec_cnt_o[1] = hwlp_end1_eq_pc && !hwlp_counter1_eq_0; end endcase // unique case (1'b1) @@ -1269,6 +1275,10 @@ generate assign hwlp_end1_eq_pc = hwlp_end_addr_i[1] == pc_id_i + 4; // Equivalent to hwlp_end_addr_i[1] - 4 == pc_id_i assign hwlp_counter0_gt_1 = hwlp_counter_i[0] > 1; assign hwlp_counter1_gt_1 = hwlp_counter_i[1] > 1; + assign hwlp_counter0_eq_1 = hwlp_counter_i[0] == 1; + assign hwlp_counter1_eq_1 = hwlp_counter_i[1] == 1; + assign hwlp_counter0_eq_0 = hwlp_counter_i[0] == 0; + assign hwlp_counter1_eq_0 = hwlp_counter_i[1] == 0; assign hwlp_end0_eq_pc_plus4 = hwlp_end_addr_i[0] == pc_id_i + 8; // Equivalent to hwlp_end_addr_i[0] - 4 == pc_id_i + 4 assign hwlp_end1_eq_pc_plus4 = hwlp_end_addr_i[1] == pc_id_i + 8; // Equivalent to hwlp_end_addr_i[1] - 4 == pc_id_i + 4 assign hwlp_start0_leq_pc = hwlp_start_addr_i[0] <= pc_id_i; @@ -1285,6 +1295,10 @@ generate assign hwlp_end1_eq_pc = 1'b0; assign hwlp_counter0_gt_1 = 1'b0; assign hwlp_counter1_gt_1 = 1'b0; + assign hwlp_counter0_eq_1 = 1'b0; + assign hwlp_counter1_eq_1 = 1'b0; + assign hwlp_counter0_eq_0 = 1'b0; + assign hwlp_counter1_eq_0 = 1'b0; assign hwlp_end0_eq_pc_plus4 = 1'b0; assign hwlp_end1_eq_pc_plus4 = 1'b0; assign hwlp_start0_leq_pc = 1'b0; @@ -1338,7 +1352,10 @@ endgenerate if ((ctrl_transfer_insn_in_dec_i == BRANCH_JALR) && (((regfile_we_wb_i == 1'b1) && (reg_d_wb_is_reg_a_i == 1'b1)) || ((regfile_we_ex_i == 1'b1) && (reg_d_ex_is_reg_a_i == 1'b1)) || - ((regfile_alu_we_fw_i == 1'b1) && (reg_d_alu_is_reg_a_i == 1'b1))) ) + ((regfile_alu_we_fw_i == 1'b1) && (reg_d_alu_is_reg_a_i == 1'b1)) || + (FPU && (apu_read_dep_for_jalr_i == 1'b1)) + ) + ) begin jr_stall_o = 1'b1; deassert_we_o = 1'b1; @@ -1551,10 +1568,11 @@ endgenerate property p_no_hwlp; @(posedge clk) (1'b1) |-> ((pc_mux_o != PC_HWLOOP) && (ctrl_fsm_cs != DECODE_HWLOOP) && - (hwlp_mask_o == 1'b0) && (is_hwlp_illegal == 'b0) && (is_hwlp_body == 'b0) && + (hwlp_mask_o == 1'b0) && (is_hwlp_body == 'b0) && (hwlp_start_addr_i == 'b0) && (hwlp_end_addr_i == 'b0) && (hwlp_counter_i[1] == 32'b0) && (hwlp_counter_i[0] == 32'b0) && (hwlp_dec_cnt_o == 2'b0) && (hwlp_jump_o == 1'b0) && (hwlp_targ_addr_o == 32'b0) && (hwlp_end0_eq_pc == 1'b0) && (hwlp_end1_eq_pc == 1'b0) && (hwlp_counter0_gt_1 == 1'b0) && (hwlp_counter1_gt_1 == 1'b0) && + (hwlp_counter0_eq_1 == 1'b0) && (hwlp_counter1_eq_1 == 1'b0) && (hwlp_end0_eq_pc_plus4 == 1'b0) && (hwlp_end1_eq_pc_plus4 == 1'b0) && (hwlp_start0_leq_pc == 0) && (hwlp_start1_leq_pc == 0) && (hwlp_end0_geq_pc == 1'b0) && (hwlp_end1_geq_pc == 1'b0) && (hwlp_end_4_id_d == 1'b0) && (hwlp_end_4_id_q == 1'b0)); endproperty diff --git a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_core.sv b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_core.sv index 528ac1c8f..e6f9f7098 100644 --- a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_core.sv +++ b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_core.sv @@ -213,6 +213,7 @@ module cv32e40p_core logic [ 2:0][ 5:0] apu_read_regs; logic [ 2:0] apu_read_regs_valid; logic apu_read_dep; + logic apu_read_dep_for_jalr; logic [ 1:0][ 5:0] apu_write_regs; logic [ 1:0] apu_write_regs_valid; logic apu_write_dep; @@ -361,7 +362,6 @@ module cv32e40p_core // APU master signals assign apu_flags_o = apu_flags_ex; - assign fflags_csr = apu_flags_i; ////////////////////////////////////////////////////////////////////////////////////////////// // ____ _ _ __ __ _ // @@ -621,14 +621,15 @@ module cv32e40p_core .apu_flags_ex_o (apu_flags_ex), .apu_waddr_ex_o (apu_waddr_ex), - .apu_read_regs_o (apu_read_regs), - .apu_read_regs_valid_o (apu_read_regs_valid), - .apu_read_dep_i (apu_read_dep), - .apu_write_regs_o (apu_write_regs), - .apu_write_regs_valid_o(apu_write_regs_valid), - .apu_write_dep_i (apu_write_dep), - .apu_perf_dep_o (perf_apu_dep), - .apu_busy_i (apu_busy), + .apu_read_regs_o (apu_read_regs), + .apu_read_regs_valid_o (apu_read_regs_valid), + .apu_read_dep_i (apu_read_dep), + .apu_read_dep_for_jalr_i(apu_read_dep_for_jalr), + .apu_write_regs_o (apu_write_regs), + .apu_write_regs_valid_o (apu_write_regs_valid), + .apu_write_dep_i (apu_write_dep), + .apu_perf_dep_o (perf_apu_dep), + .apu_busy_i (apu_busy), // CSR ID/EX .csr_access_ex_o (csr_access_ex), @@ -779,8 +780,14 @@ module cv32e40p_core .mult_multicycle_o(mult_multicycle), // to ID/EX pipe registers + .data_req_i (data_req_o), // from ID/EX pipeline + .data_rvalid_i (data_rvalid_i), // from ID/EX pipeline + .data_misaligned_ex_i(data_misaligned_ex), // from ID/EX pipeline + .data_misaligned_i (data_misaligned), + // FPU .fpu_fflags_we_o(fflags_we), + .fpu_fflags_o (fflags_csr), // APU .apu_en_i (apu_en_ex), @@ -788,14 +795,14 @@ module cv32e40p_core .apu_lat_i (apu_lat_ex), .apu_operands_i(apu_operands_ex), .apu_waddr_i (apu_waddr_ex), - .apu_flags_i (apu_flags_ex), - .apu_read_regs_i (apu_read_regs), - .apu_read_regs_valid_i (apu_read_regs_valid), - .apu_read_dep_o (apu_read_dep), - .apu_write_regs_i (apu_write_regs), - .apu_write_regs_valid_i(apu_write_regs_valid), - .apu_write_dep_o (apu_write_dep), + .apu_read_regs_i (apu_read_regs), + .apu_read_regs_valid_i (apu_read_regs_valid), + .apu_read_dep_o (apu_read_dep), + .apu_read_dep_for_jalr_o(apu_read_dep_for_jalr), + .apu_write_regs_i (apu_write_regs), + .apu_write_regs_valid_i (apu_write_regs_valid), + .apu_write_dep_o (apu_write_dep), .apu_perf_type_o(perf_apu_type), .apu_perf_cont_o(perf_apu_cont), @@ -813,6 +820,7 @@ module cv32e40p_core // response channel .apu_rvalid_i (apu_rvalid_i), .apu_result_i (apu_result_i), + .apu_flags_i (apu_flags_i), .lsu_en_i (data_req_ex), .lsu_rdata_i(lsu_rdata), @@ -901,8 +909,6 @@ module cv32e40p_core .data_misaligned_ex_i(data_misaligned_ex), // from ID/EX pipeline .data_misaligned_o (data_misaligned), - .apu_busy_i(apu_busy), - .p_elw_start_o (p_elw_start), .p_elw_finish_o(p_elw_finish), diff --git a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_cs_registers.sv b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_cs_registers.sv index f07dafb5a..25c777e21 100644 --- a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_cs_registers.sv +++ b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_cs_registers.sv @@ -505,8 +505,13 @@ module cv32e40p_cs_registers // marchid: Machine Architecture ID CSR_MARCHID: csr_rdata_int = MARCHID; + // mimpid, Machine Implementation ID + CSR_MIMPID: begin + csr_rdata_int = (FPU || COREV_PULP || COREV_CLUSTER) ? 32'h1 : 'b0; + end + // unimplemented, read 0 CSRs - CSR_MIMPID, CSR_MTVAL: csr_rdata_int = 'b0; + CSR_MTVAL: csr_rdata_int = 'b0; CSR_TSELECT, CSR_TDATA3, CSR_MCONTEXT, CSR_SCONTEXT: csr_rdata_int = 'b0; // Always read 0 CSR_TDATA1: csr_rdata_int = tmatch_control_rdata; diff --git a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_ex_stage.sv b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_ex_stage.sv index 6b58a8425..c51ef7f81 100644 --- a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_ex_stage.sv +++ b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_ex_stage.sv @@ -76,8 +76,14 @@ module cv32e40p_ex_stage output logic mult_multicycle_o, + input logic data_req_i, + input logic data_rvalid_i, + input logic data_misaligned_ex_i, + input logic data_misaligned_i, + // FPU signals output logic fpu_fflags_we_o, + output logic [APU_NUSFLAGS_CPU-1:0] fpu_fflags_o, // APU signals input logic apu_en_i, @@ -85,11 +91,12 @@ module cv32e40p_ex_stage input logic [ 1:0] apu_lat_i, input logic [ APU_NARGS_CPU-1:0][31:0] apu_operands_i, input logic [ 5:0] apu_waddr_i, - input logic [APU_NDSFLAGS_CPU-1:0] apu_flags_i, + input logic [APU_NUSFLAGS_CPU-1:0] apu_flags_i, input logic [2:0][5:0] apu_read_regs_i, input logic [2:0] apu_read_regs_valid_i, output logic apu_read_dep_o, + output logic apu_read_dep_for_jalr_o, input logic [1:0][5:0] apu_write_regs_i, input logic [1:0] apu_write_regs_valid_i, output logic apu_write_dep_o, @@ -143,7 +150,7 @@ module cv32e40p_ex_stage output logic branch_decision_o, // Stall Control - input logic is_decoding_i, // Used to mask data Dependency inside the APU dispatcher in case of an istruction non valid + input logic is_decoding_i, // Used to mask data Dependency inside the APU dispatcher in case of an istruction non valid input logic lsu_ready_ex_i, // EX part of LSU is done input logic lsu_err_i, @@ -152,29 +159,34 @@ module cv32e40p_ex_stage input logic wb_ready_i // WB stage ready for new data ); - logic [31:0] alu_result; - logic [31:0] mult_result; - logic alu_cmp_result; + logic [ 31:0] alu_result; + logic [ 31:0] mult_result; + logic alu_cmp_result; - logic regfile_we_lsu; - logic [ 5:0] regfile_waddr_lsu; + logic regfile_we_lsu; + logic [ 5:0] regfile_waddr_lsu; - logic wb_contention; - logic wb_contention_lsu; + logic wb_contention; + logic wb_contention_lsu; - logic alu_ready; - logic mult_ready; + logic alu_ready; + logic mulh_active; + logic mult_ready; // APU signals - logic apu_valid; - logic [ 5:0] apu_waddr; - logic [31:0] apu_result; - logic apu_stall; - logic apu_active; - logic apu_singlecycle; - logic apu_multicycle; - logic apu_req; - logic apu_gnt; + logic apu_valid; + logic [ 5:0] apu_waddr; + logic [ 31:0] apu_result; + logic apu_stall; + logic apu_active; + logic apu_singlecycle; + logic apu_multicycle; + logic apu_req; + logic apu_gnt; + + logic apu_rvalid_q; + logic [ 31:0] apu_result_q; + logic [APU_NUSFLAGS_CPU-1:0] apu_flags_q; // ALU write port mux always_comb begin @@ -295,9 +307,10 @@ module cv32e40p_ex_stage .result_o(mult_result), - .multicycle_o(mult_multicycle_o), - .ready_o (mult_ready), - .ex_ready_i (ex_ready_o) + .multicycle_o (mult_multicycle_o), + .mulh_active_o(mulh_active), + .ready_o (mult_ready), + .ex_ready_i (ex_ready_o) ); generate @@ -326,13 +339,14 @@ module cv32e40p_ex_stage .active_o(apu_active), .stall_o (apu_stall), - .is_decoding_i (is_decoding_i), - .read_regs_i (apu_read_regs_i), - .read_regs_valid_i (apu_read_regs_valid_i), - .read_dep_o (apu_read_dep_o), - .write_regs_i (apu_write_regs_i), - .write_regs_valid_i(apu_write_regs_valid_i), - .write_dep_o (apu_write_dep_o), + .is_decoding_i (is_decoding_i), + .read_regs_i (apu_read_regs_i), + .read_regs_valid_i (apu_read_regs_valid_i), + .read_dep_o (apu_read_dep_o), + .read_dep_for_jalr_o(apu_read_dep_for_jalr_o), + .write_regs_i (apu_write_regs_i), + .write_regs_valid_i (apu_write_regs_valid_i), + .write_dep_o (apu_write_dep_o), .perf_type_o(apu_perf_type_o), .perf_cont_o(apu_perf_cont_o), @@ -345,40 +359,61 @@ module cv32e40p_ex_stage .apu_rvalid_i(apu_valid) ); - assign apu_perf_wb_o = wb_contention | wb_contention_lsu; - assign apu_ready_wb_o = ~(apu_active | apu_en_i | apu_stall) | apu_valid; + assign apu_perf_wb_o = wb_contention | wb_contention_lsu; + assign apu_ready_wb_o = ~(apu_active | apu_en_i | apu_stall) | apu_valid; + + /////////////////////////////////////// + // APU result memorization Register // + /////////////////////////////////////// + always_ff @(posedge clk, negedge rst_n) begin : APU_Result_Memorization + if (~rst_n) begin + apu_rvalid_q <= 1'b0; + apu_result_q <= 'b0; + apu_flags_q <= 'b0; + end else begin + if (apu_rvalid_i && apu_multicycle && (data_misaligned_i || data_misaligned_ex_i || (data_req_i && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)))) begin + apu_rvalid_q <= 1'b1; + apu_result_q <= apu_result_i; + apu_flags_q <= apu_flags_i; + end else if (apu_rvalid_q && !(data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)))) begin + apu_rvalid_q <= 1'b0; + end + end + end - assign apu_req_o = apu_req; - assign apu_gnt = apu_gnt_i; - assign apu_valid = apu_rvalid_i; - assign apu_operands_o = apu_operands_i; - assign apu_op_o = apu_op_i; - assign apu_result = apu_result_i; + assign apu_req_o = apu_req; + assign apu_gnt = apu_gnt_i; + assign apu_valid = (apu_multicycle && (data_misaligned_i || data_misaligned_ex_i || ((data_req_i || data_rvalid_i) && regfile_alu_we_i) || (mulh_active && (mult_operator_i == MUL_H)))) ? 1'b0 : (apu_rvalid_i || apu_rvalid_q); + assign apu_operands_o = apu_operands_i; + assign apu_op_o = apu_op_i; + assign apu_result = apu_rvalid_q ? apu_result_q : apu_result_i; assign fpu_fflags_we_o = apu_valid; + assign fpu_fflags_o = apu_rvalid_q ? apu_flags_q : apu_flags_i; end else begin : gen_no_apu // default assignements for the case when no FPU/APU is attached. - assign apu_req_o = '0; - assign apu_operands_o[0] = '0; - assign apu_operands_o[1] = '0; - assign apu_operands_o[2] = '0; - assign apu_op_o = '0; - assign apu_req = 1'b0; - assign apu_gnt = 1'b0; - assign apu_result = 32'b0; - assign apu_valid = 1'b0; - assign apu_waddr = 6'b0; - assign apu_stall = 1'b0; - assign apu_active = 1'b0; - assign apu_ready_wb_o = 1'b1; - assign apu_perf_wb_o = 1'b0; - assign apu_perf_cont_o = 1'b0; - assign apu_perf_type_o = 1'b0; - assign apu_singlecycle = 1'b0; - assign apu_multicycle = 1'b0; - assign apu_read_dep_o = 1'b0; - assign apu_write_dep_o = 1'b0; - assign fpu_fflags_we_o = 1'b0; - + assign apu_req_o = '0; + assign apu_operands_o[0] = '0; + assign apu_operands_o[1] = '0; + assign apu_operands_o[2] = '0; + assign apu_op_o = '0; + assign apu_req = 1'b0; + assign apu_gnt = 1'b0; + assign apu_result = 32'b0; + assign apu_valid = 1'b0; + assign apu_waddr = 6'b0; + assign apu_stall = 1'b0; + assign apu_active = 1'b0; + assign apu_ready_wb_o = 1'b1; + assign apu_perf_wb_o = 1'b0; + assign apu_perf_cont_o = 1'b0; + assign apu_perf_type_o = 1'b0; + assign apu_singlecycle = 1'b0; + assign apu_multicycle = 1'b0; + assign apu_read_dep_o = 1'b0; + assign apu_read_dep_for_jalr_o = 1'b0; + assign apu_write_dep_o = 1'b0; + assign fpu_fflags_o = '0; + assign fpu_fflags_we_o = '0; end endgenerate diff --git a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_id_stage.sv b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_id_stage.sv index 0f54e31eb..7811eabfd 100644 --- a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_id_stage.sv +++ b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_id_stage.sv @@ -146,6 +146,7 @@ module cv32e40p_id_stage output logic [2:0][5:0] apu_read_regs_o, output logic [2:0] apu_read_regs_valid_o, input logic apu_read_dep_i, + input logic apu_read_dep_for_jalr_i, output logic [1:0][5:0] apu_write_regs_o, output logic [1:0] apu_write_regs_valid_o, input logic apu_write_dep_i, @@ -804,11 +805,17 @@ module cv32e40p_id_stage // dependency checks always_comb begin unique case (alu_op_a_mux_sel) + OP_A_CURRPC: begin + if (ctrl_transfer_target_mux_sel == JT_JALR) begin + apu_read_regs[0] = regfile_addr_ra_id; + apu_read_regs_valid[0] = 1'b1; + end + end // OP_A_CURRPC: OP_A_REGA_OR_FWD: begin apu_read_regs[0] = regfile_addr_ra_id; apu_read_regs_valid[0] = 1'b1; end // OP_A_REGA_OR_FWD: - OP_A_REGB_OR_FWD: begin + OP_A_REGB_OR_FWD, OP_A_REGC_OR_FWD: begin apu_read_regs[0] = regfile_addr_rb_id; apu_read_regs_valid[0] = 1'b1; end @@ -825,7 +832,7 @@ module cv32e40p_id_stage apu_read_regs[1] = regfile_addr_ra_id; apu_read_regs_valid[1] = 1'b1; end - OP_B_REGB_OR_FWD: begin + OP_B_REGB_OR_FWD, OP_B_BMASK: begin apu_read_regs[1] = regfile_addr_rb_id; apu_read_regs_valid[1] = 1'b1; end @@ -833,6 +840,15 @@ module cv32e40p_id_stage apu_read_regs[1] = regfile_addr_rc_id; apu_read_regs_valid[1] = 1'b1; end + OP_B_IMM: begin + if (alu_bmask_b_mux_sel == BMASK_B_REG) begin + apu_read_regs[1] = regfile_addr_rb_id; + apu_read_regs_valid[1] = 1'b1; + end else begin + apu_read_regs[1] = regfile_addr_rb_id; + apu_read_regs_valid[1] = 1'b0; + end + end default: begin apu_read_regs[1] = regfile_addr_rb_id; apu_read_regs_valid[1] = 1'b0; @@ -847,8 +863,15 @@ module cv32e40p_id_stage apu_read_regs_valid[2] = 1'b1; end OP_C_REGC_OR_FWD: begin - apu_read_regs[2] = regfile_addr_rc_id; - apu_read_regs_valid[2] = 1'b1; + if ((alu_op_a_mux_sel != OP_A_REGC_OR_FWD) && (ctrl_transfer_target_mux_sel != JT_JALR) && + !((alu_op_b_mux_sel == OP_B_IMM) && (alu_bmask_b_mux_sel == BMASK_B_REG)) && + !(alu_op_b_mux_sel == OP_B_BMASK)) begin + apu_read_regs[2] = regfile_addr_rc_id; + apu_read_regs_valid[2] = 1'b1; + end else begin + apu_read_regs[2] = regfile_addr_rc_id; + apu_read_regs_valid[2] = 1'b0; + end end default: begin apu_read_regs[2] = regfile_addr_rc_id; @@ -1084,7 +1107,8 @@ module cv32e40p_id_stage cv32e40p_controller #( .COREV_CLUSTER(COREV_CLUSTER), - .COREV_PULP (COREV_PULP) + .COREV_PULP (COREV_PULP), + .FPU (FPU) ) controller_i ( .clk (clk), // Gated clock .clk_ungated_i(clk_ungated_i), // Ungated clock @@ -1131,8 +1155,7 @@ module cv32e40p_id_stage .trap_addr_mux_o(trap_addr_mux_o), // HWLoop signls - .pc_id_i (pc_id_i), - .is_compressed_i(is_compressed_i), + .pc_id_i(pc_id_i), .hwlp_start_addr_i(hwlp_start_o), .hwlp_end_addr_i (hwlp_end_o), @@ -1154,9 +1177,10 @@ module cv32e40p_id_stage .mult_multicycle_i(mult_multicycle_i), // APU - .apu_en_i (apu_en), - .apu_read_dep_i (apu_read_dep_i), - .apu_write_dep_i(apu_write_dep_i), + .apu_en_i (apu_en), + .apu_read_dep_i (apu_read_dep_i), + .apu_read_dep_for_jalr_i(apu_read_dep_for_jalr_i), + .apu_write_dep_i (apu_write_dep_i), .apu_stall_o(apu_stall), diff --git a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_load_store_unit.sv b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_load_store_unit.sv index 8df1d8498..7c08ffe11 100644 --- a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_load_store_unit.sv +++ b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_load_store_unit.sv @@ -59,8 +59,6 @@ module cv32e40p_load_store_unit #( input logic data_misaligned_ex_i, // misaligned access in last ld/st -> from ID/EX pipeline output logic data_misaligned_o, // misaligned access was detected -> to controller - input logic apu_busy_i, - input logic [5:0] data_atop_ex_i, // atomic instructions signal -> from ex stage output logic [5:0] data_atop_o, // atomic instruction signal -> core output @@ -76,8 +74,6 @@ module cv32e40p_load_store_unit #( localparam DEPTH = 2; // Maximum number of outstanding transactions - logic data_req_ex_filtered; // data request from ex stage filtered when it is misaligned and there is an on-going APU instruction - // Transaction request (to cv32e40p_obi_interface) logic trans_valid; logic trans_ready; @@ -352,14 +348,12 @@ module cv32e40p_load_store_unit #( // Busy if there are ongoing (or potentially outstanding) transfers assign busy_o = (cnt_q != 2'b00) || trans_valid; - assign data_req_ex_filtered = data_req_ex_i & !(apu_busy_i & (data_misaligned_o | data_misaligned_ex_i)); - ////////////////////////////////////////////////////////////////////////////// // Transaction request generation // // Assumes that corresponding response is at least 1 cycle after request // - // - Only request transaction when EX stage requires data transfer (data_req_ex_filtered), and + // - Only request transaction when EX stage requires data transfer (data_req_ex_i), and // - maximum number of outstanding transactions will not be exceeded (cnt_q < DEPTH) ////////////////////////////////////////////////////////////////////////////// @@ -376,12 +370,12 @@ module cv32e40p_load_store_unit #( // OBI compatible (avoids combinatorial path from data_rvalid_i to data_req_o). // Multiple trans_* transactions can be issued (and accepted) before a response // (resp_*) is received. - assign trans_valid = data_req_ex_filtered && (cnt_q < DEPTH); + assign trans_valid = data_req_ex_i && (cnt_q < DEPTH); end else begin : gen_pulp_obi // Legacy PULP OBI behavior, i.e. only issue subsequent transaction if preceding transfer // is about to finish (re-introducing timing critical path from data_rvalid_i to data_req_o) - assign trans_valid = (cnt_q == 2'b00) ? data_req_ex_filtered && (cnt_q < DEPTH) : - data_req_ex_filtered && (cnt_q < DEPTH) && resp_valid; + assign trans_valid = (cnt_q == 2'b00) ? data_req_ex_i && (cnt_q < DEPTH) : + data_req_ex_i && (cnt_q < DEPTH) && resp_valid; end endgenerate @@ -391,7 +385,7 @@ module cv32e40p_load_store_unit #( // LSU EX stage readyness requires two criteria to be met: // - // - A data request (data_req_ex_filtered) has been forwarded/accepted (trans_valid && trans_ready) + // - A data request (data_req_ex_i) has been forwarded/accepted (trans_valid && trans_ready) // - The LSU WB stage is available such that EX and WB can be updated in lock step // // Default (if there is not even a data request) LSU EX is signaled to be ready, else @@ -400,11 +394,10 @@ module cv32e40p_load_store_unit #( // in case there is already at least one outstanding transaction (so WB is full) the EX // and WB stage can only signal readiness in lock step (so resp_valid is used as well). - assign lsu_ready_ex_o = !(apu_busy_i & (data_misaligned_o | data_misaligned_ex_i)) & - ((data_req_ex_i == 1'b0) ? 1'b1 : - (cnt_q == 2'b00) ? ( trans_valid && trans_ready) : - (cnt_q == 2'b01) ? (resp_valid && trans_valid && trans_ready) : - resp_valid); + assign lsu_ready_ex_o = (data_req_ex_i == 1'b0) ? 1'b1 : + (cnt_q == 2'b00) ? ( trans_valid && trans_ready) : + (cnt_q == 2'b01) ? (resp_valid && trans_valid && trans_ready) : + resp_valid; // Update signals for EX/WB registers (when EX has valid data itself and is ready for next) assign ctrl_update = lsu_ready_ex_o && data_req_ex_i; diff --git a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_mult.sv b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_mult.sv index ea0da1937..afdc5e2fc 100644 --- a/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_mult.sv +++ b/hw/vendor/openhwgroup_cv32e40p/rtl/cv32e40p_mult.sv @@ -55,6 +55,7 @@ module cv32e40p_mult output logic [31:0] result_o, output logic multicycle_o, + output logic mulh_active_o, output logic ready_o, input logic ex_ready_i ); @@ -87,7 +88,6 @@ module cv32e40p_mult logic [ 1:0] mulh_signed; logic mulh_shift_arith; logic mulh_carry_q; - logic mulh_active; logic mulh_save; logic mulh_clearcarry; logic mulh_ready; @@ -105,7 +105,7 @@ module cv32e40p_mult assign short_op_a[16] = short_signed[0] & short_op_a[15]; assign short_op_b[16] = short_signed[1] & short_op_b[15]; - assign short_op_c = mulh_active ? $signed({mulh_carry_q, op_c_i}) : $signed(op_c_i); + assign short_op_c = mulh_active_o ? $signed({mulh_carry_q, op_c_i}) : $signed(op_c_i); assign short_mul = $signed(short_op_a) * $signed(short_op_b); assign short_mac = $signed(short_op_c) + $signed(short_mul) + $signed(short_round); @@ -116,13 +116,13 @@ module cv32e40p_mult ) >>> short_imm; // choose between normal short multiplication operation and mulh operation - assign short_imm = mulh_active ? mulh_imm : imm_i; - assign short_subword = mulh_active ? mulh_subword : {2{short_subword_i}}; - assign short_signed = mulh_active ? mulh_signed : short_signed_i; - assign short_shift_arith = mulh_active ? mulh_shift_arith : short_signed_i[0]; + assign short_imm = mulh_active_o ? mulh_imm : imm_i; + assign short_subword = mulh_active_o ? mulh_subword : {2{short_subword_i}}; + assign short_signed = mulh_active_o ? mulh_signed : short_signed_i; + assign short_shift_arith = mulh_active_o ? mulh_shift_arith : short_signed_i[0]; - assign short_mac_msb1 = mulh_active ? short_mac[33] : short_mac[31]; - assign short_mac_msb0 = mulh_active ? short_mac[32] : short_mac[31]; + assign short_mac_msb1 = mulh_active_o ? short_mac[33] : short_mac[31]; + assign short_mac_msb0 = mulh_active_o ? short_mac[32] : short_mac[31]; always_comb begin @@ -132,16 +132,16 @@ module cv32e40p_mult mulh_signed = 2'b00; mulh_shift_arith = 1'b0; mulh_ready = 1'b0; - mulh_active = 1'b1; + mulh_active_o = 1'b1; mulh_save = 1'b0; mulh_clearcarry = 1'b0; multicycle_o = 1'b0; case (mulh_CS) IDLE_MULT: begin - mulh_active = 1'b0; - mulh_ready = 1'b1; - mulh_save = 1'b0; + mulh_active_o = 1'b0; + mulh_ready = 1'b1; + mulh_save = 1'b0; if ((operator_i == MUL_H) && enable_i) begin mulh_ready = 1'b0; mulh_NS = STEP0; @@ -149,12 +149,12 @@ module cv32e40p_mult end STEP0: begin - multicycle_o = 1'b1; - mulh_imm = 5'd16; - mulh_active = 1'b1; + multicycle_o = 1'b1; + mulh_imm = 5'd16; + mulh_active_o = 1'b1; //AL*BL never overflows - mulh_save = 1'b0; - mulh_NS = STEP1; + mulh_save = 1'b0; + mulh_NS = STEP1; //Here always a 32'b unsigned result (no carry) end diff --git a/hw/vendor/openhwgroup_cv32e40p/util/format-verible b/hw/vendor/openhwgroup_cv32e40p/util/format-verible index 69a46a0a4..974ecce81 100755 --- a/hw/vendor/openhwgroup_cv32e40p/util/format-verible +++ b/hw/vendor/openhwgroup_cv32e40p/util/format-verible @@ -11,4 +11,6 @@ then find rtl/ bhv/ -not -path "*rtl/vendor*" \ -name '*.sv' | \ xargs verible-verilog-format --inplace 2> /dev/zero -fi \ No newline at end of file +else +echo "verible-verilog-format not available!" +fi diff --git a/mcu_cfg_minimal.hjson b/mcu_cfg_minimal.hjson new file mode 100644 index 000000000..984405226 --- /dev/null +++ b/mcu_cfg_minimal.hjson @@ -0,0 +1,214 @@ +// Copyright 2020 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// Derived from Occamy: https://github.com/pulp-platform/snitch/blob/master/hw/system/occamy/src/occamy_cfg.hjson +// Peripherals configuration for core-v-mini-mcu. +{ + + cpu_type: cv32e20 + + bus_type: onetoM + + ram: { + address: 0x00000000, #only tried with 0, cannot be changed for now + numbanks: 2, #each bank is 32kB, cannot be changed for now + numbanks_interleaved: 0, + }, + + linker_script: { + #value used for the on-chip linker script, the on-flash linker script is generated using FLASH values and the whole RAM values + onchip_ls: { + code: { + address: 0x00000000, + lenght: 0x00000C800, #minimum size for freeRTOS and clang + } + data: { + address: 0x00000C800, + lenght: whatisleft, #keyword used to calculate the size as: ram.length - code.lenght + } + }, + } + + debug: { + address: 0x10000000, + length: 0x00100000, + }, + + ao_peripherals: { + address: 0x20000000, + length: 0x00100000, + soc_ctrl: { + offset: 0x00000000, + length: 0x00010000, + path: "./hw/ip/soc_ctrl/data/soc_ctrl.hjson" + }, + bootrom: { + offset: 0x00010000, + length: 0x00010000, + }, + spi_flash: { + offset: 0x00020000, + length: 0x00008000, + }, + spi_memio: { + offset: 0x00028000, + length: 0x00008000, + }, + spi_host: { + offset: 0x00030000, + length: 0x00010000, + path: "./hw/vendor/lowrisc_opentitan_spi_host/data/spi_host.hjson" + }, + power_manager: { + offset: 0x00040000, + length: 0x00010000, + path: "./hw/ip/power_manager/data/power_manager.hjson" + }, + rv_timer_ao: { + offset: 0x00050000, + length: 0x00010000, + }, + dma: { + offset: 0x00060000, + length: 0x00010000, + path: "./hw/ip/dma/data/dma.hjson" + }, + fast_intr_ctrl: { + offset: 0x00070000, + length: 0x00010000, + path: "./hw/ip/fast_intr_ctrl/data/fast_intr_ctrl.hjson" + }, + ext_peripheral: { + offset: 0x00080000, + length: 0x00010000, + }, + pad_control: { + offset: 0x00090000, + length: 0x00010000, + }, + gpio_ao: { + offset: 0x000A0000, + length: 0x00010000, + }, + uart: { + offset: 0x000B0000, + length: 0x00010000, + path: "./hw/vendor/lowrisc_opentitan/hw/ip/uart/data/uart.hjson" + }, + }, + + peripherals: { + address: 0x30000000, + length: 0x00100000, + rv_plic: { + offset: 0x00000000, + length: 0x00010000, + is_included: "no", + path: "./hw/vendor/lowrisc_opentitan/hw/ip/rv_plic/data/rv_plic.hjson" + }, + gpio: { + offset: 0x00020000, + length: 0x00010000, + is_included: "no", + path: "./hw/vendor/pulp_platform_gpio/gpio_regs.hjson" + }, + i2c: { + offset: 0x00030000, + length: 0x00010000, + is_included: "no", + path: "./hw/vendor/lowrisc_opentitan/hw/ip/i2c/data/i2c.hjson" + }, + rv_timer: { + offset: 0x00040000, + length: 0x00010000, + is_included: "no", + path: "./hw/vendor/lowrisc_opentitan/hw/ip/rv_timer/data/rv_timer.hjson" + }, + spi2: { + offset: 0x00050000, + length: 0x00010000, + is_included: "no", + }, + pdm2pcm: { + offset: 0x00060000, + length: 0x00010000, + is_included: "no", + path: "./hw/ip/pdm2pcm/data/pdm2pcm.hjson" + }, + i2s: { + offset: 0x00070000, + length: 0x00010000, + is_included: "no", + path: "./hw/ip/i2s/data/i2s.hjson" + }, + }, + + flash_mem: { + address: 0x40000000, + length: 0x01000000, + }, + + ext_slaves: { + address: 0xF0000000, + length: 0x01000000, + }, + + interrupts: { + number: 64, // Do not change this number! + list: { + // First one is always zero + null_intr: 0, + uart_intr_tx_watermark: 1, + uart_intr_rx_watermark: 2, + uart_intr_tx_empty: 3, + uart_intr_rx_overflow: 4, + uart_intr_rx_frame_err: 5, + uart_intr_rx_break_err: 6, + uart_intr_rx_timeout: 7, + uart_intr_rx_parity_err: 8, + gpio_intr_8: 9, + gpio_intr_9: 10, + gpio_intr_10: 11, + gpio_intr_11: 12, + gpio_intr_12: 13, + gpio_intr_13: 14, + gpio_intr_14: 15, + gpio_intr_15: 16, + gpio_intr_16: 17, + gpio_intr_17: 18, + gpio_intr_18: 19, + gpio_intr_19: 20, + gpio_intr_20: 21, + gpio_intr_21: 22, + gpio_intr_22: 23, + gpio_intr_23: 24, + gpio_intr_24: 25, + gpio_intr_25: 26, + gpio_intr_26: 27, + gpio_intr_27: 28, + gpio_intr_28: 29, + gpio_intr_29: 30, + gpio_intr_30: 31, + gpio_intr_31: 32, + intr_fmt_watermark: 33, + intr_rx_watermark: 34, + intr_fmt_overflow: 35, + intr_rx_overflow: 36, + intr_nak: 37, + intr_scl_interference: 38, + intr_sda_interference: 39, + intr_stretch_timeout: 40, + intr_sda_unstable: 41, + intr_trans_complete: 42, + intr_tx_empty: 43, + intr_tx_nonempty: 44, + intr_tx_overflow: 45, + intr_acq_overflow: 46, + intr_ack_stop: 47, + intr_host_timeout: 48, + spi2_intr_event: 49, + i2s_intr_event: 50, + dma_window_intr: 51, + } + } +} diff --git a/sw/CMakeLists.txt b/sw/CMakeLists.txt index 35ac7b1e1..d857d7927 100644 --- a/sw/CMakeLists.txt +++ b/sw/CMakeLists.txt @@ -51,6 +51,13 @@ set(CMAKE_CXX_STANDARD 14) SET(MAINFILE "main") +####################################################################### +# FIND HEADER FILES TO BE INCLUDED +####################################################################### + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Preliminary list of header files inside the source path + # Make a list of the header files that need to be included FILE(GLOB_RECURSE new_list FOLLOW_SYMLINKS ${SOURCE_PATH}*.h) SET(dir_list_str "") @@ -72,6 +79,9 @@ FOREACH(file_path ${new_list}) SET(add 1) endif() +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Prune list + if( add EQUAL 1 ) # If the file path mathced one of the criterion, add it to the list # Get the path of the obtained directory GET_FILENAME_COMPONENT(dir_path ${file_path} PATH) @@ -90,7 +100,8 @@ ENDFOREACH() LIST(REMOVE_DUPLICATES dir_list_str) LIST(REMOVE_DUPLICATES h_dir_list_) -message(STATUS "[INFO] ${dir_list_str}") +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Add list to the directories to be included # Get all the folders to include when linking SET(INCLUDE_FOLDERS "-I ${RISCV}/${COMPILER_PREFIX}elf/include \ @@ -100,6 +111,13 @@ SET(INCLUDE_FOLDERS "-I ${RISCV}/${COMPILER_PREFIX}elf/include \ ${dir_list_str}") +####################################################################### +# FIND SOURCE FILES TO BE INCLUDED +####################################################################### + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Preliminary list of source files inside the source path + # Make a list of the source files that need to be linked FILE(GLOB_RECURSE new_list FOLLOW_SYMLINKS ${SOURCE_PATH}*.c) SET( c_dir_list "" ) @@ -124,7 +142,9 @@ FOREACH(file_path IN LISTS new_list) ENDFOREACH() -# If the app did not exist in the provided path, try with the root project +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# If the app was not found, look into the root project + if( app_found EQUAL 0 ) SET(SOURCE_PATH ${ROOT_PROJECT}) @@ -150,6 +170,10 @@ endif() LIST(REMOVE_DUPLICATES c_dir_list) +####################################################################### +# DETERMINE IF APP IS EXTERNAL +####################################################################### + # Determine whether the target app is located in the root project or in an external folder if( ${SOURCE_PATH} STREQUAL ${ROOT_PROJECT} ) SET( internal_app 1 ) @@ -159,6 +183,47 @@ else() message( "${Magenta}External application${ColourReset}") endif() +####################################################################### +# FIND CRT FILES TO BE INCLUDED +####################################################################### + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Set the default CRT directories + +SET(LIB_CRT_P "${ROOT_PROJECT}device/lib/crt/crt0.S") +SET(LIB_VCTR_P "${ROOT_PROJECT}device/lib/crt/vectors.S") + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Look for external CRT files + +SET(CRTO "INTERNAL_CRTO") +SET( LIB_CRT_EXT_P "" ) +if( internal_app EQUAL 0 ) + FILE(GLOB_RECURSE new_list FOLLOW_SYMLINKS "${SOURCE_PATH}/external/lib/crt/*.S") + FOREACH(file_path IN LISTS new_list) + if(${file_path} MATCHES "external_crt0.S") + SET( CRTO "EXTERNAL_CRTO" ) + SET( LIB_CRT_EXT_P "${file_path}" ) + GET_FILENAME_COMPONENT(dir_path ${file_path} PATH) + SET(INCLUDE_FOLDERS "${INCLUDE_FOLDERS} -I ${dir_path}") + SET(h_dir_list_ ${h_dir_list_} "${dir_path}") + endif() + ENDFOREACH() +endif() + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# In case of a freertos based app + +if(${PROJECT} MATCHES "freertos") + #SET(LIB_CRT_P "${SOURCE_PATH}device/lib/crt_freertos/") + SET(LIB_VCTR_P "${SOURCE_PATH}device/lib/crt/vectors_freertos.S") +endif() + + +####################################################################### +# SET CRT AND LINKER TYPE +####################################################################### + # Get the correct path for the crt files and linker file if (${LINKER} STREQUAL "on_chip") #SET(LIB_CRT_P "${SOURCE_PATH}device/lib/crt/") @@ -175,16 +240,11 @@ elseif(${LINKER} STREQUAL "flash_exec") else() message( FATAL_ERROR "Linker specification is not correct" ) endif() -SET(LIB_CRT_P "${SOURCE_PATH}device/lib/crt/") -SET(LIB_VCTR_P "${LIB_CRT_P}vectors.S") -# Just in case it is a freertos based app -if(${PROJECT} MATCHES "freertos") - #SET(LIB_CRT_P "${SOURCE_PATH}device/lib/crt_freertos/") - SET(LIB_VCTR_P "${SOURCE_PATH}device/lib/crt/vectors_freertos.S") -endif() +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Debug messages to check the paths -# messages to check the paths +message(STATUS "[INFO] ${INCLUDE_FOLDERS}") message( "${Magenta}Current project: ${PROJECT}${ColourReset}") message( "${Magenta}Root project: ${ROOT_PROJECT}${ColourReset}") message( "${Magenta}Source path: ${SOURCE_PATH}${ColourReset}") @@ -195,13 +255,24 @@ message( "${Magenta}Targetting folder: ${INC_FOLDERS}${ColourReset}") message( "${Magenta}Target: ${TARGET}${ColourReset}") +####################################################################### +# SET LINKER PROPERTIES +####################################################################### + +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Set linked files + # Get all the files to include when linking -SET(LINKED_FILES "${LIB_CRT_P}crt0.S \ +SET(LINKED_FILES "${LIB_CRT_P} \ ${LIB_VCTR_P} \ + ${LIB_CRT_EXT_P} \ ${c_dir_list}") message( "${Magenta}Linked files: ${LINKED_FILES}${ColourReset}") +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Free-RTOS configurations + # fetch content from freertos kernel repository FetchContent_Declare( freertos_kernel GIT_REPOSITORY https://github.com/FreeRTOS/FreeRTOS-Kernel.git @@ -228,12 +299,16 @@ if(${PROJECT} MATCHES "freertos") FetchContent_MakeAvailable(freertos_kernel) endif() +# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # +# Set CMAKE flags + # specify the C standard set(COMPILER_LINKER_FLAGS "\ -march=${CMAKE_SYSTEM_PROCESSOR} \ -w -Os -g -nostdlib \ -DHOST_BUILD \ -D${CRT_TYPE} \ + -D${CRTO} \ -DportasmHANDLE_INTERRUPT=vSystemIrqHandler\ ") set(CMAKE_C_FLAGS ${COMPILER_LINKER_FLAGS}) @@ -256,6 +331,10 @@ endif() #add_subdirectory(device/lib/drivers) #add_subdirectory(device/lib/runtime) +####################################################################### +# SET TARGETS +####################################################################### + set(SOURCES ${SOURCE_PATH}applications/${PROJECT}/${MAINFILE}.c) # add the executable @@ -316,6 +395,10 @@ if (${COMPILER} MATCHES "clang") endif() endif() +####################################################################### +# SET CUSTOM COMMANDS +####################################################################### + # Post processing command to create a disassembly file add_custom_command(TARGET ${MAINFILE}.elf POST_BUILD COMMAND ${CMAKE_OBJDUMP} -S ${MAINFILE}.elf > ${MAINFILE}.disasm @@ -351,4 +434,4 @@ endforeach() SET(DCMAKE_EXPORT_COMPILE_COMMANDS ON) -#message( FATAL_ERROR "You can not do this at all, CMake will exit." ) +#message( FATAL_ERROR "You can not do this at all, CMake will exit." ) \ No newline at end of file diff --git a/tb/testharness.sv b/tb/testharness.sv index 3dddffc9d..9abe4180f 100644 --- a/tb/testharness.sv +++ b/tb/testharness.sv @@ -21,11 +21,11 @@ module testharness #( inout wire boot_select_i, inout wire execute_from_flash_i, - inout wire jtag_tck_i, - inout wire jtag_tms_i, - inout wire jtag_trst_ni, - inout wire jtag_tdi_i, - inout wire jtag_tdo_o, + input wire jtag_tck_i, + input wire jtag_tms_i, + input wire jtag_trst_ni, + input wire jtag_tdi_i, + output wire jtag_tdo_o, output logic [31:0] exit_value_o, inout wire exit_valid_o ); @@ -53,10 +53,14 @@ module testharness #( logic sim_jtag_enable = (JTAG_DPI == 1); wire sim_jtag_tck; wire sim_jtag_tms; - wire sim_jtag_trst; wire sim_jtag_tdi; wire sim_jtag_tdo; wire sim_jtag_trstn; + wire mux_jtag_tck; + wire mux_jtag_tms; + wire mux_jtag_tdi; + wire mux_jtag_tdo; + wire mux_jtag_trstn; wire [31:0] gpio; wire [3:0] spi_flash_sd_io; @@ -139,11 +143,11 @@ module testharness #( ) x_heep_system_i ( .clk_i, .rst_ni, - .jtag_tck_i(sim_jtag_tck), - .jtag_tms_i(sim_jtag_tms), - .jtag_trst_ni(sim_jtag_trstn), - .jtag_tdi_i(sim_jtag_tdi), - .jtag_tdo_o(sim_jtag_tdo), + .jtag_tck_i(mux_jtag_tck), + .jtag_tms_i(mux_jtag_tms), + .jtag_trst_ni(mux_jtag_trstn), + .jtag_tdi_i(mux_jtag_tdi), + .jtag_tdo_o(mux_jtag_tdo), .boot_select_i, .execute_from_flash_i, .exit_valid_o, @@ -335,7 +339,15 @@ module testharness #( .exit() ); - assign slow_ram_slave_req = ext_slave_req[SLOW_MEMORY_IDX]; + assign mux_jtag_tck = JTAG_DPI ? sim_jtag_tck : jtag_tck_i; + assign mux_jtag_tms = JTAG_DPI ? sim_jtag_tms : jtag_tms_i; + assign mux_jtag_tdi = JTAG_DPI ? sim_jtag_tdi : jtag_tdi_i; + assign mux_jtag_trstn = JTAG_DPI ? sim_jtag_trstn : jtag_trst_ni; + + assign sim_jtag_tdo = JTAG_DPI ? mux_jtag_tdo : '0; + assign jtag_tdo_o = !JTAG_DPI ? mux_jtag_tdo : '0; + + assign slow_ram_slave_req = ext_slave_req[SLOW_MEMORY_IDX]; assign ext_slave_resp[SLOW_MEMORY_IDX] = slow_ram_slave_resp; generate