1 # POWER9 Register Files
4 Defines the following register files:
6 * INT regfile - 32x 64-bit
7 * SPR regfile - 110x 64-bit
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)
13 Note: this should NOT have name conventions hard-coded (dedicated ports per
14 regname). However it is convenient for now.
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)
27 from soc
.regfile
.regfile
import RegFile
, RegFileArray
, RegFileMem
28 from soc
.regfile
.virtual_port
import VirtualRegPort
29 from soc
.decoder
.power_enums
import SPRfull
, SPRreduced
33 class StateRegs(RegFileArray
):
36 State regfile - PC, MSR, SVSTATE (for SimpleV)
38 * QTY 3of 64-bit registers
40 * Array-based unary-indexed (not binary-indexed)
41 * write-through capability (read on same cycle as write)
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.
51 def __init__(self
, svp64_en
=False, regreduce_en
=False):
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)
64 class IntRegs(RegFileMem
): #class IntRegs(RegFileArray):
67 * QTY 32of 64-bit registers
69 * Array-based unary-indexed (not binary-indexed)
70 * write-through capability (read on same cycle as write)
72 def __init__(self
, svp64_en
=False, regreduce_en
=False):
73 super().__init
__(64, 32)
74 self
.w_ports
= {'o': self
.write_port("dest1"),
77 'dmi': self
.read_port("dmi")} # needed for Debug (DMI)
79 self
.r_ports
['pred'] = self
.read_port("pred") # for predicate mask
81 self
.w_ports
['o1'] = self
.write_port("dest2") # (LD/ST update)
82 self
.r_ports
['ra'] = self
.read_port("src1")
83 self
.r_ports
['rb'] = self
.read_port("src2")
84 self
.r_ports
['rc'] = self
.read_port("src3")
86 self
.r_ports
['rabc'] = self
.read_port("src1")
90 class FastRegs(RegFileMem
): #RegFileArray):
93 FAST regfile - CTR, LR, TAR, SRR1, SRR2, XER, TB, DEC
95 * QTY 6of 64-bit registers
97 * Array-based unary-indexed (not binary-indexed)
98 * write-through capability (read on same cycle as write)
100 Note: r/w issue are used by issuer to increment/decrement TB/DEC.
107 XER
= 5 # non-XER bits
110 N_REGS
= 8 # maximum number of regs
111 def __init__(self
, svp64_en
=False, regreduce_en
=False):
112 super().__init
__(64, self
.N_REGS
)
113 self
.w_ports
= {'fast1': self
.write_port("dest1"),
114 'issue': self
.write_port("issue"), # writing DEC/TB
116 self
.r_ports
= {'fast1': self
.read_port("src1"),
117 'issue': self
.read_port("issue"), # reading DEC/TB
120 self
.r_ports
['fast2'] = self
.read_port("src2")
124 class CRRegs(VirtualRegPort
):
125 """Condition Code Registers (CR0-7)
127 * QTY 8of 8-bit registers
128 * 3R1W 4-bit-wide with additional 1R1W for the "full" 32-bit width
129 * Array-based unary-indexed (not binary-indexed)
130 * write-through capability (read on same cycle as write)
132 def __init__(self
, svp64_en
=False, regreduce_en
=False):
133 super().__init
__(32, 8, rd2
=True)
134 self
.w_ports
= {'full_cr': self
.full_wr
, # 32-bit (masked, 8-en lines)
135 'cr_a': self
.write_port("dest1"), # 4-bit, unary-indexed
136 'cr_b': self
.write_port("dest2")} # 4-bit, unary-indexed
137 self
.r_ports
= {'full_cr': self
.full_rd
, # 32-bit (masked, 8-en lines)
138 'full_cr_dbg': self
.full_rd2
, # for DMI
139 'cr_a': self
.read_port("src1"),
140 'cr_b': self
.read_port("src2"),
141 'cr_c': self
.read_port("src3")}
143 self
.r_ports
['cr_pred'] = self
.read_port("cr_pred") # for predicate
147 class XERRegs(VirtualRegPort
):
148 """XER Registers (SO, CA/CA32, OV/OV32)
150 * QTY 3of 2-bit registers
151 * 3R3W 2-bit-wide with additional 1R1W for the "full" 6-bit width
152 * Array-based unary-indexed (not binary-indexed)
153 * write-through capability (read on same cycle as write)
155 SO
=0 # this is actually 2-bit but we ignore 1 bit of it
158 def __init__(self
, svp64_en
=False, regreduce_en
=False):
159 super().__init
__(6, 3)
160 self
.w_ports
= {'full_xer': self
.full_wr
, # 6-bit (masked, 3-en lines)
161 'xer_so': self
.write_port("dest1"),
162 'xer_ca': self
.write_port("dest2"),
163 'xer_ov': self
.write_port("dest3")}
164 self
.r_ports
= {'full_xer': self
.full_rd
, # 6-bit (masked, 3-en lines)
165 'xer_so': self
.read_port("src1"),
166 'xer_ca': self
.read_port("src2"),
167 'xer_ov': self
.read_port("src3")}
171 class SPRRegs(RegFileMem
):
174 * QTY len(SPRs) 64-bit registers
176 * binary-indexed but REQUIRES MAPPING
177 * write-through capability (read on same cycle as write)
179 def __init__(self
, svp64_en
=False, regreduce_en
=False):
181 n_sprs
= len(SPRreduced
)
183 n_sprs
= len(SPRfull
)
184 super().__init
__(width
=64, depth
=n_sprs
)
185 self
.w_ports
= {'spr1': self
.write_port("spr1")}
186 self
.r_ports
= {'spr1': self
.read_port("spr1")}
189 # class containing all regfiles: int, cr, xer, fast, spr
191 def __init__(self
, pspec
):
192 # test is SVP64 is to be enabled
193 svp64_en
= hasattr(pspec
, "svp64") and (pspec
.svp64
== True)
195 # and regfile port reduction
196 regreduce_en
= hasattr(pspec
, "regreduce") and \
197 (pspec
.regreduce
== True)
200 # create regfiles here, Factory style
201 for (name
, kls
) in [('int', IntRegs
),
205 ('state', StateRegs
),
207 rf
= self
.rf
[name
] = kls(svp64_en
, regreduce_en
)
208 # also add these as instances, self.state, self.fast, self.cr etc.
209 setattr(self
, name
, rf
)
211 def elaborate_into(self
, m
, platform
):
212 for (name
, rf
) in self
.rf
.items():
213 setattr(m
.submodules
, name
, rf
)