diff --git a/ut_frontend/itlb/classical_version/base_components.py b/ut_frontend/itlb/classical_version/base_components.py new file mode 100644 index 00000000..545819b6 --- /dev/null +++ b/ut_frontend/itlb/classical_version/base_components.py @@ -0,0 +1,333 @@ +################################################################################ +# hit +################################################################################ + +def hit_nonStage_requestor_0(tlb) -> dict: + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_nostage_hit(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 1 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 0 + tlb.requestor_0.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_0.resp.paddr_0.value == ((signals["ppn"] << 12) | signals["offset"])) + assert (tlb.requestor_0.resp.miss.value == 0) + # return signals + return signals + + +def hit_nonStage_requestor_1(tlb) -> dict: + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_nostage_hit(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 1 + tlb.requestor_2.req.valid.value = 0 + tlb.requestor_1.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_1.resp.paddr_0.value == ((signals["ppn"] << 12) | signals["offset"])) + assert (tlb.requestor_1.resp.miss.value == 0) + # return signals + return signals + + +def hit_nonStage_requestor_2(tlb) -> dict: + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_nostage_hit(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 1 + tlb.ctrl.io_requestor_2_resp_ready.value = 1 + tlb.requestor_2.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_2.resp.paddr_0.value == ((signals["ppn"] << 12) | signals["offset"])) + assert (tlb.requestor_2.resp.miss.value == 0) + # return signals + return signals + + +################################################################################ +# miss +################################################################################ + +# no stage +def miss_nonStage_requestor_0(tlb) -> dict: + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_nostage_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 1 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 0 + tlb.requestor_0.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_0.resp.miss.value == 1) + # return signals + return signals + + +def miss_nonStage_requestor_1(tlb) -> dict: + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_nostage_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 1 + tlb.requestor_2.req.valid.value = 0 + tlb.requestor_1.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_1.resp.miss.value == 1) + # return signals + return signals + + +def miss_nonStage_requestor_2(tlb) -> dict: + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_nostage_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 1 + tlb.ctrl.io_requestor_2_resp_ready.value = 1 + tlb.requestor_2.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_2.resp.miss.value == 1) + # return signals + return signals + + +# only stage 1 +def miss_onlyStage1_requestor_0(tlb) -> dict: + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_onlyStage1_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 1 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 0 + tlb.requestor_0.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_0.resp.miss.value == 1) + # return signals + return signals + + +def miss_onlyStage1_requestor_1(tlb) -> dict: + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_onlyStage1_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 1 + tlb.requestor_2.req.valid.value = 0 + tlb.requestor_1.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_1.resp.miss.value == 1) + # return signals + return signals + + +def miss_onlyStage1_requestor_2(tlb) -> dict: + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_onlyStage1_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 1 + tlb.ctrl.io_requestor_2_resp_ready.value = 1 + tlb.requestor_2.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_2.resp.miss.value == 1) + # return signals + return signals + + +# only stage 2 +def miss_onlyStage2_requestor_0(tlb) -> dict: + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_onlyStage2_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 1 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 0 + tlb.requestor_0.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_0.resp.miss.value == 1) + # return signals + return signals + + +def miss_onlyStage2_requestor_1(tlb) -> dict: + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_onlyStage2_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 1 + tlb.requestor_2.req.valid.value = 0 + tlb.requestor_1.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_1.resp.miss.value == 1) + # return signals + return signals + + +def miss_onlyStage2_requestor_2(tlb) -> dict: + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_onlyStage2_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 1 + tlb.ctrl.io_requestor_2_resp_ready.value = 1 + tlb.requestor_2.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_2.resp.miss.value == 1) + # return signals + return signals + + +# all stage +def miss_allStage_requestor_0(tlb) -> dict: + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_allStage_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 1 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 0 + tlb.requestor_0.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_0.resp.miss.value == 1) + # return signals + return signals + + +def miss_allStage_requestor_1(tlb) -> dict: + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_allStage_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 1 + tlb.requestor_2.req.valid.value = 0 + tlb.requestor_1.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_1.resp.miss.value == 1) + # return signals + return signals + + +def miss_allStage_requestor_2(tlb) -> dict: + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_allStage_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 1 + tlb.ctrl.io_requestor_2_resp_ready.value = 1 + tlb.requestor_2.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_2.resp.miss.value == 1) + # return signals + return signals diff --git a/ut_frontend/itlb/classical_version/env/itlb_utils.py b/ut_frontend/itlb/classical_version/env/itlb_utils.py new file mode 100644 index 00000000..f7c8844a --- /dev/null +++ b/ut_frontend/itlb/classical_version/env/itlb_utils.py @@ -0,0 +1,2 @@ +def other_than(value): + return value ^ 1 diff --git a/ut_frontend/itlb/classical_version/env/itlb_wrapper.py b/ut_frontend/itlb/classical_version/env/itlb_wrapper.py index a833cb23..a3e36522 100644 --- a/ut_frontend/itlb/classical_version/env/itlb_wrapper.py +++ b/ut_frontend/itlb/classical_version/env/itlb_wrapper.py @@ -20,6 +20,7 @@ import toffee.funcov as fc from dut.TLB import * +from ut_frontend.itlb.classical_version.env.itlb_utils import other_than from .itlb_consts import * from queue import Queue from comm import get_version_checker, get_out_dir, UT_FCOV @@ -280,6 +281,14 @@ def reset(self): self.dut.reset.value = 0 # print(">>> RESET FINISHED !") + def cleanup_requestor(self, requestor: int): + self.reset() + self.flushPipe[requestor].value = 1 + self.dut.Step() + self.flushPipe[requestor].value = 0 + self.dut.Step(2) + # print(f">>> CLEANUP requestor_{i} FINISHED !") + def gene_rand_TLBreq(self): """ generate random TLB request @@ -288,6 +297,23 @@ def gene_rand_TLBreq(self): req_vaddr = random.randint(0, 2 ** 50 - 1) return req_valid, req_vaddr + def gene_rand_TLBsignal_batch(self) -> dict: + vaddr = random.randint(0, 2 ** 50 - 1) + asid = random.randint(0, 2 ** 16 - 1) + vpn = vaddr >> 12 + offset = vaddr & 0xfff + ppn = random.randint(0, 2 ** 36 - 1) + ppn_low = [random.randint(0, 2 ** 3 - 1) for _ in range(8)] + valid_idx = [random.choice([0, 1]) for _ in range(8)] + return { + "asid": asid, + "vpn": vpn, + "offset": offset, + "ppn": ppn, + "ppn_low": ppn_low, + "valid_idx": valid_idx, + } + def rand_req0(self): """ send random TLB request from requestor0 @@ -414,6 +440,136 @@ def rand_ptw_resp(self, vpn, asid, s2xlate): # TODO return randPPN + def init_dut_for_nostage_hit(self, vpn, asid, ppn, ppn_low): + # prepare data + addr_low = vpn & 0b111 + ## ctrl signals + self.ctrl.io_ptw_resp_valid.value = 1 + self.ctrl.io_ptw_resp_bits_s2xlate.value = 0b00 + # initialize conditions + self.ptw_resp_s1.entry_tag.value = vpn >> 3 + self.ptw_resp_s1.entry_asid.value = asid + self.ptw_resp_s1.entry_vmid.value = DONTCARE + self.ptw_resp_s1.entry_n.value = UNUSED0 + self.ptw_resp_s1.entry_pbmt.value = UNUSED0 + self.ptw_resp_s1.entry_perm_d.value = UNUSED0 + self.ptw_resp_s1.entry_perm_a.value = UNUSED0 + self.ptw_resp_s1.entry_perm_g.value = UNUSED0 + self.ptw_resp_s1.entry_perm_u.value = UNUSED0 + self.ptw_resp_s1.entry_perm_x.value = UNUSED1 + self.ptw_resp_s1.entry_perm_w.value = UNUSED0 + self.ptw_resp_s1.entry_perm_r.value = UNUSED0 + self.ptw_resp_s1.entry_level.value = UNUSED0 + self.ptw_resp_s1.entry_v.value = 1 + self.ptw_resp_s1.entry_ppn.value = ppn >> 3 + self.ptw_resp_s1.addr_low.value = addr_low + ppn_low_dict = { + 0: self.ptw_resp_s1.ppn_low_0, + 1: self.ptw_resp_s1.ppn_low_1, + 2: self.ptw_resp_s1.ppn_low_2, + 3: self.ptw_resp_s1.ppn_low_3, + 4: self.ptw_resp_s1.ppn_low_4, + 5: self.ptw_resp_s1.ppn_low_5, + 6: self.ptw_resp_s1.ppn_low_6, + 7: self.ptw_resp_s1.ppn_low_7 + } + valididx_dict = { + 0: self.ptw_resp_s1.valididx_0, + 1: self.ptw_resp_s1.valididx_1, + 2: self.ptw_resp_s1.valididx_2, + 3: self.ptw_resp_s1.valididx_3, + 4: self.ptw_resp_s1.valididx_4, + 5: self.ptw_resp_s1.valididx_5, + 6: self.ptw_resp_s1.valididx_6, + 7: self.ptw_resp_s1.valididx_7 + } + pteidx_dict = { + 0: self.ptw_resp_s1.pteidx_0, + 1: self.ptw_resp_s1.pteidx_1, + 2: self.ptw_resp_s1.pteidx_2, + 3: self.ptw_resp_s1.pteidx_3, + 4: self.ptw_resp_s1.pteidx_4, + 5: self.ptw_resp_s1.pteidx_5, + 6: self.ptw_resp_s1.pteidx_6, + 7: self.ptw_resp_s1.pteidx_7 + } + for i in range(8): + if i == addr_low: + ppn_low_dict[i].value = ppn & 0b111 + valididx_dict[i].value = 1 + else: + ppn_low_dict[i].value = ppn_low[i] + valididx_dict[i].value = 0 + pteidx_dict[addr_low].value = 1 + self.ptw_resp_s1.pf.value = UNUSED0 + self.ptw_resp_s1.af.value = UNUSED0 + + + def init_dut_for_nostage_miss(self, vpn, asid, ppn, ppn_low): + # prepare data + addr_low = vpn & 0b111 + ## ctrl signals + self.ctrl.io_ptw_resp_valid.value = 1 + self.ctrl.io_ptw_resp_bits_s2xlate.value = 0b00 + # initialize conditions + self.ptw_resp_s1.entry_tag.value = other_than(vpn >> 3) + self.ptw_resp_s1.entry_asid.value = asid + self.ptw_resp_s1.entry_vmid.value = DONTCARE + self.ptw_resp_s1.entry_n.value = UNUSED0 + self.ptw_resp_s1.entry_pbmt.value = UNUSED0 + self.ptw_resp_s1.entry_perm_d.value = UNUSED0 + self.ptw_resp_s1.entry_perm_a.value = UNUSED0 + self.ptw_resp_s1.entry_perm_g.value = UNUSED0 + self.ptw_resp_s1.entry_perm_u.value = UNUSED0 + self.ptw_resp_s1.entry_perm_x.value = UNUSED1 + self.ptw_resp_s1.entry_perm_w.value = UNUSED0 + self.ptw_resp_s1.entry_perm_r.value = UNUSED0 + self.ptw_resp_s1.entry_level.value = UNUSED0 + self.ptw_resp_s1.entry_v.value = 1 + self.ptw_resp_s1.entry_ppn.value = ppn >> 3 + self.ptw_resp_s1.addr_low.value = addr_low + ppn_low_dict = { + 0: self.ptw_resp_s1.ppn_low_0, + 1: self.ptw_resp_s1.ppn_low_1, + 2: self.ptw_resp_s1.ppn_low_2, + 3: self.ptw_resp_s1.ppn_low_3, + 4: self.ptw_resp_s1.ppn_low_4, + 5: self.ptw_resp_s1.ppn_low_5, + 6: self.ptw_resp_s1.ppn_low_6, + 7: self.ptw_resp_s1.ppn_low_7 + } + valididx_dict = { + 0: self.ptw_resp_s1.valididx_0, + 1: self.ptw_resp_s1.valididx_1, + 2: self.ptw_resp_s1.valididx_2, + 3: self.ptw_resp_s1.valididx_3, + 4: self.ptw_resp_s1.valididx_4, + 5: self.ptw_resp_s1.valididx_5, + 6: self.ptw_resp_s1.valididx_6, + 7: self.ptw_resp_s1.valididx_7 + } + pteidx_dict = { + 0: self.ptw_resp_s1.pteidx_0, + 1: self.ptw_resp_s1.pteidx_1, + 2: self.ptw_resp_s1.pteidx_2, + 3: self.ptw_resp_s1.pteidx_3, + 4: self.ptw_resp_s1.pteidx_4, + 5: self.ptw_resp_s1.pteidx_5, + 6: self.ptw_resp_s1.pteidx_6, + 7: self.ptw_resp_s1.pteidx_7 + } + for i in range(8): + if i == addr_low: + ppn_low_dict[i].value = ppn & 0b111 + valididx_dict[i].value = 1 + else: + ppn_low_dict[i].value = ppn_low[i] + valididx_dict[i].value = 0 + pteidx_dict[addr_low].value = 1 + self.ptw_resp_s1.pf.value = UNUSED0 + self.ptw_resp_s1.af.value = UNUSED0 + + class TLBrwWrapper(toffee.Bundle): """ Support TLB read/write only. diff --git a/ut_frontend/itlb/classical_version/test_tlb_receive_ptw_resp.py b/ut_frontend/itlb/classical_version/test_tlb_receive_ptw_resp.py index 23aee122..e083fe68 100644 --- a/ut_frontend/itlb/classical_version/test_tlb_receive_ptw_resp.py +++ b/ut_frontend/itlb/classical_version/test_tlb_receive_ptw_resp.py @@ -13,7 +13,14 @@ #**************************************************************************************/ from .env import * -import inspect + +from ut_frontend.itlb.classical_version.base_components import hit_nonStage_requestor_0, \ + hit_nonStage_requestor_1, hit_nonStage_requestor_2, \ + miss_nonStage_requestor_0, miss_nonStage_requestor_1, \ + miss_nonStage_requestor_2 + +ROUND_NUM = 1000 +ROUND_SIZE = 30 ### CASE EXAMPLE # Running the following test case will show a pass: @@ -64,4 +71,307 @@ def test_receive_ptw_resp_nonstage(tlb_fixture): assert(tlb.requestor_0.resp.paddr_0.value == ((ppn << 12) | offset)) assert(tlb.requestor_0.resp.miss.value == 0) # reset - tlb.reset() \ No newline at end of file + tlb.reset() + + +def test_receive_ptw_resp_nonstage_single_hit_icache(tlb_fixture): + """ + no stage,单次hit + """ + # connect to fixture + tlb = tlb_fixture + tlb.set_default_value() + # reset + tlb.reset() + + # add clock + tlb.dut.xclock.StepRis(lambda _: g.sample()) + + for _ in range(ROUND_NUM): + for _ in range(ROUND_SIZE): + hit_nonStage_requestor_0(tlb) + tlb.cleanup_requestor(0) + + for _ in range(ROUND_NUM): + for _ in range(ROUND_SIZE): + hit_nonStage_requestor_1(tlb) + tlb.cleanup_requestor(1) + + +def test_receive_ptw_resp_nonstage_single_hit_ifu(tlb_fixture): + """ + no stage,单次hit + """ + # connect to fixture + tlb = tlb_fixture + tlb.set_default_value() + # reset + tlb.reset() + + # add clock + tlb.dut.xclock.StepRis(lambda _: g.sample()) + + for _ in range(ROUND_NUM): + for _ in range(ROUND_SIZE): + hit_nonStage_requestor_2(tlb) + tlb.cleanup_requestor(2) + + +def test_receive_ptw_resp_nonstage_single_miss_icache(tlb_fixture): + """ + no stage,单次miss + """ + # connect to fixture + tlb = tlb_fixture + tlb.set_default_value() + # reset + tlb.reset() + + # add clock + tlb.dut.xclock.StepRis(lambda _: g.sample()) + + for _ in range(ROUND_NUM): + for _ in range(ROUND_SIZE): + miss_nonStage_requestor_0(tlb) + tlb.cleanup_requestor(0) + + for _ in range(ROUND_NUM): + for _ in range(ROUND_SIZE): + miss_nonStage_requestor_1(tlb) + tlb.cleanup_requestor(1) + + +def test_receive_ptw_resp_nonstage_single_miss_ifu(tlb_fixture): + """ + no stage,单次miss + """ + # connect to fixture + tlb = tlb_fixture + tlb.set_default_value() + # reset + tlb.reset() + + # add clock + tlb.dut.xclock.StepRis(lambda _: g.sample()) + + for _ in range(ROUND_NUM): + for _ in range(ROUND_SIZE): + miss_nonStage_requestor_2(tlb) + tlb.cleanup_requestor(2) # cleanup requestor 2 after each missing + + +def test_receive_ptw_resp_nonstage_valid_icache(tlb_fixture): + """ + no stage,valid有效性 + """ + # connect to fixture + tlb = tlb_fixture + tlb.set_default_value() + # reset + tlb.reset() + + # add clock + tlb.dut.xclock.StepRis(lambda _: g.sample()) + + for _ in range(ROUND_NUM): + for _ in range(ROUND_SIZE): + _do_test_receive_ptw_resp_nonstage_valid_requestor_0(tlb) + tlb.cleanup_requestor(0) + _do_test_receive_ptw_resp_nonstage_invalid_requestor_0(tlb) + tlb.cleanup_requestor(0) + + for _ in range(ROUND_NUM): + for _ in range(ROUND_SIZE): + _do_test_receive_ptw_resp_nonstage_valid_requestor_1(tlb) + tlb.cleanup_requestor(1) + _do_test_receive_ptw_resp_nonstage_invalid_requestor_1(tlb) + tlb.cleanup_requestor(1) + + +def test_receive_ptw_resp_nonstage_valid_ifu(tlb_fixture): + """ + no stage,valid-ready有效性 + """ + # connect to fixture + tlb = tlb_fixture + tlb.set_default_value() + # reset + tlb.reset() + + # add clock + tlb.dut.xclock.StepRis(lambda _: g.sample()) + + for _ in range(ROUND_NUM): + for _ in range(ROUND_SIZE): + _do_test_receive_ptw_resp_nonstage_valid_ready_requestor_2(tlb) + tlb.cleanup_requestor(2) + _do_test_receive_ptw_resp_nonstage_invalid_ready_requestor_2(tlb) + tlb.cleanup_requestor(2) + _do_test_receive_ptw_resp_nonstage_valid_busy_requestor_2(tlb) + tlb.cleanup_requestor(2) + _do_test_receive_ptw_resp_nonstage_invalid_busy_requestor_2(tlb) + tlb.cleanup_requestor(2) + + +def _do_test_receive_ptw_resp_nonstage_valid_requestor_0(tlb): + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_nostage_hit(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 1 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 0 + tlb.requestor_0.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_0.resp.paddr_0.value == ((signals["ppn"] << 12) | signals["offset"])) + assert (tlb.requestor_0.resp.miss.value == 0) + + +def _do_test_receive_ptw_resp_nonstage_invalid_requestor_0(tlb): + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_nostage_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 0 + tlb.requestor_0.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result, no hit anyway + assert not (tlb.requestor_0.resp.miss.value == 0 and + tlb.requestor_0.resp.paddr_0.value == ((signals["ppn"] << 12) | signals["offset"])) + + +def _do_test_receive_ptw_resp_nonstage_valid_requestor_1(tlb): + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_nostage_hit(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 1 + tlb.requestor_2.req.valid.value = 0 + tlb.requestor_1.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_1.resp.paddr_0.value == ((signals["ppn"] << 12) | signals["offset"])) + assert (tlb.requestor_1.resp.miss.value == 0) + + +def _do_test_receive_ptw_resp_nonstage_invalid_requestor_1(tlb): + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_nostage_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 0 + tlb.requestor_1.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result, no hit anyway + assert not (tlb.requestor_1.resp.miss.value == 0 and + tlb.requestor_1.resp.paddr_0.value == ((signals["ppn"] << 12) | signals["offset"])) + + +def _do_test_receive_ptw_resp_nonstage_valid_ready_requestor_2(tlb): + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_nostage_hit(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 1 + tlb.ctrl.io_requestor_2_resp_ready.value = 1 + tlb.requestor_2.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result + assert (tlb.requestor_2.resp.paddr_0.value == ((signals["ppn"] << 12) | signals["offset"])) + assert (tlb.requestor_2.resp.miss.value == 0) + + +def _do_test_receive_ptw_resp_nonstage_invalid_ready_requestor_2(tlb): + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_nostage_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 0 + tlb.ctrl.io_requestor_2_resp_ready.value = 1 + tlb.requestor_2.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result, no hit anyway + assert not (tlb.requestor_2.resp.miss.value == 0 and + tlb.requestor_2.resp.paddr_0.value == ((signals["ppn"] << 12) | signals["offset"])) + + +def _do_test_receive_ptw_resp_nonstage_valid_busy_requestor_2(tlb): + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_nostage_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 1 + tlb.ctrl.io_requestor_2_resp_ready.value = 0 + tlb.requestor_2.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result, no hit anyway + assert not (tlb.requestor_2.resp.miss.value == 0 and + tlb.requestor_2.resp.paddr_0.value == ((signals["ppn"] << 12) | signals["offset"])) + + +def _do_test_receive_ptw_resp_nonstage_invalid_busy_requestor_2(tlb): + # generate signals + signals = tlb.gene_rand_TLBsignal_batch() + # initialize dut with signals + tlb.init_dut_for_nostage_miss(signals["vpn"], signals["asid"], signals["ppn"], signals["ppn_low"]) + tlb.csr.satp.asid.value = signals["asid"] + # step to next cycle + tlb.dut.Step() + # switch requestor + tlb.requestor_0.req.valid.value = 0 + tlb.requestor_1.req.valid.value = 0 + tlb.requestor_2.req.valid.value = 0 + tlb.ctrl.io_requestor_2_resp_ready.value = 0 + tlb.requestor_2.req.bits_vaddr.value = (signals["vpn"] << 12) | signals["offset"] + # step to next cycle + tlb.dut.Step(2) + # assert result, no hit anyway + assert not (tlb.requestor_2.resp.miss.value == 0 and + tlb.requestor_2.resp.paddr_0.value == ((signals["ppn"] << 12) | signals["offset"]))