From 22439d442813065f47b2a722abb063f55b913596 Mon Sep 17 00:00:00 2001 From: Jacob Urbanczyk Date: Tue, 5 Mar 2024 13:38:52 +0100 Subject: [PATCH] Remove TestCoreSimple and TestCoreRandomized --- coreblocks/frontend/fetch.py | 8 -- test/test_core.py | 167 +---------------------------------- 2 files changed, 1 insertion(+), 174 deletions(-) diff --git a/coreblocks/frontend/fetch.py b/coreblocks/frontend/fetch.py index 1fdad5091..33a1a2129 100644 --- a/coreblocks/frontend/fetch.py +++ b/coreblocks/frontend/fetch.py @@ -38,9 +38,6 @@ def __init__(self, gen_params: GenParams, icache: CacheInterface, cont: Method) # ExceptionCauseRegister uses separate Transaction for it, so performace is not affected. self.stall_exception.add_conflict(self.resume, Priority.LEFT) - # PC of the last fetched instruction. For now only used in tests. - self.pc = Signal(self.gen_params.isa.xlen) - def elaborate(self, platform): m = TModule() @@ -91,7 +88,6 @@ def stall(exception=False): with m.If(unsafe_instr): stall() - m.d.sync += self.pc.eq(target.addr) m.d.comb += instr.eq(res.instr) self.cont(m, instr=instr, pc=target.addr, access_fault=fetch_error, rvc=0) @@ -138,9 +134,6 @@ def __init__(self, gen_params: GenParams, icache: CacheInterface, cont: Method) self.perf_rvc = HwCounter("frontend.ifu.rvc", "Number of decompressed RVC instructions") - # PC of the last fetched instruction. For now only used in tests. - self.pc = Signal(self.gen_params.isa.xlen) - def elaborate(self, platform) -> TModule: m = TModule() @@ -231,7 +224,6 @@ def elaborate(self, platform) -> TModule: m.d.sync += stalled_unsafe.eq(1) m.d.sync += flushing.eq(1) - m.d.sync += self.pc.eq(current_pc) with m.If(~cache_resp.error): m.d.sync += current_pc.eq(current_pc + Mux(is_rvc, C(2, 3), C(4, 3))) diff --git a/test/test_core.py b/test/test_core.py index 1522fa3a6..8bf5c8f1b 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -10,27 +10,15 @@ from coreblocks.params.configurations import CoreConfiguration, basic_core_config, full_core_config from coreblocks.peripherals.wishbone import WishboneBus, WishboneMemorySlave -from typing import Optional, cast +from typing import Optional import random import subprocess import tempfile from parameterized import parameterized_class from riscvmodel.insn import ( InstructionADDI, - InstructionSLTI, - InstructionSLTIU, - InstructionXORI, - InstructionORI, - InstructionANDI, - InstructionSLLI, - InstructionSRLI, - InstructionSRAI, InstructionLUI, - InstructionJAL, ) -from riscvmodel.model import Model -from riscvmodel.isa import Instruction, InstructionRType, get_insns -from riscvmodel.variant import RV32I class CoreTestElaboratable(Elaboratable): @@ -58,14 +46,12 @@ def elaborate(self, platform): ) self.core = Core(gen_params=self.gen_params, wb_instr_bus=wb_instr_bus, wb_data_bus=wb_data_bus) self.io_in = TestbenchIO(AdapterTrans(self.core.fetch_continue.method)) - self.rf_write = TestbenchIO(AdapterTrans(self.core.RF.write)) self.interrupt = TestbenchIO(AdapterTrans(self.core.interrupt_controller.report_interrupt)) m.submodules.wb_mem_slave = self.wb_mem_slave m.submodules.wb_mem_slave_data = self.wb_mem_slave_data m.submodules.c = self.core m.submodules.io_in = self.io_in - m.submodules.rf_write = self.rf_write m.submodules.interrupt = self.interrupt m.d.comb += wb_instr_bus.connect(self.wb_mem_slave.bus) @@ -74,53 +60,19 @@ def elaborate(self, platform): return m -def gen_riscv_add_instr(dst, src1, src2): - return 0b0110011 | dst << 7 | src1 << 15 | src2 << 20 - - -def gen_riscv_lui_instr(dst, imm): - return 0b0110111 | dst << 7 | imm << 12 - - class TestCoreBase(TestCaseWithSimulator): gen_params: GenParams m: CoreTestElaboratable - def check_RAT_alloc(self, rat, expected_alloc_count=None): # noqa: N802 - allocated = [] - for i in range(self.m.gen_params.isa.reg_cnt): - allocated.append((yield rat.entries[i])) - filtered_zeros = list(filter(lambda x: x != 0, allocated)) - - # check if 0th register is set to 0 - self.assertEqual(allocated[0], 0) - # check if there are no duplicate physical registers allocated for two different architectural registers - self.assertEqual(len(filtered_zeros), len(set(filtered_zeros))) - # check if the expected number of allocated registers matches reality - if expected_alloc_count: - self.assertEqual(len(filtered_zeros), expected_alloc_count) - def get_phys_reg_rrat(self, reg_id): return (yield self.m.core.RRAT.entries[reg_id]) - def get_phys_reg_frat(self, reg_id): - return (yield self.m.core.FRAT.entries[reg_id]) - def get_arch_reg_val(self, reg_id): return (yield self.m.core.RF.entries[(yield from self.get_phys_reg_rrat(reg_id))].reg_val) - def get_phys_reg_val(self, reg_id): - return (yield self.m.core.RF.entries[reg_id].reg_val) - def push_instr(self, opcode): yield from self.m.io_in.call(instr=opcode) - def compare_core_states(self, sw_core): - for i in range(self.gen_params.isa.reg_cnt): - reg_val = sw_core.state.intreg.regs[i].value - unsigned_val = reg_val & 0xFFFFFFFF - self.assertEqual((yield from self.get_arch_reg_val(i)), unsigned_val) - def push_register_load_imm(self, reg_id, val): addi_imm = signed_to_int(val & 0xFFF, 12) lui_imm = (val & 0xFFFFF000) >> 12 @@ -132,123 +84,6 @@ def push_register_load_imm(self, reg_id, val): yield from self.push_instr(InstructionADDI(reg_id, reg_id, addi_imm).encode()) -class TestCoreSimple(TestCoreBase): - def simple_test(self): - # this test first provokes allocation of physical registers, - # then sets the values in those registers, and finally runs - # an actual computation. - - # The test sets values in the reg file by hand - - # provoking allocation of physical register - for i in range(self.m.gen_params.isa.reg_cnt - 1): - yield from self.push_instr(gen_riscv_add_instr(i + 1, 0, 0)) - - # waiting for the retirement rat to be set - for i in range(100): - yield - - # checking if all registers have been allocated - yield from self.check_RAT_alloc(self.m.core.FRAT, 31) - yield from self.check_RAT_alloc(self.m.core.RRAT, 31) - - # writing values to physical registers - yield from self.m.rf_write.call(reg_id=(yield from self.get_phys_reg_rrat(1)), reg_val=1) - yield from self.m.rf_write.call(reg_id=(yield from self.get_phys_reg_rrat(2)), reg_val=2) - yield from self.m.rf_write.call(reg_id=(yield from self.get_phys_reg_rrat(3)), reg_val=3) - - # waiting for potential conflicts on rf_write - for i in range(10): - yield - - self.assertEqual((yield from self.get_arch_reg_val(1)), 1) - self.assertEqual((yield from self.get_arch_reg_val(2)), 2) - self.assertEqual((yield from self.get_arch_reg_val(3)), 3) - - # issuing actual instructions for the test - yield from self.push_instr(gen_riscv_add_instr(4, 1, 2)) - yield from self.push_instr(gen_riscv_add_instr(4, 3, 4)) - yield from self.push_instr(gen_riscv_lui_instr(5, 1)) - - # waiting for the instructions to be processed - for i in range(50): - yield - - self.assertEqual((yield from self.get_arch_reg_val(1)), 1) - self.assertEqual((yield from self.get_arch_reg_val(2)), 2) - self.assertEqual((yield from self.get_arch_reg_val(3)), 3) - # 1 + 2 + 3 = 6 - self.assertEqual((yield from self.get_arch_reg_val(4)), 6) - self.assertEqual((yield from self.get_arch_reg_val(5)), 1 << 12) - - def test_simple(self): - self.gen_params = GenParams(basic_core_config) - m = CoreTestElaboratable(self.gen_params) - self.m = m - - with self.run_simulation(m) as sim: - sim.add_sync_process(self.simple_test) - - -class TestCoreRandomized(TestCoreBase): - def randomized_input(self): - infloop_addr = (len(self.instr_mem) - 1) * 4 - # wait for PC to go past all instruction - while (yield self.m.core.fetch.pc) != infloop_addr: - yield - - # finish calculations - yield from self.tick(50) - - yield from self.compare_core_states(self.software_core) - - def test_randomized(self): - self.gen_params = GenParams(basic_core_config) - self.instr_count = 300 - random.seed(42) - - # cast is there to avoid stubbing riscvmodel - instructions = cast(list[type[Instruction]], get_insns(cls=InstructionRType, variant=RV32I)) - instructions += [ - InstructionADDI, - InstructionSLTI, - InstructionSLTIU, - InstructionXORI, - InstructionORI, - InstructionANDI, - InstructionSLLI, - InstructionSRLI, - InstructionSRAI, - InstructionLUI, - ] - - # allocate some random values for registers - init_instr_list = list( - InstructionADDI(rd=i, rs1=0, imm=random.randint(-(2**11), 2**11 - 1)) - for i in range(self.gen_params.isa.reg_cnt) - ) - - # generate random instruction stream - instr_list = list(random.choice(instructions)() for _ in range(self.instr_count)) - for instr in instr_list: - instr.randomize(RV32I) - - self.software_core = Model(RV32I) - self.software_core.execute(init_instr_list) - self.software_core.execute(instr_list) - - # We add JAL instruction at the end to effectively create a infinite loop at the end of the program. - all_instr = init_instr_list + instr_list + [InstructionJAL(rd=0, imm=0)] - - self.instr_mem = list(map(lambda x: x.encode(), all_instr)) - - m = CoreTestElaboratable(self.gen_params, instr_mem=self.instr_mem) - self.m = m - - with self.run_simulation(m) as sim: - sim.add_sync_process(self.randomized_input) - - class TestCoreAsmSourceBase(TestCoreBase): base_dir: str = "test/asm/"