switch to exact version of cython
[ieee754fpu.git] / src / ieee754 / part_cmp / gt_combiner.py
1 from nmigen import Signal, Module, Elaboratable, Mux
2 from ieee754.part_mul_add.partpoints import PartitionPoints
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.sel & 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 class GTCombiner(Elaboratable):
32
33 def __init__(self, width):
34 self.width = width
35
36 # These two signals allow this module to do more than just a
37 # partitioned greater than comparison.
38 # - If aux_input is set to 0 and gt_en is set to 1, then this
39 # module performs a partitioned greater than comparision
40 # - If aux_input is set to 1 and gt_en is set to 0, then this
41 # module is functionally equivalent to the eq_combiner
42 # module.
43 # - If aux_input is set to 1 and gt_en is set to 1, then this
44 # module performs a partitioned greater than or equals
45 # comparison
46 self.aux_input = Signal(reset_less=True) # right hand side mux input
47 self.gt_en = Signal(reset_less=True) # enable or disable gt signal
48
49 self.eqs = Signal(width, reset_less=True) # the flags for EQ
50 self.gts = Signal(width, reset_less=True) # the flags for GT
51 self.gates = Signal(width-1, reset_less=True)
52 self.outputs = Signal(width, reset_less=True)
53
54 def elaborate(self, platform):
55 m = Module()
56 comb = m.d.comb
57
58 previnput = (self.gts[0] & self.gt_en) | (self.eqs[0] & self.aux_input)
59
60 for i in range(self.width-1):
61 m.submodules["mux%d" % i] = mux = Combiner()
62
63 comb += mux.ina.eq(previnput)
64 comb += mux.inb.eq(self.aux_input)
65 comb += mux.sel.eq(self.gates[i])
66 comb += self.outputs[i].eq(mux.outb)
67 previnput = (self.gts[i+1] & self.gt_en) | \
68 (self.eqs[i+1] & mux.outa)
69
70 comb += self.outputs[-1].eq(previnput)
71
72 return m
73
74 def ports(self):
75 return [self.eqs, self.gts, self.gates, self.outputs,
76 self.gt_en, self.aux_input]