Designing our own Nios II system

2012-04-05Publicerad av Sven-Åke Andersson


After implementing a pre-built system we are now ready to design our own Nios II embedded system from scratch. To our help we have this tutorial from Altera. The tutorial introduces us to the system development flow for the Nios II processor. Using the Quartus II software and the Nios II Embedded Design Suite (EDS), we build a Nios II hardware system design and create a software program that runs on the Nios II system and interfaces with components on the Altera development board. The tutorial is a good starting point if we are new to the Nios II processor or the general concept of building embedded systems in FPGAs.

The Nios II Software Developer's Handbook

The Nios II Software Developer’s Handbook provides the basic information needed to develop embedded software for the Altera® Nios II processor. This handbook describes the Nios II software development environment, the Nios II Embedded Design Suite (EDS) tools available to you, and the process for developing software.

Design example

The design example we build in this tutorial demonstrates a small Nios II system for control applications, that displays character I/O output and blinks LEDs in a binary counting pattern. This Nios II system can also communicate with a host computer, allowing the host computer to control logic inside the FPGA. The example Nios II system contains the following components:

  • On-chip memory
  • Timer
  • 8-bit parallel I/O (PIO) pins to control the LEDs
  • System identification component


Software and hardware requirements

This tutorial requires us to have the following software:
  • Altera Quarus II software version 11.0 or later.
  • Nios II EDS version 11.0 or later

We can build this design example with any Altera development board our other custom board that meets the following requirements:
  • The board must have an Altera Stratix® series, Cyclone® series, or Arria® series FPGA.
  • The FPGA must contain a minimum of 2500 logic elements (LE) or adaptive look- up tables (ALUT).
  • The FPGA must contain a minimum of 50 M4K or M9K memory blocks.
  • An oscillator must drive a constant clock frequency to an FPGA pin. The maximum frequency limit depends on the speed grade of the FPGA. Frequencies of 50 MHz or less should work for most boards; higher frequencies might work.
  • FPGA I/O pins can optionally connect to eight or fewer LEDs to provide a visual indicator of processor activity.
  • The board must have a JTAG connection to the FPGA that provides a programming interface and communication link to the Nios II system. This connection can be a dedicated 10-pin JTAG header for an Altera USB-BlasterTM download cable (revision B or higher) or a USB connection with USB-Blaster circuitry embedded on the board.

Our board (Cyclone III FPGA Development Kit) meets all requirements. We are ready to roll.

Nios II system development flow

This figure show the the Nios II system development flow.



Using this design example

To run this example we download the and unzip it to our hard drive. Then, follow the instructions in Nios II Hardware Development Tutorial.


Downloaded files

After unzipping we get these files.


Open the example design

Let's start Quartus and open the design (nios2_quartus2_project.qsf).



Display the blockdiagram

The Block Editor allows us to enter and edit graphic design information in the form of schematics and block diagrams, and reads and edits Block Design Files (.bdf).

We can create .bdf files that contain blocks and symbols that represent logic in a design. The Block Editor incorporates the design logic represented by each block diagram, schematic, or symbol into the project. We can also create new design files from the blocks in a .bdf, update the design files when we modify the blocks and the symbols, and generate Block Symbol Files (.bsf), AHDL Include Files (.inc), and HDL files from .bdf files. We can also analyze .bdf files for errors before compilation.

 The Block Editor also provides a set of tools that help us connect blocks and primitives together, including bus and node connections and signal name mapping. We can change the Block Editor to display options, such as guidelines and grid spacing, rubberbanding, colors and screen elements, zoom, and different block and primitive properties to accommodate our design requirements.

Among the downloaded files there is already a Block Design File prepared. To open it we select File->Open.


The .bdf contains an input pin for the clock input and eight output pins to drive the LEDs on the board. We will use Qsys to fill this design with the SOC design.

Create a new Qsys system

We use Qsys to generate the Nios II processor system, adding the desired components, and configuring how they connect together.  Qsys is a powerful system integration tool which is included as part of the Quartus II software. Qsys captures system level hardware designs at a relatively high level of abstraction and also automates the task of defining and integrating customized HDL components, which may include IP cores, verification IP, and other design modules. Qsys facilitates design reuse by packaging and making available your custom components and systems. Qsys integrates our custom components with Altera and third-party developer components. In some cases, we can implement an entire design using components from the Altera component library. During system generation, Qsys automatically creates high-performance interconnect logic from the connectivity options you specify, eliminating the error-prone and time-consuming task of writing HDL to specify the system-level connections.

