Fix DFII testing, test address set
[gram.git] / gram / test / test_compat.py
1 from nmigen import *
2 from nmigen.hdl.ast import Past
3 from nmigen.asserts import Assert, Assume
4
5 from gram.compat import *
6 from utils import *
7
8 class DelayedEnterTestCase(FHDLTestCase):
9 def test_sequence(self):
10 def sequence(expected_delay):
11 m = Module()
12
13 before = Signal()
14 end = Signal()
15
16 with m.FSM():
17 with m.State("Before-Delayed-Enter"):
18 m.d.comb += before.eq(1)
19 m.next = "Delayed-Enter"
20
21 delayed_enter(m, "Delayed-Enter", "End-Delayed-Enter", expected_delay)
22
23 with m.State("End-Delayed-Enter"):
24 m.d.comb += end.eq(1)
25
26 def process():
27 while (yield before):
28 yield
29
30 delay = 0
31 while not (yield end):
32 yield
33 delay += 1
34
35 self.assertEqual(delay, expected_delay)
36
37 runSimulation(m, process, "test_delayedenter.vcd")
38
39 with self.assertRaises(AssertionError):
40 sequence(0)
41 sequence(1)
42 sequence(2)
43 sequence(10)
44 sequence(100)
45 sequence(1000)
46
47 class TimelineTestCase(FHDLTestCase):
48 def test_sequence(self):
49 sigA = Signal()
50 sigB = Signal()
51 sigC = Signal()
52 timeline = Timeline([
53 (1, sigA.eq(1)),
54 (5, sigA.eq(1)),
55 (7, sigA.eq(0)),
56 (10, sigB.eq(1)),
57 (11, sigB.eq(0)),
58 ])
59 m = Module()
60 m.submodules.timeline = timeline
61
62 def process():
63 # Test default value for unset signals
64 self.assertFalse((yield sigA))
65 self.assertFalse((yield sigB))
66
67 # Ensure that the sequence isn't triggered without the trigger signal
68 for i in range(100):
69 yield
70 self.assertFalse((yield sigA))
71 self.assertFalse((yield sigB))
72
73 yield timeline.trigger.eq(1)
74 yield
75 yield timeline.trigger.eq(0)
76
77 for i in range(11+1):
78 yield
79
80 if i == 1:
81 self.assertTrue((yield sigA))
82 self.assertFalse((yield sigB))
83 elif i == 5:
84 self.assertTrue((yield sigA))
85 self.assertFalse((yield sigB))
86 elif i == 7:
87 self.assertFalse((yield sigA))
88 self.assertFalse((yield sigB))
89 elif i == 10:
90 self.assertFalse((yield sigA))
91 self.assertTrue((yield sigB))
92 elif i == 11:
93 self.assertFalse((yield sigA))
94 self.assertFalse((yield sigB))
95
96 # Ensure no changes happen once the sequence is done
97 for i in range(100):
98 yield
99 self.assertFalse((yield sigA))
100 self.assertFalse((yield sigB))
101
102 runSimulation(m, process, "test_timeline.vcd")
103
104 class RoundRobinOutputMatchSpec(Elaboratable):
105 def __init__(self, dut):
106 self.dut = dut
107
108 def elaborate(self, platform):
109 m = Module()
110
111 m.d.comb += Assume(Rose(self.dut.stb).implies(self.dut.request == Past(self.dut.request)))
112
113 m.d.sync += Assert(((Past(self.dut.request) != 0) & Past(self.dut.stb)).implies(Past(self.dut.request) & (1 << self.dut.grant)))
114
115 return m
116
117 class RoundRobinTestCase(FHDLTestCase):
118 def test_sequence(self):
119 m = Module()
120 m.submodules.rb = roundrobin = RoundRobin(8)
121
122 def process():
123 yield roundrobin.request.eq(0b10001000)
124 yield roundrobin.stb.eq(1)
125 yield
126 yield
127
128 self.assertEqual((yield roundrobin.grant), 3)
129 yield
130
131 self.assertEqual((yield roundrobin.grant), 7)
132 yield
133
134 self.assertEqual((yield roundrobin.grant), 3)
135 yield roundrobin.request.eq(0b00000001)
136 yield
137 yield
138
139 self.assertEqual((yield roundrobin.grant), 0)
140
141 runSimulation(m, process, "test_roundrobin.vcd")
142
143 # def test_output_match(self):
144 # roundrobin = RoundRobin(32)
145 # spec = RoundRobinOutputMatchSpec(roundrobin)
146 # self.assertFormal(spec, mode="bmc", depth=10)