~kameliya/hayasa

ref: 60bb01255f7d742a3f0c4bd3d7b5ef064e8969d0 hayasa/led.py -rw-r--r-- 4.0 KiB
60bb0125Asherah Connor init 9 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
from nmigen import *
from nmigen.build import *
from nmigen_boards.icebreaker import ICEBreakerPlatform

# This PMOD is provided with your icebreaker, and should be attached
# to PMOD1A.
seven_seg_pmod = [
    Resource("seven_seg", 0,
             Subsignal("aa", PinsN("1", dir="o", conn=("pmod", 1)),
                       Attrs(IO_STANDARD="SB_LVCMOS33")),
             Subsignal("ab", PinsN("2", dir="o", conn=("pmod", 1)),
                       Attrs(IO_STANDARD="SB_LVCMOS33")),
             Subsignal("ac", PinsN("3", dir="o", conn=("pmod", 1)),
                       Attrs(IO_STANDARD="SB_LVCMOS33")),
             Subsignal("ad", PinsN("4", dir="o", conn=("pmod", 1)),
                       Attrs(IO_STANDARD="SB_LVCMOS33")),
             Subsignal("ae", PinsN("7", dir="o", conn=("pmod", 1)),
                       Attrs(IO_STANDARD="SB_LVCMOS33")),
             Subsignal("af", PinsN("8", dir="o", conn=("pmod", 1)),
                       Attrs(IO_STANDARD="SB_LVCMOS33")),
             Subsignal("ag", PinsN("9", dir="o", conn=("pmod", 1)),
                       Attrs(IO_STANDARD="SB_LVCMOS33")),
             Subsignal("ca", PinsN("10", dir="o", conn=("pmod", 1)), Attrs(IO_STANDARD="SB_LVCMOS33")))
]


class Top(Elaboratable):
    def __init__(self):
        # TODO: Figure out how to expose the P1A{1-4, 7-10} pins in the
        # constructor so Top can be built in a potentially platform-agnostic
        # way using nmigen.cli.main. For now, only put child modules in
        # constructor.
        self.ones_to_segs = DigitToSegments()
        self.tens_to_segs = DigitToSegments()

    def elaborate(self, platform):
        seg_pins = platform.request("seven_seg")

        m = Module()

        seg_pins_cat = Signal(7)

        counter = Signal(30)
        ones_counter = Signal(4)
        tens_counter = Signal(4)
        display_state = Signal(3)

        m.submodules.ones_to_segs = self.ones_to_segs
        m.submodules.tens_to_segs = self.tens_to_segs

        m.d.comb += [
            Cat([seg_pins.aa, seg_pins.ab, seg_pins.ac, seg_pins.ad,
                 seg_pins.ae, seg_pins.af, seg_pins.ag]).eq(seg_pins_cat),
            ones_counter.eq(counter[21:25]),
            tens_counter.eq(counter[25:29]),
            display_state.eq(counter[2:5]),
            self.ones_to_segs.digit.eq(ones_counter),
            self.tens_to_segs.digit.eq(tens_counter)
        ]

        m.d.sync += counter.eq(counter + 1)

        with m.Switch(display_state):
            with m.Case("00-"):
                m.d.sync += seg_pins_cat.eq(self.ones_to_segs.segments)
            with m.Case("010"):
                m.d.sync += seg_pins_cat.eq(0)
            with m.Case("011"):
                m.d.sync += seg_pins.ca.eq(1)
            with m.Case("10-"):
                m.d.sync += seg_pins_cat.eq(self.tens_to_segs.segments)
            with m.Case("110"):
                m.d.sync += seg_pins_cat.eq(0)
            with m.Case("111"):
                m.d.sync += seg_pins.ca.eq(0)

        return m


class DigitToSegments(Elaboratable):
    def __init__(self):
        self.digit = Signal(4)
        self.segments = Signal(7)

    def elaborate(self, _platform):
        m = Module()

        with m.Switch(self.digit):
            for n, seg_val in enumerate([
                    0b0111111,
                    0b0000110,
                    0b1011011,
                    0b1001111,
                    0b1100110,
                    0b1101101,
                    0b1111101,
                    0b0000111,
                    0b1111111,
                    0b1101111,
                    0b1110111,
                    0b1111100,
                    0b0111001,
                    0b1011110,
                    0b1111001,
                    0b1110001]):
                with m.Case(n):
                    m.d.sync += self.segments.eq(seg_val)

        return m


if __name__ == "__main__":
    platform = ICEBreakerPlatform()
    platform.add_resources(seven_seg_pmod)

    platform.build(Top(), do_program=True)