1 # based on microwatt plru.vhdl
3 from nmigen
import Elaboratable
, Signal
, Array
, Module
5 class PLRU(Elaboratable
):
7 def __init__(self
, BITS
=2):
9 self
.acc
= Signal(BITS
)
10 self
.acc_en
= Signal()
11 self
.lru_o
= Signal(BITS
)
13 def elaborate(self
, platform
):
15 comb
, sync
= m
.d
.comb
, m
.d
.sync
17 tree
= Array(Signal() for i
in range(self
.BITS
))
19 # XXX Check if we can turn that into a little ROM instead that
20 # takes the tree bit vector and returns the LRU. See if it's better
21 # in term of FPGA resouces usage...
22 node
= Signal(self
.BITS
)
23 for i
in range(self
.BITS
):
24 node_next
= Signal(self
.BITS
)
25 node2
= Signal(self
.BITS
)
26 # report "GET: i:" & integer'image(i) & " node:" &
27 # integer'image(node) & " val:" & Signal()'image(tree(node))
28 comb
+= self
.lru_o
[self
.BITS
-1-i
].eq(tree
[node
])
30 comb
+= node2
.eq(node
<< 1)
32 comb
+= node2
.eq(node
)
34 with m
.If(tree
[node
]):
35 comb
+= node_next
.eq(node2
+ 2)
37 comb
+= node_next
.eq(node2
+ 1)
40 with m
.If(self
.acc_en
):
41 node
= Signal(self
.BITS
)
42 for i
in range(self
.BITS
):
43 node_next
= Signal(self
.BITS
)
44 node2
= Signal(self
.BITS
)
45 # report "GET: i:" & integer'image(i) & " node:" &
46 # integer'image(node) & " val:" & Signal()'image(tree(node))
47 abit
= self
.acc
[self
.BITS
-1-i
]
48 sync
+= tree
[node
].eq(~abit
)
50 comb
+= node2
.eq(node
<< 1)
52 comb
+= node2
.eq(node
)
55 comb
+= node_next
.eq(node2
+ 2)
57 comb
+= node_next
.eq(node2
+ 1)