@@ -41,6 +41,8 @@ class instr_trace_item #(
4141 logic result_fpr [$];
4242 logic [63 : 0 ] imm;
4343 logic [63 : 0 ] result;
44+ logic dest_we_valid;
45+ logic dest_is_fp;
4446 logic [CVA6Cfg.PLEN - 1 : 0 ] paddr;
4547 string priv_lvl;
4648 bp_resolve_t bp;
@@ -49,14 +51,16 @@ class instr_trace_item #(
4951
5052 // constructor creating a new instruction trace item, e.g.: a single instruction with all relevant information
5153 function new (time simtime, longint unsigned cycle, scoreboard_entry_t sbe, logic [31 : 0 ] instr, logic [63 : 0 ] gp_reg_file [32 ],
52- logic [63 : 0 ] fp_reg_file [32 ], logic [63 : 0 ] result, logic [CVA6Cfg.PLEN - 1 : 0 ] paddr, riscv :: priv_lvl_t priv_lvl, logic debug_mode, bp_resolve_t bp);
54+ logic [63 : 0 ] fp_reg_file [32 ], logic [63 : 0 ] result, logic dest_we_valid, logic dest_is_fp, logic [CVA6Cfg.PLEN - 1 : 0 ] paddr, riscv :: priv_lvl_t priv_lvl, logic debug_mode, bp_resolve_t bp);
5355 this .simtime = simtime;
5456 this .cycle = cycle;
5557 this .pc = sbe.pc;
5658 this .sbe = sbe;
5759 this .gp_reg_file = gp_reg_file;
5860 this .fp_reg_file = fp_reg_file;
5961 this .result = result;
62+ this .dest_we_valid = dest_we_valid;
63+ this .dest_is_fp = dest_is_fp;
6064 this .paddr = paddr;
6165 this .bp = bp;
6266 this .priv_lvl = (debug_mode) ? " D" : getPrivLevel (priv_lvl);
@@ -195,6 +199,68 @@ class instr_trace_item #(
195199 endcase
196200 endfunction
197201
202+ function logic scoreboardDestIsFp ();
203+ if (sbe.fu inside { ariane_pkg :: FPU , ariane_pkg :: FPU_VEC } ) begin
204+ return ariane_pkg :: fd_changes_rd_state (sbe.op);
205+ end
206+ return ariane_pkg :: is_rd_fpr (sbe.op);
207+ endfunction
208+
209+ function logic rawDestIsFp ();
210+ if (dest_we_valid) begin
211+ return dest_is_fp;
212+ end
213+ return scoreboardDestIsFp ();
214+ endfunction
215+
216+ function logic fpInstrForcesGprDest ();
217+ logic [6 : 0 ] opcode = instr[6 : 0 ];
218+ logic [4 : 0 ] funct5 = instr[31 : 27 ];
219+ logic [2 : 0 ] rm = instr[14 : 12 ];
220+
221+ if (opcode == riscv :: OpcodeOpFp) begin
222+ if (funct5 == 5'b11000 ) begin
223+ // fcvt.*.* instructions that target an integer register
224+ return 1'b1 ;
225+ end
226+
227+ if (funct5 == 5'b10100 ) begin
228+ // fle.*, flt.*, feq.* comparisons produce integer results.
229+ return 1'b1 ;
230+ end
231+
232+ if (funct5 == 5'b11100 ) begin
233+ // fmv.x.* (rm == 000) and fclass (rm == 001) always write GPRs.
234+ if ((rm == 3'b000 ) || (rm == 3'b001 )) begin
235+ return 1'b1 ;
236+ end
237+ // Alternate encodings when FP16ALT is enabled mirror rm encodings.
238+ if (CVA6Cfg.XF16ALT && ((rm == 3'b100 ) || (rm == 3'b101 ))) begin
239+ return 1'b1 ;
240+ end
241+ end
242+ end
243+
244+ return 1'b0 ;
245+ endfunction
246+
247+ function logic effectiveDestIsFp ();
248+ logic dest_is_fp_raw = rawDestIsFp ();
249+
250+ if (fpInstrForcesGprDest ()) begin
251+ return 1'b0 ;
252+ end
253+
254+ return dest_is_fp_raw;
255+ endfunction
256+
257+ function void adjustResultRegKinds ();
258+ logic final_dest_is_fp = effectiveDestIsFp ();
259+ foreach (result_fpr[i]) begin
260+ result_fpr[i] = final_dest_is_fp;
261+ end
262+ endfunction
263+
198264 function string printInstr ();
199265 string s;
200266
@@ -379,6 +445,8 @@ class instr_trace_item #(
379445 // instr,
380446 // s);
381447
448+ adjustResultRegKinds ();
449+
382450 foreach (result_regs[i]) begin
383451 if (result_fpr[i])
384452 s = $sformatf (" %s %-4s :%16x " , s, fpRegAddrToStr (result_regs[i]), this .result);
@@ -466,45 +534,48 @@ class instr_trace_item #(
466534
467535 function string printRFBCInstr (input string mnemonic, input bit use_rnd);
468536
537+ logic dest_fp = effectiveDestIsFp ();
469538 result_regs.push_back (rd);
470- result_fpr.push_back (ariane_pkg :: is_rd_fpr (sbe.op) );
539+ result_fpr.push_back (dest_fp );
471540 read_regs.push_back (rs2);
472541 read_fpr.push_back (ariane_pkg :: is_rs2_fpr (sbe.op));
473542 read_regs.push_back (sbe.result[4 : 0 ]);
474543 read_fpr.push_back (ariane_pkg :: is_imm_fpr (sbe.op));
475544
476545 if (use_rnd && instr[14 : 12 ]!= 3'b111 )
477- return $sformatf (" %-12s %4s , %s , %s , %s " , $sformatf (" %s .%s " ,mnemonic, fpFmtToStr (instr[26 : 25 ])), ariane_pkg :: is_rd_fpr (sbe.op) ? fpRegAddrToStr (rd): regAddrToStr (rd), ariane_pkg :: is_rs2_fpr (sbe.op)? fpRegAddrToStr (rs2): regAddrToStr (rs2), ariane_pkg :: is_imm_fpr (sbe.op)? fpRegAddrToStr (sbe.result[4 : 0 ]): regAddrToStr (sbe.result[4 : 0 ]), fpRmToStr (instr[14 : 12 ]));
546+ return $sformatf (" %-12s %4s , %s , %s , %s " , $sformatf (" %s .%s " ,mnemonic, fpFmtToStr (instr[26 : 25 ])), dest_fp ? fpRegAddrToStr (rd): regAddrToStr (rd), ariane_pkg :: is_rs2_fpr (sbe.op)? fpRegAddrToStr (rs2): regAddrToStr (rs2), ariane_pkg :: is_imm_fpr (sbe.op)? fpRegAddrToStr (sbe.result[4 : 0 ]): regAddrToStr (sbe.result[4 : 0 ]), fpRmToStr (instr[14 : 12 ]));
478547 else
479- return $sformatf (" %-12s %4s , %s , %s " , $sformatf (" %s .%s " ,mnemonic, fpFmtToStr (instr[26 : 25 ])), ariane_pkg :: is_rd_fpr (sbe.op) ? fpRegAddrToStr (rd): regAddrToStr (rd), ariane_pkg :: is_rs2_fpr (sbe.op)? fpRegAddrToStr (rs2): regAddrToStr (rs2), ariane_pkg :: is_imm_fpr (sbe.op)? fpRegAddrToStr (sbe.result[4 : 0 ]): regAddrToStr (sbe.result[4 : 0 ]));
548+ return $sformatf (" %-12s %4s , %s , %s " , $sformatf (" %s .%s " ,mnemonic, fpFmtToStr (instr[26 : 25 ])), dest_fp ? fpRegAddrToStr (rd): regAddrToStr (rd), ariane_pkg :: is_rs2_fpr (sbe.op)? fpRegAddrToStr (rs2): regAddrToStr (rs2), ariane_pkg :: is_imm_fpr (sbe.op)? fpRegAddrToStr (sbe.result[4 : 0 ]): regAddrToStr (sbe.result[4 : 0 ]));
480549 endfunction // printRFInstr
481550
482551 function string printRFInstr (input string mnemonic, input bit use_rnd);
483552
553+ logic dest_fp = effectiveDestIsFp ();
484554 result_regs.push_back (rd);
485- result_fpr.push_back (ariane_pkg :: is_rd_fpr (sbe.op) );
555+ result_fpr.push_back (dest_fp );
486556 read_regs.push_back (rs1);
487557 read_fpr.push_back (ariane_pkg :: is_rs1_fpr (sbe.op));
488558 read_regs.push_back (rs2);
489559 read_fpr.push_back (ariane_pkg :: is_rs2_fpr (sbe.op));
490560
491561 if (use_rnd && instr[14 : 12 ]!= 3'b111 )
492- return $sformatf (" %-12s %4s , %s , %s , %s " , $sformatf (" %s .%s " ,mnemonic, fpFmtToStr (instr[26 : 25 ])), ariane_pkg :: is_rd_fpr (sbe.op) ? fpRegAddrToStr (rd): regAddrToStr (rd), ariane_pkg :: is_rs1_fpr (sbe.op)? fpRegAddrToStr (rs1): regAddrToStr (rs1), ariane_pkg :: is_rs2_fpr (sbe.op)? fpRegAddrToStr (rs2): regAddrToStr (rs2), fpRmToStr (instr[14 : 12 ]));
562+ return $sformatf (" %-12s %4s , %s , %s , %s " , $sformatf (" %s .%s " ,mnemonic, fpFmtToStr (instr[26 : 25 ])), dest_fp ? fpRegAddrToStr (rd): regAddrToStr (rd), ariane_pkg :: is_rs1_fpr (sbe.op)? fpRegAddrToStr (rs1): regAddrToStr (rs1), ariane_pkg :: is_rs2_fpr (sbe.op)? fpRegAddrToStr (rs2): regAddrToStr (rs2), fpRmToStr (instr[14 : 12 ]));
493563 else
494- return $sformatf (" %-12s %4s , %s , %s " , $sformatf (" %s .%s " ,mnemonic, fpFmtToStr (instr[26 : 25 ])), ariane_pkg :: is_rd_fpr (sbe.op) ? fpRegAddrToStr (rd): regAddrToStr (rd), ariane_pkg :: is_rs1_fpr (sbe.op)? fpRegAddrToStr (rs1): regAddrToStr (rs1), ariane_pkg :: is_rs2_fpr (sbe.op)? fpRegAddrToStr (rs2): regAddrToStr (rs2));
564+ return $sformatf (" %-12s %4s , %s , %s " , $sformatf (" %s .%s " ,mnemonic, fpFmtToStr (instr[26 : 25 ])), dest_fp ? fpRegAddrToStr (rd): regAddrToStr (rd), ariane_pkg :: is_rs1_fpr (sbe.op)? fpRegAddrToStr (rs1): regAddrToStr (rs1), ariane_pkg :: is_rs2_fpr (sbe.op)? fpRegAddrToStr (rs2): regAddrToStr (rs2));
495565 endfunction // printRFInstr
496566
497567 function string printRFInstr1Op (input string mnemonic, input bit use_rnd);
498568
569+ logic dest_fp = effectiveDestIsFp ();
499570 result_regs.push_back (rd);
500- result_fpr.push_back (ariane_pkg :: is_rd_fpr (sbe.op) );
571+ result_fpr.push_back (dest_fp );
501572 read_regs.push_back (rs1);
502573 read_fpr.push_back (ariane_pkg :: is_rs1_fpr (sbe.op));
503574
504575 if (use_rnd && instr[14 : 12 ]!= 3'b111 )
505- return $sformatf (" %-12s %4s , %s , %s " , $sformatf (" %s .%s " ,mnemonic, fpFmtToStr (instr[26 : 25 ])), ariane_pkg :: is_rd_fpr (sbe.op) ? fpRegAddrToStr (rd): regAddrToStr (rd), ariane_pkg :: is_rs1_fpr (sbe.op)? fpRegAddrToStr (rs1): regAddrToStr (rs1), fpRmToStr (instr[14 : 12 ]));
576+ return $sformatf (" %-12s %4s , %s , %s " , $sformatf (" %s .%s " ,mnemonic, fpFmtToStr (instr[26 : 25 ])), dest_fp ? fpRegAddrToStr (rd): regAddrToStr (rd), ariane_pkg :: is_rs1_fpr (sbe.op)? fpRegAddrToStr (rs1): regAddrToStr (rs1), fpRmToStr (instr[14 : 12 ]));
506577 else
507- return $sformatf (" %-12s %4s , %s " , $sformatf (" %s .%s " ,mnemonic, fpFmtToStr (instr[26 : 25 ])), ariane_pkg :: is_rd_fpr (sbe.op) ? fpRegAddrToStr (rd): regAddrToStr (rd), ariane_pkg :: is_rs1_fpr (sbe.op)? fpRegAddrToStr (rs1): regAddrToStr (rs1));
578+ return $sformatf (" %-12s %4s , %s " , $sformatf (" %s .%s " ,mnemonic, fpFmtToStr (instr[26 : 25 ])), dest_fp ? fpRegAddrToStr (rd): regAddrToStr (rd), ariane_pkg :: is_rs1_fpr (sbe.op)? fpRegAddrToStr (rs1): regAddrToStr (rs1));
508579 endfunction // printRFInstr1Op
509580
510581 function string printR4Instr (input string mnemonic);
@@ -523,8 +594,9 @@ class instr_trace_item #(
523594
524595 function string printFpSpecialInstr ();
525596
597+ logic dest_fp = effectiveDestIsFp ();
526598 result_regs.push_back (rd);
527- result_fpr.push_back (ariane_pkg :: is_rd_fpr (sbe.op) );
599+ result_fpr.push_back (dest_fp );
528600 read_regs.push_back (rs1);
529601 read_fpr.push_back (ariane_pkg :: is_rs1_fpr (sbe.op));
530602
@@ -634,8 +706,9 @@ class instr_trace_item #(
634706 endfunction // printCSRInstr
635707
636708 function string printLoadInstr (input string mnemonic);
709+ logic dest_fp = effectiveDestIsFp ();
637710 result_regs.push_back (rd);
638- result_fpr.push_back (ariane_pkg :: is_rd_fpr (sbe.op) );
711+ result_fpr.push_back (dest_fp );
639712 read_regs.push_back (rs1);
640713 read_fpr.push_back (1'b0 );
641714 // save the immediate for calculating the virtual address
0 commit comments