reduce regfile ports by creating separate STATE regfile
[soc.git] / src / soc / decoder / power_regspec_map.py
1 """regspec_decode
2
3 functions for the relationship between regspecs and Decode2Execute1Type
4
5 these functions encodes the understanding (relationship) between
6 Regfiles, Computation Units, and the Power ISA Decoder (PowerDecoder2).
7
8 based on the regspec, which contains the register file name and register
9 name, return a tuple of:
10
11 * how the decoder should determine whether the Function Unit needs
12 access to a given Regport or not
13 * which Regfile number on that port should be read to get that data
14 * when it comes to writing: likewise, which Regfile num should be written
15
16 Note that some of the port numbering encoding is *unary*. in the case
17 of "Full Condition Register", it's a full 8-bit mask of read/write-enables.
18 This actually matches directly with the XFX field in MTCR, and at
19 some point that 8-bit mask from the instruction could actually be passed
20 directly through to full_cr (TODO).
21
22 For the INT and CR numbering, these are expressed in binary in the
23 instruction and need to be converted to unary (1<<read_reg1.data).
24 Note however that XFX in MTCR is unary-masked!
25
26 XER regs are implicitly-encoded (hard-coded) based on whether the
27 operation has carry or overflow.
28
29 FAST regfile is, again, implicitly encoded, back in PowerDecode2, based
30 on the type of operation (see DecodeB for an example, where fast_out
31 is set, then carried into read_fast2 in PowerDecode2).
32
33 The SPR regfile on the other hand is *binary*-encoded, and, furthermore,
34 has to be "remapped" to internal SPR Enum indices (see SPRMap in PowerDecode2)
35 see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs
36 """
37 from nmigen import Const
38 from soc.regfile.regfiles import XERRegs, FastRegs, StateRegs
39 from soc.decoder.power_enums import CryIn
40
41
42 def regspec_decode_read(e, regfile, name):
43 """regspec_decode_read
44 """
45
46 # INT regfile
47
48 if regfile == 'INT':
49 # Int register numbering is *unary* encoded
50 if name == 'ra': # RA
51 return e.read_reg1.ok, 1<<e.read_reg1.data
52 if name == 'rb': # RB
53 return e.read_reg2.ok, 1<<e.read_reg2.data
54 if name == 'rc': # RS
55 return e.read_reg3.ok, 1<<e.read_reg3.data
56
57 # CR regfile
58
59 if regfile == 'CR':
60 # CRRegs register numbering is *unary* encoded
61 # *sigh*. numbering inverted on part-CRs. because POWER.
62 if name == 'full_cr': # full CR
63 return e.do.read_cr_whole, 0b11111111
64 if name == 'cr_a': # CR A
65 return e.read_cr1.ok, 1<<(7-e.read_cr1.data)
66 if name == 'cr_b': # CR B
67 return e.read_cr2.ok, 1<<(7-e.read_cr2.data)
68 if name == 'cr_c': # CR C
69 return e.read_cr3.ok, 1<<(7-e.read_cr3.data)
70
71 # XER regfile
72
73 if regfile == 'XER':
74 # XERRegs register numbering is *unary* encoded
75 SO = 1<<XERRegs.SO
76 CA = 1<<XERRegs.CA
77 OV = 1<<XERRegs.OV
78 if name == 'xer_so':
79 return (e.do.oe.oe[0] & e.do.oe.oe_ok) | e.xer_in, SO
80 if name == 'xer_ov':
81 return (e.do.oe.oe[0] & e.do.oe.oe_ok) | e.xer_in, OV
82 if name == 'xer_ca':
83 return (e.do.input_carry == CryIn.CA.value) | e.xer_in, CA
84
85 # STATE regfile
86
87 if regfile == 'STATE':
88 # STATE register numbering is *unary* encoded
89 PC = 1<<StateRegs.PC
90 MSR = 1<<Stateegs.MSR
91 if name in ['cia', 'nia']:
92 return Const(1), PC # TODO: detect read-conditions
93 if name == 'msr':
94 return Const(1), MSR # TODO: detect read-conditions
95
96 # FAST regfile
97
98 if regfile == 'FAST':
99 # FAST register numbering is *unary* encoded
100 CTR = 1<<FastRegs.CTR
101 LR = 1<<FastRegs.LR
102 TAR = 1<<FastRegs.TAR
103 SRR0 = 1<<FastRegs.SRR0
104 SRR1 = 1<<FastRegs.SRR1
105 if name == 'fast1':
106 return e.read_fast1.ok, 1<<e.read_fast1.data
107 if name == 'fast2':
108 return e.read_fast2.ok, 1<<e.read_fast2.data
109
110 # SPR regfile
111
112 if regfile == 'SPR':
113 # SPR register numbering is *binary* encoded
114 if name == 'spr1':
115 return e.read_spr1.ok, e.read_spr1.data
116
117 assert False, "regspec not found %s %s" % (regfile, name)
118
119
120 def regspec_decode_write(e, regfile, name):
121 """regspec_decode_write
122 """
123
124 # INT regfile
125
126 if regfile == 'INT':
127 # Int register numbering is *unary* encoded
128 if name == 'o': # RT
129 return e.write_reg, 1<<e.write_reg.data
130 if name == 'o1': # RA (update mode: LD/ST EA)
131 return e.write_ea, 1<<e.write_ea.data
132
133 # CR regfile
134
135 if regfile == 'CR':
136 # CRRegs register numbering is *unary* encoded
137 # *sigh*. numbering inverted on part-CRs. because POWER.
138 if name == 'full_cr': # full CR
139 return e.do.write_cr_whole, 0b11111111
140 if name == 'cr_a': # CR A
141 return e.write_cr, 1<<(7-e.write_cr.data)
142
143 # XER regfile
144
145 if regfile == 'XER':
146 # XERRegs register numbering is *unary* encoded
147 SO = 1<<XERRegs.SO
148 CA = 1<<XERRegs.CA
149 OV = 1<<XERRegs.OV
150 if name == 'xer_so':
151 return e.xer_out, SO # hmmm
152 if name == 'xer_ov':
153 return e.xer_out, OV # hmmm
154 if name == 'xer_ca':
155 return e.xer_out, CA # hmmm
156
157 # STATE regfile
158
159 if regfile == 'STATE':
160 # STATE register numbering is *unary* encoded
161 PC = 1<<StateRegs.PC
162 MSR = 1<<StateRegs.MSR
163 if name in ['cia', 'nia']:
164 return None, PC # hmmm
165 if name == 'msr':
166 return None, MSR # hmmm
167
168 # FAST regfile
169
170 if regfile == 'FAST':
171 # FAST register numbering is *unary* encoded
172 CTR = 1<<FastRegs.CTR
173 LR = 1<<FastRegs.LR
174 TAR = 1<<FastRegs.TAR
175 SRR0 = 1<<FastRegs.SRR0
176 SRR1 = 1<<FastRegs.SRR1
177 if name == 'fast1':
178 return e.write_fast1, 1<<e.write_fast1.data
179 if name == 'fast2':
180 return e.write_fast2, 1<<e.write_fast2.data
181
182 # SPR regfile
183
184 if regfile == 'SPR':
185 # SPR register numbering is *binary* encoded
186 if name == 'spr1': # SPR1
187 return e.write_spr, e.write_spr.data
188
189 assert False, "regspec not found %s %s" % (regfile, name)
190