Complete Qsys design flow


For more information about using Qsys read the Quartus II Handbook, Creating a System with Qsys.


Starting Qsys

To create a new Qsys system click Qsys in the Tools menu.



Define the system in Qsys

We use Qsys to define the hardware characterics of the Nios II system. We will start by:
  1. Specify target FPGA and clock settings
  2. Add the Nios II core, on-chip memory and other components
  3. Specify the base address and interrupt request priorities
  4. Generate the system

Specify target FPGA and clock settings

Select the Cyclone III FPGA family.

Make sure the clock is set to 50 MHz.


Read the tutorial

To build this system we go through a number of design steps that are explained in detail in the Nios II Hardware Development Tutorial. We will not repeat all steps in this description. Just be careful not to miss anything.

On-chip memory

Select On-Chip memory from the Component Library and set the memory size to 20480 (20 KB).

Click Finish to return to Qsys. Rename the on-chip memory to onchip_mem. We must name these components exactly as specified in the tutorial. Otherwise the tutorial programs written for the Nios II system will fail in later steps.



Add the Nios II processor core

Select Nios II from the Component Library.

We will use the Nios II/s. Altera specifically designed the Nios® II/s "standard" processor core to implement a small processor core without a significant trade-off in software performance. The Nios II/s core is optimal for cost-sensitive, medium-performance applications, including those with large amounts of code and/or data, such as systems running a full-featured operating system.

Set instruction cache

We will use a small instruction cache (2 KB). No data cache will be used.

Rename the Nios II processor to cpu and connect the clock and reset pins. See the Nios II Hardware Development Tutorial for a description on how to connect the pins.




The JTAG UART provides a way to communicate character data with the Nios II processor through the USB-Blaster download cable.


Do not change the default settings.

Rename the JTAG UART to jtag_uart and connect the ports.

Add the interval timer

Most control systems use a timer component to enable precise calculation of time.

In the Presets list select Full-featured.

 Rename the Interval Timer to sys_clk_timer and connect the ports.

Add the System ID peripheral

The system ID peripheral safeguards against accidentally downloading software compiled for a different Nios II system.



Do not change the default settings.

Rename the System ID peripheral to sysid and connect the ports.

Add the PIO

PIO signals provide an easy method for Nios II processor systems to receive input stimuli and drive output signals. This design example uses eight PIO signals to drive the LEDs on the board.



Do not change the default settings.


Rename the PIO to led_pio and connect the ports. We have now added all the hardware we need to build our system.

Specify base addresses and interrupt priorities

Qsys provides the Assign Base Addresses command which makes assigning component base addresses easy. For many systems, including this design example, Assign Base Addresses is adequate. However, we can adjust the base addresses to suit your needs. From the System menu select Assign Base Addreses to make Qsys assign functional base addresses to each component in the system.

In the IRQ column connnect the Nios II processor to the JTAG UART and interval timer. Click the IRQ value for jtag and type 16. Click the IRQ value for the sys_clk_timer and type 1 to assign the new IRQ value.

The complete system in Qsys

This is what the complete system looks like in Qsys. This screenplot shows the all the modules and the connection between them.

This screenplot shows the base addresses and the interrupt priorities. The timer block has the highest priority (1).


Generate the Qsys system

We are now ready to generate the Qsys system. Perform the following steps:
  1. Click the Generation tab.
  2. Select None in both the Create simulation model and Create testbench Qsys system lists.
  3. Click Generate. The Save changes? dialog box appears, prompting us to save our design.


The generation process can take several minutes. Output messages appear as generation progresses. When generation completes, the final "Info: Finished: Create HDL design files for synthesis" message appears.



Congratulations! We have finished creating the Nios II processor system. We are ready to integrate the system into the Quartus II hardware project and use the Nios II SBT for Eclipse to develop software. Here is the complete file structure for the project.



