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