reduce regfile port usage on non-svp64
[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 soc.decoder.power_enums import SPR
30
31
32 # "State" Regfile
33 class StateRegs(RegFileArray):
34 """StateRegs
35
36 State regfile - PC, MSR, SVSTATE (for SimpleV)
37
38 * QTY 3of 64-bit registers
39 * 4R3W
40 * Array-based unary-indexed (not binary-indexed)
41 * write-through capability (read on same cycle as write)
42
43 Note: d_wr1 d_rd1 are for use by the decoder, to get at the PC.
44 will probably have to also add one so it can get at the MSR as well.
45 (d_rd2)
46
47 """
48 PC = 0
49 MSR = 1
50 SVSTATE = 2
51 def __init__(self, svp64_en=False):
52 super().__init__(64, 3)
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):
73 super().__init__(64, 32)
74 self.w_ports = {'o': self.write_port("dest1"),
75 #'o1': self.write_port("dest2") # for now (LD/ST update)
76 }
77 self.r_ports = {'ra': self.read_port("src1"),
78 'rb': self.read_port("src2"),
79 'rc': self.read_port("src3"),
80 'dmi': self.read_port("dmi")} # needed for Debug (DMI)
81 if svp64_en:
82 self.r_ports['pred'] = self.read_port("pred") # for predicate mask
83
84
85 # Fast SPRs Regfile
86 class FastRegs(RegFileMem): #RegFileArray):
87 """FastRegs
88
89 FAST regfile - CTR, LR, TAR, SRR1, SRR2, XER, TB, DEC
90
91 * QTY 6of 64-bit registers
92 * 3R2W
93 * Array-based unary-indexed (not binary-indexed)
94 * write-through capability (read on same cycle as write)
95
96 Note: r/w issue are used by issuer to increment/decrement TB/DEC.
97 """
98 CTR = 0
99 LR = 1
100 TAR = 2
101 SRR0 = 3
102 SRR1 = 4
103 XER = 5 # non-XER bits
104 DEC = 6
105 TB = 7
106 N_REGS = 8 # maximum number of regs
107 def __init__(self, svp64_en=False):
108 super().__init__(64, self.N_REGS)
109 self.w_ports = {'fast1': self.write_port("dest1"),
110 'issue': self.write_port("issue"), # writing DEC/TB
111 }
112 self.r_ports = {'fast1': self.read_port("src1"),
113 'fast2': self.read_port("src2"),
114 'issue': self.read_port("issue"), # reading DEC/TB
115 }
116
117
118 # CR Regfile
119 class CRRegs(VirtualRegPort):
120 """Condition Code Registers (CR0-7)
121
122 * QTY 8of 8-bit registers
123 * 3R1W 4-bit-wide with additional 1R1W for the "full" 32-bit width
124 * Array-based unary-indexed (not binary-indexed)
125 * write-through capability (read on same cycle as write)
126 """
127 def __init__(self, svp64_en=False):
128 super().__init__(32, 8, rd2=True)
129 self.w_ports = {'full_cr': self.full_wr, # 32-bit (masked, 8-en lines)
130 'cr_a': self.write_port("dest1"), # 4-bit, unary-indexed
131 'cr_b': self.write_port("dest2")} # 4-bit, unary-indexed
132 self.r_ports = {'full_cr': self.full_rd, # 32-bit (masked, 8-en lines)
133 'full_cr_dbg': self.full_rd2, # for DMI
134 'cr_a': self.read_port("src1"),
135 'cr_b': self.read_port("src2"),
136 'cr_c': self.read_port("src3")}
137 if svp64_en:
138 self.r_ports['cr_pred'] = self.read_port("cr_pred") # for predicate
139
140
141 # XER Regfile
142 class XERRegs(VirtualRegPort):
143 """XER Registers (SO, CA/CA32, OV/OV32)
144
145 * QTY 3of 2-bit registers
146 * 3R3W 2-bit-wide with additional 1R1W for the "full" 6-bit width
147 * Array-based unary-indexed (not binary-indexed)
148 * write-through capability (read on same cycle as write)
149 """
150 SO=0 # this is actually 2-bit but we ignore 1 bit of it
151 CA=1 # CA and CA32
152 OV=2 # OV and OV32
153 def __init__(self, svp64_en=False):
154 super().__init__(6, 3)
155 self.w_ports = {'full_xer': self.full_wr, # 6-bit (masked, 3-en lines)
156 'xer_so': self.write_port("dest1"),
157 'xer_ca': self.write_port("dest2"),
158 'xer_ov': self.write_port("dest3")}
159 self.r_ports = {'full_xer': self.full_rd, # 6-bit (masked, 3-en lines)
160 'xer_so': self.read_port("src1"),
161 'xer_ca': self.read_port("src2"),
162 'xer_ov': self.read_port("src3")}
163
164
165 # SPR Regfile
166 class SPRRegs(RegFileMem):
167 """SPRRegs
168
169 * QTY len(SPRs) 64-bit registers
170 * 1R1W
171 * binary-indexed but REQUIRES MAPPING
172 * write-through capability (read on same cycle as write)
173 """
174 def __init__(self, svp64_en=False):
175 n_sprs = len(SPR)
176 super().__init__(width=64, depth=n_sprs)
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 self.rf = {}
188 # create regfiles here, Factory style
189 for (name, kls) in [('int', IntRegs),
190 ('cr', CRRegs),
191 ('xer', XERRegs),
192 ('fast', FastRegs),
193 ('state', StateRegs),
194 ('spr', SPRRegs),]:
195 rf = self.rf[name] = kls(svp64_en)
196 # also add these as instances, self.state, self.fast, self.cr etc.
197 setattr(self, name, rf)
198
199 def elaborate_into(self, m, platform):
200 for (name, rf) in self.rf.items():
201 setattr(m.submodules, name, rf)
202 return m
203