All CR tests now working
[soc.git] / src / soc / fu / cr / main_stage.py
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.
11
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
16
17 from soc.decoder.power_fields import DecodeFields
18 from soc.decoder.power_fieldsn import SignalBitRange
19
20
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()
26
27 def ispec(self):
28 return CRInputData(self.pspec)
29
30 def ospec(self):
31 return CROutputData(self.pspec)
32
33 def elaborate(self, platform):
34 m = Module()
35 comb = m.d.comb
36 op = self.i.ctx.op
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
41
42 cr_o = self.o.cr_o
43
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)]))
49
50
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)])
55
56 comb += cr_o.eq(cr_c)
57
58
59 with m.Switch(op.insn_type):
60 ##### mcrf #####
61 with m.Case(InternalOp.OP_MCRF):
62 # MCRF copies the 4 bits of crA to crB (for instance
63 # copying cr2 to cr1)
64 # Since it takes in a 4 bit cr, and outputs a 4 bit
65 # cr, we don't have to do anything special
66 comb += cr_o.eq(cr_a)
67
68
69
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.
76
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])
81
82 # Get the bit selector fields from the
83 # instruction. This operation takes in the little CR
84 # bitfields, so these fields need to get truncated to
85 # the least significant 2 bits
86 BT = xl_fields.BT[0:-1]
87 BA = xl_fields.BA[0:-1]
88 BB = xl_fields.BB[0:-1]
89 bt = Signal(2, reset_less=True)
90 ba = Signal(2, reset_less=True)
91 bb = Signal(2, reset_less=True)
92
93 # Stupid bit ordering stuff
94 comb += bt.eq(3-BT[0:2])
95 comb += ba.eq(3-BA[0:2])
96 comb += bb.eq(3-BB[0:2])
97
98 # Extract the two input bits from the CRs
99 bit_a = Signal(reset_less=True)
100 bit_b = Signal(reset_less=True)
101 comb += bit_a.eq(cr_a_arr[ba])
102 comb += bit_b.eq(cr_b_arr[bb])
103
104 # look up the output bit in the lookup table
105 bit_o = Signal()
106 comb += bit_o.eq(Mux(bit_b,
107 Mux(bit_a, lut[3], lut[1]),
108 Mux(bit_a, lut[2], lut[0])))
109
110 # insert the output bit into the 4-bit CR output
111 comb += cr_o_arr[bt].eq(bit_o)
112
113
114 ##### mtcrf #####
115 with m.Case(InternalOp.OP_MTCRF):
116 # mtocrf and mtcrf are essentially identical
117 # put input (RA) - mask-selected - into output CR, leave
118 # rest of CR alone.
119 comb += self.o.full_cr.eq((a[0:32] & mask) |
120 (self.i.full_cr & ~mask))
121
122 # ##### mfcr #####
123 with m.Case(InternalOp.OP_MFCR):
124 # Ugh. mtocrf and mtcrf have one random bit differentiating
125 # them. This bit is not in any particular field, so this
126 # extracts that bit from the instruction
127 move_one = Signal(reset_less=True)
128 comb += move_one.eq(op.insn[20])
129
130 # mfocrf
131 with m.If(move_one):
132 # output register RT
133 comb += self.o.o.eq(self.i.full_cr & mask)
134 # mfcrf
135 with m.Else():
136 # output register RT
137 comb += self.o.o.eq(self.i.full_cr)
138
139 comb += self.o.ctx.eq(self.i.ctx)
140
141 return m