minor code-shuffle on TLB, added nmigen-main caller
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 7 Apr 2019 23:18:12 +0000 (00:18 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 7 Apr 2019 23:18:12 +0000 (00:18 +0100)
TLB/src/TLB.py

index da20a6b0658916151fc5341040375d640474c9fd..3f1bcb43d3d293f2b512170d174a4c53db95ffd5 100644 (file)
@@ -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())