You are on page 1of 10

TAMS / Java / Hades / applets: contents

Hades
welcome
news
gate-level
rtlib
cosimulation
browser
waveforms
scripting
documentation
download
webstart
gallery
links
about
Applets
contents
visual index
usage
FAQ
feedback
license

As explained in more detail on the cosimulation overview page, one of the


central research goals of the Hades framework was to study algorithms for
system-simulation and fast hardware/software-cosimulation, including the
coupling of an event-driven simulation engine with instruction-level processor
simulators.
We choose the MIPS-I architecture as the demonstrator for cosimulation and
the fast simulator coupling in Hades. The first reason for this decision is the
architecture itself, with its simple and regular instruction set, straightforward
memory-model, clean exception and interrupt handling. Secondly, the market
for 32-bit embedded systems and system-on-a-chip designs is still dominated by
microcontrollers based on the MIPS and ARM architectures. Thirdly,
documentation and tools for the MIPS architecture are readily available. For
example, the DLX processor used in the textbook(s) by J.L.Hennessy and
D.Patterson is closed based on the MIPS concepts.
The remainder of this document first gives a broad overview of the MIPS
architecture, including instruction-set, memory-model, and interrupts. The
following section then describes the relevant details, user-interface, and
configuration settings of the TinyMips microprocessor. While TinyMips
faithfully implements the full MIPS-I instruction-set and memory-model, it
does use a simplified execution model without instruction pipeline. Finally, we
present an overview of the GNU toolchain and explain how to setup your own
cross-compiler and the binutils assembler and helper tools. Using the gcc crosscompiler allows you to write programs and compile programs for the TinyMips
processor on your own computer. reference when studying the applets on the
Hades website.
You might want to print a copy of this page and keep it around as reference
while studying the interactive applets based on the TinyMips and IDT R3051
microprocessors.
MIPS architecture overview
The MIPS architecture evolved from research on efficient processor
organization and VLSI integration at Stanford University. Their prototype chip
proved that a microprocessor with five-stage execution pipelineand cache
controller could be integrated onto a single silicon chip, greatly improving
performance over non-pipelined designs. At the same time, a research group at
Berkeley designed the RISC-I chip based on pretty much the same ideas.
Today, the acronym RISC is interpreted as "regular instruction set computer",
and the RISC ideas are used in every current microprocessor design.

The key concepts of the original MIPS architecture are:

five-stage execution pipeline: fetch, decode, execute, memory-access,


write-result
regular instruction set, all instructions are 32-bit
three-operand arithmetical and logical instructions
32 general-purpose registers of 32-bits each
no status register or instruction side-effects
no complex instructions (like stack management, string operations, etc.)
optional coprocessors for system management and floating-point
only the load and store instruction access memory
flat address space of 4 GBytes of main memory (2^32 bytes)
memory-management unit (MMU) maps virtual to actual physical
addresses
optimizing C compiler replaces hand-written assembly code
hardware structure does not check dependecies - not "foolproof"
but software toolchain knows about hardware and generates correct code

In 1984, MIPS corporation was founded by members of the Stanford research


team to develop a commercial version of the prototype chip. Their first product
was the R2000 microprocessor, introduced in 1985, and followed in 1987 by
the R2010 floating-point coprocessor. Both chips were successfully used in
several of the early workstations. The next MIPS processor, called R3000, was
a variant of the R2000 with the same instruction set, but optimized for low-cost
embedded systems. This processor and its system-on-a-chip implementations
are still popular and used in millions of devices (e.g. printers) even today. Since
then, several improved variants of the original instruction set have been
introduced:

MIPS-I: the original 32-bit instruction set; still common.


MIPS-II: improved instruction set with dozens of new instructions.
MIPS-III: a 64-bit instruction set used by the R4000 series.
MIPS-IV: an upgrade of the MIPS III.

One of the key features of the MIPS architecture is the regular register set. It
consists of the 32-bit wide program counter (PC), and a bank of 32 generalpurpose registers called r0..r31, each of which is 32-bit wide. All generalpurpose registers can be used as the target registers and data sources for all
logical, arithmetical, memory access, and control-flow instructions. Only r0 is
special because it is internally hardwired to zero. Reading r0 always returns the
value 0x00000000, and a value written to r0 is ignored and lost.
Note that the MIPS architecture has no separate status register. Instead, the
conditional jump instructions test the contents of the general-purpose registers,
and error conditions are handled by the interrupt/trap mechanism. Two separate

