1 # This stage is intended to adjust the input data before sending it to
2 # the acutal ALU. Things like handling inverting the input, carry_in
3 # generation for subtraction, and handling of immediates should happen
5 from nmigen
import (Module
, Signal
, Cat
, Const
, Mux
, Repl
, signed
,
7 from nmutil
.pipemodbase
import PipeModBase
8 from soc
.decoder
.power_enums
import InternalOp
9 from soc
.shift_rot
.pipe_data
import ShiftRotInputData
10 from soc
.decoder
.power_enums
import CryIn
13 class ShiftRotInputStage(PipeModBase
):
14 def __init__(self
, pspec
):
15 super().__init
__(pspec
, "input")
18 return ShiftRotInputData(self
.pspec
)
21 return ShiftRotInputData(self
.pspec
)
23 def elaborate(self
, platform
):
29 # operand a to be as-is or inverted
30 a
= Signal
.like(self
.i
.ra
)
32 with m
.If(self
.i
.ctx
.op
.invert_a
):
33 comb
+= a
.eq(~self
.i
.ra
)
35 comb
+= a
.eq(self
.i
.ra
)
37 comb
+= self
.o
.ra
.eq(a
)
38 comb
+= self
.o
.rb
.eq(self
.i
.rb
)
39 comb
+= self
.o
.rs
.eq(self
.i
.rs
)
44 # either copy incoming carry or set to 1/0 as defined by op
45 with m
.Switch(self
.i
.ctx
.op
.input_carry
):
46 with m
.Case(CryIn
.ZERO
):
47 comb
+= self
.o
.carry_in
.eq(0)
48 with m
.Case(CryIn
.ONE
):
49 comb
+= self
.o
.carry_in
.eq(1)
50 with m
.Case(CryIn
.CA
):
51 comb
+= self
.o
.carry_in
.eq(self
.i
.carry_in
)
53 ##### sticky overflow and context (both pass-through) #####
55 comb
+= self
.o
.so
.eq(self
.i
.so
)
56 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)