<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Note
Step1:  After importing, set up the module to get it ready for what comes next
Step2:  Next, the logic that blinks the LED is defined
(don't worry, I'll step you through it!)
Step3:  The blinker logic is encapsulated in a Python function that's preceded with the @chunk decorator.
This decorator takes care of PygMyHDL's housekeeping chores and should be used on any function
that defines digital hardware.
The blinker function accepts two types of parameters
Step4:  Finally, the blinker logic is instantiated by calling the blinker function
with the clk and led signals passed as arguments for its I/O ports
Step5:  While it's not done here, it's possible to call the blinker function several times using
different output signals to create multiple, independent LED blinkers.
<a name="Simulating"></a>Simulating the Blinker
Now that the LED blinker has been designed, it's time to see if it works.
As a test, you can run a simple simulation that just toggles the clock input
a number of times using the clk_sim utility
Step6:  After the simulation completes, a graphical view of the waveforms for each of the named signals is generated
using the show_waveforms utility of the MyHDLPeek package
Step7:  You can also view the signal values in a tabular format
Step8:  Looking at the waveforms, you can see the led output pulses low-high one time for every eight pulses
of the clk input.
In general, for an $N$-bit counter, the led signal will pulse at ${1}\textrm{ / }{2^N}$ the frequency of the clk signal.
<a name="Compiling"></a>Compiling into a Bitstream
Since the simulation shows the blinker is working, it's time to compile [3] the MyHDL code into a bitstream for an FPGA.
The FPGA used in this tutorial is the
Lattice Semiconductor iCE40HX1K
that is housed on the
iCEstick evaluation board
Step9:  The toVerilog function creates a file called blinker.v
containing the following Verilog code
Step10:  So now you're ready to compile the Verilog code and program your first FPGA, right?
Well, almost, but there's one more detail to handle.
The clock oscillator and LEDs on the iCEstick are hooked to specific pins of the physical FPGA chip
as follows
Step11:  Now you really are ready to program the FPGA.
The first step [4] is to synthesize the Verilog code into an intermediate form
using Yosys
Step12:  The options modify the operation of Yosys as follows
Step13:  The options specify the following place-and-route operations
Step14:  <a name="Downloading"></a>Downloading to the FPGA
At long last, you are ready to program the actual FPGA chip!
First, plug the iCEstick into a USB port on your computer [5].
Then issue the following command that will pass the blinker.bin binary bitstream
through the USB port and into the FPGA on the iCEstick
Step15:  After the download completes, the blinker logic starts to run inside the FPGA,
converting the 12 MHz clock into a 3 Hz blinking of the LED.
Looks like that's about 3 Hz to me!
<a name="No_Jupyter"></a>But I Don't Like Jupyter!
OK, maybe you're one of those guys, so here's how to do it all from the command line.
First, create a file called blinker.py using your favorite text editor (which is probably vi or Emacs, I guess).
The file just contains the same MyHDL code I showed above.
Here's my version of it
Step16:  Then, just execute the file with Python
Step17:  At this point, you will have the blinker.v Verilog file and the blinker.pcf file with the pin assignments.
Then it's just a matter of running the same icestorm commands as I showed above
<ASSISTANT_TASK:>
Python Code:
from pygmyhdl import *
Explanation: Note: If you're reading this as a static HTML page, you can also get it as an
executable Jupyter notebook here.
The Fastest, Easiest FPGA Blinker, Ever!
Everyone who wants to get started with FPGAs [1] has two thoughts:
"I don't know how to program an FPGA."
"FPGA programming tools are large and complicated."
FPGAs are typically programmed using hardware description languages (HDLs) like VHDL and Verilog.
Someday you might need to learn these languages, but not today!
This tutorial uses MyHDL - a simple HDL based on the Python programming language.
Not only is MyHDL easier to learn, you can also design, simulate and program an FPGA without leaving the
Jupyter notebook in your browser.
Programming tools from the big FPGA vendors are multi-gigabyte packages with convoluted interfaces between
subprograms that perform mysterious functions.
Someday you might need to learn these tools, but not today!
This tutorial uses APIO and the
icestorm programming tools for the
iCE40 FPGA family from Lattice Semiconductor.
These FOSS tools take up less than 200 MB and consist of command-line programs with simple options,
most of which you'll never have to use.
With these tools and this notebook, you will go from knowing nothing [2] to creating an LED blinker
with an FPGA in less than twenty minutes. The rest of this notebook will step you through:
Setting up your FPGA programming environment.
Writing a MyHDL program for a logic circuit that blinks an LED.
Simulating the program to check the operation of the blinker.
Compiling the program into a bitstream that can be loaded into the FPGA.
Downloading the bitstream into the FPGA.
<a name="Setup"></a>Setting Up Your FPGA Programming Environment
In order to use the FPGA tools, you'll need some type of computer with Python installed.
It can be any kind of computer - linux box, Raspberry Pi (RPi), Windows PC - it doesn't really matter.
For linux computers or the RPi, Python should already be installed.
For Windows, not so much so you can
follow these instructions to load Python.
Now you should have a utility called pip that helps you install other Python modules.
APIO is one such module, so install it with the command:
pip install apio
APIO manages installing and running the FPGA tools you'll need.
The easiest way to install the tools is with this command:
apio install -a
This command loads all the FPGA tools even though you really only need icestorm for this tutorial.
The next module you need is PygMyHDL:
pip install pygmyhdl
This installs MyHDL and a wrapper that makes it slightly easier to use.
It also loads some utilities for monitoring and displaying
logic signals as waveforms or tables during simulations.
Finally, you can install the Jupyter package that lets you do all your FPGA development
in a browser tab:
pip install jupyter
(If you don't want to use Jupyter, I'll show you later how to do everything from the command line.)
If you already had Python installed, then setting up the rest of these tools should have taken less than five minutes.
You can't even download the multi-gigabyte installer for a vendor-supplied FPGA tool in that amount of time.
<a name="Coding"></a>The MyHDL Blinker Program
The LED blinker is the hardware equivalent of the "Hello, World" program: it takes a clock signal
as input and outputs a signal that turns an LED on and off.
I'll show the design of a blinker using MyHDL in this Jupyter notebook, but you could
also place this code into a file and execute it with Python.
The first thing you have to do is import the PygMyHDL module so you can use the features
of MyHDL and the wrapper functions:
End of explanation
initialize()
Explanation: After importing, set up the module to get it ready for what comes next:
End of explanation
# The following function will define a chunk of logic, hence the @chunk decorator precedes it.
# The blinker logic takes three inputs:
#   clk_i:  This is a clock signal input.
#   led_o:  This is an output signal that drives an LED on and off.
#   length: This is the number of bits in the counter that generates the led_o output.
@chunk
def blinker(clk_i, led_o, length):
    
    # Define a multi-bit signal (or bus) with length bits.
    # Assign it a display name of 'cnt' for use during simulation.
    cnt = Bus(length, name='cnt')
    
    # Define a piece of sequential logic. Every time there is a positive
    # edge on the clock input (i.e., it goes from 0 -> 1), the value of
    # cnt is increased by 1. So over a sequence of clock pulses, the
    # cnt value will progress 0, 1, 2, 3, ...
    @seq_logic(clk_i.posedge)
    def counter_logic():
        cnt.next = cnt + 1
    # This is a piece of simple combinational logic. It just connects the
    # most significant bit (MSB) of the counter to the LED output.
    @comb_logic
    def output_logic():
        led_o.next = cnt[length-1]
