5d8b2cb21d7db509fd6633b9f8b6cfcfc1c52aad
[soc.git] / src / scoreboard / fu_fu_matrix.py
1 from nmigen.compat.sim import run_simulation
2 from nmigen.cli import verilog, rtlil
3 from nmigen import Module, Signal, Elaboratable, Array, Cat, Const
4
5 #from nmutil.latch import SRLatch
6 from .fu_dep_cell import FUDependenceCell
7 from .fu_picker_vec import FU_Pick_Vec
8
9 """
10
11 6600 Function Unit Dependency Table Matrix inputs / outputs
12 -----------------------------------------------------------
13
14 """
15
16 class FUFUDepMatrix(Elaboratable):
17 """ implements 11.4.7 mitch alsup FU-to-Reg Dependency Matrix, p26
18 """
19 def __init__(self, n_fu_row, n_fu_col):
20 self.n_fu_row = n_fu_row # Y (FU row#) ^v
21 self.n_fu_col = n_fu_col # X (FU col #) <>
22 self.rd_pend_i = Signal(n_fu_row, reset_less=True) # Rd pending (left)
23 self.wr_pend_i = Signal(n_fu_row, reset_less=True) # Wr pending (left)
24 self.issue_i = Signal(n_fu_col, reset_less=True) # Issue in (top)
25
26 self.go_wr_i = Signal(n_fu_row, reset_less=True) # Go Write in (left)
27 self.go_rd_i = Signal(n_fu_row, reset_less=True) # Go Read in (left)
28 self.go_die_i = Signal(n_fu_row, reset_less=True) # Go Die in (left)
29
30 # for Function Unit Readable/Writable (horizontal)
31 self.readable_o = Signal(n_fu_col, reset_less=True) # readable (bot)
32 self.writable_o = Signal(n_fu_col, reset_less=True) # writable (bot)
33
34 def elaborate(self, platform):
35 m = Module()
36
37 # ---
38 # matrix of dependency cells
39 # ---
40 dm = Array(Array(FUDependenceCell() for r in range(self.n_fu_row)) \
41 for f in range(self.n_fu_col))
42 for x in range(self.n_fu_col):
43 for y in range(self.n_fu_row):
44 setattr(m.submodules, "dm_fx%d_fy%d" % (x, y), dm[x][y])
45
46 # ---
47 # array of Function Unit Readable/Writable: row-length, horizontal
48 # ---
49 fur = Array(FU_Pick_Vec(self.n_fu_row) for r in range(self.n_fu_col))
50 for x in range(self.n_fu_col):
51 setattr(m.submodules, "fur_x%d" % (x), fur[x])
52
53 # ---
54 # connect FU Readable/Writable vector
55 # ---
56 readable = []
57 writable = []
58 for x in range(self.n_fu_col):
59 fu = fur[x]
60 # accumulate Readable/Writable Vector outputs
61 readable.append(fu.readable_o)
62 writable.append(fu.writable_o)
63
64 # ... and output them from this module (horizontal, width=REGs)
65 m.d.comb += self.readable_o.eq(Cat(*readable))
66 m.d.comb += self.writable_o.eq(Cat(*writable))
67
68 # ---
69 # connect FU Pending
70 # ---
71 for y in range(self.n_fu_row):
72 fu = fur[y]
73 rd_wait_o = []
74 wr_wait_o = []
75 for x in range(self.n_fu_col):
76 dc = dm[x][y]
77 # accumulate cell outputs rd/wr-pending
78 rd_wait_o.append(dc.rd_wait_o)
79 wr_wait_o.append(dc.wr_wait_o)
80 # connect cell reg-select outputs to Reg Vector In
81 m.d.comb += [fu.rd_pend_i.eq(Cat(*rd_wait_o)),
82 fu.wr_pend_i.eq(Cat(*wr_wait_o)),
83 ]
84 # ---
85 # connect Dependency Matrix dest/src1/src2/issue to module d/s/s/i
86 # ---
87 for x in range(self.n_fu_col):
88 issue_i = []
89 for y in range(self.n_fu_row):
90 dc = dm[x][y]
91 # accumulate cell inputs issue
92 issue_i.append(dc.issue_i)
93 # wire up inputs from module to row cell inputs (Cat is gooood)
94 m.d.comb += Cat(*issue_i).eq(self.issue_i)
95
96 # ---
97 # connect Matrix go_rd_i/go_wr_i to module readable/writable
98 # ---
99 for y in range(self.n_fu_row):
100 go_rd_i = []
101 go_wr_i = []
102 go_die_i = []
103 for x in range(self.n_fu_col):
104 dc = dm[x][y]
105 # accumulate cell go_rd/go_wr
106 go_rd_i.append(dc.go_rd_i)
107 go_wr_i.append(dc.go_wr_i)
108 go_die_i.append(dc.go_die_i)
109 # wire up inputs from module to row cell inputs (Cat is gooood)
110 m.d.comb += [Cat(*go_rd_i).eq(self.go_rd_i),
111 Cat(*go_wr_i).eq(self.go_wr_i),
112 Cat(*go_die_i).eq(self.go_die_i),
113 ]
114
115 # ---
116 # connect Matrix pending
117 # ---
118 for y in range(self.n_fu_row):
119 rd_pend_i = []
120 wr_pend_i = []
121 for x in range(self.n_fu_col):
122 if x == y: # ignore hazards on the diagonal: self-against-self
123 dummyrd = Signal(reset_less=True)
124 dummywr = Signal(reset_less=True)
125 rd_pend_i.append(dummyrd)
126 wr_pend_i.append(dummywr)
127 continue
128 dc = dm[x][y]
129 # accumulate cell rd_pend/wr_pend/go_rd/go_wr
130 rd_pend_i.append(dc.rd_pend_i)
131 wr_pend_i.append(dc.wr_pend_i)
132 # wire up inputs from module to row cell inputs (Cat is gooood)
133 m.d.comb += [Cat(*rd_pend_i).eq(self.rd_pend_i),
134 Cat(*wr_pend_i).eq(self.wr_pend_i),
135 ]
136
137 return m
138
139 def __iter__(self):
140 yield self.rd_pend_i
141 yield self.wr_pend_i
142 yield self.issue_i
143 yield self.go_wr_i
144 yield self.go_rd_i
145 yield self.readable_o
146 yield self.writable_o
147
148 def ports(self):
149 return list(self)
150
151 def d_matrix_sim(dut):
152 """ XXX TODO
153 """
154 yield dut.dest_i.eq(1)
155 yield dut.issue_i.eq(1)
156 yield
157 yield dut.issue_i.eq(0)
158 yield
159 yield dut.src1_i.eq(1)
160 yield dut.issue_i.eq(1)
161 yield
162 yield dut.issue_i.eq(0)
163 yield
164 yield dut.go_rd_i.eq(1)
165 yield
166 yield dut.go_rd_i.eq(0)
167 yield
168 yield dut.go_wr_i.eq(1)
169 yield
170 yield dut.go_wr_i.eq(0)
171 yield
172
173 def test_fu_fu_matrix():
174 dut = FUFUDepMatrix(n_fu_row=3, n_fu_col=4)
175 vl = rtlil.convert(dut, ports=dut.ports())
176 with open("test_fu_fu_matrix.il", "w") as f:
177 f.write(vl)
178
179 run_simulation(dut, d_matrix_sim(dut), vcd_name='test_fu_fu_matrix.vcd')
180
181 if __name__ == '__main__':
182 test_fu_fu_matrix()