Skip to content

Commit

Permalink
Add frontend.bpu.ittage test code
Browse files Browse the repository at this point in the history
  • Loading branch information
FrankOu2001 committed Jan 21, 2025
1 parent 2f2073a commit 5997ca2
Show file tree
Hide file tree
Showing 20 changed files with 1,344 additions and 2 deletions.
30 changes: 28 additions & 2 deletions scripts/build_ut_frontend_bpu_ittage.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,34 @@


def build(cfg):
return False
from tempfile import NamedTemporaryFile
from toffee_test.markers import match_version
from comm import error, info, get_root_dir, exe_cmd, get_all_rtl_files

# check version
if not match_version(cfg.rtl.version, "openxiangshan-kmh-*"):
error(f"frontend_bpu_ittage: Unsupported RTL version {cfg.rtl.version}")
return False

# find source files for ITTage
rtl_files = get_all_rtl_files("ITTage", cfg=cfg)
assert rtl_files, "Cannot find RTL files of Frontend.BPU.ITTage"

internal_signals_path = os.path.join(get_root_dir("ut_frontend/bpu/ittage/internal.yaml"))
assert os.path.exists(internal_signals_path), "Cannot find internal signal files"

# export ITTage.sv
if not os.path.exists(get_root_dir("dut/ITTage")):
info("Exporting ITTage.sv")
with NamedTemporaryFile("w+", encoding="utf-8", suffix=".txt") as filelist:
filelist.write("\n".join(rtl_files))
filelist.flush()
s, _, err = exe_cmd(
f"picker export --cp_lib false {rtl_files[0]} --fs {filelist.name} --lang python --tdir "
f"{get_root_dir('dut')}/ -w ITTage.fst -c --internal={internal_signals_path}")
assert s, err
return True


def line_coverage_files(cfg):
return []
return ["ITTage.v"]
Empty file.
48 changes: 48 additions & 0 deletions ut_frontend/bpu/ittage/env/bundle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
__all__ = ['UpdateBundle', 'InBundle', 'OutBundle', 'PipelineCtrl']

from toffee import Bundle, Signals, Signal

class PipelineCtrl(Bundle):
s0_fire_0, s0_fire_1, s0_fire_2, s0_fire_3 = Signals(4)
s1_fire_0, s1_fire_1, s1_fire_2, s1_fire_3 = Signals(4)
s2_fire_0, s2_fire_1, s2_fire_2, s2_fire_3 = Signals(4)

class FullPred(Bundle):
jalr_target = Signal()

class FoldedHist(Bundle):
[hist_14_folded_hist, hist_13_folded_hist , hist_12_folded_hist , hist_10_folded_hist,
hist_6_folded_hist , hist_4_folded_hist , hist_3_folded_hist , hist_2_folded_hist] = Signals(8)

class FTBEntry(Bundle):
tailSlot_offset, tailSlot_sharing, tailSlot_valid, isRet, isJalr = Signals(5)

class CFI(Bundle):
valid, bits = Signals(2)

# io_update_
class UpdateBundle(Bundle):
valid, bits_pc, bits_jmp_taken, bits_mispred_mask_2, bits_meta, bits_full_target = Signals(6)
bits_ghist = Signal()
ftb_entry = FTBEntry.from_prefix("bits_ftb_entry_")
# folded_hist= FoldedHist.from_prefix("bits_spec_info_folded_hist_")
cfi = CFI.from_prefix("bits_cfi_idx_")

# io_in_
class InBundle(Bundle):
bits_s0_pc_3 = Signal()

folded_hist = FoldedHist.from_prefix("bits_s1_folded_hist_3_")
pred0 = FullPred.from_prefix("bits_resp_in_0_s2_full_pred_0_")
pred1 = FullPred.from_prefix("bits_resp_in_0_s2_full_pred_1_")
pred2 = FullPred.from_prefix("bits_resp_in_0_s2_full_pred_2_")
pred3 = FullPred.from_prefix("bits_resp_in_0_s2_full_pred_3_")

# io_out_
class OutBundle(Bundle):
last_stage_meta = Signal()

pred1 = FullPred.from_prefix("s3_full_pred_1_")
pred0 = FullPred.from_prefix("s3_full_pred_0_")
pred2 = FullPred.from_prefix("s3_full_pred_2_")
pred3 = FullPred.from_prefix("s3_full_pred_3_")
26 changes: 26 additions & 0 deletions ut_frontend/bpu/ittage/env/global_history.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
__all__ = ["GlobalHistory"]

GLOBAL_HISTORY_LEN = 256
GLOBAL_HISTORY_MASK = (1 << GLOBAL_HISTORY_LEN) - 1


class GlobalHistory:
def __init__(self, init_val: int = 0, gh_len: int = GLOBAL_HISTORY_LEN):
self.value = init_val
self._len = gh_len

def update(self, taken: bool) -> None:
g = self.value
self.value = (g << 1) | taken & GLOBAL_HISTORY_MASK

def get_fh(self, folded_len: int, hist_len: int) -> int:
if folded_len == 0:
return 0
res = 0
g = self.value & ((1 << hist_len) - 1)
mask = (1 << folded_len) - 1
for _ in range(0, min(self._len, hist_len), folded_len):
res ^= g & mask
g >>= folded_len

return res
134 changes: 134 additions & 0 deletions ut_frontend/bpu/ittage/env/ittage_wrapper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import os.path
import random
from datetime import datetime


import toffee
from toffee import ClockCycles
from dut.ITTage import DUTITTage
from ..util.common import get_folded_hist
from .bundle import *

__all__ = ['ITTageWrapper']


class ITTageWrapper:
def __init__(self, dut: DUTITTage):
# Create DUT
self.dut = dut
self.dut.InitClock("clock")
self.xclock = self.dut.xclock # for callback function

