Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
227 changes: 225 additions & 2 deletions ut_frontend/ftq/ftq_top/env/ftq_agent.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import random
from toffee import *

FTQSIZE = 64

class FtqAgent(Agent):
def __init__(self, ftq_bundle):
Expand Down Expand Up @@ -542,4 +543,226 @@ async def get_fromBpu_resp_ready(self):

return self.bundle.fromBpu.resp_ready.value


@driver_method()
async def drive_s1_full_signals(self, dict):
self.bundle.fromBpuNew.valid.value = dict['valid']
self.bundle.fromBpuNew.s1.pc_3.value = dict['pc_3']
self.bundle.fromBpuNew.s1.full_pred_3_fallThroughErr.value = dict['full_pred_3_fallThroughErr']
self.bundle.fromBpuNew.s1.full_pred_3_br_taken_mask_0.value = dict['full_pred_3_br_taken_mask_0']
self.bundle.fromBpuNew.s1.full_pred_3_br_taken_mask_1.value = dict['full_pred_3_br_taken_mask_1']
self.bundle.fromBpuNew.s1.full_pred_3_slot_valids_0.value = dict['full_pred_3_slot_valids_0']
self.bundle.fromBpuNew.s1.full_pred_3_slot_valids_1.value = dict['full_pred_3_slot_valids_1']
self.bundle.fromBpuNew.s1.full_pred_3_targets_0.value = dict['full_pred_3_targets_0']
self.bundle.fromBpuNew.s1.full_pred_3_targets_1.value = dict['full_pred_3_targets_1']
self.bundle.fromBpuNew.s1.full_pred_3_offsets_0.value = dict['full_pred_3_offsets_0']
self.bundle.fromBpuNew.s1.full_pred_3_offsets_1.value = dict['full_pred_3_offsets_1']
self.bundle.fromBpuNew.s1.full_pred_3_fallThroughAddr.value = dict['full_pred_3_fallThroughAddr']
self.bundle.fromBpuNew.s1.full_pred_3_is_br_sharing.value = dict['full_pred_3_is_br_sharing']
self.bundle.fromBpuNew.s1.full_pred_3_hit.value = dict['full_pred_3_hit']
return self.bundle.as_dict()

@driver_method()
async def drive_s2_full_signals(self, dict):
self.bundle.fromBpuNew.s2.pc_3.value = dict['pc_3']
self.bundle.fromBpuNew.s2.full_pred_3_fallThroughErr.value = dict['full_pred_3_fallThroughErr']
self.bundle.fromBpuNew.s2.full_pred_3_br_taken_mask_0.value = dict['full_pred_3_br_taken_mask_0']
self.bundle.fromBpuNew.s2.full_pred_3_br_taken_mask_1.value = dict['full_pred_3_br_taken_mask_1']
self.bundle.fromBpuNew.s2.full_pred_3_slot_valids_0.value = dict['full_pred_3_slot_valids_0']
self.bundle.fromBpuNew.s2.full_pred_3_slot_valids_1.value = dict['full_pred_3_slot_valids_1']
self.bundle.fromBpuNew.s2.full_pred_3_targets_0.value = dict['full_pred_3_targets_0']
self.bundle.fromBpuNew.s2.full_pred_3_targets_1.value = dict['full_pred_3_targets_1']
self.bundle.fromBpuNew.s2.full_pred_3_offsets_0.value = dict['full_pred_3_offsets_0']
self.bundle.fromBpuNew.s2.full_pred_3_offsets_1.value = dict['full_pred_3_offsets_1']
self.bundle.fromBpuNew.s2.full_pred_3_fallThroughAddr.value = dict['full_pred_3_fallThroughAddr']
self.bundle.fromBpuNew.s2.full_pred_3_is_br_sharing.value = dict['full_pred_3_is_br_sharing']
self.bundle.fromBpuNew.s2.full_pred_3_hit.value = dict['full_pred_3_hit']
self.bundle.fromBpuNew.s2.valid_3.value = dict['valid_3']
self.bundle.fromBpuNew.s2.hasRedirect_3.value = dict['hasRedirect_3']
self.bundle.fromBpuNew.s2.ftq_idx_flag.value = dict['ftq_idx_flag']
self.bundle.fromBpuNew.s2.ftq_idx_value.value = dict['ftq_idx_value']
return self.bundle.as_dict()

