switch to exact version of cython
[ieee754fpu.git] / src / ieee754 / part_cmp / gt_combiner.py
1 from nmigen import Signal, Module, Elaboratable, Mux
2
3
4 class Combiner(Elaboratable):
5
6 def __init__(self):
7 self.ina = Signal()
8 self.inb = Signal()
9 self.sel = Signal()
10 self.outa = Signal()
11 self.outb = Signal()
12
13 def elaborate(self, platform):
14 m = Module()
15 comb = m.d.comb
16
17 comb += self.outa.eq(Mux(self.sel, self.inb, self.ina))
18 comb += self.outb.eq(self.ina)
19
20 return m
21
22 # This is similar to EQCombiner, except that for a greater than
23 # comparison, it needs to deal with both the greater than and equals
24 # signals from each partition. The signals are combined using a
25 # cascaded AND/OR to give the following effect:
26 # When a partition is open, the output is set if either the current
27 # partition's greater than flag is set, or the current partition's
28 # equal flag is set AND the previous partition's greater than output
29 # is true
30
31
32 class GTCombiner(Elaboratable):
33
34 def __init__(self, width):
35 self.width = width
36
37 # These two signals allow this module to do more than just a
38 # partitioned greater than comparison.
39 # - If aux_input is set to 0 and gt_en is set to 1, then this
40 # module performs a partitioned greater than comparision
41 # - If aux_input is set to 1 and gt_en is set to 0, then this
42 # module is functionally equivalent to the eq_combiner
43 # module.
44 # - If aux_input is set to 1 and gt_en is set to 1, then this
45 # module performs a partitioned greater than or equals
46 # comparison
47 self.aux_input = Signal(reset_less=True) # right hand side mux input
48 self.gt_en = Signal(reset_less=True) # enable or disable gt signal
49
50 self.eqs = Signal(width, reset_less=True) # the flags for EQ
51 self.gts = Signal(width, reset_less=True) # the flags for GT
52 self.gates = Signal(width-1, reset_less=True)
53 self.outputs = Signal(width, reset_less=True)
54
55 def elaborate(self, platform):
56 m = Module()
57 comb = m.d.comb
58
59 previnput = (self.gts[0] & self.gt_en) | (self.eqs[0] & self.aux_input)
60
61 for i in range(self.width-1):
62 m.submodules["mux%d" % i] = mux = Combiner()
63
64 comb += mux.ina.eq(previnput)
65 comb += mux.inb.eq(self.aux_input)
66 comb += mux.sel.eq(self.gates[i])
67 comb += self.outputs[i].eq(mux.outb)
68 previnput = (self.gts[i+1] & self.gt_en) | \
69 (self.eqs[i+1] & mux.outa)
70
71 comb += self.outputs[-1].eq(previnput)
72
73 return m
74
75 def ports(self):
76 return [self.eqs, self.gts, self.gates, self.outputs,
77 self.gt_en, self.aux_input]