move SVP64 Extra reg decoding into main PowerDecoder module
[soc.git] / src / soc / scoreboard / fu_mem_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 soc.scoreboard.fumem_dep_cell import FUMemDependenceCell
6 from soc.scoreboard.fu_mem_picker_vec import FUMem_Pick_Vec
7
8 """
9
10 6600 Function Unit Dependency Table Matrix inputs / outputs
11 -----------------------------------------------------------
12
13 """
14
15 class FUMemDepMatrix(Elaboratable):
16 """ implements FU-to-FU Memory Dependency Matrix
17 """
18 def __init__(self, n_fu_row, n_fu_col):
19 self.n_fu_row = n_fu_row # Y (FU row#) ^v
20 self.n_fu_col = n_fu_col # X (FU col #) <>
21 self.st_pend_i = Signal(n_fu_row, reset_less=True) # Rd pending (left)
22 self.ld_pend_i = Signal(n_fu_row, reset_less=True) # Wr pending (left)
23 self.issue_i = Signal(n_fu_col, reset_less=True) # Issue in (top)
24
25 self.go_ld_i = Signal(n_fu_row, reset_less=True) # Go Write in (left)
26 self.go_st_i = Signal(n_fu_row, reset_less=True) # Go Read in (left)
27 self.go_die_i = Signal(n_fu_row, reset_less=True) # Go Die in (left)
28
29 # for Function Unit Readable/Writable (horizontal)
30 self.storable_o = Signal(n_fu_col, reset_less=True) # storable (bot)
31 self.loadable_o = Signal(n_fu_col, reset_less=True) # loadable (bot)
32
33 def elaborate(self, platform):
34 m = Module()
35
36 # ---
37 # matrix of dependency cells
38 # ---
39 dm = Array(FUMemDependenceCell(f, self.n_fu_col) \
40 for f in range(self.n_fu_row))
41 for y in range(self.n_fu_row):
42 setattr(m.submodules, "dm%d" % y, dm[y])
43
44 # ---
45 # array of Function Unit Readable/Writable: row-length, horizontal
46 # ---
47 fur = Array(FUMem_Pick_Vec(self.n_fu_row) for r in range(self.n_fu_col))
48 for x in range(self.n_fu_col):
49 setattr(m.submodules, "fur_x%d" % (x), fur[x])
50
51 # ---
52 # connect FU Readable/Writable vector
53 # ---
54 storable = []
55 loadable = []
56 for y in range(self.n_fu_row):
57 fu = fur[y]
58 # accumulate Readable/Writable Vector outputs
59 storable.append(fu.storable_o)
60 loadable.append(fu.loadable_o)
61
62 # ... and output them from this module (horizontal, width=REGs)
63 m.d.comb += self.storable_o.eq(Cat(*storable))
64 m.d.comb += self.loadable_o.eq(Cat(*loadable))
65
66 # ---
67 # connect FU Pending
68 # ---
69 for y in range(self.n_fu_row):
70 dc = dm[y]
71 fu = fur[y]
72 # connect cell reg-select outputs to Reg Vector In
73 m.d.comb += [fu.st_pend_i.eq(dc.st_wait_o),
74 fu.ld_pend_i.eq(dc.ld_wait_o),
75 ]
76
77 # ---
78 # connect Dependency Matrix dest/src1/src2/issue to module d/s/s/i
79 # ---
80 for x in range(self.n_fu_col):
81 issue_i = []
82 for y in range(self.n_fu_row):
83 dc = dm[y]
84 # accumulate cell inputs issue
85 issue_i.append(dc.issue_i[x])
86 # wire up inputs from module to row cell inputs
87 m.d.comb += Cat(*issue_i).eq(self.issue_i)
88
89 # ---
90 # connect Matrix go_st_i/go_ld_i to module storable/loadable
91 # ---
92 for y in range(self.n_fu_row):
93 dc = dm[y]
94 # wire up inputs from module to row cell inputs
95 m.d.comb += [dc.go_st_i.eq(self.go_st_i),
96 dc.go_ld_i.eq(self.go_ld_i),
97 dc.go_die_i.eq(self.go_die_i),
98 ]
99
100 # ---
101 # connect Matrix pending
102 # ---
103 for y in range(self.n_fu_row):
104 dc = dm[y]
105 # wire up inputs from module to row cell inputs
106 m.d.comb += [dc.st_pend_i.eq(self.st_pend_i),
107 dc.ld_pend_i.eq(self.ld_pend_i),
108 ]
109
110 return m
111
112 def __iter__(self):
113 yield self.st_pend_i
114 yield self.ld_pend_i
115 yield self.issue_i
116 yield self.go_ld_i
117 yield self.go_st_i
118 yield self.storable_o
119 yield self.loadable_o
120
121 def ports(self):
122 return list(self)
123
124 def d_matrix_sim(dut):
125 """ XXX TODO
126 """
127 yield dut.ld_i.eq(1)
128 yield dut.issue_i.eq(1)
129 yield
130 yield dut.issue_i.eq(0)
131 yield
132 yield dut.st_i.eq(1)
133 yield dut.issue_i.eq(1)
134 yield
135 yield dut.issue_i.eq(0)
136 yield
137 yield dut.go_st_i.eq(1)
138 yield
139 yield dut.go_st_i.eq(0)
140 yield
141 yield dut.go_ld_i.eq(1)
142 yield
143 yield dut.go_ld_i.eq(0)
144 yield
145
146 def test_fu_fu_matrix():
147 dut = FUMemDepMatrix(n_fu_row=3, n_fu_col=3)
148 vl = rtlil.convert(dut, ports=dut.ports())
149 with open("test_fu_mem_matrix.il", "w") as f:
150 f.write(vl)
151
152 run_simulation(dut, d_matrix_sim(dut), vcd_name='test_fu_mem_matrix.vcd')
153
154 if __name__ == '__main__':
155 test_fu_fu_matrix()