From: Michael Nolan Date: Wed, 13 May 2020 18:52:26 +0000 (-0400) Subject: Add missing input stage and pipe_data X-Git-Tag: div_pipeline~1257 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e9364a86ddb60c12ad187beeaf200a1ff68ab9f1;p=soc.git Add missing input stage and pipe_data --- diff --git a/src/soc/shift_rot/input_stage.py b/src/soc/shift_rot/input_stage.py new file mode 100644 index 00000000..72e4c925 --- /dev/null +++ b/src/soc/shift_rot/input_stage.py @@ -0,0 +1,58 @@ +# 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, 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.shift_rot.pipe_data import ShiftRotInputData +from soc.decoder.power_enums import CryIn + + +class ShiftRotInputStage(PipeModBase): + def __init__(self, pspec): + super().__init__(pspec, "input") + + def ispec(self): + return ShiftRotInputData(self.pspec) + + def ospec(self): + return ShiftRotInputData(self.pspec) + + 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.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) + 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.carry_in.eq(0) + with m.Case(CryIn.ONE): + comb += self.o.carry_in.eq(1) + with m.Case(CryIn.CA): + comb += self.o.carry_in.eq(self.i.carry_in) + + ##### sticky overflow and context (both pass-through) ##### + + comb += self.o.so.eq(self.i.so) + comb += self.o.ctx.eq(self.i.ctx) + + return m diff --git a/src/soc/shift_rot/pipe_data.py b/src/soc/shift_rot/pipe_data.py new file mode 100644 index 00000000..291ecf0a --- /dev/null +++ b/src/soc/shift_rot/pipe_data.py @@ -0,0 +1,42 @@ +from nmigen import Signal, Const +from nmutil.dynamicpipe import SimpleHandshakeRedir +from soc.alu.alu_input_record import CompALUOpSubset +from ieee754.fpcommon.getop import FPPipeContext + + +class IntegerData: + + def __init__(self, pspec): + self.ctx = FPPipeContext(pspec) + self.muxid = self.ctx.muxid + + def __iter__(self): + yield from self.ctx + + def eq(self, i): + return [self.ctx.eq(i.ctx)] + + +class ShiftRotInputData(IntegerData): + def __init__(self, pspec): + super().__init__(pspec) + self.ra = Signal(64, reset_less=True) # RA + self.rs = Signal(64, reset_less=True) # RS + self.rb = Signal(64, reset_less=True) # RB/immediate + self.so = Signal(reset_less=True) + self.carry_in = Signal(reset_less=True) + + def __iter__(self): + yield from super().__iter__() + yield self.ra + yield self.rs + yield self.rb + yield self.carry_in + yield self.so + + def eq(self, i): + lst = super().eq(i) + return lst + [self.rs.eq(i.rs), self.ra.eq(i.ra), + self.rb.eq(i.rb), + self.carry_in.eq(i.carry_in), + self.so.eq(i.so)]