add predication read ports (CR and INT)
[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 'pred': self.read_port("pred"), # for predicate mask
81 'dmi': self.read_port("dmi")} # needed for Debug (DMI)
82
83
84 # Fast SPRs Regfile
85 class FastRegs(RegFileMem): #RegFileArray):
86 """FastRegs
87
88 FAST regfile - CTR, LR, TAR, SRR1, SRR2, XER, TB, DEC
89
90 * QTY 6of 64-bit registers
91 * 3R2W
92 * Array-based unary-indexed (not binary-indexed)
93 * write-through capability (read on same cycle as write)
94
95 Note: r/w issue are used by issuer to increment/decrement TB/DEC.
96 """
97 CTR = 0
98 LR = 1
99 TAR = 2
100 SRR0 = 3
101 SRR1 = 4
102 XER = 5 # non-XER bits
103 DEC = 6
104 TB = 7
105 N_REGS = 8 # maximum number of regs
106 def __init__(self):
107 super().__init__(64, self.N_REGS)
108 self.w_ports = {'fast1': self.write_port("dest1"),
109 'issue': self.write_port("issue"), # writing DEC/TB
110 }
111 self.r_ports = {'fast1': self.read_port("src1"),
112 'fast2': self.read_port("src2"),
113 'issue': self.read_port("issue"), # reading DEC/TB
114 }
115
116
117 # CR Regfile
118 class CRRegs(VirtualRegPort):
119 """Condition Code Registers (CR0-7)
120
121 * QTY 8of 8-bit registers
122 * 3R1W 4-bit-wide with additional 1R1W for the "full" 32-bit width
123 * Array-based unary-indexed (not binary-indexed)
124 * write-through capability (read on same cycle as write)
125 """
126 def __init__(self):
127 super().__init__(32, 8, rd2=True)
128 self.w_ports = {'full_cr': self.full_wr, # 32-bit (masked, 8-en lines)
129 'cr_a': self.write_port("dest1"), # 4-bit, unary-indexed
130 'cr_b': self.write_port("dest2")} # 4-bit, unary-indexed
131 self.r_ports = {'full_cr': self.full_rd, # 32-bit (masked, 8-en lines)
132 'full_cr_dbg': self.full_rd2, # for DMI
133 'cr_pred': self.read_port("cr_pred"), # for predicate
134 'cr_a': self.read_port("src1"),
135 'cr_b': self.read_port("src2"),
136 'cr_c': self.read_port("src3")}
137
138
139 # XER Regfile
140 class XERRegs(VirtualRegPort):
141 """XER Registers (SO, CA/CA32, OV/OV32)
142
143 * QTY 3of 2-bit registers
144 * 3R3W 2-bit-wide with additional 1R1W for the "full" 6-bit width
145 * Array-based unary-indexed (not binary-indexed)
146 * write-through capability (read on same cycle as write)
147 """
148 SO=0 # this is actually 2-bit but we ignore 1 bit of it
149 CA=1 # CA and CA32
150 OV=2 # OV and OV32
151 def __init__(self):
152 super().__init__(6, 3)
153 self.w_ports = {'full_xer': self.full_wr, # 6-bit (masked, 3-en lines)
154 'xer_so': self.write_port("dest1"),
155 'xer_ca': self.write_port("dest2"),
156 'xer_ov': self.write_port("dest3")}
157 self.r_ports = {'full_xer': self.full_rd, # 6-bit (masked, 3-en lines)
158 'xer_so': self.read_port("src1"),
159 'xer_ca': self.read_port("src2"),
160 'xer_ov': self.read_port("src3")}
161
162
163 # SPR Regfile
164 class SPRRegs(RegFileMem):
165 """SPRRegs
166
167 * QTY len(SPRs) 64-bit registers
168 * 1R1W
169 * binary-indexed but REQUIRES MAPPING
170 * write-through capability (read on same cycle as write)
171 """
172 def __init__(self):
173 n_sprs = len(SPR)
174 super().__init__(width=64, depth=n_sprs)
175 self.w_ports = {'spr1': self.write_port("spr1")}
176 self.r_ports = {'spr1': self.read_port("spr1")}
177
178
179 # class containing all regfiles: int, cr, xer, fast, spr
180 class RegFiles:
181 def __init__(self):
182 self.rf = {}
183 # create regfiles here, Factory style
184 for (name, kls) in [('int', IntRegs),
185 ('cr', CRRegs),
186 ('xer', XERRegs),
187 ('fast', FastRegs),
188 ('state', StateRegs),
189 ('spr', SPRRegs),]:
190 rf = self.rf[name] = kls()
191 # also add these as instances, self.state, self.fast, self.cr etc.
192 setattr(self, name, rf)
193
194 def elaborate_into(self, m, platform):
195 for (name, rf) in self.rf.items():
196 setattr(m.submodules, name, rf)
197 return m
198