fd3fd1edd78c097acc7d242781e52ac317fac6dc
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
.fu
.alu
.pipe_data
import ALUInputData
10 from soc
.decoder
.power_enums
import CryIn
13 class ALUInputStage(PipeModBase
):
14 def __init__(self
, pspec
):
15 super().__init
__(pspec
, "input")
18 return ALUInputData(self
.pspec
)
21 return ALUInputData(self
.pspec
)
23 def elaborate(self
, platform
):
30 # operand a to be as-is or inverted
31 a
= Signal
.like(self
.i
.a
)
33 with m
.If(ctx
.op
.invert_a
):
34 comb
+= a
.eq(~self
.i
.a
)
36 comb
+= a
.eq(self
.i
.a
)
38 comb
+= self
.o
.a
.eq(a
)
39 comb
+= self
.o
.b
.eq(self
.i
.b
)
43 # either copy incoming carry or set to 1/0 as defined by op
44 with m
.Switch(ctx
.op
.input_carry
):
45 with m
.Case(CryIn
.ZERO
):
46 comb
+= self
.o
.carry_in
.eq(0)
47 with m
.Case(CryIn
.ONE
):
48 comb
+= self
.o
.carry_in
.eq(1)
49 with m
.Case(CryIn
.CA
):
50 comb
+= self
.o
.carry_in
.eq(self
.i
.carry_in
)
52 ##### sticky overflow and context (both pass-through) #####
54 comb
+= self
.o
.so
.eq(self
.i
.so
)
55 comb
+= self
.o
.ctx
.eq(ctx
)