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