1 # This stage is intended to handle the gating of carry and overflow
2 # out, summary overflow generation, and updating the condition
4 from nmigen
import (Module
, Signal
, Cat
, Repl
)
5 from soc
.fu
.alu
.pipe_data
import ALUInputData
, ALUOutputData
6 from soc
.fu
.common_output_stage
import CommonOutputStage
7 from ieee754
.part
.partsig
import PartitionedSignal
8 from soc
.decoder
.power_enums
import InternalOp
11 class ALUOutputStage(CommonOutputStage
):
14 return ALUOutputData(self
.pspec
)
17 return ALUOutputData(self
.pspec
)
19 def elaborate(self
, platform
):
20 m
= super().elaborate(platform
)
23 xer_so_i
, xer_ov_i
= self
.i
.xer_so
.data
, self
.i
.xer_ov
.data
25 # XXX see https://bugs.libre-soc.org/show_bug.cgi?id=319#c5
26 comb
+= self
.so
.eq(xer_so_i
[0] | xer_ov_i
[0]) # SO
28 # copy overflow and sticky-overflow. indicate to CompALU if they
29 # are actually required (oe enabled/set) otherwise the CompALU
30 # can (will) ignore them.
31 oe
= Signal(reset_less
=True)
32 comb
+= oe
.eq(op
.oe
.oe
& op
.oe
.oe_ok
)
34 comb
+= self
.o
.xer_so
.data
.eq(self
.so
)
35 comb
+= self
.o
.xer_so
.ok
.eq(1)
36 comb
+= self
.o
.xer_ov
.data
.eq(xer_ov_i
)
37 comb
+= self
.o
.xer_ov
.ok
.eq(1) # OV/32 is to be set