test_rat.py
1 from transactron.testing import TestCaseWithSimulator, SimpleTestCircuit, TestbenchContext 2 3 from coreblocks.core_structs.rat import FRAT, RRAT 4 from coreblocks.params import GenParams 5 from coreblocks.params.configurations import test_core_config 6 7 from collections import deque 8 from random import Random 9 10 import pytest 11 12 13 class TestFrontendRegisterAliasTable(TestCaseWithSimulator): 14 def gen_input(self): 15 for _ in range(self.test_steps): 16 rl = self.rand.randrange(self.gen_params.isa.reg_cnt) 17 rp = self.rand.randrange(1, 2**self.gen_params.phys_regs_bits) if rl != 0 else 0 18 rl_s1 = self.rand.randrange(self.gen_params.isa.reg_cnt) 19 rl_s2 = self.rand.randrange(self.gen_params.isa.reg_cnt) 20 21 self.to_execute_list.append({"rl": rl, "rp": rp, "rl_s1": rl_s1, "rl_s2": rl_s2}) 22 23 async def do_rename(self, sim: TestbenchContext): 24 for _ in range(self.test_steps): 25 to_execute = self.to_execute_list.pop() 26 res = await self.m.rename.call( 27 sim, 28 rl_dst=to_execute["rl"], 29 rp_dst=to_execute["rp"], 30 rl_s1=to_execute["rl_s1"], 31 rl_s2=to_execute["rl_s2"], 32 ) 33 assert res.rp_s1 == self.expected_entries[to_execute["rl_s1"]] 34 assert res.rp_s2 == self.expected_entries[to_execute["rl_s2"]] 35 36 self.expected_entries[to_execute["rl"]] = to_execute["rp"] 37 38 def test_single(self): 39 self.rand = Random(0) 40 self.test_steps = 2000 41 self.gen_params = GenParams(test_core_config.replace(phys_regs_bits=5, rob_entries_bits=6)) 42 m = SimpleTestCircuit(FRAT(gen_params=self.gen_params)) 43 self.m = m 44 45 self.log_regs = self.gen_params.isa.reg_cnt 46 self.phys_regs = 2**self.gen_params.phys_regs_bits 47 48 self.to_execute_list = deque() 49 self.expected_entries = [0 for _ in range(self.log_regs)] 50 51 self.gen_input() 52 with self.run_simulation(m) as sim: 53 sim.add_testbench(self.do_rename) 54 55 56 @pytest.mark.parametrize("ports", [1, 2, 4]) 57 class TestRetirementRegisterAliasTable(TestCaseWithSimulator): 58 async def clear_chosen(self, sim: TestbenchContext): 59 while True: 60 self.chosen = set() 61 await sim.tick() 62 63 def do_commit(self, i: int): 64 async def tb(sim: TestbenchContext): 65 # wait until R-RAT clears itself after reset 66 await self.tick(sim, self.gen_params.isa.reg_cnt) 67 for _ in range(self.test_steps): 68 await sim.delay(1e-12 * i) 69 rl = self.rand.choice(list(set(range(self.gen_params.isa.reg_cnt)) - self.chosen)) 70 rp = self.rand.randrange(1, 2**self.gen_params.phys_regs_bits) if rl != 0 else 0 71 self.chosen.add(rl) 72 73 if self.rand.randrange(2): 74 peek_res = await self.m.peek[i].call(sim, rl_dst=rl) 75 assert peek_res.old_rp_dst == self.expected_entries[rl] 76 else: 77 res = await self.m.commit[i].call(sim, rl_dst=rl, rp_dst=rp) 78 assert res.old_rp_dst == self.expected_entries[rl] 79 80 self.expected_entries[rl] = rp 81 82 return tb 83 84 def test_single(self, ports: int): 85 self.rand = Random(0) 86 self.test_steps = 2000 87 self.gen_params = GenParams( 88 test_core_config.replace(phys_regs_bits=5, rob_entries_bits=6, retirement_superscalarity=ports) 89 ) 90 m = SimpleTestCircuit(RRAT(gen_params=self.gen_params)) 91 self.m = m 92 93 self.log_regs = self.gen_params.isa.reg_cnt 94 self.phys_regs = 2**self.gen_params.phys_regs_bits 95 96 self.to_execute_list = deque() 97 self.expected_entries = [0 for _ in range(self.log_regs)] 98 99 with self.run_simulation(m) as sim: 100 for i in range(ports): 101 sim.add_testbench(self.do_commit(i)) 102 sim.add_testbench(self.clear_chosen, background=True)