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