1 # This stage is intended to do Condition Register instructions
2 # and output, as well as carry and overflow generation.
3 # NOTE: with the exception of mtcrf and mfcr, we really should be doing
4 # the field decoding which
5 # selects which bits of CR are to be read / written, back in the
6 # decoder / insn-isue, have both self.i.cr and self.o.cr
7 # be broken down into 4-bit-wide "registers", with their
8 # own "Register File" (indexed by bt, ba and bb),
9 # exactly how INT regs are done (by RA, RB, RS and RT)
10 # however we are pushed for time so do it as *one* register.
12 from nmigen
import (Module
, Signal
, Cat
, Repl
, Mux
, Const
, Array
)
13 from nmutil
.pipemodbase
import PipeModBase
14 from soc
.fu
.cr
.pipe_data
import CRInputData
, CROutputData
15 from soc
.decoder
.power_enums
import InternalOp
17 from soc
.decoder
.power_fields
import DecodeFields
18 from soc
.decoder
.power_fieldsn
import SignalBitRange
21 class CRMainStage(PipeModBase
):
22 def __init__(self
, pspec
):
23 super().__init
__(pspec
, "main")
24 self
.fields
= DecodeFields(SignalBitRange
, [self
.i
.ctx
.op
.insn
])
25 self
.fields
.create_specs()
28 return CRInputData(self
.pspec
)
31 return CROutputData(self
.pspec
)
33 def elaborate(self
, platform
):
37 a
, full_cr
= self
.i
.a
, self
.i
.full_cr
38 cr_a
, cr_b
, cr_c
= self
.i
.cr_a
, self
.i
.cr_b
, self
.i
.cr_c
39 xl_fields
= self
.fields
.FormXL
40 xfx_fields
= self
.fields
.FormXFX
44 # Generate the mask for mtcrf, mtocrf, and mfocrf
45 # replicate every fxm field in the insn to 4-bit, as a mask
46 FXM
= xfx_fields
.FXM
[0:-1]
47 mask
= Signal(32, reset_less
=True)
48 comb
+= mask
.eq(Cat(*[Repl(FXM
[i
], 4) for i
in range(8)]))
51 # Generate array of bits for cr_a and cr_b
52 cr_a_arr
= Array([cr_a
[i
] for i
in range(4)])
53 cr_b_arr
= Array([cr_b
[i
] for i
in range(4)])
54 cr_o_arr
= Array([cr_o
[i
] for i
in range(4)])
59 with m
.Switch(op
.insn_type
):
61 with m
.Case(InternalOp
.OP_MCRF
):
62 # MCRF copies the 4 bits of crA to crB (for instance
64 # Since it takes in a 4 bit cr, and outputs a 4 bit
65 # cr, we don't have to do anything special
70 # ##### crand, cror, crnor etc. #####
71 with m
.Case(InternalOp
.OP_CROP
):
72 # crand/cror and friends get decoded to the same opcode, but
73 # one of the fields inside the instruction is a 4 bit lookup
74 # table. This lookup table gets indexed by bits a and b from
75 # the CR to determine what the resulting bit should be.
77 # Grab the lookup table for cr_op type instructions
78 lut
= Signal(4, reset_less
=True)
79 # There's no field, just have to grab it directly from the insn
80 comb
+= lut
.eq(op
.insn
[6:10])
82 # Get the bit selector fields from the instruction
83 BT
= xl_fields
.BT
[0:-1]
84 BA
= xl_fields
.BA
[0:-1]
85 BB
= xl_fields
.BB
[0:-1]
86 bt
= Signal(2, reset_less
=True)
87 ba
= Signal(2, reset_less
=True)
88 bb
= Signal(2, reset_less
=True)
90 comb
+= bt
.eq(3-BT
[0:2])
91 comb
+= ba
.eq(3-BA
[0:2])
92 comb
+= bb
.eq(3-BB
[0:2])
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_a_arr
[ba
])
98 comb
+= bit_b
.eq(cr_b_arr
[bb
])
101 comb
+= bit_o
.eq(Mux(bit_b
,
102 Mux(bit_a
, lut
[3], lut
[1]),
103 Mux(bit_a
, lut
[2], lut
[0])))
104 comb
+= cr_o_arr
[bt
].eq(bit_o
)
108 # with m.Case(InternalOp.OP_MTCRF):
109 # # mtocrf and mtcrf are essentially identical
110 # # put input (RA) - mask-selected - into output CR, leave
111 # # rest of CR alone.
112 # comb += cr_o.eq((a[0:32] & mask) | (cr & ~mask))
115 # with m.Case(InternalOp.OP_MFCR):
116 # # Ugh. mtocrf and mtcrf have one random bit differentiating
117 # # them. This bit is not in any particular field, so this
118 # # extracts that bit from the instruction
119 # move_one = Signal(reset_less=True)
120 # comb += move_one.eq(op.insn[20])
123 # with m.If(move_one):
124 # comb += self.o.o.eq(cr & mask) # output register RT
127 # comb += self.o.o.eq(cr) # output register RT
129 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)