add SVSRR0 to FastRegsEnum
[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 'sv': self.write_port("sv"), # writing SVSTATE (issuer)
56 'd_wr1': self.write_port("d_wr1")} # writing PC (issuer)
57 self.r_ports = {'cia': self.read_port("cia"), # reading PC (issuer)
58 'msr': self.read_port("msr"), # reading MSR (issuer)
59 'sv': self.read_port("sv"), # reading SV (issuer)
60 }
61
62
63 # Integer Regfile
64 class IntRegs(RegFileMem): #class IntRegs(RegFileArray):
65 """IntRegs
66
67 * QTY 32of 64-bit registers
68 * 3R2W
69 * Array-based unary-indexed (not binary-indexed)
70 * write-through capability (read on same cycle as write)
71 """
72 def __init__(self, svp64_en=False, regreduce_en=False):
73 super().__init__(64, 32, fwd_bus_mode=not regreduce_en)
74 self.w_ports = {'o': self.write_port("dest1"),
75 }
76 self.r_ports = {
77 'dmi': self.read_port("dmi")} # needed for Debug (DMI)
78 if svp64_en:
79 self.r_ports['pred'] = self.read_port("pred") # for predicate mask
80 if not regreduce_en:
81 self.w_ports['o1'] = self.write_port("dest2") # (LD/ST update)
82 self.r_ports['ra'] = self.read_port("src1")
83 self.r_ports['rb'] = self.read_port("src2")
84 self.r_ports['rc'] = self.read_port("src3")
85 else:
86 self.r_ports['rabc'] = self.read_port("src1")
87
88
89 # Fast SPRs Regfile
90 class FastRegs(RegFileMem, FastRegsEnum): #RegFileArray):
91 """FastRegs
92
93 FAST regfile - CTR, LR, TAR, SRR1, SRR2, XER, TB, DEC, SVSRR0
94
95 * QTY 6of 64-bit registers
96 * 3R2W
97 * Array-based unary-indexed (not binary-indexed)
98 * write-through capability (read on same cycle as write)
99
100 Note: r/w issue are used by issuer to increment/decrement TB/DEC.
101 """
102 def __init__(self, svp64_en=False, regreduce_en=False):
103 super().__init__(64, FastRegsEnum.N_REGS, fwd_bus_mode=not regreduce_en)
104 self.w_ports = {'fast1': self.write_port("dest1"),
105 'issue': self.write_port("issue"), # writing DEC/TB
106 }
107 self.r_ports = {'fast1': self.read_port("src1"),
108 'issue': self.read_port("issue"), # reading DEC/TB
109 }
110 if not regreduce_en:
111 self.r_ports['fast2'] = self.read_port("src2")
112
113
114 # CR Regfile
115 class CRRegs(VirtualRegPort):
116 """Condition Code Registers (CR0-7)
117
118 * QTY 8of 8-bit registers
119 * 3R1W 4-bit-wide with additional 1R1W for the "full" 32-bit width
120 * Array-based unary-indexed (not binary-indexed)
121 * write-through capability (read on same cycle as write)
122 """
123 def __init__(self, svp64_en=False, regreduce_en=False):
124 super().__init__(32, 8, rd2=True)
125 self.w_ports = {'full_cr': self.full_wr, # 32-bit (masked, 8-en lines)
126 'cr_a': self.write_port("dest1"), # 4-bit, unary-indexed
127 'cr_b': self.write_port("dest2")} # 4-bit, unary-indexed
128 self.r_ports = {'full_cr': self.full_rd, # 32-bit (masked, 8-en lines)
129 'full_cr_dbg': self.full_rd2, # for DMI
130 'cr_a': self.read_port("src1"),
131 'cr_b': self.read_port("src2"),
132 'cr_c': self.read_port("src3")}
133 if svp64_en:
134 self.r_ports['cr_pred'] = self.read_port("cr_pred") # for predicate
135
136
137 # XER Regfile
138 class XERRegs(VirtualRegPort, XERRegsEnum):
139 """XER Registers (SO, CA/CA32, OV/OV32)
140
141 * QTY 3of 2-bit registers
142 * 3R3W 2-bit-wide with additional 1R1W for the "full" 6-bit width
143 * Array-based unary-indexed (not binary-indexed)
144 * write-through capability (read on same cycle as write)
145 """
146 SO=0 # this is actually 2-bit but we ignore 1 bit of it
147 CA=1 # CA and CA32
148 OV=2 # OV and OV32
149 def __init__(self, svp64_en=False, regreduce_en=False):
150 super().__init__(6, XERRegsEnum.N_REGS)
151 self.w_ports = {'full_xer': self.full_wr, # 6-bit (masked, 3-en lines)
152 'xer_so': self.write_port("dest1"),
153 'xer_ca': self.write_port("dest2"),
154 'xer_ov': self.write_port("dest3")}
155 self.r_ports = {'full_xer': self.full_rd, # 6-bit (masked, 3-en lines)
156 'xer_so': self.read_port("src1"),
157 'xer_ca': self.read_port("src2"),
158 'xer_ov': self.read_port("src3")}
159
160
161 # SPR Regfile
162 class SPRRegs(RegFileMem):
163 """SPRRegs
164
165 * QTY len(SPRs) 64-bit registers
166 * 1R1W
167 * binary-indexed but REQUIRES MAPPING
168 * write-through capability (read on same cycle as write)
169 """
170 def __init__(self, svp64_en=False, regreduce_en=False):
171 if regreduce_en:
172 n_sprs = len(SPRreduced)
173 else:
174 n_sprs = len(SPRfull)
175 super().__init__(width=64, depth=n_sprs,
176 fwd_bus_mode=not regreduce_en)
177 self.w_ports = {'spr1': self.write_port("spr1")}
178 self.r_ports = {'spr1': self.read_port("spr1")}
179
180
181 # class containing all regfiles: int, cr, xer, fast, spr
182 class RegFiles:
183 def __init__(self, pspec):
184 # test is SVP64 is to be enabled
185 svp64_en = hasattr(pspec, "svp64") and (pspec.svp64 == True)
186
187 # and regfile port reduction
188 regreduce_en = hasattr(pspec, "regreduce") and \
189 (pspec.regreduce == True)
190
191 self.rf = {}
192 # create regfiles here, Factory style
193 for (name, kls) in [('int', IntRegs),
194 ('cr', CRRegs),
195 ('xer', XERRegs),
196 ('fast', FastRegs),
197 ('state', StateRegs),
198 ('spr', SPRRegs),]:
199 rf = self.rf[name] = kls(svp64_en, regreduce_en)
200 # also add these as instances, self.state, self.fast, self.cr etc.
201 setattr(self, name, rf)
202
203 def elaborate_into(self, m, platform):
204 for (name, rf) in self.rf.items():
205 setattr(m.submodules, name, rf)
206 return m
207