Skip to content

Commit

Permalink
Merge pull request #936 from silabs-oivind/bhv_todo_fix_1
Browse files Browse the repository at this point in the history
Corrected simulation trace documentation
  • Loading branch information
Silabs-ArjanB authored Sep 7, 2023
2 parents 5916d4d + c345c34 commit 14081f0
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 65 deletions.
5 changes: 3 additions & 2 deletions bhv/cv32e40x_rvfi.sv
Original file line number Diff line number Diff line change
Expand Up @@ -849,13 +849,14 @@ module cv32e40x_rvfi
rvfi_trap_next.exception_cause = ctrl_fsm_i.csr_cause.exception_code[5:0]; // All synchronous exceptions fit in lower 6 bits
rvfi_trap_next.clicptr = clic_ptr_wb_i;

// Separate exception causes with the same ecseption cause code
// Separate exception causes with the same exception cause code
case (ctrl_fsm_i.csr_cause.exception_code)
EXC_CAUSE_INSTR_FAULT : begin
rvfi_trap_next.cause_type = instr_pmp_err[STAGE_WB] ? 2'h1 : 2'h0;
end
EXC_CAUSE_BREAKPOINT : begin
// Todo: Add support for trigger match exceptions when implemented in rtl
// etrigger.action=0 is not implemented, cause_type is always 0 upon breakpoint exceptions
rvfi_trap_next.cause_type = 2'h0;
end
EXC_CAUSE_LOAD_FAULT : begin
rvfi_trap_next.cause_type = mem_err[STAGE_WB];
Expand Down
99 changes: 61 additions & 38 deletions bhv/cv32e40x_rvfi_sim_trace.sv
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,28 @@ module cv32e40x_rvfi_sim_trace
trace_t itrace, tmp_trace;
trace_t imap[int];
int file, logfile;
int elements_found, asmlen;
int elements_found, asmlen, num_memop, num_trace_lines;
string filename, logfilename, line;
string asms[5];
string asm_string, rvfi_info_string;
bit itb_file_ok, logfile_ok, enable_log_write;
bit itb_file_ok, logfile_ok;

// Populate itrace based on retired instruction
// todo: update tracer to support Zc sequences
// Currently only the lower index of rvfi_mem is used, and no usage of rvfi_gpr*
// Return number of memory operations based on rvfi_mem_rmask/wmask
function int get_num_memop(bit [4*NMEM-1:0] rvfi_mem_mask);

int num_memop;
num_memop = 0;

for (int i=0; i<NMEM; i++) begin
if(|rvfi_mem_mask[i*4 +: 4]) begin
num_memop++;
end
end

return num_memop;
endfunction : get_num_memop

