1 # This stage is intended to do most of the work of executing Logical
2 # instructions. This is OR, AND, XOR, POPCNT, PRTY, CMPB, BPERMD, CNTLZ
3 # however input and output stages also perform bit-negation on input(s)
4 # and output, as well as 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
, Array
)
9 from nmutil
.pipemodbase
import PipeModBase
10 from soc
.cr
.pipe_data
import CRInputData
, CROutputData
11 from ieee754
.part
.partsig
import PartitionedSignal
12 from soc
.decoder
.power_enums
import InternalOp
13 from soc
.countzero
.countzero
import ZeroCounter
15 from soc
.decoder
.power_fields
import DecodeFields
16 from soc
.decoder
.power_fieldsn
import SignalBitRange
19 def array_of(count
, bitwidth
):
21 for i
in range(count
):
22 res
.append(Signal(bitwidth
, reset_less
=True))
26 class CRMainStage(PipeModBase
):
27 def __init__(self
, pspec
):
28 super().__init
__(pspec
, "main")
29 self
.fields
= DecodeFields(SignalBitRange
, [self
.i
.ctx
.op
.insn
])
30 self
.fields
.create_specs()
33 return CRInputData(self
.pspec
)
36 return CROutputData(self
.pspec
)
38 def elaborate(self
, platform
):
42 xl_fields
= self
.fields
.instrs
['XL']
44 cr_output
= Signal
.like(self
.i
.cr
)
45 comb
+= cr_output
.eq(self
.i
.cr
)
47 # Generate array for cr input so bits can be selected
48 cr_arr
= Array([Signal(name
=f
"cr_arr_{i}") for i
in range(32)])
50 comb
+= cr_arr
[i
].eq(self
.i
.cr
[31-i
])
52 # Generate array for cr output so the bit to write to can be
53 # selected by a signal
54 cr_out_arr
= Array([Signal(name
=f
"cr_out_{i}") for i
in range(32)])
56 comb
+= cr_output
[31-i
].eq(cr_out_arr
[i
])
57 comb
+= cr_out_arr
[i
].eq(cr_arr
[i
])
60 # crand/cror and friends get decoded to the same opcode, but
61 # one of the fields inside the instruction is a 4 bit lookup
62 # table. This lookup table gets indexed by bits a and b from
63 # the CR to determine what the resulting bit should be.
65 # Grab the lookup table for cr_op type instructions
66 lut
= Signal(4, reset_less
=True)
67 # There's no field, just have to grab it directly from the insn
68 comb
+= lut
.eq(self
.i
.ctx
.op
.insn
[6:10])
71 with m
.Switch(op
.insn_type
):
72 with m
.Case(InternalOp
.OP_MCRF
):
73 # MCRF copies the 4 bits of crA to crB (for instance
77 bf
= Signal(xl_fields
['BF'][0:-1].shape())
78 comb
+= bf
.eq(xl_fields
['BF'][0:-1])
80 bfa
= Signal(xl_fields
['BFA'][0:-1].shape())
81 comb
+= bfa
.eq(xl_fields
['BFA'][0:-1])
84 comb
+= cr_out_arr
[bf
*4 + i
].eq(cr_arr
[bfa
*4 + i
])
85 with m
.Case(InternalOp
.OP_CROP
):
86 # Get the bit selector fields from the instruction
87 bt
= Signal(xl_fields
['BT'][0:-1].shape())
88 comb
+= bt
.eq(xl_fields
['BT'][0:-1])
89 ba
= Signal(xl_fields
['BA'][0:-1].shape())
90 comb
+= ba
.eq(xl_fields
['BA'][0:-1])
91 bb
= Signal(xl_fields
['BB'][0:-1].shape())
92 comb
+= bb
.eq(xl_fields
['BB'][0:-1])
94 # Extract the two input bits from the CR
95 bit_a
= Signal(reset_less
=True)
96 bit_b
= Signal(reset_less
=True)
97 comb
+= bit_a
.eq(cr_arr
[ba
])
98 comb
+= bit_b
.eq(cr_arr
[bb
])
100 bit_out
= Signal(reset_less
=True)
102 # Use the two input bits to look up the result in the
104 comb
+= bit_out
.eq(Mux(bit_b
,
105 Mux(bit_a
, lut
[3], lut
[1]),
106 Mux(bit_a
, lut
[2], lut
[0])))
107 # Set the output to the result above
108 comb
+= cr_out_arr
[bt
].eq(bit_out
)
112 comb
+= self
.o
.cr
.eq(cr_output
)
113 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)