up_counter: Forgot to remove commented imports
[nmigen-examples.git] / up_counter / up_counter.py
1 from nmigen import Signal, Value, Elaboratable, Module, Cat, Const
2 from nmigen.build import Platform
3
4 # --- CONVERT ---
5 from nmigen.back import verilog
6
7 from nmigen.sim import Simulator, Delay, Settle, Tick, Passive
8
9 from nmutil.gtkw import write_gtkw
10
11
12 class UpCounter(Elaboratable):
13 """
14 A 16-bit up counter with a fixed limit.
15
16 Parameters
17 ----------
18 limit : int
19 The value at which the counter overflows.
20
21 Attributes
22 ----------
23 en : Signal, in
24 The counter is incremented if ``en`` is asserted, and retains
25 its value otherwise.
26 ovf : Signal, out
27 ``ovf`` is asserted when the counter reaches its limit.
28 """
29 def __init__(self, limit):
30 self.limit = limit
31
32 # Ports
33 self.en = Signal()
34 self.ovf = Signal()
35
36 # State
37 self.count = Signal(16)
38
39 def elaborate(self, platform):
40 m = Module()
41
42 m.d.comb += self.ovf.eq(self.count == self.limit)
43
44 with m.If(self.en):
45 with m.If(self.ovf):
46 m.d.sync += self.count.eq(0)
47 with m.Else():
48 m.d.sync += self.count.eq(self.count + 1)
49
50 return m
51 # --- TEST ---
52 from nmigen.sim import Simulator
53
54
55 dut = UpCounter(25)
56 def bench():
57 # Disabled counter should not overflow.
58 yield dut.en.eq(0)
59 for _ in range(30):
60 yield
61 assert not (yield dut.ovf)
62
63 # Once enabled, the counter should overflow in 25 cycles.
64 yield dut.en.eq(1)
65 for _ in range(25):
66 yield
67 assert not (yield dut.ovf)
68 yield
69 assert (yield dut.ovf)
70
71 # The overflow should clear in one cycle.
72 yield
73 assert not (yield dut.ovf)
74
75
76 sim = Simulator(dut)
77 sim.add_clock(1e-6) # 1 MHz
78 sim.add_sync_process(bench)
79 with sim.write_vcd("up_counter.vcd"):
80 sim.run()
81
82 # GTKWave doc generation
83 style = {
84 '': {'base': 'dec'},
85 'in': {'color': 'orange'},
86 'out': {'color': 'yellow'},
87 'pad_i': {'color': 'orange'},
88 'pad_o': {'color': 'yellow'},
89 'core_i': {'color': 'indigo'},
90 'core_o': {'color': 'blue'},
91 'debug': {'module': 'top', 'color': 'red'}
92 }
93 traces = [
94 ('Counter', [
95 ('clk', 'in'),
96 ('en', 'in'),
97 ('ovf', 'in'),
98 ('rst', 'in'),
99 ('count[15:0]', 'out')
100 ])
101 ]
102
103 write_gtkw("up_counter.gtkw", "up_counter.vcd", traces, style, module="bench.top")
104
105 top = UpCounter(25)
106 with open("up_counter.v", "w") as f:
107 f.write(verilog.convert(top, ports=[top.en, top.ovf]))