@@ -65,7 +65,8 @@ module ibex_tracer (
6565 input logic [ 3 : 0 ] rvfi_mem_rmask,
6666 input logic [ 3 : 0 ] rvfi_mem_wmask,
6767 input logic [31 : 0 ] rvfi_mem_rdata,
68- input logic [31 : 0 ] rvfi_mem_wdata
68+ input logic [31 : 0 ] rvfi_mem_wdata,
69+ input logic [15 : 0 ] rvfi_ext_expanded_insn
6970);
7071
7172 // These signals are part of RVFI, but not used in this module currently.
@@ -143,6 +144,9 @@ module ibex_tracer (
143144 $fwrite (fh, " load:0x%08x " , rvfi_mem_rdata);
144145 end
145146 end
147+ if (rvfi_ext_expanded_insn != 16'b0 ) begin
148+ $fwrite (fh, " expand_insn: (0x%04x %s )" , rvfi_ext_expanded_insn, decode_expanded_insn ());
149+ end
146150
147151 $fwrite (fh, " \n " );
148152 endfunction
@@ -157,6 +161,32 @@ module ibex_tracer (
157161 end
158162 endfunction
159163
164+ // Format register address with "x" prefix, left-aligned to a fixed width of 3 characters.
165+ function automatic string reg_addr_to_abi_str (input logic [4 : 0 ] addr);
166+ case (addr)
167+ // Hard-wired Zero Register
168+ 5'd0 : return " zero" ;
169+ // Return Address and Pointers
170+ 5'd1 : return " ra" ; // Return Address
171+ 5'd2 : return " sp" ; // Stack Pointer
172+ 5'd3 : return " gp" ; // Global Pointer
173+ 5'd4 : return " tp" ; // Thread Pointer
174+ // Temporary Registers
175+ 5'd5 , 5'd6 , 5'd7 : return $sformatf (" t%0d " , addr - 5 );
176+ // Saved Registers
177+ 5'd8 , 5'd9 : return $sformatf (" s%0d " , addr - 8 );
178+ // Function Arguments / Return Values
179+ 5'd10 , 5'd11 , 5'd12 , 5'd13 ,
180+ 5'd14 , 5'd15 , 5'd16 , 5'd17 : return $sformatf (" a%0d " , addr - 10 );
181+ // Saved Registers
182+ 5'd18 , 5'd19 , 5'd20 , 5'd21 , 5'd22 ,
183+ 5'd23 , 5'd24 , 5'd25 , 5'd26 , 5'd27 : return $sformatf (" s%0d " , addr - 16 );
184+ // Temporary Registers
185+ 5'd28 , 5'd29 , 5'd30 , 5'd31 : return $sformatf (" t%0d " , addr - 25 );
186+ default : return $sformatf (" x%0d " , addr);
187+ endcase
188+ endfunction
189+
160190 // Get a CSR name for a CSR address.
161191 function automatic string get_csr_name (input logic [11 : 0 ] csr_addr);
162192 unique case (csr_addr)
@@ -664,6 +694,55 @@ module ibex_tracer (
664694 decoded_str = $sformatf (" %s \t x%0d ,%0d (x%0d )" , mnemonic, rvfi_rd_addr, imm, rvfi_rs1_addr);
665695 endfunction
666696
697+ function automatic string cm_reg_to_str (input logic [2 : 0 ] addr);
698+ logic [4 : 0 ] xreg = { addr[2 : 1 ] > 0 , addr[2 : 1 ]== 0 , addr[2 : 0 ]} ;
699+ return reg_addr_to_abi_str (xreg);
700+ endfunction
701+
702+ function automatic string decode_Zcmp_cmmv_insn (input string mnemonic);
703+ return $sformatf (" %s \t %0s ,%0s " , mnemonic, cm_reg_to_str (rvfi_ext_expanded_insn[9 : 7 ]),
704+ cm_reg_to_str (rvfi_ext_expanded_insn[4 : 2 ]));
705+ endfunction
706+
707+ function automatic string decode_Zcmp_cmpp_insn (input string mnemonic);
708+ logic [3 : 0 ] rlist;
709+ logic [1 : 0 ] spimm;
710+ string rlist_str;
711+ int base;
712+ int spimm_val;
713+ rlist = rvfi_ext_expanded_insn[7 : 4 ];
714+ spimm = rvfi_ext_expanded_insn[3 : 2 ];
715+ // Decode rlist to string
716+ if (rlist < 4 ) begin
717+ rlist_str = $sformatf (" {INVALID (%0d )}" , rlist);
718+ end else begin
719+ case (rlist)
720+ 4 : rlist_str = " {ra}" ;
721+ 5 : rlist_str = " {ra, s0}" ;
722+ 15 : rlist_str = " {ra, s0-s11}" ; // The special case for s10/s11
723+ // The default case handles the general pattern for rlist 6 through 14
724+ default : rlist_str = $sformatf (" {ra, s0-s%0d }" , rlist - 5 );
725+ endcase
726+ end
727+ // Decode spimm
728+ base = (rlist == 15 ) ? 64 : (32 '(rlist) >> 2 ) * 16 ;
729+ spimm_val = base + (spimm * 16 );
730+ spimm_val = mnemonic == " cm.push" ? - spimm_val : spimm_val;
731+ return $sformatf (" %s \t %s ,%0d " , mnemonic, rlist_str, spimm_val);
732+ endfunction
733+
734+ function automatic string decode_expanded_insn ();
735+ unique casez (rvfi_ext_expanded_insn)
736+ INSN_CMPUSH : return decode_Zcmp_cmpp_insn (" cm.push" );
737+ INSN_CMPOP : return decode_Zcmp_cmpp_insn (" cm.pop" );
738+ INSN_CMPOPRETZ : return decode_Zcmp_cmpp_insn (" cm.popretz" );
739+ INSN_CMPOPRET : return decode_Zcmp_cmpp_insn (" cm.popret" );
740+ INSN_CMMVSA01 : return decode_Zcmp_cmmv_insn (" cm.mvsa01" );
741+ INSN_CMMVA01S : return decode_Zcmp_cmmv_insn (" cm.mva01s" );
742+ default : return " Decoding error" ;
743+ endcase
744+ endfunction
745+
667746 function automatic void decode_load_insn ();
668747 string mnemonic;
669748
@@ -879,6 +958,9 @@ module ibex_tracer (
879958 INSN_CSLLI : decode_ci_cslli_insn (" c.slli" );
880959 INSN_CLWSP : decode_compressed_load_insn (" c.lwsp" );
881960 INSN_SWSP : decode_compressed_store_insn (" c.swsp" );
961+ // Zc extension C2: We should never see those on the rvfi_insn interface since they must
962+ // get expanded into other instructions. They will be annotated through the
963+ // `decode_expanded_insn` function instead and the `rvfi_ext_expanded_insn` signal.
882964 default : decode_mnemonic (" INVALID" );
883965 endcase
884966 end
0 commit comments