From 6ca2068404b31ee53d7fdbe9b2e16d2847f78907 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Mon, 8 Apr 2019 00:18:12 +0100 Subject: [PATCH] minor code-shuffle on TLB, added nmigen-main caller --- TLB/src/TLB.py | 204 ++++++++++++++++++++++++++++--------------------- 1 file changed, 115 insertions(+), 89 deletions(-) diff --git a/TLB/src/TLB.py b/TLB/src/TLB.py index da20a6b0..3f1bcb43 100644 --- a/TLB/src/TLB.py +++ b/TLB/src/TLB.py @@ -5,7 +5,7 @@ * Tag (N - 79) / ASID (78 - 64) / PTE (63 - 0) """ -from nmigen import Memory, Module, Signal +from nmigen import Memory, Module, Signal, Cat from nmigen.cli import main from PermissionValidator import PermissionValidator @@ -50,98 +50,124 @@ class TLB(): self.perm_valid = Signal(1) # Denotes if the permissions are correct self.pte_out = Signal(pte_size) # PTE that was mapped to by the VMA - def elaborate(self, platform): - m = Module() - # Add submodules - # Submodules for L1 Cache - m.d.submodules.cam_L1 = self.cam_L1 - m.d.sumbmodules.read_L1 = read_L1 = self.mem_L1.read_port() - m.d.sumbmodules.read_L1 = write_L1 = self.mem_L1.write_port() - # Permission Validator Submodule - m.d.submodules.perm_valididator = self.perm_validator - - # When MODE specifies translation - # TODO add in different bit length handling ie prefix 0s - with m.If(self.mode != 0): + def search(self, m, read_L1, write_L1): + """ searches the TLB + """ + m.d.comb += [ + write_L1.en.eq(0), + self.cam_L1.write_enable.eq(0), + self.cam_L1.data_in.eq(self.vma) + ] + # Match found in L1 CAM + match_found = Signal(reset_less=True) + m.d.comb += match_found.eq(self.cam_L1.single_match + | self.cam_L1.multiple_match) + with m.If(match_found): + # Memory shortcut variables + mem_address = self.cam_L1.match_address + # Memory Logic + m.d.comb += read_L1.addr.eq(mem_address) + # Permission Validator Logic + m.d.comb += [ + self.hit.eq(1), + # Set permission validator data to the correct + # register file data according to CAM match + # address + self.perm_validator.data.eq(read_L1.data), + # Execute, Read, Write + self.perm_validator.xwr.eq(self.xwr), + # Supervisor Mode + self.perm_validator.super_mode.eq(self.supermode), + # Supverisor Access + self.perm_validator.super_access.eq(self.super_access), + # Address Space IDentifier (ASID) + self.perm_validator.asid.eq(self.asid), + # Output result of permission validation + self.perm_valid.eq(self.perm_validator.valid) + ] + # Do not output PTE if permissions fail + with m.If(self.perm_validator.valid): + # XXX TODO - dummy for now + reg_data = Signal.like(self.pte_out) m.d.comb += [ - self.cam_L1.enable.eq(1) + self.pte_out.eq(reg_data) ] - with m.Switch(self.command): - # Search - with m.Case("01"): - m.d.comb += [ - write_L1.en.eq(0), - self.cam_L1.write_enable.eq(0), - self.cam_L1.data_in.eq(self.vma) - ] - # Match found in L1 CAM - with m.If(self.cam_L1.single_match - | self.cam_L1.multiple_match): - # Memory shortcut variables - mem_addrress = self.cam_L1.match_address - # Memory Logic - m.d.comb += read_L1.addr(mem_address) - # Permission Validator Logic - m.d.comb += [ - self.hit.eq(1), - # Set permission validator data to the correct - # register file data according to CAM match - # address - self.perm_validator.data.eq(read_L1.data), - # Execute, Read, Write - self.perm_validator.xwr.eq(self.xwr), - # Supervisor Mode - self.perm_validator.supermode.eq(self.supermode), - # Supverisor Access - self.perm_validator.super_access.eq(self.super_access), - # Address Space IDentifier (ASID) - self.perm_validator.asid.eq(self.asid), - # Output result of permission validation - self.perm_valid.eq(self.perm_validator.valid) - ] - # Do not output PTE if permissions fail - with m.If(self.perm_validator.valid): - m.d.comb += [ - self.pte_out.eq(reg_data) - ] - with m.Else(): - m.d.comb += [ - self.pte_out.eq(0) - ] - # Miss Logic - with m.Else(): - m.d.comb += [ - self.hit.eq(0), - self.perm_valid.eq(0), - self.pte_out.eq(0) - ] - - # Write L1 - # Expected that the miss will be handled in software - with m.Case("10"): - # Memory_L1 Logic - m.d.comb += [ - write_L1.en.eq(1), - write_L1.addr.eq(self.address_L1), - # The Cat places arguments from LSB -> MSB - write_L1.data.eq(Cat(self.pte, self.asid)) - ] - # CAM_L1 Logic - m.d.comb += [ - self.cam_L1.write_enable.eq(1), - self.cam_L1.data_in.eq(self.vma), - ] - - # TODO - #with m.Case("11"): - # When disabled with m.Else(): m.d.comb += [ - self.cam_L1.enable.eq(0), - self.reg_file.enable.eq(0), - self.hit.eq(0), - self.valid.eq(0), self.pte_out.eq(0) ] - return m + # Miss Logic + with m.Else(): + m.d.comb += [ + self.hit.eq(0), + self.perm_valid.eq(0), + self.pte_out.eq(0) + ] + + def write_l1(self, m, read_L1, write_L1): + """ writes to the L1 cache + """ + # Memory_L1 Logic + m.d.comb += [ + write_L1.en.eq(1), + write_L1.addr.eq(self.address_L1), + # The Cat places arguments from LSB -> MSB + write_L1.data.eq(Cat(self.pte_in, self.asid)) + ] + # CAM_L1 Logic + m.d.comb += [ + self.cam_L1.write_enable.eq(1), + self.cam_L1.data_in.eq(self.vma), + ] + + def elaborate(self, platform): + m = Module() + # Add submodules + # Submodules for L1 Cache + m.d.submodules.cam_L1 = self.cam_L1 + m.d.sumbmodules.read_L1 = read_L1 = self.mem_L1.read_port() + m.d.sumbmodules.read_L1 = write_L1 = self.mem_L1.write_port() + # Permission Validator Submodule + m.d.submodules.perm_valididator = self.perm_validator + + # When MODE specifies translation + # TODO add in different bit length handling ie prefix 0s + tlb_enable = Signal(reset_less=True) + m.d.comb += tlb_enable.eq(self.mode != 0) + + with m.If(tlb_enable): + m.d.comb += [ + self.cam_L1.enable.eq(1) + ] + with m.Switch(self.command): + # Search + with m.Case("01"): + self.search(m, read_L1, write_L1) + + # Write L1 + # Expected that the miss will be handled in software + with m.Case("10"): + self.write_l1(m, read_L1, write_L1) + + # TODO + #with m.Case("11"): + + # When disabled + with m.Else(): + m.d.comb += [ + self.cam_L1.enable.eq(0), + # XXX TODO - self.reg_file.enable.eq(0), + self.hit.eq(0), + self.perm_valid.eq(0), # XXX TODO, check this + self.pte_out.eq(0) + ] + return m + +if __name__ == '__main__': + tlb = TLB(15, 36, 64, 4) + main(tlb, ports=[ tlb.supermode, tlb.super_access, tlb.command, + tlb.xwr, tlb.mode, tlb.address_L1, tlb.asid, + tlb.vma, tlb.pte_in, + tlb.hit, tlb.perm_valid, tlb.pte_out, + ] + tlb.cam_L1.ports()) -- 2.30.2