# Connect Bundle
self.update_bundle = UpdateBundle.from_prefix("io_update_").set_name("ittage_update").bind(self.dut)
self.in_bundle = InBundle.from_prefix("io_in_").set_name("ittage_in").bind(self.dut)
self.out_bundle = OutBundle.from_prefix("io_out_").set_name("ittage_out").bind(self.dut)
self.pipeline_ctrl = PipelineCtrl.from_prefix("io_").set_name("ittage_pipeline_ctrl").bind(self.dut)

# Reset
self.reset()

def finalize(self):
self.dut.Finish()

async def __rst_async__(self):
self.dut.reset.value = 1
await ClockCycles(self.dut, 10)
self.dut.reset.value = 0

def __set_fire__(self, stage):
for i in range(0, 4):
getattr(self.pipeline_ctrl, f"s{stage}_fire_{i}").value = 1


def __unset_fire__(self, stage):
for i in range(0, 4):
getattr(self.pipeline_ctrl, f"s{stage}_fire_{i}").value = 0

async def __predict_async__(self, fh, pc, use_dummy_fh=False):
# stage0
self.__set_fire__(0)
self.in_bundle.bits_s0_pc_3.value = pc
if use_dummy_fh:
self.in_bundle.folded_hist.set_all(0)
else:
self.in_bundle.folded_hist.assign(get_folded_hist(fh))
await ClockCycles(self.dut, 1)
self.__unset_fire__(0)

# stage1
self.__set_fire__(1)
await ClockCycles(self.dut, 1)
self.__unset_fire__(1)

# stage2
self.__set_fire__(2)
await ClockCycles(self.dut, 1)
self.__unset_fire__(2)

# stage3
await ClockCycles(self.dut, 1)

return self.out_bundle.as_dict()

async def __update_async__(self, update_req):
self.update_bundle.assign(update_req)
self.update_bundle.valid.value = 1
await ClockCycles(self.dut, 1)
self.update_bundle.valid.value = 0

await ClockCycles(self.dut, 3)

return None

def predict(self, fh, pc, use_dummy_fh=False):
# stage0
self.__set_fire__(0)
self.in_bundle.bits_s0_pc_3.value = pc
if use_dummy_fh:
self.in_bundle.folded_hist.set_all(0)
else:
self.in_bundle.folded_hist.assign(get_folded_hist(fh))
self.xclock.Step(1)
self.__unset_fire__(0)

# stage1
self.__set_fire__(1)
self.xclock.Step(1)
self.__unset_fire__(1)

# stage2
self.__set_fire__(2)
self.xclock.Step(1)
self.__unset_fire__(2)

# stage3
self.xclock.Step(1)

return self.out_bundle.as_dict()

def predict_async(self, fh, pc, use_dummy_fh=False):
return toffee.create_task(self.__predict_async__(fh, pc, use_dummy_fh))

def update(self, update_req):
self.update_bundle.assign(update_req)
self.update_bundle.valid.value = 1
self.xclock.Step(1)
self.update_bundle.valid.value = 0

self.xclock.Step(1)
pass

def update_async(self, update_req):
return toffee.create_task(self.__update_async__(update_req))

def reset(self):
self.dut.reset.value = 1
self.xclock.Step(1)
self.dut.reset.value = 0
while self.dut.io_s1_ready.value == 0:
self.xclock.Step(1)
self.xclock.Step(10)

def reset_async(self):
return toffee.create_task(self.__rst_async__())
62 changes: 62 additions & 0 deletions ut_frontend/bpu/ittage/internal.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
ITTage:
- "logic s3_altProvided"
- "logic [1:0] s3_altProviderCtr"
- "logic [40:0] s3_altProviderTarget"
- "logic [2:0] s3_altProvider"
- "logic s3_provided"
- "logic [1:0] s3_providerCtr"
- "logic s3_providerU"
- "logic [2:0] s3_provider"
- "logic [40:0] s3_providerTarget"
- "logic [7:0] tickCtr"
- "logic updateValid"
- tables_0:
- "wire io_resp_valid"
- "wire io_update_valid"
- "wire io_update_alloc"
- "wire io_update_correct"
- "wire [1:0] io_update_oldCtr"
- "wire [1:0] update_wdata_ctr"
- "wire io_update_reset_u"
- "wire io_update_uValid"
- "wire io_update_u"
- tables_1:
- "wire io_resp_valid"
- "wire io_update_valid"
- "wire io_update_alloc"
- "wire io_update_correct"
- "wire [1:0] io_update_oldCtr"
- "wire [1:0] update_wdata_ctr"
- "wire io_update_reset_u"
- "wire io_update_uValid"
- "wire io_update_u"
- tables_2:
- "wire io_resp_valid"
- "wire io_update_valid"
- "wire io_update_alloc"
- "wire io_update_correct"
- "wire [1:0] io_update_oldCtr"
- "wire [1:0] update_wdata_ctr"
- "wire io_update_reset_u"
- "wire io_update_uValid"
- "wire io_update_u"
- tables_3:
- "wire io_resp_valid"
- "wire io_update_valid"
- "wire io_update_alloc"
- "wire io_update_correct"
- "wire [1:0] io_update_oldCtr"
- "wire [1:0] update_wdata_ctr"
- "wire io_update_reset_u"
- "wire io_update_uValid"
- "wire io_update_u"
- tables_4:
- "wire io_resp_valid"
- "wire io_update_valid"
- "wire io_update_alloc"
- "wire io_update_correct"
- "wire [1:0] io_update_oldCtr"
- "wire [1:0] update_wdata_ctr"
- "wire io_update_reset_u"
- "wire io_update_uValid"
- "wire io_update_u"
Empty file.
Loading

0 comments on commit 5997ca2

Please sign in to comment.