move DEC and TB from StateRegs to FastRegs for several reasons
[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 def __init__(self):
101 super().__init__(64, 8)
102 self.w_ports = {'fast1': self.write_port("dest1"),
103 'issue': self.write_port("issue"), # writing DEC/TB
104 }
105 self.r_ports = {'fast1': self.read_port("src1"),
106 'fast2': self.read_port("src2"),
107 'issue': self.read_port("issue"), # reading DEC/TB
108 }
109
110
111 # CR Regfile
112 class CRRegs(VirtualRegPort):
113 """Condition Code Registers (CR0-7)
114
115 * QTY 8of 8-bit registers
116 * 3R1W 4-bit-wide with additional 1R1W for the "full" 32-bit width
117 * Array-based unary-indexed (not binary-indexed)
118 * write-through capability (read on same cycle as write)
119 """
120 def __init__(self):
121 super().__init__(32, 8, rd2=True)
122 self.w_ports = {'full_cr': self.full_wr, # 32-bit (masked, 8-en lines)
123 'cr_a': self.write_port("dest1"), # 4-bit, unary-indexed
124 'cr_b': self.write_port("dest2")} # 4-bit, unary-indexed
125 self.r_ports = {'full_cr': self.full_rd, # 32-bit (masked, 8-en lines)
126 'full_cr_dbg': self.full_rd2, # for DMI
127 'cr_a': self.read_port("src1"),
128 'cr_b': self.read_port("src2"),
129 'cr_c': self.read_port("src3")}
130
131
132 # XER Regfile
133 class XERRegs(VirtualRegPort):
134 """XER Registers (SO, CA/CA32, OV/OV32)
135
136 * QTY 3of 2-bit registers
137 * 3R3W 2-bit-wide with additional 1R1W for the "full" 6-bit width
138 * Array-based unary-indexed (not binary-indexed)
139 * write-through capability (read on same cycle as write)
140 """
141 SO=0 # this is actually 2-bit but we ignore 1 bit of it
142 CA=1 # CA and CA32
143 OV=2 # OV and OV32
144 def __init__(self):
145 super().__init__(6, 3)
146 self.w_ports = {'full_xer': self.full_wr, # 6-bit (masked, 3-en lines)
147 'xer_so': self.write_port("dest1"),
148 'xer_ca': self.write_port("dest2"),
149 'xer_ov': self.write_port("dest3")}
150 self.r_ports = {'full_xer': self.full_rd, # 6-bit (masked, 3-en lines)
151 'xer_so': self.read_port("src1"),
152 'xer_ca': self.read_port("src2"),
153 'xer_ov': self.read_port("src3")}
154
155
156 # SPR Regfile
157 class SPRRegs(RegFileMem):
158 """SPRRegs
159
160 * QTY len(SPRs) 64-bit registers
161 * 1R1W
162 * binary-indexed but REQUIRES MAPPING
163 * write-through capability (read on same cycle as write)
164 """
165 def __init__(self):
166 n_sprs = len(SPR)
167 super().__init__(width=64, depth=n_sprs)
168 self.w_ports = {'spr1': self.write_port("spr1")}
169 self.r_ports = {'spr1': self.read_port("spr1")}
170
171
172 # class containing all regfiles: int, cr, xer, fast, spr
173 class RegFiles:
174 def __init__(self):
175 self.rf = {}
176 for (name, kls) in [('int', IntRegs),
177 ('cr', CRRegs),
178 ('xer', XERRegs),
179 ('fast', FastRegs),
180 ('state', StateRegs),
181 ('spr', SPRRegs),]:
182 rf = self.rf[name] = kls()
183 setattr(self, name, rf)
184
185 def elaborate_into(self, m, platform):
186 for (name, rf) in self.rf.items():
187 setattr(m.submodules, name, rf)
188 return m
189