- m.d.submodules.perm_valid = perm_valid = PermissionValidator(113)
- m.d.sync += [
- Case(self.command, {
- # Search for PTE
- 1: [
- # Check first entry in set
- # TODO make module?
- read_port_l1.addr.eq(vma[0,2]),
- If(read_port_l1.data[0] == 1,
- perm_valid.data.eq(read_port_l1.data),
- perm_valid.xwr.eq(self.xwr),
- perm_valid.super.eq(self.super),
- perm_valid.super_access.eq(self.super_access),
- perm_valid.asid.eq(self.asid),
- self.valid,eq(perm_valid.valid)
- ),
- If(self.valid == 0,
- read_port_l1.addr.eq(vma[0,2] + 1),
- If(read_port_l1.data[0] == 1,
- perm_valid.data.eq(read_port_l1.data),
- perm_valid.xwr.eq(self.xwr),
- perm_valid.super.eq(self.super),
- perm_valid.super_access.eq(self.super_access),
- perm_valid.asid.eq(self.asid),
- self.valid,eq(perm_valid.valid)
- )
- )
- ]
- })
- ]
+ # 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.read_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):
+ m.d.comb += [
+ self.cam_L1.enable.eq(1)
+ ]
+ 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)
+ ]
+ # 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 first argument is the LSB
+ 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"):
+
+ # 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 vVlidator 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)
+ ]
+ # 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)
+ ]