<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Getting Started
Magma is a hardware construction language written in Python 3. The central abstraction in Magma is a Circuit, which is analagous to a verilog module. A circuit is a set of functional units that are wired together.
Magma is designed to work with Mantle, a library of hardware building blocks including logic and arithmetic units, registers, memories, etc. 
The Loam system builds upon the Magma Circuit abstraction to represent parts and boards. A board consists of a set of parts that are wired together. Loam makes it is easy to setup a board such as the Lattice IceStick.
Lattice IceStick
In this tutorial, we will be using the Lattice IceStick.
This breakout board contains a ICE40HX FPGA with 1K 4-input LUTs. 
The board has several useful peripherals including an FTDI USB interface 
with an integrated JTAG interface which is used to program the FPGA
and a USART which is used to communicate with the host.
The board also contains 5 LEDs, 
a PMOD interface, 
and 2 10-pin headers (J1 and J3). 
The 10-pin headers bring out 8 GPIO pins, 
as well as power and ground.
This board is inexpensive ($25), can be plugged into the USB port on your laptop,
and, best of all, can be
programmed using an open source software toolchain.
Additional information about the IceStick Board can be found in the 
IceStick Programmers Guide
Blink
As a first example,
let's write a Magma program that blinks an LED on the Icestick Board.
First, we import Magma as the module m.
Next, we import Counter from Mantle.
Before doing the import we configure mantle to use the ICE40 as the target device.
Step1:  The next step is to setup the IceStick board. We import the class IceStick from Loam. 
We then create an instance of an IceStick.
This board instance has member variables 
that store the configuration of all the parts on the board.
The blink program will use the Clock and the LED D5. 
Turning on the Clock and the LED D5 sets up the build environment 
to use the associated ICE40 GPIO pins.
Step2:  Now that the IceStick setup is done, 
we create a main program that runs on the Lattice ICE40 FPGA. 
This main program becomes the top level module.
We create a simple circuit inside main. 
The circuit has a a 22-bit counter wired to D5. 
The crystal connected to the ICE40 has a frequency of 12 Mhz. 
so the counter will increment at that rate.
Wiring the most-significant bit of the counter to D5
will cause the LED to blink roughly 3 times per second.
D5 is accessible via main.
In a similar way, the output of the counter is accesible via counter.O,
and since this an array of bits we can access the MSB using Python's standard list indexing syntax.
Step3:  We then compile the program to verilog. This step also creates a PCF (physical constraints file).
Step4:  Now we run the open source tools for the Lattice ICE40. 
yosys synthesizes the input verilog file (blink.v) 
to produce an output netlist (blink.blif).
arachne-pnr runs the place and router and generates the bitstream as a text file.
icepack creates a binary bitstream file that can be downloaded to the FPGA. iceprog uploads the bitstream to the device. Once the device has been programmed, you should see the center, green LED blinking.
Step5:  You can view the verilog file generated by Magma.
Step6:  Notice that the top-level module contains two arguments (ports),
D5 and CLKIN. 
D5 has been configured as an output,
and CLKIN as an input.
The mapping from these named arguments to pins is contained in the
PCF (physical constraint file).
<ASSISTANT_TASK:>
Python Code:
import magma as m
m.set_mantle_target("ice40")
Explanation: Getting Started
Magma is a hardware construction language written in Python 3. The central abstraction in Magma is a Circuit, which is analagous to a verilog module. A circuit is a set of functional units that are wired together.
Magma is designed to work with Mantle, a library of hardware building blocks including logic and arithmetic units, registers, memories, etc. 
The Loam system builds upon the Magma Circuit abstraction to represent parts and boards. A board consists of a set of parts that are wired together. Loam makes it is easy to setup a board such as the Lattice IceStick.
Lattice IceStick
In this tutorial, we will be using the Lattice IceStick.
This breakout board contains a ICE40HX FPGA with 1K 4-input LUTs. 
The board has several useful peripherals including an FTDI USB interface 
with an integrated JTAG interface which is used to program the FPGA
and a USART which is used to communicate with the host.
The board also contains 5 LEDs, 
a PMOD interface, 
and 2 10-pin headers (J1 and J3). 
The 10-pin headers bring out 8 GPIO pins, 
as well as power and ground.
This board is inexpensive ($25), can be plugged into the USB port on your laptop,
and, best of all, can be
programmed using an open source software toolchain.
Additional information about the IceStick Board can be found in the 
IceStick Programmers Guide
Blink
As a first example,
let's write a Magma program that blinks an LED on the Icestick Board.
First, we import Magma as the module m.
Next, we import Counter from Mantle.
Before doing the import we configure mantle to use the ICE40 as the target device.
End of explanation
from loam.boards.icestick import IceStick
# Create an instance of an IceStick board
icestick = IceStick()
# Turn on the Clock 
# The clock must turned on because we are using a synchronous counter
icestick.Clock.on()
# Turn on the LED D5
icestick.D5.on();
Explanation: The next step is to setup the IceStick board. We import the class IceStick from Loam. 
We then create an instance of an IceStick.
This board instance has member variables 
that store the configuration of all the parts on the board.
The blink program will use the Clock and the LED D5. 
Turning on the Clock and the LED D5 sets up the build environment 
to use the associated ICE40 GPIO pins.
End of explanation
from mantle import Counter
N = 22
# Define the main Magma Circuit on the FPGA on the IceStick
main = icestick.DefineMain()
# Instance a 22-bit counter
counter = Counter(N)
# Wire bit 21 of the counter's output to D5.
main.D5 <= counter.O[N-1]
# End main
m.EndDefine()
Explanation: Now that the IceStick setup is done, 
we create a main program that runs on the Lattice ICE40 FPGA. 
This main program becomes the top level module.
We create a simple circuit inside main. 
The circuit has a a 22-bit counter wired to D5. 
The crystal connected to the ICE40 has a frequency of 12 Mhz. 
so the counter will increment at that rate.
Wiring the most-significant bit of the counter to D5
will cause the LED to blink roughly 3 times per second.
D5 is accessible via main.
In a similar way, the output of the counter is accesible via counter.O,
and since this an array of bits we can access the MSB using Python's standard list indexing syntax.
End of explanation
m.compile('build/blink', main)
Explanation: We then compile the program to verilog. This step also creates a PCF (physical constraints file).
End of explanation
%%bash
cd build
yosys -q -p 'synth_ice40 -top main -blif blink.blif' blink.v
arachne-pnr -q -d 1k -o blink.txt -p blink.pcf blink.blif 
icepack blink.txt blink.bin
#iceprog blink.bin
Explanation: Now we run the open source tools for the Lattice ICE40. 
yosys synthesizes the input verilog file (blink.v) 
to produce an output netlist (blink.blif).
arachne-pnr runs the place and router and generates the bitstream as a text file.
icepack creates a binary bitstream file that can be downloaded to the FPGA. iceprog uploads the bitstream to the device. Once the device has been programmed, you should see the center, green LED blinking.
End of explanation
%cat build/blink.v
Explanation: You can view the verilog file generated by Magma.
End of explanation
%cat build/blink.pcf
Explanation: Notice that the top-level module contains two arguments (ports),
D5 and CLKIN. 
D5 has been configured as an output,
and CLKIN as an input.
The mapping from these named arguments to pins is contained in the
PCF (physical constraint file).
End of explanation
<END_TASK>