add shadow_fn.py, split out from function unit
[ieee754fpu.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 from nmigen.lib.coding import Decoder
6
7
8 class ShadowFn(Elaboratable):
9 """ implements shadowing 11.5.1, p55, just the individual shadow function
10 """
11 def __init__(self):
12
13 # inputs
14 self.issue_i = Signal(reset_less=True)
15 self.shadow_i = Signal(reset_less=True)
16 self.s_fail_i = Signal(reset_less=True)
17 self.s_good_i = Signal(reset_less=True)
18
19 # outputs
20 self.shadow_o = Signal(reset_less=True)
21 self.recover_o = Signal(reset_less=True)
22 self.shadow_o = Signal(reset_less=True)
23
24 def elaborate(self, platform):
25 m = Module()
26 m.submodules.sl = sl = SRLatch(sync=False)
27
28 m.d.comb += sl.s.eq(self.shadow_i & self.issue_i)
29 m.d.comb += sl.r.eq(self.s_good_i)
30 m.d.comb += self.recover_o.eq(sl.q & self.s_fail_i)
31 m.d.comb += self.shadow_o.eq(sl.q)
32
33 return m
34
35 def __iter__(self):
36 yield self.issue_i
37 yield self.shadow_i
38 yield self.s_fail_i
39 yield self.s_good_i
40 yield self.shadow_o
41 yield self.recover_o
42 yield self.shadow_o
43
44 def ports(self):
45 return list(self)
46
47
48 def shadow_fn_unit_sim(dut):
49 yield dut.dest_i.eq(1)
50 yield dut.issue_i.eq(1)
51 yield
52 yield dut.issue_i.eq(0)
53 yield
54 yield dut.src1_i.eq(1)
55 yield dut.issue_i.eq(1)
56 yield
57 yield
58 yield
59 yield dut.issue_i.eq(0)
60 yield
61 yield dut.go_read_i.eq(1)
62 yield
63 yield dut.go_read_i.eq(0)
64 yield
65 yield dut.go_write_i.eq(1)
66 yield
67 yield dut.go_write_i.eq(0)
68 yield
69
70
71 def test_shadow_fn_unit():
72 dut = ShadowFn()
73 vl = rtlil.convert(dut, ports=dut.ports())
74 with open("test_shadow_fn_unit.il", "w") as f:
75 f.write(vl)
76
77 run_simulation(dut, shadow_fn_unit_sim(dut),
78 vcd_name='test_shadow_fn_unit.vcd')
79
80 if __name__ == '__main__':
81 test_shadow_fn_unit()