finish ittage top init version

This commit is contained in:
llyyqq 2024-09-18 15:25:12 +08:00
parent b511a0dd00
commit c641d911f3
2 changed files with 62 additions and 9 deletions

View File

@ -155,6 +155,8 @@ class ITTAGEInfo(ITTAGEInterReg, ITTAGELastStageMeta):
self.jmp_taken = 0
self.cfi_idx_valid = 0
self.cfi_idx = 0
# only used for dut
self.meta_str = ""
def clear(self) -> None:
self.is_trace = 0
@ -167,6 +169,7 @@ class ITTAGEInfo(ITTAGEInterReg, ITTAGELastStageMeta):
self.ftb_entry_tailslot_valid = 0
self.ftb_entry_is_jalr = 0
self.ftb_entry_is_ret = 0
self.meta_str = ""
self.reinit()
def log(self, stage: int = 0) -> None:
@ -337,7 +340,7 @@ class ITTAGEModel:
def update(self, update: ITTAGEInfo) -> None:
_update_valid = update.update_valid and update.ftb_entry_is_jalr and not update.ftb_entry_is_ret and \
update.ftb_entry_tailslot_valid and not update.ftb_entry_tailslot_sharing and \
update.jmp_taken and update.cfi_idx_valid and update.cif_idx == update.ftb_entry_tailslot_offset
update.jmp_taken and update.cfi_idx_valid and update.cfi_idx == update.ftb_entry_tailslot_offset
# Every cycle only enable one update transaction
if _update_valid and not self.update_q.empty() and self.update_q.queue[0][1] != self.cycles:
self.update_q.put((update, self.cycles + 2))

View File

