07fb0180de7d73f627386a3d847dd56ded43aadd
1 # This stage is intended to do most of the work of executing the ALU
2 # instructions. This would be like the additions, logical operations,
3 # and shifting, as well as carry and overflow generation. This module
4 # however should not gate the carry or overflow, that's up to the
6 from nmigen
import (Module
, Signal
)
7 from nmutil
.pipemodbase
import PipeModBase
8 from soc
.alu
.pipe_data
import ALUInputData
, ALUOutputData
9 from ieee754
.part
.partsig
import PartitionedSignal
10 from soc
.decoder
.power_enums
import InternalOp
13 class ALUMainStage(PipeModBase
):
14 def __init__(self
, pspec
):
15 super().__init
__(pspec
, "main")
18 return ALUInputData(self
.pspec
)
21 return ALUOutputData(self
.pspec
)
23 def elaborate(self
, platform
):
27 add_output
= Signal(self
.i
.a
.width
+ 1, reset_less
=True)
28 comb
+= add_output
.eq(self
.i
.a
+ self
.i
.b
+ self
.i
.carry_in
)
31 with m
.Switch(self
.i
.ctx
.op
.insn_type
):
32 with m
.Case(InternalOp
.OP_ADD
):
33 comb
+= self
.o
.o
.eq(add_output
[0:64])
34 comb
+= self
.o
.carry_out
.eq(add_output
[64])
35 with m
.Case(InternalOp
.OP_AND
):
36 comb
+= self
.o
.o
.eq(self
.i
.a
& self
.i
.b
)
37 with m
.Case(InternalOp
.OP_OR
):
38 comb
+= self
.o
.o
.eq(self
.i
.a | self
.i
.b
)
39 with m
.Case(InternalOp
.OP_XOR
):
40 comb
+= self
.o
.o
.eq(self
.i
.a ^ self
.i
.b
)
42 ###### sticky overflow and context, both pass-through #####
44 comb
+= so
.eq(self
.i
.so
)
45 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)