+ m.d.comb += self.o.outputs[0].eq(io8.output)
+
+ for i in range(8):
+ m.d.comb += self.o.part_ops[i].eq(out_part_ops[i])
+ m.d.comb += self.o.part_pts.eq(out_part_pts)
+ m.d.comb += self.o.intermediate_output.eq(self.i.output)
+
+ return m
+
+
+class Mul8_16_32_64(Elaboratable):
+ """Signed/Unsigned 8/16/32/64-bit partitioned integer multiplier.
+
+ XXX NOTE: this class is intended for unit test purposes ONLY.
+
+ Supports partitioning into any combination of 8, 16, 32, and 64-bit
+ partitions on naturally-aligned boundaries. Supports the operation being
+ set for each partition independently.
+
+ :attribute part_pts: the input partition points. Has a partition point at
+ multiples of 8 in 0 < i < 64. Each partition point's associated
+ ``Value`` is a ``Signal``. Modification not supported, except for by
+ ``Signal.eq``.
+ :attribute part_ops: the operation for each byte. The operation for a
+ particular partition is selected by assigning the selected operation
+ code to each byte in the partition. The allowed operation codes are:
+
+ :attribute OP_MUL_LOW: the LSB half of the product. Equivalent to
+ RISC-V's `mul` instruction.
+ :attribute OP_MUL_SIGNED_HIGH: the MSB half of the product where both
+ ``a`` and ``b`` are signed. Equivalent to RISC-V's `mulh`
+ instruction.
+ :attribute OP_MUL_SIGNED_UNSIGNED_HIGH: the MSB half of the product
+ where ``a`` is signed and ``b`` is unsigned. Equivalent to RISC-V's
+ `mulhsu` instruction.
+ :attribute OP_MUL_UNSIGNED_HIGH: the MSB half of the product where both
+ ``a`` and ``b`` are unsigned. Equivalent to RISC-V's `mulhu`
+ instruction.
+ """
+
+ def __init__(self, register_levels=()):
+ """ register_levels: specifies the points in the cascade at which
+ flip-flops are to be inserted.
+ """
+
+ self.id_wid = 0 # num_bits(num_rows)
+ self.op_wid = 0
+ self.pspec = PipelineSpec(64, self.id_wid, self.op_wid, n_ops=3)
+ self.pspec.n_parts = 8
+
+ # parameter(s)
+ self.register_levels = list(register_levels)
+
+ self.i = self.ispec()
+ self.o = self.ospec()
+
+ # inputs
+ self.part_pts = self.i.part_pts
+ self.part_ops = self.i.part_ops
+ self.a = self.i.a
+ self.b = self.i.b
+
+ # output
+ self.intermediate_output = self.o.intermediate_output
+ self.output = self.o.output
+
+ def ispec(self):
+ return InputData()
+
+ def ospec(self):
+ return OutputData()