From 167df40b5248182cb331bc567535ace7bd299834 Mon Sep 17 00:00:00 2001 From: miceforrat <91134302+miceforrat@users.noreply.github.com> Date: Thu, 7 Aug 2025 11:05:22 +0800 Subject: [PATCH] Revert "Pr smy ifu predecode new (#140)" This reverts commit 59460cfdc08629bdd91d8ccb58156dfd2ae8fc2e. --- .gitignore | 2 +- .../f3predecoder/agent/f3predecoder_agent.py | 5 - .../f3predecoder/test/f3predecoder_fixture.py | 45 ---- .../test/f3predecoder_instr_gen.py | 231 ------------------ .../f3predecoder/test/f3predecoder_test.py | 182 +------------- .../ifu/predecode/agent/predecode_agent.py | 15 +- .../ifu/predecode/test/predecode_fixture.py | 41 +--- .../ifu/predecode/test/predecode_instr_gen.py | 168 ------------- .../ifu/predecode/test/predecode_test.py | 106 +------- 9 files changed, 11 insertions(+), 784 deletions(-) delete mode 100644 ut_frontend/ifu/f3predecoder/test/f3predecoder_instr_gen.py delete mode 100644 ut_frontend/ifu/predecode/test/predecode_instr_gen.py diff --git a/.gitignore b/.gitignore index 2bb9371..d19094d 100644 --- a/.gitignore +++ b/.gitignore @@ -173,4 +173,4 @@ cython_debug/ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ +#.idea/ \ No newline at end of file diff --git a/ut_frontend/ifu/f3predecoder/agent/f3predecoder_agent.py b/ut_frontend/ifu/f3predecoder/agent/f3predecoder_agent.py index 789bd0b..be5b1b9 100644 --- a/ut_frontend/ifu/f3predecoder/agent/f3predecoder_agent.py +++ b/ut_frontend/ifu/f3predecoder/agent/f3predecoder_agent.py @@ -9,10 +9,6 @@ class F3PreDecodeData(): def __str__(self): return f"brTypes: {self.brTypes}\nisCalls: {self.isCalls}\nisRets: {self.isRets}" - def clear(self): - self.brTypes = [] - self.isCalls = [] - self.isRets = [] class F3PreDecoderAgent(Agent): def __init__(self, bundle:F3PreDecoderBundle): @@ -27,7 +23,6 @@ class F3PreDecoderAgent(Agent): await self.bundle.step() ret = F3PreDecodeData() - ret.clear() for i in range(16): ret.brTypes.append(getattr(self.bundle.io._out_pd, f"_{i}")._brType.value) ret.isCalls.append(getattr(self.bundle.io._out_pd, f"_{i}")._isCall.value) diff --git a/ut_frontend/ifu/f3predecoder/test/f3predecoder_fixture.py b/ut_frontend/ifu/f3predecoder/test/f3predecoder_fixture.py index 55e5550..5d4de34 100644 --- a/ut_frontend/ifu/f3predecoder/test/f3predecoder_fixture.py +++ b/ut_frontend/ifu/f3predecoder/test/f3predecoder_fixture.py @@ -2,56 +2,11 @@ import toffee_test from dut.F3Predecoder import DUTF3Predecoder from toffee import start_clock from ..env import F3PreDecoderEnv -import toffee.funcov as fc -from comm import UT_FCOV, module_name_with - -grp = fc.CovGroup(UT_FCOV("../../CLASSIC")) -def init_cov(dut:DUTF3Predecoder, grp: fc.CovGroup): - for i in range(16): - grp.add_cover_point(dut,{ - "instr is not cfi": lambda x: getattr(dut, f'io_out_pd_{i}_brType').value == 0, - "instr is branch": lambda x: getattr(dut, f'io_out_pd_{i}_brType').value == 1, - "instr is jal": lambda x: getattr(dut, f'io_out_pd_{i}_brType').value == 2, - "instr is jalr": lambda x: getattr(dut, f'io_out_pd_{i}_brType').value == 3, - },name = f'check_cfi_{i}') - - for i in range(16): - grp.add_cover_point(dut,{ - "instr is RVI.JAL and is call": lambda x: getattr(dut, f'io_out_pd_{i}_isCall').value == 1 and getattr(dut, f'io_in_instr_{i}').value & 0b1111111 == 0b1101111, - "instr is RVI.JAL and is not call or ret": lambda x: getattr(dut, f'io_out_pd_{i}_isCall').value == 0 and getattr(dut, f'io_out_pd_{i}_isRet').value == 0 and getattr(dut, f'io_in_instr_{i}').value & 0b1111111 == 0b1101111, - "instr is RVC.JAL and is not call or ret": lambda x: getattr(dut, f'io_out_pd_{i}_isCall').value == 0 and getattr(dut, f'io_out_pd_{i}_isRet').value == 0 and getattr(dut, f'io_in_instr_{i}').value & 0b11 == 0b01 and (getattr(dut, f'io_in_instr_{i}').value >> 13) == 0b101, - },name = f'check_jal_{i}') - - for i in range(16): - grp.add_cover_point(dut,{ - "instr is RVI.JALR and is call":lambda x: getattr(dut, f'io_out_pd_{i}_isCall').value == 1 and getattr(dut, f'io_in_instr_{i}').value & 0b1111111 == 0b1100111, - "instr is RVI.JALR and is ret":lambda x: getattr(dut, f'io_out_pd_{i}_isRet').value == 1 and getattr(dut, f'io_in_instr_{i}').value & 0b1111111 == 0b1100111, - "instr is RVI.JALR and is not call or ret":lambda x: getattr(dut, f'io_out_pd_{i}_isRet').value == 0 and getattr(dut, f'io_out_pd_{i}_isCall').value == 0 and getattr(dut, f'io_in_instr_{i}').value & 0b1111111 == 0b1100111, - "instr is RVC.JALR and is not call or ret":lambda x: getattr(dut, f'io_out_pd_{i}_isRet').value == 0 and getattr(dut, f'io_out_pd_{i}_isCall').value == 0 and getattr(dut, f'io_in_instr_{i}').value & 0b1111111 == 0b0000010 and (getattr(dut, f'io_in_instr_{i}').value >> 12) == 0b1001 - },name=f'check_jalr_{i}') - - for i in range(16): - grp.add_cover_point(dut,{ - "instr is RVC.JR and is ret":lambda x: getattr(dut, f'io_out_pd_{i}_isRet').value == 1 and getattr(dut, f'io_in_instr_{i}').value & 0b1111111 == 0b0000010 and (getattr(dut, f'io_in_instr_{i}').value >> 12) == 0b1000, - "instr is RVC.JR and is not call or ret":lambda x:getattr(dut, f'io_out_pd_{i}_isRet').value == 0 and getattr(dut, f'io_out_pd_{i}_isCall').value == 0 and getattr(dut, f'io_in_instr_{i}').value & 0b1111111 == 0b0000010 and (getattr(dut, f'io_in_instr_{i}').value >> 12) == 0b1000, - },name=f'check_jr_{i}') - - def _mark(name): - return module_name_with(name, "../f3predecoder_test") - - for i in range(16): - grp.mark_function(f'check_cfi_{i}',_mark(["test_cfi_checker_1_1","test_cfi_checker_1_2","test_cfi_checker_1_3"])) - grp.mark_function(f'check_jal_{i}',_mark(["test_cfi_checker_2_2_1_1","test_cfi_checker_2_2_1_2","test_cfi_checker_2_2_2"])) - grp.mark_function(f'check_jalr_{i}',_mark(["test_cfi_checker_2_3_2_1","test_cfi_checker_2_3_1_2","test_cfi_checker_2_3_1_3","test_cfi_checker_2_3_2_1"])) - grp.mark_function(f'check_jr_{i}',_mark(["test_cfi_checker_2_3_2_2_1","test_cfi_checker_2_3_2_2_2"])) - return grp - @toffee_test.fixture async def f3predecoder_env(toffee_request: toffee_test.ToffeeRequest): import asyncio dut = toffee_request.create_dut(DUTF3Predecoder) - toffee_request.add_cov_groups(init_cov(dut, grp)) start_clock(dut) predecode_env = F3PreDecoderEnv(dut) yield predecode_env diff --git a/ut_frontend/ifu/f3predecoder/test/f3predecoder_instr_gen.py b/ut_frontend/ifu/f3predecoder/test/f3predecoder_instr_gen.py deleted file mode 100644 index 73e5521..0000000 --- a/ut_frontend/ifu/f3predecoder/test/f3predecoder_instr_gen.py +++ /dev/null @@ -1,231 +0,0 @@ -import random - -class F3PredecodeInstrGen(): - def __init__(self): - self.brTypes = [] - self.isCalls = [] - self.isRets = [] - self.instrs = [] - - def clear(self): - self.brTypes = [] - self.isCalls = [] - self.isRets = [] - self.instrs = [] - - def inst_gen(self, isa = 'random', type = 'not_cfi'): - if type == 'br': - #generate br type instructions - for _ in range(16): - #rvi - opcode = 0b1100011 - funct3 = random.choice([0b000,0b001,0b100,0b101,0b110,0b111]) - rs1 = random.getrandbits(5) - rs2 = random.getrandbits(5) - instr_rvi = (random.getrandbits(7) << 25) | rs1 << 20 |\ - rs2 << 15 | funct3 << 12 | (random.getrandbits(5) << 7) |\ - opcode - - #rvc - op = 0b01 - func3 = random.choice([0b110,0b111]) - instr_rvc = func3 << 13 | (random.getrandbits(11) << 2) | op - - self.brTypes.append(1) - if isa == 'random': - self.instrs.append(random.choice([instr_rvi, instr_rvc])) - elif isa == 'rvi': - self.instrs.append(instr_rvi) - elif isa == 'rvc': - self.instrs.append(instr_rvc) - - elif type == 'jal': - #generate jal type instructions - for _ in range(16): - #rvi - opcode = 0b1101111 - instr_rvi = (random.getrandbits(25) << 7) | opcode - - #rvc - func3 = 0b101 - op = 0b01 - instr_rvc = (func3 << 13) | (random.getrandbits(11) << 2) | op - - self.brTypes.append(2) - if isa == 'random': - self.instrs.append(random.choice([instr_rvi, instr_rvc])) - elif isa == 'rvi': - self.instrs.append(instr_rvi) - elif isa == 'rvc': - self.instrs.append(instr_rvc) - - elif type == 'jalr': - #generate jalr type instructions - for _ in range(16): - #rvi - funct3 = 0b000 - opcode = 0b1100111 - instr_rvi = (random.getrandbits(17) << 25) | funct3 << 12 |\ - (random.getrandbits(5) << 7) | opcode - - #rvc - rs1 = random.getrandbits(5) | 0b1 - head = random.choice([0b1001,0b1000]) - tail = 0b00000_10 - instr_rvc = (head << 12) | (rs1 << 7) | tail - - self.brTypes.append(3) - if isa == 'random': - self.instrs.append(random.choice([instr_rvi, instr_rvc])) - elif isa == 'rvi': - self.instrs.append(instr_rvi) - elif isa == 'rvc': - self.instrs.append(instr_rvc) - - elif type == 'not_cfi': - #generate not cfi type instructions - for _ in range(16): - #rvi - opcode = random.getrandbits(7) | 0b11 - funct3 = random.getrandbits(3) - - while True: - flag1 = (opcode == 0b1100011) and (funct3 in [0b000,0b001,0b010,0b011,0b100,0b101,0b110,0b111]) - flag2 = (opcode == 0b1101111) - flag3 = (opcode == 0b1100111) and (funct3 == 0b000) - if not flag3 and not flag2 and not flag1: - break - opcode = random.getrandbits(7) | 0b11 - funct3 = random.getrandbits(3) - instr_rvi = random.getrandbits(17) << 15 | funct3 << 12 | random.getrandbits(5) << 7 | opcode - - #rvc - c_ebreak = 0b100_1_00000_00000_10 - instr_rvc = random.getrandbits(16) - while True: - op = instr_rvc & 0b11 - func3 = instr_rvc >> 13 - flag1 = (op == 0b01) and (func3 in [0b110, 0b111, 0b101]) - - j1 = instr_rvc & 0b1111111 - j2 = instr_rvc >> 12 - flag2 = (j1 == 0b0000010) and (j2 in [0b1001, 0b1000]) - - flag3 = op == 0b11 - - if not flag1 and not flag2 and not flag3: - break - instr_rvc = random.getrandbits(16) - - self.brTypes.append(0) - self.instrs.append(random.choice([instr_rvc,instr_rvi,c_ebreak])) - - return self.instrs, self.brTypes - - def ret_call_checker(self,task = '2.1.1'): - if task =='2.1.1': - self.inst_gen(type = 'not_cfi') - self.isCalls = [0 for _ in range(16)] - self.isRets = [0 for _ in range(16)] - return self.instrs, self.isCalls, self.isRets - if task == '2.1.2': - self.inst_gen(type = 'br') - self.isCalls = [0 for _ in range(16)] - self.isRets = [0 for _ in range(16)] - return self.instrs, self.isCalls, self.isRets - if task == '2.2.1.1': - def rd(): - return random.choice([1, 5]) << 7 - mask = 0b1111_1111_1111_1111_1111_0000_0111_1111 - self.inst_gen(type = 'jal', isa = 'rvi') - self.instrs = [i & mask | rd() for i in self.instrs] - self.isCalls = [1 for _ in range(16)] - self.isRets = [0 for _ in range(16)] - return self.instrs, self.isCalls, self.isRets - if task == '2.2.1.2': - def rd(): - valid_numbers = [x for x in range(33) if x not in {1, 5}] - num = random.choice(valid_numbers) - return num << 7 - mask = 0b1111_1111_1111_1111_1111_0000_0111_1111 - self.inst_gen(type = 'jal', isa = 'rvi') - self.instrs = [i & mask | rd() for i in self.instrs] - self.isCalls = [0 for _ in range(16)] - self.isRets = [0 for _ in range(16)] - return self.instrs, self.isCalls, self.isRets - if task == '2.2.2': - self.isCalls = [0 for _ in range(16)] - self.isRets = [0 for _ in range(16)] - self.inst_gen(type = 'jal', isa = 'rvc') - return self.instrs, self.isCalls, self.isRets - if task == '2.3.1.1': - def rd(): - return random.choice([1, 5]) << 7 - mask = 0b1111_1111_1111_1111_1111_0000_0111_1111 - self.inst_gen(type = 'jalr', isa = 'rvi') - self.instrs = [i & mask | rd() for i in self.instrs] - self.isCalls = [1 for _ in range(16)] - self.isRets = [0 for _ in range(16)] - return self.instrs, self.isCalls, self.isRets - - if task == '2.3.1.2': - def rs(): - return random.choice([1,5]) << 15 - def rd(): - valid_numbers = [x for x in range(32) if x not in {1, 5}] - num = random.choice(valid_numbers) - return num << 7 - mask = 0b1111_1111_1111_0000_0111_0000_0111_1111 - self.inst_gen('jalr', 'rvi') - self.inst_gen(type = 'jalr', isa = 'rvi') - self.instrs = [i & mask | rd() | rs() for i in self.instrs] - self.isCalls = [0 for _ in range(16)] - self.isRets = [1 for _ in range(16)] - return self.instrs, self.isCalls, self.isRets - - if task == '2.3.1.3': - def rd(): - valid_numbers = [x for x in range(32) if x not in {1, 5}] - num = random.choice(valid_numbers) - return num << 7 - def rs(): - valid_numbers = [x for x in range(32) if x not in {1, 5}] - num = random.choice(valid_numbers) - return num << 15 - mask = 0b1111_1111_1111_0000_0111_0000_0111_1111 - self.inst_gen('jalr', 'rvi') - self.inst_gen(type = 'jalr', isa = 'rvi') - self.instrs = [i & mask | rd() | rs() for i in self.instrs] - self.isCalls = [0 for _ in range(16)] - self.isRets = [0 for _ in range(16)] - return self.instrs, self.isCalls, self.isRets - - if task == '2.3.2.1': - self.inst_gen(type = 'jalr', isa = 'rvc') - self.instrs = [i | 1 << 12 for i in self.instrs] - self.isCalls = [1 for _ in range(16)] - self.isRets = [0 for _ in range(16)] - return self.instrs, self.isCalls, self.isRets - - if task == '2.3.2.2.1': - def rs(): - return random.choice([1,5]) << 7 - mask = 0b1110000001111111 - self.inst_gen(type = 'jalr', isa = 'rvc') - self.instrs = [i & mask | rs() for i in self.instrs] - self.isCalls = [0 for _ in range(16)] - self.isRets = [1 for _ in range(16)] - return self.instrs, self.isCalls, self.isRets - - if task == '2.3.2.2.2': - def rs(): - valid_numbers = [x for x in range(32) if x not in {1, 5}] - num = random.choice(valid_numbers) - return num << 7 - mask = 0b1110000001111111 - self.inst_gen(type = 'jalr', isa = 'rvc') - self.instrs = [i & mask | rs() for i in self.instrs] - self.isCalls = [0 for _ in range(16)] - self.isRets = [0 for _ in range(16)] - return self.instrs, self.isCalls, self.isRets - diff --git a/ut_frontend/ifu/f3predecoder/test/f3predecoder_test.py b/ut_frontend/ifu/f3predecoder/test/f3predecoder_test.py index fccc22a..fe52d21 100644 --- a/ut_frontend/ifu/f3predecoder/test/f3predecoder_test.py +++ b/ut_frontend/ifu/f3predecoder/test/f3predecoder_test.py @@ -1,184 +1,10 @@ from .f3predecoder_fixture import f3predecoder_env from ..env import F3PreDecoderEnv import toffee_test -from .f3predecoder_instr_gen import F3PredecodeInstrGen - -instrGen = F3PredecodeInstrGen() @toffee_test.testcase -async def test_cfi_checker_1_1(f3predecoder_env : F3PreDecoderEnv): - print("test_cfi_checker_1_1") - for _ in range(100): - instrGen.clear() - instrs, brTypes = instrGen.inst_gen(type='not_cfi', isa='rvc') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.brTypes == brTypes - - instrGen.clear() - instrs, brTypes = instrGen.inst_gen(type='not_cfi', isa='rvi') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.brTypes == brTypes +async def test_smoke(f3predecoder_env : F3PreDecoderEnv): + instrs = [483 for i in range(16)] - -@toffee_test.testcase -async def test_cfi_checker_1_2(f3predecoder_env : F3PreDecoderEnv): - print("test_cfi_checker_1_2") - for _ in range(100): - instrGen.clear() - instrs, brTypes = instrGen.inst_gen(type='br', isa='rvi') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.brTypes == brTypes - - instrGen.clear() - instrs, brTypes = instrGen.inst_gen(type='br', isa='rvc') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.brTypes == brTypes - -@toffee_test.testcase -async def test_cfi_checker_1_3(f3predecoder_env : F3PreDecoderEnv): - print("test_cfi_checker_1_3") - for _ in range(100): - instrGen.clear() - instrs, brTypes = instrGen.inst_gen(type='jal', isa='rvi') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.brTypes == brTypes - - instrGen.clear() - instrs, brTypes = instrGen.inst_gen(type='jal', isa='rvc') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.brTypes == brTypes - -@toffee_test.testcase -async def test_cfi_checker_1_4(f3predecoder_env : F3PreDecoderEnv): - print("test_cfi_checker_1_4") - for _ in range(100): - instrGen.clear() - instrs, brTypes = instrGen.inst_gen(type='jalr', isa='rvi') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.brTypes == brTypes - - instrGen.clear() - instrs, brTypes = instrGen.inst_gen(type='jalr', isa='rvc') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.brTypes == brTypes - -@toffee_test.testcase -async def test_ret_call_checker_2_1_1(f3predecoder_env : F3PreDecoderEnv): - #check not cfi - print("test_ret_call_checker_2_1_1") - for _ in range(100): - instrGen.clear() - instrs, isCalls, isRets = instrGen.ret_call_checker(task = '2.1.1') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.isCalls == isCalls - assert res.isRets == isRets - -@toffee_test.testcase -async def test_ret_call_checker_2_1_2(f3predecoder_env : F3PreDecoderEnv): - #check br - print("test_ret_call_checker_2_1_2") - for _ in range(100): - instrGen.clear() - instrs, isCalls, isRets = instrGen.ret_call_checker(task = '2.1.2') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.isCalls == isCalls - assert res.isRets == isRets - -@toffee_test.testcase -async def test_ret_call_checker_2_2_1_1(f3predecoder_env : F3PreDecoderEnv): - #check RVI.JAL call - print("test_ret_call_checker_2_2_1_1") - for _ in range(100): - instrGen.clear() - instrs, isCalls, isRets = instrGen.ret_call_checker(task = '2.2.1.1') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.isCalls == isCalls - assert res.isRets == isRets - -@toffee_test.testcase -async def test_ret_call_checker_2_2_1_2(f3predecoder_env : F3PreDecoderEnv): - #check RVI.JAL not call and ret - print("test_ret_call_checker_2_2_1_2") - for _ in range(100): - instrGen.clear() - instrs, isCalls, isRets = instrGen.ret_call_checker(task = '2.2.1.2') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.isCalls == isCalls - assert res.isRets == isRets - -@toffee_test.testcase -async def test_ret_call_checker_2_2_2(f3predecoder_env : F3PreDecoderEnv): - #check RVC.JAL not call and ret - print("test_ret_call_checker_2_2_2") - for _ in range(100): - instrGen.clear() - instrs, isCalls, isRets = instrGen.ret_call_checker(task = '2.2.2') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.isCalls == isCalls - assert res.isRets == isRets - -@toffee_test.testcase -async def test_ret_call_checker_2_3_1_1(f3predecoder_env : F3PreDecoderEnv): - #check RVI.JALR call - print("test_ret_call_checker_2_3_1_1") - for _ in range(100): - instrGen.clear() - instrs, isCalls, isRets = instrGen.ret_call_checker(task = '2.3.1.1') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.isCalls == isCalls - assert res.isRets == isRets - -@toffee_test.testcase -async def test_ret_call_checker_2_3_1_2(f3predecoder_env : F3PreDecoderEnv): - #check RVI.JALR ret - print("test_ret_call_checker_2_3_1_2") - for _ in range(100): - instrGen.clear() - instrs, isCalls, isRets = instrGen.ret_call_checker(task = '2.3.1.2') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.isCalls == isCalls - assert res.isRets == isRets - -@toffee_test.testcase -async def test_ret_call_checker_2_3_1_3(f3predecoder_env : F3PreDecoderEnv): - #check RVI.JALR not call and ret - print("test_ret_call_checker_2_3_1_3") - for _ in range(100): - instrGen.clear() - instrs, isCalls, isRets = instrGen.ret_call_checker(task = '2.3.1.3') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.isCalls == isCalls - assert res.isRets == isRets - -@toffee_test.testcase -async def test_ret_call_checker_2_3_2_1(f3predecoder_env: F3PreDecoderEnv): - #check RVC.JALR call - print("test_ret_call_checker_2_3_2_1") - for _ in range(100): - instrGen.clear() - instrs, isCalls, isRets = instrGen.ret_call_checker(task = '2.3.2.1') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.isCalls == isCalls - assert res.isRets == isRets - -@toffee_test.testcase -async def test_ret_call_checker_2_3_2_2_1(f3predecoder_env: F3PreDecoderEnv): - #check RVC.JR ret - print("test_ret_call_checker_2_3_2_2_1") - for _ in range(100): - instrGen.clear() - instrs, isCalls, isRets = instrGen.ret_call_checker(task = '2.3.2.2.1') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.isCalls == isCalls - assert res.isRets == isRets - -@toffee_test.testcase -async def test_ret_call_checker_2_3_2_2_2(f3predecoder_env: F3PreDecoderEnv): - #check RVC.JR not ret - print("test_ret_call_checker_2_3_2_2_2") - for _ in range(100): - instrGen.clear() - instrs, isCalls, isRets = instrGen.ret_call_checker(task = '2.3.2.2.2') - res = await f3predecoder_env.agent.f3_predecode(instrs) - assert res.isCalls == isCalls - assert res.isRets == isRets + print(await f3predecoder_env.agent.f3_predecode(instrs)) + \ No newline at end of file diff --git a/ut_frontend/ifu/predecode/agent/predecode_agent.py b/ut_frontend/ifu/predecode/agent/predecode_agent.py index ad0159f..c5e7eaf 100644 --- a/ut_frontend/ifu/predecode/agent/predecode_agent.py +++ b/ut_frontend/ifu/predecode/agent/predecode_agent.py @@ -16,16 +16,6 @@ class PreDecodeDataDef(): res = f"new instrs: {self.new_instrs}\njump offsets: {self.jmp_offsets}\nrvcs: {self.rvcs}\nvalid_starts: {self.valid_starts}\nhalf_valid_starts: {self.half_valid_starts}\n" res += f"isRets:{self.isRets}\nisCalls:{self.isCalls}\nbyTypes:{self.brTypes}" return res - def clear(self): - self.new_instrs = [] - self.jmp_offsets = [] - self.rvcs = [] - self.valid_starts = [] - self.half_valid_starts = [] - - self.isRets = [] - self.isCalls = [] - self.brTypes = [] class PreDecodeAgent(Agent): @@ -39,11 +29,10 @@ class PreDecodeAgent(Agent): async def predecode(self, instrs: list[int]) -> PreDecodeDataDef: for i in range(17): getattr(self.bundle.io._in_bits_data, f"_{i}").value = instrs[i] - #print("going to step") + print("going to step") await self.bundle.step() - #print("step over") + print("step over") ret = PreDecodeDataDef() - ret.clear() for i in range(16): ret.new_instrs.append(getattr(self.bundle.io._out._instr, f"_{i}").value) diff --git a/ut_frontend/ifu/predecode/test/predecode_fixture.py b/ut_frontend/ifu/predecode/test/predecode_fixture.py index 212fa22..fd1be4f 100644 --- a/ut_frontend/ifu/predecode/test/predecode_fixture.py +++ b/ut_frontend/ifu/predecode/test/predecode_fixture.py @@ -2,50 +2,13 @@ import toffee_test from dut.PreDecode import DUTPreDecode from ..env import PreDecodeEnv from toffee import start_clock -import toffee.funcov as fc -from comm import UT_FCOV, module_name_with - -grp = fc.CovGroup(UT_FCOV("../../CLASSIC")) - -def init_cov(dut:DUTPreDecode, grp: fc.CovGroup): - for i in range(16): - grp.add_cover_point(dut,{ - "instr is rvc:": lambda x: getattr(dut,f'io_out_pd_{i}_isRVC').value == 1, - "instr is rvi:": lambda x: getattr(dut,f'io_out_pd_{i}_isRVC').value == 0, - },name=f'check_rvc_rvi_{i}') - - for i in range(2,16): - grp.add_cover_point(dut,{ - "instr is half_valid_start:": lambda x: getattr(dut,f'io_out_hasHalfValid_{i}').value == 1, - "instr is not half_valid_start:": lambda x: getattr(dut,f'io_out_hasHalfValid_{i}').value == 0, - },name=f'check_half_valid_start_{i}') - - for i in range(1,16): - grp.add_cover_point(dut,{ - "instr is valid_starts:": lambda x: getattr(dut,f'io_out_pd_{i}_valid').value == 1, - "instr is not valid_starts:": lambda x: getattr(dut,f'io_out_pd_{i}_valid').value == 0, - },name=f'check_valid_start_{i}') - - - - def _mark(name): - return module_name_with(name, "../predecode_test") - - for i in range(16): - grp.mark_function(f'check_rvc_rvi_{i}',_mark(["test_rvc_rvi_checker_2_1_2","test_rvc_rvi_checker_2_1_1"])) - for i in range(2,16): - grp.mark_function(f'check_half_valid_start_{i}',_mark(["test_precoding_checker_2_3_2"])) - for i in range(1,16): - grp.mark_function(f'check_valid_start_{i}',_mark(["test_precoding_checker_2_3_1"])) - - return grp @toffee_test.fixture async def predecode_env(toffee_request: toffee_test.ToffeeRequest): import asyncio + # version_check() dut = toffee_request.create_dut(DUTPreDecode) - toffee_request.add_cov_groups(init_cov(dut, grp)) start_clock(dut) predecode_env = PreDecodeEnv(dut) yield predecode_env @@ -57,4 +20,4 @@ async def predecode_env(toffee_request: toffee_test.ToffeeRequest): try: await task except asyncio.CancelledError: - break + break \ No newline at end of file diff --git a/ut_frontend/ifu/predecode/test/predecode_instr_gen.py b/ut_frontend/ifu/predecode/test/predecode_instr_gen.py deleted file mode 100644 index b8eb7ac..0000000 --- a/ut_frontend/ifu/predecode/test/predecode_instr_gen.py +++ /dev/null @@ -1,168 +0,0 @@ -import random - -class PreDecodeInstrGen(): - def __init__(self): - self.instrs = [] - self.new_instrs = [] - self.jmp_offsets = [] - self.rvcs = [] - self.valid_starts = [] - self.half_valid_starts = [] - - self.isRets = [] - self.isCalls = [] - self.brTypes = [] - - def clear(self): - self.instrs = [] - self.new_instrs = [] - self.jmp_offsets = [] - self.rvcs = [] - self.valid_starts = [] - self.half_valid_starts = [] - - self.isRets = [] - self.isCalls = [] - self.brTypes = [] - - def random_instrs(self): - #genetare random instructions - self.instrs = [random.getrandbits(16) for _ in range(17)] - self.new_instrs = [self.instrs[i+1] << 16 | self.instrs[i] for i in range(16)] - return self.instrs, self.new_instrs - def instr_gen(self, type='random', isa='rvi'): - if type == 'random': - instr_rvi = random.getrandbits(32) | 0b11 - instr_rvc = random.getrandbits(14) << 2 | random.choice([0b00,0b01,0b10]) - return instr_rvi if isa == 'rvi' else instr_rvc - if type == 'j': - opcode = 0b1101111 - instr_rvi = (random.getrandbits(25) << 7) | opcode - func3 = random.choice([0b101]) - op = 0b01 - instr_rvc = (func3) << 13 | (random.getrandbits(11) << 2) | op - - return instr_rvi if isa == 'rvi' else instr_rvc - - if type == 'br': - instr_rvi = 0 #instr_rvi is aborted - func3 = random.choice([0b110,0b111]) - op = 0b01 - instr_rvc = func3 << 13 | random.getrandbits(11) << 2 | op - return instr_rvi if isa == 'rvi' else instr_rvc - - if type == 'jalr': - instr_rvc = (0b1101) << 12 | random.getrandbits(5) << 7 | 0b0000010 - instr_rvi = random.getrandbits(1) << 15 | (0b000) << 12 | random.getrandbits(5) << 7 | 0b1100111 - return instr_rvi - if type == 'jal': - instr_rvi = random.getrandbits(9) << 7 | 0b1101111 - return instr_rvi - - - def precoding_checker(self, task = '2.1.1'): - if task == '2.1.1': - self.instrs = [self.instr_gen(type = 'random', isa = 'rvc') for _ in range(17)] - self.rvcs = [1 for _ in range(16)] - return self.instrs, self.rvcs - if task == '2.1.2': - self.instrs = [random.getrandbits(16) | 0b11 for _ in range(17)] - self.rvcs = [0 for _ in range(16)] - return self.instrs, self.rvcs - - if task == '2.2.1': - self.instrs = [self.instr_gen(type = 'j', isa = 'rvc') for _ in range(17)] - def offset(instr): - mask = 0b11111111111 - offset = (instr >> 2) & mask - o11 = (offset >> 10) & 1 - o4 = (offset >> 9) & 1 - o98 = (offset >> 7) & 0b11 - o10 = (offset >> 6) & 1 - o6 = (offset >> 5) & 1 - o7 = (offset >> 4) & 1 - o31 = (offset >> 1) & 0b111 - o5 = (offset >> 0) & 1 - offset = (o11 << 11) | (o4 << 4) | (o98 << 8) | (o10 << 10) | (o6 << 6) | (o7 << 7) | (o31 << 1) | (o5 << 5) - offset = offset if o11 == 0 else (offset | (0b1111) << 12) & 0xFFFF - return offset - self.jmp_offsets = [offset(i) for i in self.instrs] - self.jmp_offsets.pop() - return self.instrs, self.jmp_offsets - if task == '2.2.2': - self.instrs = [random.getrandbits(9) << 7 | 0b1101111 for _ in range(17)] - self.new_instrs = [self.instrs[i+1] << 16 | self.instrs[i] for i in range(16)] - def offset(instr): - offset = instr >> 12 - o20 = (offset >> 19) & 1 - o101 = (offset >> 9) & 0b1111111111 - o11 = (offset >> 8) & 1 - o1912 = offset & 0b11111111 - offset = (o20 << 20) | (o101 << 1) | (o11 << 11) | (o1912 << 12) - offset = offset & 0xFFFFFFFF if o20 == 0 else (offset | (0xFFFFFF) << 21) & 0xFFFFFFFF - return offset - self.jmp_offsets = [offset(i) for i in self.new_instrs] - return self.instrs, self.jmp_offsets - - if task == '2.2.3': - self.instrs = [self.instr_gen(type = 'br', isa = 'rvc') for _ in range(17)] - def offset(instr): - o5 = (instr >> 2) & 1 - o21 = (instr >> 3) & 0b11 - o76 = (instr >> 5) & 0b11 - o43 = (instr >> 10) & 0b11 - o8 = (instr >> 12) & 1 - offset = o5 << 5 | o21 << 1 | o76 << 6 | o43 << 3 | o8 << 8 - offset = offset if o8 == 0 else (offset | 0xFF << 9) & 0xFFFF - return offset - self.jmp_offsets = [offset(i) for i in self.instrs] - self.jmp_offsets.pop() - return self.instrs, self.jmp_offsets - if task == '2.2.4': - def offset(instr): - o12 = (instr >> 31) & 1 - o105 = (instr >> 25) & 0b111111 - o11 = (instr >> 7) & 1 - o41 = (instr >> 8) & 0b1111 - offset = o12 << 12 | o105 << 5 | o11 << 11 | o41 << 1 - offset = offset if o12 == 0 else (offset | 0xFFFFFFF << 13) & 0xFFFFFFFF - return offset - self.instrs = [random.getrandbits(5) << 7 | random.getrandbits(1) << 15 | 0b1100011 | random.choice([0b000,0b001,0b100,0b101,0b110,0b111]) << 12 for _ in range(17)] - self.new_instrs = [self.instrs[i+1] << 16 | self.instrs[i] for i in range(16)] - self.jmp_offsets = [offset(i) for i in self.new_instrs] - return self.instrs, self.jmp_offsets - - if task == '3.1': - self.instrs = [random.getrandbits(16) for _ in range(17)] - self.new_instrs = [self.instrs[i+1] << 16 | self.instrs[i] for i in range(16)] - mask = 0b11 - flag = (self.new_instrs[0] & mask) == 0b11 - self.valid_starts.append(1) - - for i in range(1, 16): - if flag: - self.valid_starts.append(0) - flag = False - else: - self.valid_starts.append(1) - flag = (self.new_instrs[i] & mask) == 0b11 - return self.instrs, self.valid_starts - - if task == '3.2': - self.instrs = [random.getrandbits(16) for _ in range(17)] - self.new_instrs = [self.instrs[i+1] << 16 | self.instrs[i] for i in range(16)] - mask = 0b11 - self.half_valid_starts.append(0) # i == 0 - self.half_valid_starts.append(1) # i == 1 - flag = (self.new_instrs[1] & mask) == 0b11 - - for i in range(2, 16): - if flag: - self.half_valid_starts.append(0) - flag = False - else: - self.half_valid_starts.append(1) - flag = (self.new_instrs[i] & mask) == 0b11 - return self.instrs, self.half_valid_starts - - diff --git a/ut_frontend/ifu/predecode/test/predecode_test.py b/ut_frontend/ifu/predecode/test/predecode_test.py index 51b898d..69ae09c 100644 --- a/ut_frontend/ifu/predecode/test/predecode_test.py +++ b/ut_frontend/ifu/predecode/test/predecode_test.py @@ -1,112 +1,10 @@ import toffee_test from .predecode_fixture import predecode_env from ..env import PreDecodeEnv -from .predecode_instr_gen import PreDecodeInstrGen - -instrGen = PreDecodeInstrGen() - @toffee_test.testcase -async def test_smoke(predecode_env: PreDecodeEnv): +async def test_smoke(predecode_env : PreDecodeEnv): fake_instrs = [54541 for i in range(17)] res = await predecode_env.agent.predecode(fake_instrs) - - -@toffee_test.testcase -async def test_splice_checker(predecode_env: PreDecodeEnv): - # 指令拼接测试 - print("test_splice_checker") - for _ in range(100): - instrGen.clear() - instrs, new_instrs = instrGen.random_instrs() - res = await predecode_env.agent.predecode(instrs) - assert res.new_instrs == new_instrs - - -@toffee_test.testcase -async def test_precoding_checker_2_1_1(predecode_env: PreDecodeEnv): - ##RVC判定 传入RVC指令 - print("test_precoding_checker_2_1_1") - for _ in range(100): - instrGen.clear() - instrs, rvcs = instrGen.precoding_checker(task="2.1.1") - res = await predecode_env.agent.predecode(instrs) - assert res.rvcs == rvcs - - -@toffee_test.testcase -async def test_precoding_checker_2_1_2(predecode_env: PreDecodeEnv): - # RVI判定 传入RVI指令 - print("test_precoding_checker_2_1_2") - for _ in range(100): - instrGen.clear() - instrs, rvcs = instrGen.precoding_checker(task="2.1.2") - res = await predecode_env.agent.predecode(instrs) - assert res.rvcs == rvcs - - -@toffee_test.testcase -async def test_precoding_checker_2_2_1(predecode_env: PreDecodeEnv): - ##RVC.J计算 offset - print("test_precoding_checker_2_2_1") - for _ in range(100): - instrGen.clear() - instrs, jmp_offsets = instrGen.precoding_checker(task="2.2.1") - res = await predecode_env.agent.predecode(instrs) - assert [i & 0xFFFF for i in res.jmp_offsets] == jmp_offsets - - -@toffee_test.testcase -async def test_precoding_checker_2_2_2(predecode_env: PreDecodeEnv): - ##RVI.J计算 offset - print("test_precoding_checker_2_2_2") - for _ in range(100): - instrGen.clear() - instrs, jmp_offsets = instrGen.precoding_checker(task="2.2.2") - res = await predecode_env.agent.predecode(instrs) - assert [i & 0xFFFFFFFF for i in res.jmp_offsets] == jmp_offsets - - -@toffee_test.testcase -async def test_precoding_checker_2_2_3(predecode_env: PreDecodeEnv): - # RVC.BR计算 offset - print("test_precoding_checker_2_2_3") - for _ in range(100): - instrGen.clear() - instrs, jmp_offsets = instrGen.precoding_checker(task="2.2.3") - res = await predecode_env.agent.predecode(instrs) - assert [i & 0xFFFF for i in res.jmp_offsets] == jmp_offsets - - -@toffee_test.testcase -async def test_precoding_checker_2_2_4(predecode_env: PreDecodeEnv): - # RVI.BR计算 offset - print("test_precoding_checker_2_2_4") - for _ in range(100): - instrGen.clear() - instrs, jmp_offsets = instrGen.precoding_checker(task="2.2.4") - res = await predecode_env.agent.predecode(instrs) - assert [i & 0xFFFFFFFF for i in res.jmp_offsets] == jmp_offsets - - -@toffee_test.testcase -async def test_precoding_checker_3_1(predecode_env: PreDecodeEnv): - # 有效指令开始向量计算1 - print("test_precoding_checker_3_1") - for _ in range(100): - instrGen.clear() - instrs, valid_starts = instrGen.precoding_checker(task="3.1") - res = await predecode_env.agent.predecode(instrs) - assert res.valid_starts == valid_starts - - -@toffee_test.testcase -async def test_precoding_checker_3_2(predecode_env: PreDecodeEnv): - # 有效指令开始向量计算2 - print("test_precoding_checker_3_2") - for _ in range(100): - instrGen.clear() - instrs, half_valid_starts = instrGen.precoding_checker(task="3.2") - res = await predecode_env.agent.predecode(instrs) - assert res.half_valid_starts == half_valid_starts + print(res)