add MSR reading to issue FSM
[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
77 self.r_ports = {'cia': self.read_port("src1"),
78 'msr': self.read_port("src2"),
79 'fast1': self.read_port("src3"),
80 'fast2': self.read_port("src4"),
81 'd_rd1': self.read_port("d_rd1"), # reading PC
82 'd_rd2': self.read_port("d_rd2")} # reading MSR
83
84
85 # CR Regfile
86 class CRRegs(VirtualRegPort):
87 """Condition Code Registers (CR0-7)
88
89 * QTY 8of 8-bit registers
90 * 3R1W 4-bit-wide with additional 1R1W for the "full" 32-bit width
91 * Array-based unary-indexed (not binary-indexed)
92 * write-through capability (read on same cycle as write)
93 """
94 def __init__(self):
95 super().__init__(32, 8)
96 self.w_ports = {'full_cr': self.full_wr, # 32-bit (masked, 8-en lines)
97 'cr_a': self.write_port("dest1"), # 4-bit, unary-indexed
98 'cr_b': self.write_port("dest2")} # 4-bit, unary-indexed
99 self.r_ports = {'full_cr': self.full_rd, # 32-bit (masked, 8-en lines)
100 'cr_a': self.read_port("src1"),
101 'cr_b': self.read_port("src2"),
102 'cr_c': self.read_port("src3")}
103
104
105 # XER Regfile
106 class XERRegs(VirtualRegPort):
107 """XER Registers (SO, CA/CA32, OV/OV32)
108
109 * QTY 3of 2-bit registers
110 * 3R3W 2-bit-wide with additional 1R1W for the "full" 6-bit width
111 * Array-based unary-indexed (not binary-indexed)
112 * write-through capability (read on same cycle as write)
113 """
114 SO=0 # this is actually 2-bit but we ignore 1 bit of it
115 CA=1 # CA and CA32
116 OV=2 # OV and OV32
117 def __init__(self):
118 super().__init__(6, 3)
119 self.w_ports = {'full_xer': self.full_wr, # 6-bit (masked, 3-en lines)
120 'xer_so': self.write_port("dest1"),
121 'xer_ca': self.write_port("dest2"),
122 'xer_ov': self.write_port("dest3")}
123 self.r_ports = {'full_xer': self.full_rd, # 6-bit (masked, 3-en lines)
124 'xer_so': self.read_port("src1"),
125 'xer_ca': self.read_port("src2"),
126 'xer_ov': self.read_port("src3")}
127
128
129 # SPR Regfile
130 class SPRRegs(RegFile):
131 """SPRRegs
132
133 * QTY len(SPRs) 64-bit registers
134 * 1R1W
135 * binary-indexed but REQUIRES MAPPING
136 * write-through capability (read on same cycle as write)
137 """
138 def __init__(self):
139 n_sprs = len(SPR)
140 super().__init__(64, n_sprs)
141 self.w_ports = {'spr1': self.write_port(name="dest")}
142 self.r_ports = {'spr1': self.read_port("src")}
143
144
145 # class containing all regfiles: int, cr, xer, fast, spr
146 class RegFiles:
147 def __init__(self):
148 self.rf = {}
149 for (name, kls) in [('int', IntRegs),
150 ('cr', CRRegs),
151 ('xer', XERRegs),
152 ('fast', FastRegs),
153 ('spr', SPRRegs),]:
154 rf = self.rf[name] = kls()
155 setattr(self, name, rf)
156
157 def elaborate_into(self, m, platform):
158 for (name, rf) in self.rf.items():
159 setattr(m.submodules, name, rf)
160 return m
161