mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-20 03:47:15 -04:00
[test] Connect FPU subsystem
This commit is contained in:
parent
83588ae089
commit
13bbaf72d9
16 changed files with 830 additions and 198 deletions
|
@ -58,8 +58,8 @@ ISS := spike
|
|||
# ISS runtime options
|
||||
ISS_OPTS :=
|
||||
# ISA
|
||||
ISA := rv32imcb
|
||||
ISA_ISS := rv32imc_Zba_Zbb_Zbc_Zbs_Xbitmanip
|
||||
ISA := rv32imfcb
|
||||
ISA_ISS := rv32imfc_Zba_Zbb_Zbc_Zbs_Xbitmanip
|
||||
# Test name (default: full regression)
|
||||
TEST := all
|
||||
TESTLIST := riscv_dv_extension/testlist.yaml
|
||||
|
|
|
@ -13,6 +13,54 @@
|
|||
+define+TRACE_EXECUTION
|
||||
+define+RVFI
|
||||
|
||||
// common cells
|
||||
+incdir+${PRJ_DIR}/vendor/pulp_common_cells/include
|
||||
${PRJ_DIR}/vendor/pulp_common_cells/src/cf_math_pkg.sv
|
||||
${PRJ_DIR}/vendor/pulp_common_cells/src/fifo_v3.sv
|
||||
${PRJ_DIR}/vendor/pulp_common_cells/src/stream_fifo.sv
|
||||
${PRJ_DIR}/vendor/pulp_common_cells/src/lzc.sv
|
||||
${PRJ_DIR}/vendor/pulp_common_cells/src/rr_arb_tree.sv
|
||||
|
||||
// fpu_div_sqrt_mvp
|
||||
+incdir+${PRJ_DIR}/vendor/pulp_fpu_div_sqrt_mvp/
|
||||
${PRJ_DIR}/vendor/pulp_fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_div_sqrt_mvp/hdl/control_mvp.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_div_sqrt_mvp/hdl/div_sqrt_mvp_wrapper.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv
|
||||
|
||||
// fpnew
|
||||
+incdir+${PRJ_DIR}/vendor/openhwgroup_cvfpu/
|
||||
${PRJ_DIR}/vendor/openhwgroup_cvfpu/src/fpnew_pkg.sv
|
||||
${PRJ_DIR}/vendor/openhwgroup_cvfpu/src/fpnew_cast_multi.sv
|
||||
${PRJ_DIR}/vendor/openhwgroup_cvfpu/src/fpnew_classifier.sv
|
||||
${PRJ_DIR}/vendor/openhwgroup_cvfpu/src/fpnew_divsqrt_multi.sv
|
||||
${PRJ_DIR}/vendor/openhwgroup_cvfpu/src/fpnew_fma.sv
|
||||
${PRJ_DIR}/vendor/openhwgroup_cvfpu/src/fpnew_fma_multi.sv
|
||||
${PRJ_DIR}/vendor/openhwgroup_cvfpu/src/fpnew_noncomp.sv
|
||||
${PRJ_DIR}/vendor/openhwgroup_cvfpu/src/fpnew_opgroup_block.sv
|
||||
${PRJ_DIR}/vendor/openhwgroup_cvfpu/src/fpnew_opgroup_fmt_slice.sv
|
||||
${PRJ_DIR}/vendor/openhwgroup_cvfpu/src/fpnew_opgroup_multifmt_slice.sv
|
||||
${PRJ_DIR}/vendor/openhwgroup_cvfpu/src/fpnew_rounding.sv
|
||||
${PRJ_DIR}/vendor/openhwgroup_cvfpu/src/fpnew_top.sv
|
||||
|
||||
// FPU Subsystem files
|
||||
+incdir+${PRJ_DIR}/vendor/pulp_fpu_ss/src
|
||||
${PRJ_DIR}/vendor/pulp_fpu_ss/src/fpu_ss_pkg.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_ss/src/fpu_ss_instr_pkg.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_ss/src/fpu_ss_prd_f_pkg.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_ss/src/fpu_ss_prd_zfinx_pkg.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_ss/src/fpu_ss.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_ss/src/fpu_ss_compressed_predecoder.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_ss/src/fpu_ss_predecoder.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_ss/src/fpu_ss_decoder.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_ss/src/fpu_ss_regfile.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_ss/src/fpu_ss_csr.sv
|
||||
${PRJ_DIR}/vendor/pulp_fpu_ss/src/fpu_ss_controller.sv
|
||||
|
||||
// Shared lowRISC code
|
||||
+incdir+${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl
|
||||
${PRJ_DIR}/vendor/lowrisc_ip/ip/prim/rtl/prim_assert.sv
|
||||
|
|
|
@ -32,7 +32,8 @@ finally:
|
|||
INSTR_RE = \
|
||||
re.compile(r"^\s*(?P<time>\d+)\s+(?P<cycle>\d+)\s+(?P<pc>[0-9a-f]+)\s+"
|
||||
r"(?P<bin>[0-9a-f]+)\s+(?P<instr>\S+\s+\S+)\s*")
|
||||
RD_RE = re.compile(r"(x(?P<rd>[1-9]\d*)=0x(?P<rd_val>[0-9a-f]+))")
|
||||
# RD_RE = re.compile(r"(x(?P<rd>[1-9]\d*)=0x(?P<rd_val>[0-9a-f]+))")
|
||||
RD_RE = re.compile(r"((?P<reg>[xf]?)(?P<rd>[0-9]\d*)=0x(?P<rd_val>[0-9a-f]+))")
|
||||
ADDR_RE = re.compile(r"(?P<rd>[a-z0-9]+?),"
|
||||
r"(?P<imm>[\-0-9]+?)"
|
||||
r"\((?P<rs1>[a-z0-9]+)\)")
|
||||
|
@ -76,10 +77,14 @@ def _process_ibex_sim_log_fd(log_fd, csv_fd, full_trace=True):
|
|||
expand_trace_entry(trace_entry, m.group("instr").split()[1])
|
||||
|
||||
c = RD_RE.search(line)
|
||||
# if c:
|
||||
# abi_name = gpr_to_abi("x{}".format(c.group("rd")))
|
||||
if c:
|
||||
abi_name = gpr_to_abi("x{}".format(c.group("rd")))
|
||||
gpr_entry = "{}:{}".format(abi_name, c.group("rd_val"))
|
||||
trace_entry.gpr.append(gpr_entry)
|
||||
not_x0 = (c.group("reg") + c.group("rd")) != 'x0'
|
||||
if not_x0:
|
||||
abi_name = gpr_to_abi("{}{}".format(c.group("reg"), c.group("rd")))
|
||||
gpr_entry = "{}:{}".format(abi_name, c.group("rd_val"))
|
||||
trace_entry.gpr.append(gpr_entry)
|
||||
|
||||
trace_csv.write_trace_entry(trace_entry)
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
parameter int XLEN = 32;
|
||||
|
||||
// GPR setting
|
||||
parameter int NUM_FLOAT_GPR = 0;
|
||||
parameter int NUM_FLOAT_GPR = 32;
|
||||
parameter int NUM_GPR = 32;
|
||||
parameter int NUM_VEC_GPR = 0;
|
||||
|
||||
|
@ -53,7 +53,7 @@ bit support_unaligned_load_store = 1'b1;
|
|||
|
||||
// ISA supported by the processor
|
||||
riscv_instr_group_t supported_isa[$] = {RV32I, RV32M, RV32C,
|
||||
RV32ZBA, RV32ZBB, RV32ZBC, RV32ZBS, RV32B};
|
||||
RV32ZBA, RV32ZBB, RV32ZBC, RV32ZBS, RV32B, RV32F, RV32FC};
|
||||
|
||||
// Interrupt mode support
|
||||
mtvec_mode_t supported_interrupt_mode[$] = {VECTORED};
|
||||
|
|
|
@ -768,3 +768,30 @@
|
|||
rtl_test: core_ibex_base_test
|
||||
rtl_params:
|
||||
RV32B: ["ibex_pkg::RV32BFull", "ibex_pkg::RV32BOTEarlGrey", "ibex_pkg::RV32BBalanced"]
|
||||
|
||||
# Floating Point Tests
|
||||
- test: riscv_arithmetic_fp_test
|
||||
description: >
|
||||
Arithmetic instruction test, no load/store/branch instructions
|
||||
gen_opts: >
|
||||
+instr_cnt=10000
|
||||
+num_of_sub_program=0
|
||||
+no_fence=1
|
||||
+no_data_page=1
|
||||
+no_branch_jump=1
|
||||
+boot_mode=m
|
||||
+enable_floating_point=1
|
||||
iterations: 10
|
||||
gen_test: riscv_instr_base_test
|
||||
rtl_test: core_ibex_base_test
|
||||
|
||||
- test: riscv_rand_instr_fp_test
|
||||
description: >
|
||||
Random instruction stress test
|
||||
iterations: 10
|
||||
gen_test: riscv_instr_base_test
|
||||
gen_opts: >
|
||||
+instr_cnt=10000
|
||||
+num_of_sub_program=5
|
||||
+enable_floating_point=1
|
||||
rtl_test: core_ibex_base_test
|
||||
|
|
|
@ -68,6 +68,31 @@ module core_ibex_tb_top;
|
|||
parameter bit XInterface = 1'b1;
|
||||
parameter bit MemInterface = 1'b1;
|
||||
|
||||
logic x_compressed_valid;
|
||||
logic x_compressed_ready;
|
||||
ibex_pkg::x_compressed_req_t x_compressed_req;
|
||||
ibex_pkg::x_compressed_resp_t x_compressed_resp;
|
||||
|
||||
logic x_issue_valid;
|
||||
logic x_issue_ready;
|
||||
ibex_pkg::x_issue_req_t x_issue_req;
|
||||
ibex_pkg::x_issue_resp_t x_issue_resp;
|
||||
|
||||
logic x_commit_valid;
|
||||
ibex_pkg::x_commit_t x_commit;
|
||||
|
||||
logic x_mem_valid;
|
||||
logic x_mem_ready;
|
||||
ibex_pkg::x_mem_req_t x_mem_req;
|
||||
ibex_pkg::x_mem_resp_t x_mem_resp;
|
||||
|
||||
logic x_mem_result_valid;
|
||||
ibex_pkg::x_mem_result_t x_mem_result;
|
||||
|
||||
logic x_result_valid;
|
||||
logic x_result_ready;
|
||||
ibex_pkg::x_result_t x_result;
|
||||
|
||||
ibex_top_tracing #(
|
||||
.DmHaltAddr (32'h`BOOT_ADDR + 'h0 ),
|
||||
.DmExceptionAddr (32'h`BOOT_ADDR + 'h4 ),
|
||||
|
@ -139,27 +164,83 @@ module core_ibex_tb_top;
|
|||
.alert_major_bus_o (dut_if.alert_major_bus ),
|
||||
.core_sleep_o (dut_if.core_sleep ),
|
||||
|
||||
.x_compressed_valid_o ( ),
|
||||
.x_compressed_ready_i (1'b0 ),
|
||||
.x_compressed_req_o ( ),
|
||||
.x_compressed_resp_i ('0 ),
|
||||
.x_issue_valid_o ( ),
|
||||
.x_issue_ready_i (1'b0 ),
|
||||
.x_issue_req_o ( ),
|
||||
.x_issue_resp_i ('0 ),
|
||||
.x_commit_valid_o ( ),
|
||||
.x_commit_o ( ),
|
||||
.x_mem_valid_i (1'b0 ),
|
||||
.x_mem_ready_o ( ),
|
||||
.x_mem_req_i ('0 ),
|
||||
.x_mem_resp_o ( ),
|
||||
.x_mem_result_valid_o ( ),
|
||||
.x_mem_result_o ( ),
|
||||
.x_result_valid_i (1'b0 ),
|
||||
.x_result_ready_o ( ),
|
||||
.x_result_i ('0 )
|
||||
.x_compressed_valid_o (x_compressed_valid ),
|
||||
.x_compressed_ready_i (x_compressed_ready ),
|
||||
.x_compressed_req_o (x_compressed_req ),
|
||||
.x_compressed_resp_i (x_compressed_resp ),
|
||||
.x_issue_valid_o (x_issue_valid ),
|
||||
.x_issue_ready_i (x_issue_ready ),
|
||||
.x_issue_req_o (x_issue_req ),
|
||||
.x_issue_resp_i (x_issue_resp ),
|
||||
.x_commit_valid_o (x_commit_valid ),
|
||||
.x_commit_o (x_commit ),
|
||||
.x_mem_valid_i (x_mem_valid ),
|
||||
.x_mem_ready_o (x_mem_ready ),
|
||||
.x_mem_req_i (x_mem_req ),
|
||||
.x_mem_resp_o (x_mem_resp ),
|
||||
.x_mem_result_valid_o (x_mem_result_valid ),
|
||||
.x_mem_result_o (x_mem_result ),
|
||||
.x_result_valid_i (x_result_valid ),
|
||||
.x_result_ready_o (x_result_ready ),
|
||||
.x_result_i (x_result )
|
||||
);
|
||||
|
||||
fpu_ss #(
|
||||
.PULP_ZFINX ( 0 ),
|
||||
.INPUT_BUFFER_DEPTH ( 2 ),
|
||||
.OUT_OF_ORDER ( 1 ),
|
||||
.FORWARDING ( 1 ),
|
||||
.FPU_FEATURES ( ),
|
||||
.FPU_IMPLEMENTATION ( )
|
||||
) fpu_ss_i (
|
||||
// clock and reset
|
||||
.clk_i (clk),
|
||||
.rst_ni (rst_n),
|
||||
|
||||
// Compressed Interface
|
||||
.x_compressed_valid_i (x_compressed_valid),
|
||||
.x_compressed_ready_o (x_compressed_ready),
|
||||
.x_compressed_req_i (x_compressed_req),
|
||||
.x_compressed_resp_o (x_compressed_resp),
|
||||
|
||||
// Issue Interface
|
||||
.x_issue_valid_i (x_issue_valid),
|
||||
.x_issue_ready_o (x_issue_ready),
|
||||
.x_issue_req_i (x_issue_req),
|
||||
.x_issue_resp_o (x_issue_resp),
|
||||
|
||||
// Commit Interface
|
||||
.x_commit_valid_i (x_commit_valid),
|
||||
.x_commit_i (x_commit),
|
||||
|
||||
// Memory Request/Response Interface
|
||||
.x_mem_valid_o (x_mem_valid),
|
||||
.x_mem_ready_i (x_mem_ready),
|
||||
.x_mem_req_o (x_mem_req),
|
||||
.x_mem_resp_i (x_mem_resp),
|
||||
|
||||
// Memory Result Interface
|
||||
.x_mem_result_valid_i (x_mem_result_valid),
|
||||
.x_mem_result_i (x_mem_result),
|
||||
|
||||
// Result Interface
|
||||
.x_result_valid_o (x_result_valid),
|
||||
.x_result_ready_i (x_result_ready),
|
||||
.x_result_o (x_result)
|
||||
);
|
||||
|
||||
// always_comb begin
|
||||
// if (fpu_ss_i.fpr_we) begin
|
||||
// force dut.u_ibex_top.u_ibex_core.rvfi_rd_wdata_d = fpu_ss_i.fpr_wb_data;
|
||||
// end else begin
|
||||
// release dut.u_ibex_top.u_ibex_core.rvfi_rd_wdata_d;
|
||||
// end
|
||||
// end
|
||||
|
||||
always_comb begin
|
||||
force dut.u_ibex_top.u_ibex_core.rvfi_rd_wdata_fp = fpu_ss_i.fpr_wb_data;
|
||||
end
|
||||
|
||||
// We should never see any alerts triggered in normal testing
|
||||
`ASSERT(NoAlertsTriggered,
|
||||
!dut_if.alert_minor && !dut_if.alert_major_internal && !dut_if.alert_major_bus, clk, !rst_n)
|
||||
|
|
|
@ -149,6 +149,7 @@ targets:
|
|||
# RAM primitives wider than 64bit (required for ECC) fail to build in
|
||||
# Verilator without increasing the unroll count (see Verilator#1266)
|
||||
- "--unroll-count 72"
|
||||
- "-Wno-BLKANDNBLK"
|
||||
|
||||
sim:
|
||||
<<: *default_target
|
||||
|
@ -171,7 +172,17 @@ targets:
|
|||
- '-CFLAGS "-std=c++11 -Wall -DVM_TRACE_FMT_FST -DTOPLEVEL_NAME=ibex_simple_system -g"'
|
||||
- '-LDFLAGS "-pthread -lutil -lelf"'
|
||||
- "-Wall"
|
||||
- "-Wwarn-IMPERFECTSCH"
|
||||
# - "-Wwarn-IMPERFECTSCH"
|
||||
# RAM primitives wider than 64bit (required for ECC) fail to build in
|
||||
# Verilator without increasing the unroll count (see Verilator#1266)
|
||||
- "--unroll-count 72"
|
||||
- "-Wno-BLKANDNBLK"
|
||||
- "-Wno-UNUSED"
|
||||
- "-Wno-WIDTH"
|
||||
- "-Wno-LITENDIAN"
|
||||
- "-Wno-UNOPTFLAT"
|
||||
- "-Wno-UNSIGNED"
|
||||
- "-Wno-WIDTHCONCAT"
|
||||
- "-Wno-VARHIDDEN"
|
||||
- "-Wno-IMPORTSTAR"
|
||||
- "-Wno-DECLFILENAME"
|
||||
|
|
|
@ -9,6 +9,7 @@ filesets:
|
|||
depend:
|
||||
- lowrisc:ibex:ibex_top_tracing
|
||||
- lowrisc:ibex:sim_shared
|
||||
- lowrisc:ibex:fpu_ss
|
||||
files:
|
||||
- rtl/ibex_simple_system.sv
|
||||
file_type: systemVerilogSource
|
||||
|
|
|
@ -185,6 +185,31 @@ module ibex_simple_system (
|
|||
assign instr_rdata_intg = '0;
|
||||
end
|
||||
|
||||
logic x_compressed_valid;
|
||||
logic x_compressed_ready;
|
||||
ibex_pkg::x_compressed_req_t x_compressed_req;
|
||||
ibex_pkg::x_compressed_resp_t x_compressed_resp;
|
||||
|
||||
logic x_issue_valid;
|
||||
logic x_issue_ready;
|
||||
ibex_pkg::x_issue_req_t x_issue_req;
|
||||
ibex_pkg::x_issue_resp_t x_issue_resp;
|
||||
|
||||
logic x_commit_valid;
|
||||
ibex_pkg::x_commit_t x_commit;
|
||||
|
||||
logic x_mem_valid;
|
||||
logic x_mem_ready;
|
||||
ibex_pkg::x_mem_req_t x_mem_req;
|
||||
ibex_pkg::x_mem_resp_t x_mem_resp;
|
||||
|
||||
logic x_mem_result_valid;
|
||||
ibex_pkg::x_mem_result_t x_mem_result;
|
||||
|
||||
logic x_result_valid;
|
||||
logic x_result_ready;
|
||||
ibex_pkg::x_result_t x_result;
|
||||
|
||||
ibex_top_tracing #(
|
||||
.SecureIbex ( SecureIbex ),
|
||||
.ICacheScramble ( ICacheScramble ),
|
||||
|
@ -258,27 +283,71 @@ module ibex_simple_system (
|
|||
.alert_major_bus_o (),
|
||||
.core_sleep_o (),
|
||||
|
||||
.x_compressed_valid_o (),
|
||||
.x_compressed_ready_i (1'b0),
|
||||
.x_compressed_req_o (),
|
||||
.x_compressed_resp_i ('0),
|
||||
.x_issue_valid_o (),
|
||||
.x_issue_ready_i (1'b0),
|
||||
.x_issue_req_o (),
|
||||
.x_issue_resp_i ('0),
|
||||
.x_commit_valid_o (),
|
||||
.x_commit_o (),
|
||||
.x_mem_valid_i (1'b0),
|
||||
.x_mem_ready_o (),
|
||||
.x_mem_req_i ('0),
|
||||
.x_mem_resp_o (),
|
||||
.x_mem_result_valid_o (),
|
||||
.x_mem_result_o (),
|
||||
.x_result_valid_i (1'b0),
|
||||
.x_result_ready_o (),
|
||||
.x_result_i ('0)
|
||||
.x_compressed_valid_o (x_compressed_valid),
|
||||
.x_compressed_ready_i (x_compressed_ready),
|
||||
.x_compressed_req_o (x_compressed_req),
|
||||
.x_compressed_resp_i (x_compressed_resp),
|
||||
.x_issue_valid_o (x_issue_valid),
|
||||
.x_issue_ready_i (x_issue_ready),
|
||||
.x_issue_req_o (x_issue_req),
|
||||
.x_issue_resp_i (x_issue_resp),
|
||||
.x_commit_valid_o (x_commit_valid),
|
||||
.x_commit_o (x_commit),
|
||||
.x_mem_valid_i (x_mem_valid),
|
||||
.x_mem_ready_o (x_mem_ready),
|
||||
.x_mem_req_i (x_mem_req),
|
||||
.x_mem_resp_o (x_mem_resp),
|
||||
.x_mem_result_valid_o (x_mem_result_valid),
|
||||
.x_mem_result_o (x_mem_result),
|
||||
.x_result_valid_i (x_result_valid),
|
||||
.x_result_ready_o (x_result_ready),
|
||||
.x_result_i (x_result)
|
||||
);
|
||||
|
||||
fpu_ss #(
|
||||
.PULP_ZFINX ( 0 ),
|
||||
.INPUT_BUFFER_DEPTH ( 2 ),
|
||||
.OUT_OF_ORDER ( 1 ),
|
||||
.FORWARDING ( 1 ),
|
||||
.FPU_FEATURES ( ),
|
||||
.FPU_IMPLEMENTATION ( )
|
||||
) fpu_ss_i (
|
||||
// clock and reset
|
||||
.clk_i (clk_sys),
|
||||
.rst_ni (rst_sys_n),
|
||||
|
||||
// Compressed Interface
|
||||
.x_compressed_valid_i (x_compressed_valid),
|
||||
.x_compressed_ready_o (x_compressed_ready),
|
||||
.x_compressed_req_i (x_compressed_req),
|
||||
.x_compressed_resp_o (x_compressed_resp),
|
||||
|
||||
// Issue Interface
|
||||
.x_issue_valid_i (x_issue_valid),
|
||||
.x_issue_ready_o (x_issue_ready),
|
||||
.x_issue_req_i (x_issue_req),
|
||||
.x_issue_resp_o (x_issue_resp),
|
||||
|
||||
// Commit Interface
|
||||
.x_commit_valid_i (x_commit_valid),
|
||||
.x_commit_i (x_commit),
|
||||
|
||||
// Memory Request/Response Interface
|
||||
.x_mem_valid_o (x_mem_valid),
|
||||
.x_mem_ready_i (x_mem_ready),
|
||||
.x_mem_req_o (x_mem_req),
|
||||
.x_mem_resp_i (x_mem_resp),
|
||||
|
||||
// Memory Result Interface
|
||||
.x_mem_result_valid_i (x_mem_result_valid),
|
||||
.x_mem_result_i (x_mem_result),
|
||||
|
||||
// Result Interface
|
||||
.x_result_valid_o (x_result_valid),
|
||||
.x_result_ready_i (x_result_ready),
|
||||
.x_result_o (x_result)
|
||||
);
|
||||
|
||||
// SRAM block for instruction and data storage
|
||||
ram_2p #(
|
||||
.Depth(1024*1024/4),
|
||||
|
|
|
@ -8,7 +8,7 @@ COMMON_SRCS = $(wildcard $(COMMON_DIR)/*.c)
|
|||
INCS := -I$(COMMON_DIR)
|
||||
|
||||
# ARCH = rv32im # to disable compressed instructions
|
||||
ARCH ?= rv32imc
|
||||
ARCH ?= rv32imfc
|
||||
|
||||
ifdef PROGRAM
|
||||
PROGRAM_C := $(PROGRAM).c
|
||||
|
|
14
examples/sw/simple_system/hello_test_float/Makefile
Normal file
14
examples/sw/simple_system/hello_test_float/Makefile
Normal file
|
@ -0,0 +1,14 @@
|
|||
# Copyright lowRISC contributors.
|
||||
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# Generate a baremetal application
|
||||
|
||||
# Name of the program $(PROGRAM).c will be added as a source file
|
||||
PROGRAM = hello_test_float
|
||||
PROGRAM_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
# Any extra source files to include in the build. Use the upper case .S
|
||||
# extension for assembly files
|
||||
EXTRA_SRCS :=
|
||||
|
||||
include ${PROGRAM_DIR}/../common/common.mk
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "simple_system_common.h"
|
||||
// #include "stdio.h"
|
||||
volatile float a, b, c;
|
||||
|
||||
void add(float a, float b, float *res) {
|
||||
*res = a + a * b;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
pcount_enable(0);
|
||||
pcount_reset();
|
||||
pcount_enable(1);
|
||||
|
||||
a = 123.243;
|
||||
b = 475.874;
|
||||
add(a, b, &c);
|
||||
// printf("The result is: %f", c);
|
||||
|
||||
|
||||
puts("Hello simple system\n");
|
||||
puthex(0xDEADBEEF);
|
||||
putchar('\n');
|
||||
puthex(0xBAADF00D);
|
||||
putchar('\n');
|
||||
|
||||
pcount_enable(0);
|
||||
|
||||
// Enable periodic timer interrupt
|
||||
// (the actual timebase is a bit meaningless in simulation)
|
||||
timer_enable(2000);
|
||||
|
||||
uint64_t last_elapsed_time = get_elapsed_time();
|
||||
|
||||
while (last_elapsed_time <= 4) {
|
||||
uint64_t cur_time = get_elapsed_time();
|
||||
if (cur_time != last_elapsed_time) {
|
||||
last_elapsed_time = cur_time;
|
||||
|
||||
if (last_elapsed_time & 1) {
|
||||
puts("Tick!\n");
|
||||
} else {
|
||||
puts("Tock!\n");
|
||||
}
|
||||
}
|
||||
asm volatile("wfi");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
442
rtl/ibex_core.sv
442
rtl/ibex_core.sv
|
@ -1238,6 +1238,51 @@ module ibex_core import ibex_pkg::*; #(
|
|||
end
|
||||
|
||||
`ifdef RVFI
|
||||
typedef struct packed {
|
||||
logic [63:0] rvfi_order;
|
||||
logic [31:0] rvfi_insn;
|
||||
logic rvfi_trap;
|
||||
logic rvfi_halt;
|
||||
logic rvfi_intr;
|
||||
logic [ 1:0] rvfi_mode;
|
||||
logic [ 1:0] rvfi_ixl;
|
||||
logic [ 4:0] rvfi_rs1_addr;
|
||||
logic [ 4:0] rvfi_rs2_addr;
|
||||
logic [ 4:0] rvfi_rs3_addr;
|
||||
logic [31:0] rvfi_rs1_rdata;
|
||||
logic [31:0] rvfi_rs2_rdata;
|
||||
logic [31:0] rvfi_rs3_rdata;
|
||||
logic [ 4:0] rvfi_rd_addr;
|
||||
logic [31:0] rvfi_rd_wdata;
|
||||
logic [31:0] rvfi_pc_rdata;
|
||||
logic [31:0] rvfi_pc_wdata;
|
||||
logic [31:0] rvfi_mem_addr;
|
||||
logic [ 3:0] rvfi_mem_rmask;
|
||||
logic [ 3:0] rvfi_mem_wmask;
|
||||
logic [31:0] rvfi_mem_rdata;
|
||||
logic [31:0] rvfi_mem_wdata;
|
||||
logic [31:0] rvfi_ext_mip;
|
||||
logic rvfi_ext_nmi;
|
||||
logic rvfi_ext_debug_req;
|
||||
logic [63:0] rvfi_ext_mcycle;
|
||||
} rvfi_t;
|
||||
|
||||
rvfi_t rvfi_ibex_push, rvfi_ibex_pop;
|
||||
rvfi_t [ICB_DEPTH-1:0] rvfi_xif_q;
|
||||
rvfi_t rvfi_out;
|
||||
logic rvfi_out_valid;
|
||||
logic [ICB_ID_W-1:0] rvfi_xif_id_q;
|
||||
logic rvfi_xif_id_valid_q;
|
||||
logic rvfi_ibex_push_valid;
|
||||
logic rvfi_ibex_pop_valid, rvfi_ibex_pop_ready;
|
||||
logic rvfi_xif_push_valid;
|
||||
logic rvfi_xif_pop_valid, rvfi_xif_pop_ready;
|
||||
|
||||
rvfi_t [31:0] rvfi_xif_buffer;
|
||||
logic [31:0] rvfi_xif_valid_q, rvfi_xif_valid_d;
|
||||
logic [5:0] rvfi_xif_addr_push, rvfi_xif_addr_pop;
|
||||
logic [5:0] rvfi_xif_addr_fin;
|
||||
|
||||
// When writeback stage is present RVFI information is emitted when instruction is finished in
|
||||
// third stage but some information must be captured whilst the instruction is in the second
|
||||
// stage. Without writeback stage RVFI information is all emitted when instruction retires in
|
||||
|
@ -1292,6 +1337,8 @@ module ibex_core import ibex_pkg::*; #(
|
|||
logic [31:0] rvfi_rd_wdata_wb;
|
||||
logic [31:0] rvfi_rd_wdata_d;
|
||||
logic [31:0] rvfi_rd_wdata_q;
|
||||
logic [31:0] rvfi_rd_wdata_fp;
|
||||
logic [31:0] rvfi_rd_wdata_int;
|
||||
logic rvfi_rd_we_wb;
|
||||
logic [3:0] rvfi_mem_mask_int;
|
||||
logic [31:0] rvfi_mem_rdata_d;
|
||||
|
@ -1303,10 +1350,9 @@ module ibex_core import ibex_pkg::*; #(
|
|||
logic rvfi_trap_id;
|
||||
logic rvfi_trap_wb;
|
||||
logic [63:0] rvfi_stage_order_d;
|
||||
logic [63:0] rvfi_stage_order_last;
|
||||
logic [63:0] rvfi_stage_order_q;
|
||||
logic rvfi_id_done;
|
||||
logic rvfi_wb_done;
|
||||
logic rvfi_xif_last_q;
|
||||
|
||||
logic new_debug_req;
|
||||
logic new_nmi;
|
||||
|
@ -1327,47 +1373,65 @@ module ibex_core import ibex_pkg::*; #(
|
|||
|
||||
logic rvfi_stage_valid_d [RVFI_STAGES];
|
||||
|
||||
logic [ICB_DEPTH-1:0][63:0] rvfi_offl_order;
|
||||
logic [ICB_DEPTH-1:0][31:0] rvfi_offl_rs1_rdata;
|
||||
logic [ICB_DEPTH-1:0][31:0] rvfi_offl_rs2_rdata;
|
||||
logic [ICB_DEPTH-1:0][31:0] rvfi_offl_rs3_rdata;
|
||||
logic [ICB_DEPTH-1:0][4:0] rvfi_offl_rs1_addr;
|
||||
logic [ICB_DEPTH-1:0][4:0] rvfi_offl_rs2_addr;
|
||||
logic [ICB_DEPTH-1:0][4:0] rvfi_offl_rs3_addr;
|
||||
logic [ICB_DEPTH-1:0][4:0] rvfi_offl_rd_addr;
|
||||
logic [ICB_DEPTH-1:0][31:0] rvfi_offl_insn;
|
||||
logic [ICB_DEPTH-1:0][31:0] rvfi_offl_pc_rdata;
|
||||
logic [ICB_DEPTH-1:0][31:0] rvfi_offl_pc_wdata;
|
||||
logic [ICB_DEPTH-1:0][1:0] rvfi_offl_mode;
|
||||
logic instr_id_xif_mem;
|
||||
logic instr_id_xif_mem_result;
|
||||
|
||||
logic [ICB_ID_W-1:0] rvfi_xif_issue_id;
|
||||
logic [ICB_ID_W-1:0] rvfi_xif_issue_id_q;
|
||||
logic [ICB_ID_W-1:0] rvfi_xif_commit_id;
|
||||
logic [ICB_ID_W-1:0] rvfi_xif_mem_id;
|
||||
logic [ICB_ID_W-1:0] rvfi_xif_mem_result_id;
|
||||
logic [ICB_ID_W-1:0] rvfi_xif_result_id;
|
||||
|
||||
assign rvfi_valid = rvfi_stage_valid [RVFI_STAGES-1];
|
||||
assign rvfi_order = rvfi_stage_order [RVFI_STAGES-1];
|
||||
assign rvfi_insn = rvfi_stage_insn [RVFI_STAGES-1];
|
||||
assign rvfi_trap = rvfi_stage_trap [RVFI_STAGES-1];
|
||||
assign rvfi_halt = rvfi_stage_halt [RVFI_STAGES-1];
|
||||
assign rvfi_intr = rvfi_stage_intr [RVFI_STAGES-1];
|
||||
assign rvfi_mode = rvfi_stage_mode [RVFI_STAGES-1];
|
||||
assign rvfi_ixl = rvfi_stage_ixl [RVFI_STAGES-1];
|
||||
assign rvfi_rs1_addr = rvfi_stage_rs1_addr [RVFI_STAGES-1];
|
||||
assign rvfi_rs2_addr = rvfi_stage_rs2_addr [RVFI_STAGES-1];
|
||||
assign rvfi_rs3_addr = rvfi_stage_rs3_addr [RVFI_STAGES-1];
|
||||
assign rvfi_rs1_rdata = rvfi_stage_rs1_rdata[RVFI_STAGES-1];
|
||||
assign rvfi_rs2_rdata = rvfi_stage_rs2_rdata[RVFI_STAGES-1];
|
||||
assign rvfi_rs3_rdata = rvfi_stage_rs3_rdata[RVFI_STAGES-1];
|
||||
assign rvfi_rd_addr = rvfi_stage_rd_addr [RVFI_STAGES-1];
|
||||
assign rvfi_rd_wdata = rvfi_stage_rd_wdata [RVFI_STAGES-1];
|
||||
assign rvfi_pc_rdata = rvfi_stage_pc_rdata [RVFI_STAGES-1];
|
||||
assign rvfi_pc_wdata = rvfi_stage_pc_wdata [RVFI_STAGES-1];
|
||||
assign rvfi_mem_addr = rvfi_stage_mem_addr [RVFI_STAGES-1];
|
||||
assign rvfi_mem_rmask = rvfi_stage_mem_rmask[RVFI_STAGES-1];
|
||||
assign rvfi_mem_wmask = rvfi_stage_mem_wmask[RVFI_STAGES-1];
|
||||
assign rvfi_mem_rdata = rvfi_stage_mem_rdata[RVFI_STAGES-1];
|
||||
assign rvfi_mem_wdata = rvfi_stage_mem_wdata[RVFI_STAGES-1];
|
||||
assign rvfi_valid = rvfi_out_valid;
|
||||
assign rvfi_order = rvfi_out.rvfi_order;
|
||||
assign rvfi_insn = rvfi_out.rvfi_insn;
|
||||
assign rvfi_trap = rvfi_out.rvfi_trap;
|
||||
assign rvfi_halt = rvfi_out.rvfi_halt;
|
||||
assign rvfi_intr = rvfi_out.rvfi_intr;
|
||||
assign rvfi_mode = rvfi_out.rvfi_mode;
|
||||
assign rvfi_ixl = rvfi_out.rvfi_ixl;
|
||||
assign rvfi_rs1_addr = rvfi_out.rvfi_rs1_addr;
|
||||
assign rvfi_rs2_addr = rvfi_out.rvfi_rs2_addr;
|
||||
assign rvfi_rs3_addr = rvfi_out.rvfi_rs3_addr;
|
||||
assign rvfi_rs1_rdata = rvfi_out.rvfi_rs1_rdata;
|
||||
assign rvfi_rs2_rdata = rvfi_out.rvfi_rs2_rdata;
|
||||
assign rvfi_rs3_rdata = rvfi_out.rvfi_rs3_rdata;
|
||||
assign rvfi_rd_addr = rvfi_out.rvfi_rd_addr;
|
||||
assign rvfi_rd_wdata = rvfi_out.rvfi_rd_wdata;
|
||||
assign rvfi_pc_rdata = rvfi_out.rvfi_pc_rdata;
|
||||
assign rvfi_pc_wdata = rvfi_out.rvfi_pc_wdata;
|
||||
assign rvfi_mem_addr = rvfi_out.rvfi_mem_addr;
|
||||
assign rvfi_mem_rmask = rvfi_out.rvfi_mem_rmask;
|
||||
assign rvfi_mem_wmask = rvfi_out.rvfi_mem_wmask;
|
||||
assign rvfi_mem_rdata = rvfi_out.rvfi_mem_rdata;
|
||||
assign rvfi_mem_wdata = rvfi_out.rvfi_mem_wdata;
|
||||
assign rvfi_ext_mip = rvfi_out.rvfi_ext_mip;
|
||||
assign rvfi_ext_nmi = rvfi_out.rvfi_ext_nmi;
|
||||
assign rvfi_ext_debug_req = rvfi_out.rvfi_ext_debug_req;
|
||||
assign rvfi_ext_mcycle = rvfi_out.rvfi_ext_mcycle;
|
||||
|
||||
assign rvfi_ibex_push_valid = rvfi_stage_valid [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_order = rvfi_stage_order [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_insn = rvfi_stage_insn [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_trap = rvfi_stage_trap [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_halt = rvfi_stage_halt [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_intr = rvfi_stage_intr [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_mode = rvfi_stage_mode [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_ixl = rvfi_stage_ixl [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_rs1_addr = rvfi_stage_rs1_addr [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_rs2_addr = rvfi_stage_rs2_addr [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_rs3_addr = rvfi_stage_rs3_addr [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_rs1_rdata = rvfi_stage_rs1_rdata[RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_rs2_rdata = rvfi_stage_rs2_rdata[RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_rs3_rdata = rvfi_stage_rs3_rdata[RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_rd_addr = rvfi_stage_rd_addr [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_rd_wdata = rvfi_stage_rd_wdata [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_pc_rdata = rvfi_stage_pc_rdata [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_pc_wdata = rvfi_stage_pc_wdata [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_mem_addr = rvfi_stage_mem_addr [RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_mem_rmask = rvfi_stage_mem_rmask[RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_mem_wmask = rvfi_stage_mem_wmask[RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_mem_rdata = rvfi_stage_mem_rdata[RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_mem_wdata = rvfi_stage_mem_wdata[RVFI_STAGES-1];
|
||||
|
||||
assign rvfi_rd_addr_wb = rf_waddr_wb;
|
||||
assign rvfi_rd_wdata_wb = rf_we_wb ? rf_wdata_wb : rf_wdata_lsu;
|
||||
|
@ -1376,16 +1440,16 @@ module ibex_core import ibex_pkg::*; #(
|
|||
always_comb begin
|
||||
// Use always_comb instead of continuous assign so first assign can set 0 as default everywhere
|
||||
// that is overridden by more specific settings.
|
||||
rvfi_ext_mip = '0;
|
||||
rvfi_ext_mip[CSR_MSIX_BIT] = rvfi_ext_stage_mip[RVFI_STAGES].irq_software;
|
||||
rvfi_ext_mip[CSR_MTIX_BIT] = rvfi_ext_stage_mip[RVFI_STAGES].irq_timer;
|
||||
rvfi_ext_mip[CSR_MEIX_BIT] = rvfi_ext_stage_mip[RVFI_STAGES].irq_external;
|
||||
rvfi_ext_mip[CSR_MFIX_BIT_HIGH:CSR_MFIX_BIT_LOW] = rvfi_ext_stage_mip[RVFI_STAGES].irq_fast;
|
||||
rvfi_ibex_push.rvfi_ext_mip = '0;
|
||||
rvfi_ibex_push.rvfi_ext_mip[CSR_MSIX_BIT] = rvfi_ext_stage_mip[RVFI_STAGES].irq_software;
|
||||
rvfi_ibex_push.rvfi_ext_mip[CSR_MTIX_BIT] = rvfi_ext_stage_mip[RVFI_STAGES].irq_timer;
|
||||
rvfi_ibex_push.rvfi_ext_mip[CSR_MEIX_BIT] = rvfi_ext_stage_mip[RVFI_STAGES].irq_external;
|
||||
rvfi_ibex_push.rvfi_ext_mip[CSR_MFIX_BIT_HIGH:CSR_MFIX_BIT_LOW] = rvfi_ext_stage_mip[RVFI_STAGES].irq_fast;
|
||||
end
|
||||
|
||||
assign rvfi_ext_nmi = rvfi_ext_stage_nmi[RVFI_STAGES];
|
||||
assign rvfi_ext_debug_req = rvfi_ext_stage_debug_req[RVFI_STAGES];
|
||||
assign rvfi_ext_mcycle = rvfi_ext_stage_mcycle[RVFI_STAGES-1];
|
||||
assign rvfi_ibex_push.rvfi_ext_nmi = rvfi_ext_stage_nmi[RVFI_STAGES];
|
||||
assign rvfi_ibex_push.rvfi_ext_debug_req = rvfi_ext_stage_debug_req[RVFI_STAGES];
|
||||
assign rvfi_ibex_push.rvfi_ext_mcycle = rvfi_ext_stage_mcycle[RVFI_STAGES-1];
|
||||
|
||||
// When an instruction takes a trap the `rvfi_trap` signal will be set. Instructions that take
|
||||
// traps flush the pipeline so ordinarily wouldn't be seen to be retire. The RVFI tracking
|
||||
|
@ -1406,11 +1470,11 @@ module ibex_core import ibex_pkg::*; #(
|
|||
// awaiting instruction retirement and RF Write data/Mem read data whilst instruction is in WB
|
||||
// So first stage becomes valid when instruction leaves ID/EX stage and remains valid until
|
||||
// instruction leaves WB
|
||||
assign rvfi_stage_valid_d[0] = (rvfi_id_done & ~dummy_instr_id) | instr_id_xif_done |
|
||||
assign rvfi_stage_valid_d[0] = (rvfi_id_done & ~dummy_instr_id) |
|
||||
(rvfi_stage_valid[0] & ~rvfi_wb_done);
|
||||
// Second stage is output stage so simple valid cycle after instruction leaves WB (and so has
|
||||
// retired)
|
||||
assign rvfi_stage_valid_d[1] = rvfi_wb_done;
|
||||
assign rvfi_stage_valid_d[1] = rvfi_wb_done & rvfi_stage_valid[0];
|
||||
|
||||
// Signal new instruction in WB cycle after instruction leaves ID/EX (to enter WB)
|
||||
logic rvfi_instr_new_wb_q;
|
||||
|
@ -1434,7 +1498,7 @@ module ibex_core import ibex_pkg::*; #(
|
|||
end else begin : gen_rvfi_no_wb_stage
|
||||
// Without writeback stage first RVFI stage is output stage so simply valid the cycle after
|
||||
// instruction leaves ID/EX (and so has retired)
|
||||
assign rvfi_stage_valid_d[0] = (rvfi_id_done & ~dummy_instr_id) | instr_id_xif_done;
|
||||
assign rvfi_stage_valid_d[0] = (rvfi_id_done & ~dummy_instr_id);
|
||||
// Without writeback stage signal new instr_new_wb when instruction enters ID/EX to correctly
|
||||
// setup register write signals
|
||||
assign rvfi_instr_new_wb = instr_new_id;
|
||||
|
@ -1443,10 +1507,7 @@ module ibex_core import ibex_pkg::*; #(
|
|||
assign rvfi_wb_done = instr_done_wb;
|
||||
end
|
||||
|
||||
assign rvfi_stage_order_last = rvfi_xif_last_q ?
|
||||
rvfi_offl_order[rvfi_xif_issue_id_q] : rvfi_stage_order[0];
|
||||
assign rvfi_stage_order_d = dummy_instr_id ?
|
||||
rvfi_stage_order_last : rvfi_stage_order_last + 64'd1;
|
||||
assign rvfi_stage_order_d = dummy_instr_id ? rvfi_stage_order_q : rvfi_stage_order_q + 64'd1;
|
||||
|
||||
// For interrupts and debug Ibex will take the relevant trap as soon as whatever instruction in ID
|
||||
// finishes or immediately if the ID stage is empty. The rvfi_ext interface provides the DV
|
||||
|
@ -1517,51 +1578,190 @@ module ibex_core import ibex_pkg::*; #(
|
|||
end
|
||||
end
|
||||
|
||||
assign rvfi_xif_issue_id = x_issue_req_o.id[ICB_ID_W-1:0];
|
||||
assign rvfi_xif_commit_id = x_commit_o.id[ICB_ID_W-1:0];
|
||||
assign rvfi_xif_result_id = x_result_i.id[ICB_ID_W-1:0];
|
||||
prim_fifo_sync #(
|
||||
.Width (5),
|
||||
.Pass (1'b1),
|
||||
.Depth (32),
|
||||
.OutputZeroIfEmpty(1'b1)
|
||||
) rvfi_xif_fifo_i (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.clr_i (1'b0),
|
||||
|
||||
// Record the metadata of offloaded instructions, that writeback to the
|
||||
// integer register file. those will appear in the core trace log.
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
rvfi_offl_order <= '0;
|
||||
rvfi_offl_rs1_rdata <= '0;
|
||||
rvfi_offl_rs2_rdata <= '0;
|
||||
rvfi_offl_rs3_rdata <= '0;
|
||||
rvfi_offl_rs1_addr <= '0;
|
||||
rvfi_offl_rs2_addr <= '0;
|
||||
rvfi_offl_rs3_addr <= '0;
|
||||
rvfi_offl_rd_addr <= '0;
|
||||
rvfi_offl_insn <= '0;
|
||||
rvfi_offl_pc_rdata <= '0;
|
||||
rvfi_offl_pc_wdata <= '0;
|
||||
rvfi_offl_mode <= '0;
|
||||
rvfi_xif_issue_id_q <= '0;
|
||||
end else if (instr_id_xif_offl) begin
|
||||
rvfi_offl_order[rvfi_xif_issue_id] <= rvfi_stage_order_d;
|
||||
rvfi_offl_rs1_rdata[rvfi_xif_issue_id] <= x_issue_req_o.rs[0];
|
||||
rvfi_offl_rs2_rdata[rvfi_xif_issue_id] <= x_issue_req_o.rs[1];
|
||||
rvfi_offl_rs3_rdata[rvfi_xif_issue_id] <= (X_NUM_RS == 2) ? '0 : x_issue_req_o.rs[2];
|
||||
rvfi_offl_rs1_addr[rvfi_xif_issue_id] <= instr_rs1;
|
||||
rvfi_offl_rs2_addr[rvfi_xif_issue_id] <= instr_rs2;
|
||||
rvfi_offl_rs3_addr[rvfi_xif_issue_id] <= instr_rs3;
|
||||
rvfi_offl_rd_addr[rvfi_xif_issue_id] <= instr_rd;
|
||||
rvfi_offl_insn[rvfi_xif_issue_id] <= rvfi_insn_id;
|
||||
rvfi_offl_pc_rdata[rvfi_xif_issue_id] <= pc_id;
|
||||
rvfi_offl_pc_wdata[rvfi_xif_issue_id] <= pc_if;
|
||||
rvfi_offl_mode[rvfi_xif_issue_id] <= {priv_mode_id};
|
||||
rvfi_xif_issue_id_q <= rvfi_xif_issue_id;
|
||||
.wvalid_i(rvfi_xif_push_valid),
|
||||
.wready_o(),
|
||||
.wdata_i (rvfi_xif_addr_push),
|
||||
|
||||
.rvalid_o(rvfi_xif_pop_valid),
|
||||
.rready_i(rvfi_xif_pop_ready),
|
||||
.rdata_o (rvfi_xif_addr_pop),
|
||||
|
||||
.full_o (),
|
||||
.depth_o()
|
||||
);
|
||||
|
||||
prim_fifo_sync #(
|
||||
.Width ($bits(rvfi_ibex_push)),
|
||||
.Pass (1'b1),
|
||||
.Depth (32),
|
||||
.OutputZeroIfEmpty(1'b1)
|
||||
) rvfi_ibex_fifo_i (
|
||||
.clk_i (clk_i),
|
||||
.rst_ni (rst_ni),
|
||||
.clr_i (1'b0),
|
||||
|
||||
.wvalid_i(rvfi_ibex_push_valid),
|
||||
.wready_o(),
|
||||
.wdata_i (rvfi_ibex_push),
|
||||
|
||||
.rvalid_o(rvfi_ibex_pop_valid),
|
||||
.rready_i(rvfi_ibex_pop_ready),
|
||||
.rdata_o (rvfi_ibex_pop),
|
||||
|
||||
.full_o (),
|
||||
.depth_o()
|
||||
);
|
||||
|
||||
assign rvfi_xif_addr_fin = rvfi_xif_q[rvfi_xif_id_q].rvfi_order[4:0];
|
||||
assign rvfi_xif_addr_push = rvfi_stage_order_d[4:0];
|
||||
|
||||
always_comb begin
|
||||
rvfi_xif_valid_d = rvfi_xif_valid_q;
|
||||
if (rvfi_xif_pop_ready) begin
|
||||
rvfi_xif_valid_d[rvfi_xif_addr_pop] = 1'b0;
|
||||
end
|
||||
if (rvfi_xif_id_valid_q) begin
|
||||
rvfi_xif_valid_d[rvfi_xif_addr_fin] = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
rvfi_xif_last_q <= 1'b0;
|
||||
end else if (instr_id_xif_offl) begin
|
||||
rvfi_xif_last_q <= 1'b1;
|
||||
end else if (rvfi_id_done) begin
|
||||
rvfi_xif_last_q <= 1'b0;
|
||||
rvfi_xif_buffer <= '0;
|
||||
end else if (rvfi_xif_id_valid_q) begin
|
||||
rvfi_xif_buffer[rvfi_xif_addr_fin] <= rvfi_xif_q[rvfi_xif_id_q];
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
rvfi_xif_id_valid_q <= 1'b0;
|
||||
rvfi_xif_id_q <= '0;
|
||||
end else begin
|
||||
rvfi_xif_id_valid_q <= instr_id_xif_done;
|
||||
rvfi_xif_id_q <= rvfi_xif_result_id;
|
||||
end
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
rvfi_out_valid = 1'b0;
|
||||
rvfi_out = '0;
|
||||
rvfi_xif_pop_ready = 1'b0;
|
||||
rvfi_ibex_pop_ready = 1'b0;
|
||||
if (rvfi_xif_pop_valid & rvfi_ibex_pop_valid) begin
|
||||
if (rvfi_ibex_pop.rvfi_order < rvfi_xif_buffer[rvfi_xif_addr_pop].rvfi_order) begin
|
||||
rvfi_ibex_pop_ready = 1'b1;
|
||||
rvfi_out_valid = 1'b1;
|
||||
rvfi_out = rvfi_ibex_pop;
|
||||
end else begin
|
||||
if (rvfi_xif_valid_q[rvfi_xif_addr_pop]) begin
|
||||
rvfi_xif_pop_ready = 1'b1;
|
||||
rvfi_out_valid = 1'b1;
|
||||
rvfi_out = rvfi_xif_buffer[rvfi_xif_addr_pop];
|
||||
end
|
||||
end
|
||||
end else if (rvfi_xif_pop_valid & ~rvfi_ibex_pop_valid) begin
|
||||
if (rvfi_xif_valid_q[rvfi_xif_addr_pop]) begin
|
||||
rvfi_xif_pop_ready = 1'b1;
|
||||
rvfi_out_valid = 1'b1;
|
||||
rvfi_out = rvfi_xif_buffer[rvfi_xif_addr_pop];
|
||||
end
|
||||
end else if (~rvfi_xif_pop_valid & rvfi_ibex_pop_valid) begin
|
||||
rvfi_ibex_pop_ready = 1'b1;
|
||||
rvfi_out_valid = 1'b1;
|
||||
rvfi_out = rvfi_ibex_pop;
|
||||
end
|
||||
end
|
||||
|
||||
assign rvfi_xif_issue_id = x_issue_req_o.id[ICB_ID_W-1:0];
|
||||
assign rvfi_xif_mem_id = x_mem_req_i.id[ICB_ID_W-1:0];
|
||||
assign rvfi_xif_mem_result_id = x_mem_result_o.id[ICB_ID_W-1:0];
|
||||
assign rvfi_xif_result_id = x_result_i.id[ICB_ID_W-1:0];
|
||||
|
||||
assign instr_id_xif_mem = x_mem_valid_i & x_mem_ready_o;
|
||||
assign instr_id_xif_mem_result = x_mem_result_valid_o;
|
||||
|
||||
assign rvfi_xif_push_valid = instr_id_xif_offl;
|
||||
|
||||
assign rvfi_rd_wdata_fp = '0;
|
||||
assign rvfi_rd_wdata_int = x_result_i.data;
|
||||
|
||||
// Record the metadata of offloaded instructions, that writeback to the
|
||||
// integer register file. those will appear in the core trace log.
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
rvfi_xif_q <= '0;
|
||||
end else begin
|
||||
if (instr_id_xif_offl) begin
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_order <= rvfi_stage_order_d;
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_rs1_rdata <= x_issue_req_o.rs[0];
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_rs2_rdata <= x_issue_req_o.rs[1];
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_rs3_rdata <= (X_NUM_RS == 2) ? '0 : x_issue_req_o.rs[2];
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_rs1_addr <= instr_rs1;
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_rs2_addr <= instr_rs2;
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_rs3_addr <= instr_rs3;
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_rd_addr <= instr_rd;
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_insn <= rvfi_insn_id;
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_pc_rdata <= pc_id;
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_pc_wdata <= pc_if;
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_mode <= {priv_mode_id};
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_mem_rmask <= '0;
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_mem_wmask <= '0;
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_mem_rdata <= '0;
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_mem_wdata <= '0;
|
||||
rvfi_xif_q[rvfi_xif_issue_id].rvfi_mem_addr <= '0;
|
||||
end
|
||||
if (instr_id_xif_mem) begin
|
||||
rvfi_xif_q[rvfi_xif_mem_id].rvfi_mem_rmask <= rvfi_mem_mask_int;
|
||||
rvfi_xif_q[rvfi_xif_mem_id].rvfi_mem_wmask <= data_we_o ? rvfi_mem_mask_int : 4'b0000;
|
||||
rvfi_xif_q[rvfi_xif_mem_id].rvfi_mem_rdata <= rvfi_mem_rdata_d;
|
||||
rvfi_xif_q[rvfi_xif_mem_id].rvfi_mem_wdata <= rvfi_mem_wdata_d;
|
||||
rvfi_xif_q[rvfi_xif_mem_id].rvfi_mem_addr <= rvfi_mem_addr_d;
|
||||
end
|
||||
if (instr_id_xif_mem_result) begin
|
||||
rvfi_xif_q[rvfi_xif_mem_id].rvfi_mem_rdata <= rvfi_mem_rdata_d;
|
||||
end
|
||||
if (instr_id_xif_done) begin
|
||||
rvfi_xif_q[rvfi_xif_result_id].rvfi_halt <= '0;
|
||||
rvfi_xif_q[rvfi_xif_result_id].rvfi_trap <= rvfi_trap_id;
|
||||
rvfi_xif_q[rvfi_xif_result_id].rvfi_intr <= rvfi_intr_d;
|
||||
rvfi_xif_q[rvfi_xif_result_id].rvfi_ixl <= CSR_MISA_MXL;
|
||||
rvfi_xif_q[rvfi_xif_result_id].rvfi_ext_mip <= '0;
|
||||
rvfi_xif_q[rvfi_xif_result_id].rvfi_ext_nmi <= '0;
|
||||
rvfi_xif_q[rvfi_xif_result_id].rvfi_ext_debug_req <= '0;
|
||||
rvfi_xif_q[rvfi_xif_result_id].rvfi_ext_mcycle <= cs_registers_i.mcycle_counter_i.counter_val_o;
|
||||
if (id_stage_i.x_result_wb_en) begin
|
||||
rvfi_xif_q[rvfi_xif_result_id].rvfi_rd_wdata <= rvfi_rd_wdata_int;
|
||||
end else begin
|
||||
rvfi_xif_q[rvfi_xif_result_id].rvfi_rd_wdata <= rvfi_rd_wdata_fp;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
rvfi_stage_order_q <= '0;
|
||||
end else if (instr_id_xif_offl | rvfi_id_done) begin
|
||||
rvfi_stage_order_q <= rvfi_stage_order_d;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
rvfi_xif_valid_q <= '0;
|
||||
end else begin
|
||||
rvfi_xif_valid_q <= rvfi_xif_valid_d;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -1627,62 +1827,6 @@ module ibex_core import ibex_pkg::*; #(
|
|||
rvfi_ext_stage_nmi[i+1] <= rvfi_ext_stage_nmi[i];
|
||||
rvfi_ext_stage_debug_req[i+1] <= rvfi_ext_stage_debug_req[i];
|
||||
rvfi_ext_stage_mcycle[i] <= cs_registers_i.mcycle_counter_i.counter_val_o;
|
||||
end else if (instr_id_xif_done) begin
|
||||
if (instr_id_xif_offl & rvfi_xif_issue_id == rvfi_xif_result_id) begin
|
||||
rvfi_stage_halt[i] <= '0;
|
||||
rvfi_stage_trap[i] <= rvfi_trap_id;
|
||||
rvfi_stage_intr[i] <= rvfi_intr_d;
|
||||
rvfi_stage_order[i] <= rvfi_stage_order_d;
|
||||
rvfi_stage_insn[i] <= rvfi_insn_id;
|
||||
rvfi_stage_mode[i] <= {priv_mode_id};
|
||||
rvfi_stage_ixl[i] <= CSR_MISA_MXL;
|
||||
rvfi_stage_rs1_addr[i] <= instr_rs1;
|
||||
rvfi_stage_rs2_addr[i] <= instr_rs2;
|
||||
rvfi_stage_rs3_addr[i] <= instr_rs3;
|
||||
rvfi_stage_pc_rdata[i] <= pc_id;
|
||||
rvfi_stage_pc_wdata[i] <= pc_if;
|
||||
rvfi_stage_mem_rmask[i] <= rvfi_mem_mask_int;
|
||||
rvfi_stage_mem_wmask[i] <= data_we_o ? rvfi_mem_mask_int : 4'b0000;
|
||||
rvfi_stage_rs1_rdata[i] <= x_issue_req_o.rs[0];
|
||||
rvfi_stage_rs2_rdata[i] <= x_issue_req_o.rs[1];
|
||||
rvfi_stage_rs3_rdata[i] <= (X_NUM_RS == 2) ? '0 : x_issue_req_o.rs[2];
|
||||
rvfi_stage_rd_addr[i] <= instr_rd;
|
||||
rvfi_stage_rd_wdata[i] <= rvfi_rd_wdata_d;
|
||||
rvfi_stage_mem_rdata[i] <= '0;
|
||||
rvfi_stage_mem_wdata[i] <= '0;
|
||||
rvfi_stage_mem_addr[i] <= '0;
|
||||
rvfi_ext_stage_mip[i+1] <= rvfi_ext_stage_mip[i];
|
||||
rvfi_ext_stage_nmi[i+1] <= rvfi_ext_stage_nmi[i];
|
||||
rvfi_ext_stage_debug_req[i+1] <= rvfi_ext_stage_debug_req[i];
|
||||
rvfi_ext_stage_mcycle[i] <= cs_registers_i.mcycle_counter_i.counter_val_o;
|
||||
end else begin
|
||||
rvfi_stage_halt[i] <= '0;
|
||||
rvfi_stage_trap[i] <= rvfi_trap_id;
|
||||
rvfi_stage_intr[i] <= rvfi_intr_d;
|
||||
rvfi_stage_order[i] <= rvfi_offl_order[rvfi_xif_commit_id];
|
||||
rvfi_stage_insn[i] <= rvfi_offl_insn[rvfi_xif_result_id];
|
||||
rvfi_stage_mode[i] <= rvfi_offl_mode[rvfi_xif_result_id];
|
||||
rvfi_stage_ixl[i] <= CSR_MISA_MXL;
|
||||
rvfi_stage_rs1_addr[i] <= rvfi_offl_rs1_addr[rvfi_xif_result_id];
|
||||
rvfi_stage_rs2_addr[i] <= rvfi_offl_rs2_addr[rvfi_xif_result_id];
|
||||
rvfi_stage_rs3_addr[i] <= rvfi_offl_rs3_addr[rvfi_xif_result_id];
|
||||
rvfi_stage_pc_rdata[i] <= rvfi_offl_pc_rdata[rvfi_xif_result_id];
|
||||
rvfi_stage_pc_wdata[i] <= rvfi_offl_pc_wdata[rvfi_xif_result_id];
|
||||
rvfi_stage_mem_rmask[i] <= rvfi_mem_mask_int;
|
||||
rvfi_stage_mem_wmask[i] <= data_we_o ? rvfi_mem_mask_int : 4'b0000;
|
||||
rvfi_stage_rs1_rdata[i] <= rvfi_offl_rs1_rdata[rvfi_xif_result_id];
|
||||
rvfi_stage_rs2_rdata[i] <= rvfi_offl_rs2_rdata[rvfi_xif_result_id];
|
||||
rvfi_stage_rs3_rdata[i] <= rvfi_offl_rs3_rdata[rvfi_xif_result_id];
|
||||
rvfi_stage_rd_addr[i] <= rvfi_offl_rd_addr[rvfi_xif_result_id];
|
||||
rvfi_stage_rd_wdata[i] <= rvfi_rd_wdata_d;
|
||||
rvfi_stage_mem_rdata[i] <= '0;
|
||||
rvfi_stage_mem_wdata[i] <= '0;
|
||||
rvfi_stage_mem_addr[i] <= '0;
|
||||
rvfi_ext_stage_mip[i+1] <= rvfi_ext_stage_mip[i];
|
||||
rvfi_ext_stage_nmi[i+1] <= rvfi_ext_stage_nmi[i];
|
||||
rvfi_ext_stage_debug_req[i+1] <= rvfi_ext_stage_debug_req[i];
|
||||
rvfi_ext_stage_mcycle[i] <= cs_registers_i.mcycle_counter_i.counter_val_o;
|
||||
end
|
||||
end
|
||||
end else begin
|
||||
if (rvfi_wb_done) begin
|
||||
|
|
|
@ -95,6 +95,7 @@ module ibex_tracer (
|
|||
localparam logic [4:0] RD = (1 << 3);
|
||||
localparam logic [4:0] MEM = (1 << 4);
|
||||
logic [4:0] data_accessed;
|
||||
logic [3:0] data_accessed_fp;
|
||||
|
||||
logic trace_log_enable;
|
||||
initial begin
|
||||
|
@ -135,15 +136,27 @@ module ibex_tracer (
|
|||
if ((data_accessed & RS1) != 0) begin
|
||||
$fwrite(file_handle, " %s:0x%08x", reg_addr_to_str(rvfi_rs1_addr), rvfi_rs1_rdata);
|
||||
end
|
||||
if ((data_accessed_fp & RS1) != 0) begin
|
||||
$fwrite(file_handle, " %s:0x%08x", reg_addr_to_str_fp(rvfi_rs1_addr), rvfi_rs1_rdata);
|
||||
end
|
||||
if ((data_accessed & RS2) != 0) begin
|
||||
$fwrite(file_handle, " %s:0x%08x", reg_addr_to_str(rvfi_rs2_addr), rvfi_rs2_rdata);
|
||||
end
|
||||
if ((data_accessed_fp & RS2) != 0) begin
|
||||
$fwrite(file_handle, " %s:0x%08x", reg_addr_to_str_fp(rvfi_rs2_addr), rvfi_rs2_rdata);
|
||||
end
|
||||
if ((data_accessed & RS3) != 0) begin
|
||||
$fwrite(file_handle, " %s:0x%08x", reg_addr_to_str(rvfi_rs3_addr), rvfi_rs3_rdata);
|
||||
end
|
||||
if ((data_accessed_fp & RS3) != 0) begin
|
||||
$fwrite(file_handle, " %s:0x%08x", reg_addr_to_str_fp(rvfi_rs3_addr), rvfi_rs3_rdata);
|
||||
end
|
||||
if ((data_accessed & RD) != 0) begin
|
||||
$fwrite(file_handle, " %s=0x%08x", reg_addr_to_str(rvfi_rd_addr), rvfi_rd_wdata);
|
||||
end
|
||||
if ((data_accessed_fp & RD) != 0) begin
|
||||
$fwrite(file_handle, " %s=0x%08x", reg_addr_to_str_fp(rvfi_rd_addr), rvfi_rd_wdata);
|
||||
end
|
||||
if ((data_accessed & MEM) != 0) begin
|
||||
$fwrite(file_handle, " PA:0x%08x", rvfi_mem_addr);
|
||||
|
||||
|
@ -168,6 +181,15 @@ module ibex_tracer (
|
|||
end
|
||||
endfunction
|
||||
|
||||
// Format register address with "f" prefix, left-aligned to a fixed width of 3 characters.
|
||||
function automatic string reg_addr_to_str_fp(input logic [4:0] addr);
|
||||
if (addr < 10) begin
|
||||
return $sformatf(" f%0d", addr);
|
||||
end else begin
|
||||
return $sformatf("f%0d", addr);
|
||||
end
|
||||
endfunction
|
||||
|
||||
// Get a CSR name for a CSR address.
|
||||
function automatic string get_csr_name(input logic [11:0] csr_addr);
|
||||
unique case (csr_addr)
|
||||
|
@ -735,6 +757,91 @@ module ibex_tracer (
|
|||
decoded_str = $sformatf("fence\t%s,%s", predecessor, successor);
|
||||
endfunction
|
||||
|
||||
// floating point support
|
||||
|
||||
function automatic void decode_fp_store_insn(input string mnemonic);
|
||||
data_accessed = MEM;
|
||||
data_accessed_fp = RS1 | RS2;
|
||||
decoded_str = $sformatf("%s\tf%0d,%0d(x%0d)",
|
||||
mnemonic,
|
||||
rvfi_rs2_addr,
|
||||
$signed({{20{rvfi_insn[31]}}, rvfi_insn[31:25], rvfi_insn[11:7]}),
|
||||
rvfi_rs1_addr);
|
||||
endfunction
|
||||
|
||||
function automatic void decode_fp_load_insn(input string mnemonic);
|
||||
data_accessed = MEM;
|
||||
data_accessed_fp = RD | RS1;
|
||||
decoded_str = $sformatf("%s\tf%0d,%0d(x%0d)", mnemonic, rvfi_rd_addr,
|
||||
$signed({{20 {rvfi_insn[31]}}, rvfi_insn[31:20]}), rvfi_rs1_addr);
|
||||
endfunction
|
||||
|
||||
function automatic void decode_fp_s_insn(input string mnemonic);
|
||||
data_accessed_fp = RD | RS1;
|
||||
decoded_str = $sformatf("%s\tf%0d,f%0d", mnemonic, rvfi_rd_addr, rvfi_rs1_addr);
|
||||
endfunction
|
||||
|
||||
function automatic void decode_fp_s2_insn(input string mnemonic);
|
||||
data_accessed_fp = RD | RS1 | RS2;
|
||||
decoded_str = $sformatf("%s\tf%0d,f%0d,f%0d", mnemonic, rvfi_rd_addr, rvfi_rs1_addr,
|
||||
rvfi_rs2_addr);
|
||||
endfunction
|
||||
|
||||
function automatic void decode_fp_s3_insn(input string mnemonic);
|
||||
data_accessed_fp = RD | RS1 | RS2 | RS3;
|
||||
decoded_str = $sformatf("%s\tf%0d,f%0d,f%0d,f%0d", mnemonic, rvfi_rd_addr, rvfi_rs1_addr,
|
||||
rvfi_rs2_addr, rvfi_rs3_addr);
|
||||
endfunction
|
||||
|
||||
function automatic void decode_fp_w_s_insn(input string mnemonic);
|
||||
data_accessed = RD;
|
||||
data_accessed_fp = RS1;
|
||||
decoded_str = $sformatf("%s\tx%0d,f%0d", mnemonic, rvfi_rd_addr, rvfi_rs1_addr);
|
||||
endfunction
|
||||
|
||||
function automatic void decode_fp_w_s2_insn(input string mnemonic);
|
||||
data_accessed = RD;
|
||||
data_accessed_fp = RS1 | RS2;
|
||||
decoded_str = $sformatf("%s\tx%0d,f%0d,f%0d", mnemonic, rvfi_rd_addr, rvfi_rs1_addr,
|
||||
rvfi_rs2_addr);
|
||||
endfunction
|
||||
|
||||
function automatic void decode_fp_s_w_insn(input string mnemonic);
|
||||
data_accessed = RS1;
|
||||
data_accessed_fp = RD;
|
||||
decoded_str = $sformatf("%s\tf%0d,x%0d", mnemonic, rvfi_rd_addr, rvfi_rs1_addr);
|
||||
endfunction
|
||||
|
||||
function automatic void decode_fp_compressed_load_insn(input string mnemonic);
|
||||
logic [7:0] imm;
|
||||
if (rvfi_insn[1:0] == OPCODE_C0) begin
|
||||
// C.FLW
|
||||
imm = {1'b0, rvfi_insn[5], rvfi_insn[12:10], rvfi_insn[6], 2'b00};
|
||||
end else begin
|
||||
// C.FLWSP
|
||||
imm = {rvfi_insn[3:2], rvfi_insn[12], rvfi_insn[6:4], 2'b00};
|
||||
end
|
||||
|
||||
data_accessed = MEM;
|
||||
data_accessed_fp = RS1 | RD;
|
||||
decoded_str = $sformatf("%s\tf%0d,%0d(x%0d)", mnemonic, rvfi_rd_addr, imm, rvfi_rs1_addr);
|
||||
endfunction
|
||||
|
||||
function automatic void decode_fp_compressed_store_insn(input string mnemonic);
|
||||
logic [7:0] imm;
|
||||
if (rvfi_insn[1:0] == OPCODE_C0) begin
|
||||
// C.FSW
|
||||
imm = {1'b0, rvfi_insn[5], rvfi_insn[12:10], rvfi_insn[6], 2'b00};
|
||||
end else begin
|
||||
// C.FSWSP
|
||||
imm = {rvfi_insn[8:7], rvfi_insn[12:9], 2'b00};
|
||||
end
|
||||
|
||||
data_accessed = MEM;
|
||||
data_accessed_fp = RS1 | RS2;
|
||||
decoded_str = $sformatf("%s\tf%0d,%0d(x%0d)", mnemonic, rvfi_rs2_addr, imm, rvfi_rs1_addr);
|
||||
endfunction
|
||||
|
||||
// cycle counter
|
||||
always_ff @(posedge clk_i or negedge rst_ni) begin
|
||||
if (!rst_ni) begin
|
||||
|
@ -761,6 +868,7 @@ module ibex_tracer (
|
|||
always_comb begin
|
||||
decoded_str = "";
|
||||
data_accessed = 5'h0;
|
||||
data_accessed_fp = 4'h0;
|
||||
insn_is_compressed = 0;
|
||||
|
||||
// Check for compressed instructions
|
||||
|
@ -822,6 +930,11 @@ module ibex_tracer (
|
|||
INSN_CSLLI: decode_ci_cslli_insn("c.slli");
|
||||
INSN_CLWSP: decode_compressed_load_insn("c.lwsp");
|
||||
INSN_SWSP: decode_compressed_store_insn("c.swsp");
|
||||
// FP Instructions
|
||||
INSN_C_FLW: decode_fp_compressed_load_insn("c.flw");
|
||||
INSN_C_FSW: decode_fp_compressed_store_insn("c.fsw");
|
||||
INSN_C_FLWSP: decode_fp_compressed_load_insn("c.flwsp");
|
||||
INSN_C_FSWSP: decode_fp_compressed_store_insn("c.fswsp");
|
||||
default: decode_mnemonic("INVALID");
|
||||
endcase
|
||||
end
|
||||
|
@ -1062,6 +1175,34 @@ module ibex_tracer (
|
|||
INSN_CRC32C_H: decode_r1_insn("crc32c.h");
|
||||
INSN_CRC32C_W: decode_r1_insn("crc32c.w");
|
||||
|
||||
// RV32F
|
||||
INSN_FLW: decode_fp_load_insn("flw");
|
||||
INSN_FSW: decode_fp_store_insn("fsw");
|
||||
INSN_FMADD_S: decode_fp_s3_insn("fmadd.s");
|
||||
INSN_FMSUB_S: decode_fp_s3_insn("fmsub.s");
|
||||
INSN_FNMADD_S: decode_fp_s3_insn("fnmadd.s");
|
||||
INSN_FNMSUB_S: decode_fp_s3_insn("fnmsub.s");
|
||||
INSN_FADD_S: decode_fp_s2_insn("fadd.s");
|
||||
INSN_FSUB_S: decode_fp_s2_insn("fsub.s");
|
||||
INSN_FMUL_S: decode_fp_s2_insn("fmul.s");
|
||||
INSN_FDIV_S: decode_fp_s2_insn("fdiv.s");
|
||||
INSN_FSQRT_S: decode_fp_s_insn("fsqrt.s");
|
||||
INSN_FSGNJ_S: decode_fp_s2_insn("fsgnj.s");
|
||||
INSN_FSGNJN_S: decode_fp_s2_insn("fsgnjn.s");
|
||||
INSN_FSGNJX_S: decode_fp_s2_insn("fsgnjx.s");
|
||||
INSN_FMIN_S: decode_fp_s2_insn("fmin.s");
|
||||
INSN_FMAX_S: decode_fp_s2_insn("fmax.s");
|
||||
INSN_FCVT_W_S: decode_fp_w_s_insn("fcvt.w.s");
|
||||
INSN_FCVT_WU_S: decode_fp_w_s_insn("fcvt.wu.s");
|
||||
INSN_FMV_X_W: decode_fp_w_s_insn("fmv.x.w");
|
||||
INSN_FEQ_S: decode_fp_w_s2_insn("feq.s");
|
||||
INSN_FLT_S: decode_fp_w_s2_insn("flt.s");
|
||||
INSN_FLE_S: decode_fp_w_s2_insn("fle.s");
|
||||
INSN_FCLASS_S: decode_fp_w_s_insn("fclass.s");
|
||||
INSN_FCVT_S_W: decode_fp_s_w_insn("fcvt.s.w");
|
||||
INSN_FCVT_S_WU: decode_fp_s_w_insn("fcvt.s.wu");
|
||||
INSN_FMV_W_X: decode_fp_s_w_insn("fmv.w.x");
|
||||
|
||||
default: decode_mnemonic("INVALID");
|
||||
endcase
|
||||
end
|
||||
|
|
|
@ -332,4 +332,40 @@ package ibex_tracer_pkg;
|
|||
parameter logic [15:0] INSN_CJR = { 3'b100, 1'b0, 5'h0, 5'h0, {OPCODE_C2} };
|
||||
parameter logic [15:0] INSN_CJALR = { 3'b100, 1'b1, 5'h?, 5'h0, {OPCODE_C2} };
|
||||
|
||||
// F Extension
|
||||
parameter logic [31:0] INSN_FLW = { 17'h?, 3'b010, 5'h?, 7'b0000111 };
|
||||
parameter logic [31:0] INSN_FSW = { 17'h?, 3'b010, 5'h?, 7'b0100111 };
|
||||
|
||||
parameter logic [31:0] INSN_FMADD_S = { 5'h?, 2'b00, 18'h?, 7'b1000011 };
|
||||
parameter logic [31:0] INSN_FMSUB_S = { 5'h?, 2'b00, 18'h?, 7'b1000111 };
|
||||
parameter logic [31:0] INSN_FNMSUB_S = { 5'h?, 2'b00, 18'h?, 7'b1001011 };
|
||||
parameter logic [31:0] INSN_FNMADD_S = { 5'h?, 2'b00, 18'h?, 7'b1001111 };
|
||||
|
||||
parameter logic [31:0] INSN_FADD_S = { 5'b00000, 2'b00, 18'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FSUB_S = { 5'b00001, 2'b00, 18'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FMUL_S = { 5'b00010, 2'b00, 18'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FDIV_S = { 5'b00011, 2'b00, 18'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FSQRT_S = { 5'b01011, 2'b00, 5'b00000, 13'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FSGNJ_S = { 5'b00100, 2'b00, 10'h?, 3'b000, 5'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FSGNJN_S = { 5'b00100, 2'b00, 10'h?, 3'b001, 5'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FSGNJX_S = { 5'b00100, 2'b00, 10'h?, 3'b010, 5'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FMIN_S = { 5'b00101, 2'b00, 10'h?, 3'b000, 5'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FMAX_S = { 5'b00101, 2'b00, 10'h?, 3'b001, 5'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FCVT_W_S = { 5'b11000, 2'b00, 5'b00000, 13'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FCVT_WU_S = { 5'b11000, 2'b00, 5'b00001, 13'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FMV_X_W = { 5'b11100, 2'b00, 5'b00000, 5'h?, 3'b000, 5'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FEQ_S = { 5'b10100, 2'b00, 10'h?, 3'b010, 5'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FLT_S = { 5'b10100, 2'b00, 10'h?, 3'b001, 5'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FLE_S = { 5'b10100, 2'b00, 10'h?, 3'b000, 5'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FCLASS_S = { 5'b11100, 2'b00, 5'b00000, 5'h?, 3'b001, 5'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FCVT_S_W = { 5'b11010, 2'b00, 5'b00000, 13'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FCVT_S_WU = { 5'b11010, 2'b00, 5'b00001, 13'h?, 7'b1010011 };
|
||||
parameter logic [31:0] INSN_FMV_W_X = { 5'b11110, 2'b00, 5'b00000, 5'h?, 3'b000, 5'h?, 7'b1010011 };
|
||||
|
||||
// Compressed F Instruction
|
||||
parameter logic [15:0] INSN_C_FLWSP = { 3'b011, 11'h?, {OPCODE_C2} };
|
||||
parameter logic [15:0] INSN_C_FSWSP = { 3'b111, 11'h?, {OPCODE_C2} };
|
||||
parameter logic [15:0] INSN_C_FLW = { 3'b011, 11'h?, {OPCODE_C0} };
|
||||
parameter logic [15:0] INSN_C_FSW = { 3'b111, 11'h?, {OPCODE_C0} };
|
||||
|
||||
endpackage
|
||||
|
|
|
@ -27,8 +27,10 @@ sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))
|
|||
from riscv_trace_csv import *
|
||||
from lib import *
|
||||
|
||||
# RD_RE = re.compile(r"(core\s+\d+:\s+)?(?P<pri>\d) 0x(?P<addr>[a-f0-9]+?) " \
|
||||
# "\((?P<bin>.*?)\) (?P<reg>[xf]\s*\d*?) 0x(?P<val>[a-f0-9]+)")
|
||||
RD_RE = re.compile(r"(core\s+\d+:\s+)?(?P<pri>\d) 0x(?P<addr>[a-f0-9]+?) " \
|
||||
"\((?P<bin>.*?)\) (?P<reg>[xf]\s*\d*?) 0x(?P<val>[a-f0-9]+)")
|
||||
"\((?P<bin>.*?)\) ((c([0-9]+?)_([a-z]+?) 0x([a-f0-9]+?) )*?)(?P<reg>[xf]\s*\d*?) 0x(?P<val>[a-f0-9]+)")
|
||||
CORE_RE = re.compile(
|
||||
r"core\s+\d+:\s+0x(?P<addr>[a-f0-9]+?) \(0x(?P<bin>.*?)\) (?P<instr>.*?)$")
|
||||
ADDR_RE = re.compile(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue