from amaranth.build import Platform
from amaranth import *

from debouncer import Debouncer

class ToggleButton(Elaboratable):

    def __init__(self):
        #signals
        self.i = Signal()
        self.o = Signal()

        #state
        self.last_seen = Signal()

    def elaborate(self, platform: Platform):
        m = Module()

        debouncer = Debouncer(10000)

        m.submodules += debouncer

        m.d.comb += debouncer.i.eq(self.i)

        with m.If((debouncer.o != self.last_seen) & (debouncer.o == 1)):
            m.d.sync += self.o.eq(~self.o)

        m.d.sync += self.last_seen.eq(debouncer.o)

        return m


from amaranth.sim import Simulator, Period

dut = ToggleButton()

async def testbench(ctx):
    await ctx.tick().repeat(2)
    ctx.set(dut.i, True)
    await ctx.tick().repeat(5)
    ctx.set(dut.i, False)
    await ctx.tick().repeat(5)
    ctx.set(dut.i, True)
    await ctx.tick().repeat(5)
    ctx.set(dut.i, False)

sim = Simulator(dut)
sim.add_clock(Period(MHz=1))
sim.add_testbench(testbench)
with sim.write_vcd("ToggleButton.vcd"):
    sim.run_until(Period(MHz=1) * 25)