32-bit registers called HI and LO are provided for the integer multiplication and
division instructions.
MIPS-I memory model and MMU
The original MIPS architecture defines three data-types: 32-bit word, 16-bit
halfword, and 8-bit bytes. The later variants add the 64-bit double-word and
floating-point data-types. All machine instructions are encoded as 32-bit words,
and most integer operations are performed on 32-bit integers. The analysis of
typical processor workloads indicated that byte load and store operations were
used frequently, which led the MIPS designers to organize the main memory as
a single flat array of bytes. Using 32-bit addresses, this results in a maximum
main memory of 4 Gigabytes.
However, based on the external 32-bit data bus, all data transfers between
memory and processor always use a full word, or 32-bits. Extra logic in the
processor and the memory is used to enable and to extract the corresponding
subset of the data when executing the half-word and byte load and store
instructions. All memory accesses have to be aligned for the corresponding
data-type: even addresses for half-word accesses, and multiples-of-four for
word accesses and instruction fetch. Misaligned memory accesses are detected
by the processor and the program is terminated.
Next to the 32-bit data bus and address-bus, the MIPS processors also generate
four byte-enable signals during each memory access, where a low level ('0')
indicates that the corresponding group of 8-bits is active during the transfer.
The MipsMemory simulation component in Hades implements this behaviour,
and also includes a simple MIPS disassembler to better visualize the execution
of MIPS programs.
One rather unusual feature of the MIPS architecture is the support of both
the big-endian and little-endianmemory models. That is, the ordering of bytes
inside a four-byte word can be selected by configuring the bus-interface of the
processor. While the TinyMips processor can be switched to use either the
little-endian or big-endian memory model, this feature has not been thoroughly
tested. Only the little-endian variant is used for the example applets, because
this is the default generated by our gcc cross-compiler.
To better support multitasking and multithreaded applications, all MIPS
processors use a memory management unit (MMU) to map virtual program
addresses to actual physical hardware addresses. The same mapping is used for
instruction fetch and the load/store memory accesses. The R2000 processor and
the later high-performance processors rely on a fully-featured MMU, which is
programmed via coprocessor 0 instructions. The low-end processors like the
R3000 rely on a much simpler scheme with the following static mapping from
virtual to physical addresses:

virtual address
range
0xc000.0000 0xffff.ffff
0xa000.0000 0xbfff.ffff

0x8000.0000 0x9fff.ffff
0x0000.0000 0x7fff.ffff

physical address name description


range (static
MMU)
0x0000.0000 - kseg2 1024 MBytes mapped cached
0x7fff.ffff
kernel segment
0x0000.0000 - kseg1 512 MBytes unmapped uncached
0x1fff.ffff
kernel segment. The default reset
address is 0xbfc0.0000, which is
mapped to physical address
0x1fc0.0000.
0x0000.0000 - kseg0 512 MBytes unmapped cached
0x1fff.ffff
kernel segment.
0x4000.0000 - kuseg 2048 MBytes user space, mapped
0xbfff.ffff
and cached.

Programs running in user mode can only access memory addresses in the "user
space" segment, while memory accesses in either of the kernel segments are
only allowed for programs in supervisor mode. This in turn is decided by a
status bit in the system coprocessor 0. However, typical embedded systems
often don't require multi-user support, and the software could run in privileged
mode all the time.
While the static mapping explained above is rather simple, no virtual address
remains unchanged by the mapping. This adds another layer of complexity
when trying to keep track of memory accesses during a simulation, because the
software operates with virtual addresses, while the physical addresses appear on
the address bus and are used to control the external memories and peripheral
devices. Therefore, the TinyMips processor can also be used with the memory
management switched off, so that virtual and physical addresses are the same.
This mode helps understanding the software running on the simulated
processor, and is used in all of the introductory applets.
MIPS-I instruction set
The MIPS instruction set can be divided into three main groups of instructions,
each of which has its own distinctive encoding:
I-Type (immediate)
| 31 26 | 25 21 | 20
| opcode | rs
| rt

16 | 15
| offset

0 |
|

J-Type (jump)
| 31 26 | 25
| opcode | instr_index
R-Type (register)
| 31 26 | 25 21 | 20

0 |
|
16 | 15

11 | 10

6 | 5

0 |

| opcode | rs

| rt

| rd

| sa

| function |

Here, the opcode field indicates the 6-bit main opcode, while the 5-bit
fields rt, rs and rd select the target register and one or two source registers for
the instruction:

The I-type or immediate instructions hold a 16-bit field; depending on


the instruction this is interpreted as an unsigned integer in the range
0..65535 or a sign-extended integer in the range -32768..32767.
The J-type or jump instructions reserve a 26-bit offset. This can be used
as a sign-extended offset for PC-relative branches, or the lowest 5 bits
are used to select one of the general-purpose registers.
The R-type or register instruction group includes all common
arithmetical and logical operations, but also the load- and store
instructions. The function field acts as a 6-bit sub-opcode that selects the
operation, while the sa field encodes the shift-amount used for the shiftoperations.

