# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: light
#       format_version: '1.5'
#       jupytext_version: 1.14.4
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# ## Counter

import magma as m
m.set_mantle_target("ice40")

# ## Counter Circuit

# To implement a counter we can use the `Register` primitive and the `+` operator. 

# +
from mantle import Register

class SimpleCounter4(m.Circuit):
    IO = ["O", m.Out(m.UInt[4])] + m.ClockInterface()
    @classmethod
    def definition(io):
        reg4 = Register(4, _type=m.UInt)
        io.O <= reg4(reg4.O + 1)


# -

# The above example shows how to create a circuit by subclassing `Circuit`.
# Another way to construct a circuit is using a function that builds the circuit.

def SimpleCounter4():
    _SimpleCounter4 = DefineCircuit('SimpleCounter4', "O", m.Out(m.UInt[4]), *m.ClockInterface())
    reg4 = Register(4)
    _SimpleCounter4.O <= reg4(reg4.O + 1)
    EndCircuit()
    return _SimpleCounter4


# ## Counter Circuit Generator
#
# The above example creates a counter of fixed size 4. How can we make a more general counter of arbitray width?

# +
def DefineCounter(n):
    class _Counter(m.Circuit):
        name = f'Counter{n}'
        IO = ["O", m.Out(m.UInt[n])] + m.ClockInterface()
        @classmethod
        def definition(io):
            reg = Register(n, type=m.UInt)
            io.O <= reg(reg.O) + 1)
    return _Counter

def Counter(n):
    return DefineCounter(n)()


# -

# The definition of the generated `n`-bit counter can use the `n` parameter that is captured in the closure environment.

# ## Test bench

# +
from loam.boards.icestick import IceStick

N = 30

icestick = IceStick()
icestick.Clock.on()
for i in range(8):
    icestick.J3[i].output().on()
    
main = icestick.DefineMain()

counter = Counter(N)
main.J3 <= counter()[N-8:N]

m.EndDefine()
# -

# We can compile and inspect the verilog.

m.compile("build/counter", main)

# + language="bash"
# cd build
# yosys -q -p 'synth_ice40 -top main -blif counter.blif' counter.v
# arachne-pnr -q -d 1k -o counter.txt -p counter.pcf counter.blif 
# icepack counter.txt counter.bin
# #iceprog counter.bin
# -

# %cat build/counter.v

StarcoderdataJupyterScriptsDedupFiltered