// Populate itrace and trace log based on retired instruction
generate
begin
if (ITRACE_ENABLE) begin
Expand All @@ -84,61 +97,71 @@ module cv32e40x_rvfi_sim_trace
if (^rvfi_pc_rdata !== 1'bx && imap.exists(rvfi_pc_rdata)) begin
// Pick trace from instruction map
itrace = imap[rvfi_pc_rdata];
if (logfile_ok) begin
end
else begin
itrace = TRACE_UNKNOWN;
end

if (logfile_ok) begin

num_memop = get_num_memop(rvfi_mem_wmask) + get_num_memop(rvfi_mem_rmask);

// Print one line if there are no transfers to memory
num_trace_lines = num_memop > 0 ? num_memop : 1;

for (int unsigned i_trace=0; i_trace < num_trace_lines; i_trace++) begin
rvfi_info_string = $sformatf(
"0x%8h | x%-2d (0x%8h) | x%-2d (0x%8h) | x%-2d (0x%8h) | 0x%8h | 0x%4b | 0x%8h | 0x%4b | 0x%8h ||",
rvfi_pc_rdata,
rvfi_rs1_addr, rvfi_rs1_rdata,
rvfi_rs2_addr, rvfi_rs2_rdata,
rvfi_rd_addr, rvfi_rd_wdata,
rvfi_mem_addr[31:0],
rvfi_mem_rmask[3:0], rvfi_mem_rdata[31:0],
rvfi_mem_wmask[3:0], rvfi_mem_wdata[31:0]);
"0x%8h | x%-2d (0x%8h) | x%-2d (0x%8h) | x%-2d (0x%8h) | 0x%8h | 0x%4b | 0x%8h | 0x%4b | 0x%8h || ",
rvfi_pc_rdata,
rvfi_rs1_addr, rvfi_rs1_rdata,
rvfi_rs2_addr, rvfi_rs2_rdata,
rvfi_rd_addr, rvfi_rd_wdata,
rvfi_mem_addr[i_trace*32+:32],
rvfi_mem_rmask[i_trace*4+:4], rvfi_mem_rdata[i_trace*32+:32],
rvfi_mem_wmask[i_trace*4+:4], rvfi_mem_wdata[i_trace*32+:32]);
asm_string = $sformatf("%-s %-s", rvfi_info_string, string'(itrace.asm));
$fdisplay(logfile, asm_string);
asm_string = "";
end
end
else begin
itrace = TRACE_UNKNOWN;
end

end
end

// Parse the listing file
initial begin
enable_log_write = 1'b1;

$display("RISC-V Trace: Using itb path defined by plusarg: %s", ITB_PLUSARG);

$display("RISC-V Trace: Using log file path defined by plusarg: %s", LOGFILE_PATH_PLUSARG);
if (!$value$plusargs({LOGFILE_PATH_PLUSARG,"=%s"}, logfilename)) begin
$display($sformatf("Not generating instruction trace log file, please supply +%0s=<PATH> if desired.", LOGFILE_PATH_PLUSARG));
enable_log_write = 1'b0;
end
else begin
logfile = $fopen(logfilename, "w");
if (logfile == 0) begin
$warning("RISC-V Trace: Failed to open log file: %0s", logfilename);
logfile_ok = 1'b0;
end
else begin
$display("RISC-V Trace: Writing log to: %s", logfilename);

logfile_ok = 1'b1;
$fdisplay(logfile, {$sformatf("%-10s | %-3s (%-10s) | %-3s (%-10s) | %-3s (%-10s) | ",
"pc", "rs1", " data", "rs2", " data", "rd", " data"),
$sformatf("%-10s | %-6s | %-10s | %-6s | %-10s || Assembly",
"memaddr", "rmask", "rdata", "wmask", "wdata")
});
$fdisplay(logfile, {"==================================================================",
"=========================================================================="});
end
end

$display("RISC-V Trace: Using itb path defined by plusarg: %s", ITB_PLUSARG);
if (!$value$plusargs({ITB_PLUSARG,"=%s"}, filename)) begin
$display("RISC-V Trace: No instruction table file found.");
end
else begin

file = $fopen(filename, "r");
if (enable_log_write == 1'b1) begin
logfile = $fopen(logfilename, "w");
if (logfile == 0) begin
$warning("Failed to open log file: %0s", logfilename);
logfile_ok = 1'b0;
end
else begin
logfile_ok = 1'b1;
$fdisplay(logfile, {$sformatf("%-10s | %-3s (%-10s) | %-3s (%-10s) | %-3s (%-10s) | ",
"pc", "rs1", " data", "rs2", " data", "rd", " data"),
$sformatf("%-10s | %-6s | %-10s | %-6s | %-10s || Assembly",
"memaddr", "rmask", "rdata", "wmask", "wdata")
});
$fdisplay(logfile, {"==================================================================",
"=========================================================================="});
end
end

if (file == 0) begin
$display("RISC-V Trace: Failed to open instruction table file %s", filename);
Expand Down
Binary file added docs/user_manual/images/rvfi_trace.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
55 changes: 30 additions & 25 deletions docs/user_manual/source/rvfi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -325,38 +325,43 @@ The ``rvfi_mode`` signal shows the *current* privilege mode as opposed to the *e

``rvfi_instr_prot`` indicates the value of OBI prot used for fetching the retired instruction. Note that this will be undefined upon access faults.

Trace output file
Simulation trace
-----------------

Tracing can be enabled during simulation by defining **CV32E40X_TRACE_EXECUTION**. All traced instructions are written to a log file.
The log file is named ``trace_rvfi.log``.
The module ``cv32e40x_rvfi_sim_trace`` can be bound to ``cv32e40x_rvfi`` to enable tracing capabilities.
``cv32e40x_rvfi_sim_trace`` supports trace output to log file and trace annotation in waveforms.

Trace annotation in waveforms is enabled by providing the path to an .itb file through the simulation plusarg ``itb_file``. The name of the plusarg can be overridden through the ``cv32e40x_rvfi_sim_trace`` parameter ``ITB_PLUSARG``.
The struct ``itrace`` in ``cv32e40x_rvfi_sim_trace`` will contain information about the most recently retired instruction.

Trace output to log is enabled by providing log file path through the simulation plusarg ``log_file``. The name of the plusarg can be overridden through the ``cv32e40x_rvfi_sim_trace`` parameter ``LOGFILE_PATH_PLUSARG``.

Trace output format
-------------------

The trace output is in tab-separated columns.

1. **PC**: The program counter
2. **Instr**: The executed instruction (base 16).
32 bit wide instructions (8 hex digits) are uncompressed instructions, 16 bit wide instructions (4 hex digits) are compressed instructions.
3. **rs1_addr** Register read port 1 source address, 0x0 if not used by instruction
4. **rs1_data** Register read port 1 read data, 0x0 if not used by instruction
5. **rs2_addr** Register read port 2 source address, 0x0 if not used by instruction
6. **rs2_data** Register read port 2 read data, 0x0 if not used by instruction
7. **rd_addr** Register write port 1 destination address, 0x0 if not used by instruction
8. **rd_data** Register write port 1 write data, 0x0 if not used by instruction
9. **mem_addr** Memory address for instructions accessing memory
10. **rvfi_mem_rmask** Bitmask specifying which bytes in ``rvfi_mem_rdata`` contain valid read data
11. **rvfi_mem_wmask** Bitmask specifying which bytes in ``rvfi_mem_wdata`` contain valid write data
12. **rvfi_mem_rdata** The data read from memory address specified in ``mem_addr``
13. **rvfi_mem_wdata** The data written to memory address specified in ``mem_addr``
The trace log file format is as described below.

1. **pc**: The program counter
2. **rs1(data)** Register read port 1 source register and read data
3. **rs2(data)** Register read port 2 source register and read data
4. **rd(data)** Register write port 1 destination register and write data
5. **memaddr** Memory address for instructions accessing memory
6. **rmask** Bitmask specifying which bytes in ``rdata`` contain valid read data
7. **rdata** The data read from memory address specified in ``memaddr``
8. **wmask** Bitmask specifying which bytes in ``wdata`` contain valid write data
9. **wdata** The data written to memory address specified in ``memaddr``
10. **Assembly** Assembly code. This column is only populated if an itb file is provided

.. code-block:: text
PC Instr rs1_addr rs1_rdata rs2_addr rs2_rdata rd_addr rd_wdata mem_addr mem_rmask mem_wmask mem_rdata mem_wdata
00001f9c 14c70793 0e 000096c8 0c 00000000 0f 00009814 00009814 0 0 00000000 00000000
00001fa0 14f72423 0e 000096c8 0f 00009814 00 00000000 00009810 0 f 00000000 00009814
00001fa4 0000bf6d 1f 00000000 1b 00000000 00 00000000 00001fa6 0 0 00000000 00000000
00001f5e 000043d8 0f 00009814 04 00000000 0e 00000000 00009818 f 0 00000000 00000000
00001f60 0000487d 00 00000000 1f 00000000 10 0000001f 0000001f 0 0 00000000 00000000
pc | rs1 ( data ) | rs2 ( data ) | rd ( data ) | memaddr | rmask | rdata | wmask | wdata || Assembly
0x00000080 | x0 (0x00000000) | x0 (0x00000000) | x3 (0x00013080) | 0x00013080 | 0x0000 | 0x00000000 | 0x0000 | 0x00000000 || auipc x3,0x13
0x00000084 | x3 (0x00013080) | x0 (0x00000000) | x3 (0x00013610) | 0x00013610 | 0x0000 | 0x00000000 | 0x0000 | 0x00000000 || addi x3,x3,1424
0x00000088 | x0 (0x00000000) | x0 (0x00000000) | x10 (0x00000088) | 0x00000088 | 0x0000 | 0x00000000 | 0x0000 | 0x00000000 || auipc x10,0x0
0x0000008c | x10 (0x00000088) | x0 (0x00000000) | x10 (0x00000400) | 0x00000400 | 0x0000 | 0x00000000 | 0x0000 | 0x00000000 || addi x10,x10,888
The waveform annotation for the same trace is depicted below:

.. figure:: ../images/rvfi_trace.png
:name: Trace waveform annotation
:align: center

0 comments on commit 14081f0

Please sign in to comment.