super is a keyword: replace with "supermode" in TLB and PermValidator
[soc.git] / TLB / src / TLB.py
1 """ TLB Module
2
3 The expected form of the data is:
4 * Item (Bits)
5 * Tag (N - 79) / ASID (78 - 64) / PTE (63 - 0)
6 """
7
8 from nmigen import Memory, Module, Signal
9 from nmigen.cli import main
10
11 from PermissionValidator import PermissionValidator
12 from Cam import Cam
13
14 class TLB():
15 def __init__(self, asid_size, vma_size, pte_size):
16 """ Arguments
17 * asid_size: Address Space IDentifier (ASID) typically 15 bits
18 * vma_size: Virtual Memory Address (VMA) typically 36 bits
19 * pte_size: Page Table Entry (PTE) typically 64 bits
20
21 Notes:
22 These arguments should represent the largest possible size
23 defined by the MODE settings. See
24 Volume II: RISC-V Privileged Architectures V1.10 Page 57
25 """
26
27 # Internal
28 self.state = 0
29 # L1 Cache Modules
30 L1_size = 8
31 self.cam_L1 = Cam(vma_size, cam_size)
32 self.mem_L1 = Memory(asid_size + pte_size, cam_size)
33
34 # Permission Validator
35 self.perm_validator = PermissionValidator(asid_size + pte_size)
36
37 # Inputs
38 self.supermode = Signal(1) # Supervisor Mode
39 self.super_access = Signal(1) # Supervisor Access
40 self.command = Signal(2) # 00=None, 01=Search, 10=Write L1, 11=Write L2
41 self.xwr = Signal(3) # Execute, Write, Read
42 self.mode = Signal(4) # 4 bits for access to Sv48 on Rv64
43 self.address_L1 = Signal(max= am_size)
44 self.asid = Signal(asid_size) # Address Space IDentifier (ASID)
45 self.vma = Signal(vma_size) # Virtual Memory Address (VMA)
46 self.pte_in = Signal(pte_size) # To be saved Page Table Entry (PTE)
47
48 # Outputs
49 self.hit = Signal(1) # Denotes if the VMA had a mapped PTE
50 self.perm_valid = Signal(1) # Denotes if the permissions are correct
51 self.pte_out = Signal(pte_size) # PTE that was mapped to by the VMA
52
53 def elaborate(self, platform):
54 m = Module()
55 # Add submodules
56 # Submodules for L1 Cache
57 m.d.submodules.cam_L1 = self.cam_L1
58 m.d.sumbmodules.read_L1 = read_L1 = self.mem_L1.read_port
59 m.d.sumbmodules.read_L1 = write_L1 = self.mem_L1.read_port
60 # Permission Validator Submodule
61 m.d.submodules.perm_valididator = self.perm_validator
62
63 # When MODE specifies translation
64 # TODO add in different bit length handling ie prefix 0s
65 with m.If(self.mode != 0):
66 m.d.comb += [
67 self.cam_L1.enable.eq(1)
68 ]
69 with m.Switch(self.command):
70 # Search
71 with m.Case("01"):
72 m.d.comb += [
73 write_L1.en.eq(0),
74 self.cam_L1.write_enable.eq(0),
75 self.cam_L1.data_in.eq(self.vma)
76 ]
77 # Write L1
78 # Expected that the miss will be handled in software
79 with m.Case("10"):
80 # Memory_L1 Logic
81 m.d.comb += [
82 write_L1.en.eq(1),
83 write_L1.addr.eq(self.address_L1),
84 # The first argument is the LSB
85 write_L1.data.eq(Cat(self.pte, self.asid))
86 ]
87 # CAM_L1 Logic
88 m.d.comb += [
89 self.cam_L1.write_enable.eq(1),
90 self.cam_L1.data_in.eq(self.vma),
91 ]
92 # TODO
93 #with m.Case("11"):
94
95 # Match found in L1 CAM
96 with m.If(self.cam_L1.single_match
97 | self.cam_L1.multiple_match):
98 # Memory shortcut variables
99 mem_addrress = self.cam_L1.match_address
100 # Memory Logic
101 m.d.comb += read_L1.addr(mem_address)
102 # Permission vVlidator Logic
103 m.d.comb += [
104 self.hit.eq(1),
105 # Set permission validator data to the correct
106 # register file data according to CAM match
107 # address
108 self.perm_validator.data.eq(read_L1.data),
109 # Execute, Read, Write
110 self.perm_validator.xwr.eq(self.xwr),
111 # Supervisor Mode
112 self.perm_validator.supermode.eq(self.supermode),
113 # Supverisor Access
114 self.perm_validator.super_access.eq(self.super_access),
115 # Address Space IDentifier (ASID)
116 self.perm_validator.asid.eq(self.asid),
117 # Output result of permission validation
118 self.perm_valid.eq(self.perm_validator.valid)
119 ]
120 # Do not output PTE if permissions fail
121 with m.If(self.perm_validator.valid):
122 m.d.comb += [
123 self.pte_out.eq(reg_data)
124 ]
125 with m.Else():
126 m.d.comb += [
127 self.pte_out.eq(0)
128 ]
129 # Miss Logic
130 with m.Else():
131 m.d.comb += [
132 self.hit.eq(0),
133 self.perm_valid.eq(0),
134 self.pte_out.eq(0)
135 ]
136 # When disabled
137 with m.Else():
138 m.d.comb += [
139 self.cam_L1.enable.eq(0),
140 self.reg_file.enable.eq(0),
141 self.hit.eq(0),
142 self.valid.eq(0),
143 self.pte_out.eq(0)
144 ]
145 return m
146