attempting to add SPRs to rfid test
[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 (note however that XFX in MTCR is unary-masked!)
24
25 XER is implicitly-encoded based on whether the operation has carry or
26 overflow.
27
28 FAST regfile is, again, implicitly encoded, back in PowerDecode2, based
29 on the type of operation (see DecodeB for an example).
30
31 The SPR regfile on the other hand is *binary*-encoded, and, furthermore,
32 has to be "remapped".
33 see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs
34 """
35 from nmigen import Const
36 from soc.regfile.regfiles import XERRegs, FastRegs
37 from soc.decoder.power_enums import CryIn
38
39
40 def regspec_decode_read(e, regfile, name):
41 """regspec_decode_read
42 """
43
44 if regfile == 'INT':
45 # Int register numbering is *unary* encoded
46 if name == 'ra': # RA
47 return e.read_reg1.ok, 1<<e.read_reg1.data
48 if name == 'rb': # RB
49 return e.read_reg2.ok, 1<<e.read_reg2.data
50 if name == 'rc': # RS
51 return e.read_reg3.ok, 1<<e.read_reg3.data
52
53 if regfile == 'CR':
54 # CRRegs register numbering is *unary* encoded
55 # *sigh*. numbering inverted on part-CRs. because POWER.
56 if name == 'full_cr': # full CR
57 return e.read_cr_whole, 0b11111111
58 if name == 'cr_a': # CR A
59 return e.read_cr1.ok, 1<<(7-e.read_cr1.data)
60 if name == 'cr_b': # CR B
61 return e.read_cr2.ok, 1<<(7-e.read_cr2.data)
62 if name == 'cr_c': # CR C
63 return e.read_cr3.ok, 1<<(7-e.read_cr3.data)
64
65 if regfile == 'XER':
66 # XERRegs register numbering is *unary* encoded
67 SO = 1<<XERRegs.SO
68 CA = 1<<XERRegs.CA
69 OV = 1<<XERRegs.OV
70 if name == 'xer_so':
71 return e.oe.oe[0] & e.oe.oe_ok, SO
72 if name == 'xer_ov':
73 return e.oe.oe[0] & e.oe.oe_ok, OV
74 if name == 'xer_ca':
75 return (e.input_carry == CryIn.CA.value), CA
76
77 if regfile == 'FAST':
78 # FAST register numbering is *unary* encoded
79 PC = 1<<FastRegs.PC
80 MSR = 1<<FastRegs.MSR
81 CTR = 1<<FastRegs.CTR
82 LR = 1<<FastRegs.LR
83 TAR = 1<<FastRegs.TAR
84 SRR0 = 1<<FastRegs.SRR0
85 SRR1 = 1<<FastRegs.SRR1
86 if name in ['cia', 'nia']:
87 return Const(1), PC # TODO: detect read-conditions
88 if name == 'msr':
89 return Const(1), MSR # TODO: detect read-conditions
90 # TODO: remap the SPR numbers to FAST regs
91 if name == 'spr1':
92 return e.read_fast1.ok, 1<<e.read_fast1.data
93 if name == 'spr2':
94 return e.read_fast2.ok, 1<<e.read_fast2.data
95
96 if regfile == 'SPR':
97 assert False, "regfile TODO %s %s" % (regfile, name)
98 assert False, "regspec not found %s %s" % (regfile, name)
99
100
101 def regspec_decode_write(e, regfile, name):
102 """regspec_decode_write
103 """
104
105 if regfile == 'INT':
106 # Int register numbering is *unary* encoded
107 if name == 'o': # RT
108 return e.write_reg, 1<<e.write_reg.data
109 if name == 'o1': # RA (update mode: LD/ST EA)
110 return e.write_ea, 1<<e.write_ea.data
111
112 if regfile == 'CR':
113 # CRRegs register numbering is *unary* encoded
114 # *sigh*. numbering inverted on part-CRs. because POWER.
115 if name == 'full_cr': # full CR
116 return e.write_cr_whole, 0b11111111
117 if name == 'cr_a': # CR A
118 return e.write_cr, 1<<(7-e.write_cr.data)
119
120 if regfile == 'XER':
121 # XERRegs register numbering is *unary* encoded
122 SO = 1<<XERRegs.SO
123 CA = 1<<XERRegs.CA
124 OV = 1<<XERRegs.OV
125 if name == 'xer_so':
126 return None, SO # hmmm
127 if name == 'xer_ov':
128 return None, OV # hmmm
129 if name == 'xer_ca':
130 return None, CA # hmmm
131
132 if regfile == 'FAST':
133 # FAST register numbering is *unary* encoded
134 PC = 1<<FastRegs.PC
135 MSR = 1<<FastRegs.MSR
136 CTR = 1<<FastRegs.CTR
137 LR = 1<<FastRegs.LR
138 TAR = 1<<FastRegs.TAR
139 SRR0 = 1<<FastRegs.SRR0
140 SRR1 = 1<<FastRegs.SRR1
141 if name in ['cia', 'nia']:
142 return None, PC # hmmm
143 if name == 'msr':
144 return None, MSR # hmmm
145 # TODO: remap the SPR numbers to FAST regs
146 if name == 'spr1':
147 return e.write_fast1, 1<<e.write_fast1.data
148 if name == 'spr2':
149 return e.write_fast2, 1<<e.write_fast2.data
150
151 if regfile == 'SPR':
152 assert False, "regfile TODO %s %s" % (regfile, name)
153 assert False, "regspec not found %s %s" % (regfile, name)
154