add SVSTATE to StateRegs
[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):
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):
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
82
83 # Fast SPRs Regfile
84 class FastRegs(RegFileMem): #RegFileArray):
85 """FastRegs
86
87 FAST regfile - CTR, LR, TAR, SRR1, SRR2, XER, TB, DEC
88
89 * QTY 6of 64-bit registers
90 * 3R2W
91 * Array-based unary-indexed (not binary-indexed)
92 * write-through capability (read on same cycle as write)
93
94 Note: r/w issue are used by issuer to increment/decrement TB/DEC.
95 """
96 CTR = 0
97 LR = 1
98 TAR = 2
99 SRR0 = 3
100 SRR1 = 4
101 XER = 5 # non-XER bits
102 DEC = 6
103 TB = 7
104 N_REGS = 8 # maximum number of regs
105 def __init__(self):
106 super().__init__(64, self.N_REGS)
107 self.w_ports = {'fast1': self.write_port("dest1"),
108 'issue': self.write_port("issue"), # writing DEC/TB
109 }
110 self.r_ports = {'fast1': self.read_port("src1"),
111 'fast2': self.read_port("src2"),
112 'issue': self.read_port("issue"), # reading DEC/TB
113 }
114
115
116 # CR Regfile
117 class CRRegs(VirtualRegPort):
118 """Condition Code Registers (CR0-7)
119
120 * QTY 8of 8-bit registers
121 * 3R1W 4-bit-wide with additional 1R1W for the "full" 32-bit width
122 * Array-based unary-indexed (not binary-indexed)
123 * write-through capability (read on same cycle as write)
124 """
125 def __init__(self):
126 super().__init__(32, 8, rd2=True)
127 self.w_ports = {'full_cr': self.full_wr, # 32-bit (masked, 8-en lines)
128 'cr_a': self.write_port("dest1"), # 4-bit, unary-indexed
129 'cr_b': self.write_port("dest2")} # 4-bit, unary-indexed
130 self.r_ports = {'full_cr': self.full_rd, # 32-bit (masked, 8-en lines)
131 'full_cr_dbg': self.full_rd2, # for DMI
132 'cr_a': self.read_port("src1"),
133 'cr_b': self.read_port("src2"),
134 'cr_c': self.read_port("src3")}
135
136
137 # XER Regfile
138 class XERRegs(VirtualRegPort):
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):
150 super().__init__(6, 3)
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):
171 n_sprs = len(SPR)
172 super().__init__(width=64, depth=n_sprs)
173 self.w_ports = {'spr1': self.write_port("spr1")}
174 self.r_ports = {'spr1': self.read_port("spr1")}
175
176
177 # class containing all regfiles: int, cr, xer, fast, spr
178 class RegFiles:
179 def __init__(self):
180 self.rf = {}
181 for (name, kls) in [('int', IntRegs),
182 ('cr', CRRegs),
183 ('xer', XERRegs),
184 ('fast', FastRegs),
185 ('state', StateRegs),
186 ('spr', SPRRegs),]:
187 rf = self.rf[name] = kls()
188 setattr(self, name, rf)
189
190 def elaborate_into(self, m, platform):
191 for (name, rf) in self.rf.items():
192 setattr(m.submodules, name, rf)
193 return m
194