@driver_method()
async def drive_s3_full_signals(self, dict):
self.bundle.fromBpuNew.s3.pc_3.value = dict['pc_3']
self.bundle.fromBpuNew.s3.full_pred_3_fallThroughErr.value = dict['full_pred_3_fallThroughErr']
self.bundle.fromBpuNew.s3.full_pred_3_br_taken_mask_0.value = dict['full_pred_3_br_taken_mask_0']
self.bundle.fromBpuNew.s3.full_pred_3_br_taken_mask_1.value = dict['full_pred_3_br_taken_mask_1']
self.bundle.fromBpuNew.s3.full_pred_3_slot_valids_0.value = dict['full_pred_3_slot_valids_0']
self.bundle.fromBpuNew.s3.full_pred_3_slot_valids_1.value = dict['full_pred_3_slot_valids_1']
self.bundle.fromBpuNew.s3.full_pred_3_targets_0.value = dict['full_pred_3_targets_0']
self.bundle.fromBpuNew.s3.full_pred_3_targets_1.value = dict['full_pred_3_targets_1']
self.bundle.fromBpuNew.s3.full_pred_3_offsets_0.value = dict['full_pred_3_offsets_0']
self.bundle.fromBpuNew.s3.full_pred_3_offsets_1.value = dict['full_pred_3_offsets_1']
self.bundle.fromBpuNew.s3.full_pred_3_fallThroughAddr.value = dict['full_pred_3_fallThroughAddr']
self.bundle.fromBpuNew.s3.full_pred_3_is_br_sharing.value = dict['full_pred_3_is_br_sharing']
self.bundle.fromBpuNew.s3.full_pred_3_hit.value = dict['full_pred_3_hit']
self.bundle.fromBpuNew.s3.valid_3.value = dict['valid_3']
self.bundle.fromBpuNew.s3.hasRedirect_3.value = dict['hasRedirect_3']
self.bundle.fromBpuNew.s3.ftq_idx_flag.value = dict['ftq_idx_flag']
self.bundle.fromBpuNew.s3.ftq_idx_value.value = dict['ftq_idx_value']
return self.bundle.as_dict()

@driver_method()
async def drive_last_stage_ftb_entry_signals(self, dict):
self.bundle.fromBpuNew.last_stage_ftb_entry.valid.value = dict['valid']
self.bundle.fromBpuNew.last_stage_ftb_entry.isJalr.value = dict['isJalr']
self.bundle.fromBpuNew.last_stage_ftb_entry.isCall.value = dict['isCall']
self.bundle.fromBpuNew.last_stage_ftb_entry.isRet.value = dict['isRet']
self.bundle.fromBpuNew.last_stage_ftb_entry.last_may_be_rvi_call.value = dict['last_may_be_rvi_call']
self.bundle.fromBpuNew.last_stage_ftb_entry.carry.value = dict['carry']
self.bundle.fromBpuNew.last_stage_ftb_entry.pftAddr.value = dict['pftAddr']
self.bundle.fromBpuNew.last_stage_ftb_entry.brSlots_0_valid.value = dict['brSlots_0_valid']
self.bundle.fromBpuNew.last_stage_ftb_entry.brSlots_0_sharing.value = dict['brSlots_0_sharing']
self.bundle.fromBpuNew.last_stage_ftb_entry.brSlots_0_offset.value = dict['brSlots_0_offset']
self.bundle.fromBpuNew.last_stage_ftb_entry.tailSlot_valid.value = dict['tailSlot_valid']
self.bundle.fromBpuNew.last_stage_ftb_entry.tailSlot_offset.value = dict['tailSlot_offset']
self.bundle.fromBpuNew.last_stage_ftb_entry.tailSlot_sharing.value = dict['tailSlot_sharing']

return self.bundle.as_dict()

@driver_method()
async def drive_last_stage_spec_info_signals(self, dict):
self.bundle.fromBpuNew.last_stage_spec_info.histPtr_flag.value = dict['histPtr_flag']
self.bundle.fromBpuNew.last_stage_spec_info.histPtr_value.value = dict['histPtr_value']
self.bundle.fromBpuNew.last_stage_spec_info.ssp.value = dict['ssp']
self.bundle.fromBpuNew.last_stage_spec_info.sctr.value = dict['sctr']
self.bundle.fromBpuNew.last_stage_spec_info.TOSW_flag.value = dict['TOSW_flag']
self.bundle.fromBpuNew.last_stage_spec_info.TOSW_value.value = dict['TOSW_value']
self.bundle.fromBpuNew.last_stage_spec_info.TOSR_flag.value = dict['TOSR_flag']
self.bundle.fromBpuNew.last_stage_spec_info.TOSR_value.value = dict['TOSR_value']
self.bundle.fromBpuNew.last_stage_spec_info.NOS_flag.value = dict['NOS_flag']
self.bundle.fromBpuNew.last_stage_spec_info.NOS_value.value = dict['NOS_value']
self.bundle.fromBpuNew.last_stage_spec_info.topAddr.value = dict['topAddr']
self.bundle.fromBpuNew.last_stage_spec_info.sc_disagree_0.value = dict['sc_disagree_0']
self.bundle.fromBpuNew.last_stage_spec_info.sc_disagree_1.value = dict['sc_disagree_1']
return self.bundle.as_dict()

