mirror of
https://github.com/johnwinans/rvalp.git
synced 2025-09-30 14:40:39 -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}
|
note = {Editors Andrew Waterman and Krste Asanovi\'c}
|
||||||
}
|
}
|
||||||
|
|
||||||
The RISC-V Instruction Set Manual
|
|
||||||
Volume II: Privileged Architecture
|
|
||||||
@manual{rvismv2:2017,
|
@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}",
|
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}",
|
organization = "\href{https://riscv.org/}{RISC-V Foundation}",
|
||||||
@ -18,6 +16,15 @@ Volume II: Privileged Architecture
|
|||||||
note = {Editors Andrew Waterman and Krste Asanovi\'c}
|
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,
|
@book{riscvreader:2017,
|
||||||
title = {The RISC-V Reader: An Open Architecture Atlas},
|
title = {The RISC-V Reader: An Open Architecture Atlas},
|
||||||
author = {David Patterson and Andrew Waterman},
|
author = {David Patterson and Andrew Waterman},
|
||||||
|
@ -77,7 +77,7 @@
|
|||||||
\clearpage
|
\clearpage
|
||||||
\bibliography{bibliography}
|
\bibliography{bibliography}
|
||||||
\addcontentsline{toc}{chapter}{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{alpha}
|
||||||
\bibliographystyle{ieeetr}
|
\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
|
This document may contain inaccuracies or errors. The author provides no
|
||||||
guarantee regarding the accuracy of this document's contents. If you
|
guarantee regarding the accuracy of this document's contents. If you
|
||||||
discover that this document contains errors, please notify the author.
|
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
|
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}
|
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}
|
\newglossaryentry{bit}
|
||||||
{
|
{
|
||||||
name=bit,
|
name=bit,
|
||||||
@ -101,18 +106,67 @@
|
|||||||
\newglossaryentry{register}
|
\newglossaryentry{register}
|
||||||
{
|
{
|
||||||
name={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}
|
\newglossaryentry{program}
|
||||||
{
|
{
|
||||||
name={program},
|
name={program},
|
||||||
description={A ordered list of one or more instructions}
|
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{msb}{MSB}{Most Significant Bit}
|
||||||
\newacronym{lsb}{LSB}{Least Significant Bit}
|
\newacronym{lsb}{LSB}{Least Significant Bit}
|
||||||
\newacronym{isa}{ISA}{Instruction Set Architecture}
|
\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
|
These program instructions are expressed in what is called
|
||||||
\gls{MachineLanguage}. Each machine language instruction is a binary value.
|
\gls{MachineLanguage}. Each machine language instruction is a binary value.
|
||||||
In order to provide a method to simplify the management of machine language
|
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
|
specify each machine instruction and any of its parameters\ldots\ rather
|
||||||
than mandate that programs be expressed as binary machine language
|
than require that programs be expressed as a series of binary values.
|
||||||
instructions. The set of mneumonics, parameters and rules for specifying
|
A set of mneumonics, parameters and rules for specifying their use for
|
||||||
them is called an {\em Assembly Language}.
|
the purpose of programming a CPU is called an {\em Assembly Language}.
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\section{The Digital Computer}
|
\section{The Digital Computer}
|
||||||
|
|
||||||
A digital computer is composed of storage systems (memory, disc drives,
|
There are different types of computers. A {\em digital} computer is
|
||||||
USB drives, etc.), a CPU (with one or more cores), input peripherals like
|
the type that most people think of when they hear the word {\em computer}.
|
||||||
a keyboard and mouse and output peripherals like a display or speakers.
|
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}
|
\subsection{Storage Systems}
|
||||||
|
|
||||||
@ -28,11 +38,13 @@ for the CPU.
|
|||||||
Types of computer storage can be classified into two categories.
|
Types of computer storage can be classified into two categories.
|
||||||
Volatile and non--volatile.
|
Volatile and non--volatile.
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\subsubsection{Volatile Storage}
|
\subsubsection{Volatile Storage}
|
||||||
|
|
||||||
Volatile storage is characterized by the fact that it will lose its
|
Volatile storage is characterized by the fact that it will lose its
|
||||||
contents (forget) any time that it is powered off.
|
contents (forget) any time that it is powered off.
|
||||||
|
|
||||||
|
\index{register}
|
||||||
One type of volatile storage is provided inside the CPU itself in
|
One type of volatile storage is provided inside the CPU itself in
|
||||||
small blocks called \glspl{register}. These registers are used to
|
small blocks called \glspl{register}. These registers are used to
|
||||||
hold individual data values that can be manipulated by the instructions
|
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
|
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.
|
the registers and main memory is a desirable trait of good programs.
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\subsubsection{Non--Volatile Storage}
|
\subsubsection{Non--Volatile Storage}
|
||||||
|
|
||||||
Non--volatile storage is characterized by the fact that it will {\em NOT}
|
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
|
It is typical for a computer system's non--volatile storage to operate
|
||||||
more slowly than its main memory.
|
more slowly than its main memory.
|
||||||
|
|
||||||
|
This text is not particularly concerned with non--volatile storage.
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\subsection{CPU}
|
\subsection{CPU}
|
||||||
|
|
||||||
|
\index{CPU}
|
||||||
The \acrshort{cpu} is a collection of registers and circuitry designed
|
The \acrshort{cpu} is a collection of registers and circuitry designed
|
||||||
to read data and instructions from the system storage. The instructions
|
to read data and instructions from the storage system. The instructions
|
||||||
are used to instruct the CPU how to perform various mathamatical and
|
tell the CPU to perform various mathamatical and logical operations on
|
||||||
logical operations on the data in its registers and write the results
|
the data in its registers and where to save the results of those operations.
|
||||||
of those operations back into the system storage.
|
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\subsection{Peripherals}
|
\subsection{Peripherals}
|
||||||
|
|
||||||
A peripheral is a device that is not a CPU or main memory. They are
|
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}
|
\section{Instruction Set Architecture}
|
||||||
|
|
||||||
The catalog of rules that describe all of the details of the instructions
|
\index{ISA}
|
||||||
that a given CPU can execute is called its \acrfull{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
|
dividing the ISA into modules is to allow an implementor to select which
|
||||||
features to incorporate into a CPU design.
|
features to incorporate into a CPU design.
|
||||||
|
|
||||||
Any given RISC--V implementation must provide one of the {\em base}
|
Any given RISC--V implementation must provide one of the {\em base}
|
||||||
modules and zero or more of the {\em extension} modules.
|
modules and zero or more of the {\em extension} modules.
|
||||||
|
|
||||||
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\subsection{RV Base Modules}
|
\subsection{RV Base Modules}
|
||||||
|
\index{RV32I}
|
||||||
The base modules are RV32I (32--bit general purpose),
|
The base modules are RV32I (32--bit general purpose),
|
||||||
RV32E (32--bit embedded), RV64I (64--bit general purpose)
|
RV32E (32--bit embedded), RV64I (64--bit general purpose)
|
||||||
and RV128I (128--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
|
needed to execute an application. The differing bit--widths address
|
||||||
the needs of different main--memory sizes.
|
the needs of different main--memory sizes.
|
||||||
|
|
||||||
|
This text primairly focuses on the RV32I base module and how to program it.
|
||||||
|
|
||||||
|
|
||||||
\subsection{Extension Modules}
|
\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
|
RISC-V extension modules may be included by an implementor interested
|
||||||
in optimizing a design for one or more purposes.
|
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.
|
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
|
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} %
|
% \label{Code:#1} %
|
||||||
% \VerbatimInput[frame=single,numbers=left,numbersep=2mm,framesep=3mm,label={#2}]{#1}}
|
% \VerbatimInput[frame=single,numbers=left,numbersep=2mm,framesep=3mm,label={#2}]{#1}}
|
||||||
|
|
||||||
\newcommand{\theListingFontFamily}{\ttfamily\small}
|
%\newcommand{\theListingFontFamily}{\ttfamily\small}
|
||||||
%\newcommand{\theListingFontFamily}{\ttfamily\footnotesize}
|
\newcommand{\theListingFontFamily}{\ttfamily\footnotesize}
|
||||||
%\newcommand{\theListingFontFamily}{\ttfamily\scriptsize}
|
%\newcommand{\theListingFontFamily}{\ttfamily\scriptsize}
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
Loading…
x
Reference in New Issue
Block a user