mirror of
https://github.com/johnwinans/rvalp.git
synced 2025-09-29 14:11:14 -04:00
Added the introduction chapter.
This commit is contained in:
parent
dfc426f4b6
commit
7181d823cf
@ -8,8 +8,6 @@
|
||||
note = {Editors Andrew Waterman and Krste Asanovi\'c}
|
||||
}
|
||||
|
||||
The RISC-V Instruction Set Manual
|
||||
Volume II: Privileged Architecture
|
||||
@manual{rvismv2:2017,
|
||||
title = "\href{https://github.com/riscv/riscv-isa-manual}{The RISC-V Instruction Set Manual, Volume II: Privileged Architecture, Document Version 1.10}",
|
||||
organization = "\href{https://riscv.org/}{RISC-V Foundation}",
|
||||
@ -18,6 +16,15 @@ Volume II: Privileged Architecture
|
||||
note = {Editors Andrew Waterman and Krste Asanovi\'c}
|
||||
}
|
||||
|
||||
|
||||
@manual{rvpsabi:2017,
|
||||
title = "\href{https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md}{RISC-V ELF psABI specification}",
|
||||
author = {Palmer Dabbelt and Stefan O'Rear and Kito Cheng and Andrew Waterman and Michael Clark and Alex Bradbury and David Horner and Max Nordlund and Karsten Merker},
|
||||
year = 2017
|
||||
|
||||
}
|
||||
|
||||
|
||||
@book{riscvreader:2017,
|
||||
title = {The RISC-V Reader: An Open Architecture Atlas},
|
||||
author = {David Patterson and Andrew Waterman},
|
||||
|
@ -77,7 +77,7 @@
|
||||
\clearpage
|
||||
\bibliography{bibliography}
|
||||
\addcontentsline{toc}{chapter}{Bibliography}
|
||||
%\nocite{*} % force all bib items to file appear even if not cited
|
||||
\nocite{*} % force all bib items to file appear even if not cited
|
||||
%\bibliographystyle{alpha}
|
||||
\bibliographystyle{ieeetr}
|
||||
|
||||
|
@ -11,3 +11,10 @@ Download your own copy of this book from github here:
|
||||
This document may contain inaccuracies or errors. The author provides no
|
||||
guarantee regarding the accuracy of this document's contents. If you
|
||||
discover that this document contains errors, please notify the author.
|
||||
|
||||
\enote{Need to say something about trademarks for things mentioned in this
|
||||
text}
|
||||
|
||||
|
||||
ARM\rtm{} is a registered trademark of ARM Limited in the
|
||||
EU and other countries.
|
||||
|
@ -12,7 +12,12 @@
|
||||
these two states are represented by the numbers one and zero or
|
||||
by the conditions true and false and can be stored in one bit}
|
||||
}
|
||||
|
||||
\newglossaryentry{hexadecimal}
|
||||
{
|
||||
name=hexadecimal,
|
||||
description={A base--16 numbering system whose digits are
|
||||
0123456789abcdef. The hex digits (hits) are not case--sensitive}
|
||||
}
|
||||
\newglossaryentry{bit}
|
||||
{
|
||||
name=bit,
|
||||
@ -101,18 +106,67 @@
|
||||
\newglossaryentry{register}
|
||||
{
|
||||
name={register},
|
||||
description={A unit of storage inside a CPU}
|
||||
description={A unit of storage inside a CPU with the capacity of XLEN bits}
|
||||
}
|
||||
\newglossaryentry{program}
|
||||
{
|
||||
name={program},
|
||||
description={A ordered list of one or more instructions}
|
||||
}
|
||||
\newglossaryentry{address}
|
||||
{
|
||||
name={address},
|
||||
description={A numeric value used to uniquely identify each byte of main memory}
|
||||
}
|
||||
\newglossaryentry{alignment}
|
||||
{
|
||||
name={alignment},
|
||||
description={Refers to a range of numeric values that begin
|
||||
at a multiple of some number. Primairly used when referring to
|
||||
a memory address. For example an alignment of two refers to one
|
||||
or more addresses starting at even address and continuing onto
|
||||
subsequent adjacent, increasing memory addresses}
|
||||
}
|
||||
\newglossaryentry{exception}
|
||||
{
|
||||
name={exception},
|
||||
description={An error encountered by the CPU while executing an instruction
|
||||
that can not be completed}
|
||||
}
|
||||
|
||||
\newglossaryentry{bigendian}
|
||||
{
|
||||
name={big endian},
|
||||
description={A number format where the most significant values are
|
||||
printed to the left of the lesser significant values. This is the
|
||||
method that everyone used to write decimal numbers every day}
|
||||
}
|
||||
\newglossaryentry{littleendian}
|
||||
{
|
||||
name={little endian},
|
||||
description={A number format where the least significant values are
|
||||
printed to the left of the more significant values. This is the
|
||||
opposite ordering that everyone learns in grade school when learning
|
||||
how to count. For example a big endian number written as ``1234''
|
||||
would be written in little endian form as ``4321''}
|
||||
}
|
||||
\newglossaryentry{rvddt}
|
||||
{
|
||||
name={rvddt},
|
||||
description={A RV32I simulator and debugging tool inspired by the
|
||||
simplicity of the Dynamic Debugging Tool (ddt) that was part of
|
||||
the CP/M operating system}
|
||||
}
|
||||
\newglossaryentry{mneumonic}
|
||||
{
|
||||
name={mneumonic},
|
||||
description={A method used to remember something. In the case of
|
||||
assembly language, each machine instruction is given a name
|
||||
so the programmer need not memorize the biary values of each
|
||||
machine instruction}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
\newacronym{hart}{hart}{Hardware Thread}
|
||||
\newacronym{msb}{MSB}{Most Significant Bit}
|
||||
\newacronym{lsb}{LSB}{Least Significant Bit}
|
||||
\newacronym{isa}{ISA}{Instruction Set Architecture}
|
||||
|
@ -6,19 +6,29 @@ CPU executes a continuous stream of instructions called a \gls{program}.
|
||||
These program instructions are expressed in what is called
|
||||
\gls{MachineLanguage}. Each machine language instruction is a binary value.
|
||||
In order to provide a method to simplify the management of machine language
|
||||
programs a symbolic mapping is provided where a mneumonic can be used to
|
||||
programs a symbolic mapping is provided where a \gls{mneumonic} can be used to
|
||||
specify each machine instruction and any of its parameters\ldots\ rather
|
||||
than mandate that programs be expressed as binary machine language
|
||||
instructions. The set of mneumonics, parameters and rules for specifying
|
||||
them is called an {\em Assembly Language}.
|
||||
than require that programs be expressed as a series of binary values.
|
||||
A set of mneumonics, parameters and rules for specifying their use for
|
||||
the purpose of programming a CPU is called an {\em Assembly Language}.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\section{The Digital Computer}
|
||||
|
||||
A digital computer is composed of storage systems (memory, disc drives,
|
||||
USB drives, etc.), a CPU (with one or more cores), input peripherals like
|
||||
a keyboard and mouse and output peripherals like a display or speakers.
|
||||
There are different types of computers. A {\em digital} computer is
|
||||
the type that most people think of when they hear the word {\em computer}.
|
||||
Other vareities of computers include {\em analog} and {\em quantum}.
|
||||
|
||||
A digital computer is one that that processes data that are represented
|
||||
using numeric values (digits), most commonly expressed in binary
|
||||
(ones and zeros) form.
|
||||
|
||||
This text focuses on digital computing.
|
||||
|
||||
A typical digital computer is composed of storage systems (memory, disc
|
||||
drives, USB drives, etc.), a CPU (with one or more cores), input peripherals
|
||||
(a keyboard and mouse) and output peripherals (display, printer or speakers.)
|
||||
|
||||
\subsection{Storage Systems}
|
||||
|
||||
@ -28,11 +38,13 @@ for the CPU.
|
||||
Types of computer storage can be classified into two categories.
|
||||
Volatile and non--volatile.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsubsection{Volatile Storage}
|
||||
|
||||
Volatile storage is characterized by the fact that it will lose its
|
||||
contents (forget) any time that it is powered off.
|
||||
|
||||
\index{register}
|
||||
One type of volatile storage is provided inside the CPU itself in
|
||||
small blocks called \glspl{register}. These registers are used to
|
||||
hold individual data values that can be manipulated by the instructions
|
||||
@ -55,6 +67,7 @@ dictate that the vast majority of volatile computer storage be provided
|
||||
in its main memory. As a result, optimizing the copying of data between
|
||||
the registers and main memory is a desirable trait of good programs.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsubsection{Non--Volatile Storage}
|
||||
|
||||
Non--volatile storage is characterized by the fact that it will {\em NOT}
|
||||
@ -66,14 +79,18 @@ drives. Prices can vary widely depending on size and transfer speeds.
|
||||
It is typical for a computer system's non--volatile storage to operate
|
||||
more slowly than its main memory.
|
||||
|
||||
This text is not particularly concerned with non--volatile storage.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{CPU}
|
||||
|
||||
\index{CPU}
|
||||
The \acrshort{cpu} is a collection of registers and circuitry designed
|
||||
to read data and instructions from the system storage. The instructions
|
||||
are used to instruct the CPU how to perform various mathamatical and
|
||||
logical operations on the data in its registers and write the results
|
||||
of those operations back into the system storage.
|
||||
to read data and instructions from the storage system. The instructions
|
||||
tell the CPU to perform various mathamatical and logical operations on
|
||||
the data in its registers and where to save the results of those operations.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{Peripherals}
|
||||
|
||||
A peripheral is a device that is not a CPU or main memory. They are
|
||||
@ -90,17 +107,24 @@ instructions are used to initiate, execute and/or synchronize data transfers.
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\section{Instruction Set Architecture}
|
||||
|
||||
The catalog of rules that describe all of the details of the instructions
|
||||
that a given CPU can execute is called its \acrfull{isa}.
|
||||
\index{ISA}
|
||||
The catalog of rules that describes the details of the instructions
|
||||
and features that a given CPU provides is called its \acrfull{isa}.
|
||||
|
||||
The RISC--V CPU ISA is defined as a set of modules. The purpose of
|
||||
An ISA is typically expressed in terms of the specific meaning of
|
||||
each binary instruction that a CPU can recognize and how it will
|
||||
process each one.
|
||||
|
||||
The RISC--V ISA is defined as a set of modules. The purpose of
|
||||
dividing the ISA into modules is to allow an implementor to select which
|
||||
features to incorporate into a CPU design.
|
||||
|
||||
Any given RISC--V implementation must provide one of the {\em base}
|
||||
modules and zero or more of the {\em extension} modules.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{RV Base Modules}
|
||||
\index{RV32I}
|
||||
The base modules are RV32I (32--bit general purpose),
|
||||
RV32E (32--bit embedded), RV64I (64--bit general purpose)
|
||||
and RV128I (128--bit general purpose).
|
||||
@ -109,9 +133,18 @@ These base modules provide the minimal functional set of integer operations
|
||||
needed to execute an application. The differing bit--widths address
|
||||
the needs of different main--memory sizes.
|
||||
|
||||
This text primairly focuses on the RV32I base module and how to program it.
|
||||
|
||||
|
||||
\subsection{Extension Modules}
|
||||
|
||||
\index{RV32M}
|
||||
\index{RV32A}
|
||||
\index{RV32F}
|
||||
\index{RV32D}
|
||||
\index{RV32Q}
|
||||
\index{RV32C}
|
||||
\index{RV32G}
|
||||
RISC-V extension modules may be included by an implementor interested
|
||||
in optimizing a design for one or more purposes.
|
||||
|
||||
@ -120,7 +153,279 @@ F (32--bit floating point), D (64--bit floating point),
|
||||
Q (128--bit floating point), C (compressed size instructions) and others.
|
||||
|
||||
The extension name {\em G} is used to represent the combined set of IMAFD
|
||||
extensions as is expected to be a common combination.
|
||||
extensions as it is expected to be a common combination.
|
||||
|
||||
|
||||
This text discusses programming the RV32IM ISA using assembly language.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\section{An Example Computer}
|
||||
|
||||
\enote{Need a block diagram and description of the virtual machine
|
||||
that is used in this text.}%
|
||||
The machine used to execute the programs presented in this text
|
||||
has one RV32I CPU with 32 registers, one \acrshort{hart}
|
||||
(analogous to what is called a {\em core} on other CPUs such as an ARM)
|
||||
and 65536 bytes of memory.
|
||||
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\section{An Example Program}
|
||||
|
||||
To observe the operation of our example computer an RV32I simulator
|
||||
will be used that will print a message describing the status of the
|
||||
CPU and the instructions that it executes as it goes along.
|
||||
|
||||
The process of executing an instruction is called the
|
||||
\index{instruction cycle} instruction cycle and it is comprised
|
||||
of an {\em instruction fetch} and an {\em instruction execute} phase.
|
||||
|
||||
The status of the CPU is entirely embodied in the data values that
|
||||
are stored in its registers at any moment in time. The simulator
|
||||
can print all of the register values before it executes an instruction
|
||||
for reference.
|
||||
|
||||
When an instruction is executed the simulator can print a message
|
||||
describing where in main memory it came from, its numeric machine code
|
||||
value, its mneumonic, a description of any associated parameters,
|
||||
the values of those parameters and then carry out the operation as
|
||||
defined by the ISA.
|
||||
|
||||
For this to work, the instructions to be executed will have been
|
||||
previously stored in a list in the main memory and any parameters that
|
||||
an instruction specifies will either be part of the instruction itself
|
||||
or read from (or stored into) one or more of the registers.
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{Instruction Fetch}
|
||||
|
||||
In order to {\em fetch} an instruction from the main memory the CPU
|
||||
must have a method to identify which instruction should be fetched and
|
||||
a method to fetch it.
|
||||
|
||||
To make this possible the main memory is broken up into small blocks
|
||||
called \gls{byte}s that are each given a unique identifying number
|
||||
called an \gls{address}. The process of identifying which instruction
|
||||
to fetch is therefore a matter of knowing what address it is stored in.
|
||||
|
||||
A byte is comprised of eight binary digits called \gls{bit}s.
|
||||
|
||||
Every possible instruction that the RV32I can execute contains
|
||||
exactly 32 bits. Therefore each instruction must be stored in
|
||||
four bytes of the main memory.
|
||||
|
||||
To simplify the hardware, each instruction
|
||||
must be placed into four adjacent bytes whose numeric address sequence
|
||||
begins with a multiple four. For example, an instruction might be
|
||||
located in bytes 12, 13, 14 and 15 (but not in 15, 16, 17 and 18
|
||||
nor 8, 207, 5, and 1073\ldots).
|
||||
|
||||
This sort of addressing requirement is common and is referred to as
|
||||
\gls{alignment}. An aligned instruction begins at a memory address
|
||||
that is a multiple of four. An {\em unaligned} instruction would
|
||||
be one beginning at any other address and is {\em illegal}.
|
||||
|
||||
An attempt to fetch an instruction from an unaligned address
|
||||
will result in an error referred to as an alignment {\em \gls{exception}}.
|
||||
This and other exceptions cause the CPU to stop executing the
|
||||
curent instruction and start executing a different set of instructions
|
||||
that are prepared to handle the problem. Often an exception is
|
||||
handled by completely stopping the program in a way that is commonly
|
||||
refered to as a system or application {\em crash}.
|
||||
|
||||
Given a properly aligned instruction address, the CPU can request
|
||||
that the main memory locate and deliver the values of the four bytes
|
||||
in the address sequence to the CPU using what is called a memory
|
||||
read operation. Some systems can deliver four (or more) bytes at the
|
||||
same time while others might only be capable of delivering one or
|
||||
two bytes at a time. These differences in hardware typically impact the
|
||||
cost and performance of a system.\footnote{The design and implementation
|
||||
choices that determine how any given system operates are part of what is
|
||||
called a system's {\em organization} and is beyond the scope of this text.
|
||||
See~\cite{codriscv:2017} for more information on computer organization.}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{Instruction Execute}
|
||||
|
||||
Once an instruction has been fetched by the CPU, it can be executed.
|
||||
|
||||
Typical instructions do things like add a number to the value
|
||||
currently stored in one of the registers or store the contents of a
|
||||
register into the main memory at some given address.
|
||||
|
||||
Also part of every instruction is a notion of what should be done next.
|
||||
|
||||
Most of the time an instruction will be complete by indicating that
|
||||
the CPU should proceed to fetch and execute the instruction at the next
|
||||
larger main memory address.
|
||||
|
||||
Some instructions can specify that the CPU proceed to execute an
|
||||
instruction at an address other than the one that follows itself.
|
||||
This class of instructions have names like {\em jump} and {\em branch}
|
||||
and are available in a variety of different styles.
|
||||
|
||||
The RV ISA uses the word {\em jump} to refer to an {\em unconditional}
|
||||
change in the sequential processing of instructions and the word
|
||||
{\em branch} to refer to a {\em conditional} change.
|
||||
|
||||
For example, a (conditional) branch instruction might instruct the CPU
|
||||
to proceed to the instruction at the next main memory address if the value
|
||||
in register number 8 is currently less than the value in register number
|
||||
24 {\em but otherwise} proceed to an instruction at a different address
|
||||
when it is not. This type of instruction can therefore result in having
|
||||
one of two different actions pending the resulting {\em condition} of
|
||||
the comparison.\footnote{This is the fundamental method used by a CPU
|
||||
to make decisions.}
|
||||
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{A Sample Program Source Listing}
|
||||
|
||||
A simple program that illustrates how this text presents
|
||||
program source code is seen in \listingRef{zero4regs.S}.
|
||||
This program will place a zero in each of the 4 registers
|
||||
named x28, x29, x30 and x31.
|
||||
|
||||
\listing{zero4regs.S}{Setting four registers to zero.}
|
||||
|
||||
This program listing illustrates a number of things:
|
||||
\begin{itemize}
|
||||
\item Listings are identified by the name of the file within which
|
||||
they are stored. This listing is from a file named: \verb@zero4regs.S@.
|
||||
\item The assembly language programs discussed in this text will be saved
|
||||
in files that end with: \verb@.S@ (Alternately you can use \verb@.sx@
|
||||
on systems that don't understand the difference between upper and
|
||||
lowercase letters.\footnote{The author of this text prefers to avoid
|
||||
using such systems.})
|
||||
\item A description of the listing's purpose appears under the name of the
|
||||
file. The description of \listingRef{zero4regs.S} is
|
||||
{\em Setting four registers to zero.}
|
||||
\item The lines of the listing are numberd on the left margin for
|
||||
easy reference.
|
||||
\item An assembly program consists of lines of plain text.
|
||||
\item The lines that start with a dot `.' (on lines 1, 2 and 3) are
|
||||
called {\em assembler directives} as they tell the assembler itself
|
||||
how we want it to translate the following {\em assembly language instructions}
|
||||
into {\em machine language instructions.} There are as many
|
||||
(if not more) assembler directives than there are valid
|
||||
instructions!
|
||||
\item Line 4 shows a {\em label} named {\em \_start}. The colon
|
||||
at the end is the indicator to the assembler that causes it to
|
||||
recognize the preceeding characters as a label.
|
||||
\item Lines 5-8 are the four assembly language instructions that
|
||||
make up the program. Each instruction in this program
|
||||
consists of four {\em fields}. (Different instructions can have
|
||||
a different number of fields.) The fields on line 5 are:
|
||||
|
||||
\begin{itemize}
|
||||
\item [addi] The instruction mneumonic. It indicated th eoperation the
|
||||
CPU will perform.
|
||||
\item [x28] The {\em destination} register that will receive the
|
||||
sum when the {\em addi} instruction is finished. The names of
|
||||
the 32 registers are expressed as x0 -- x31.
|
||||
\item [x0] One of the addends of the sum operation. The x0 register
|
||||
will always contain the vlaue zero. It can never be changed.
|
||||
\item [0] The second addend is the number zero.
|
||||
\item [\# set \ldots] Any text anywhere in a RISC-V assembly language
|
||||
program that starts with the pound--sign is ignored by the assembler.
|
||||
They are used to place a {\em comment} in the program to help
|
||||
the reader better understand the motive of the programmer.
|
||||
\end{itemize}
|
||||
|
||||
\item The RV ISAs do not provide an operation that will simply
|
||||
set a register to a numeric value. To accomplish our goal this
|
||||
program will add zero to zero and place the sum in in each of the
|
||||
foutr registers.
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\subsection{Running a Program With rvddt}
|
||||
\index{rvddt}
|
||||
|
||||
To illustrate what a CPU does when it executes instructions this text
|
||||
will use a simulator that shows sequence of events and the binary values
|
||||
involved. \listingRef{zero4regs.out} shows the operation of the four
|
||||
{\em addi} instructions from \listingRef{zero4regs.S} when executed using the
|
||||
\gls{rvddt} simulator.\footnote{The {\em rvddt} application was written to
|
||||
generate the listings for this text. It is quite similar to the {\em spike}
|
||||
simulator that this author had trouble getting to do what was desired.
|
||||
Given the simplicity of the RV32I ISA, rvddt required only 1500
|
||||
lines of C++ and was written in one (long) afternoon. Doing so was an
|
||||
incredibly useful task as it revealed a few misunderstandings of some of
|
||||
the RV32I instructions.}
|
||||
|
||||
\listing{zero4regs.out}{Running a program with the rvddt simulator}
|
||||
|
||||
\begin{itemize}
|
||||
\item [$\ell$ 1] This listing includes the command-line that shows how the simulator
|
||||
was executed to load a file containing the machine instructions (aka
|
||||
machine code) from the assembler.
|
||||
\item [$\ell$ 2] A message from the simulator indicating that it loaded the machine
|
||||
code into simulated memory at address 0.
|
||||
\item [$\ell$ 3] This line shows the prompt from the debugger and the command
|
||||
\verb@t4@ that the user entered to request that the simulator trace
|
||||
the execution of four extructions.
|
||||
\item [$\ell$ 4-8] Prior to executing the first instruction, the state of the
|
||||
CPU registers is displayed.
|
||||
\item [$\ell$ 4] The values in registers 0, 1, 2, 3, 4, 5, 6 and 7 are printed
|
||||
from left to right in \gls{bigendian}, \gls{hexadecimal} form.
|
||||
The dash `\verb@-@' character in the middle of the line is a reference
|
||||
to make it easier to visually navigate across the line without being
|
||||
forced to count the values from the far left when seeking the value
|
||||
of, say, x5.
|
||||
\item [$\ell$ 5-7] The values of registers 8--31 are printed.
|
||||
\item [$\ell$ 8] The {\em program counter} (\reg{pc}) register is printed.
|
||||
It contains the address of the instruction that the CPU will execute.
|
||||
After each instruction, the \reg{pc} will either advance four bytes
|
||||
ahead or be set to another value by a branch instruction as discussed above.
|
||||
\item [$\ell$ 9] A four--byte instruction is fetched from memory at the address
|
||||
in the \reg{pc} register, is decoded and printed. From left to right
|
||||
the fields shown on this line are:
|
||||
|
||||
\begin{itemize}
|
||||
|
||||
\item [00000000] The memory address from which the instruction was
|
||||
fetched. This address is displayed in \gls{bigendian},
|
||||
\gls{hexadecimal} form.
|
||||
\item [00000e13] The machine code of the instruction displayed in
|
||||
\gls{bigendian}, \gls{hexadecimal} form.
|
||||
\item [addi] The mneumonic for the machine instruction.
|
||||
\item [x28] The \reg{rd} field of the addi instruction.
|
||||
\item [x0] The \reg{rs1} field of the addi instruction that
|
||||
holds one of the two addends of the operation.
|
||||
\item [0] The \reg{imm} field of the addi instruction that
|
||||
holds the second of the two addends of the operation.
|
||||
\item [\# \ldots] A simulator--generated comment that exaplains
|
||||
what the instruction is doing. For this instruction it indicates
|
||||
that \reg{x28} will have the value zero stored into it as a result
|
||||
of performing the addition: $0+0$.
|
||||
\end{itemize}
|
||||
|
||||
\item [$\ell$ 10-14] These lines are printed as the prelude while tracing the
|
||||
second instruction. Lines 7 and 13 show that \reg{x28} has changed
|
||||
from \verb@f0f0f0f0@ to \verb@00000000@ as a result of executing the
|
||||
first instruction and lines 8 and 14 show that the \reg{pc} has
|
||||
advanced from zero (the location of the first instruction) to
|
||||
four, where the second instruction will be fetched. None of the
|
||||
rest of the registers have changed values.
|
||||
\item [$\ell$ 15] The second instruction decoded executed and described.
|
||||
This time register \reg{x29} will be assigned a value.
|
||||
\item [$\ell$ 16-27] The third and fourth instructions are traced.
|
||||
\item [$\ell$ 28] Tracing has completed. The simulator prints its prompt
|
||||
and the user enters the `r' command to see the register state
|
||||
after the fourth instruction has completed executing.
|
||||
\item [$\ell$ 29-33] Following the fourth instruction it can be observed
|
||||
that registers \reg{x28}, \reg{x29}, \reg{x30} and \reg{x31}
|
||||
have been set to zero and that the \reg{pc} has advanced from
|
||||
zero to four, then eight, then 12 (the hex value for 12 is c)
|
||||
and then to 16 (which, in hex, is 10).
|
||||
\item [$\ell$ 34] The simulator exit command `x' is entered by the user and
|
||||
the terminal displays the shell prompt.
|
||||
|
||||
\end{itemize}
|
||||
|
8
book/intro/zero4regs.S
Normal file
8
book/intro/zero4regs.S
Normal file
@ -0,0 +1,8 @@
|
||||
.text # put this into the text section
|
||||
.align 2 # align to 2^2
|
||||
.globl _start
|
||||
_start:
|
||||
addi x28, x0, 0 # set register x28 to zero
|
||||
addi x29, x0, 0 # set register x29 to zero
|
||||
addi x30, x0, 0 # set register x30 to zero
|
||||
addi x31, x0, 0 # set register x31 to zero
|
35
book/intro/zero4regs.out
Normal file
35
book/intro/zero4regs.out
Normal file
@ -0,0 +1,35 @@
|
||||
[winans@w510 src]$ ./rvddt -f ../t1/load4regs.bin
|
||||
Loading '../t1/load4regs.bin' to 0x0
|
||||
ddt> t4
|
||||
x0: 00000000 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
x8: f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
x16: f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
x24: f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
pc: 00000000
|
||||
00000000: 00000e13 addi x28, x0, 0 # x28 = 0x00000000 = 0x00000000 + 0x00000000
|
||||
x0: 00000000 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
x8: f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
x16: f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
x24: f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0-00000000 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
pc: 00000004
|
||||
00000004: 00000e93 addi x29, x0, 0 # x29 = 0x00000000 = 0x00000000 + 0x00000000
|
||||
x0: 00000000 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
x8: f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
x16: f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
x24: f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0-00000000 00000000 f0f0f0f0 f0f0f0f0
|
||||
pc: 00000008
|
||||
00000008: 00000f13 addi x30, x0, 0 # x30 = 0x00000000 = 0x00000000 + 0x00000000
|
||||
x0: 00000000 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
x8: f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
x16: f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
x24: f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0-00000000 00000000 00000000 f0f0f0f0
|
||||
pc: 0000000c
|
||||
0000000c: 00000f93 addi x31, x0, 0 # x31 = 0x00000000 = 0x00000000 + 0x00000000
|
||||
ddt> r
|
||||
x0: 00000000 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
x8: f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
x16: f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0-f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
|
||||
x24: f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0-00000000 00000000 00000000 00000000
|
||||
pc: 00000010
|
||||
ddt> x
|
||||
[winans@w510 src]$
|
@ -119,8 +119,8 @@
|
||||
% \label{Code:#1} %
|
||||
% \VerbatimInput[frame=single,numbers=left,numbersep=2mm,framesep=3mm,label={#2}]{#1}}
|
||||
|
||||
\newcommand{\theListingFontFamily}{\ttfamily\small}
|
||||
%\newcommand{\theListingFontFamily}{\ttfamily\footnotesize}
|
||||
%\newcommand{\theListingFontFamily}{\ttfamily\small}
|
||||
\newcommand{\theListingFontFamily}{\ttfamily\footnotesize}
|
||||
%\newcommand{\theListingFontFamily}{\ttfamily\scriptsize}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
Loading…
x
Reference in New Issue
Block a user