@ -14,7 +14,7 @@ import queue
import random
class ITTAGETop:
def __init__(self, dut: DUTITTage, log_mode: int = 0) -> None:
def __init__(self, dut: DUTITTage = None, log_mode: int = 0) -> None:
self.dut = dut
self.ref = ITTAGEModel(log_mode)
# input in current cycle
@ -31,14 +31,31 @@ class ITTAGETop:
self.latency = 20
# for debug
self.log_mode = log_mode
self.has_dut = isinstance(dut, DUTITTage)
def _gen_ref_output(self) -> ITTAGEInfo:
# Get ref output
return self.ref.get_output()
def _gen_dut_output(self) -> ITTAGEInfo:
# TODO: Get DUT output
raise NotImplementedError
if not self.has_dut:
return ITTAGEInfo()
_dut_out = ITTAGEInfo()
_dut_out.meta_str = self.dut.io_out_last_stage_meta.xdata.AsBinaryString()
_meta_str = self.dut.io_out_last_stage_meta.xdata.AsBinaryString()[::-1].ljust(101, '0')
_dut_out.has_provider = int(_meta_str[100] == '1')
_dut_out.provider = int(_meta_str[97:100][::-1], 2)
_dut_out.has_alt = int(_meta_str[96] == '1')
_dut_out.alt = int(_meta_str[93:96][::-1], 2)
_dut_out.alt_differs = int(_meta_str[92] == '1')
_dut_out.provider_u = int(_meta_str[91] == '1')
_dut_out.provider_ctr = int(_meta_str[89:91][::-1], 2)
_dut_out.alt_ctr = int(_meta_str[87:89][::-1], 2)
_dut_out.alloc_valid = int(_meta_str[86] == '1')
_dut_out.alloc_table = int(_meta_str[83:86][::-1], 2)
_dut_out.provider_target = int(_meta_str[41:82][::-1], 2)
_dut_out.alt_target = int(_meta_str[0:41][::-1], 2)
return _dut_out
def _assign_update_sig(self, update: ITTAGEInfo):
update.update_valid = 1
@ -49,13 +66,14 @@ class ITTAGETop:
update.ftb_entry_is_jalr = 1
update.ftb_entry_is_ret = 0
update.jmp_taken = 1
update.cfi_idx_valid = 0
update.cfi_idx_valid = 1
update.cfi_idx = index
return self
def _assign_dut_alloc_to_ref(self, ref_info: ITTAGEInfo, dut_info: ITTAGEInfo):
def _assign_dut_meta_to_ref(self, ref_info: ITTAGEInfo, dut_info: ITTAGEInfo):
ref_info.alloc_valid = dut_info.alloc_valid
ref_info.alloc_table = dut_info.alloc_table
ref_info.meta_str = dut_info.meta_str
def _assign_mispred(self, out_info: ITTAGEInfo):
# When no provider, set mispred to allocate new table item
@ -72,6 +90,8 @@ class ITTAGETop:
return self
def _compare_dut_ref_output(self, ref_info: ITTAGEInfo, dut_info: ITTAGEInfo) -> bool:
if not self.has_dut:
return True
if not ref_info.check_provider(dut_info.has_provider, dut_info.provider, \
dut_info.provider_u, dut_info.provider_ctr, dut_info.provider_target):
return False
@ -97,6 +117,8 @@ class ITTAGETop:
self.ref.cycle(_input_info)
def _dut_input_and_step(self):
if not self.has_dut:
return
# Set DUT pipeline shake hand signal
self.dut.io_s0_fire_3.xdata.value = self.s0_fire
self.dut.io_s1_fire_3.xdata.value = self.s1_fire
@ -114,7 +136,35 @@ class ITTAGETop:
self.dut.Step(1)
def _assign_dut_update(self, update: ITTAGEInfo = None):
raise NotImplementedError
# TODO: assign DUT update signals
# no DUT or no update valid in this cycle
if not self.has_dut:
return
if not isinstance(update, ITTAGEInfo):
self.dut.io_update_valid = 0
return
# assign update signals in DUT
self.dut.io_update_valid.xdata.value = 1
self.dut.io_update_bits_pc.xdata.value = update.pc
self.dut.io_update_bits_spec_info_folded_hist_hist_12_folded_hist.xdata.value = update.folded_hists[0]
self.dut.io_update_bits_spec_info_folded_hist_hist_14_folded_hist.xdata.value = update.folded_hists[1]
self.dut.io_update_bits_spec_info_folded_hist_hist_13_folded_hist.xdata.value = update.folded_hists[2][0]
self.dut.io_update_bits_spec_info_folded_hist_hist_4_folded_hist.xdata.value = update.folded_hists[2][1]
self.dut.io_update_bits_spec_info_folded_hist_hist_6_folded_hist.xdata.value = update.folded_hists[3][0]
self.dut.io_update_bits_spec_info_folded_hist_hist_2_folded_hist.xdata.value = update.folded_hists[3][1]
self.dut.io_update_bits_spec_info_folded_hist_hist_10_folded_hist.xdata.value = update.folded_hists[4][0]
self.dut.io_update_bits_spec_info_folded_hist_hist_3_folded_hist.xdata.value = update.folded_hists[4][1]
self.dut.io_update_bits_ftb_entry_isJalr.xdata.value = update.ftb_entry_is_jalr
self.dut.io_update_bits_ftb_entry_isRet.xdata.value = update.ftb_entry_is_ret
self.dut.io_update_bits_ftb_entry_tailSlot_valid.xdata.value = update.ftb_entry_tailslot_valid
self.dut.io_update_bits_ftb_entry_tailSlot_sharing.xdata.value = update.ftb_entry_tailslot_sharing
self.dut.io_update_bits_ftb_entry_tailSlot_offset.xdata.value = update.ftb_entry_tailslot_offset
self.dut.io_update_bits_cfi_idx_valid.xdata.value = update.cfi_idx_valid
self.dut.io_update_bits_cfi_idx_bits.xdata.value = update.cfi_idx
self.dut.io_update_bits_jmp_taken.xdata.value = update.jmp_taken
self.dut.io_update_bits_mispred_mask_2.xdata.value = update.mispred
self.dut.io_update_bits_meta.xdata.value = '0b' + update.meta_str
self.dut.io_update_bits_full_target.xdata.value = update.target
def _log_info(self, ref_info: ITTAGEInfo, dut_info: ITTAGEInfo):
# basic meta log
@ -141,7 +191,7 @@ class ITTAGETop:
# ------------- Gen DUT Output --------------
_out_dut_info = self._gen_dut_output()
# ------------- Outpur Comparision --------------
# ------------- Output Comparision --------------
if self.log_mode == 1:
self._log_info(_out_ref_info, _out_dut_info)
if self._compare_dut_ref_output(_out_ref_info, _out_dut_info):
@ -151,7 +201,7 @@ class ITTAGETop:
# Generate update feedback to ITTAGE (Only for traced signal)
if _out_ref_info.is_trace:
self._assign_update_sig(_out_ref_info)
self._assign_dut_alloc_to_ref(_out_ref_info, _out_dut_info)
self._assign_dut_meta_to_ref(_out_ref_info, _out_dut_info)
self._assign_mispred(_out_ref_info)
# push update info to queue and set random latency for each update
self.update_q.put((_out_ref_info, self.cycles + self.latency))