add SVSTATE (SVSRR0) to TRAP pipeline
[soc.git] / src / soc / regfile / regfiles.py
1 # POWER9 Register Files
2 """POWER9 regfiles
3
4 Defines the following register files:
5
6 * INT regfile - 32x 64-bit
7 * SPR regfile - 110x 64-bit
8 * CR regfile - CR0-7
9 * XER regfile - XER.so, XER.ca/ca32, XER.ov/ov32
10 * FAST regfile - CTR, LR, TAR, SRR1, SRR2
11 * STATE regfile - PC, MSR, (SimpleV VL later)
12
13 Note: this should NOT have name conventions hard-coded (dedicated ports per
14 regname). However it is convenient for now.
15
16 Links:
17
18 * https://bugs.libre-soc.org/show_bug.cgi?id=345
19 * https://bugs.libre-soc.org/show_bug.cgi?id=351
20 * https://libre-soc.org/3d_gpu/architecture/regfile/
21 * https://libre-soc.org/openpower/isatables/sprs.csv
22 * https://libre-soc.org/openpower/sv/sprs/ (SVSTATE)
23 """
24
25 # TODO
26
27 from soc.regfile.regfile import RegFile, RegFileArray, RegFileMem
28 from soc.regfile.virtual_port import VirtualRegPort
29 from openpower.decoder.power_enums import SPRfull, SPRreduced
30
31 # XXX MAKE DAMN SURE TO KEEP THESE UP-TO-DATE if changing/adding regs
32 from openpower.consts import StateRegsEnum, XERRegsEnum, FastRegsEnum
33
34
35 # "State" Regfile
36 class StateRegs(RegFileArray, StateRegsEnum):
37 """StateRegs
38
39 State regfile - PC, MSR, SVSTATE (for SimpleV)
40
41 * QTY 3of 64-bit registers
42 * 4R3W
43 * Array-based unary-indexed (not binary-indexed)
44 * write-through capability (read on same cycle as write)
45
46 Note: d_wr1 d_rd1 are for use by the decoder, to get at the PC.
47 will probably have to also add one so it can get at the MSR as well.
48 (d_rd2)
49
50 """
51 def __init__(self, svp64_en=False, regreduce_en=False):
52 super().__init__(64, StateRegsEnum.N_REGS)
53 self.w_ports = {'nia': self.write_port("nia"),
54 'msr': self.write_port("msr"),
55 'svstate': self.write_port("svstate"),
56 'sv': self.write_port("sv"), # writing SVSTATE (issuer)
57 'd_wr1': self.write_port("d_wr1")} # writing PC (issuer)
58 self.r_ports = {'cia': self.read_port("cia"), # reading PC (issuer)
59 'msr': self.read_port("msr"), # reading MSR (issuer)
60 'sv': self.read_port("sv"), # reading SV (issuer)
61 }
62
63
64 # Integer Regfile
65 class IntRegs(RegFileMem): #class IntRegs(RegFileArray):
66 """IntRegs
67
68 * QTY 32of 64-bit registers
69 * 3R2W
70 * Array-based unary-indexed (not binary-indexed)
71 * write-through capability (read on same cycle as write)
72 """
73 def __init__(self, svp64_en=False, regreduce_en=False):
74 super().__init__(64, 32, fwd_bus_mode=not regreduce_en)
75 self.w_ports = {'o': self.write_port("dest1"),
76 }
77 self.r_ports = {
78 'dmi': self.read_port("dmi")} # needed for Debug (DMI)
79 if svp64_en:
80 self.r_ports['pred'] = self.read_port("pred") # for predicate mask
81 if not regreduce_en:
82 self.w_ports['o1'] = self.write_port("dest2") # (LD/ST update)
83 self.r_ports['ra'] = self.read_port("src1")
84 self.r_ports['rb'] = self.read_port("src2")
85 self.r_ports['rc'] = self.read_port("src3")
86 else:
87 self.r_ports['rabc'] = self.read_port("src1")
88
89
90 # Fast SPRs Regfile
91 class FastRegs(RegFileMem, FastRegsEnum): #RegFileArray):
92 """FastRegs
93
94 FAST regfile - CTR, LR, TAR, SRR1, SRR2, XER, TB, DEC, SVSRR0
95
96 * QTY 6of 64-bit registers
97 * 3R2W
98 * Array-based unary-indexed (not binary-indexed)
99 * write-through capability (read on same cycle as write)
100
101 Note: r/w issue are used by issuer to increment/decrement TB/DEC.
102 """
103 def __init__(self, svp64_en=False, regreduce_en=False):
104 super().__init__(64, FastRegsEnum.N_REGS, fwd_bus_mode=not regreduce_en)
105 self.w_ports = {'fast1': self.write_port("dest1"),
106 'issue': self.write_port("issue"), # writing DEC/TB
107 }
108 self.r_ports = {'fast1': self.read_port("src1"),
109 'issue': self.read_port("issue"), # reading DEC/TB
110 }
111 if not regreduce_en:
112 self.r_ports['fast2'] = self.read_port("src2")
113
114
115 # CR Regfile
116 class CRRegs(VirtualRegPort):
117 """Condition Code Registers (CR0-7)
118
119 * QTY 8of 8-bit registers
120 * 3R1W 4-bit-wide with additional 1R1W for the "full" 32-bit width
121 * Array-based unary-indexed (not binary-indexed)
122 * write-through capability (read on same cycle as write)
123 """
124 def __init__(self, svp64_en=False, regreduce_en=False):
125 super().__init__(32, 8, rd2=True)
126 self.w_ports = {'full_cr': self.full_wr, # 32-bit (masked, 8-en lines)
127 'cr_a': self.write_port("dest1"), # 4-bit, unary-indexed
128 'cr_b': self.write_port("dest2")} # 4-bit, unary-indexed
129 self.r_ports = {'full_cr': self.full_rd, # 32-bit (masked, 8-en lines)
130 'full_cr_dbg': self.full_rd2, # for DMI
131 'cr_a': self.read_port("src1"),
132 'cr_b': self.read_port("src2"),
133 'cr_c': self.read_port("src3")}
134 if svp64_en:
135 self.r_ports['cr_pred'] = self.read_port("cr_pred") # for predicate
136
137
138 # XER Regfile
139 class XERRegs(VirtualRegPort, XERRegsEnum):
140 """XER Registers (SO, CA/CA32, OV/OV32)
141
142 * QTY 3of 2-bit registers
143 * 3R3W 2-bit-wide with additional 1R1W for the "full" 6-bit width
144 * Array-based unary-indexed (not binary-indexed)
145 * write-through capability (read on same cycle as write)
146 """
147 SO=0 # this is actually 2-bit but we ignore 1 bit of it
148 CA=1 # CA and CA32
149 OV=2 # OV and OV32
150 def __init__(self, svp64_en=False, regreduce_en=False):
151 super().__init__(6, XERRegsEnum.N_REGS)
152 self.w_ports = {'full_xer': self.full_wr, # 6-bit (masked, 3-en lines)
153 'xer_so': self.write_port("dest1"),
154 'xer_ca': self.write_port("dest2"),
155 'xer_ov': self.write_port("dest3")}
156 self.r_ports = {'full_xer': self.full_rd, # 6-bit (masked, 3-en lines)
157 'xer_so': self.read_port("src1"),
158 'xer_ca': self.read_port("src2"),
159 'xer_ov': self.read_port("src3")}
160
161
162 # SPR Regfile
163 class SPRRegs(RegFileMem):
164 """SPRRegs
165
166 * QTY len(SPRs) 64-bit registers
167 * 1R1W
168 * binary-indexed but REQUIRES MAPPING
169 * write-through capability (read on same cycle as write)
170 """
171 def __init__(self, svp64_en=False, regreduce_en=False):
172 if regreduce_en:
173 n_sprs = len(SPRreduced)
174 else:
175 n_sprs = len(SPRfull)
176 super().__init__(width=64, depth=n_sprs,
177 fwd_bus_mode=not regreduce_en)
178 self.w_ports = {'spr1': self.write_port("spr1")}
179 self.r_ports = {'spr1': self.read_port("spr1")}
180
181
182 # class containing all regfiles: int, cr, xer, fast, spr
183 class RegFiles:
184 def __init__(self, pspec):
185 # test is SVP64 is to be enabled
186 svp64_en = hasattr(pspec, "svp64") and (pspec.svp64 == True)
187
188 # and regfile port reduction
189 regreduce_en = hasattr(pspec, "regreduce") and \
190 (pspec.regreduce == True)
191
192 self.rf = {}
193 # create regfiles here, Factory style
194 for (name, kls) in [('int', IntRegs),
195 ('cr', CRRegs),
196 ('xer', XERRegs),
197 ('fast', FastRegs),
198 ('state', StateRegs),
199 ('spr', SPRRegs),]:
200 rf = self.rf[name] = kls(svp64_en, regreduce_en)
201 # also add these as instances, self.state, self.fast, self.cr etc.
202 setattr(self, name, rf)
203
204 def elaborate_into(self, m, platform):
205 for (name, rf) in self.rf.items():
206 setattr(m.submodules, name, rf)
207 return m
208