@driver_method()
async def drive_last_stage_meta_signals(self):
self.bundle.fromBpuNew.last_stage_meta.last_stage_meta.value = random.randint(0, (1 << 516) - 1)

@driver_method()
async def drive_backend_inputs_full(self, dict):
b = self.bundle.fromBackend
# simple direct mappings where fields are known to exist in FtqBundle.fromBackend
if 'io_fromBackend_redirect_valid' in dict:
b.redirect_valid.value = dict['io_fromBackend_redirect_valid']
if 'io_fromBackend_redirect_bits_ftqIdx_flag' in dict:
b.redirect_bits_ftqIdx_flag.value = dict['io_fromBackend_redirect_bits_ftqIdx_flag']
if 'io_fromBackend_redirect_bits_ftqIdx_value' in dict:
b.redirect_bits_ftqIdx_value.value = dict['io_fromBackend_redirect_bits_ftqIdx_value']
if 'io_fromBackend_redirect_bits_ftqOffset' in dict:
b.redirect_bits_ftqOffset.value = dict['io_fromBackend_redirect_bits_ftqOffset']
if 'io_fromBackend_redirect_bits_level' in dict:
b.redirect_bits_level.value = dict['io_fromBackend_redirect_bits_level']
# cfi update fields (map to known names if present)
if 'io_fromBackend_redirect_bits_cfiUpdate_target' in dict:
b.redirect_bits_cfiUpdate_target.value = dict['io_fromBackend_redirect_bits_cfiUpdate_target']
if 'io_fromBackend_redirect_bits_cfiUpdate_taken' in dict:
b.redirect_bits_cfiUpdate_taken.value = dict['io_fromBackend_redirect_bits_cfiUpdate_taken']
if 'io_fromBackend_redirect_bits_cfiUpdate_isMisPred' in dict:
b.redirect_bits_cfiUpdate_isMisPred.value = dict['io_fromBackend_redirect_bits_cfiUpdate_isMisPred']
# debug fields
if 'io_fromBackend_redirect_bits_debugIsCtrl' in dict:
b.redirect_bits_debugIsCtrl.value = dict['io_fromBackend_redirect_bits_debugIsCtrl']
if 'io_fromBackend_redirect_bits_debugIsMemVio' in dict:
b.redirect_bits_debugIsMemVio.value = dict['io_fromBackend_redirect_bits_debugIsMemVio']
# ftq ahead / selector
if 'io_fromBackend_ftqIdxAhead_0_valid' in dict:
b.ftqIdxAhead_0_valid.value = dict['io_fromBackend_ftqIdxAhead_0_valid']
if 'io_fromBackend_ftqIdxAhead_0_bits_value' in dict:
b.ftqIdxAhead_0_bits_value.value = dict['io_fromBackend_ftqIdxAhead_0_bits_value']
if 'io_fromBackend_ftqIdxSelOH_bits' in dict:
b.ftqIdxSelOH_bits.value = dict['io_fromBackend_ftqIdxSelOH_bits']

# For any extra cfi fields that may exist on the bundle, set them if present
# e.g., cfiUpdate_pc, backendIGPF/IPF/IAF — only set if those attributes exist.
try:
if 'io_fromBackend_redirect_bits_cfiUpdate_pc' in dict and hasattr(b, 'redirect_bits_cfiUpdate_pc'):
b.redirect_bits_cfiUpdate_pc.value = dict['io_fromBackend_redirect_bits_cfiUpdate_pc']
except Exception:
pass
for extra in ('io_fromBackend_redirect_bits_cfiUpdate_backendIGPF',
'io_fromBackend_redirect_bits_cfiUpdate_backendIPF',
'io_fromBackend_redirect_bits_cfiUpdate_backendIAF'):
if extra in dict:
# try common attribute name pattern on bundle; ignore if not present
attr = extra.replace('io_fromBackend_redirect_bits_', 'redirect_bits_')
if hasattr(b, attr):
getattr(b, attr).value = dict[extra]

