2 # Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
3 # Copyright (C) 2020 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
5 # This stage is intended to do Condition Register instructions (and ISEL)
6 # and output, as well as carry and overflow generation.
7 # NOTE: with the exception of mtcrf and mfcr, we really should be doing
8 # the field decoding which
9 # selects which bits of CR are to be read / written, back in the
10 # decoder / insn-isue, have both self.i.cr and self.o.cr
11 # be broken down into 4-bit-wide "registers", with their
12 # own "Register File" (indexed by bt, ba and bb),
13 # exactly how INT regs are done (by RA, RB, RS and RT)
14 # however we are pushed for time so do it as *one* register.
16 from nmigen
import (Module
, Signal
, Cat
, Repl
, Mux
, Const
, Array
)
17 from nmutil
.pipemodbase
import PipeModBase
18 from soc
.fu
.cr
.pipe_data
import CRInputData
, CROutputData
19 from openpower
.decoder
.power_enums
import MicrOp
21 from openpower
.decoder
.power_fields
import DecodeFields
22 from openpower
.decoder
.power_fieldsn
import SignalBitRange
25 class CRMainStage(PipeModBase
):
26 def __init__(self
, pspec
):
27 super().__init
__(pspec
, "main")
28 self
.fields
= DecodeFields(SignalBitRange
, [self
.i
.ctx
.op
.insn
])
29 self
.fields
.create_specs()
32 return CRInputData(self
.pspec
)
35 return CROutputData(self
.pspec
)
37 def elaborate(self
, platform
):
41 a
, b
, full_cr
= self
.i
.a
, self
.i
.b
, self
.i
.full_cr
42 cr_a
, cr_b
, cr_c
= self
.i
.cr_a
, self
.i
.cr_b
, self
.i
.cr_c
43 cr_o
, full_cr_o
, rt_o
= self
.o
.cr
, self
.o
.full_cr
, self
.o
.o
45 xl_fields
= self
.fields
.FormXL
47 # Generate array of bits for cr_a, cr_b and cr_c
48 cr_a_arr
= Array([cr_a
[i
] for i
in range(4)])
49 cr_b_arr
= Array([cr_b
[i
] for i
in range(4)])
50 cr_o_arr
= Array([cr_o
[i
] for i
in range(4)])
52 with m
.Switch(op
.insn_type
):
54 with m
.Case(MicrOp
.OP_MCRF
):
55 # MCRF copies the 4 bits of crA to crB (for instance
57 # Since it takes in a 4 bit cr, and outputs a 4 bit
58 # cr, we don't have to do anything special
60 comb
+= cr_o
.ok
.eq(1) # indicate "this CR has changed"
62 # ##### crand, cror, crnor etc. #####
63 with m
.Case(MicrOp
.OP_CROP
):
64 # crand/cror and friends get decoded to the same opcode, but
65 # one of the fields inside the instruction is a 4 bit lookup
66 # table. This lookup table gets indexed by bits a and b from
67 # the CR to determine what the resulting bit should be.
69 # Grab the lookup table for cr_op type instructions
70 lut
= Signal(4, reset_less
=True)
71 # There's no field, just have to grab it directly from the insn
72 comb
+= lut
.eq(op
.insn
[6:10])
74 # Get the bit selector fields from the
75 # instruction. This operation takes in the little CR
76 # bitfields, so these fields need to get truncated to
77 # the least significant 2 bits
81 bt
= Signal(2, reset_less
=True)
82 ba
= Signal(2, reset_less
=True)
83 bb
= Signal(2, reset_less
=True)
85 # Stupid bit ordering stuff. Because POWER.
86 comb
+= bt
.eq(3-BT
[0:2])
87 comb
+= ba
.eq(3-BA
[0:2])
88 comb
+= bb
.eq(3-BB
[0:2])
90 # Extract the two input bits from the CRs
91 bit_a
= Signal(reset_less
=True)
92 bit_b
= Signal(reset_less
=True)
93 comb
+= bit_a
.eq(cr_a_arr
[ba
])
94 comb
+= bit_b
.eq(cr_b_arr
[bb
])
96 # look up the output bit in the lookup table
98 comb
+= bit_o
.eq(Mux(bit_b
,
99 Mux(bit_a
, lut
[3], lut
[1]),
100 Mux(bit_a
, lut
[2], lut
[0])))
102 # may have one bit modified by OP_CROP. copy the other 3
103 comb
+= cr_o
.data
.eq(cr_c
)
104 # insert the (index-targetted) output bit into 4-bit CR output
105 comb
+= cr_o_arr
[bt
].eq(bit_o
)
106 comb
+= cr_o
.ok
.eq(1) # indicate "this CR has changed"
109 with m
.Case(MicrOp
.OP_MTCRF
):
110 # mtocrf and mtcrf are essentially identical. PowerDecoder2
111 # takes care of the mask, by putting FXM (as-is or one-hot)
112 # into the CR regfile "full_cr" write-enable, in conjunction
113 # with regspec_decode_write
114 comb
+= full_cr_o
.data
.eq(a
[0:32])
115 comb
+= full_cr_o
.ok
.eq(1) # indicate "this CR has changed"
118 with m
.Case(MicrOp
.OP_MFCR
):
119 # output register RT. again, like mtocrf/mtcrf, PowerDecoder2
120 # takes care of the masking, this time by putting FXM (or 1hot)
121 # into the CR regfile "full_cr" *read* enable, in conjunction
122 # with regspect_decode_read.
123 comb
+= rt_o
.data
.eq(full_cr
)
124 comb
+= rt_o
.ok
.eq(1) # indicate "INT reg changed"
127 with m
.Case(MicrOp
.OP_ISEL
):
128 # just like in branch, CR0-7 is incoming into cr_a, we
129 # need to select from the last 2 bits of BC
130 a_fields
= self
.fields
.FormA
131 BC
= Signal(2, reset_less
=True)
132 comb
+= BC
.eq(a_fields
.BC
[0:2])
133 cr_bits
= Array([cr_a
[3-i
] for i
in range(4)])
135 # The bit of (cr_a=CR0-7) selected by BC
136 cr_bit
= Signal(reset_less
=True)
137 comb
+= cr_bit
.eq(cr_bits
[BC
])
139 # select a or b as output
140 comb
+= rt_o
.eq(Mux(cr_bit
, a
, b
))
141 comb
+= rt_o
.ok
.eq(1) # indicate "INT reg changed"
143 with m
.Case(MicrOp
.OP_SETB
):
145 comb
+= rt_o
.data
.eq(-1)
146 with m
.Elif(cr_a
[2]):
147 comb
+= rt_o
.data
.eq(1)
149 comb
+= rt_o
.data
.eq(0)
150 comb
+= rt_o
.ok
.eq(1)
152 comb
+= self
.o
.ctx
.eq(self
.i
.ctx
)