1 from nmigen
.compat
.sim
import run_simulation
2 from nmigen
.cli
import verilog
, rtlil
3 from nmigen
import Module
, Signal
, Const
, Elaboratable
4 from nmutil
.latch
import SRLatch
7 class DepCell(Elaboratable
):
10 def __init__(self
, llen
=1):
13 self
.pend_i
= Signal(llen
, reset_less
=True) # pending bit in (left)
14 self
.issue_i
= Signal(llen
, reset_less
=True) # Issue in (top)
15 self
.go_i
= Signal(llen
, reset_less
=True) # Go read/write in (left)
16 self
.die_i
= Signal(llen
, reset_less
=True) # Go die in (left)
19 self
.wait_o
= Signal(llen
, reset_less
=True) # wait out (right)
21 def elaborate(self
, platform
):
23 m
.submodules
.l
= l
= SRLatch(sync
=False, llen
=self
.llen
) # async latch
25 # reset on go HI, set on dest and issue
26 m
.d
.comb
+= l
.s
.eq(self
.issue_i
& self
.pend_i
)
27 m
.d
.comb
+= l
.r
.eq(self
.go_i | self
.die_i
)
30 m
.d
.comb
+= self
.wait_o
.eq(l
.qlq
& ~self
.issue_i
)
45 class FUDependenceCell(Elaboratable
):
46 """ implements 11.4.7 mitch alsup dependence cell, p27
48 def __init__(self
, dummy
, n_fu
=1):
50 self
.dummy
= Const(~
(1<<dummy
), n_fu
)
52 self
.rd_pend_i
= Signal(n_fu
, reset_less
=True) # read pend in (left)
53 self
.wr_pend_i
= Signal(n_fu
, reset_less
=True) # write pend in (left)
54 self
.issue_i
= Signal(n_fu
, reset_less
=True) # Issue in (top)
56 self
.go_wr_i
= Signal(n_fu
, reset_less
=True) # Go Write in (left)
57 self
.go_rd_i
= Signal(n_fu
, reset_less
=True) # Go Read in (left)
58 self
.go_die_i
= Signal(n_fu
, reset_less
=True) # Go Die in (left)
60 # outputs (latched rd/wr wait)
61 self
.rd_wait_o
= Signal(n_fu
, reset_less
=True) # read wait out (right)
62 self
.wr_wait_o
= Signal(n_fu
, reset_less
=True) # write wait out (right)
64 def elaborate(self
, platform
):
66 m
.submodules
.rd_c
= rd_c
= DepCell(self
.n_fu
)
67 m
.submodules
.wr_c
= wr_c
= DepCell(self
.n_fu
)
70 for c
in [rd_c
, wr_c
]:
71 m
.d
.comb
+= c
.issue_i
.eq(self
.issue_i
)
72 m
.d
.comb
+= c
.die_i
.eq(self
.go_die_i
)
74 # connect go_rd / go_wr
75 m
.d
.comb
+= wr_c
.go_i
.eq(self
.go_wr_i
)
76 m
.d
.comb
+= rd_c
.go_i
.eq(self
.go_rd_i
)
79 m
.d
.comb
+= wr_c
.pend_i
.eq(self
.wr_pend_i
& self
.dummy
)
80 m
.d
.comb
+= rd_c
.pend_i
.eq(self
.rd_pend_i
& self
.dummy
)
83 m
.d
.comb
+= self
.wr_wait_o
.eq(wr_c
.wait_o
)
84 m
.d
.comb
+= self
.rd_wait_o
.eq(rd_c
.wait_o
)
103 yield dut
.dest_i
.eq(1)
104 yield dut
.issue_i
.eq(1)
106 yield dut
.issue_i
.eq(0)
108 yield dut
.src1_i
.eq(1)
109 yield dut
.issue_i
.eq(1)
111 yield dut
.issue_i
.eq(0)
113 yield dut
.go_rd_i
.eq(1)
115 yield dut
.go_rd_i
.eq(0)
117 yield dut
.go_wr_i
.eq(1)
119 yield dut
.go_wr_i
.eq(0)
123 dut
= FUDependenceCell()
124 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
125 with
open("test_fu_dcell.il", "w") as f
:
128 run_simulation(dut
, dcell_sim(dut
), vcd_name
='test_fu_dcell.vcd')
130 if __name__
== '__main__':