ae87e614000f4689ab6a75c2927548f248488f70
[soc.git] / src / scoreboard / shadow_fn.py
1 from nmigen.compat.sim import run_simulation
2 from nmigen.cli import verilog, rtlil
3 from nmigen import Module, Signal, Cat, Elaboratable
4 from nmutil.latch import SRLatch
5
6
7 class ShadowFn(Elaboratable):
8 """ implements shadowing 11.5.1, p55, just the individual shadow function
9 """
10 def __init__(self, syncreset=False):
11
12 self.syncreset = syncreset
13
14 # inputs
15 self.issue_i = Signal(reset_less=True)
16 self.shadow_i = Signal(reset_less=True)
17 self.reset_i = Signal(reset_less=True)
18 self.s_fail_i = Signal(reset_less=True)
19 self.s_good_i = Signal(reset_less=True)
20
21 # outputs
22 self.shadow_o = Signal(reset_less=True)
23 self.recover_o = Signal(reset_less=True)
24
25 def elaborate(self, platform):
26 m = Module()
27 m.submodules.sl = sl = SRLatch(sync=False)
28
29 reset_r = Signal()
30 if self.syncreset:
31 m.d.comb += reset_r.eq(self.s_good_i | self.s_fail_i | self.reset_i)
32 else:
33 m.d.comb += reset_r.eq(self.s_good_i | self.s_fail_i | self.reset_i)
34
35 m.d.comb += sl.s.eq(self.shadow_i & self.issue_i & \
36 ~self.s_good_i & ~reset_r)
37 m.d.comb += sl.r.eq(self.reset_i | reset_r | self.s_good_i | \
38 (self.issue_i & ~self.shadow_i))
39 m.d.comb += self.recover_o.eq(sl.qlq & self.s_fail_i)
40 m.d.comb += self.shadow_o.eq(sl.qlq)
41
42 return m
43
44 def __iter__(self):
45 yield self.issue_i
46 yield self.s_reset_i
47 yield self.shadow_i
48 yield self.s_fail_i
49 yield self.s_good_i
50 yield self.shadow_o
51 yield self.recover_o
52
53 def ports(self):
54 return list(self)
55
56
57 def shadow_fn_unit_sim(dut):
58 yield dut.dest_i.eq(1)
59 yield dut.issue_i.eq(1)
60 yield
61 yield dut.issue_i.eq(0)
62 yield
63 yield dut.src1_i.eq(1)
64 yield dut.issue_i.eq(1)
65 yield
66 yield
67 yield
68 yield dut.issue_i.eq(0)
69 yield
70 yield dut.go_rd_i.eq(1)
71 yield
72 yield dut.go_rd_i.eq(0)
73 yield
74 yield dut.go_wr_i.eq(1)
75 yield
76 yield dut.go_wr_i.eq(0)
77 yield
78
79
80 def test_shadow_fn_unit():
81 dut = ShadowFn()
82 vl = rtlil.convert(dut, ports=dut.ports())
83 with open("test_shadow_fn_unit.il", "w") as f:
84 f.write(vl)
85
86 run_simulation(dut, shadow_fn_unit_sim(dut),
87 vcd_name='test_shadow_fn_unit.vcd')
88
89 if __name__ == '__main__':
90 test_shadow_fn_unit()