/ test / core_structs / test_rat.py
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)