Tut Nios2 Introduction
Tut Nios2 Introduction
Contents:
Nios II System
Overview of Nios II Processor Features
Register Structure
Accessing Memory and I/O Devices
Addressing
Instruction Set
Assembler Directives
Example Program
Exception Processing
Cache Memory
Tightly Coupled Memory
1
Altera’s Nios II is a soft processor, defined in a hardware description language, which can be implemented in
Altera’s FPGA devices by using the Quartus
R
II CAD system. This tutorial provides a basic introduction to the
Nios II processor, intended for a user who wishes to implement a Nios II based system on the Altera DE2 board.
1 Nios II System
The Nios II processor can be used with a variety of other components to form a complete system. These compo-
nents include a number of standard peripherals, but it is also possible to define custom peripherals. Altera’s DE2
Development and Education board contains several components that can be integrated into a Nios II system. An
example of such a system is shown in Figure 1.
Host computer
USB-Blaster
interface
Cyclone II
JTAG Debug JTAG UART FPGA chip
Nios II processor module interface
2
The Nios II processor and the interfaces needed to connect to other chips on the DE2 board are implemented in
the Cyclone II FPGA chip. These components are interconnected by means of the interconnection network called
the Avalon Switch Fabric. Memory blocks in the Cyclone II device can be used to provide an on-chip memory for
the Nios II processor. They can be connected to the processor either directly or through the Avalon network. The
SRAM and SDRAM memory chips on the DE2 board are accessed through the appropriate interfaces. Input/output
interfaces are instantiated to provide connection to the I/O devices used in the system. A special JTAG UART
interface is used to connect to the circuitry that provides a Universal Serial Bus (USB) link to the host computer to
which the DE2 board is connected. This circuitry and the associated software is called the USB-Blaster. Another
module, called the JTAG Debug module, is provided to allow the host computer to control the Nios II processor.
It makes it possible to perform operations such as downloading programs into memory, starting and stopping
execution, setting program breakpoints, and collecting real-time execution trace data.
Since all parts of the Nios II system implemented on the FPGA chip are defined by using a hardware description
language, a knowledgeable user could write such code to implement any part of the system. This would be an
onnerous and time consuming task. Instead, one can use the SOPC Builder tool in the Quartus II software to
implement a desired system simply by choosing the required components and specifying the parameters needed
to make each component fit the overall requirements of the system.
• Nios II/s is a "standard" version that requires less resources in an FPGA device as a trade-off for reduced
performance.
• Nios II/e is an "economy" version which requires the least amount of FPGA resources, but also has the most
limited set of user-configurable features.
The Nios II processor has a Reduced Instruction Set Computer (RISC) architecture. Its arithmetic and logic
operations are performed on operands in the general purpose registers. The data is moved between the memory
and these registers by means of Load and Store instructions.
The wordlength of the Nios II processor is 32 bits. All registers are 32 bits long. Byte addresses in a 32-bit
word are assigned in little-endian style, in which the lower byte addresses are used for the less significant bytes
(the rightmost bytes) of the word.
The Nios II architecture uses separate instruction and data buses, which is often referred to as the Harvard
architecture.
A Nios II processor may operate in the following three modes:
• Supervisor mode – allows the processor to execute all instructions and perform all available functions. When
the processor is reset, it enters this mode.
• User mode – the intent of this mode is to prevent execution of some instructions that shoud be used for
systems purposes only. Some processor features are not accessible in this mode.
• Debug mode – is used by software debugging tools to implement features such as breakpoints and watch-
points.
Application programs can be run in either the User or Supervisor modes. Presently available versions of the Nios
II processor do not support the User mode.
3
3 Register Structure
The Nios II processor has thirty two 32-bit general purpose registers, as shown in Figure 2. Some of these registers
are intended for a specific purpose and have special names that are recognized by the Assembler.
• Register r0 is referred to as the zero register. It always contains the constant 0. Thus, reading this register
returns the value 0, while writing to it has no effect.
• Register r1 is used by the Assembler as a temporary register; it should not be referenced in user programs
• Registers r24 and r29 are used for processing of exceptions; they are not available in User mode
• Registers r25 and r30 are used exclusively by the JTAG Debug module
• Registers r27 and r28 are used to control the stack used by the Nios II processor
• Register r31 is used to hold the return address when a subroutine is called
There are six 32-bit control registers, as indicated in Figure 3. The names given in the figure are recognized
by the Assembler. These registers are used automatically for control purposes. They can be read and written to by
special instructions rdctl and wrctl, which can be executed only in the supervisor mode. The registers are used as
follows:
• Register ctl0 reflects the operating status of the processor. Only two bits of this register are meaningful:
– U is the User/Supervisor mode bit; U = 1 for User mode, while U = 0 for Supervisor mode.
– PIE is the processor interrupt-enable bit. When PIE = 1, the processor may accept external interrupts.
When PIE = 0, the processor ignores external interrupts.
• Register ctl1 holds a saved copy of the status register during exception processing. The bits EU and EPIE
are the saved values of the status bits U and PIE.
4
• Register ctl2 holds a saved copy of the status register during debug break processing. The bits BU and BPIE
are the saved values of the status bits U and PIE.
• Register ctl3 is used to enable individual external interrupts. Each bit corresponds to one of the interrupts
irq0 to irq31. The value of 1 means that the interrupt is enabled, while 0 means that it is disabled.
• Register ctl4 indicates which interrupts are pending. The value of a given bit, ctl4k , is set to 1 if the interrupt
irqk is both active and enabled by having the interrupt-enable bit, ctl3k , set to 1.
• Register ctl5 holds a value that uniquely identifies the processor in a multiprocessor system.
5
Cyclone II
FPGA chip General purpose
Program counter registers
Instruction Data
cache cache
Memory I/O
device device
5 Addressing
The Nios II processor issues 32-bit addresses. The memory space is byte-addressable. Instructions can read and
write words (32 bits), halfwords (16 bits), or bytes (8 bits) of data. Reading or writing to an address that does not
correspond to an existing memory or I/O location produces an undefined result.
There are five addressing modes provided:
• Immediate mode – a 16-bit operand is given explicitly in the instruction. This value may be sign extended
to produce a 32-bit operand in instructions that perform arithmetic operations.
• Register mode – the operand is in a processor register
• Displacement mode – the effective address of the operand is the sum of the contents of a register and a
signed 16-bit displacement value given in the instruction
• Register indirect mode – the effective address of the operand is the contents of a register specified in the
instruction. This is equivalent to the displacement mode where the displacement value is equal to 0.
6
• Absolute mode – a 16-bit absolute address of an operand can be specified by using the displacement mode
with register r0 which always contains the value 0.
6 Instructions
All Nios II instructions are 32-bits long. In addition to machine instructions that are executed directly by the pro-
cessor, the Nios II instruction set includes a number of pseudoinstructions that can be used in assembly language
programs. The Assembler replaces each pseudoinstruction by one or more machine instructions.
Figure 5 depicts the three possible instruction formats: I-type, R-type and J-type. In all cases the six bits b5−0
denote the OP code. The remaining bits are used to specify registers, immediate operands, or extended OP codes.
• I-type – Five-bit fields A and B are used to specify general purpose registers. A 16-bit field IMMED16
provides immediate data which can be sign extended to provide a 32-bit operand.
• R-type – Five-bit fields A, B and C are used to specify general purpose registers. An 11-bit field OPX is
used to extend the OP code.
• J-type – A 26-bit field IMMED26 contains an unsigned immediate value. This format is used only in the
Call instruction.
31 27 26 22 21 6 5 0
A B IMMED16 OP
(a) I-type
31 27 26 22 21 17 16 6 5 0
A B C OPX OP
(b) R-type
31 6 5 0
IMMED26 OP
(c) J-type
The following subsections discuss briefly the main features of the Nios II instruction set. For a complete
description of the instruction set, including the details of how each instruction is encoded, the reader should
consult the Nios II Processor Reference Handbook.
7
determines the effective address of a memory location as the sum of a byte_offset value and the contents of register
A. The 16-bit byte_offset value is sign extended to 32 bits. The 32-bit memory operand is loaded into register B.
For instance, assume that the contents of register r4 are 126010 and the byte_offset value is 8010 . Then, the
instruction
loads the 32-bit operand at memory address 134010 into register r3.
It stores the contents of register B into the memory location at the address computed as the sum of the byte_offset
value and the contents of register A.
There are Load and Store instructions that use operands that are only 8 or 16 bits long. They are referred to as
Load/Store Byte and Load/Store Halfword instructions, respectively. Such Load instructions are:
When a shorter operand is loaded into a 32-bit register, its value has to be adjusted to fit into the register. This
is done by sign extending the 8- or 16-bit value to 32 bits in the ldb and ldh instructions. In the ldbu and ldhu
instructions the operand is zero extended.
Each Load and Store instruction has a version intended for accessing locations in I/O device interfaces. These
instructions are:
The difference is that these instructions bypass the cache, if one exists.
8
6.2 Arithmetic Instructions
The arithmetic instructions operate on the data that is either in the general purpose registers or given as an imme-
diate value in the instruction. These instructions are of R-type or I-type, respectively. They include:
• add (Add Registers)
• addi (Add Immediate)
• sub (Subtract Registers)
• subi (Subtract Immediate)
• mul (Multiply)
• muli (Multiply Immediate)
• div (Divide)
• divu (Divide Unsigned)
The Add instruction
add rC, rA, rB
adds the contents of registers A and B, and places the sum into register C.
9
The Divide instruction
div rC, rA, rB
divides the contents of register A by the contents of register B and places the integer portion of the quotient into
register C. The operands are treated as signed integers. The divu instruction is performed in the same way except
that the operands are treated as unsigned integers.
It is also possible to use the 16-bit immediate operand as the 16 high-order bits in the logic operations, in which
case the low-order 16 bits of the operand are zeros. This is accomplished with the instructions:
• andhi (AND High Immediate)
• orhi (OR High Immediate)
• xorhi (XOR High Immediate)
10
movui rB, IMMED16
zero extends the IMMED16 value to 32 bits and loads it into register B. It is implemented as
ori rB, r0, IMMED16
11
The immediate versions of the Comparison instructions involve an immediate operand. For example, the
Compare Less Than Signed Immediate instruction
compares the signed number in register A with the sign-extended immediate operand. It writes a 1 into register B
if rA < IMMED16; otherwise, it writes a 0.
compares the unsigned number in register A with the zero-extended immediate operand. It writes a 1 into register
B if rA < IMMED16; otherwise, it writes a 0.
12
The srl instruction shifts the contents of register A to the right by the number of bit positions specified by the five
least-significant bits (number in the range 0 to 31) in register B, and stores the result in register C. The vacated
bits on the left side of the shifted operand are filled with 0s.
The srli instruction shifts the contents of register A to the right by the number of bit positions specified by the
five-bit unsigned value, IMMED5, given in the instruction.
The sra and srai instructions perform the same actions as the srl and srli instructions, except that the sign bit,
rA31 , is replicated into the vacated bits on the left side of the shifted operand.
The sll and slli instructions are similar to the srl and srli instructions, but they shift the operand in register A to the
left and fill the vacated bits on the right side with 0s.
The ror instruction rotates the bits of register A in the left-to-right direction by the number of bit positions spec-
ified by the five least-significant bits (number in the range 0 to 31) in register B, and stores the result in register C.
The rol instruction is similar to the ror instruction, but it rotates the operand in the right-to-left direction.
The roli instruction rotates the bits of register A in the right-to-left direction by the number of bit positions specified
by the five-bit unsigned value, IMMED5, given in the instruction, and stores the result in register C.
jmp rA
transfers execution unconditionally to the instruction at address LABEL. This is an instruction of I-type, in which
a 16-bit immediate value (interpreted as a signed number) specifies the offset to the branch target instruction. The
offset is the distance in bytes from the instruction that immediately follows br to the address LABEL.
Conditional transfer of execution is achieved with the Conditional Branch instructions, which compare the
contents of two registers and cause a branch if the result is true. These instructions are of I-type and the offset is
determined as explained above for the br instruction.
13
The Branch if Less Than Signed instruction
performs the comparison rA < rB, treating the contents of the registers as signed numbers.
performs the comparison rA < rB, treating the contents of the registers as unsigned numbers.
call LABEL
is of J-type, which includes a 26-bit unsigned immediate value (IMMED26). The instruction saves the return
address (which is the address of the next instruction) in register r31. Then, it transfers control to the instruction
at address LABEL. This address is determined by concatenating the four high-order bits of the Program Counter
with the IMMED26 value as follows
Note that the two least-significant bits are 0 because Nios II instructions must be aligned on word boundaries.
callr rA
is of R-type. It saves the return address in register r31 and then transfers control to the instruction at the address
contained in register A.
ret
14
6.10 Control Instructions
The Nios II control registers can be read and written by special instructions. The Read Control Register instruction
wrctl ctlN, rA
There are two instructions provided for dealing with exceptions: trap and eret. They are similar to the call
and ret instructions, but they are used for exceptions. Their use is discussed in section 8.2.
The instructions break and bret generate breaks and return from breaks. They are used exclusively by the
software debugging tools.
The Nios II cache memories are managed with the instructions: flushd (Flush Data Cache Line), flushi (Flush
Instruction Cache Line), initd (Initialize Data Cache Line), and initi (Initialize Instruction Cache Line). These
instructions are discussed in section 9.1.
Having executed this instruction, a possible occurrence of a carry out of the most-significant bit (C31 ) can be
detected by checking whether the unsigned sum (in register C) is less than one of the unsigned operands. For
example, if this instruction is followed by the instruction
Similarly, if a branch is required when a carry occurs, this can be accomplished as follows:
add rC, rA, rB
bltu rC, rA, LABEL
A test for arithmetic overflow can be done by checking the signs of the summands and the resulting sum. An
overflow occurs if two positive numbers produce a negative sum, or if two negative numbers produce a positive
sum. Using this approach, the overflow condition can control a conditional branch as follows:
add rC, rA, rB /* The required Add operation */
xor rD, rC, rA /* Compare signs of sum and rA */
xor rE, rC, rB /* Compare signs of sum and rB */
and rD, rD, rE /* Set D31 = 1 if ((A31 == B31 ) ! = C31 ) */
blt rD, r0, LABEL /* Branch if overflow occurred */
15
A similar approach can be used to detect the carry and overflow conditions in Subtract operations. A carry out
of the most-significant bit of the resulting difference can be detected by checking whether the first operand is less
than the second operand. Thus, the carry can be used to control a conditional branch as follows:
sub rC, rA, rB
bltu rA, rB, LABEL
The arithmetic overflow in a Subtract operation is detected by comparing the sign of the generated difference with
the signs of the operands. Overflow occurs if the operands in registers A and B have different signs, and the sign
of the difference in register C is different than the sign of A. Thus, a conditional branch based on the arithmetic
overflow can be achieved as follows:
sub rC, rA, rB /* The required Subtract operation */
xor rD, rA, rB /* Compare signs of rA and rB */
xor rE, rA, rC /* Compare signs of rA and rC */
and rD, rD, rE /* Set D31 = 1 if ((A31 ! = B31 ) && (A31 ! = C31 )) */
blt rD, r0, LABEL /* Branch if overflow occurred */
7 Assembler Directives
The Nios II Assembler conforms to the widely used GNU Assembler, which is software available in the public
domain. Thus, the GNU Assembler directives can be used in Nios II programs. Assembler directives begin with a
period. We describe some of the more frequently used assembler directives below.
.ascii "string"...
A string of ASCII characters is loaded into consecutive byte addresses in the memory. Multiple strings, separated
by commas, can be specified.
.asciz "string"...
This directive is the same as .ascii, except that each string is followed (terminated) by a zero byte.
.byte expressions
Expressions separated by commas are specified. Each expression is assembled into the next byte. Examples of
expressions are: 8, 5 + LABEL, and K − 6.
.data
Identifies the data that should be placed in the data section of the memory. The desired memory location for the
data section can be specified in the Altera Monitor Program’s system configuration window.
.end
Marks the end of the source code file; everything after this directive is ignored by the assembler.
16
.global symbol
.hword expressions
Expressions separated by commas are specified. Each expression is assembled into a 16-bit number.
.include "filename"
.org new-lc
Advances the location counter by new-lc, where new-lc is used as an offset from the starting location specified
in the Altera Monitor Program’s system configuration window. The .org directive may only increase the location
counter, or leave it unchanged; it cannot move the location counter backwards.
.skip size
Emits the number of bytes specified in size; the value of each byte is zero.
.text
Identifies the code that should be placed in the text section of the memory. The desired memory location for the
text section can be specified in the Altera Monitor Program’s system configuration window.
.word expressions
Expressions separated by commas are specified. Each expression is assembled into a 32-bit number.
8 Example Program
As an illustration of Nios II instructions and assembler directives, Figure 6 gives an assembly language program
that computes a dot product of two vectors, A and B. The vectors have n elements. The required computation is
Pn−1
Dot product = i=0 A(i) × B(i)
The vectors are stored in memory locations at addresses AVECTOR and BVECTOR, respectively. The number of el-
ements, n, is stored in memory location N . The computed result is written into memory location DOT_PRODUCT.
Each vector element is assumed to be a signed 32-bit number.
17
.include "nios_macros.s"
.global _start
_start:
movia r2, AVECTOR /* Register r2 is a pointer to vector A */
movia r3, BVECTOR /* Register r3 is a pointer to vector B */
movia r4, N
ldw r4, 0(r4) /* Register r4 is used as the counter for loop iterations */
add r5, r0, r0 /* Register r5 is used to accumulate the product */
LOOP: ldw r6, 0(r2) /* Load the next element of vector A */
ldw r7, 0(r3) /* Load the next element of vector B */
mul r8, r6, r7 /* Compute the product of next pair of elements */
add r5, r5, r8 /* Add to the sum */
addi r2, r2, 4 /* Increment the pointer to vector A */
addi r3, r3, 4 /* Increment the pointer to vector B */
subi r4, r4, 1 /* Decrement the counter */
bgt r4, r0, LOOP /* Loop again if not finished */
stw r5, DOT_PRODUCT(r0) /* Store the result in memory */
STOP: br STOP
N:
.word 6 /* Specify the number of elements */
AVECTOR:
.word 5, 3, −6, 19, 8, 12 /* Specify the elements of vector A */
BVECTOR:
.word 2, 14, −3, 2, −5, 36 /* Specify the elements of vector B */
DOT_PRODUCT:
.skip 4
Note that the program ends by continuously looping on the last Branch instruction. If instead we wanted to pass
control to debugging software, we could replace this br instruction with the break instruction.
.include "nios_macros.s"
which informs the Assembler to use some macro commands that have been created for the Nios II processor. In
this program, the macro used converts the movia pseudoinstruction into two OR instructions as explained in sec-
tion 6.4.
The directive
.global _start
indicates to the Assembler that the label _start is accessible outside the assembled object file. This label is the
default label we use to indicate to the Linker program the beginning of the application program.
The program includes some sample data. It illustrates how the .word directive can be used to load data items
into memory. The memory locations involved are those that follow the location occupied by the br instruction.
Since we have not explicitly specified the starting address of the program itself, the assembled code will be loaded
in memory starting at address 0.
To execute the program in Figure 6 on Altera’s DE2 board, it is necessary to implement a Nios II processor
and its memory (which can be just the on-chip memory of the Cyclone II FPGA). Since the program includes the
18
Multiply instruction, it cannot be executed on the economy version of the processor, because Nios II/e does not
support the mul instruction. Either Nios II/s or Nios II/f processors can be used.
The tutorial Introduction to the Altera SOPC Builder explains how a Nios II system can be implemented.
The tutorial Altera Monitor Program explains how an application program can be assembled, downloaded and
executed on the DE2 board.
9 Exception Processing
An exception in the normal flow of program execution can be caused by:
• Software trap
• Hardware interrupt
• Unimplemented instruction
1. Saves the existing processor status information by copying the contents of the status register (ctl0) into the
estatus register (ctl1)
2. Clears the U bit in the status register, to ensure that the processor is in the Supervisor mode
3. Clears the PIE bit in the status register, thus disabling the additional external processor interrupts
4. Writes the address of the instruction after the exception into the ea register (r29)
5. Transfers execution to the address of the exception handler which determines the cause of the exception and
dispatches an appropriate exception routine to respond to the exception
The address of the exception handler is specified at system generation time using the SOPC Builder, and it cannot
be changed by software at run time. This address can be provided by the designer; otherwise, the default address
is 2016 from the starting address of the main memory. For example, if the memory starts at address 0, then the
default address of the exception handler is 0x00000020.
19
The contents of the ipending register (ctl4) indicate which interrupt requests are pending. An exception routine
determines which of the pending interrupts has the highest priority, and transfers control to the corresponding
interrupt-service routine.
Upon completion of the interrupt-service routine, the execution control is returned to the interrupted program
by means of the eret instruction, as explained above. However, since an external interrupt request is handled
without first completing the instruction that is being executed when the interrupt occurs, the interrupted instruction
must be re-executed upon return from the interrupt-service routine. To achieve this, the interrupt-service routine
has to adjust the contents of the ea register which are at this time pointing to the next instruction of the interrupted
program. Hence, the value in the ea register has to be decremented by 4 prior to executing the eret instruction.
1. Read the ipending register to see if a hardware interrupt has occurred; if so, then go to the appropriate
interrupt-service routine.
2. Read the instruction that was being executed when the exception occurred. The address of this instruction
is the value in the ea register minus 4. If this is the trap instruction, then go to the software-trap-handling
routine.
20
.org 0x20
/* Exception handler */
rdctl et, ctl4 /* Check if external interrupt occurred */
beq et, r0, OTHER_EXCEPTIONS /* If zero, check exceptions */
subi ea, ea, 4 /* Hardware interrupt, decrement ea to execute the interrupted */
/* instruction upon return to main program */
andi r13, et, 2 /* Check if irq1 asserted */
bne r13, r0, EXT_IRQ1 /* If yes, go to IRQ1 service routine */
/* Instructions that check for other hardware interrupts should be placed here */
OTHER_EXCEPTIONS:
/* Instructions that check for other types of exceptions should be placed here */
.org 0x100
/* Interrupt-service routine for the desired hardware interrupt */
EXT_IRQ1:
/* Instructions that handle the irq1 interrupt request should be placed here */
10 Cache Memory
As shown in Figure 4, a Nios II system can include instruction and data caches, which are implemented in the
memory blocks in the FPGA chip. The caches can be specified when a system is being designed by using the
SOPC Builder software. Inclusion of caches improves the performance of a Nios II system significantly, particu-
larly when most of the main memory is provided by an external SDRAM chip, as is the case with Altera’s DE2
board. Both instruction and data caches are direct-mapped.
The instruction cache can be implemented in the fast and standard versions of the Nios II processor systems.
It is organized in 8 words per cache line, and its size is a user-selectable design parameter.
The data cache can be implemented only with the Nios II/f processor. It has a configurable line size of 4, 16
or 32 bytes per cache line. Its overall size is also a user-selectable design parameter.
21
• flushd IMMED16(rA) (Flush data-cache line)
Computes the effective address by adding the sign-extended value IMMED16 and the contents of register
rA. Then, it identifies the cache line associated with this effective address, writes any dirty data in the cache
line back to memory, and invalidates the cache line.
Copyright
2008
c Altera Corporation. All rights reserved. Altera, The Programmable Solutions Company, the
stylized Altera logo, specific device designations, and all other words and logos that are identified as trademarks
and/or service marks are, unless noted otherwise, the trademarks and service marks of Altera Corporation in
the U.S. and other countries. All other product or service names are the property of their respective holders.
Altera products are protected under numerous U.S. and foreign patents and pending applications, mask work
rights, and copyrights. Altera warrants performance of its semiconductor products to current specifications in
accordance with Altera’s standard warranty, but reserves the right to make changes to any products and services at
any time without notice. Altera assumes no responsibility or liability arising out of the application or use of any
information, product, or service described herein except as expressly agreed to in writing by Altera Corporation.
Altera customers are advised to obtain the latest version of device specifications before relying on any published
information and before placing orders for products or services.
This document is being provided on an “as-is” basis and as an accommodation and therefore all warranties, rep-
resentations or guarantees of any kind (whether express, implied or statutory) including, without limitation, war-
ranties of merchantability, non-infringement, or fitness for a particular purpose, are specifically disclaimed.
22