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 openpower
.decoder
.power_enums
import SPRfull
, SPRreduced
31 # XXX MAKE DAMN SURE TO KEEP THESE UP-TO-DATE if changing/adding regs
32 from openpower
.consts
import StateRegsEnum
, XERRegsEnum
, FastRegsEnum
36 class StateRegs(RegFileArray
, StateRegsEnum
):
39 State regfile - PC, MSR, SVSTATE (for SimpleV)
41 * QTY 3of 64-bit registers
43 * Array-based unary-indexed (not binary-indexed)
44 * write-through capability (read on same cycle as write)
46 Note: d_wr1 d_rd1 are for use by the decoder, to get at the PC.
47 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, StateRegsEnum
.N_REGS
)
53 self
.w_ports
= {'nia': self
.write_port("nia"),
54 'msr': self
.write_port("msr"),
55 'svstate': self
.write_port("svstate"),
56 'sv': self
.write_port("sv"), # writing SVSTATE (issuer)
57 'd_wr1': self
.write_port("d_wr1")} # writing PC (issuer)
58 self
.r_ports
= {'cia': self
.read_port("cia"), # reading PC (issuer)
59 'msr': self
.read_port("msr"), # reading MSR (issuer)
60 'sv': self
.read_port("sv"), # reading SV (issuer)
65 class IntRegs(RegFileMem
): #class IntRegs(RegFileArray):
68 * QTY 32of 64-bit registers
70 * Array-based unary-indexed (not binary-indexed)
71 * write-through capability (read on same cycle as write)
73 def __init__(self
, svp64_en
=False, regreduce_en
=False):
74 super().__init
__(64, 32, fwd_bus_mode
=not regreduce_en
)
75 self
.w_ports
= {'o': self
.write_port("dest1"),
78 'dmi': self
.read_port("dmi")} # needed for Debug (DMI)
80 self
.r_ports
['pred'] = self
.read_port("pred") # for predicate mask
82 self
.w_ports
['o1'] = self
.write_port("dest2") # (LD/ST update)
83 self
.r_ports
['ra'] = self
.read_port("src1")
84 self
.r_ports
['rb'] = self
.read_port("src2")
85 self
.r_ports
['rc'] = self
.read_port("src3")
87 self
.r_ports
['rabc'] = self
.read_port("src1")
91 class FastRegs(RegFileMem
, FastRegsEnum
): #RegFileArray):
94 FAST regfile - CTR, LR, TAR, SRR1, SRR2, XER, TB, DEC, SVSRR0
96 * QTY 6of 64-bit registers
98 * Array-based unary-indexed (not binary-indexed)
99 * write-through capability (read on same cycle as write)
101 Note: r/w issue are used by issuer to increment/decrement TB/DEC.
103 def __init__(self
, svp64_en
=False, regreduce_en
=False):
104 super().__init
__(64, FastRegsEnum
.N_REGS
, fwd_bus_mode
=not regreduce_en
)
105 self
.w_ports
= {'fast1': self
.write_port("dest1"),
106 'issue': self
.write_port("issue"), # writing DEC/TB
108 self
.r_ports
= {'fast1': self
.read_port("src1"),
109 'issue': self
.read_port("issue"), # reading DEC/TB
112 self
.r_ports
['fast2'] = self
.read_port("src2")
116 class CRRegs(VirtualRegPort
):
117 """Condition Code Registers (CR0-7)
119 * QTY 8of 8-bit registers
120 * 3R1W 4-bit-wide with additional 1R1W for the "full" 32-bit width
121 * Array-based unary-indexed (not binary-indexed)
122 * write-through capability (read on same cycle as write)
124 def __init__(self
, svp64_en
=False, regreduce_en
=False):
125 super().__init
__(32, 8, rd2
=True)
126 self
.w_ports
= {'full_cr': self
.full_wr
, # 32-bit (masked, 8-en lines)
127 'cr_a': self
.write_port("dest1"), # 4-bit, unary-indexed
128 'cr_b': self
.write_port("dest2")} # 4-bit, unary-indexed
129 self
.r_ports
= {'full_cr': self
.full_rd
, # 32-bit (masked, 8-en lines)
130 'full_cr_dbg': self
.full_rd2
, # for DMI
131 'cr_a': self
.read_port("src1"),
132 'cr_b': self
.read_port("src2"),
133 'cr_c': self
.read_port("src3")}
135 self
.r_ports
['cr_pred'] = self
.read_port("cr_pred") # for predicate
139 class XERRegs(VirtualRegPort
, XERRegsEnum
):
140 """XER Registers (SO, CA/CA32, OV/OV32)
142 * QTY 3of 2-bit registers
143 * 3R3W 2-bit-wide with additional 1R1W for the "full" 6-bit width
144 * Array-based unary-indexed (not binary-indexed)
145 * write-through capability (read on same cycle as write)
147 SO
=0 # this is actually 2-bit but we ignore 1 bit of it
150 def __init__(self
, svp64_en
=False, regreduce_en
=False):
151 super().__init
__(6, XERRegsEnum
.N_REGS
)
152 self
.w_ports
= {'full_xer': self
.full_wr
, # 6-bit (masked, 3-en lines)
153 'xer_so': self
.write_port("dest1"),
154 'xer_ca': self
.write_port("dest2"),
155 'xer_ov': self
.write_port("dest3")}
156 self
.r_ports
= {'full_xer': self
.full_rd
, # 6-bit (masked, 3-en lines)
157 'xer_so': self
.read_port("src1"),
158 'xer_ca': self
.read_port("src2"),
159 'xer_ov': self
.read_port("src3")}
163 class SPRRegs(RegFileMem
):
166 * QTY len(SPRs) 64-bit registers
168 * binary-indexed but REQUIRES MAPPING
169 * write-through capability (read on same cycle as write)
171 def __init__(self
, svp64_en
=False, regreduce_en
=False):
173 n_sprs
= len(SPRreduced
)
175 n_sprs
= len(SPRfull
)
176 super().__init
__(width
=64, depth
=n_sprs
,
177 fwd_bus_mode
=not regreduce_en
)
178 self
.w_ports
= {'spr1': self
.write_port("spr1")}
179 self
.r_ports
= {'spr1': self
.read_port("spr1")}
182 # class containing all regfiles: int, cr, xer, fast, spr
184 def __init__(self
, pspec
):
185 # test is SVP64 is to be enabled
186 svp64_en
= hasattr(pspec
, "svp64") and (pspec
.svp64
== True)
188 # and regfile port reduction
189 regreduce_en
= hasattr(pspec
, "regreduce") and \
190 (pspec
.regreduce
== True)
193 # create regfiles here, Factory style
194 for (name
, kls
) in [('int', IntRegs
),
198 ('state', StateRegs
),
200 rf
= self
.rf
[name
] = kls(svp64_en
, regreduce_en
)
201 # also add these as instances, self.state, self.fast, self.cr etc.
202 setattr(self
, name
, rf
)
204 def elaborate_into(self
, m
, platform
):
205 for (name
, rf
) in self
.rf
.items():
206 setattr(m
.submodules
, name
, rf
)