--- /dev/null
+# This stage is intended to adjust the input data before sending it to
+# the acutal ALU. Things like handling inverting the input, carry_in
+# generation for subtraction, should happen here
+from nmigen import (Module, Signal)
+from nmutil.pipemodbase import PipeModBase
+from soc.decoder.power_enums import InternalOp
+from soc.decoder.power_enums import CryIn
+
+
+class CommonInputStage(PipeModBase):
+
+ def elaborate(self, platform):
+ m = Module()
+ comb = m.d.comb
+
+ ##### operand A #####
+
+ # operand a to be as-is or inverted
+ a = Signal.like(self.i.a)
+
+ with m.If(self.i.ctx.op.invert_a):
+ comb += a.eq(~self.i.a)
+ with m.Else():
+ comb += a.eq(self.i.a)
+
+ comb += self.o.a.eq(a)
+
+ ##### carry-in #####
+
+ # either copy incoming carry or set to 1/0 as defined by op
+ with m.Switch(self.i.ctx.op.input_carry):
+ with m.Case(CryIn.ZERO):
+ comb += self.o.xer_ca.eq(0b00)
+ with m.Case(CryIn.ONE):
+ comb += self.o.xer_ca.eq(0b11) # XER CA/CA32
+ with m.Case(CryIn.CA):
+ comb += self.o.xer_ca.eq(self.i.xer_ca)
+
+ ##### sticky overflow and context (both pass-through) #####
+
+ comb += self.o.xer_so.eq(self.i.xer_so)
+ comb += self.o.ctx.eq(self.i.ctx)
+
+ return m
comb = m.d.comb
rec = CompALUOpSubset()
- recwidth = 0
# Setup random inputs for dut.op
for p in rec.ports():
- width = p.width
- recwidth += width
- comb += p.eq(AnyConst(width))
+ comb += p.eq(AnyConst(p.width))
- pspec = ALUPipeSpec(id_wid=2, op_wid=recwidth)
+ pspec = ALUPipeSpec(id_wid=2)
m.submodules.dut = dut = ShiftRotMainStage(pspec)
# convenience variables
a = dut.i.rs
b = dut.i.rb
- ra = dut.i.ra
+ ra = dut.i.a
carry_in = dut.i.xer_ca[0]
carry_in32 = dut.i.xer_ca[1]
so_in = dut.i.xer_so
# the acutal ALU. Things like handling inverting the input, carry_in
# generation for subtraction, and handling of immediates should happen
# here
-from nmigen import (Module, Signal, Cat, Const, Mux, Repl, signed,
- unsigned)
-from nmutil.pipemodbase import PipeModBase
-from soc.decoder.power_enums import InternalOp
+from soc.fu.common_input_stage import CommonInputStage
from soc.fu.shift_rot.pipe_data import ShiftRotInputData
-from soc.decoder.power_enums import CryIn
-class ShiftRotInputStage(PipeModBase):
+class ShiftRotInputStage(CommonInputStage):
def __init__(self, pspec):
super().__init__(pspec, "input")
return ShiftRotInputData(self.pspec)
def elaborate(self, platform):
- m = Module()
+ m = super().elaborate(platform) # handles A, carry and sticky overflow
comb = m.d.comb
- ##### operand A #####
-
- # operand a to be as-is or inverted
- a = Signal.like(self.i.ra)
-
- with m.If(self.i.ctx.op.invert_a):
- comb += a.eq(~self.i.ra)
- with m.Else():
- comb += a.eq(self.i.ra)
-
- comb += self.o.ra.eq(a)
+ # operands ra and rb
comb += self.o.rb.eq(self.i.rb)
comb += self.o.rs.eq(self.i.rs)
-
- ##### carry-in #####
-
- # either copy incoming carry or set to 1/0 as defined by op
- with m.Switch(self.i.ctx.op.input_carry):
- with m.Case(CryIn.ZERO):
- comb += self.o.xer_ca.eq(0b00)
- with m.Case(CryIn.ONE):
- comb += self.o.xer_ca.eq(0b11) # XER CA/CA32
- with m.Case(CryIn.CA):
- comb += self.o.xer_ca.eq(self.i.xer_ca)
-
- ##### sticky overflow and context (both pass-through) #####
-
- comb += self.o.xer_so.eq(self.i.xer_so)
- comb += self.o.ctx.eq(self.i.ctx)
-
return m
def elaborate(self, platform):
m = Module()
comb = m.d.comb
+ op = self.i.ctx.op
# obtain me and mb fields from instruction.
m_fields = self.fields.instrs['M']
rotator.mb.eq(mb),
rotator.mb_extra.eq(mb_extra),
rotator.rs.eq(self.i.rs),
- rotator.ra.eq(self.i.ra),
+ rotator.ra.eq(self.i.a),
rotator.shift.eq(self.i.rb),
- rotator.is_32bit.eq(self.i.ctx.op.is_32bit),
- rotator.arith.eq(self.i.ctx.op.is_signed),
+ rotator.is_32bit.eq(op.is_32bit),
+ rotator.arith.eq(op.is_signed),
]
# instruction rotate type
mode = Signal(3, reset_less=True)
- with m.Switch(self.i.ctx.op.insn_type):
+ with m.Switch(op.insn_type):
with m.Case(InternalOp.OP_SHL): comb += mode.eq(0b000)
with m.Case(InternalOp.OP_SHR): comb += mode.eq(0b001) # R-shift
with m.Case(InternalOp.OP_RLC): comb += mode.eq(0b110) # clear LR
class ShiftRotInputData(IntegerData):
- regspec = [('INT', 'ra', '0:63'),
+ regspec = [('INT', 'a', '0:63'),
('INT', 'rs', '0:63'),
('INT', 'rb', '0:63'),
('XER', 'xer_so', '32'),
('XER', 'xer_ca', '34,45')]
def __init__(self, pspec):
super().__init__(pspec)
- self.ra = Signal(64, reset_less=True) # RA
+ self.a = Signal(64, reset_less=True) # RA
self.rs = Signal(64, reset_less=True) # RS
self.rb = Signal(64, reset_less=True) # RB/immediate
self.xer_so = Signal(reset_less=True) # XER bit 32: SO
def __iter__(self):
yield from super().__iter__()
- yield self.ra
+ yield self.a
yield self.rs
yield self.rb
yield self.xer_ca
def eq(self, i):
lst = super().eq(i)
- return lst + [self.rs.eq(i.rs), self.ra.eq(i.ra),
+ return lst + [self.rs.eq(i.rs), self.a.eq(i.a),
self.rb.eq(i.rb),
self.xer_ca.eq(i.xer_ca),
self.xer_so.eq(i.xer_so)]
else:
data2 = 0
- yield alu.p.data_i.ra.eq(data1)
+ yield alu.p.data_i.a.eq(data1)
yield alu.p.data_i.rb.eq(data2)
yield alu.p.data_i.rs.eq(data3)