itlb_content = PTE()
itlb_is_2M = Signal()
itlb_is_1G = Signal()
+ itlb_is_512G = Signal()
itlb_lu_hit = Signal()
dtlb_lu_access = Signal()
dtlb_content = PTE()
dtlb_is_2M = Signal()
dtlb_is_1G = Signal()
+ dtlb_is_512G = Signal()
dtlb_lu_hit = Signal()
# Assignments
itlb_content.eq(i_tlb.lu_content_o),
itlb_is_2M.eq(i_tlb.lu_is_2M_o),
itlb_is_1G.eq(i_tlb.lu_is_1G_o),
+ itlb_is_512G.eq(i_tlb.lu_is_512G_o),
itlb_lu_hit.eq(i_tlb.lu_hit_o),
]
dtlb_content.eq(d_tlb.lu_content_o),
dtlb_is_2M.eq(d_tlb.lu_is_2M_o),
dtlb_is_1G.eq(d_tlb.lu_is_1G_o),
+ dtlb_is_512G.eq(d_tlb.lu_is_512G_o),
dtlb_lu_hit.eq(d_tlb.lu_hit_o),
]
# Check whether we are allowed to access this memory region
# from a fetch perspective
- # XXX TODO: use PermissionValidator instead [we like modules]
+ # PLATEN TODO: use PermissionValidator instead [we like modules]
m.d.comb += iaccess_err.eq(self.icache_areq_i.fetch_req & \
(((self.priv_lvl_i == PRIV_LVL_U) & \
~itlb_content.u) | \
# an error.
with m.If (self.enable_translation_i):
# we work with SV48, so if VM is enabled, check that
- # all bits [63:38] are equal
+ # all bits [47:38] are equal
with m.If (self.icache_areq_i.fetch_req & \
- ~(((~self.icache_areq_i.fetch_vaddr[38:64]) == 0) | \
- (self.icache_areq_i.fetch_vaddr[38:64]) == 0)):
+ ~(((~self.icache_areq_i.fetch_vaddr[47:64]) == 0) | \
+ (self.icache_areq_i.fetch_vaddr[47:64]) == 0)):
fe = self.icache_areq_o.fetch_exception
m.d.comb += [fe.cause.eq(INSTR_ACCESS_FAULT),
fe.tval.eq(self.icache_areq_i.fetch_vaddr),
m.d.comb += paddr[12:30].eq(
self.icache_areq_i.fetch_vaddr[12:30])
m.d.comb += self.icache_areq_o.fetch_paddr.eq(paddr)
+ # Tera page
+ with m.If(itlb_is_512G):
+ m.d.comb += paddr[12:39].eq(
+ self.icache_areq_i.fetch_vaddr[12:39])
+ m.d.comb += self.icache_areq_o.fetch_paddr.eq(paddr)
# ---------
# ITLB Hit
lsu_req = Signal()
lsu_is_store = Signal()
dtlb_hit = Signal()
- dtlb_is_2M = Signal()
- dtlb_is_1G = Signal()
+ #dtlb_is_2M = Signal()
+ #dtlb_is_1G = Signal()
+ #dtlb_is_512 = Signal()
# check if we need to do translation or if we are always
# ready (e.g.: we are not translating anything)
dtlb_pte.eq(dtlb_content),
dtlb_hit.eq(dtlb_lu_hit),
lsu_is_store.eq(self.lsu_is_store_i),
- dtlb_is_2M.eq(dtlb_is_2M),
- dtlb_is_1G.eq(dtlb_is_1G),
+ #dtlb_is_2M.eq(dtlb_is_2M),
+ #dtlb_is_1G.eq(dtlb_is_1G),
+ ##dtlb_is_512.eq(self.dtlb_is_512G) #????
]
m.d.sync += [
self.lsu_paddr_o.eq(lsu_vaddr),
with m.If(dtlb_is_1G):
m.d.comb += paddr[12:30].eq(lsu_vaddr[12:30])
m.d.sync += self.lsu_paddr_o.eq(paddr)
+ # TODO platen tera_page
# ---------
# DTLB Hit
self.valid = Signal() # valid flag
self.is_2M = Signal()
self.is_1G = Signal()
+ self.is_512G = Signal()
self.vpn = Signal(27)
self.asid = Signal(asid_width)
self.content = PTE()
# -----------
self.itlb_update_o.vpn.eq(vaddr[12:48]),
self.dtlb_update_o.vpn.eq(vaddr[12:48]),
- #TODO_PLATEN: extend by 9 bits
# update the correct page table level
- self.itlb_update_o.is_2M.eq(ptw_lvl2),
- self.itlb_update_o.is_1G.eq(ptw_lvl1),
- self.dtlb_update_o.is_2M.eq(ptw_lvl2),
- self.dtlb_update_o.is_1G.eq(ptw_lvl1),
+ self.itlb_update_o.is_2M.eq(ptw_lvl3),
+ self.itlb_update_o.is_1G.eq(ptw_lvl2),
+ self.itlb_update_o.is_512G.eq(ptw_lvl1),
+ self.dtlb_update_o.is_2M.eq(ptw_lvl3),
+ self.dtlb_update_o.is_1G.eq(ptw_lvl2),
+ self.dtlb_update_o.is_512G.eq(ptw_lvl1),
+
# output the correct ASID
self.itlb_update_o.asid.eq(tlb_update_asid),
self.dtlb_update_o.asid.eq(tlb_update_asid),
l1err = Signal(reset_less=True)
l2err = Signal(reset_less=True)
- m.d.comb += [l2err.eq((ptw_lvl2) & pte.ppn[0:9] != Const(0, 9)),
- l1err.eq((ptw_lvl1) & pte.ppn[0:18] != Const(0, 18)) ]
+ m.d.comb += [l3err.eq((ptw_lvl3) & pte.ppn[0:9] != Const(0,0)),
+ l2err.eq((ptw_lvl2) & pte.ppn[0:18] != Const(0, 18)),
+ l1err.eq((ptw_lvl1) & pte.ppn[0:27] != Const(0, 27))]
# check if the global mapping bit is set
with m.If (pte.g):
m.next = "PROPAGATE_ERROR"
# check if the ppn is correctly aligned: Case (6)
- with m.If(l1err | l2err):
+ with m.If(l1err | l2err | l3err):
m.next = "PROPAGATE_ERROR"
m.d.comb += [self.dtlb_update_o.valid.eq(0),
self.itlb_update_o.valid.eq(0)]
self.lu_content_o = PTE()
self.lu_is_2M_o = Signal()
self.lu_is_1G_o = Signal()
+ self.lu_is_512G_o = Signal()
self.lu_hit_o = Signal()
# Update TLB
self.pte_width = len(self.lu_content_o.flatten())
# SV48 defines four levels of page tables
m.d.comb += [ vpn0.eq(self.lu_vaddr_i[12:21]),
vpn1.eq(self.lu_vaddr_i[21:30]),
- vpn2.eq(self.lu_vaddr_i[30:39]), ### PLATEN ### OK
- vpn3.eq(self.lu_vaddr_i[39:48]), ### PLATEN ### now using SV48
+ vpn2.eq(self.lu_vaddr_i[30:39]),
+ vpn3.eq(self.lu_vaddr_i[39:48]), ### FIXME
]
tc = []
m.d.comb += active.eq(~hitsel.n)
with m.If(active):
# active hit, send selected as output
- m.d.comb += [ self.lu_is_1G_o.eq(tc[idx].lu_is_1G_o),
+ m.d.comb += [ self.lu_is_512G_o.eq(tc[idx].lu_is_512G_o),
+ self.lu_is_1G_o.eq(tc[idx].lu_is_1G_o),
self.lu_is_2M_o.eq(tc[idx].lu_is_2M_o),
self.lu_hit_o.eq(1),
self.lu_content_o.flatten().eq(tc[idx].lu_content_o),
def ports(self):
return [self.flush_i, self.lu_access_i,
self.lu_asid_i, self.lu_vaddr_i,
- self.lu_is_2M_o, self.lu_is_1G_o, self.lu_hit_o,
+ self.lu_is_2M_o, self.lu_1G_o, self.lu_is_512G_o, self.lu_hit_o
] + self.lu_content_o.ports() + self.update_i.ports()
if __name__ == '__main__':
self.vpn1 = Signal(9)
self.vpn2 = Signal(9)
self.vpn3 = Signal(9)
- #TODO_PLATEN: use that signal
self.is_2M = Signal()
self.is_1G = Signal()
+ self.is_512G = Signal()
self.valid = Signal()
def flatten(self):
# Lookup signals
self.lu_asid_i = Signal(asid_width)
self.lu_content_o = Signal(pte_width)
+ self.lu_is_512G_o = Signal()
self.lu_is_2M_o = Signal()
self.lu_is_1G_o = Signal()
self.lu_hit_o = Signal()
tags_2M.eq(tags.is_2M),
vpn0_ok.eq(self.vpn0 == tags.vpn0),
vpn0_or_2M.eq(tags_2M | vpn0_ok)]
+ # TODO temporaries for 3rd level match
+
# first level match, this may be a giga page,
# check the ASID flags as well
with m.If(vpn2_hit):
tags.vpn2.eq(self.update_i.vpn[18:27]),
tags.vpn1.eq(self.update_i.vpn[9:18]),
tags.vpn0.eq(self.update_i.vpn[0:9]),
+ tags.is_512G.eq(self.update_i.is_512G),
tags.is_1G.eq(self.update_i.is_1G),
tags.is_2M.eq(self.update_i.is_2M),
tags.valid.eq(1),
def ports(self):
return [self.flush_i,
self.lu_asid_i,
- self.lu_is_2M_o, self.lu_is_1G_o, self.lu_hit_o,
+ self.lu_is_2M_o, self.lu_is_1G_o,self.lu_is_512G_o, self.lu_hit_o,
] + self.update_i.content.ports() + self.update_i.ports()