Explanation: Next, the logic that blinks the LED is defined
(don't worry, I'll step you through it!):
End of explanation
clk = Wire(name='clk')  # This is a single-bit signal that carries the clock input.
led = Wire(name='led')  # This is another single-bit signal that receives the LED output.
Explanation: The blinker logic is encapsulated in a Python function that's preceded with the @chunk decorator.
This decorator takes care of PygMyHDL's housekeeping chores and should be used on any function
that defines digital hardware.
The blinker function accepts two types of parameters: 1) normal Python objects like length,
and 2) signals such as clk_i and led_o
that convey single or multi-bit digital logic values in or out of the function.
Another signal, cnt, is declared as the first statement in blinker.
This is a multi-bit signal that holds the value of a binary counter.
The number of bits in the counter is determined by the value of the length parameter.
For example, if length is three, then the counter will have three bits with
bit indices of 0, 1 and 2 (which is the most significant bit or MSB).
The next portion of blinker defines the actual function of the counter.
The @seq_logic decorator denotes that the following function
describes some sequential logic.
The argument to the decorator, clk_i.posedge, indicates that the function
will only be executed when the clk_i signal makes a transition from a logic 0
to a logic 1 level.
The function after the decorator, counter_logic, defines the operation of the counter:
the next value in the cnt signal becomes the current value plus 1.
So as a sequence of rising edges on clk_i is received, the value of cnt will
increase.
Once cnt reaches its maximum value (which would be 111=7 for a three-bit counter),
it rolls over and goes back to zero whereupon it continues counting upward.
Following the counter logic is some combinational logic
denoted by the @comb_logic decorator.
The output_logic function just drives the next value of the led_o output with the binary value found
in the MSB of the counter (as indicated by using the bit index length-1).
The net result is that the led_o output will transition from logic 0 to 1
like the input clock, but at a much slower rate.
(You'll see this when you simulate the operation of the blinker.)
After the blinker logic function is defined, a couple of signals are needed to connect it to a clock signal and an LED:
End of explanation
blinker(clk_i=clk, led_o=led, length=3);  # Attach the clock and LED signals to a 3-bit blinker circuit.
Explanation: Finally, the blinker logic is instantiated by calling the blinker function
with the clk and led signals passed as arguments for its I/O ports:
End of explanation
clk_sim(clk, num_cycles=16)  # Pulse the clock input 16 times.
Explanation: While it's not done here, it's possible to call the blinker function several times using
different output signals to create multiple, independent LED blinkers.
<a name="Simulating"></a>Simulating the Blinker
Now that the LED blinker has been designed, it's time to see if it works.
As a test, you can run a simple simulation that just toggles the clock input
a number of times using the clk_sim utility:
End of explanation
show_waveforms()
Explanation: After the simulation completes, a graphical view of the waveforms for each of the named signals is generated
using the show_waveforms utility of the MyHDLPeek package:
End of explanation
show_text_table()
Explanation: You can also view the signal values in a tabular format:
End of explanation
toVerilog(blinker, clk_i=clk, led_o=led, length=22) # Give it the function name, signal connections, and counter size.
Explanation: Looking at the waveforms, you can see the led output pulses low-high one time for every eight pulses
of the clk input.
In general, for an $N$-bit counter, the led signal will pulse at ${1}\textrm{ / }{2^N}$ the frequency of the clk signal.
<a name="Compiling"></a>Compiling into a Bitstream
Since the simulation shows the blinker is working, it's time to compile [3] the MyHDL code into a bitstream for an FPGA.
The FPGA used in this tutorial is the
Lattice Semiconductor iCE40HX1K
that is housed on the
iCEstick evaluation board:
In addition to the FPGA, the iCEstick also includes a 12 MHz clock oscillator and five LEDs
so it's perfect for the LED blinker.
Well, almost.
Since the clock is 12 MHz, dividing it by eight will cause the LED to turn on and off at a 1.5 MHz rate.
Unless you're Superman, your eyes won't notice much of anything over 30 Hz.
The counter in the blinker is going to need more bits to get the LED blink rate down to something less than 5 Hz.
If you make the counter length 22 bits, then the blink rate is reduced to 
$12,000,000 \textrm{ Hz / } 2^{22} = 2.9 \textrm{ Hz}$, or about three times per second.
Even I can see that.
After adjusting the counter size, the blinker code has to be synthesized into an intermediate form
which is then placed-and-routed into a particular FPGA.
This is done using the Yosys synthesizer and
Arachne-pnr, respectively, that are included in the icestorm tools.
But Yosys works with the Verilog HDL and you're using MyHDL!
Therefore, you'll have to use one of MyHDL's conversion functions to generate
a Verilog version of the blinker code:
End of explanation
print(open('blinker.v').read())
Explanation: The toVerilog function creates a file called blinker.v
containing the following Verilog code:
End of explanation
with open('blinker.pcf', 'w') as pcf:
    pcf.write(
'''
set_io led_o 99
set_io clk_i 21
'''
    )
Explanation: So now you're ready to compile the Verilog code and program your first FPGA, right?
Well, almost, but there's one more detail to handle.
The clock oscillator and LEDs on the iCEstick are hooked to specific pins of the physical FPGA chip
as follows:
| iCEstick Function &nbsp;&nbsp;&nbsp;&nbsp; | FPGA Pin |
|:------------------|:--------:|
| 12 MHz clock osc. | 21       |
| LED D1            | 99       |
| LED D2            | 98       |
| LED D3            | 97       |
| LED D4            | 96       |
| LED D5            | 95       |
You need to tell the icestorm tools which pins the signals for the blinker are attached to.
This is done with a pin constraints file (PCF) that associates each signal name
in the parameter list of the blinker function with a pin of the FPGA.
You can create the PCF using a text editor, or use Python like this:
End of explanation
!yosys -q -p "synth_ice40 -blif blinker.blif" blinker.v
Explanation: Now you really are ready to program the FPGA.
The first step [4] is to synthesize the Verilog code into an intermediate form
using Yosys:
End of explanation
!arachne-pnr -q -d 1k -p blinker.pcf blinker.blif -o blinker.asc
Explanation: The options modify the operation of Yosys as follows:
| Option             | Effect   |
|:-------------------|:---------|
| -q               | Execute in quiet mode so you're not bombarded with so many progress messages.|
| -p "synth_ice40 -blif blinker.blif" | Synthesize for the iCE40 family of FPGAs and output the intermediate code to the file blinker.blif.|
The blinker.blif file with the synthesized intermediate code is then placed-and-routed
with the Arachne-pnr utility:
End of explanation
!icepack blinker.asc blinker.bin
Explanation: The options specify the following place-and-route operations:
| Option            | Effect   |
|:------------------|:---------|
| -q              | Execute in quiet mode.|
| -d 1k"          | Specifically target the iCE40HX1K FPGA.|
| -p blinker.pcf  | Look for pin assignments in blinker.pcf.|
| -o blinker.asc  | Output the bitstream to blinker.asc.|
The output of Arachne-pnr is a bitstream of 1's and 0's that specifies how the logic
cells in the FPGA are connected through internal switches to implement the blinker logic.
The bitstream uses ASCII characters to represent the bits, so another utility is used to
convert it into a binary file:
End of explanation
!iceprog blinker.bin
Explanation: <a name="Downloading"></a>Downloading to the FPGA
At long last, you are ready to program the actual FPGA chip!
First, plug the iCEstick into a USB port on your computer [5].
Then issue the following command that will pass the blinker.bin binary bitstream
through the USB port and into the FPGA on the iCEstick:
End of explanation
print(open('blinker.py').read())
Explanation: After the download completes, the blinker logic starts to run inside the FPGA,
converting the 12 MHz clock into a 3 Hz blinking of the LED.
Looks like that's about 3 Hz to me!
<a name="No_Jupyter"></a>But I Don't Like Jupyter!
OK, maybe you're one of those guys, so here's how to do it all from the command line.
First, create a file called blinker.py using your favorite text editor (which is probably vi or Emacs, I guess).
The file just contains the same MyHDL code I showed above.
Here's my version of it:
End of explanation
!python blinker.py
Explanation: Then, just execute the file with Python:
End of explanation
!yosys -q -p "synth_ice40 -blif blinker.blif" blinker.v
!arachne-pnr -q -d 1k -p blinker.pcf blinker.blif -o blinker.asc
!icepack blinker.asc blinker.bin
!iceprog blinker.bin
Explanation: At this point, you will have the blinker.v Verilog file and the blinker.pcf file with the pin assignments.
Then it's just a matter of running the same icestorm commands as I showed above:
End of explanation
<END_TASK>