add FU-FU Dependency Matrix
[ieee754fpu.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
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_write_i = Signal(n_fu_row, reset_less=True) # Go Write in (left)
27 self.go_read_i = Signal(n_fu_row, reset_less=True) # Go Read in (left)
28
29 # for Function Unit Readable/Writable (horizontal)
30 self.readable_o = Signal(n_fu_col, reset_less=True) # readable (bot)
31 self.writable_o = Signal(n_fu_col, reset_less=True) # writable (bot)
32
33 def elaborate(self, platform):
34 m = Module()
35
36 # ---
37 # matrix of dependency cells
38 # ---
39 dm = Array(Array(FUDependenceCell() for r in range(self.n_fu_row)) \
40 for f in range(self.n_fu_col))
41 for x in range(self.n_fu_col):
42 for y in range(self.n_fu_row):
43 setattr(m.submodules, "dm_fx%d_fy%d" % (x, y), dm[x][y])
44
45 # ---
46 # array of Function Unit Readable/Writable: row-length, horizontal
47 # ---
48 fur = Array(FU_Pick_Vec(self.n_fu_row) for r in range(self.n_fu_col))
49 for x in range(self.n_fu_col):
50 setattr(m.submodules, "fur_x%d" % (x), fur[x])
51
52 # ---
53 # connect FU Readable/Writable vector
54 # ---
55 readable = []
56 writable = []
57 for x in range(self.n_fu_col):
58 fu = fur[x]
59 rd_pend_o = []
60 wr_pend_o = []
61 for y in range(self.n_fu_row):
62 dc = dm[x][y]
63 # accumulate cell outputs rd/wr-pending
64 rd_pend_o.append(dc.rd_pend_o)
65 wr_pend_o.append(dc.wr_pend_o)
66 # connect cell reg-select outputs to Reg Vector In
67 m.d.comb += [fu.rd_pend_i.eq(Cat(*rd_pend_o)),
68 fu.wr_pend_i.eq(Cat(*wr_pend_o)),
69 ]
70 # accumulate Readable/Writable Vector outputs
71 readable.append(fu.readable_o)
72 writable.append(fu.writable_o)
73
74 # ... and output them from this module (horizontal, width=REGs)
75 m.d.comb += self.readable_o.eq(Cat(*readable))
76 m.d.comb += self.writable_o.eq(Cat(*writable))
77
78 # ---
79 # connect Dependency Matrix dest/src1/src2/issue to module d/s/s/i
80 # ---
81 for y in range(self.n_fu_row):
82 issue_i = []
83 for x in range(self.n_fu_col):
84 dc = dm[x][y]
85 # accumulate cell inputs issue
86 issue_i.append(dc.issue_i)
87 # wire up inputs from module to row cell inputs (Cat is gooood)
88 m.d.comb += Cat(*issue_i).eq(self.issue_i)
89
90 # ---
91 # connect Matrix go_read_i/go_write_i to module readable/writable
92 # ---
93 for x in range(self.n_fu_col):
94 go_read_i = []
95 go_write_i = []
96 rd_pend_i = []
97 wr_pend_i = []
98 for y in range(self.n_fu_row):
99 dc = dm[x][y]
100 # accumulate cell rd_pend/wr_pend/go_read/go_write
101 rd_pend_i.append(dc.rd_pend_i)
102 wr_pend_i.append(dc.wr_pend_i)
103 go_read_i.append(dc.go_read_i)
104 go_write_i.append(dc.go_write_i)
105 # wire up inputs from module to row cell inputs (Cat is gooood)
106 m.d.comb += [Cat(*go_read_i).eq(self.go_read_i),
107 Cat(*go_write_i).eq(self.go_write_i),
108 Cat(*rd_pend_i).eq(self.rd_pend_i),
109 Cat(*wr_pend_i).eq(self.wr_pend_i),
110 ]
111
112 return m
113
114 def __iter__(self):
115 yield self.rd_pend_i
116 yield self.wr_pend_i
117 yield self.issue_i
118 yield self.go_write_i
119 yield self.go_read_i
120 yield self.readable_o
121 yield self.writable_o
122
123 def ports(self):
124 return list(self)
125
126 def d_matrix_sim(dut):
127 """ XXX TODO
128 """
129 yield dut.dest_i.eq(1)
130 yield dut.issue_i.eq(1)
131 yield
132 yield dut.issue_i.eq(0)
133 yield
134 yield dut.src1_i.eq(1)
135 yield dut.issue_i.eq(1)
136 yield
137 yield dut.issue_i.eq(0)
138 yield
139 yield dut.go_read_i.eq(1)
140 yield
141 yield dut.go_read_i.eq(0)
142 yield
143 yield dut.go_write_i.eq(1)
144 yield
145 yield dut.go_write_i.eq(0)
146 yield
147
148 def test_fu_fu_matrix():
149 dut = FUFUDepMatrix(n_fu_row=3, n_fu_col=4)
150 vl = rtlil.convert(dut, ports=dut.ports())
151 with open("test_fu_fu_matrix.il", "w") as f:
152 f.write(vl)
153
154 run_simulation(dut, d_matrix_sim(dut), vcd_name='test_fu_fu_matrix.vcd')
155
156 if __name__ == '__main__':
157 test_fu_fu_matrix()