+class LSBNegTerm(Elaboratable):
+
+ def __init__(self, bit_width):
+ self.bit_width = bit_width
+ self.part = Signal(reset_less=True)
+ self.signed = Signal(reset_less=True)
+ self.op = Signal(bit_width, reset_less=True)
+ self.msb = Signal(reset_less=True)
+ self.nt = Signal(bit_width*2, reset_less=True)
+ self.nl = Signal(bit_width*2, reset_less=True)
+
+ def elaborate(self, platform):
+ m = Module()
+ comb = m.d.comb
+ bit_wid = self.bit_width
+ ext = Repl(0, bit_wid) # extend output to HI part
+
+ # determine sign of each incoming number *in this partition*
+ enabled = Signal(reset_less=True)
+ m.d.comb += enabled.eq(self.part & self.msb & self.signed)
+
+ # for 8-bit values: form a * 0xFF00 by using -a * 0x100, the
+ # negation operation is split into a bitwise not and a +1.
+ # likewise for 16, 32, and 64-bit values.
+
+ # width-extended 1s complement if a is signed, otherwise zero
+ comb += self.nt.eq(Mux(enabled, Cat(ext, ~self.op), 0))
+
+ # add 1 if signed, otherwise add zero
+ comb += self.nl.eq(Cat(ext, enabled, Repl(0, bit_wid-1)))
+
+ return m
+
+
+class Parts(Elaboratable):
+
+ def __init__(self, pbwid, epps, n_parts):
+ self.pbwid = pbwid
+ # inputs
+ self.epps = PartitionPoints.like(epps, name="epps") # expanded points
+ # outputs
+ self.parts = [Signal(name=f"part_{i}") for i in range(n_parts)]
+
+ def elaborate(self, platform):
+ m = Module()
+
+ epps, parts = self.epps, self.parts
+ # collect part-bytes (double factor because the input is extended)
+ pbs = Signal(self.pbwid, reset_less=True)
+ tl = []
+ for i in range(self.pbwid):
+ pb = Signal(name="pb%d" % i, reset_less=True)
+ m.d.comb += pb.eq(epps.part_byte(i, mfactor=2)) # double
+ tl.append(pb)
+ m.d.comb += pbs.eq(Cat(*tl))
+
+ # negated-temporary copy of partition bits
+ npbs = Signal.like(pbs, reset_less=True)
+ m.d.comb += npbs.eq(~pbs)
+ byte_count = 8 // len(parts)
+ for i in range(len(parts)):
+ pbl = []
+ pbl.append(npbs[i * byte_count - 1])
+ for j in range(i * byte_count, (i + 1) * byte_count - 1):
+ pbl.append(pbs[j])
+ pbl.append(npbs[(i + 1) * byte_count - 1])
+ value = Signal(len(pbl), name="value_%d" % i, reset_less=True)
+ m.d.comb += value.eq(Cat(*pbl))
+ m.d.comb += parts[i].eq(~(value).bool())
+
+ return m
+
+