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
26 from soc
.regfile
.regfile
import RegFile
, RegFileArray
27 from soc
.regfile
.virtual_port
import VirtualRegPort
28 from soc
.decoder
.power_enums
import SPR
29 from nmigen
import Memory
, Elaboratable
33 class StateRegs(RegFileArray
):
36 State regfile - PC, MSR and later SimpleV VL
38 * QTY 2of 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.
50 super().__init
__(64, 2)
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)
60 class IntRegs(RegFileArray
):
63 * QTY 32of 64-bit registers
65 * Array-based unary-indexed (not binary-indexed)
66 * write-through capability (read on same cycle as write)
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)
73 self
.r_ports
= {'ra': self
.read_port("src1"),
74 'rbc': self
.read_port("src3"),
75 'dmi': self
.read_port("dmi")} # needed for Debug (DMI)
79 class FastRegs(RegFileArray
):
82 FAST regfile - CTR, LR, TAR, SRR1, SRR2
84 * QTY 5of 64-bit registers
86 * Array-based unary-indexed (not binary-indexed)
87 * write-through capability (read on same cycle as write)
95 super().__init
__(64, 5)
96 self
.w_ports
= {'fast1': self
.write_port("dest3"),
98 self
.r_ports
= {'fast1': self
.read_port("src1"),
103 class CRRegs(VirtualRegPort
):
104 """Condition Code Registers (CR0-7)
106 * QTY 8of 8-bit registers
107 * 3R1W 4-bit-wide with additional 1R1W for the "full" 32-bit width
108 * Array-based unary-indexed (not binary-indexed)
109 * write-through capability (read on same cycle as write)
112 super().__init
__(32, 8)
113 self
.w_ports
= {'full_cr': self
.full_wr
, # 32-bit (masked, 8-en lines)
114 'cr_a': self
.write_port("dest1"), # 4-bit, unary-indexed
115 'cr_b': self
.write_port("dest2")} # 4-bit, unary-indexed
116 self
.r_ports
= {'full_cr': self
.full_rd
, # 32-bit (masked, 8-en lines)
117 'cr_a': self
.read_port("src1"),
118 'cr_b': self
.read_port("src2"),
119 'cr_c': self
.read_port("src3")}
123 class XERRegs(VirtualRegPort
):
124 """XER Registers (SO, CA/CA32, OV/OV32)
126 * QTY 3of 2-bit registers
127 * 3R3W 2-bit-wide with additional 1R1W for the "full" 6-bit width
128 * Array-based unary-indexed (not binary-indexed)
129 * write-through capability (read on same cycle as write)
131 SO
=0 # this is actually 2-bit but we ignore 1 bit of it
135 super().__init
__(6, 3)
136 self
.w_ports
= {'full_xer': self
.full_wr
, # 6-bit (masked, 3-en lines)
137 'xer_so': self
.write_port("dest1"),
138 'xer_ca': self
.write_port("dest2"),
139 'xer_ov': self
.write_port("dest3")}
140 self
.r_ports
= {'full_xer': self
.full_rd
, # 6-bit (masked, 3-en lines)
141 'xer_so': self
.read_port("src1"),
142 'xer_ca': self
.read_port("src2"),
143 'xer_ov': self
.read_port("src3")}
147 class SPRRegs(Memory
, Elaboratable
):
150 * QTY len(SPRs) 64-bit registers
152 * binary-indexed but REQUIRES MAPPING
153 * write-through capability (read on same cycle as write)
157 super().__init
__(width
=64, depth
=n_sprs
)
158 self
.w_ports
= {'spr1': self
.write_port()}
159 self
.r_ports
= {'spr1': self
.read_port()}
161 # make read/write ports look like RegFileArray
162 self
.w_ports
['spr1'].wen
= self
.w_ports
['spr1'].en
163 self
.w_ports
['spr1'].data_i
= self
.w_ports
['spr1'].data
165 self
.r_ports
['spr1'].ren
= self
.w_ports
['spr1'].en
166 self
.r_ports
['spr1'].data_o
= self
.w_ports
['spr1'].data
169 # class containing all regfiles: int, cr, xer, fast, spr
173 for (name
, kls
) in [('int', IntRegs
),
177 ('state', StateRegs
),
179 rf
= self
.rf
[name
] = kls()
180 setattr(self
, name
, rf
)
182 def elaborate_into(self
, m
, platform
):
183 for (name
, rf
) in self
.rf
.items():
184 setattr(m
.submodules
, name
, rf
)