Please refer to the datasheets or the literature for a complete listing and
explanation of all instructions. You can also look at the source code of
the MIPS32 interpreter, which defines all opcodes and contains the actual
implementation of each instruction.
MIPS-I interrupts
TO BE WRITTEN...
The MIPS coprocessor concept
TO BE WRITTEN...
Register convention
As explained above, the MIPS hardware does not enforce a specific use for the
general-purpose registers (except for r0). However, the following register
convention has evolved as a standard for MIPS programming and is is used by
most tools, compilers, and operating systems:
Register
Name Description
number
0
zero Always returns 0
1
(assembler temporary) Reserved for use by assembler
at
2-3
v0 v1 Value returned by subroutine
4-7
a0-a3 (arguments) First four parameters for a subroutine
8-15
t0-t7 (temporaries) Subroutines can use without saving
24-25
t8-t9 (temporaries) Subroutines can use without saving

16-23

s0-s7 Subroutine register variables, must be restored before


returning
26-27
k0,k1 Reserved for use by interrupt/trap handler; may change
under your feet
28
Global pointer; used to access "static" or "extern"
gp
variables
29
Stack pointer
sp
30
s8/fp Frame pointer or ninth subroutine variable
31
Return address for subroutine
ra
These register names are also typically used by disassemblers and debuggers
instead of the raw register numbers. When a subroutine wants to use the
registers s0-s8 for its intermediate results, it must save the values on the stack
and restore those values before returning.

TinyMips overview
While pipelined execution is the focus of the original RISC concept, it is also
possible to design a slower non-pipelined implementation of the MIPS-I
architecture and instruction set. Similar to the well-knownSPIM simulator, the
TinyMips microprocessor in Hades implements such a simplified version of the
MIPS architecture. Unlike SPIM, Hades allows you to change the system
environment for the TinyMips and to add and simulate peripherial devices with
exact timing.
Conceptually, all instructions execute on TinyMips in one cycle. Of course,
designing this processor as real hardware would require a (rather inefficient)
multicycle implementation. On the other hand, the simulation model of a nonpipelined processor is straightforward and much less complex than a pipelined
processor. As a result of this, the simulation (unlike the real hardware) runs
much faster, and is well suited to demonstrate the software development for
embedded systems. Note that Hades also includes a simulation model of the
IDT R3051 processor, which models the full instruction pipeline and on-chip
caches.
To keep the TinyMips model as simple and regular as possible, it is based on
the original MIPS-I 32-bit instruction set. If one of the MIPS-II, -III or -IV
instructions is detected at runtime, the simulator will print a warning and enter
the exception handler.
The system interface of the TinyMips processor consists of the following:

nRESET: low-active reset input.


CLK: clock input, the next instruction is executed after a rising-edge.
DATA: 32-bit bidirectional data bus.

ADDR: 32-bit address bus.


NBEN: 4 low-active byte-enable signals for halfword- and bytetransfers.
nWR: low-active write-enable output.
nRD: low-active read-enable output.
ALE: address-latch enable output, indicates a valid address.

So far, the user-interface of the processor is rather plain. It consists of a single


memory editor that allows to watch and edit the contents of the on-chip
registers.

the general-purpose registers are mapped to addresses 0..31. Usually,


r29 is used as the stack pointer, r30 as the frame pointer, and r31 as the
subroutine return address.
the program counter is shown at address 32.
the HI multiplication register is shown at address 34.
the LO multiplication register is shown at address 35.
the MODE register is shown at address 39.
the other addresses are unused and show as XXXX.XXXX.

The bits in the MODE register control the behaviour of the simulation model.
You can change the values at runtime by typing a new value into the memory
editor. When you save the Hades design file with a TinyMips processor
instance, the current value of the MODE register is saved, and restored when
you load the design file. Currently, the following bits are implemented:

bit 4: 0=no MMU 1=use R3000-style static memory mapping


bit 2: 0=debugging off 1=trace memory accesses
bit 1: 0=debugging off 1=trace instruction execution

After a processor reset, the TinyMips uses the MIPS default virtual address of
0xbfc0.0000 to fetch the first instruction, which translates to physical address
0x1fc0.0000 after conversion by the MMU. However, thereset address can also
be specified explictly instead of relying on the default value given above. This
allows simplifying the demos and avoids an extra memory component at the
(rather odd) address range starting with 0x1fc0.0000. Most of the applets demos
disable the MMU and the programs are compiled to start at processor address
0x0000.0000. Note that the start address of a program can easily be specified
via the -Tflags when the GNU linker/loader is used.

