From a3d13717c6e0bc8bdc4c042eacb056482e7b2f00 Mon Sep 17 00:00:00 2001 From: Daniel Benusovich Date: Tue, 19 Mar 2019 21:55:46 -0700 Subject: [PATCH] Add PteEntry parser to centralize Page Table Entry parsing --- TLB/src/PteEntry.py | 36 +++++++++++++ TLB/test/test_pte_entry.py | 101 +++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+) create mode 100644 TLB/src/PteEntry.py create mode 100644 TLB/test/test_pte_entry.py diff --git a/TLB/src/PteEntry.py b/TLB/src/PteEntry.py new file mode 100644 index 00000000..249251e8 --- /dev/null +++ b/TLB/src/PteEntry.py @@ -0,0 +1,36 @@ +from nmigen import Module, Signal +from nmigen.cli import main + +class PteEntry(): + def __init__(self, asid_size, pte_size): + # Internal + self.asid_start = pte_size + self.asid_end = pte_size + asid_size + + # Input + self.i = Signal(asid_size + pte_size) + + # Output + self.d = Signal(1) # Dirty bit (From pte) + self.a = Signal(1) # Accessed bit (From pte) + self.g = Signal(1) # Global Access (From pte) + self.u = Signal(1) # User Mode (From pte) + self.xwr = Signal(3) # Execute Read Write (From pte) + self.v = Signal(1) # Valid (From pte) + self.asid = Signal(asid_size) # Associated Address Space IDentifier + self.pte = Signal(pte_size) # Full Page Table Entry + + def elaborate(self, platform=None): + m = Module() + # Pull out all control bites from PTE + m.d.comb += [ + self.d.eq(self.i[7]), + self.a.eq(self.i[6]), + self.g.eq(self.i[5]), + self.u.eq(self.i[4]), + self.xwr.eq(self.i[1:4]), + self.v.eq(self.i[0]) + ] + m.d.comb += self.asid.eq(self.i[self.asid_start:self.asid_end]) + m.d.comb += self.pte.eq(self.i[0:self.asid_start]) + return m \ No newline at end of file diff --git a/TLB/test/test_pte_entry.py b/TLB/test/test_pte_entry.py new file mode 100644 index 00000000..3b1c1392 --- /dev/null +++ b/TLB/test/test_pte_entry.py @@ -0,0 +1,101 @@ +import sys +sys.path.append("../src") +sys.path.append("../../TestUtil") + +from nmigen.compat.sim import run_simulation + +from PteEntry import PteEntry + +from test_helper import assert_op + +def set_entry(dut, i): + yield dut.i.eq(i) + yield + +def check_dirty(dut, d, op): + out_d = yield dut.d + assert_op("Dirty", out_d, d, op) + +def check_accessed(dut, a, op): + out_a = yield dut.a + assert_op("Accessed", out_a, a, op) + +def check_global(dut, o, op): + out = yield dut.g + assert_op("Global", out, o, op) + +def check_user(dut, o, op): + out = yield dut.u + assert_op("User Mode", out, o, op) + +def check_xwr(dut, o, op): + out = yield dut.xwr + assert_op("XWR", out, o, op) + +def check_asid(dut, o, op): + out = yield dut.asid + assert_op("ASID", out, o, op) + +def check_pte(dut, o, op): + out = yield dut.pte + assert_op("ASID", out, o, op) + +def check_valid(dut, v, op): + out_v = yield dut.v + assert_op("Valid", out_v, v, op) + +def check_all(dut, d, a, g, u, xwr, v, asid, pte): + yield from check_dirty(dut, d, 0) + yield from check_accessed(dut, a, 0) + yield from check_global(dut, g, 0) + yield from check_user(dut, u, 0) + yield from check_xwr(dut, xwr, 0) + yield from check_valid(dut, v, 0) + +def testbench(dut): + # 80 bits represented. Ignore the MSB as it will be truncated + # ASID is bits first 4 hex values (bits 64 - 78) + + i = 0x7FFF0000000000000031 + dirty = 0 + access = 0 + glob = 1 + user = 1 + xwr = 0 + valid = 1 + asid = 0x7FFF + pte = 0x0000000000000031 + yield from set_entry(dut, i) + yield from check_all(dut, dirty, access, glob, user, xwr, valid, asid, pte) + + i = 0x0FFF00000000000000FF + dirty = 1 + access = 1 + glob = 1 + user = 1 + xwr = 7 + valid = 1 + asid = 0x0FFF + pte = 0x00000000000000FF + yield from set_entry(dut, i) + yield from check_all(dut, dirty, access, glob, user, xwr, valid, asid, pte) + + i = 0x0721000000001100001F + dirty = 0 + access = 0 + glob = 0 + user = 1 + xwr = 7 + valid = 1 + asid = 0x0721 + pte = 0x00000000110000FF + yield from set_entry(dut, i) + yield from check_all(dut, dirty, access, glob, user, xwr, valid, asid, pte) + + yield + + +if __name__ == "__main__": + dut = PteEntry(15, 64); + run_simulation(dut, testbench(dut), vcd_name="Waveforms/test_pte_entry.vcd") + print("PteEntry Unit Test Success") \ No newline at end of file -- 2.30.2