1 # This stage is intended to do most of the work of executing Logical
2 # instructions. This is OR, AND and XOR, however input and output
3 # stages also perform bit-negation on input(s) and output, as well as
4 # carry and overflow generation.
5 # This module however should not gate the carry or overflow, that's up
8 from nmigen
import (Module
, Signal
, Cat
, Repl
, Mux
, Const
)
9 from nmutil
.pipemodbase
import PipeModBase
10 from soc
.logical
.pipe_data
import ALUInputData
11 from soc
.alu
.pipe_data
import ALUOutputData
12 from ieee754
.part
.partsig
import PartitionedSignal
13 from soc
.decoder
.power_enums
import InternalOp
16 class LogicalMainStage(PipeModBase
):
17 def __init__(self
, pspec
):
18 super().__init
__(pspec
, "main")
21 return ALUInputData(self
.pspec
)
24 return ALUOutputData(self
.pspec
) # TODO: ALUIntermediateData
26 def elaborate(self
, platform
):
30 ##########################
31 # main switch for logic ops AND, OR and XOR, parity, and popcount
33 with m
.Switch(self
.i
.ctx
.op
.insn_type
):
34 with m
.Case(InternalOp
.OP_AND
):
35 comb
+= self
.o
.o
.eq(self
.i
.a
& self
.i
.b
)
36 with m
.Case(InternalOp
.OP_OR
):
37 comb
+= self
.o
.o
.eq(self
.i
.a | self
.i
.b
)
38 with m
.Case(InternalOp
.OP_XOR
):
39 comb
+= self
.o
.o
.eq(self
.i
.a ^ self
.i
.b
)
40 ###### popcount #######
41 # TODO with m.Case(InternalOp.OP_POPCNT):
43 # TODO with m.Case(InternalOp.OP_PRTY):
45 ###### sticky overflow and context, both pass-through #####
47 comb
+= self
.o
.so
.eq(self
.i
.so
)
48 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)