1 from nmigen
.compat
.sim
import run_simulation
2 from nmigen
.cli
import verilog
, rtlil
3 from nmigen
import Module
, Signal
, Cat
, Repl
, Const
, Elaboratable
4 from nmutil
.latch
import SRLatch
7 class ShadowFn(Elaboratable
):
8 """ implements shadowing 11.5.1, p55, just the individual shadow function
10 shadowing can be used for branches as well as exceptions (interrupts),
11 load/store hold (exceptions again), and vector-element predication
12 (once the predicate is known, which it may not be at instruction issue)
15 * :shadow_wid: number of shadow/fail/good/go_die sets
18 * when shadow_wid = 0, recover and shadown are Consts (i.e. do nothing)
20 def __init__(self
, slen
, syncreset
=False):
23 self
.syncreset
= syncreset
27 self
.issue_i
= Signal(reset_less
=True)
28 self
.shadow_i
= Signal(slen
, reset_less
=True)
29 self
.reset_i
= Signal(reset_less
=True)
30 self
.s_fail_i
= Signal(slen
, reset_less
=True)
31 self
.s_good_i
= Signal(slen
, reset_less
=True)
34 self
.shadown_o
= Signal(reset_less
=True)
35 self
.go_die_o
= Signal(reset_less
=True)
37 # outputs when no shadowing needed
38 self
.shadown_o
= Const(1)
39 self
.go_die_o
= Const(0)
41 def elaborate(self
, platform
):
46 m
.submodules
.sl
= sl
= SRLatch(sync
=False, llen
=self
.slen
)
48 r_ext
= Repl(self
.reset_i
, self
.slen
)
49 reset_r
= Signal(self
.slen
)
51 m
.d
.comb
+= reset_r
.eq(self
.s_good_i | self
.s_fail_i | r_ext
)
53 m
.d
.comb
+= reset_r
.eq(self
.s_good_i | self
.s_fail_i | r_ext
)
55 i_ext
= Repl(self
.issue_i
, self
.slen
)
56 m
.d
.comb
+= sl
.s
.eq(self
.shadow_i
& i_ext
& \
57 ~self
.s_good_i
& ~reset_r
)
58 m
.d
.comb
+= sl
.r
.eq(r_ext | reset_r | self
.s_good_i | \
59 (i_ext
& ~self
.shadow_i
))
60 m
.d
.comb
+= self
.go_die_o
.eq((sl
.qlq
& self
.s_fail_i
).bool())
61 m
.d
.comb
+= self
.shadown_o
.eq(~sl
.qlq
.bool())
78 def shadow_fn_unit_sim(dut
):
79 yield dut
.dest_i
.eq(1)
80 yield dut
.issue_i
.eq(1)
82 yield dut
.issue_i
.eq(0)
84 yield dut
.src1_i
.eq(1)
85 yield dut
.issue_i
.eq(1)
89 yield dut
.issue_i
.eq(0)
91 yield dut
.go_rd_i
.eq(1)
93 yield dut
.go_rd_i
.eq(0)
95 yield dut
.go_wr_i
.eq(1)
97 yield dut
.go_wr_i
.eq(0)
101 def test_shadow_fn_unit():
103 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
104 with
open("test_shadow_fn_unit.il", "w") as f
:
107 run_simulation(dut
, shadow_fn_unit_sim(dut
),
108 vcd_name
='test_shadow_fn_unit.vcd')
110 if __name__
== '__main__':
111 test_shadow_fn_unit()