d5916a0a7a0aa803f5f0a3a39b93a4d4d1b86b10
[soc.git] / src / soc / fu / common_input_stage.py
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, should happen here
4 from nmigen import (Module, Signal)
5 from nmutil.pipemodbase import PipeModBase
6 from soc.decoder.power_enums import InternalOp
7 from soc.decoder.power_enums import CryIn
8
9
10 class CommonInputStage(PipeModBase):
11
12 def elaborate(self, platform):
13 m = Module()
14 comb = m.d.comb
15 op = self.i.ctx.op
16
17 ##### operand A #####
18
19 # operand a to be as-is or inverted
20 a = Signal.like(self.i.a)
21
22 if hasattr(op, "invert_a"):
23 with m.If(op.invert_a):
24 comb += a.eq(~self.i.a)
25 with m.Else():
26 comb += a.eq(self.i.a)
27 else:
28 comb += a.eq(self.i.a)
29
30 comb += self.o.a.eq(a)
31
32 ##### carry-in #####
33
34 # either copy incoming carry or set to 1/0 as defined by op
35 if hasattr(self.i, "xer_ca"): # hack (for now - for LogicalInputData)
36 with m.Switch(op.input_carry):
37 with m.Case(CryIn.ZERO):
38 comb += self.o.xer_ca.eq(0b00)
39 with m.Case(CryIn.ONE):
40 comb += self.o.xer_ca.eq(0b11) # XER CA/CA32
41 with m.Case(CryIn.CA):
42 comb += self.o.xer_ca.eq(self.i.xer_ca)
43
44 ##### sticky overflow and context (both pass-through) #####
45
46 if hasattr(self.o, "xer_so"): # hack (for now - for LogicalInputData)
47 with m.If(op.oe.oe_ok):
48 comb += self.o.xer_so.eq(self.i.xer_so)
49 comb += self.o.ctx.eq(self.i.ctx)
50
51 return m