Toggle Flip-Flop

In this example we create a toggle flip-flop (TFF) from a d-flip-flop (DFF) and an xor gate. In Magma, finite state machines can be constructed by composing combinational logic with register primitives, such as a DFF or Register.


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()()


import lattice ice40
import lattice mantle40
magma:ERROR:Input port SB_DFF_inst0.C not driven

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


/Users/hanrahan/git/magmathon/notebooks/tutorial/icestick/build

Let's inspect the generated verilog.


In [6]:
%cat build/tff.v


module TFF (output  O, input  CLK);
wire  SB_DFF_inst0_Q;
wire  SB_LUT4_inst0_O;
SB_DFF SB_DFF_inst0 (.C(CLK), .D(SB_LUT4_inst0_O), .Q(SB_DFF_inst0_Q));
SB_LUT4 #(.LUT_INIT(16'h5555)) SB_LUT4_inst0 (.I0(SB_DFF_inst0_Q), .I1(1'b0), .I2(1'b0), .I3(1'b0), .O(SB_LUT4_inst0_O));
assign O = SB_DFF_inst0_Q;
endmodule

module main (output  J3, input  CLKIN);
wire  TFF_inst0_O;
TFF TFF_inst0 (.O(TFF_inst0_O), .CLK(CLKIN));
assign J3 = TFF_inst0_O;
endmodule

We can verify our implementation is function correctly by using a logic analyzer.


In [7]:
%cat build/tff.pcf


set_io J3 62
set_io CLKIN 21