from ieee754.part.partsig import PartitionedSignal
from soc.decoder.power_enums import MicrOp
+from soc.decoder.power_fields import DecodeFields
+from soc.decoder.power_fieldsn import SignalBitRange
+
# microwatt calc_ov function.
def calc_ov(msb_a, msb_b, ca, msb_r):
class ALUMainStage(PipeModBase):
def __init__(self, pspec):
super().__init__(pspec, "main")
+ self.fields = DecodeFields(SignalBitRange, [self.i.ctx.op.insn])
+ self.fields.create_specs()
def ispec(self):
return ALUInputData(self.pspec) # defines pipeline stage input format
ov_o = self.o.xer_ov
a, b, cry_i, op = self.i.a, self.i.b, self.i.xer_ca, self.i.ctx.op
+ # get L-field for OP_CMP
+ x_fields = self.fields.FormX
+ L = x_fields.L[0]
+
# check if op is 32-bit, and get sign bit from operand a
is_32bit = Signal(reset_less=True)
- sign_bit = Signal(reset_less=True)
- comb += is_32bit.eq(op.is_32bit)
- comb += sign_bit.eq(Mux(is_32bit, a[31], a[63]))
+
+ with m.If(op.insn_type == MicrOp.OP_CMP):
+ comb += is_32bit.eq(~L)
# little trick: do the add using only one add (not 2)
# LSB: carry-in [0]. op/result: [1:-1]. MSB: carry-out [-1]
add_a = Signal(a.width + 2, reset_less=True)
add_b = Signal(a.width + 2, reset_less=True)
add_o = Signal(a.width + 2, reset_less=True)
+
+ a_i = Signal.like(a)
+ b_i = Signal.like(b)
+ with m.If(is_32bit):
+ comb += a_i.eq(exts(a, 32, 64))
+ comb += b_i.eq(exts(b, 32, 64))
+ with m.Else():
+ comb += a_i.eq(a)
+ comb += b_i.eq(b)
+
with m.If((op.insn_type == MicrOp.OP_ADD) |
(op.insn_type == MicrOp.OP_CMP)):
# in bit 0, 1+carry_in creates carry into bit 1 and above
- comb += add_a.eq(Cat(cry_i[0], a, Const(0, 1)))
- comb += add_b.eq(Cat(Const(1, 1), b, Const(0, 1)))
+ comb += add_a.eq(Cat(cry_i[0], a_i, Const(0, 1)))
+ comb += add_b.eq(Cat(Const(1, 1), b_i, Const(0, 1)))
comb += add_o.eq(add_a + add_b)
##########################
# https://bugs.libre-soc.org/show_bug.cgi?id=319#c5
ca = Signal(2, reset_less=True)
comb += ca[0].eq(add_o[-1]) # XER.CA
- comb += ca[1].eq(add_o[33] ^ (a[32] ^ b[32])) # XER.CA32
+ comb += ca[1].eq(add_o[33] ^ (a_i[32] ^ b_i[32])) # XER.CA32
comb += cry_o.data.eq(ca)
comb += cry_o.ok.eq(1)
# 32-bit (ov[1]) and 64-bit (ov[0]) overflow
ov = Signal(2, reset_less=True)
- comb += ov[0].eq(calc_ov(a[-1], b[-1], ca[0], add_o[-2]))
- comb += ov[1].eq(calc_ov(a[31], b[31], ca[1], add_o[32]))
+ comb += ov[0].eq(calc_ov(a_i[-1], b_i[-1], ca[0], add_o[-2]))
+ comb += ov[1].eq(calc_ov(a_i[31], b_i[31], ca[1], add_o[32]))
comb += ov_o.data.eq(ov)
comb += ov_o.ok.eq(1)