Instantiate the Qsys module in the Quartus project

To instantiate the system module in the .bdf, perform the following steps:
  1. Double-click in the empty space to the right of the input and output wires.
  2. The Symbol dialog box appears.
  3. Under Libraries, expand Project.
  4. Click first_nios2_system. The Symbol dialog box displays the first_nios2_system symbol.
  5. Click OK. You return to the .bdf schematic. The first_nios2_system symbol tracks with your mouse pointer.
  6. Position the symbol so the pins on the symbol align with the wires on the schematic.
  7. Click to anchor the symbol in place.
  8. To save the completed .bdf, click Save on the File menu.

Adding the Quartus IP definition file

This file lists the Quartus II software needed to compile your design. We must add the .qip file to our Quartus II project.

  1. On the Assignments menu, click Settings. The Settings dialog box appears.
  2. Under Category, click Files. The Files page appears.
  3. Next to File name, click the browse (...) button.
  4. In the Files of type list, select Script Files (*.tcl, *.sdc, *.qip).
  5. Browse to locate <design files directory>/first_nios2_system/synthesis/ first_nios2_system.qip and click Open to select the file.
  6. Click Add to include first_nios2_system.qip in the project.
  7. Click OK to close the Settings dialog box.


Assign FPGA device and pin locations

In this section, we assign a specific target device and then assign FPGA pin locations to match the pinouts of our board.To assign the device we select Device from the Assignment menu.


Before we start the pin assignment  we will run the Analysis & Elaboration from the Processing menu. This will make sure we have a complete design ready for the pin assignment. Here is the result.



We use the Pin Planner to assign the pins. Start the Pin Planner from the Assignment menu. Enter the pin locations for the PLD_CLOCKINPUT and the LEDs.



 Protect unused pins

Unused pins are set as input tri-stated with weak pull-up to remove contention which might damage the board. Depending on the board, you might have to make more assignments for the project to function correctly. You can damage the board if you fail to account for the board design. To setup unused pins click Device in the Assignment menu and then click the Device and Pin Options button.



Compile the Quartus project

At this point we are ready to compile the Quartus II project and verify that the resulting design meets timing requirements. We must compile the hardware design to create a .sof that we can download to the board. After the compilation completes, we must analyze the timing performance of the FPGA design to verify that the design will work in hardware.

Editing the syntesis constraints file

Open the file <design directory>/hw_dev_tutorial.sdc and make sure the system clock has the right clock period (20 ns = 50 MHz).



Verify timing

To ensure the design meets timing we will run the TimeQuest Timing Analyzer. The TimeQuest timing analyzer is a powerful ASIC-style timing analysis tool that validates the timing performance of all logic in a design using industry standard constraint, analysis, and reporting methodology. The TimeQuest timing analyzer includes support for Synopsis Design Constraints (SDC). Additionally, the TimeQuest timing analyzer includes an extensive tool command language (Tcl) scripting API. The timing analysis will take place during the compilation phase.

On the Assignment menu, click Settings. In the Setting dialog box under Category click TimeQuest Timing Analyzer.


Add the constraints file hw_dev_tutorial.sdc and turn on Enable multicore timing analysis during compilation.

Start compilation

On the Processing menu, click Start Compilation. The Tasks window and percentage and time counters in the lower-right corner display progress. The compilation process can take several minutes. When compilation completes, a dialog box displays the message "Full Compilation was successful."

Check timing reports

To check the timing report we look in the Compilation Report window. The failing Removal values we will ignore for now. I am not sure why it is failing.


Download the design to the target board.

See the chapter Implementing a Nios II embedded processor system for information on how to configure the FPGA on the target board.

Develop software using the Nios II software build tool

See the chapter Nios II Embedded Design Suite EDS for information on how to compile a C language program, load and, run it on the target system. We will use the template program count_binary.



Setup Nios II BSP properties

In the Project Explorer view, right-click count_binary_bsp and click properties. Click the Nios II BSP Properties page. To reduce the size of the compiled executable we adjust the settings like this.



Run the program on the target hardware

After downloading the software executable and starting the program the LEDs will blink in a binary counting pattern and the following display will appear in the Nios II console.


Stopping the progam execution

Click the red button to stop the program.