In [1]:
import magma as m
m.set_mantle_target("ice40")
As before, we can use a native Python function to organize the definition of our TFF into a reusable component.
In [2]:
from mantle import DFF
class TFF(m.Circuit):
IO = ['O', m.Out(m.Bit)] + m.ClockInterface()
@classmethod
def definition(io):
# instance a dff to hold the state of the toggle flip-flop - this needs to be done first
dff = DFF()
# compute the next state as the not of the old state ff.O
io.O <= dff(~dff.O)
def tff():
return TFF()()
Then we simply call this function inside our definition of the IceStick main.
In [3]:
from loam.boards.icestick import IceStick
icestick = IceStick()
icestick.Clock.on()
icestick.J3[0].rename('J3').output().on()
main = icestick.DefineMain()
main.J3 <= tff()
m.EndDefine()
We'll compile and build our program using the standard flow.
In [4]:
m.compile("build/tff", main)
In [5]:
%%bash
cd build
yosys -q -p 'synth_ice40 -top main -blif tff.blif' tff.v
arachne-pnr -q -d 1k -o tff.txt -p tff.pcf tff.blif
icepack tff.txt tff.bin
#iceprog tff.bin
Let's inspect the generated verilog.
In [6]:
%cat build/tff.v
We can verify our implementation is function correctly by using a logic analyzer.
In [7]:
%cat build/tff.pcf