1253795708f6f4e86c01378c0a1eca7a4cca441c
[soc.git] / src / soc / pipe / alu / output_stage.py
1 # This stage is intended to handle the gating of carry and overflow
2 # out, summary overflow generation, and updating the condition
3 # register
4 from nmigen import (Module, Signal, Cat, Repl)
5 from nmutil.pipemodbase import PipeModBase
6 from soc.alu.pipe_data import ALUInputData, ALUOutputData
7 from ieee754.part.partsig import PartitionedSignal
8 from soc.decoder.power_enums import InternalOp
9
10
11 class ALUOutputStage(PipeModBase):
12 def __init__(self, pspec):
13 super().__init__(pspec, "output")
14
15 def ispec(self):
16 return ALUOutputData(self.pspec) # TODO: ALUIntermediateData
17
18 def ospec(self):
19 return ALUOutputData(self.pspec)
20
21 def elaborate(self, platform):
22 m = Module()
23 comb = m.d.comb
24
25 # op requests inversion of the output
26 o = Signal.like(self.i.o)
27 with m.If(self.i.ctx.op.invert_out):
28 comb += o.eq(~self.i.o)
29 with m.Else():
30 comb += o.eq(self.i.o)
31
32 # create condition register cr0 and sticky-overflow
33 is_zero = Signal(reset_less=True)
34 is_positive = Signal(reset_less=True)
35 is_negative = Signal(reset_less=True)
36 msb_test = Signal(reset_less=True) # set equal to MSB, invert if OP=CMP
37 is_cmp = Signal(reset_less=True) # true if OP=CMP
38 so = Signal(reset_less=True)
39
40 # TODO: if o[63] is XORed with "operand == OP_CMP"
41 # that can be used as a test
42 # see https://bugs.libre-soc.org/show_bug.cgi?id=305#c60
43
44 comb += is_cmp.eq(self.i.ctx.op.insn_type == InternalOp.OP_CMP)
45 comb += msb_test.eq(o[-1] ^ is_cmp)
46 comb += is_zero.eq(o == 0)
47 comb += is_positive.eq(~is_zero & ~msb_test)
48 comb += is_negative.eq(~is_zero & msb_test)
49 comb += so.eq(self.i.so | self.i.ov)
50
51 comb += self.o.o.eq(o)
52 with m.If(self.i.ctx.op.insn_type != InternalOp.OP_CMPEQB):
53 comb += self.o.cr0.eq(Cat(so, is_zero, is_positive, is_negative))
54 with m.Else():
55 comb += self.o.cr0.eq(self.i.cr0)
56
57 comb += self.o.so.eq(so)
58
59 comb += self.o.ctx.eq(self.i.ctx)
60
61 return m