Add PteEntry comments
[soc.git] / TLB / src / AddressEncoder.py
1 from nmigen import Module, Signal
2 from nmigen.lib.coding import Encoder, PriorityEncoder
3
4 class AddressEncoder():
5 """Address Encoder
6
7 The purpose of this module is to take in a vector and
8 encode the bits that are one hot into an address. This module
9 combines both nmigen's Encoder and PriorityEncoder and will state
10 whether the input line has a single bit hot, multiple bits hot,
11 or no bits hot. The output line will always have the lowest value
12 address output.
13
14 Usage:
15 The output is valid when either single or multiple match is high.
16 Otherwise output is 0.
17 """
18 def __init__(self, width):
19 """ Arguments:
20 * width: The desired length of the input vector
21 """
22 # Internal
23 self.encoder = Encoder(width)
24 self.p_encoder = PriorityEncoder(width)
25
26 # Input
27 self.i = Signal(width)
28
29 # Output
30 self.single_match = Signal(1)
31 self.multiple_match = Signal(1)
32 self.o = Signal(max=width)
33
34 def elaborate(self, platform=None):
35 m = Module()
36
37 # Add internal submodules
38 m.submodules.encoder = self.encoder
39 m.submodules.p_encoder = self.p_encoder
40
41 m.d.comb += [
42 self.encoder.i.eq(self.i),
43 self.p_encoder.i.eq(self.i)
44 ]
45
46 # If the priority encoder recieves an input of 0
47 # If n is 1 then the output is not valid
48 with m.If(self.p_encoder.n):
49 m.d.comb += [
50 self.single_match.eq(0),
51 self.multiple_match.eq(0),
52 self.o.eq(0)
53 ]
54 # If the priority encoder recieves an input > 0
55 with m.Else():
56 # Multiple Match if encoder n is invalid
57 with m.If(self.encoder.n):
58 m.d.comb += [
59 self.single_match.eq(0),
60 self.multiple_match.eq(1)
61 ]
62 # Single Match if encoder n is valid
63 with m.Else():
64 m.d.comb += [
65 self.single_match.eq(1),
66 self.multiple_match.eq(0)
67 ]
68 # Always set output based on priority encoder output
69 m.d.comb += self.o.eq(self.p_encoder.o)
70 return m