test.blinky: invert LED status when button/switch is active.
[nmigen-boards.git] / nmigen_boards / test / blinky.py
1 import itertools
2
3 from nmigen import *
4 from nmigen.build import ResourceError
5
6
7 __all__ = ["Blinky"]
8
9
10 class Blinky(Elaboratable):
11 def elaborate(self, platform):
12 m = Module()
13
14 def get_all_resources(name):
15 resources = []
16 for number in itertools.count():
17 try:
18 resources.append(platform.request(name, number))
19 except ResourceError:
20 break
21 return resources
22
23 leds = [res.o for res in get_all_resources("led")]
24 buttons = [res.i for res in get_all_resources("button")]
25 switches = [res.i for res in get_all_resources("switch")]
26
27 inverts = [0 for _ in leds]
28 for index, button in zip(itertools.cycle(range(len(inverts))), buttons):
29 inverts[index] ^= button
30 for index, switch in zip(itertools.cycle(range(len(inverts))), switches):
31 inverts[index] ^= switch
32
33 clk_freq = platform.default_clk_frequency
34 timer = Signal(max=int(clk_freq//2), reset=int(clk_freq//2) - 1)
35 flops = Signal(len(leds))
36
37 m.d.comb += Cat(leds).eq(flops ^ Cat(inverts))
38 with m.If(timer == 0):
39 m.d.sync += timer.eq(timer.reset)
40 m.d.sync += flops.eq(~flops)
41 with m.Else():
42 m.d.sync += timer.eq(timer - 1)
43
44 return m