reduce number of FastRegs read ports
[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 - PC, MSR, CTR, LR, TAR, SRR1, SRR2
11
12 Note: this should NOT have name conventions hard-coded (dedicated ports per
13 regname). However it is convenient for now.
14
15 Links:
16
17 * https://bugs.libre-soc.org/show_bug.cgi?id=345
18 * https://bugs.libre-soc.org/show_bug.cgi?id=351
19 * https://libre-soc.org/3d_gpu/architecture/regfile/
20 * https://libre-soc.org/openpower/isatables/sprs.csv
21 """
22
23 # TODO
24
25 from soc.regfile.regfile import RegFile, RegFileArray
26 from soc.regfile.virtual_port import VirtualRegPort
27 from soc.decoder.power_enums import SPR
28
29
30 # Integer Regfile
31 class IntRegs(RegFileArray):
32 """IntRegs
33
34 * QTY 32of 64-bit registers
35 * 3R2W
36 * Array-based unary-indexed (not binary-indexed)
37 * write-through capability (read on same cycle as write)
38 """
39 def __init__(self):
40 super().__init__(64, 32)
41 self.w_ports = {'o': self.write_port("dest1"),
42 'o1': self.write_port("dest2")} # for now (LD/ST update)
43 self.r_ports = {'ra': self.read_port("src1"),
44 'rb': self.read_port("src2"),
45 'rc': self.read_port("src3")}
46
47
48 # Fast SPRs Regfile
49 class FastRegs(RegFileArray):
50 """FastRegs
51
52 FAST regfile - PC, MSR, CTR, LR, TAR, SRR1, SRR2
53
54 * QTY 8of 64-bit registers
55 * 3R2W
56 * Array-based unary-indexed (not binary-indexed)
57 * write-through capability (read on same cycle as write)
58
59 Note: d_wr1 d_rd1 are for use by the decoder, to get at the PC.
60 will probably have to also add one so it can get at the MSR as well.
61 (d_rd2)
62 """
63 PC = 0
64 MSR = 1
65 CTR = 2
66 LR = 3
67 TAR = 4
68 SRR0 = 5
69 SRR1 = 6
70 def __init__(self):
71 super().__init__(64, 8)
72 self.w_ports = {'nia': self.write_port("nia"),
73 'msr': self.write_port("dest2"),
74 'fast1': self.write_port("dest3"),
75 'fast2': self.write_port("dest4"),
76 'd_wr1': self.write_port("d_wr1")} # writing PC (issuer)
77 self.r_ports = {'cia': self.read_port("cia"), # reading PC (issuer)
78 'msr': self.read_port("msr"), # reading MSR (issuer)
79 'fast1': self.read_port("src1"),
80 'fast2': self.read_port("src2"),
81 }
82
83
84 # CR Regfile
85 class CRRegs(VirtualRegPort):
86 """Condition Code Registers (CR0-7)
87
88 * QTY 8of 8-bit registers
89 * 3R1W 4-bit-wide with additional 1R1W for the "full" 32-bit width
90 * Array-based unary-indexed (not binary-indexed)
91 * write-through capability (read on same cycle as write)
92 """
93 def __init__(self):
94 super().__init__(32, 8)
95 self.w_ports = {'full_cr': self.full_wr, # 32-bit (masked, 8-en lines)
96 'cr_a': self.write_port("dest1"), # 4-bit, unary-indexed
97 'cr_b': self.write_port("dest2")} # 4-bit, unary-indexed
98 self.r_ports = {'full_cr': self.full_rd, # 32-bit (masked, 8-en lines)
99 'cr_a': self.read_port("src1"),
100 'cr_b': self.read_port("src2"),
101 'cr_c': self.read_port("src3")}
102
103
104 # XER Regfile
105 class XERRegs(VirtualRegPort):
106 """XER Registers (SO, CA/CA32, OV/OV32)
107
108 * QTY 3of 2-bit registers
109 * 3R3W 2-bit-wide with additional 1R1W for the "full" 6-bit width
110 * Array-based unary-indexed (not binary-indexed)
111 * write-through capability (read on same cycle as write)
112 """
113 SO=0 # this is actually 2-bit but we ignore 1 bit of it
114 CA=1 # CA and CA32
115 OV=2 # OV and OV32
116 def __init__(self):
117 super().__init__(6, 3)
118 self.w_ports = {'full_xer': self.full_wr, # 6-bit (masked, 3-en lines)
119 'xer_so': self.write_port("dest1"),
120 'xer_ca': self.write_port("dest2"),
121 'xer_ov': self.write_port("dest3")}
122 self.r_ports = {'full_xer': self.full_rd, # 6-bit (masked, 3-en lines)
123 'xer_so': self.read_port("src1"),
124 'xer_ca': self.read_port("src2"),
125 'xer_ov': self.read_port("src3")}
126
127
128 # SPR Regfile
129 class SPRRegs(RegFile):
130 """SPRRegs
131
132 * QTY len(SPRs) 64-bit registers
133 * 1R1W
134 * binary-indexed but REQUIRES MAPPING
135 * write-through capability (read on same cycle as write)
136 """
137 def __init__(self):
138 n_sprs = len(SPR)
139 super().__init__(64, n_sprs)
140 self.w_ports = {'spr1': self.write_port(name="dest")}
141 self.r_ports = {'spr1': self.read_port("src")}
142
143
144 # class containing all regfiles: int, cr, xer, fast, spr
145 class RegFiles:
146 def __init__(self):
147 self.rf = {}
148 for (name, kls) in [('int', IntRegs),
149 ('cr', CRRegs),
150 ('xer', XERRegs),
151 ('fast', FastRegs),
152 ('spr', SPRRegs),]:
153 rf = self.rf[name] = kls()
154 setattr(self, name, rf)
155
156 def elaborate_into(self, m, platform):
157 for (name, rf) in self.rf.items():
158 setattr(m.submodules, name, rf)
159 return m
160