comments in power_regspec_map.py
[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
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.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.oe.oe[0] & e.oe.oe_ok) | e.xer_in, SO
80 if name == 'xer_ov':
81 return (e.oe.oe[0] & e.oe.oe_ok) | e.xer_in, OV
82 if name == 'xer_ca':
83 return (e.input_carry == CryIn.CA.value) | e.xer_in, CA
84
85 # FAST regfile
86
87 if regfile == 'FAST':
88 # FAST register numbering is *unary* encoded
89 PC = 1<<FastRegs.PC
90 MSR = 1<<FastRegs.MSR
91 CTR = 1<<FastRegs.CTR
92 LR = 1<<FastRegs.LR
93 TAR = 1<<FastRegs.TAR
94 SRR0 = 1<<FastRegs.SRR0
95 SRR1 = 1<<FastRegs.SRR1
96 if name in ['cia', 'nia']:
97 return Const(1), PC # TODO: detect read-conditions
98 if name == 'msr':
99 return Const(1), MSR # TODO: detect read-conditions
100 # TODO: remap the SPR numbers to FAST regs
101 if name == 'fast1':
102 return e.read_fast1.ok, 1<<e.read_fast1.data
103 if name == 'fast2':
104 return e.read_fast2.ok, 1<<e.read_fast2.data
105
106 # SPR regfile
107
108 if regfile == 'SPR':
109 # SPR register numbering is *binary* encoded
110 if name == 'spr1':
111 return e.read_spr1.ok, e.read_spr1.data
112
113 assert False, "regspec not found %s %s" % (regfile, name)
114
115
116 def regspec_decode_write(e, regfile, name):
117 """regspec_decode_write
118 """
119
120 # INT regfile
121
122 if regfile == 'INT':
123 # Int register numbering is *unary* encoded
124 if name == 'o': # RT
125 return e.write_reg, 1<<e.write_reg.data
126 if name == 'o1': # RA (update mode: LD/ST EA)
127 return e.write_ea, 1<<e.write_ea.data
128
129 # CR regfile
130
131 if regfile == 'CR':
132 # CRRegs register numbering is *unary* encoded
133 # *sigh*. numbering inverted on part-CRs. because POWER.
134 if name == 'full_cr': # full CR
135 return e.write_cr_whole, 0b11111111
136 if name == 'cr_a': # CR A
137 return e.write_cr, 1<<(7-e.write_cr.data)
138
139 # XER regfile
140
141 if regfile == 'XER':
142 # XERRegs register numbering is *unary* encoded
143 SO = 1<<XERRegs.SO
144 CA = 1<<XERRegs.CA
145 OV = 1<<XERRegs.OV
146 if name == 'xer_so':
147 return e.xer_out, SO # hmmm
148 if name == 'xer_ov':
149 return e.xer_out, OV # hmmm
150 if name == 'xer_ca':
151 return e.xer_out, CA # hmmm
152
153 # FAST regfile
154
155 if regfile == 'FAST':
156 # FAST register numbering is *unary* encoded
157 PC = 1<<FastRegs.PC
158 MSR = 1<<FastRegs.MSR
159 CTR = 1<<FastRegs.CTR
160 LR = 1<<FastRegs.LR
161 TAR = 1<<FastRegs.TAR
162 SRR0 = 1<<FastRegs.SRR0
163 SRR1 = 1<<FastRegs.SRR1
164 if name in ['cia', 'nia']:
165 return None, PC # hmmm
166 if name == 'msr':
167 return None, MSR # hmmm
168 # TODO: remap the SPR numbers to FAST regs
169 if name == 'fast1':
170 return e.write_fast1, 1<<e.write_fast1.data
171 if name == 'fast2':
172 return e.write_fast2, 1<<e.write_fast2.data
173
174 # SPR regfile
175
176 if regfile == 'SPR':
177 # SPR register numbering is *binary* encoded
178 if name == 'spr1': # SPR1
179 return e.write_spr, e.write_spr.data
180
181 assert False, "regspec not found %s %s" % (regfile, name)
182