# rob_commits: handle 0..7 RobCommitBundle entries if present in bundle and dict
for i in range(8):
rb_name = f'rob_commits_{i}'
key_base = f'io_fromBackend_rob_commits_{i}_'
if not hasattr(b, rb_name):
continue
rb = getattr(b, rb_name)
if key_base + 'valid' in dict and hasattr(rb, 'valid'):
rb.valid.value = dict[key_base + 'valid']
if key_base + 'bits_commitType' in dict and hasattr(rb, 'bits_commitType'):
rb.bits_commitType.value = dict[key_base + 'bits_commitType']
if key_base + 'bits_ftqIdx_flag' in dict and hasattr(rb, 'bits_ftqIdx_flag'):
rb.bits_ftqIdx_flag.value = dict[key_base + 'bits_ftqIdx_flag']
if key_base + 'bits_ftqIdx_value' in dict and hasattr(rb, 'bits_ftqIdx_value'):
rb.bits_ftqIdx_value.value = dict[key_base + 'bits_ftqIdx_value']
if key_base + 'bits_ftqOffset' in dict and hasattr(rb, 'bits_ftqOffset'):
rb.bits_ftqOffset.value = dict[key_base + 'bits_ftqOffset']

return self.bundle.as_dict()

@driver_method()
async def drive_ifu_inputs_full(self, dict):
f = self.bundle.fromIfu
# top-level valid / ftqIdx fields
if 'io_fromIfu_pdWb_valid' in dict:
f.pdWb_valid.value = dict['io_fromIfu_pdWb_valid']
if 'io_fromIfu_pdWb_bits_ftqIdx_flag' in dict:
f.pdWb_bits_ftqIdx_flag.value = dict['io_fromIfu_pdWb_bits_ftqIdx_flag']
if 'io_fromIfu_pdWb_bits_ftqIdx_value' in dict:
f.pdWb_bits_ftqIdx_value.value = dict['io_fromIfu_pdWb_bits_ftqIdx_value']

# pc entries
for i in range(16):
key = f"io_fromIfu_pdWb_bits_pc_{i}"
attr = f"pdWb_bits_pc_{i}"
if key in dict and hasattr(f, attr):
getattr(f, attr).value = dict[key]

# per-slot pd fields (brType, isCall, isRet, valid, isRVC) if present
for i in range(16):
base = f"pdWb_bits_pd_{i}"
if hasattr(f, base):
pd_obj = getattr(f, base)
if f"io_fromIfu_pdWb_bits_pd_{i}_valid" in dict and hasattr(pd_obj, "valid"):
pd_obj.valid.value = dict[f"io_fromIfu_pdWb_bits_pd_{i}_valid"]
if f"io_fromIfu_pdWb_bits_pd_{i}_isRVC" in dict and hasattr(pd_obj, "isRVC"):
pd_obj.isRVC.value = dict[f"io_fromIfu_pdWb_bits_pd_{i}_isRVC"]
if f"io_fromIfu_pdWb_bits_pd_{i}_brType" in dict and hasattr(pd_obj, "brType"):
pd_obj.brType.value = dict[f"io_fromIfu_pdWb_bits_pd_{i}_brType"]
if f"io_fromIfu_pdWb_bits_pd_{i}_isCall" in dict and hasattr(pd_obj, "isCall"):
pd_obj.isCall.value = dict[f"io_fromIfu_pdWb_bits_pd_{i}_isCall"]
if f"io_fromIfu_pdWb_bits_pd_{i}_isRet" in dict and hasattr(pd_obj, "isRet"):
pd_obj.isRet.value = dict[f"io_fromIfu_pdWb_bits_pd_{i}_isRet"]

# misOffset / cfiOffset / target / jalTarget / instrRange
if 'io_fromIfu_pdWb_bits_misOffset_valid' in dict:
f.pdWb_bits_misOffset_valid.value = dict['io_fromIfu_pdWb_bits_misOffset_valid']
if 'io_fromIfu_pdWb_bits_misOffset_bits' in dict:
f.pdWb_bits_misOffset_bits.value = dict['io_fromIfu_pdWb_bits_misOffset_bits']
if 'io_fromIfu_pdWb_bits_cfiOffset_valid' in dict:
f.pdWb_bits_cfiOffset_valid.value = dict['io_fromIfu_pdWb_bits_cfiOffset_valid']
if 'io_fromIfu_pdWb_bits_target' in dict and hasattr(f, 'pdWb_bits_target'):
f.pdWb_bits_target.value = dict['io_fromIfu_pdWb_bits_target']
if 'io_fromIfu_pdWb_bits_jalTarget' in dict and hasattr(f, 'pdWb_bits_jalTarget'):
f.pdWb_bits_jalTarget.value = dict['io_fromIfu_pdWb_bits_jalTarget']

# instrRange entries if they exist on bundle
for i in range(16):
key = f"io_fromIfu_pdWb_bits_instrRange_{i}"
attr = f"pdWb_bits_instrRange_{i}"
if key in dict and hasattr(f, attr):
getattr(f, attr).value = dict[key]

return self.bundle.as_dict()
Loading
Loading