adb12f47549c549a67799e16d55def375c36d625
1 from nmigen
.compat
.sim
import run_simulation
2 from nmigen
.cli
import verilog
, rtlil
3 from nmigen
import Module
, Signal
, Cat
, Array
, Const
, Elaboratable
4 from nmigen
.lib
.coding
import Decoder
6 from nmutil
.latch
import SRLatch
, latchregister
8 from scoreboard
.shadow_fn
import ShadowFn
11 class Shadow(Elaboratable
):
12 """ implements shadowing 11.5.1, p55
14 shadowing can be used for branches as well as exceptions (interrupts),
15 load/store hold (exceptions again), and vector-element predication
16 (once the predicate is known, which it may not be at instruction issue)
20 * :wid: register file width
21 * :shadow_wid: number of shadow/fail/good/go_die sets
22 * :n_dests: number of destination regfile(s) (index: rfile_sel_i)
23 * :wr_pend: if true, writable observes the g_wr_pend_i vector
24 otherwise observes g_rd_pend_i
28 * dest_i / src1_i / src2_i are in *binary*, whereas...
29 * ...g_rd_pend_i / g_wr_pend_i and rd_pend_o / wr_pend_o are UNARY
30 * req_rel_i (request release) is the direct equivalent of pipeline
31 "output valid" (valid_o)
32 * recover is a local python variable (actually go_die_o)
33 * when shadow_wid = 0, recover and shadown are Consts (i.e. do nothing)
34 * wr_pend is set False for the majority of uses: however for
35 use in a STORE Function Unit it is set to True
37 def __init__(self
, shadow_wid
=0):
38 self
.shadow_wid
= shadow_wid
41 self
.issue_i
= Signal(reset_less
=True)
42 self
.shadow_i
= Signal(shadow_wid
, reset_less
=True)
43 self
.s_fail_i
= Signal(shadow_wid
, reset_less
=True)
44 self
.s_good_i
= Signal(shadow_wid
, reset_less
=True)
45 self
.go_die_o
= Signal(reset_less
=True)
46 self
.shadown_o
= Signal(reset_less
=True)
48 self
.shadown_o
= Const(1)
49 self
.go_die_o
= Const(0)
51 def elaborate(self
, platform
):
54 for i
in range(self
.shadow_wid
):
56 setattr(m
.submodules
, "shadow%d" % i
, sh
)
59 # shadow / recover (optional: shadow_wid > 0)
67 # get list of latch signals. really must be a better way to do this
70 shi_l
.append(l
.shadow_i
)
71 fail_l
.append(l
.s_fail_i
)
72 good_l
.append(l
.s_good_i
)
73 sho_l
.append(l
.shadow_o
)
74 rec_l
.append(l
.recover_o
)
75 m
.d
.comb
+= Cat(*i_l
).eq(self
.issue_i
)
76 m
.d
.comb
+= Cat(*fail_l
).eq(self
.s_fail_i
)
77 m
.d
.comb
+= Cat(*good_l
).eq(self
.s_good_i
)
78 m
.d
.comb
+= Cat(*shi_l
).eq(self
.shadow_i
)
79 m
.d
.comb
+= self
.shadown_o
.eq(~
(Cat(*sho_l
).bool()))
80 m
.d
.comb
+= self
.go_die_o
.eq(Cat(*rec_l
).bool())
98 yield dut
.dest_i
.eq(1)
99 yield dut
.issue_i
.eq(1)
101 yield dut
.issue_i
.eq(0)
103 yield dut
.src1_i
.eq(1)
104 yield dut
.issue_i
.eq(1)
108 yield dut
.issue_i
.eq(0)
110 yield dut
.go_rd_i
.eq(1)
112 yield dut
.go_rd_i
.eq(0)
114 yield dut
.go_wr_i
.eq(1)
116 yield dut
.go_wr_i
.eq(0)
121 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
122 with
open("test_shadow.il", "w") as f
:
125 run_simulation(dut
, shadow_sim(dut
), vcd_name
='test_shadow.vcd')
127 if __name__
== '__main__':