diff --git a/test/func_blocks/fu/common/test_rs.py b/test/func_blocks/fu/common/test_rs.py index fdd07d805..6e626c4fc 100644 --- a/test/func_blocks/fu/common/test_rs.py +++ b/test/func_blocks/fu/common/test_rs.py @@ -150,390 +150,3 @@ def get_possible_ids(): assert data.exec_fn.op_type in self.optype_groups[optype_group] assert taken == set(range(len(self.data_list))) self.finished = True - - -class TestRSMethodInsert(TestCaseWithSimulator): - def test_insert(self): - self.gen_params = GenParams(test_core_config) - self.rs_entries_bits = self.gen_params.max_rs_entries_bits - self.m = SimpleTestCircuit(RS(self.gen_params, 2**self.rs_entries_bits, 0, None)) - self.insert_list = [ - { - "rs_entry_id": id, - "rs_data": { - "rp_s1": id * 2, - "rp_s2": id * 2 + 1, - "rp_dst": id * 2, - "rob_id": id, - "exec_fn": { - "op_type": 1, - "funct3": 2, - "funct7": 4, - }, - "s1_val": id, - "s2_val": id, - "imm": id, - "pc": id, - }, - } - for id in range(2**self.rs_entries_bits) - ] - self.check_list = create_check_list(self.rs_entries_bits, self.insert_list) - - with self.run_simulation(self.m) as sim: - sim.add_testbench(self.simulation_process) - - async def simulation_process(self, sim: TestbenchContext): - # After each insert, entry should be marked as full - for index, record in enumerate(self.insert_list): - assert sim.get(self.m._dut.data[index].rec_full) == 0 - await self.m.insert.call(sim, record) - assert sim.get(self.m._dut.data[index].rec_full) == 1 - - # Check data integrity - for expected, record in zip(self.check_list, self.m._dut.data): - assert expected == data_const_to_dict(sim.get(record)) - - -class TestRSMethodSelect(TestCaseWithSimulator): - def test_select(self): - self.gen_params = GenParams(test_core_config) - self.rs_entries_bits = self.gen_params.max_rs_entries_bits - self.m = SimpleTestCircuit(RS(self.gen_params, 2**self.rs_entries_bits, 0, None)) - self.insert_list = [ - { - "rs_entry_id": id, - "rs_data": { - "rp_s1": id * 2, - "rp_s2": id * 2, - "rp_dst": id * 2, - "rob_id": id, - "exec_fn": { - "op_type": 1, - "funct3": 2, - "funct7": 4, - }, - "s1_val": id, - "s2_val": id, - "imm": id, - "pc": id, - }, - } - for id in range(2**self.rs_entries_bits - 1) - ] - self.check_list = create_check_list(self.rs_entries_bits, self.insert_list) - - with self.run_simulation(self.m) as sim: - sim.add_testbench(self.simulation_process) - - async def simulation_process(self, sim: TestbenchContext): - # In the beginning the select method should be ready and id should be selectable - for index, record in enumerate(self.insert_list): - assert sim.get(self.m._dut.select.ready) == 1 - assert (await self.m.select.call(sim)).rs_entry_id == index - assert sim.get(self.m._dut.data[index].rec_reserved) == 1 - await self.m.insert.call(sim, record) - - # Check if RS state is as expected - for expected, record in zip(self.check_list, self.m._dut.data): - assert sim.get(record.rec_full) == expected["rec_full"] - assert sim.get(record.rec_reserved) == expected["rec_reserved"] - - # Reserve the last entry, then select ready should be false - assert sim.get(self.m._dut.select.ready) == 1 - assert (await self.m.select.call(sim)).rs_entry_id == 3 - assert sim.get(self.m._dut.select.ready) == 0 - - # After take, select ready should be true, with 0 index returned - await self.m.take.call(sim, rs_entry_id=0) - assert sim.get(self.m._dut.select.ready) == 1 - assert (await self.m.select.call(sim)).rs_entry_id == 0 - - # After reservation, select is false again - assert sim.get(self.m._dut.select.ready) == 0 - - -class TestRSMethodUpdate(TestCaseWithSimulator): - def test_update(self): - self.gen_params = GenParams(test_core_config) - self.rs_entries_bits = self.gen_params.max_rs_entries_bits - self.m = SimpleTestCircuit(RS(self.gen_params, 2**self.rs_entries_bits, 0, None)) - self.insert_list = [ - { - "rs_entry_id": id, - "rs_data": { - "rp_s1": id * 2, - "rp_s2": id * 2 + 1, - "rp_dst": id * 2, - "rob_id": id, - "exec_fn": { - "op_type": 1, - "funct3": 2, - "funct7": 4, - }, - "s1_val": id, - "s2_val": id, - "imm": id, - "pc": id, - }, - } - for id in range(2**self.rs_entries_bits) - ] - self.check_list = create_check_list(self.rs_entries_bits, self.insert_list) - - with self.run_simulation(self.m) as sim: - sim.add_testbench(self.simulation_process) - - async def simulation_process(self, sim: TestbenchContext): - # Insert all reacords - for record in self.insert_list: - await self.m.insert.call(sim, record) - - # Check data integrity - for expected, record in zip(self.check_list, self.m._dut.data): - assert expected == data_const_to_dict(sim.get(record)) - - # Update second entry first SP, instruction should be not ready - value_sp1 = 1010 - assert sim.get(self.m._dut.data_ready[1]) == 0 - await self.m.update.call(sim, reg_id=2, reg_val=value_sp1) - assert sim.get(self.m._dut.data[1].rs_data.rp_s1) == 0 - assert sim.get(self.m._dut.data[1].rs_data.s1_val) == value_sp1 - assert sim.get(self.m._dut.data_ready[1]) == 0 - - # Update second entry second SP, instruction should be ready - value_sp2 = 2020 - await self.m.update.call(sim, reg_id=3, reg_val=value_sp2) - assert sim.get(self.m._dut.data[1].rs_data.rp_s2) == 0 - assert sim.get(self.m._dut.data[1].rs_data.s2_val) == value_sp2 - assert sim.get(self.m._dut.data_ready[1]) == 1 - - # Insert new instruction to entries 0 and 1, check if update of multiple registers works - reg_id = 4 - value_spx = 3030 - data = { - "rp_s1": reg_id, - "rp_s2": reg_id, - "rp_dst": 1, - "rob_id": 12, - "exec_fn": { - "op_type": 1, - "funct3": 2, - "funct7": 4, - }, - "s1_val": 0, - "s2_val": 0, - "pc": 40, - } - - for index in range(2): - await self.m.insert.call(sim, rs_entry_id=index, rs_data=data) - assert sim.get(self.m._dut.data_ready[index]) == 0 - - await self.m.update.call(sim, reg_id=reg_id, reg_val=value_spx) - for index in range(2): - assert sim.get(self.m._dut.data[index].rs_data.rp_s1) == 0 - assert sim.get(self.m._dut.data[index].rs_data.rp_s2) == 0 - assert sim.get(self.m._dut.data[index].rs_data.s1_val) == value_spx - assert sim.get(self.m._dut.data[index].rs_data.s2_val) == value_spx - assert sim.get(self.m._dut.data_ready[index]) == 1 - - -class TestRSMethodTake(TestCaseWithSimulator): - def test_take(self): - self.gen_params = GenParams(test_core_config) - self.rs_entries_bits = self.gen_params.max_rs_entries_bits - self.m = SimpleTestCircuit(RS(self.gen_params, 2**self.rs_entries_bits, 0, None)) - self.insert_list = [ - { - "rs_entry_id": id, - "rs_data": { - "rp_s1": id * 2, - "rp_s2": id * 2, - "rp_dst": id * 2, - "rob_id": id, - "exec_fn": { - "op_type": 1, - "funct3": 2, - "funct7": 4, - }, - "s1_val": id, - "s2_val": id, - "imm": id, - "pc": id, - }, - } - for id in range(2**self.rs_entries_bits) - ] - self.check_list = create_check_list(self.rs_entries_bits, self.insert_list) - - with self.run_simulation(self.m) as sim: - sim.add_testbench(self.simulation_process) - - async def simulation_process(self, sim: TestbenchContext): - # After each insert, entry should be marked as full - for record in self.insert_list: - await self.m.insert.call(sim, record) - - # Check data integrity - for expected, record in zip(self.check_list, self.m._dut.data): - assert expected == data_const_to_dict(sim.get(record)) - - # Take first instruction - assert sim.get(self.m._dut.get_ready_list[0].ready) == 1 - data = data_const_to_dict(await self.m.take.call(sim, rs_entry_id=0)) - for key in data: - assert data[key] == self.check_list[0]["rs_data"][key] - assert sim.get(self.m._dut.get_ready_list[0].ready) == 0 - - # Update second instuction and take it - reg_id = 2 - value_spx = 1 - await self.m.update.call(sim, reg_id=reg_id, reg_val=value_spx) - assert sim.get(self.m._dut.get_ready_list[0].ready) == 1 - data = data_const_to_dict(await self.m.take.call(sim, rs_entry_id=1)) - for key in data: - assert data[key] == self.check_list[1]["rs_data"][key] - assert sim.get(self.m._dut.get_ready_list[0].ready) == 0 - - # Insert two new ready instructions and take them - reg_id = 0 - value_spx = 3030 - entry_data = { - "rp_s1": reg_id, - "rp_s2": reg_id, - "rp_dst": 1, - "rob_id": 12, - "exec_fn": { - "op_type": 1, - "funct3": 2, - "funct7": 4, - }, - "s1_val": 0, - "s2_val": 0, - "imm": 1, - "pc": 40, - } - - for index in range(2): - await self.m.insert.call(sim, rs_entry_id=index, rs_data=entry_data) - assert sim.get(self.m._dut.get_ready_list[0].ready) == 1 - assert sim.get(self.m._dut.data_ready[index]) == 1 - - data = data_const_to_dict(await self.m.take.call(sim, rs_entry_id=0)) - for key in data: - assert data[key] == entry_data[key] - assert sim.get(self.m._dut.get_ready_list[0].ready) == 1 - - data = data_const_to_dict(await self.m.take.call(sim, rs_entry_id=1)) - for key in data: - assert data[key] == entry_data[key] - assert sim.get(self.m._dut.get_ready_list[0].ready) == 0 - - -class TestRSMethodGetReadyList(TestCaseWithSimulator): - def test_get_ready_list(self): - self.gen_params = GenParams(test_core_config) - self.rs_entries_bits = self.gen_params.max_rs_entries_bits - self.m = SimpleTestCircuit(RS(self.gen_params, 2**self.rs_entries_bits, 0, None)) - self.insert_list = [ - { - "rs_entry_id": id, - "rs_data": { - "rp_s1": id // 2, - "rp_s2": id // 2, - "rp_dst": id * 2, - "rob_id": id, - "exec_fn": { - "op_type": 1, - "funct3": 2, - "funct7": 4, - }, - "s1_val": id, - "s2_val": id, - "imm": id, - "pc": id, - }, - } - for id in range(2**self.rs_entries_bits) - ] - self.check_list = create_check_list(self.rs_entries_bits, self.insert_list) - - with self.run_simulation(self.m) as sim: - sim.add_testbench(self.simulation_process) - - async def simulation_process(self, sim: TestbenchContext): - # After each insert, entry should be marked as full - for record in self.insert_list: - await self.m.insert.call(sim, record) - - # Check ready vector integrity - ready_list = (await self.m.get_ready_list[0].call(sim)).ready_list - assert ready_list == 0b0011 - - # Take first record and check ready vector integrity - await self.m.take.call(sim, rs_entry_id=0) - ready_list = (await self.m.get_ready_list[0].call(sim)).ready_list - assert ready_list == 0b0010 - - # Take second record and check ready vector integrity - await self.m.take.call(sim, rs_entry_id=1) - option_ready_list = await self.m.get_ready_list[0].call_try(sim) - assert option_ready_list is None - - -class TestRSMethodTwoGetReadyLists(TestCaseWithSimulator): - def test_two_get_ready_lists(self): - self.gen_params = GenParams(test_core_config) - self.rs_entries = self.gen_params.max_rs_entries - self.rs_entries_bits = self.gen_params.max_rs_entries_bits - self.m = SimpleTestCircuit( - RS(self.gen_params, 2**self.rs_entries_bits, 0, [[OpType(1), OpType(2)], [OpType(3), OpType(4)]]), - ) - self.insert_list = [ - { - "rs_entry_id": id, - "rs_data": { - "rp_s1": 0, - "rp_s2": 0, - "rp_dst": id * 2, - "rob_id": id, - "exec_fn": { - "op_type": OpType(id + 1), - "funct3": 2, - "funct7": 4, - }, - "s1_val": id, - "s2_val": id, - "imm": id, - }, - } - for id in range(self.rs_entries) - ] - self.check_list = create_check_list(self.rs_entries_bits, self.insert_list) - - with self.run_simulation(self.m) as sim: - sim.add_testbench(self.simulation_process) - - async def simulation_process(self, sim: TestbenchContext): - # After each insert, entry should be marked as full - for record in self.insert_list: - await self.m.insert.call(sim, record) - - masks = [0b0011, 0b1100] - - for i in range(self.m._dut.rs_entries + 1): - # Check ready vectors' integrity - for j in range(2): - ready_list = await self.m.get_ready_list[j].call_try(sim) - if masks[j]: - assert ready_list.ready_list == masks[j] - else: - assert ready_list is None - - # Take a record - if i == self.m._dut.rs_entries: - break - await self.m.take.call(sim, rs_entry_id=i) - - masks = [mask & ~(1 << i) for mask in masks]