add CR read to DMI interface
[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, RegFileMem
27 from soc.regfile.virtual_port import VirtualRegPort
28 from soc.decoder.power_enums import SPR
29
30
31 # "State" Regfile
32 class StateRegs(RegFileArray):
33 """StateRegs
34
35 State regfile - PC, MSR and later SimpleV VL
36
37 * QTY 2of 64-bit registers
38 * 3R2W
39 * Array-based unary-indexed (not binary-indexed)
40 * write-through capability (read on same cycle as write)
41
42 Note: d_wr1 d_rd1 are for use by the decoder, to get at the PC.
43 will probably have to also add one so it can get at the MSR as well.
44 (d_rd2)
45 """
46 PC = 0
47 MSR = 1
48 def __init__(self):
49 super().__init__(64, 2)
50 self.w_ports = {'nia': self.write_port("nia"),
51 'msr': self.write_port("msr"),
52 'd_wr1': self.write_port("d_wr1")} # writing PC (issuer)
53 self.r_ports = {'cia': self.read_port("cia"), # reading PC (issuer)
54 'msr': self.read_port("msr"), # reading MSR (issuer)
55 }
56
57
58 # Integer Regfile
59 class IntRegs(RegFileMem): #class IntRegs(RegFileArray):
60 """IntRegs
61
62 * QTY 32of 64-bit registers
63 * 3R2W
64 * Array-based unary-indexed (not binary-indexed)
65 * write-through capability (read on same cycle as write)
66 """
67 def __init__(self):
68 super().__init__(64, 32)
69 self.w_ports = {'o': self.write_port("dest1"),
70 #'o1': self.write_port("dest2") # for now (LD/ST update)
71 }
72 self.r_ports = {'ra': self.read_port("src1"),
73 'rb': self.read_port("src2"),
74 'rc': self.read_port("src3"),
75 'dmi': self.read_port("dmi")} # needed for Debug (DMI)
76
77
78 # Fast SPRs Regfile
79 class FastRegs(RegFileMem): #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("dest1"),
97 }
98 self.r_ports = {'fast1': self.read_port("src1"),
99 'fast2': self.read_port("src2"),
100 }
101
102
103 # CR Regfile
104 class CRRegs(VirtualRegPort):
105 """Condition Code Registers (CR0-7)
106
107 * QTY 8of 8-bit registers
108 * 3R1W 4-bit-wide with additional 1R1W for the "full" 32-bit width
109 * Array-based unary-indexed (not binary-indexed)
110 * write-through capability (read on same cycle as write)
111 """
112 def __init__(self):
113 super().__init__(32, 8, rd2=True)
114 self.w_ports = {'full_cr': self.full_wr, # 32-bit (masked, 8-en lines)
115 'cr_a': self.write_port("dest1"), # 4-bit, unary-indexed
116 'cr_b': self.write_port("dest2")} # 4-bit, unary-indexed
117 self.r_ports = {'full_cr': self.full_rd, # 32-bit (masked, 8-en lines)
118 'full_cr_dbg': self.full_rd2, # for DMI
119 'cr_a': self.read_port("src1"),
120 'cr_b': self.read_port("src2"),
121 'cr_c': self.read_port("src3")}
122
123
124 # XER Regfile
125 class XERRegs(VirtualRegPort):
126 """XER Registers (SO, CA/CA32, OV/OV32)
127
128 * QTY 3of 2-bit registers
129 * 3R3W 2-bit-wide with additional 1R1W for the "full" 6-bit width
130 * Array-based unary-indexed (not binary-indexed)
131 * write-through capability (read on same cycle as write)
132 """
133 SO=0 # this is actually 2-bit but we ignore 1 bit of it
134 CA=1 # CA and CA32
135 OV=2 # OV and OV32
136 def __init__(self):
137 super().__init__(6, 3)
138 self.w_ports = {'full_xer': self.full_wr, # 6-bit (masked, 3-en lines)
139 'xer_so': self.write_port("dest1"),
140 'xer_ca': self.write_port("dest2"),
141 'xer_ov': self.write_port("dest3")}
142 self.r_ports = {'full_xer': self.full_rd, # 6-bit (masked, 3-en lines)
143 'xer_so': self.read_port("src1"),
144 'xer_ca': self.read_port("src2"),
145 'xer_ov': self.read_port("src3")}
146
147
148 # SPR Regfile
149 class SPRRegs(RegFileMem):
150 """SPRRegs
151
152 * QTY len(SPRs) 64-bit registers
153 * 1R1W
154 * binary-indexed but REQUIRES MAPPING
155 * write-through capability (read on same cycle as write)
156 """
157 def __init__(self):
158 n_sprs = len(SPR)
159 super().__init__(width=64, depth=n_sprs)
160 self.w_ports = {'spr1': self.write_port("spr1")}
161 self.r_ports = {'spr1': self.read_port("spr1")}
162
163
164 # class containing all regfiles: int, cr, xer, fast, spr
165 class RegFiles:
166 def __init__(self):
167 self.rf = {}
168 for (name, kls) in [('int', IntRegs),
169 ('cr', CRRegs),
170 ('xer', XERRegs),
171 ('fast', FastRegs),
172 ('state', StateRegs),
173 ('spr', SPRRegs),]:
174 rf = self.rf[name] = kls()
175 setattr(self, name, rf)
176
177 def elaborate_into(self, m, platform):
178 for (name, rf) in self.rf.items():
179 setattr(m.submodules, name, rf)
180 return m
181