0b9ebd922c221555faedc63afe04ef148ba22733
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 from nmutil
.latch
import SRLatch
7 class DependenceCell(Elaboratable
):
8 """ implements 11.4.7 mitch alsup dependence cell, p27
12 self
.dest_i
= Signal(reset_less
=True) # Dest in (top)
13 self
.src1_i
= Signal(reset_less
=True) # oper1 in (top)
14 self
.src2_i
= Signal(reset_less
=True) # oper2 in (top)
15 self
.issue_i
= Signal(reset_less
=True) # Issue in (top)
17 self
.go_wr_i
= Signal(reset_less
=True) # Go Write in (left)
18 self
.go_rd_i
= Signal(reset_less
=True) # Go Read in (left)
20 # for Register File Select Lines (vertical)
21 self
.dest_rsel_o
= Signal(reset_less
=True) # dest reg sel (bottom)
22 self
.src1_rsel_o
= Signal(reset_less
=True) # src1 reg sel (bottom)
23 self
.src2_rsel_o
= Signal(reset_less
=True) # src2 reg sel (bottom)
25 # for Function Unit "forward progress" (horizontal)
26 self
.dest_fwd_o
= Signal(reset_less
=True) # dest FU fw (right)
27 self
.src1_fwd_o
= Signal(reset_less
=True) # src1 FU fw (right)
28 self
.src2_fwd_o
= Signal(reset_less
=True) # src2 FU fw (right)
30 def elaborate(self
, platform
):
32 m
.submodules
.dest_l
= dest_l
= SRLatch(sync
=False) # clock-sync'd
33 m
.submodules
.src1_l
= src1_l
= SRLatch(sync
=False) # clock-sync'd
34 m
.submodules
.src2_l
= src2_l
= SRLatch(sync
=False) # clock-sync'd
36 # destination latch: reset on go_wr HI, set on dest and issue
37 m
.d
.comb
+= dest_l
.s
.eq(self
.issue_i
& self
.dest_i
)
38 m
.d
.comb
+= dest_l
.r
.eq(self
.go_wr_i
)
40 # src1 latch: reset on go_rd HI, set on src1_i and issue
41 m
.d
.comb
+= src1_l
.s
.eq(self
.issue_i
& self
.src1_i
)
42 m
.d
.comb
+= src1_l
.r
.eq(self
.go_rd_i
)
44 # src2 latch: reset on go_rd HI, set on op2_i and issue
45 m
.d
.comb
+= src2_l
.s
.eq(self
.issue_i
& self
.src2_i
)
46 m
.d
.comb
+= src2_l
.r
.eq(self
.go_rd_i
)
48 # FU "Forward Progress" (read out horizontally)
49 m
.d
.comb
+= self
.dest_fwd_o
.eq(dest_l
.q
& self
.go_wr_i
)
50 m
.d
.comb
+= self
.src1_fwd_o
.eq(src1_l
.q
& self
.go_rd_i
)
51 m
.d
.comb
+= self
.src2_fwd_o
.eq(src2_l
.q
& self
.go_rd_i
)
53 # Register File Select (read out vertically)
54 m
.d
.comb
+= self
.dest_rsel_o
.eq(dest_l
.q
& self
.dest_i
)
55 m
.d
.comb
+= self
.src1_rsel_o
.eq(src1_l
.q
& self
.src1_i
)
56 m
.d
.comb
+= self
.src2_rsel_o
.eq(src2_l
.q
& self
.src2_i
)
67 yield self
.dest_rsel_o
68 yield self
.src1_rsel_o
69 yield self
.src2_rsel_o
78 class DependencyRow(Elaboratable
):
79 def __init__(self
, n_reg_col
):
80 self
.n_reg_col
= n_reg_col
83 # fields all match DependencyCell precisely
85 self
.dest_i
= Signal(n_reg_col
, reset_less
=True)
86 self
.src1_i
= Signal(n_reg_col
, reset_less
=True)
87 self
.src2_i
= Signal(n_reg_col
, reset_less
=True)
89 self
.issue_i
= Signal(reset_less
=True)
90 self
.go_wr_i
= Signal(reset_less
=True)
91 self
.go_rd_i
= Signal(reset_less
=True)
93 self
.dest_rsel_o
= Signal(n_reg_col
, reset_less
=True)
94 self
.src1_rsel_o
= Signal(n_reg_col
, reset_less
=True)
95 self
.src2_rsel_o
= Signal(n_reg_col
, reset_less
=True)
97 self
.dest_fwd_o
= Signal(n_reg_col
, reset_less
=True)
98 self
.src1_fwd_o
= Signal(n_reg_col
, reset_less
=True)
99 self
.src2_fwd_o
= Signal(n_reg_col
, reset_less
=True)
101 def elaborate(self
, platform
):
103 rcell
= Array(DependenceCell() for f
in range(self
.n_reg_col
))
104 for rn
in range(self
.n_reg_col
):
105 setattr(m
.submodules
, "dm_r%d" % rn
, rcell
[rn
])
108 # connect Dep dest/src to module dest/src
113 for rn
in range(self
.n_reg_col
):
115 # accumulate cell inputs dest/src1/src2
116 dest_i
.append(dc
.dest_i
)
117 src1_i
.append(dc
.src1_i
)
118 src2_i
.append(dc
.src2_i
)
119 # wire up inputs from module to row cell inputs (Cat is gooood)
120 m
.d
.comb
+= [Cat(*dest_i
).eq(self
.dest_i
),
121 Cat(*src1_i
).eq(self
.src1_i
),
122 Cat(*src2_i
).eq(self
.src2_i
),
126 # connect Dep issue_i/go_rd_i/go_wr_i to module issue_i/go_rd/go_wr
128 for rn
in range(self
.n_reg_col
):
130 m
.d
.comb
+= [dc
.go_rd_i
.eq(self
.go_rd_i
),
131 dc
.go_wr_i
.eq(self
.go_wr_i
),
132 dc
.issue_i
.eq(self
.issue_i
),
136 # connect Function Unit vector
141 for rn
in range(self
.n_reg_col
):
143 # accumulate cell fwd outputs for dest/src1/src2
144 dest_fwd_o
.append(dc
.dest_fwd_o
)
145 src1_fwd_o
.append(dc
.src1_fwd_o
)
146 src2_fwd_o
.append(dc
.src2_fwd_o
)
147 # connect cell fwd outputs to FU Vector Out [Cat is gooood]
148 m
.d
.comb
+= [self
.dest_fwd_o
.eq(Cat(*dest_fwd_o
)),
149 self
.src1_fwd_o
.eq(Cat(*src1_fwd_o
)),
150 self
.src2_fwd_o
.eq(Cat(*src2_fwd_o
))
154 # connect Reg Selection vector
159 for rn
in range(self
.n_reg_col
):
161 # accumulate cell reg-select outputs dest/src1/src2
162 dest_rsel_o
.append(dc
.dest_rsel_o
)
163 src1_rsel_o
.append(dc
.src1_rsel_o
)
164 src2_rsel_o
.append(dc
.src2_rsel_o
)
165 # connect cell reg-select outputs to Reg Vector Out
166 m
.d
.comb
+= self
.dest_rsel_o
.eq(Cat(*dest_rsel_o
))
167 m
.d
.comb
+= self
.src1_rsel_o
.eq(Cat(*src1_rsel_o
))
168 m
.d
.comb
+= self
.src2_rsel_o
.eq(Cat(*src2_rsel_o
))
179 yield self
.dest_rsel_o
180 yield self
.src1_rsel_o
181 yield self
.src2_rsel_o
182 yield self
.dest_fwd_o
183 yield self
.src1_fwd_o
184 yield self
.src2_fwd_o
191 yield dut
.dest_i
.eq(1)
192 yield dut
.issue_i
.eq(1)
194 yield dut
.issue_i
.eq(0)
196 yield dut
.src1_i
.eq(1)
197 yield dut
.issue_i
.eq(1)
201 yield dut
.issue_i
.eq(0)
203 yield dut
.go_rd_i
.eq(1)
205 yield dut
.go_rd_i
.eq(0)
207 yield dut
.go_wr_i
.eq(1)
209 yield dut
.go_wr_i
.eq(0)
213 dut
= DependencyRow(4)
214 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
215 with
open("test_drow.il", "w") as f
:
218 dut
= DependenceCell()
219 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
220 with
open("test_dcell.il", "w") as f
:
223 run_simulation(dut
, dcell_sim(dut
), vcd_name
='test_dcell.vcd')
225 if __name__
== '__main__':