reduce regfile port usage for INT and FAST
[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
27 from soc.regfile.virtual_port import VirtualRegPort
28 from soc.decoder.power_enums import SPR
29 from nmigen import Memory, Elaboratable
30
31
32 # "State" Regfile
33 class StateRegs(RegFileArray):
34 """StateRegs
35
36 State regfile - PC, MSR and later SimpleV VL
37
38 * QTY 2of 64-bit registers
39 * 3R2W
40 * Array-based unary-indexed (not binary-indexed)
41 * write-through capability (read on same cycle as write)
42
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.
45 (d_rd2)
46 """
47 PC = 0
48 MSR = 1
49 def __init__(self):
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)
56 }
57
58
59 # Integer Regfile
60 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 'rbc': self.read_port("src3"),
75 'dmi': self.read_port("dmi")} # needed for Debug (DMI)
76
77
78 # Fast SPRs Regfile
79 class FastRegs(RegFileArray):
80 """FastRegs
81
82 FAST regfile - CTR, LR, TAR, SRR1, SRR2
83
84 * QTY 5of 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 def __init__(self):
95 super().__init__(64, 5)
96 self.w_ports = {'fast1': self.write_port("dest3"),
97 }
98 self.r_ports = {'fast1': self.read_port("src1"),
99 }
100
101
102 # CR Regfile
103 class CRRegs(VirtualRegPort):
104 """Condition Code Registers (CR0-7)
105
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)
110 """
111 def __init__(self):
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")}
120
121
122 # XER Regfile
123 class XERRegs(VirtualRegPort):
124 """XER Registers (SO, CA/CA32, OV/OV32)
125
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)
130 """
131 SO=0 # this is actually 2-bit but we ignore 1 bit of it
132 CA=1 # CA and CA32
133 OV=2 # OV and OV32
134 def __init__(self):
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")}
144
145
146 # SPR Regfile
147 class SPRRegs(Memory, Elaboratable):
148 """SPRRegs
149
150 * QTY len(SPRs) 64-bit registers
151 * 1R1W
152 * binary-indexed but REQUIRES MAPPING
153 * write-through capability (read on same cycle as write)
154 """
155 def __init__(self):
156 n_sprs = len(SPR)
157 super().__init__(width=64, depth=n_sprs)
158 self.w_ports = {'spr1': self.write_port()}
159 self.r_ports = {'spr1': self.read_port()}
160
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
164
165 self.r_ports['spr1'].ren = self.w_ports['spr1'].en
166 self.r_ports['spr1'].data_o = self.w_ports['spr1'].data
167
168
169 # class containing all regfiles: int, cr, xer, fast, spr
170 class RegFiles:
171 def __init__(self):
172 self.rf = {}
173 for (name, kls) in [('int', IntRegs),
174 ('cr', CRRegs),
175 ('xer', XERRegs),
176 ('fast', FastRegs),
177 ('state', StateRegs),
178 ('spr', SPRRegs),]:
179 rf = self.rf[name] = kls()
180 setattr(self, name, rf)
181
182 def elaborate_into(self, m, platform):
183 for (name, rf) in self.rf.items():
184 setattr(m.submodules, name, rf)
185 return m
186