From 8f983684c488bf3bba95f7432f4097fbd22b9934 Mon Sep 17 00:00:00 2001 From: Yoann Pruvost Date: Tue, 26 Mar 2024 11:44:35 +0800 Subject: [PATCH] RVFI - Correcting issue on trace log generation from rvfi --- bhv/cv32e40p_instr_trace.svh | 34 ++++++++++++- bhv/cv32e40p_rvfi.sv | 32 +++++++++--- bhv/cv32e40p_rvfi_trace.sv | 94 ++++++++++++++++++++++-------------- bhv/cv32e40p_tb_wrapper.sv | 5 ++ bhv/cv32e40p_tracer.sv | 3 +- bhv/insn_trace.sv | 20 +++++++- 6 files changed, 142 insertions(+), 46 deletions(-) diff --git a/bhv/cv32e40p_instr_trace.svh b/bhv/cv32e40p_instr_trace.svh index a89ed4e45..9b1bd3b7f 100644 --- a/bhv/cv32e40p_instr_trace.svh +++ b/bhv/cv32e40p_instr_trace.svh @@ -35,7 +35,10 @@ typedef struct { class instr_trace_t; time simtime; + time stoptime; + bit external_time; int cycles; + int stopcycles; logic [31:0] pc; logic [31:0] instr; bit compressed; @@ -56,10 +59,15 @@ class instr_trace_t; regs_read = {}; regs_write = {}; mem_access = {}; + external_time = 0; + stoptime = 0; + stopcycles = 0; endfunction function void init(int unsigned cycles, bit [31:0] pc, bit compressed, bit [31:0] instr); - this.simtime = $time; + if(!this.external_time) begin + this.simtime = $time; + end this.cycles = cycles; this.pc = pc; this.compressed = compressed; @@ -308,7 +316,23 @@ class instr_trace_t; begin string insn_str; // Accumulate writes into a single string to enable single $fwrite - insn_str = $sformatf("%t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + if(simtime < 100ns) begin + insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end else if (simtime < 1us) begin + insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end else if (simtime < 10us) begin + insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end else if (simtime < 100us) begin + insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end else if (simtime < 1ms) begin + insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end else if (simtime < 10ms) begin + insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end else if (simtime < 100ms) begin + insn_str = $sformatf(" %t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end else begin + insn_str = $sformatf("%t %15d %h %h %-36s", simtime, cycles, pc, instr, str); + end foreach (regs_write[i]) begin if (regs_write[i].addr != 0) @@ -330,6 +354,12 @@ class instr_trace_t; insn_str = $sformatf("%s PA:%08x", insn_str, mem_acc.addr); end + casex (instr) + INSTR_FDIV: insn_str = $sformatf("%s %15d %t", insn_str, stopcycles, stoptime); + INSTR_FSQRT:insn_str = $sformatf("%s %15d %t", insn_str, stopcycles, stoptime); + default: ; + endcase + $fwrite(f, "%s\n", insn_str); end endfunction diff --git a/bhv/cv32e40p_rvfi.sv b/bhv/cv32e40p_rvfi.sv index ab86e917b..607f889ab 100644 --- a/bhv/cv32e40p_rvfi.sv +++ b/bhv/cv32e40p_rvfi.sv @@ -328,6 +328,10 @@ module cv32e40p_rvfi // the convention of RISC-V Formal Interface Specification. output logic [ 0:0] rvfi_valid, output logic [63:0] rvfi_order, + output integer rvfi_start_cycle, + output time rvfi_start_time, + output integer rvfi_stop_cycle, + output time rvfi_stop_time, output logic [31:0] rvfi_insn, output rvfi_trap_t rvfi_trap, output logic [ 0:0] rvfi_halt, @@ -347,6 +351,7 @@ module cv32e40p_rvfi output logic rvfi_frd_wvalid [1:0], output logic [ 4:0] rvfi_frd_addr [1:0], output logic [31:0] rvfi_frd_wdata [1:0], + output logic rvfi_2_rd, output logic [ 4:0] rvfi_rs1_addr, output logic [ 4:0] rvfi_rs2_addr, output logic [ 4:0] rvfi_rs3_addr, @@ -367,8 +372,8 @@ module cv32e40p_rvfi output logic [31:0] rvfi_pc_wdata, output logic [31:0] rvfi_mem_addr, - output logic [ 3:0] rvfi_mem_rmask, - output logic [ 3:0] rvfi_mem_wmask, + output logic [31:0] rvfi_mem_rmask, + output logic [31:0] rvfi_mem_wmask, output logic [31:0] rvfi_mem_rdata, output logic [31:0] rvfi_mem_wdata, @@ -619,6 +624,13 @@ module cv32e40p_rvfi bit clk_i_d; assign #0.01 clk_i_d = clk_i; + integer cycles; + // cycle counter + always_ff @(posedge clk_i_d, negedge rst_ni) begin + if (rst_ni == 1'b0) cycles <= 0; + else cycles <= cycles + 1; + end + logic pc_mux_debug; logic pc_mux_dret; logic pc_mux_exception; @@ -749,6 +761,10 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end rvfi_order = new_rvfi_trace.m_order; + rvfi_start_cycle = new_rvfi_trace.m_start_cycle; + rvfi_start_time = new_rvfi_trace.m_start_time; + rvfi_stop_cycle = new_rvfi_trace.m_stop_cycle; + rvfi_stop_time = new_rvfi_trace.m_stop_time; rvfi_pc_rdata = new_rvfi_trace.m_pc_rdata; rvfi_insn = new_rvfi_trace.m_insn; @@ -803,6 +819,7 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; rvfi_frd_addr[1] = '0; rvfi_frd_wdata[1] = '0; + rvfi_2_rd = new_rvfi_trace.m_2_rd_insn; if (new_rvfi_trace.m_rd_addr[0][5] == 1'b0) begin rvfi_rd_addr[0] = new_rvfi_trace.m_rd_addr[0][4:0]; rvfi_rd_wdata[0] = new_rvfi_trace.m_rd_wdata[0]; @@ -1364,6 +1381,9 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; end end csr_to_apu_resp(); + + trace_apu_resp.m_stop_cycle = cycles; + trace_apu_resp.m_stop_time = $time; send_rvfi(trace_apu_resp); ->e_send_rvfi_trace_apu_resp; end @@ -1398,10 +1418,10 @@ insn_trace_t trace_if, trace_id, trace_ex, trace_ex_next, trace_wb; 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; + mask[7:0] = (be[0] == 1'b1) ? 8'hFF : 8'h00; + mask[15:8] = (be[1] == 1'b1) ? 8'hFF : 8'h00; + mask[23:16] = (be[2] == 1'b1) ? 8'hFF : 8'h00; + mask[31:24] = (be[3] == 1'b1) ? 8'hFF : 8'h00; be_to_mask = mask; return mask; diff --git a/bhv/cv32e40p_rvfi_trace.sv b/bhv/cv32e40p_rvfi_trace.sv index 417f562a2..a7b2c7b22 100644 --- a/bhv/cv32e40p_rvfi_trace.sv +++ b/bhv/cv32e40p_rvfi_trace.sv @@ -32,9 +32,13 @@ module cv32e40p_rvfi_trace input logic [31:0] imm_s3_type, - input logic rvfi_valid, - input logic [31:0] rvfi_insn, - input logic [31:0] rvfi_pc_rdata, + input logic rvfi_valid, + input logic [31:0] rvfi_insn, + input integer rvfi_start_cycle, + input time rvfi_start_time, + input integer rvfi_stop_cycle, + input time rvfi_stop_time, + input logic [31:0] rvfi_pc_rdata, input logic [ 4:0] rvfi_rd_addr [1:0], input logic [31:0] rvfi_rd_wdata[1:0], @@ -42,6 +46,7 @@ module cv32e40p_rvfi_trace input logic rvfi_frd_wvalid[1:0], input logic [ 4:0] rvfi_frd_addr [1:0], input logic [31:0] rvfi_frd_wdata [1:0], + input logic rvfi_2_rd, input logic [ 4:0] rvfi_rs1_addr, input logic [ 4:0] rvfi_rs2_addr, @@ -61,8 +66,8 @@ module cv32e40p_rvfi_trace 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_rmask, + input logic [31:0] rvfi_mem_wmask, input logic [31:0] rvfi_mem_rdata, input logic [31:0] rvfi_mem_wdata ); @@ -74,7 +79,7 @@ module cv32e40p_rvfi_trace integer f; //file pointer string fn; - integer cycles; + // integer cycles; string info_tag; logic is_compressed; @@ -125,7 +130,13 @@ module cv32e40p_rvfi_trace rs3_value = rvfi_rs3_rdata; end - if (rvfi_frd_wvalid[0]) begin + if (rvfi_2_rd) begin + if (rvfi_frd_wvalid[1]) begin + rd = {1'b1, rvfi_frd_addr[1]}; + end else begin + rd = {1'b0, rvfi_rd_addr[1]}; + end + end else if (rvfi_frd_wvalid[0]) begin rd = {1'b1, rvfi_frd_addr[0]}; end else begin rd = {1'b0, rvfi_rd_addr[0]}; @@ -134,57 +145,68 @@ module cv32e40p_rvfi_trace 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]}; - assign imm_s_type = {{20{rvfi_insn[31]}}, rvfi_insn[31:25], rvfi_insn[11:7]}; + cv32e40p_compressed_decoder #( + .FPU(FPU) + ) rvfi_trace_decompress_i ( + .instr_i(rvfi_insn), + .instr_o(decomp_insn), + .is_compressed_o(is_compressed) + ); + + assign imm_i_type = {{20{decomp_insn[31]}}, decomp_insn[31:20]}; + assign imm_iz_type = {20'b0, decomp_insn[31:20]}; + assign imm_s_type = {{20{decomp_insn[31]}}, decomp_insn[31:25], decomp_insn[11:7]}; assign imm_sb_type = { - {19{rvfi_insn[31]}}, rvfi_insn[31], rvfi_insn[7], rvfi_insn[30:25], rvfi_insn[11:8], 1'b0 + {19{decomp_insn[31]}}, + decomp_insn[31], + decomp_insn[7], + decomp_insn[30:25], + decomp_insn[11:8], + 1'b0 }; - assign imm_u_type = {rvfi_insn[31:12], 12'b0}; + assign imm_u_type = {decomp_insn[31:12], 12'b0}; assign imm_uj_type = { - {12{rvfi_insn[31]}}, rvfi_insn[19:12], rvfi_insn[20], rvfi_insn[30:21], 1'b0 + {12{decomp_insn[31]}}, decomp_insn[19:12], decomp_insn[20], decomp_insn[30:21], 1'b0 }; - assign imm_z_type = '0; //{27'b0, rvfi_insn[REG_S1_MSB:REG_S1_LSB]}; + assign imm_z_type = '0; //{27'b0, decomp_insn[REG_S1_MSB:REG_S1_LSB]}; - assign imm_s2_type = {27'b0, rvfi_insn[24:20]}; + assign imm_s2_type = {27'b0, decomp_insn[24:20]}; assign imm_vs_type = '0; assign imm_vu_type = '0; assign imm_shuffle_type = '0; assign imm_clip_type = '0; - cv32e40p_compressed_decoder #( - .FPU(FPU) - ) rvfi_trace_decompress_i ( - .instr_i(rvfi_insn), - .instr_o(decomp_insn), - .is_compressed_o(is_compressed) - ); - `include "cv32e40p_instr_trace.svh" instr_trace_t trace_retire; function instr_trace_t trace_new_instr(); instr_trace_t trace; trace = new(); - trace.init(.cycles(cycles), .pc(rvfi_pc_rdata), .compressed(is_compressed), + trace.external_time = 1; + trace.simtime = rvfi_start_time - 1ns; + trace.stoptime = rvfi_stop_time; + trace.stopcycles = rvfi_stop_cycle; + trace.init(.cycles(rvfi_start_cycle), .pc(rvfi_pc_rdata), .compressed(is_compressed), .instr(decomp_insn)); return trace; endfunction : trace_new_instr function void apply_reg_write(); foreach (trace_retire.regs_write[i]) 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 (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 + foreach (trace_retire.regs_write[i]) 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 + end endfunction : apply_reg_write function void apply_mem_access(); @@ -202,11 +224,9 @@ instr_trace_t trace_retire; end endfunction : apply_mem_access - // cycle counter - always_ff @(posedge clk_i, negedge rst_ni) begin - if (rst_ni == 1'b0) cycles <= 0; - else cycles <= cycles + 1; - end + string insn_disas; + logic [31:0] insn_pc; + logic [31:0] insn_val; always @(posedge clk_i) begin if (rvfi_valid) begin @@ -214,6 +234,9 @@ instr_trace_t trace_retire; apply_reg_write(); apply_mem_access(); trace_retire.printInstrTrace(); + insn_disas = trace_retire.str; + insn_pc = trace_retire.pc; + insn_val = trace_retire.instr; end end @@ -223,7 +246,8 @@ instr_trace_t trace_retire; $sformat(info_tag, "CORE_TRACER %2d", hart_id_i); $display("[%s] Output filename is: %s", info_tag, fn); f = $fopen(fn, "w"); - $fwrite(f, "Time\tCycle\tPC\tInstr\tDecoded instruction\tRegister and memory contents\n"); + $fwrite(f, + " Time Cycle PC Instr Decoded instruction Register and memory contents Stop cycle Stop time\n"); end diff --git a/bhv/cv32e40p_tb_wrapper.sv b/bhv/cv32e40p_tb_wrapper.sv index 1716c8c6c..f50b42686 100644 --- a/bhv/cv32e40p_tb_wrapper.sv +++ b/bhv/cv32e40p_tb_wrapper.sv @@ -455,12 +455,17 @@ module cv32e40p_tb_wrapper .rvfi_valid(rvfi_valid), .rvfi_insn(rvfi_insn), + .rvfi_start_cycle(rvfi_start_cycle), + .rvfi_start_time(rvfi_start_time), + .rvfi_stop_cycle(rvfi_stop_cycle), + .rvfi_stop_time(rvfi_stop_time), .rvfi_pc_rdata(rvfi_pc_rdata), .rvfi_rd_addr(rvfi_rd_addr), .rvfi_rd_wdata(rvfi_rd_wdata), .rvfi_frd_wvalid(rvfi_frd_wvalid), .rvfi_frd_addr(rvfi_frd_addr), .rvfi_frd_wdata(rvfi_frd_wdata), + .rvfi_2_rd(rvfi_2_rd), .rvfi_rs1_addr(rvfi_rs1_addr), .rvfi_rs2_addr(rvfi_rs2_addr), .rvfi_rs3_addr(rvfi_rs3_addr), diff --git a/bhv/cv32e40p_tracer.sv b/bhv/cv32e40p_tracer.sv index 8208f2e61..199482407 100644 --- a/bhv/cv32e40p_tracer.sv +++ b/bhv/cv32e40p_tracer.sv @@ -183,7 +183,8 @@ module cv32e40p_tracer $sformat(info_tag, "CORE_TRACER %2d", hart_id_i); $display("[%s] Output filename is: %s", info_tag, fn); f = $fopen(fn, "w"); - $fwrite(f, "Time\tCycle\tPC\tInstr\tDecoded instruction\tRegister and memory contents\n"); + $fwrite(f, + " Time Cycle PC Instr Decoded instruction Register and memory contents\n"); end //initial begin diff --git a/bhv/insn_trace.sv b/bhv/insn_trace.sv index bf73c6dc4..61048f27f 100644 --- a/bhv/insn_trace.sv +++ b/bhv/insn_trace.sv @@ -23,6 +23,10 @@ class insn_trace_t; bit m_valid; logic [63:0] m_order; + integer m_start_cycle; + integer m_stop_cycle; + time m_start_time; + time m_stop_time; bit m_skip_order; //next order was used by trap; logic [31:0] m_pc_rdata; logic [31:0] m_insn; @@ -71,9 +75,9 @@ struct { logic [31:0] addr ; - logic [ 3:0] rmask; + logic [31:0] rmask; logic [31:0] rdata; - logic [ 3:0] wmask; + logic [31:0] wmask; logic [31:0] wdata; } m_mem; @@ -162,6 +166,10 @@ function new(); this.m_order = 0; + this.m_start_cycle = 0; + this.m_stop_cycle = 0; + this.m_start_time = 0; + this.m_stop_time = 0; this.m_skip_order = 1'b0; this.m_valid = 1'b0; this.m_move_down_pipe = 1'b0; @@ -899,6 +907,10 @@ this.m_valid = 1'b1; this.m_stage = ID; this.m_order = this.m_order + 64'h1; + this.m_start_cycle = cycles; + this.m_stop_cycle = 0; + this.m_start_time = $time; + this.m_stop_time = 0; if(this.m_skip_order) begin this.m_order = this.m_order + 64'h1; end @@ -976,6 +988,10 @@ this.m_valid = m_source.m_valid; this.m_stage = m_source.m_stage; this.m_order = m_source.m_order; + this.m_start_cycle = m_source.m_start_cycle; + this.m_stop_cycle = m_source.m_stop_cycle; + this.m_start_time = m_source.m_start_time; + this.m_stop_time = m_source.m_stop_time; this.m_pc_rdata = m_source.m_pc_rdata; this.m_insn = m_source.m_insn; this.m_mnemonic = m_source.m_mnemonic;