# This stage is intended to adjust the input data before sending it to
-# the acutal ALU. Things like handling inverting the input, carry_in
+# the acutal ALU. Things like handling inverting the input, xer_ca
# generation for subtraction, and handling of immediates should happen
# here
from nmigen import (Module, Signal, Cat, Const, Mux, Repl, signed,
# either copy incoming carry or set to 1/0 as defined by op
with m.Switch(ctx.op.input_carry):
with m.Case(CryIn.ZERO):
- comb += self.o.carry_in.eq(0)
+ comb += self.o.xer_ca.eq(0b00)
with m.Case(CryIn.ONE):
- comb += self.o.carry_in.eq(1)
+ comb += self.o.xer_ca.eq(0b11) # set both CA and CA32
with m.Case(CryIn.CA):
- comb += self.o.carry_in.eq(self.i.carry_in)
+ comb += self.o.xer_ca.eq(self.i.xer_ca)
##### sticky overflow and context (both pass-through) #####
- comb += self.o.so.eq(self.i.so)
+ comb += self.o.xer_so.eq(self.i.xer_so)
comb += self.o.ctx.eq(ctx)
return m
def elaborate(self, platform):
m = Module()
comb = m.d.comb
- cry_o, o, cr0 = self.o.xer_co, self.o.o, self.o.cr0
- a, b, cry_i, op = self.i.a, self.i.b, self.i.carry_in, self.i.ctx.op
+ cry_o, o, cr0 = self.o.xer_ca, self.o.o, self.o.cr0
+ a, b, cry_i, op = self.i.a, self.i.b, self.i.xer_ca, self.i.ctx.op
# check if op is 32-bit, and get sign bit from operand a
is_32bit = Signal(reset_less=True)
with m.If((op.insn_type == InternalOp.OP_ADD) |
(op.insn_type == InternalOp.OP_CMP)):
# in bit 0, 1+carry_in creates carry into bit 1 and above
- comb += add_a.eq(Cat(cry_i, a, Const(0, 1)))
+ 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_o.eq(add_a + add_b)
###### sticky overflow and context, both pass-through #####
- comb += self.o.xer_so.data.eq(self.i.so)
+ comb += self.o.xer_so.data.eq(self.i.xer_so)
comb += self.o.ctx.eq(self.i.ctx)
return m
comb += target.eq(o)
# Handle carry_out
- comb += self.o.xer_co.data.eq(self.i.xer_co.data)
- comb += self.o.xer_co.ok.eq(op.output_carry)
+ comb += self.o.xer_ca.data.eq(self.i.xer_ca.data)
+ comb += self.o.xer_ca.ok.eq(op.output_carry)
# create condition register cr0 and sticky-overflow
is_zero = Signal(reset_less=True)
super().__init__(pspec)
self.a = Signal(64, reset_less=True) # RA
self.b = Signal(64, reset_less=True) # RB/immediate
- self.so = Signal(reset_less=True)
- self.carry_in = Signal(reset_less=True)
+ self.xer_so = Signal(reset_less=True) # XER bit 32: SO
+ self.xer_ca = Signal(2, reset_less=True) # XER bit 34/45: CA/CA32
def __iter__(self):
yield from super().__iter__()
yield self.a
yield self.b
- yield self.carry_in
- yield self.so
+ yield self.xer_ca
+ yield self.xer_so
def eq(self, i):
lst = super().eq(i)
return lst + [self.a.eq(i.a), self.b.eq(i.b),
- self.carry_in.eq(i.carry_in),
- self.so.eq(i.so)]
+ self.xer_ca.eq(i.xer_ca),
+ self.xer_so.eq(i.xer_so)]
# TODO: ALUIntermediateData which does not have
# cr0, ov, ov32 in it (because they are generated as outputs by
super().__init__(pspec)
self.o = Signal(64, reset_less=True, name="stage_o")
self.cr0 = Data(4, name="cr0")
- self.xer_co = Data(2, name="xer_co") # bit0: co, bit1: co32
+ self.xer_ca = Data(2, name="xer_co") # bit0: ca, bit1: ca32
self.xer_ov = Data(2, name="xer_ov") # bit0: ov, bit1: ov32
self.xer_so = Data(1, name="xer_so")
def __iter__(self):
yield from super().__iter__()
yield self.o
- yield self.xer_co
+ yield self.xer_ca
yield self.cr0
yield self.xer_ov
yield self.xer_so
def eq(self, i):
lst = super().eq(i)
return lst + [self.o.eq(i.o),
- self.xer_co.eq(i.xer_co),
+ self.xer_ca.eq(i.xer_ca),
self.cr0.eq(i.cr0),
self.xer_ov.eq(i.xer_ov), self.xer_so.eq(i.xer_so)]
def set_extra_alu_inputs(alu, dec2, sim):
carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0
- yield alu.p.data_i.carry_in.eq(carry)
+ carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0
+ yield alu.p.data_i.xer_ca[0].eq(carry)
+ yield alu.p.data_i.xer_ca[1].eq(carry32)
so = 1 if sim.spr['XER'][XER_bits['SO']] else 0
- yield alu.p.data_i.so.eq(so)
+ yield alu.p.data_i.xer_so.eq(so)
# This test bench is a bit different than is usual. Initially when I
write_reg_idx = yield pdecode2.e.write_reg.data
expected = simulator.gpr(write_reg_idx).value
print(f"expected {expected:x}, actual: {alu_out:x}")
- self.assertEqual(expected, alu_out)
+ self.assertEqual(expected, alu_out, code)
yield from self.check_extra_alu_outputs(alu, pdecode2,
simulator, code)
cry_out = yield dec2.e.output_carry
if cry_out:
expected_carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0
- real_carry = yield alu.n.data_o.xer_co.data[0] # XXX CO not CO32
+ real_carry = yield alu.n.data_o.xer_ca.data[0] # XXX CO not CO32
self.assertEqual(expected_carry, real_carry, code)
expected_carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0
- real_carry32 = yield alu.n.data_o.xer_co.data[1] # XXX CO32
+ real_carry32 = yield alu.n.data_o.xer_ca.data[1] # XXX CO32
self.assertEqual(expected_carry32, real_carry32, code)
###### sticky overflow and context, both pass-through #####
- comb += self.o.xer_so.data.eq(self.i.so)
+ comb += self.o.xer_so.data.eq(self.i.xer_so)
comb += self.o.ctx.eq(self.i.ctx)
return m
super().__init__(pspec)
self.a = Signal(64, reset_less=True) # RA
self.b = Signal(64, reset_less=True) # RB/immediate
- self.so = Signal(reset_less=True)
- self.carry_in = Signal(reset_less=True)
+ self.xer_so = Signal(reset_less=True) # XER bit 32: SO
+ self.xer_ca = Signal(2, reset_less=True) # XER bit 34/45: CA/CA32
def __iter__(self):
yield from super().__iter__()
yield self.a
yield self.b
- yield self.carry_in
- yield self.so
+ yield self.xer_ca
+ yield self.xer_so
def eq(self, i):
lst = super().eq(i)
return lst + [self.a.eq(i.a), self.b.eq(i.b),
- self.carry_in.eq(i.carry_in),
- self.so.eq(i.so)]
+ self.xer_ca.eq(i.xer_ca),
+ self.xer_so.eq(i.xer_so)]
def set_extra_alu_inputs(alu, dec2, sim):
carry = 1 if sim.spr['XER'][XER_bits['CA']] else 0
- yield alu.p.data_i.carry_in.eq(carry)
+ carry32 = 1 if sim.spr['XER'][XER_bits['CA32']] else 0
+ yield alu.p.data_i.xer_ca[0].eq(carry)
+ yield alu.p.data_i.xer_ca[1].eq(carry32)
so = 1 if sim.spr['XER'][XER_bits['SO']] else 0
- yield alu.p.data_i.so.eq(so)
+ yield alu.p.data_i.xer_so.eq(so)
# This test bench is a bit different than is usual. Initially when I