Close

Getting to Blinky, MyHDL Style!

A project log for CAT Board

The CAT Board is part of a Raspberry Pi-based hand-held FPGA programming system.

Dave VandenboutDave Vandenbout 05/09/2016 at 23:342 Comments

In my previous post, I showed how to blink an LED on the CAT Board using Verilog. Now I'll do the same thing using MyHDL, a hardware description language based on Python.

I'll assume a starting point of a Raspberry Pi running the Raspbian OS with the yosys, arachne-pnr and icestorm FPGA tools installed. If you're following along and haven't already got that, read the previous post. The stuff I describe here won't work without it.

Install MyHDL

Before you can use MyHDL, you have to install it. Installing the latest release is as simple as:

sudo pip install myhdl

But I like to use the development version because that's where all the new features are. That's installed like this:

cd /opt
sudo git clone https://github.com/jandecaluwe/myhdl.git
cd myhdl
sudo python setup.py install

Blinky in MyHDL

Blinking an LED with Verilog wasn't hard, and doing it in MyHDL isn't either. Here's the source code that's stored in a Python file called blinky.py.

from myhdl import *

# Define the Blinky module.
@block
def blinky(clk_i, led_o):

    cnt = Signal(intbv(0, 0, 50000000)) # Counter from 0 to 49999999.
    tgl = Signal(bool(0)) # Toggle flag drives the LED.

    # Sequential block triggered on every rising edge of the clock.
    @always_seq(clk_i.posedge, reset=None)
    def toggle_led():
        if cnt == cnt.max-1: # When the counter reaches its max value...
            tgl.next = ~tgl  # Toggle the flag...
            led_o.next = tgl # Output the flag to the LED...
            cnt.next = 0     # Reset the counter.
        else: # Counter hasn't reached max so just keep incrementing.
            cnt.next = cnt + 1

    # Return a reference to the Blinky logic.
    return toggle_led

# Define the connections to Blinky.
clk_i = Signal(bool(0))
led_o = Signal(bool(0))

# Create an instantiation of Blinky.
top = blinky(clk_i, led_o)

# Output Verilog code for Blinky.
top.convert(hdl='Verilog')

Compiling to Blinky

The blinky.py file containing the MyHDL code shown above is executed as follows:

python blinky.py

This translates the MyHDL code into Verilog that's stored in the blinky.v file. Then this Verilog file can be compiled into a bitstream using the yosys, arachne-pnr and icepack tools just like in the previous post. Once the bitstream is downloaded to the CAT Board, the LED will blink.

Raison de'Etre

Why bother doing this in MyHDL? It just adds another step, but does it add any value?

In this case, no, it doesn't. Because this design is so simple, the MyHDL code isn't any more compact or expressive than the original Verilog. The value of MyHDL is experienced when doing design exploration, i.e. trying various approaches to solving a problem. Then all the features of the Python ecosystem can be used with MyHDL to come up with a solution. I showed a few examples of this here and here.

Discussions

Steven Ourada wrote 05/11/2016 at 04:42 point

Very nice. FYI, for those playing along on an iCEstick, you can use clk_i=21 and led_o=99.

  Are you sure? yes | no

Dave Vandenbout wrote 05/11/2016 at 05:05 point

Thanks! I've still got that iCEStick I bought when I couldn't get the first CAT Board working. Original packaging. Never opened if someone wants to buy it!

  Are you sure? yes | no