Computer Architecture Lab/FPGA Hello World Example

From Wikiversity
Jump to navigation Jump to search

When one starts to use a new language or environment the first program written is usually the famous 'Hello World' example. What is the 'Hello World' program in hardware, in an FPGA? The smallest project that produces dynamic output is a blinking LED. We will show the steps for a blinking LED example using Altera/Intel's Quartus and an FPGA board.

Design Flow[edit | edit source]

All your design files (VHDL and/or Verilog files) make up a project in Quartus. A Quartus II project is defined in Quartus II with just three files: projectname.qpf, projectname.qsf, and projectname.cdf (Close your Quartus II project before editing the files).

Create a New Project[edit | edit source]

Start Quartus II and create a new project with:

  1. File -- New Project Wizard...
  2. Select a project directory and select a project name. The project name is usually the name of the top-level design entity. In our case hello_world (make sure to name the project this exactly, or you will have compilation problems).
  3. In the next dialog box the VHDL source files can be added to the project. As we have no VHDL files at the moment we will skip this step
  4. We have to select the target device. Choose the right family and device depending on your board.
  5. We leave the EDA tools settings blank
  6. Press Finish at the summary window

Device and Pin Options[edit | edit source]

At the default setting the unused pins drive ground. As the default settings in Quartus II for a device are dangerous we specify more details for our target device:

  1. Assignments -- Device to open the device properties
  2. Press the button Device & Pin Options...
  3. Important! At the tab Unused Pins select As input tri-stated.
  4. The LVCMOS, selected in tab Voltage, is the better IO standard to interface e.g. SRAM devices
  5. Close the dialog box and the next with OK

Hello World in Chisel[edit | edit source]

To get started with Chisel there is a Hello World example in Chisel available at: Chisel Hello World

The following code shows the Hello World hardware in Chisel.

import Chisel._

/**
 * The blinking LED component.
 */

class Hello extends Module {
  val io = new Bundle {
    val led = UInt(OUTPUT, 1)
  }
  val CNT_MAX = UInt(50000000 / 2 - 1);

  val cntReg = Reg(init = UInt(0, 32))
  val blkReg = Reg(init = UInt(0, 1))

  cntReg := cntReg + UInt(1)
  when(cntReg === CNT_MAX) {
    cntReg := UInt(0)
    blkReg := ~blkReg
  }
  io.led := blkReg
}

/**
 * An object containing a main() to invoke chiselMain()
 * to generate the Verilog code.
 */
object Hello {
  def main(args: Array[String]): Unit = {
    chiselMain(Array("--backend", "v"), () => Module(new Hello()))
  }
}

Compile and generate the Verilog hardware description with a simple

   make

For FPGA synthesize you can either use your project you setup before or the Quartus project that is part of the Chisel hello world repository.

The Hello World VHDL Example[edit | edit source]

Add a VHDL file to the project with File -- New... and select VHDL File. Enter the following code and save the file with filename hello_world.

    --
    --  hello_world.vhd
    --
    --  The 'Hello World' example for FPGA programming.
    --
    --  Author: Martin Schoeberl (martin@jopdesign.com)
    --
    --  2006-08-04  created
    --

    library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;

    entity hello_world is

    port (
        clk     : in std_logic;
        led     : out std_logic
    );
    end hello_world;

    architecture rtl of hello_world is

        constant CLK_FREQ : integer := 20000000;
        constant BLINK_FREQ : integer := 1;
        constant CNT_MAX : integer := CLK_FREQ/BLINK_FREQ/2-1;

        signal cnt      : unsigned(24 downto 0);
        signal blink    : std_logic;

    begin

        process(clk)
        begin

            if rising_edge(clk) then
                if cnt=CNT_MAX then
                    cnt <= (others => '0');
                    blink <= not blink;
                else
                    cnt <= cnt + 1;
                end if;
            end if;

        end process;

        led <= blink;

    end rtl;

The not yet famous VHDL 'Hello World' example

Compiling and Pin Assignment[edit | edit source]

The analysis, synthesize, map, and place & route processes are all started with Processing -- Start Compilation. The compiler did not know that our PCB is already done, so the compiler assigned any pin numbers for the inputs and outputs.

If Full Compilation fails you may try to manually correct the toplevel entity.

However, the pin numbers are fixed for the board. We have to assign the pin numbers for our two ports clk and led. Open the pin assignment window with Assignments -- Pins. Our two ports are already listed in the All Pins window. Double click the field under Location and select the pin number. Enter following assignments:

   clk  look up in board docu
   led  look up in board docu

With the correct pin assignment restart the compilation with Processing -- Start Compilation (or use the play button) and check the correct assignment in the compilation report under Fitter -- Pin-Out-File. The clk pin should be located at nn and led at mm; all unused pins should be listed as RESERVED_INPUT.

FPGA Configuration[edit | edit source]

Downloading your hardware project into the FPGA is called configuration. There are several ways an FPGA can be configured. Here we describe configuration via JTAG.

UsbBlaster[edit | edit source]

This section describes configuration via UsbBlaster connected to the printer port.

  1. Connect your UsbBlaster to the PC and FPGA board
  2. Start the programmer with Tools -- Programmer
  3. Press the button Auto Detect and the programmer window should list the correct device.
  4. Double click for the filename of the FPGA device and select hello_world.sof.
  5. Select the checkbox under Program/Configure for the FPGA and press the Start button to configure the FPGA

The LED should now blink!

Further Experiments[edit | edit source]

Play with the code and do following changes:

  • Change the blinking frequency.
  • Have the on shorter than the off time of the LED.

Further Information[edit | edit source]

Tips[edit | edit source]

  • The Chisel or VHDL source files and the project files do not have to be in the same directory. Keeping them in separate directories is a better organization and simplifies reuse
  • Use relative paths wherever possible to enable project sharing
  • In general choose the entity name as filename. However, with different files (and names) for different versions of an entity a project can be easily configured just with different Quartus II projects

Quartus File Types[edit | edit source]

The most important file types used by Quartus:

.qpf
Quartus II Project File. Contains almost no information.
.qsf
Quartus II Settings File defines the project. VHDL files that make up your project are listed. Constraints such as pin assignments and timing constraints set here.
.cdf
Chain Description File. This file stores device name, device order, and programming file name information for the programmer.
.tcl
Tool Command Language. Can be used in Quartus to automate parts of the design flow (e.g. pin assignment).
.sof
SRAM Output File. Configuration for Altera devices. Used by the Quartus programmer or by quartus_pgm. Can be converted to various (or too many) different format. Some are listed below.

Links[edit | edit source]