Gnu binutils and gcc toolchain


The focus of the TinyMips demonstration applets on the Hades website is
system-simulation and hardware-software cosimulation. While software for

small 8-bit microcontrollers is still commonly written in assembly, high-level


languages are a prerequisite to develop the often very large system and
application software programs used on 32-bit microprocessor systems. We
chose the popular GNU toolchain for the software development, because the
corresponding tools support the MIPS architecture, are free, open-source, and
can be built on a variety of platforms. The gcc compiler also generates very
efficient code.
All software used in the applets was compiled for the MIPS via a crosscompiler running on a Linux host (our Hades development platform). You can
easily download and build the required tools on your own system. First, visit
the binutils project homepage and download the sourcecode. Naturally, you
might already have a precompiled version on your system, but you will need to
build the cross-toolchain that runs on your computer but generates code for the
(Tiny) MIPS architecture. Once you have built the tools, you can already use
the GNU assembler to write assembly code programs for the TinyMips.
Afterwards, visit one of the download servers of the GNU
project, http://gcc.gnu.org/mirrors.html, and download a release (stable) version
of the GCC compiler. Again, follow the instructions to build a cross-compiler
that runs on your own system but generates MIPS output.
If you are running Linux, you also try to download the following gccmips.tgz archive in tar.gz format; it includes gcc 2.7.2.3 and corresponding
binutils ready for Linux/x86 (Pentium,Athlon) hosts. Note that the tools expect
to be installed into a directory called /opt/mips. This path is configured into
the tools; you will have to build the tools yourself and supply the corresponding
-prefix option to change the base directory.
The gnu tools and website provide instructions about how to build the crosscompiler and binutils from the sources. Depending on your system, you might
also need additional tools (e.g. flex) to build the binutils or the gcc compiler. If
necessary, download, build, and install such tools before and then repeat the
binutils and gcc installation. For example, we used the following steps to build
the tools:
mkdir /opt/mips/sources
cd /opt/mips/sources
tar -xzvf /tmp/binutils-2.9.1.0.25.tar.gz
cd binutils-2.9.1.0.25
./configure --target=mips-idt-elf --prefix=/opt/mips
make
make install

Next, it might be necessary to create a few header files required for the
compiler. On Linux systems, it is often possible to just copy the native headers
files and reuse them for the crosscompiler. However, you might also want to
edit the files to exactly match your target system:
mkdir /opt/mips/mips-idt-elf/include

cd /opt/mips/mips-idt-elf/include
mkdir bits
mkdir sys
mkdir gnu
cp /usr/include/stdio.h .
cp /usr/include/bits/types.h bits/
cp /usr/include/bits/stdio_lim.h bits/
cp /usr/include/libio.h .
cp /usr/include/features.h .
cp /usr/include/_G_config.h .
cp /usr/include/bits/stdio.h bits/
cp /usr/include/sys/cdefs.h sys/
cp /usr/include/gnu/stubs.h gnu/

Finally, you can unpack, configure, and build gcc as a cross-compiler. We want
a compiler that generates MIPS code for the R-3000 series and use the ELF
binary-code format:
mkdir /opt/mips/mips-idt-elf/include
...
cd /opt/mips/sources
tar -xzvf /tmp/gcc-2.7.2.3.tar.gz
cd gcc-2.7.2.3
./configure --target=mips-idt-elf --with-gnu-as --with-gnu-ld
\
--prefix=/opt/mips
make LANGUAGES=c
make LANGUAGES=c install

Building the compiler might take a while. The tools are finally installed in the
/opt/mips/bin/ directory and can be run from there.
TO BE WRITTEN: Running the Hades disassembler Setting the memory
regions Debugging tips

TinyMips Applet Demos


Please click the following link(s) to go back to the live applet demonstrations
based on the TinyMips processor:

TinyMips applets overview


Sieve of Erathostenes
recursive functions
mult/div instructions
string operations
multiplexed LED display
graphical LCD display
UART and terminal
UART polling demo
interrupt demo

References and external links

MIPS corporation homepage


IDT corporation - R3041 processor documentation and datasheets
SPIM simulator
Computer Organization and Design by David Patterson and John L.
Hennessy (Morgan Kaufman ISBN: 1558604286)
See MIPS run by Dominic Sweetman (Morgan Kaufman, ISBN:
1558604103).

Impressumhttp://tams-www.informatik.uni-hamburg.de/applets/hades/webdemos/mips.html

You might also like