1+ import random
12from toffee import *
2-
3+ FTQSIZE = 64
34
45class FtqAgent (Agent ):
56 def __init__ (self , ftq_bundle ):
@@ -542,4 +543,226 @@ async def get_fromBpu_resp_ready(self):
542543
543544 return self .bundle .fromBpu .resp_ready .value
544545
545-
546+ @driver_method ()
547+ async def drive_s1_full_signals (self , dict ):
548+ self .bundle .fromBpuNew .valid .value = dict ['valid' ]
549+ self .bundle .fromBpuNew .s1 .pc_3 .value = dict ['pc_3' ]
550+ self .bundle .fromBpuNew .s1 .full_pred_3_fallThroughErr .value = dict ['full_pred_3_fallThroughErr' ]
551+ self .bundle .fromBpuNew .s1 .full_pred_3_br_taken_mask_0 .value = dict ['full_pred_3_br_taken_mask_0' ]
552+ self .bundle .fromBpuNew .s1 .full_pred_3_br_taken_mask_1 .value = dict ['full_pred_3_br_taken_mask_1' ]
553+ self .bundle .fromBpuNew .s1 .full_pred_3_slot_valids_0 .value = dict ['full_pred_3_slot_valids_0' ]
554+ self .bundle .fromBpuNew .s1 .full_pred_3_slot_valids_1 .value = dict ['full_pred_3_slot_valids_1' ]
555+ self .bundle .fromBpuNew .s1 .full_pred_3_targets_0 .value = dict ['full_pred_3_targets_0' ]
556+ self .bundle .fromBpuNew .s1 .full_pred_3_targets_1 .value = dict ['full_pred_3_targets_1' ]
557+ self .bundle .fromBpuNew .s1 .full_pred_3_offsets_0 .value = dict ['full_pred_3_offsets_0' ]
558+ self .bundle .fromBpuNew .s1 .full_pred_3_offsets_1 .value = dict ['full_pred_3_offsets_1' ]
559+ self .bundle .fromBpuNew .s1 .full_pred_3_fallThroughAddr .value = dict ['full_pred_3_fallThroughAddr' ]
560+ self .bundle .fromBpuNew .s1 .full_pred_3_is_br_sharing .value = dict ['full_pred_3_is_br_sharing' ]
561+ self .bundle .fromBpuNew .s1 .full_pred_3_hit .value = dict ['full_pred_3_hit' ]
562+ return self .bundle .as_dict ()
563+
564+ @driver_method ()
565+ async def drive_s2_full_signals (self , dict ):
566+ self .bundle .fromBpuNew .s2 .pc_3 .value = dict ['pc_3' ]
567+ self .bundle .fromBpuNew .s2 .full_pred_3_fallThroughErr .value = dict ['full_pred_3_fallThroughErr' ]
568+ self .bundle .fromBpuNew .s2 .full_pred_3_br_taken_mask_0 .value = dict ['full_pred_3_br_taken_mask_0' ]
569+ self .bundle .fromBpuNew .s2 .full_pred_3_br_taken_mask_1 .value = dict ['full_pred_3_br_taken_mask_1' ]
570+ self .bundle .fromBpuNew .s2 .full_pred_3_slot_valids_0 .value = dict ['full_pred_3_slot_valids_0' ]
571+ self .bundle .fromBpuNew .s2 .full_pred_3_slot_valids_1 .value = dict ['full_pred_3_slot_valids_1' ]
572+ self .bundle .fromBpuNew .s2 .full_pred_3_targets_0 .value = dict ['full_pred_3_targets_0' ]
573+ self .bundle .fromBpuNew .s2 .full_pred_3_targets_1 .value = dict ['full_pred_3_targets_1' ]
574+ self .bundle .fromBpuNew .s2 .full_pred_3_offsets_0 .value = dict ['full_pred_3_offsets_0' ]
575+ self .bundle .fromBpuNew .s2 .full_pred_3_offsets_1 .value = dict ['full_pred_3_offsets_1' ]
576+ self .bundle .fromBpuNew .s2 .full_pred_3_fallThroughAddr .value = dict ['full_pred_3_fallThroughAddr' ]
577+ self .bundle .fromBpuNew .s2 .full_pred_3_is_br_sharing .value = dict ['full_pred_3_is_br_sharing' ]
578+ self .bundle .fromBpuNew .s2 .full_pred_3_hit .value = dict ['full_pred_3_hit' ]
579+ self .bundle .fromBpuNew .s2 .valid_3 .value = dict ['valid_3' ]
580+ self .bundle .fromBpuNew .s2 .hasRedirect_3 .value = dict ['hasRedirect_3' ]
581+ self .bundle .fromBpuNew .s2 .ftq_idx_flag .value = dict ['ftq_idx_flag' ]
582+ self .bundle .fromBpuNew .s2 .ftq_idx_value .value = dict ['ftq_idx_value' ]
583+ return self .bundle .as_dict ()
584+
585+ @driver_method ()
586+ async def drive_s3_full_signals (self , dict ):
587+ self .bundle .fromBpuNew .s3 .pc_3 .value = dict ['pc_3' ]
588+ self .bundle .fromBpuNew .s3 .full_pred_3_fallThroughErr .value = dict ['full_pred_3_fallThroughErr' ]
589+ self .bundle .fromBpuNew .s3 .full_pred_3_br_taken_mask_0 .value = dict ['full_pred_3_br_taken_mask_0' ]
590+ self .bundle .fromBpuNew .s3 .full_pred_3_br_taken_mask_1 .value = dict ['full_pred_3_br_taken_mask_1' ]
591+ self .bundle .fromBpuNew .s3 .full_pred_3_slot_valids_0 .value = dict ['full_pred_3_slot_valids_0' ]
592+ self .bundle .fromBpuNew .s3 .full_pred_3_slot_valids_1 .value = dict ['full_pred_3_slot_valids_1' ]
593+ self .bundle .fromBpuNew .s3 .full_pred_3_targets_0 .value = dict ['full_pred_3_targets_0' ]
594+ self .bundle .fromBpuNew .s3 .full_pred_3_targets_1 .value = dict ['full_pred_3_targets_1' ]
595+ self .bundle .fromBpuNew .s3 .full_pred_3_offsets_0 .value = dict ['full_pred_3_offsets_0' ]
596+ self .bundle .fromBpuNew .s3 .full_pred_3_offsets_1 .value = dict ['full_pred_3_offsets_1' ]
597+ self .bundle .fromBpuNew .s3 .full_pred_3_fallThroughAddr .value = dict ['full_pred_3_fallThroughAddr' ]
598+ self .bundle .fromBpuNew .s3 .full_pred_3_is_br_sharing .value = dict ['full_pred_3_is_br_sharing' ]
599+ self .bundle .fromBpuNew .s3 .full_pred_3_hit .value = dict ['full_pred_3_hit' ]
600+ self .bundle .fromBpuNew .s3 .valid_3 .value = dict ['valid_3' ]
601+ self .bundle .fromBpuNew .s3 .hasRedirect_3 .value = dict ['hasRedirect_3' ]
602+ self .bundle .fromBpuNew .s3 .ftq_idx_flag .value = dict ['ftq_idx_flag' ]
603+ self .bundle .fromBpuNew .s3 .ftq_idx_value .value = dict ['ftq_idx_value' ]
604+ return self .bundle .as_dict ()
605+
606+ @driver_method ()
607+ async def drive_last_stage_ftb_entry_signals (self , dict ):
608+ self .bundle .fromBpuNew .last_stage_ftb_entry .valid .value = dict ['valid' ]
609+ self .bundle .fromBpuNew .last_stage_ftb_entry .isJalr .value = dict ['isJalr' ]
610+ self .bundle .fromBpuNew .last_stage_ftb_entry .isCall .value = dict ['isCall' ]
611+ self .bundle .fromBpuNew .last_stage_ftb_entry .isRet .value = dict ['isRet' ]
612+ self .bundle .fromBpuNew .last_stage_ftb_entry .last_may_be_rvi_call .value = dict ['last_may_be_rvi_call' ]
613+ self .bundle .fromBpuNew .last_stage_ftb_entry .carry .value = dict ['carry' ]
614+ self .bundle .fromBpuNew .last_stage_ftb_entry .pftAddr .value = dict ['pftAddr' ]
615+ self .bundle .fromBpuNew .last_stage_ftb_entry .brSlots_0_valid .value = dict ['brSlots_0_valid' ]
616+ self .bundle .fromBpuNew .last_stage_ftb_entry .brSlots_0_sharing .value = dict ['brSlots_0_sharing' ]
617+ self .bundle .fromBpuNew .last_stage_ftb_entry .brSlots_0_offset .value = dict ['brSlots_0_offset' ]
618+ self .bundle .fromBpuNew .last_stage_ftb_entry .tailSlot_valid .value = dict ['tailSlot_valid' ]
619+ self .bundle .fromBpuNew .last_stage_ftb_entry .tailSlot_offset .value = dict ['tailSlot_offset' ]
620+ self .bundle .fromBpuNew .last_stage_ftb_entry .tailSlot_sharing .value = dict ['tailSlot_sharing' ]
621+
622+ return self .bundle .as_dict ()
623+
624+ @driver_method ()
625+ async def drive_last_stage_spec_info_signals (self , dict ):
626+ self .bundle .fromBpuNew .last_stage_spec_info .histPtr_flag .value = dict ['histPtr_flag' ]
627+ self .bundle .fromBpuNew .last_stage_spec_info .histPtr_value .value = dict ['histPtr_value' ]
628+ self .bundle .fromBpuNew .last_stage_spec_info .ssp .value = dict ['ssp' ]
629+ self .bundle .fromBpuNew .last_stage_spec_info .sctr .value = dict ['sctr' ]
630+ self .bundle .fromBpuNew .last_stage_spec_info .TOSW_flag .value = dict ['TOSW_flag' ]
631+ self .bundle .fromBpuNew .last_stage_spec_info .TOSW_value .value = dict ['TOSW_value' ]
632+ self .bundle .fromBpuNew .last_stage_spec_info .TOSR_flag .value = dict ['TOSR_flag' ]
633+ self .bundle .fromBpuNew .last_stage_spec_info .TOSR_value .value = dict ['TOSR_value' ]
634+ self .bundle .fromBpuNew .last_stage_spec_info .NOS_flag .value = dict ['NOS_flag' ]
635+ self .bundle .fromBpuNew .last_stage_spec_info .NOS_value .value = dict ['NOS_value' ]
636+ self .bundle .fromBpuNew .last_stage_spec_info .topAddr .value = dict ['topAddr' ]
637+ self .bundle .fromBpuNew .last_stage_spec_info .sc_disagree_0 .value = dict ['sc_disagree_0' ]
638+ self .bundle .fromBpuNew .last_stage_spec_info .sc_disagree_1 .value = dict ['sc_disagree_1' ]
639+ return self .bundle .as_dict ()
640+
641+ @driver_method ()
642+ async def drive_last_stage_meta_signals (self ):
643+ self .bundle .fromBpuNew .last_stage_meta .last_stage_meta .value = random .randint (0 , (1 << 516 ) - 1 )
644+
645+ @driver_method ()
646+ async def drive_backend_inputs_full (self , dict ):
647+ b = self .bundle .fromBackend
648+ # simple direct mappings where fields are known to exist in FtqBundle.fromBackend
649+ if 'io_fromBackend_redirect_valid' in dict :
650+ b .redirect_valid .value = dict ['io_fromBackend_redirect_valid' ]
651+ if 'io_fromBackend_redirect_bits_ftqIdx_flag' in dict :
652+ b .redirect_bits_ftqIdx_flag .value = dict ['io_fromBackend_redirect_bits_ftqIdx_flag' ]
653+ if 'io_fromBackend_redirect_bits_ftqIdx_value' in dict :
654+ b .redirect_bits_ftqIdx_value .value = dict ['io_fromBackend_redirect_bits_ftqIdx_value' ]
655+ if 'io_fromBackend_redirect_bits_ftqOffset' in dict :
656+ b .redirect_bits_ftqOffset .value = dict ['io_fromBackend_redirect_bits_ftqOffset' ]
657+ if 'io_fromBackend_redirect_bits_level' in dict :
658+ b .redirect_bits_level .value = dict ['io_fromBackend_redirect_bits_level' ]
659+ # cfi update fields (map to known names if present)
660+ if 'io_fromBackend_redirect_bits_cfiUpdate_target' in dict :
661+ b .redirect_bits_cfiUpdate_target .value = dict ['io_fromBackend_redirect_bits_cfiUpdate_target' ]
662+ if 'io_fromBackend_redirect_bits_cfiUpdate_taken' in dict :
663+ b .redirect_bits_cfiUpdate_taken .value = dict ['io_fromBackend_redirect_bits_cfiUpdate_taken' ]
664+ if 'io_fromBackend_redirect_bits_cfiUpdate_isMisPred' in dict :
665+ b .redirect_bits_cfiUpdate_isMisPred .value = dict ['io_fromBackend_redirect_bits_cfiUpdate_isMisPred' ]
666+ # debug fields
667+ if 'io_fromBackend_redirect_bits_debugIsCtrl' in dict :
668+ b .redirect_bits_debugIsCtrl .value = dict ['io_fromBackend_redirect_bits_debugIsCtrl' ]
669+ if 'io_fromBackend_redirect_bits_debugIsMemVio' in dict :
670+ b .redirect_bits_debugIsMemVio .value = dict ['io_fromBackend_redirect_bits_debugIsMemVio' ]
671+ # ftq ahead / selector
672+ if 'io_fromBackend_ftqIdxAhead_0_valid' in dict :
673+ b .ftqIdxAhead_0_valid .value = dict ['io_fromBackend_ftqIdxAhead_0_valid' ]
674+ if 'io_fromBackend_ftqIdxAhead_0_bits_value' in dict :
675+ b .ftqIdxAhead_0_bits_value .value = dict ['io_fromBackend_ftqIdxAhead_0_bits_value' ]
676+ if 'io_fromBackend_ftqIdxSelOH_bits' in dict :
677+ b .ftqIdxSelOH_bits .value = dict ['io_fromBackend_ftqIdxSelOH_bits' ]
678+
679+ # For any extra cfi fields that may exist on the bundle, set them if present
680+ # e.g., cfiUpdate_pc, backendIGPF/IPF/IAF — only set if those attributes exist.
681+ try :
682+ if 'io_fromBackend_redirect_bits_cfiUpdate_pc' in dict and hasattr (b , 'redirect_bits_cfiUpdate_pc' ):
683+ b .redirect_bits_cfiUpdate_pc .value = dict ['io_fromBackend_redirect_bits_cfiUpdate_pc' ]
684+ except Exception :
685+ pass
686+ for extra in ('io_fromBackend_redirect_bits_cfiUpdate_backendIGPF' ,
687+ 'io_fromBackend_redirect_bits_cfiUpdate_backendIPF' ,
688+ 'io_fromBackend_redirect_bits_cfiUpdate_backendIAF' ):
689+ if extra in dict :
690+ # try common attribute name pattern on bundle; ignore if not present
691+ attr = extra .replace ('io_fromBackend_redirect_bits_' , 'redirect_bits_' )
692+ if hasattr (b , attr ):
693+ getattr (b , attr ).value = dict [extra ]
694+
695+ # rob_commits: handle 0..7 RobCommitBundle entries if present in bundle and dict
696+ for i in range (8 ):
697+ rb_name = f'rob_commits_{ i } '
698+ key_base = f'io_fromBackend_rob_commits_{ i } _'
699+ if not hasattr (b , rb_name ):
700+ continue
701+ rb = getattr (b , rb_name )
702+ if key_base + 'valid' in dict and hasattr (rb , 'valid' ):
703+ rb .valid .value = dict [key_base + 'valid' ]
704+ if key_base + 'bits_commitType' in dict and hasattr (rb , 'bits_commitType' ):
705+ rb .bits_commitType .value = dict [key_base + 'bits_commitType' ]
706+ if key_base + 'bits_ftqIdx_flag' in dict and hasattr (rb , 'bits_ftqIdx_flag' ):
707+ rb .bits_ftqIdx_flag .value = dict [key_base + 'bits_ftqIdx_flag' ]
708+ if key_base + 'bits_ftqIdx_value' in dict and hasattr (rb , 'bits_ftqIdx_value' ):
709+ rb .bits_ftqIdx_value .value = dict [key_base + 'bits_ftqIdx_value' ]
710+ if key_base + 'bits_ftqOffset' in dict and hasattr (rb , 'bits_ftqOffset' ):
711+ rb .bits_ftqOffset .value = dict [key_base + 'bits_ftqOffset' ]
712+
713+ return self .bundle .as_dict ()
714+
715+ @driver_method ()
716+ async def drive_ifu_inputs_full (self , dict ):
717+ f = self .bundle .fromIfu
718+ # top-level valid / ftqIdx fields
719+ if 'io_fromIfu_pdWb_valid' in dict :
720+ f .pdWb_valid .value = dict ['io_fromIfu_pdWb_valid' ]
721+ if 'io_fromIfu_pdWb_bits_ftqIdx_flag' in dict :
722+ f .pdWb_bits_ftqIdx_flag .value = dict ['io_fromIfu_pdWb_bits_ftqIdx_flag' ]
723+ if 'io_fromIfu_pdWb_bits_ftqIdx_value' in dict :
724+ f .pdWb_bits_ftqIdx_value .value = dict ['io_fromIfu_pdWb_bits_ftqIdx_value' ]
725+
726+ # pc entries
727+ for i in range (16 ):
728+ key = f"io_fromIfu_pdWb_bits_pc_{ i } "
729+ attr = f"pdWb_bits_pc_{ i } "
730+ if key in dict and hasattr (f , attr ):
731+ getattr (f , attr ).value = dict [key ]
732+
733+ # per-slot pd fields (brType, isCall, isRet, valid, isRVC) if present
734+ for i in range (16 ):
735+ base = f"pdWb_bits_pd_{ i } "
736+ if hasattr (f , base ):
737+ pd_obj = getattr (f , base )
738+ if f"io_fromIfu_pdWb_bits_pd_{ i } _valid" in dict and hasattr (pd_obj , "valid" ):
739+ pd_obj .valid .value = dict [f"io_fromIfu_pdWb_bits_pd_{ i } _valid" ]
740+ if f"io_fromIfu_pdWb_bits_pd_{ i } _isRVC" in dict and hasattr (pd_obj , "isRVC" ):
741+ pd_obj .isRVC .value = dict [f"io_fromIfu_pdWb_bits_pd_{ i } _isRVC" ]
742+ if f"io_fromIfu_pdWb_bits_pd_{ i } _brType" in dict and hasattr (pd_obj , "brType" ):
743+ pd_obj .brType .value = dict [f"io_fromIfu_pdWb_bits_pd_{ i } _brType" ]
744+ if f"io_fromIfu_pdWb_bits_pd_{ i } _isCall" in dict and hasattr (pd_obj , "isCall" ):
745+ pd_obj .isCall .value = dict [f"io_fromIfu_pdWb_bits_pd_{ i } _isCall" ]
746+ if f"io_fromIfu_pdWb_bits_pd_{ i } _isRet" in dict and hasattr (pd_obj , "isRet" ):
747+ pd_obj .isRet .value = dict [f"io_fromIfu_pdWb_bits_pd_{ i } _isRet" ]
748+
749+ # misOffset / cfiOffset / target / jalTarget / instrRange
750+ if 'io_fromIfu_pdWb_bits_misOffset_valid' in dict :
751+ f .pdWb_bits_misOffset_valid .value = dict ['io_fromIfu_pdWb_bits_misOffset_valid' ]
752+ if 'io_fromIfu_pdWb_bits_misOffset_bits' in dict :
753+ f .pdWb_bits_misOffset_bits .value = dict ['io_fromIfu_pdWb_bits_misOffset_bits' ]
754+ if 'io_fromIfu_pdWb_bits_cfiOffset_valid' in dict :
755+ f .pdWb_bits_cfiOffset_valid .value = dict ['io_fromIfu_pdWb_bits_cfiOffset_valid' ]
756+ if 'io_fromIfu_pdWb_bits_target' in dict and hasattr (f , 'pdWb_bits_target' ):
757+ f .pdWb_bits_target .value = dict ['io_fromIfu_pdWb_bits_target' ]
758+ if 'io_fromIfu_pdWb_bits_jalTarget' in dict and hasattr (f , 'pdWb_bits_jalTarget' ):
759+ f .pdWb_bits_jalTarget .value = dict ['io_fromIfu_pdWb_bits_jalTarget' ]
760+
761+ # instrRange entries if they exist on bundle
762+ for i in range (16 ):
763+ key = f"io_fromIfu_pdWb_bits_instrRange_{ i } "
764+ attr = f"pdWb_bits_instrRange_{ i } "
765+ if key in dict and hasattr (f , attr ):
766+ getattr (f , attr ).value = dict [key ]
767+
768+ return self .bundle .as_dict ()
0 commit comments