+class DTLBUpdate(Elaboratable):
+ def __init__(self, dtlb_valid_bits, dtlb_ptes):
+ self.tlbie = Signal()
+ self.tlbwe = Signal()
+ self.doall = Signal()
+ self.tlb_hit = Signal()
+ self.tlb_req_index = Signal(TLB_SET_BITS)
+
+ self.dtlb_valid_bits = dtlb_valid_bits
+ self.dtlb_ptes = dtlb_ptes
+
+ self.tlb_hit_way = Signal(TLB_WAY_BITS)
+ self.tlb_tag_way = Signal(TLB_TAG_WAY_BITS)
+ self.tlb_pte_way = Signal(TLB_PTE_WAY_BITS)
+ self.repl_way = Signal(TLB_WAY_BITS)
+ self.eatag = Signal(TLB_EA_TAG_BITS)
+ self.pte_data = Signal(TLB_PTE_BITS)
+
+ def elaborate(self, platform):
+ m = Module()
+ comb = m.d.comb
+ sync = m.d.sync
+
+ tagset = Signal(TLB_TAG_WAY_BITS)
+ pteset = Signal(TLB_PTE_WAY_BITS)
+
+ vb = Signal(TLB_NUM_WAYS)
+ db = Signal(TLB_PTE_WAY_BITS)
+
+ sync += vb.eq(self.dtlb_valid_bits[self.tlb_req_index])
+ sync += db.eq(self.dtlb_ptes[self.tlb_req_index])
+
+ with m.If(self.tlbie & self.doall):
+ # clear all valid bits at once
+ for i in range(TLB_SET_SIZE):
+ sync += self.dtlb_valid_bits[i].eq(0)
+
+ with m.Elif(self.tlbie):
+ with m.If(self.tlb_hit):
+ sync += vb.bit_select(self.tlb_hit_way, 1).eq(Const(0, 1))
+
+ with m.Elif(self.tlbwe):
+
+ comb += tagset.eq(self.tlb_tag_way)
+ comb += write_tlb_tag(self.repl_way, tagset, self.eatag)
+ sync += db.eq(tagset)
+
+ comb += pteset.eq(self.tlb_pte_way)
+ comb += write_tlb_pte(self.repl_way, pteset, self.pte_data)
+ sync += db.eq(pteset)
+
+ sync += vb.bit_select(self.repl_way, 1).eq(1)
+
+ return m
+
+