\documentclass{gqtekspec}
|
\documentclass{gqtekspec}
|
\usepackage{import}
|
\usepackage{import}
|
\usepackage{bytefield}
|
\usepackage{bytefield}
|
\project{CMod S6 SoC}
|
\project{CMod S6 SoC}
|
\title{Specification}
|
\title{Specification}
|
\author{Dan Gisselquist, Ph.D.}
|
\author{Dan Gisselquist, Ph.D.}
|
\email{dgisselq (at) opencores.org}
|
\email{dgisselq (at) opencores.org}
|
\revision{Rev.~0.2}
|
\revision{Rev.~0.2}
|
\begin{document}
|
\begin{document}
|
\pagestyle{gqtekspecplain}
|
\pagestyle{gqtekspecplain}
|
\titlepage
|
\titlepage
|
\begin{license}
|
\begin{license}
|
Copyright (C) \theyear\today, Gisselquist Technology, LLC
|
Copyright (C) \theyear\today, Gisselquist Technology, LLC
|
|
|
This project is free software (firmware): you can redistribute it and/or
|
This project is free software (firmware): you can redistribute it and/or
|
modify it under the terms of the GNU General Public License as published
|
modify it under the terms of the GNU General Public License as published
|
by the Free Software Foundation, either version 3 of the License, or (at
|
by the Free Software Foundation, either version 3 of the License, or (at
|
your option) any later version.
|
your option) any later version.
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
|
ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
for more details.
|
for more details.
|
|
|
You should have received a copy of the GNU General Public License along
|
You should have received a copy of the GNU General Public License along
|
with this program. If not, see \texttt{http://www.gnu.org/licenses/} for a copy.
|
with this program. If not, see \texttt{http://www.gnu.org/licenses/} for a copy.
|
\end{license}
|
\end{license}
|
\begin{revisionhistory}
|
\begin{revisionhistory}
|
0.2 & 5/14/2016 & Gisselquist & Updated Draft, still not complete \\\hline
|
0.2 & 5/14/2016 & Gisselquist & Updated Draft, still not complete \\\hline
|
0.1 & 4/22/2016 & Gisselquist & First Draft \\\hline
|
0.1 & 4/22/2016 & Gisselquist & First Draft \\\hline
|
\end{revisionhistory}
|
\end{revisionhistory}
|
% Revision History
|
% Revision History
|
% Table of Contents, named Contents
|
% Table of Contents, named Contents
|
\tableofcontents
|
\tableofcontents
|
\listoffigures
|
\listoffigures
|
\listoftables
|
\listoftables
|
\begin{preface}
|
\begin{preface}
|
The Zip CPU was built with the express purpose of being an area optimized,
|
The Zip CPU was built with the express purpose of being an area optimized,
|
32--bit FPGA soft processor.
|
32--bit FPGA soft processor.
|
|
|
The S6~SoC is designed to prove that the ZipCPU has met this goal.
|
The S6~SoC is designed to prove that the ZipCPU has met this goal.
|
\end{preface}
|
\end{preface}
|
|
|
\chapter{Introduction}
|
\chapter{Introduction}
|
\pagenumbering{arabic}
|
\pagenumbering{arabic}
|
\setcounter{page}{1}
|
\setcounter{page}{1}
|
|
|
This project is ongoing. Any and all files, to include this one, are subject
|
This project is ongoing. Any and all files, to include this one, are subject
|
to change without notice.
|
to change without notice.
|
|
|
This project comes from my desire to demonstrate the Zip CPU's utility in a
|
This project comes from my desire to demonstrate the Zip CPU's utility in a
|
challenging environment. The CMod~S6 board fits this role nicely.
|
challenging environment. The CMod~S6 board fits this role nicely.
|
\begin{enumerate}
|
\begin{enumerate}
|
\item The Spartan--6 LX4 FPGA is very limited in its resources:
|
\item The Spartan--6 LX4 FPGA is very limited in its resources:
|
It only has 2,400 look--up tables (LUTs), and can only support
|
It only has 2,400 look--up tables (LUTs), and can only support
|
a 4,096~Word RAM memory (16 kB).
|
a 4,096~Word RAM memory (16 kB).
|
\item With only 4kW RAM, the majority of any program will need to be placed into
|
\item With only 4kW RAM, the majority of any program will need to be placed into
|
and run from flash. (The chip will actually support more, just not
|
and run from flash. (The chip will actually support more, just not
|
8k RAM.)
|
8k RAM.)
|
\item While the chip has enough area for the CPU, it doesn't have enough area
|
\item While the chip has enough area for the CPU, it doesn't have enough area
|
to include the CPU and \ldots write access to the flash, debug access,
|
to include the CPU and \ldots write access to the flash, debug access,
|
wishbone command access from the UART, pipelined CPU operations, and
|
wishbone command access from the UART, pipelined CPU operations, and
|
more. Other solutions will need to be found.
|
more. Other solutions will need to be found.
|
\end{enumerate}
|
\end{enumerate}
|
|
|
Of course, if someone just wants the functionality of a small, cheap, CPU,
|
Of course, if someone just wants the functionality of a small, cheap, CPU,
|
this project does not fit that role very well. While the S6 is not very
|
this project does not fit that role very well. While the S6 is not very
|
expensive, it is still an order of magnitude greater than it's CPU competitors
|
expensive, it is still an order of magnitude greater than it's CPU competitors
|
in price. This includes such CPU's as the Raspberry Pi Zero, or even the
|
in price. This includes such CPU's as the Raspberry Pi Zero, or even the
|
TeensyLC.
|
TeensyLC.
|
|
|
If, on the other hand, what you want is a small, cheap, CPU that can be embedded
|
If, on the other hand, what you want is a small, cheap, CPU that can be embedded
|
within an FPGA without using too much of the FPGA's resources, this project
|
within an FPGA without using too much of the FPGA's resources, this project
|
will demonstrate that utility and possibility. Alternatively, if you wish to
|
will demonstrate that utility and possibility. Alternatively, if you wish to
|
study how to get a CPU to work in a small, constrained environment, this project
|
study how to get a CPU to work in a small, constrained environment, this project
|
may be what you are looking for.
|
may be what you are looking for.
|
|
|
\chapter{Architecture}
|
\chapter{Architecture}
|
Fig.~\ref{fig:architecture}
|
Fig.~\ref{fig:architecture}
|
\begin{figure}\begin{center}
|
\begin{figure}\begin{center}
|
\includegraphics[width=5in]{../gfx/s6bones.eps}
|
\includegraphics[width=5in]{../gfx/s6bones.eps}
|
\caption{CMod S6 SoC Architecture: ZipCPU and
|
\caption{CMod S6 SoC Architecture: ZipCPU and
|
Peripherals}\label{fig:architecture}
|
Peripherals}\label{fig:architecture}
|
\end{center}\end{figure}
|
\end{center}\end{figure}
|
shows the basic internal architecture of the S6~SoC. In summary, it consists of a CPU
|
shows the basic internal architecture of the S6~SoC. In summary, it consists of a CPU
|
coupled with a variety of peripherals for the purpose of controlling the
|
coupled with a variety of peripherals for the purpose of controlling the
|
external peripherals of the S6: flash, LEDs, buttons, and GPIO. External
|
external peripherals of the S6: flash, LEDs, buttons, and GPIO. External
|
devices may also be added on, such as an audio device, an external serial
|
devices may also be added on, such as an audio device, an external serial
|
port, an external keypad, and an external display. All of these devices
|
port, an external keypad, and an external display. All of these devices
|
are then available for the CPU to interact with.
|
are then available for the CPU to interact with.
|
|
|
If you are familiar with the Zip CPU, you'll notice this architecture provides
|
If you are familiar with the Zip CPU, you'll notice this architecture provides
|
no access to the Zip CPU debug port. There simply wasn't enough room on the
|
no access to the Zip CPU debug port. There simply wasn't enough room on the
|
device. Debugging the ZipCPU will instead need to take place via other means,
|
device. Debugging the ZipCPU will instead need to take place via other means,
|
such as dumping all registers and/or memory to the serial port on any reboot.
|
such as dumping all registers and/or memory to the serial port on any reboot.
|
|
|
Further, the ZipCPU has no ability to write to flash memory. For this reason,
|
Further, the ZipCPU has no ability to write to flash memory. For this reason,
|
there exists an alternate CMod S6~SoC architecture, as shown in
|
there exists an alternate CMod S6~SoC architecture, as shown in
|
Fig.~\ref{fig:altarchitecture}.
|
Fig.~\ref{fig:altarchitecture}.
|
\begin{figure}\begin{center}
|
\begin{figure}\begin{center}
|
\includegraphics[width=5in]{../gfx/altbones.eps}
|
\includegraphics[width=5in]{../gfx/altbones.eps}
|
\caption{Alternate CMod S6 SoC Architecture: Peripherals, with no
|
\caption{Alternate CMod S6 SoC Architecture: Peripherals, with no
|
CPU}\label{fig:altarchitecture}
|
CPU}\label{fig:altarchitecture}
|
\end{center}\end{figure}
|
\end{center}\end{figure}
|
Using this alternate architecture, it should be possible to test the peripherals
|
Using this alternate architecture, it should be possible to test the peripherals
|
and program the flash memory. Both architectures may be loaded into the flash,
|
and program the flash memory. Both architectures may be loaded into the flash,
|
together with the programming code for the Zip CPU.
|
together with the programming code for the Zip CPU.
|
|
|
The basic approach to loading the board is actually quite simple. Using the
|
The basic approach to loading the board is actually quite simple. Using the
|
Digilent ADEPT JTAG configuration program, {\tt djtgcfg}, the alternate
|
Digilent ADEPT JTAG configuration program, {\tt djtgcfg}, the alternate
|
configuration may be written directly to the device. Once this alternate
|
configuration may be written directly to the device. Once this alternate
|
configuration has been loaded, the flash may be examined and programmed.
|
configuration has been loaded, the flash may be examined and programmed.
|
This includes programming a primary and alternate configuration into the
|
This includes programming a primary and alternate configuration into the
|
configuration section of the flash. Once complete, the system may then be
|
configuration section of the flash. Once complete, the system may then be
|
reloaded with the primary configuration file which will contain an image of
|
reloaded with the primary configuration file which will contain an image of
|
the CPU. The CPU will then begin following the instructions found in flash
|
the CPU. The CPU will then begin following the instructions found in flash
|
memory.
|
memory.
|
|
|
|
|
\chapter{Software}
|
\chapter{Software}
|
\section{Directory Structure}
|
\section{Directory Structure}
|
\begin{itemize}
|
\begin{itemize}
|
\item[{\tt trunk/bench}] Contains software for emulating the S6 without the S6
|
\item[{\tt trunk/bench}] Contains software for emulating the S6 without the S6
|
present.
|
present.
|
\begin{itemize}
|
\begin{itemize}
|
\item[{\tt trunk/bench/cpp}] All of the bench testing software is
|
\item[{\tt trunk/bench/cpp}] All of the bench testing software is
|
written in C++, so it is found in this directory. Primary
|
written in C++, so it is found in this directory. Primary
|
among these programs is the {\tt zip\_sim} program which will
|
among these programs is the {\tt zip\_sim} program which will
|
simulate the ZipCPU within the S6--Soc. Specifically, it
|
simulate the ZipCPU within the S6--Soc. Specifically, it
|
simulates everything at or below the {\tt busmaster.v} level.
|
simulates everything at or below the {\tt busmaster.v} level.
|
|
|
Some, although not all, of the peripherals have been simulated
|
Some, although not all, of the peripherals have been simulated
|
and made a part of this simulation. These include the
|
and made a part of this simulation. These include the
|
Quad--SPI flash, the UART, and the LED's.
|
Quad--SPI flash, the UART, and the LED's.
|
|
|
\end{itemize}
|
\end{itemize}
|
\item[{\tt trunk/doc}] All of the documentation for the S6SoC project may be
|
\item[{\tt trunk/doc}] All of the documentation for the S6SoC project may be
|
found in this documentation directory. Specifically, I would commend
|
found in this documentation directory. Specifically, I would commend
|
your attention to anything with a {\tt .pdf} extension, as these
|
your attention to anything with a {\tt .pdf} extension, as these
|
are the completed documents. Among these you should find a copy of the
|
are the completed documents. Among these you should find a copy of the
|
GPL copyright under which this software is released, as well as a
|
GPL copyright under which this software is released, as well as a
|
pre--built copy of this document.
|
pre--built copy of this document.
|
\begin{itemize}
|
\begin{itemize}
|
\item[{\tt trunk/doc/gfx}] Here is where the graphics are located in
|
\item[{\tt trunk/doc/gfx}] Here is where the graphics are located in
|
support of this specification document.
|
support of this specification document.
|
\item[{\tt trunk/doc/src}] And here is where the \LaTeX files are
|
\item[{\tt trunk/doc/src}] And here is where the \LaTeX files are
|
kept that were used in building both this document as well as
|
kept that were used in building both this document as well as
|
the GPL copyright.
|
the GPL copyright.
|
\end{itemize}
|
\end{itemize}
|
\item[{\tt trunk/rtl}] Verilog files
|
\item[{\tt trunk/rtl}] Verilog files
|
\begin{itemize}
|
\begin{itemize}
|
\item[{\tt trunk/rtl/cpu}] Verilog files containing the ZipCPU
|
\item[{\tt trunk/rtl/cpu}] Verilog files containing the ZipCPU
|
core and peripherals. The toplevel file here is the
|
core and peripherals. The toplevel file here is the
|
{\tt zipbones.v} file, although some of the peripherals, such
|
{\tt zipbones.v} file, although some of the peripherals, such
|
as the {\tt ziptimer.v} are referenced independently.
|
as the {\tt ziptimer.v} are referenced independently.
|
\end{itemize}
|
\end{itemize}
|
\item[{\tt trunk/sw}] The main software directory, primarily a repository
|
\item[{\tt trunk/sw}] The main software directory, primarily a repository
|
for software subdirectories beneath it.
|
for software subdirectories beneath it.
|
\begin{itemize}
|
\begin{itemize}
|
\item[{\tt trunk/sw/dev}] This directory holds a variety of
|
\item[{\tt trunk/sw/dev}] This directory holds a variety of
|
simple programs for the ZipCPU, such as {\tt helloworld},
|
simple programs for the ZipCPU, such as {\tt helloworld},
|
{\tt doorbell} and {\tt doorbell2}, as well as software drivers
|
{\tt doorbell} and {\tt doorbell2}, as well as software drivers
|
for various peripherals, such as the real--time clock simulator,
|
for various peripherals, such as the real--time clock simulator,
|
and the keypad and display device drivers.
|
and the keypad and display device drivers.
|
\item[{\tt trunk/sw/host}] This directory holds support software which
|
\item[{\tt trunk/sw/host}] This directory holds support software which
|
can be built on and run on the host machine. Building this
|
can be built on and run on the host machine. Building this
|
software will involve adjusting the Makefile so that it knows
|
software will involve adjusting the Makefile so that it knows
|
where your local ADEPT installation directory is.\footnote{Many
|
where your local ADEPT installation directory is.\footnote{Many
|
of the programs also depend upon the serial number of my CMod
|
of the programs also depend upon the serial number of my CMod
|
S6 device. This will need to be adjusted in any new install.}
|
S6 device. This will need to be adjusted in any new install.}
|
Once built, you will find a variety of very useful programs
|
Once built, you will find a variety of very useful programs
|
within here.
|
within here.
|
\item[{\tt trunk/sw/zipos}] This directory contains the source code for
|
\item[{\tt trunk/sw/zipos}] This directory contains the source code for
|
a rudimentary, very basic, operating system that I
|
a rudimentary, very basic, operating system that I
|
call the ZipOS.
|
call the ZipOS.
|
\end{itemize}
|
\end{itemize}
|
\end{itemize}
|
\end{itemize}
|
|
|
\section{ZipCPU Tool Chain}
|
\section{ZipCPU Tool Chain}
|
To build programs for the ZipCPU, you will need the ZipCPU toolchain. You
|
To build programs for the ZipCPU, you will need the ZipCPU toolchain. You
|
can find this as part of the ZipCPU project, available at OpenCores. Building
|
can find this as part of the ZipCPU project, available at OpenCores. Building
|
the ZipCPU project should result in a set of binaries in the
|
the ZipCPU project should result in a set of binaries in the
|
\hbox{\tt trunk/sw/install/cross-tools/bin} directory. Make this directory
|
\hbox{\tt trunk/sw/install/cross-tools/bin} directory. Make this directory
|
a part of your path, and you should be able to build the CMod S6 ZipCPU
|
a part of your path, and you should be able to build the CMod S6 ZipCPU
|
software. Specifically, you will need to use {\tt zip-gcc}, {\tt zip-as}
|
software. Specifically, you will need to use {\tt zip-gcc}, {\tt zip-as}
|
{\tt zip-ld}, and {\tt zip-cpp}. Other tools, such as {\tt zip-objdump} and
|
{\tt zip-ld}, and {\tt zip-cpp}. Other tools, such as {\tt zip-objdump} and
|
{\tt zip-readelf}, may also prove to be very useful when trying to figure out
|
{\tt zip-readelf}, may also prove to be very useful when trying to figure out
|
what is going on within the SoC.
|
what is going on within the SoC.
|
|
|
\section{Bench Test Software}
|
\section{Bench Test Software}
|
|
|
Bench testing software currently consists of the {\tt zip\_sim} program found
|
Bench testing software currently consists of the {\tt zip\_sim} program found
|
within {\tt trunk/bench/cpp}. This program requires Verilator to run, and
|
within {\tt trunk/bench/cpp}. This program requires Verilator to run, and
|
simulates in a cycle accurate fashion, the entire S6SoC from {\tt busmaster.v}
|
simulates in a cycle accurate fashion, the entire S6SoC from {\tt busmaster.v}
|
on down. Further, the external Quad--SPI flash memory, UART, and LED's are
|
on down. Further, the external Quad--SPI flash memory, UART, and LED's are
|
also simulated, although the 2--line display, audio, and keypad are not.
|
also simulated, although the 2--line display, audio, and keypad are not.
|
|
|
\section{Host Software}
|
\section{Host Software}
|
These include:
|
These include:
|
\begin{itemize}
|
\begin{itemize}
|
\item {\tt dumpuart}: My current approach to debugging involves
|
\item {\tt dumpuart}: My current approach to debugging involves
|
dumping the state of the registers and memory to the
|
dumping the state of the registers and memory to the
|
UART upon reboot. The dumpuart command found here is
|
UART upon reboot. The dumpuart command found here is
|
designed to make certain that the UART is first set
|
designed to make certain that the UART is first set
|
up correctly at 9600~Baud, and that second everything
|
up correctly at 9600~Baud, and that second everything
|
read from the UART is directly sent to both a file and
|
read from the UART is directly sent to both a file and
|
to the screen. In this fashion, it is similar to the
|
to the screen. In this fashion, it is similar to the
|
UNIX {\tt tee} program, save for its serial port
|
UNIX {\tt tee} program, save for its serial port
|
attachment.
|
attachment.
|
\item {\tt readflash}: As I am loathe to remove anything from
|
\item {\tt readflash}: As I am loathe to remove anything from
|
a device that came factory installed, the
|
a device that came factory installed, the
|
{\tt readflash} program reads the original installed
|
{\tt readflash} program reads the original installed
|
configuration from the flash and dumps it to a file.
|
configuration from the flash and dumps it to a file.
|
\item {\tt wbregs}
|
\item {\tt wbregs}
|
\item {\tt zipload}: This is the primary program you will need
|
\item {\tt zipload}: This is the primary program you will need
|
to get your software loaded on the CMod. It takes three
|
to get your software loaded on the CMod. It takes three
|
arguments. The first is the name of the primary
|
arguments. The first is the name of the primary
|
Xilinx configuration file, the second is the name
|
Xilinx configuration file, the second is the name
|
of the alternate Xilinx configuration file, and the
|
of the alternate Xilinx configuration file, and the
|
third is the name of the ZipCPU program you wish to
|
third is the name of the ZipCPU program you wish to
|
write to Flash memory.
|
write to Flash memory.
|
|
|
Each of these arguments is optional. For example, if
|
Each of these arguments is optional. For example, if
|
only one configuration file is given, the loader will
|
only one configuration file is given, the loader will
|
load the primary configuration. If only one ZipCPU
|
load the primary configuration. If only one ZipCPU
|
program is given, the program will be loaded into
|
program is given, the program will be loaded into
|
the program memory area and the configuration file areas
|
the program memory area and the configuration file areas
|
will be left untouched.
|
will be left untouched.
|
\end{itemize}
|
\end{itemize}
|
\section{ZipCPU Programs}
|
\section{ZipCPU Programs}
|
\begin{itemize}
|
\begin{itemize}
|
\item {\tt helloworld}: The first program any programmer should build,
|
\item {\tt helloworld}: The first program any programmer should build,
|
``Hello, world!'' This program sends the string, ``Hello, world!''
|
``Hello, world!'' This program sends the string, ``Hello, world!''
|
over the UART connection once per second. It is a very valuable
|
over the UART connection once per second. It is a very valuable
|
program because, if you can get this program running, you know you have
|
program because, if you can get this program running, you know you have
|
a lot of things working and working correctly. For example, running
|
a lot of things working and working correctly. For example, running
|
this program means you can run the {\tt zip-gcc} compiler, load
|
this program means you can run the {\tt zip-gcc} compiler, load
|
the auxiliar configuration, load the program info flash memory, load
|
the auxiliar configuration, load the program info flash memory, load
|
the primary configuration, and read from the UART port. It also means
|
the primary configuration, and read from the UART port. It also means
|
that you must have the UART port properly configured and wired to your
|
that you must have the UART port properly configured and wired to your
|
CMod board.
|
CMod board.
|
\item {\tt doorbell}: This annoying program verifies the functionality of the
|
\item {\tt doorbell}: This annoying program verifies the functionality of the
|
audio device by playing a doorbell sound to the audio port. It will
|
audio device by playing a doorbell sound to the audio port. It will
|
then wait ten seconds, and play the doorbell sound again (and again,
|
then wait ten seconds, and play the doorbell sound again (and again,
|
and again). (It gets old after a while ...)
|
and again). (It gets old after a while ...)
|
\item {\tt doorbell2}: This adds to the functionality of the {\tt doorbell}
|
\item {\tt doorbell2}: This adds to the functionality of the {\tt doorbell}
|
program a wait for keypress, and a display of the current time on the
|
program a wait for keypress, and a display of the current time on the
|
2--line display. While almost our fully functional program, this
|
2--line display. While almost our fully functional program, this
|
does not include any menus to configure the device or set time, since
|
does not include any menus to configure the device or set time, since
|
it doesn't include any keypad functionality.
|
it doesn't include any keypad functionality.
|
\item {\tt kptest}: A test of whether or not they keypad driver works. When
|
\item {\tt kptest}: A test of whether or not they keypad driver works. When
|
run, anytime a key is pressed, the key's value (in hex) will be
|
run, anytime a key is pressed, the key's value (in hex) will be
|
sent to the UART. Further, pressing an `F' on the keypad will also
|
sent to the UART. Further, pressing an `F' on the keypad will also
|
send a newline over the UART, in case you wish to keep your lines from
|
send a newline over the UART, in case you wish to keep your lines from
|
getting too long.
|
getting too long.
|
\end{itemize}
|
\end{itemize}
|
\section{ZipOS}
|
\section{ZipOS}
|
This operating system is pre--emptive and multitasking, although with many
|
This operating system is pre--emptive and multitasking, although with many
|
limitations. Those familiar with the internals of the Linux kernel may laugh
|
limitations. Those familiar with the internals of the Linux kernel may laugh
|
that I call this an Operating System at all: it has no memory management unit,
|
that I call this an Operating System at all: it has no memory management unit,
|
no paging, no virtual memory, no file I/O access, no network stack, no ability
|
no paging, no virtual memory, no file I/O access, no network stack, no ability
|
to dynamically add or remove tasks, indeed it hardly has any of the things
|
to dynamically add or remove tasks, indeed it hardly has any of the things
|
most often associated with an Operating System. It does, however, handle
|
most often associated with an Operating System. It does, however, handle
|
interrupts, support multiple pre--emptive tasks in a multitasking, timesharing
|
interrupts, support multiple pre--emptive tasks in a multitasking, timesharing
|
fashion, and it supports some very basic and rudimentary system calls. In a
|
fashion, and it supports some very basic and rudimentary system calls. In a
|
similar fashion, it does contain just about all of the functionality necessary
|
similar fashion, it does contain just about all of the functionality necessary
|
for a multi--tasking microcontroller built around a do--forever loop. For its
|
for a multi--tasking microcontroller built around a do--forever loop. For its
|
size, I consider it an impressive achievement. You are welcome to disagree
|
size, I consider it an impressive achievement. You are welcome to disagree
|
with me, however.
|
with me, however.
|
|
|
This version of the ZipOS starts in the resetdump.s code, so that upon
|
This version of the ZipOS starts in the resetdump.s code, so that upon
|
any startup the ZipOS will dump register contents, the BusError register, and
|
any startup the ZipOS will dump register contents, the BusError register, and
|
any scope contents to the UART. This can take some time, so you may wish to
|
any scope contents to the UART. This can take some time, so you may wish to
|
configure what you really wish to send--if anything. If desired, this will
|
configure what you really wish to send--if anything. If desired, this will
|
also dump the entire memory as well. All of this is quite useful in case the
|
also dump the entire memory as well. All of this is quite useful in case the
|
ZipCPU encounters a bus error or other sort of error that causes it to hang,
|
ZipCPU encounters a bus error or other sort of error that causes it to hang,
|
stall, or reboot, as these registers are very carefully not touched prior to
|
stall, or reboot, as these registers are very carefully not touched prior to
|
being sent to the UART output port.
|
being sent to the UART output port.
|
|
|
{\tt resetdump.s} also calls a rudimentary bootloader, to load the parts of
|
{\tt resetdump.s} also calls a rudimentary bootloader, to load the parts of
|
the ZipOS that need to run faster into Block RAM. The choice of what parts
|
the ZipOS that need to run faster into Block RAM. The choice of what parts
|
to load into Block RAM is made on a file by file basis, and found within
|
to load into Block RAM is made on a file by file basis, and found within
|
the linker script, {\tt cmodram.ld}.
|
the linker script, {\tt cmodram.ld}.
|
|
|
Upon completion, {\tt resetdump.s} calls the entry routine for the O/S,
|
Upon completion, {\tt resetdump.s} calls the entry routine for the O/S,
|
{\tt kernel\_entry()} found in {\tt kernel.c}. This is the main task loop for
|
{\tt kernel\_entry()} found in {\tt kernel.c}. This is the main task loop for
|
the entire O/S, and worth studying if you are interested in understanding how
|
the entire O/S, and worth studying if you are interested in understanding how
|
the O/S works.
|
the O/S works.
|
|
|
The user tasks are found (mostly) within {\tt doorbell.c}, also found in the
|
The user tasks are found (mostly) within {\tt doorbell.c}, also found in the
|
ZipOS directory. This file contains two kernel entry points, {\tt kntasks()},
|
ZipOS directory. This file contains two kernel entry points, {\tt kntasks()},
|
which returns the number of tasks the kernel needs to know about, and
|
which returns the number of tasks the kernel needs to know about, and
|
{\tt kinit()}, which builds each of the tasks and connects their file
|
{\tt kinit()}, which builds each of the tasks and connects their file
|
descriptors to the various devices they will be referencing.
|
descriptors to the various devices they will be referencing.
|
\subsection{Traps}
|
\subsection{Traps}
|
The ZipCPU supports a variety of traps, listed here:
|
The ZipOS supports a variety of traps, listed here:
|
\begin{itemize}
|
\begin{itemize}
|
\item WAIT: Halts the execution of a process until an event takes place, or
|
\item WAIT: Halts the execution of a process until an event takes place, or
|
a timeout has been reached. The events that can take place are a
|
a timeout has been reached. The events that can take place are a
|
bitmask of the various interrupts the CPU supports, together with a
|
bitmask of the various interrupts the CPU supports, together with a
|
bitmask of the values found in {\tt swint.h}.
|
bitmask of the values found in {\tt swint.h}.
|
|
|
The timeout value can either be zero, to return immediately with the
|
The timeout value can either be zero, to return immediately with the
|
list of events that have taken place, negative, to wait indefinitely,
|
list of events that have taken place, negative, to wait indefinitely,
|
or a positive number of milliseconds in order to wait at least that
|
or a positive number of milliseconds in order to wait at least that
|
time for the event of interest to take place.
|
time for the event of interest to take place.
|
|
|
This also allows a process to sleep for any number of milliseconds.
|
This also allows a process to sleep for any number of milliseconds.
|
|
|
When wait returns, any events returned by the wait have been cleared.
|
When wait returns, any events returned by the wait have been cleared.
|
|
|
The other thing to be aware of is that events may accumulate before the
|
The other thing to be aware of is that events may accumulate before the
|
wait system call. They will only be returned and cleared, though, if
|
wait system call. They will only be returned and cleared, though, if
|
the wait call indicates an interest in those events.
|
the wait call indicates an interest in those events.
|
\item CLEAR: This system call works closely with the wait system call.
|
\item CLEAR: This system call works closely with the wait system call.
|
Indeed, it is very similar to a wait system call with a zero timeout.
|
Indeed, it is very similar to a wait system call with a zero timeout.
|
It clears any of the requested events which may be pending. If given
|
It clears any of the requested events which may be pending. If given
|
a timeout (in milliseconds), it will start a timer and generate a
|
a timeout (in milliseconds), it will start a timer and generate a
|
{\tt SWINT\_TIMEOUT} event to be sent to this process when the timer
|
{\tt SWINT\_TIMEOUT} event to be sent to this process when the timer
|
completes.
|
completes.
|
\item POST: Certain devices, such as the real--time clock and the doorbell
|
\item POST: Certain devices, such as the real--time clock and the doorbell
|
reader, need the ability of being able to post events to any listener
|
reader, need the ability of being able to post events to any listener
|
within the O/S. The POST system call allows them to POST events in
|
within the O/S. The POST system call allows them to POST events in
|
this manner.
|
this manner.
|
\item YIELD: This is simply a way of being nice to other processes. This system
|
\item YIELD: This is simply a way of being nice to other processes. This system
|
call takes no arguments and simply asks the scheduler to schedule the
|
call takes no arguments and simply asks the scheduler to schedule the
|
next process. It does not take this process off of the ready to run
|
next process. It does not take this process off of the ready to run
|
list, so the next process may be this one. However, since the scheduler
|
list, so the next process may be this one. However, since the scheduler
|
is a round--robin scheduler, it will only return to this process if
|
is a round--robin scheduler, it will only return to this process if
|
nothing else is available to run.
|
nothing else is available to run.
|
\item READ: This is roughly the same system call as the POSIX read() system
|
\item READ: This is roughly the same system call as the POSIX read() system
|
call. It reads some number of memory addresses (words, not octets),
|
call. It reads some number of memory addresses (words, not octets),
|
to the given file descriptor. If the memory requested is unavailable,
|
to the given file descriptor. If the memory requested is unavailable,
|
the read will wait until it is available, possibly indefinitely.
|
the read will wait until it is available, possibly indefinitely.
|
\item WRITE: This is roughly the same system call as the POSIX write() system
|
\item WRITE: This is roughly the same system call as the POSIX write() system
|
call. It writes some number of memory addresses (words, not octets),
|
call. It writes some number of memory addresses (words, not octets),
|
to the given file descriptor. If nothing is reading from the device,
|
to the given file descriptor. If nothing is reading from the device,
|
the write stall the task forever, otherwise it will only stall the task
|
the write stall the task forever, otherwise it will only stall the task
|
until the data is either written to the receiving task, or copied into
|
until the data is either written to the receiving task, or copied into
|
a memory buffer.
|
a memory buffer.
|
\item TIME: Returns the number of seconds since startup. Eventually, this will
|
\item TIME: Returns the number of seconds since startup. Eventually, this will
|
return the number of seconds since January 1, 1970, and be identical
|
return the number of seconds since January 1, 1970, and be identical
|
to the UNIX system time() command, but that may not happen on this
|
to the UNIX system time() command, but that may not happen on this
|
project.
|
project.
|
% \item SEMGET
|
% \item SEMGET
|
% \item SEMPUT
|
% \item SEMPUT
|
\item MALLOC: Allocates memory from the system/kernel heap. This is a very
|
\item MALLOC: Allocates memory from the system/kernel heap. This is a very
|
low overhead memory allocator that, while it does allocate memory,
|
low overhead memory allocator that, while it does allocate memory,
|
cannot free it later. It is nearly 100\% efficient since only
|
cannot free it later. It is nearly 100\% efficient since only
|
one memory address, the top of the heap, is used to determine what
|
one memory address, the top of the heap, is used to determine what
|
memory has been allocated.
|
memory has been allocated.
|
\item FREE: Not currently implemented.
|
\item FREE: Not currently implemented.
|
\end{itemize}
|
\end{itemize}
|
\subsection{Scheduler}
|
\subsection{Scheduler}
|
The ZipCPU currently supports only a round--robin scheduler. Tasks are executed
|
The ZipCPU currently supports only a round--robin scheduler. Tasks are executed
|
in the order they were created, as long as they are available to be executed.
|
in the order they were created, as long as they are available to be executed.
|
If no tasks are available to be run, the Scheduler will run the idle task which
|
If no tasks are available to be run, the Scheduler will run the idle task which
|
puts the CPU to sleep while waiting for an interrupt.
|
puts the CPU to sleep while waiting for an interrupt.
|
|
|
\chapter{Operation}
|
\chapter{Operation}
|
|
|
\chapter{Registers}
|
\chapter{Registers}
|
There are several address regions on the S6~SoC, as shown in
|
There are several address regions on the S6~SoC, as shown in
|
Tbl.~\ref{tbl:memregions}.
|
Tbl.~\ref{tbl:memregions}.
|
\begin{table}[htbp]
|
\begin{table}[htbp]
|
\begin{center}\begin{tabular}{|p{0.75in}|p{0.75in}|p{0.5in}|p{3.0in}|}\hline
|
\begin{center}\begin{tabular}{|p{0.75in}|p{0.75in}|p{0.5in}|p{3.0in}|}\hline
|
\rowcolor[gray]{0.85} Start & End & & Purpose \\\hline\hline
|
\rowcolor[gray]{0.85} Start & End & & Purpose \\\hline\hline
|
\scalebox{0.9}{\tt 0x000100} & \scalebox{0.9}{\tt 0x000107} & R/W & Peripheral I/O Control \\\hline
|
\scalebox{0.9}{\tt 0x000100} & \scalebox{0.9}{\tt 0x000107} & R/W & Peripheral I/O Control \\\hline
|
\scalebox{0.9}{\tt 0x000200} & \scalebox{0.9}{\tt 0x000201} & R/(W) & Debugging scope\\\hline
|
\scalebox{0.9}{\tt 0x000200} & \scalebox{0.9}{\tt 0x000201} & R/(W) & Debugging scope\\\hline
|
\scalebox{0.9}{\tt 0x000400} & \scalebox{0.9}{\tt 0x00043f} & R/W & Internal Configuration Access Port\\\hline
|
\scalebox{0.9}{\tt 0x000400} & \scalebox{0.9}{\tt 0x00043f} & R/W & Internal Configuration Access Port\\\hline
|
\scalebox{0.9}{\tt 0x000800} & \scalebox{0.9}{\tt 0x000803} & R/W & RTC Clock (if present)\\\hline
|
\scalebox{0.9}{\tt 0x000800} & \scalebox{0.9}{\tt 0x000803} & R/W & RTC Clock (if present)\\\hline
|
\scalebox{0.9}{\tt 0x002000} & \scalebox{0.9}{\tt 0x002fff} & R/W & 16kB On-Chip Block RAM \\\hline
|
\scalebox{0.9}{\tt 0x002000} & \scalebox{0.9}{\tt 0x002fff} & R/W & 16kB On-Chip Block RAM \\\hline
|
\scalebox{0.9}{\tt 0x400000} & \scalebox{0.9}{\tt 0x7fffff} & R & 16~MB SPI Flash memory\\\hline
|
\scalebox{0.9}{\tt 0x400000} & \scalebox{0.9}{\tt 0x7fffff} & R & 16~MB SPI Flash memory\\\hline
|
\end{tabular}
|
\end{tabular}
|
\caption{Address Regions}\label{tbl:memregions}
|
\caption{Address Regions}\label{tbl:memregions}
|
\end{center}\end{table}
|
\end{center}\end{table}
|
In general, the address regions that are made up of RAM or flash act like
|
In general, the address regions that are made up of RAM or flash act like
|
memory. The RAM can be read and written, and the flash acts like read only
|
memory. The RAM can be read and written, and the flash acts like read only
|
memory.
|
memory.
|
|
|
This isn't quite so true with the other address regions. Accessing the I/O
|
This isn't quite so true with the other address regions. Accessing the I/O
|
region, while it may be read/write, may have side-effects. For example, reading
|
region, while it may be read/write, may have side-effects. For example, reading
|
from the debugging scope device's data port will read a word from the scope's
|
from the debugging scope device's data port will read a word from the scope's
|
buffer and advance the buffer pointer.
|
buffer and advance the buffer pointer.
|
|
|
\section{Peripheral I/O Control}
|
\section{Peripheral I/O Control}
|
Tbl.~\ref{tbl:ioregs}
|
Tbl.~\ref{tbl:ioregs}
|
\begin{table}[htbp]
|
\begin{table}[htbp]
|
\begin{center}\begin{reglist}
|
\begin{center}\begin{reglist}
|
PIC &\scalebox{0.8}{\tt 0x0100} & 32 & R/W & Interrupt Controller \\\hline
|
PIC &\scalebox{0.8}{\tt 0x0100} & 32 & R/W & Interrupt Controller \\\hline
|
BUSERR &\scalebox{0.8}{\tt 0x0101} & 32 & R & Last Bus Error Address\\\hline
|
BUSERR &\scalebox{0.8}{\tt 0x0101} & 32 & R & Last Bus Error Address\\\hline
|
TIMA &\scalebox{0.8}{\tt 0x0102} & 32 & R/W & ZipTimer A\\\hline
|
TIMA &\scalebox{0.8}{\tt 0x0102} & 32 & R/W & ZipTimer A\\\hline
|
TIMB &\scalebox{0.8}{\tt 0x0103} & 32 & R/W & ZipTimer B\\\hline
|
TIMB &\scalebox{0.8}{\tt 0x0103} & 32 & R/W & ZipTimer B\\\hline
|
PWM &\scalebox{0.8}{\tt 0x0104} & 32 & R/W & PWM Audio Controller\\\hline
|
PWM &\scalebox{0.8}{\tt 0x0104} & 32 & R/W & PWM Audio Controller\\\hline
|
SPIO &\scalebox{0.8}{\tt 0x0105} & 32 & R/W & Special Purpose I/O, Keypad, LED Controller \\\hline
|
SPIO &\scalebox{0.8}{\tt 0x0105} & 32 & R/W & Special Purpose I/O, Keypad, LED Controller \\\hline
|
GPIO &\scalebox{0.8}{\tt 0x0106} & 32 & R/W & GPIO Controller \\\hline
|
GPIO &\scalebox{0.8}{\tt 0x0106} & 32 & R/W & GPIO Controller \\\hline
|
UART &\scalebox{0.8}{\tt 0x0107} & 32 & R/W & UART data\\\hline
|
UART &\scalebox{0.8}{\tt 0x0107} & 32 & R/W & UART data\\\hline
|
\end{reglist}
|
\end{reglist}
|
\caption{I/O Peripheral Registers}\label{tbl:ioregs}
|
\caption{I/O Peripheral Registers}\label{tbl:ioregs}
|
\end{center}\end{table}
|
\end{center}\end{table}
|
shows the addresses of various I/O peripherals included as part of the SoC.
|
shows the addresses of various I/O peripherals included as part of the SoC.
|
|
|
\subsection{Interrupt Controller}
|
\subsection{Interrupt Controller}
|
The interrupt controller is identical to the one found with the ZipSystem.
|
The interrupt controller is identical to the one found with the ZipSystem.
|
The layout of the PIC bits is shown in Fig.~\ref{fig:picreg}.
|
The layout of the PIC bits is shown in Fig.~\ref{fig:picreg}.
|
\begin{figure}\begin{center}
|
\begin{figure}\begin{center}
|
\begin{bytefield}[endianness=big]{32}
|
\begin{bytefield}[endianness=big]{32}
|
\bitheader{0-31} \\
|
\bitheader{0-31} \\
|
\bitbox{1}{E}
|
\bitbox{1}{E}
|
\bitbox{15}{Enabled}
|
\bitbox{15}{Enabled}
|
\bitbox{1}{A}
|
\bitbox{1}{A}
|
\bitbox{15}{ACTIVE}
|
\bitbox{15}{ACTIVE}
|
\\
|
\\
|
\end{bytefield}
|
\end{bytefield}
|
\caption{Programmable Interrupt Control (PIC) Register}\label{fig:picreg}
|
\caption{Programmable Interrupt Control (PIC) Register}\label{fig:picreg}
|
\end{center}\end{figure}
|
\end{center}\end{figure}
|
This controller supports up to fifteen interrupts, however only twelve are
|
This controller supports up to fifteen interrupts, however only twelve are
|
defined within the SoC. If any interrupt line is active, the PIC controller
|
defined within the SoC. If any interrupt line is active, the PIC controller
|
will have that bit set among it's active set. Once set, the bit and hence the
|
will have that bit set among it's active set. Once set, the bit and hence the
|
interrupt can only be cleared by writing to the controller. Interrupts can
|
interrupt can only be cleared by writing to the controller. Interrupts can
|
also be enabled as well. The enabled bit mask controls which interrupt lines
|
also be enabled as well. The enabled bit mask controls which interrupt lines
|
are permitted to interrupt the CPU. Hence, just because an interrupt is active
|
are permitted to interrupt the CPU. Hence, just because an interrupt is active
|
doesn't mean it will interrupt the CPU--the enabled line must be set as well.
|
doesn't mean it will interrupt the CPU--the enabled line must be set as well.
|
Finally, then {\tt A} or {\tt ANY} bit will be high if any interrupts are both
|
Finally, then {\tt A} or {\tt ANY} bit will be high if any interrupts are both
|
enabled and active, whereas the {\tt E} or global interrupt enable bit can be
|
enabled and active, whereas the {\tt E} or global interrupt enable bit can be
|
set to allow the PIC to interrupt the CPU or cleared to disable all interrupts.
|
set to allow the PIC to interrupt the CPU or cleared to disable all interrupts.
|
|
|
To keep operations on this register atomic, most of the bits of this register
|
To keep operations on this register atomic, most of the bits of this register
|
have special meanings upon write. The one exception to this is the global
|
have special meanings upon write. The one exception to this is the global
|
interrupt enable bit. On any write, interrupts will be globally enabled or
|
interrupt enable bit. On any write, interrupts will be globally enabled or
|
disabled based upon the value of this bit. Further, the {\tt ANY} bit is a
|
disabled based upon the value of this bit. Further, the {\tt ANY} bit is a
|
read only bit, so writes to it have no effect.
|
read only bit, so writes to it have no effect.
|
|
|
Enabling specific interrupts, via writes to the enable lines, are different.
|
Enabling specific interrupts, via writes to the enable lines, are different.
|
To enable a specific interrupt, enable all interrupts and
|
To enable a specific interrupt, enable all interrupts and
|
set the wire high associated with the specific interrupt you wish to enable.
|
set the wire high associated with the specific interrupt you wish to enable.
|
Hence writing a {\tt 0x80010000} will enable interrupt line zero, while also
|
Hence writing a {\tt 0x80010000} will enable interrupt line zero, while also
|
enabling all previously enabled interrupts.
|
enabling all previously enabled interrupts.
|
To disable a specific interrupt, disable all interrupts and write a one to the
|
To disable a specific interrupt, disable all interrupts and write a one to the
|
enable line of the interrupt you wish to disable. In this fashion, writing a
|
enable line of the interrupt you wish to disable. In this fashion, writing a
|
{\tt 0x00010000} will disable all interrupts and leave interrupt line zero
|
{\tt 0x00010000} will disable all interrupts and leave interrupt line zero
|
disabled when the interrupts are re--enabled later, whereas {\tt 0x07fff0000}
|
disabled when the interrupts are re--enabled later, whereas {\tt 0x07fff0000}
|
will disable all specific interrupts.
|
will disable all specific interrupts.
|
|
|
Interrupts are acknowledged in a fashion similar to enabling interrupts. By
|
Interrupts are acknowledged in a fashion similar to enabling interrupts. By
|
writing a `1' to the active bit mask, the interrupt will be acknowledged and
|
writing a `1' to the active bit mask, the interrupt will be acknowledged and
|
reset, whereas writing a `0' leaves the interrupt untouched. In this fashion,
|
reset, whereas writing a `0' leaves the interrupt untouched. In this fashion,
|
as individual interrupts are handled, a `1' may be written to this bottom mask
|
as individual interrupts are handled, a `1' may be written to this bottom mask
|
to clear the interrupt. Be aware, however, that any interrupt acknowledgement
|
to clear the interrupt. Be aware, however, that any interrupt acknowledgement
|
may also globally enable or disable interrupts.
|
may also globally enable or disable interrupts.
|
|
|
\subsection{Last Bus Error Address}
|
\subsection{Last Bus Error Address}
|
The Bus Error peripheral simply records the address of the last bus error.
|
The Bus Error peripheral simply records the address of the last bus error.
|
This can be useful when debugging. While the peripheral may only be read,
|
This can be useful when debugging. While the peripheral may only be read,
|
setting it is really as easy as creating a bus error and trapping the result.
|
setting it is really as easy as creating a bus error and trapping the result.
|
Another use for this is upon any reboot, it is possible to read the address
|
Another use for this is upon any reboot, it is possible to read the address
|
of the last bus error and perhaps learn something of what caused the CPU to
|
of the last bus error and perhaps learn something of what caused the CPU to
|
restart.
|
restart.
|
|
|
\subsection{ZipTimer}
|
\subsection{ZipTimer}
|
The S6 Soc contains two ZipTimers, available for the CPU to use. These are
|
The S6 Soc contains two ZipTimers, available for the CPU to use. These are
|
countdown timers. Writing any non--zero value to them will cause them to
|
countdown timers. Writing any non--zero value to them will cause them to
|
immediately start counting down from that value towards zero, and to interrupt
|
immediately start counting down from that value towards zero, and to interrupt
|
the CPU when they reach zero. Writing a new value while the timer is running
|
the CPU when they reach zero. Writing a new value while the timer is running
|
will cause that new value to automatically load into the CPU and start counting
|
will cause that new value to automatically load into the CPU and start counting
|
from there. Writing a zero to the timer disables the timer, and causes it to
|
from there. Writing a zero to the timer disables the timer, and causes it to
|
stop.
|
stop.
|
|
|
ZipTimer A can be set to auto reload. When set, the timer will automatically
|
ZipTimer A can be set to auto reload. When set, the timer will automatically
|
load it's last set value upon reaching zero and interrupting the CPU. This
|
load it's last set value upon reaching zero and interrupting the CPU. This
|
effectively turns it into an interrupt timer if desired. To set this feature,
|
effectively turns it into an interrupt timer if desired. To set this feature,
|
write to the timer the number of clock ticks before an interrupt, but also set
|
write to the timer the number of clock ticks before an interrupt, but also set
|
the high order bit. In this fashion, writing a {\tt 0x80013880} will interrupt
|
the high order bit. In this fashion, writing a {\tt 0x80013880} will interrupt
|
the CPU every millisecond, starting one millisecond after the write takes place
|
the CPU every millisecond, starting one millisecond after the write takes place
|
(assuming an 80~MHz system clock).
|
(assuming an 80~MHz system clock).
|
|
|
ZipTimer B has been wired for a different purpose. ZipTimer B does not support
|
ZipTimer B has been wired for a different purpose. ZipTimer B does not support
|
auto reload, nor will it interrupt the CPU. Instead, ZipTimer B has been wired
|
auto reload, nor will it interrupt the CPU. Instead, ZipTimer B has been wired
|
as a watchdog timer. When this timer reaches zero, the CPU will be rebooted.
|
as a watchdog timer. When this timer reaches zero, the CPU will be rebooted.
|
One way to use this timer would be in conjunction with the ZipTimer A, and to
|
One way to use this timer would be in conjunction with the ZipTimer A, and to
|
write a number to it upon any entry to the interrupt service routine. If given
|
write a number to it upon any entry to the interrupt service routine. If given
|
enough time, this would cause the CPU to reboot if for any reason it locked up.
|
enough time, this would cause the CPU to reboot if for any reason it locked up.
|
|
|
\subsection{PWM Audio Controller}
|
\subsection{PWM Audio Controller}
|
The bit fields of the PWM Audio controller are shown in Fig.~\ref{fig:pwmreg}.
|
The bit fields of the PWM Audio controller are shown in Fig.~\ref{fig:pwmreg}.
|
\begin{figure}\begin{center}
|
\begin{figure}\begin{center}
|
\begin{bytefield}[endianness=big]{32}
|
\begin{bytefield}[endianness=big]{32}
|
\bitheader{0-31} \\
|
\bitheader{0-31} \\
|
\bitbox{10}{Unused}
|
\bitbox{10}{Unused}
|
\bitbox{1}{S}
|
\bitbox{1}{S}
|
\bitbox{1}{G}
|
\bitbox{1}{G}
|
\bitbox{3}{}
|
\bitbox{3}{}
|
\bitbox{1}{E}
|
\bitbox{1}{E}
|
\bitbox{16}{Sample}
|
\bitbox{16}{Sample}
|
\\
|
\\
|
\end{bytefield}
|
\end{bytefield}
|
\caption{PWM Audio Controller Bitfields}\label{fig:pwmreg}
|
\caption{PWM Audio Controller Bitfields}\label{fig:pwmreg}
|
\end{center}\end{figure}
|
\end{center}\end{figure}
|
This controller has been designed for easy writing. To send a sample to the
|
This controller has been designed for easy writing. To send a sample to the
|
PWM audio controller, simply write the sample to the controller and clear the
|
PWM audio controller, simply write the sample to the controller and clear the
|
PWM audio interrupt. When the audio interrupts the CPU again, it is ready
|
PWM audio interrupt. When the audio interrupts the CPU again, it is ready
|
for the next sample.
|
for the next sample.
|
|
|
The audio sample rate has been fixed at 8~kHz. While changing this rate is
|
The audio sample rate has been fixed at 8~kHz. While changing this rate is
|
easy to do within {\tt busmaster.v}, the rate itself takes some work to keep
|
easy to do within {\tt busmaster.v}, the rate itself takes some work to keep
|
up with, so I wouldn't recommend going much (any) faster.
|
up with, so I wouldn't recommend going much (any) faster.
|
|
|
The audio controller supports two additional functionalities, however. The
|
The audio controller supports two additional functionalities, however. The
|
first is that the {\tt E} bit will be set upon any read when or if the audio
|
first is that the {\tt E} bit will be set upon any read when or if the audio
|
controller is ready for another sample. Equivalently, the audio interrupt
|
controller is ready for another sample. Equivalently, the audio interrupt
|
will be asserted.
|
will be asserted.
|
|
|
The second functionality has to do with the two auxiliary control bits present
|
The second functionality has to do with the two auxiliary control bits present
|
in the PModAMP2 audio device. These are the gain and shutdown bits. To set
|
in the PModAMP2 audio device. These are the gain and shutdown bits. To set
|
these bits, write a sample to the controller while also setting the {\tt E}
|
these bits, write a sample to the controller while also setting the {\tt E}
|
bit. When the {\tt E} bit is set upon any write, the shutdown and gain bits
|
bit. When the {\tt E} bit is set upon any write, the shutdown and gain bits
|
will also be set. (Be aware, the shutdown bit is negative logic.) Hence, one
|
will also be set. (Be aware, the shutdown bit is negative logic.) Hence, one
|
may start this interface by writing a {\tt 0x0310000} to the device, and later
|
may start this interface by writing a {\tt 0x0310000} to the device, and later
|
shut it back off by writing a {\tt 0x010000}.
|
shut it back off by writing a {\tt 0x010000}.
|
|
|
\subsection{Special Purpose I/O}
|
\subsection{Special Purpose I/O}
|
|
|
Register {\tt SPIO}, as shown in Fig.~\ref{fig:spioreg},
|
Register {\tt SPIO}, as shown in Fig.~\ref{fig:spioreg},
|
\begin{figure}\begin{center}
|
\begin{figure}\begin{center}
|
\begin{bytefield}[endianness=big]{32}
|
\begin{bytefield}[endianness=big]{32}
|
\bitheader{0-31} \\
|
\bitheader{0-31} \\
|
\begin{leftwordgroup}{Read}\bitbox[lrt]{16}{Zeros}
|
\begin{leftwordgroup}{Read}\bitbox[lrt]{16}{Zeros}
|
\bitbox[lrt]{4}{Kpad}
|
\bitbox[lrt]{4}{Kpad}
|
\bitbox[lrt]{4}{Kpad}
|
\bitbox[lrt]{4}{Kpad}
|
\bitbox[lrt]{2}{00}
|
\bitbox[lrt]{2}{00}
|
\bitbox[lrt]{2}{Btn}
|
\bitbox[lrt]{2}{Btn}
|
\bitbox[lrt]{4}{LED} \\
|
\bitbox[lrt]{4}{LED} \\
|
\bitbox[lrb]{16}{}
|
\bitbox[lrb]{16}{}
|
\bitbox[lrb]{4}{Col Out}
|
\bitbox[lrb]{4}{Col Out}
|
\bitbox[lrb]{4}{Row In}
|
\bitbox[lrb]{4}{Row In}
|
\bitbox[lrb]{2}{}
|
\bitbox[lrb]{2}{}
|
\bitbox[lrb]{2}{}
|
\bitbox[lrb]{2}{}
|
\bitbox[lrb]{4}{}\end{leftwordgroup} \\
|
\bitbox[lrb]{4}{}\end{leftwordgroup} \\
|
\begin{leftwordgroup}{Write}\bitbox[lrt]{16}{Ignored}
|
\begin{leftwordgroup}{Write}\bitbox[lrt]{16}{Ignored}
|
\bitbox[lrt]{4}{Col}
|
\bitbox[lrt]{4}{Col}
|
\bitbox[lrt]{4}{Col}
|
\bitbox[lrt]{4}{Col}
|
\bitbox[lrt]{4}{LED}
|
\bitbox[lrt]{4}{LED}
|
\bitbox[lrt]{4}{LED} \\
|
\bitbox[lrt]{4}{LED} \\
|
\bitbox[lrb]{16}{}
|
\bitbox[lrb]{16}{}
|
\bitbox[lrb]{4}{Out}
|
\bitbox[lrb]{4}{Out}
|
\bitbox[lrb]{4}{Enable}
|
\bitbox[lrb]{4}{Enable}
|
\bitbox[lrb]{4}{Enable}
|
\bitbox[lrb]{4}{Enable}
|
\bitbox[lrb]{4}{}\end{leftwordgroup} \\
|
\bitbox[lrb]{4}{}\end{leftwordgroup} \\
|
\end{bytefield}
|
\end{bytefield}
|
\caption{SPIO Control Register}\label{fig:spioreg}
|
\caption{SPIO Control Register}\label{fig:spioreg}
|
\end{center}\end{figure}
|
\end{center}\end{figure}
|
is a Special Purpose Input/Output (SPIO) register. It is
|
is a Special Purpose Input/Output (SPIO) register. It is
|
designed to control the on-board LED's, buttons, and keypad. Upon any read,
|
designed to control the on-board LED's, buttons, and keypad. Upon any read,
|
the register reads the current state of the keypad column output, the keypad
|
the register reads the current state of the keypad column output, the keypad
|
row input, the buttons and the LED's. Writing is more difficult, in order to
|
row input, the buttons and the LED's. Writing is more difficult, in order to
|
make certain that parts of these registers can be modified atomically.
|
make certain that parts of these registers can be modified atomically.
|
Specifically, to change an LED, write the new value as well as a `1' to the
|
Specifically, to change an LED, write the new value as well as a `1' to the
|
corresponding LED change enable bit. The same goes for the keypad column
|
corresponding LED change enable bit. The same goes for the keypad column
|
output, a `1' needs to be written to the change enable bit in order for a
|
output, a `1' needs to be written to the change enable bit in order for a
|
new value to be accepted.
|
new value to be accepted.
|
|
|
As examples, writing a {\tt 0x0ff} to the {\tt SPIO} register will turn all
|
As examples, writing a {\tt 0x0ff} to the {\tt SPIO} register will turn all
|
LED's on, {\tt 0x0f0} will turn all LED's off, and {\tt 0x011} and {\tt 0x010}
|
LED's on, {\tt 0x0f0} will turn all LED's off, and {\tt 0x011} and {\tt 0x010}
|
will turn LED0 on and then off again respectively.
|
will turn LED0 on and then off again respectively.
|
|
|
The controller will generate a keypad interrupt whenever any row input is
|
The controller will generate a keypad interrupt whenever any row input is
|
zero, and a button interrupt whenever any button value is a one. This also
|
zero, and a button interrupt whenever any button value is a one. This also
|
means that, once generated, the interrupt must be disabled until the key or
|
means that, once generated, the interrupt must be disabled until the key or
|
button is released.
|
button is released.
|
|
|
\subsection{General Purpose I/O}
|
\subsection{General Purpose I/O}
|
The General Purpose Input and Output (GPIO) control register, shown in
|
The General Purpose Input and Output (GPIO) control register, shown in
|
Fig.~\ref{fig:gpioreg},
|
Fig.~\ref{fig:gpioreg},
|
\begin{figure}\begin{center}
|
\begin{figure}\begin{center}
|
\begin{bytefield}[endianness=big]{32}
|
\begin{bytefield}[endianness=big]{32}
|
\bitheader{0-31} \\
|
\bitheader{0-31} \\
|
\bitbox[lrtb]{16}{Current Input Vals (x16)}\bitbox[lrt]{16}{Current Output} \\
|
\bitbox[lrtb]{16}{Current Input Vals (x16)}\bitbox[lrt]{16}{Current Output} \\
|
\bitbox[lrtb]{16}{Output Change Enable}\bitbox[lrb]{16}{Values (16-outs)}
|
\bitbox[lrtb]{16}{Output Change Enable}\bitbox[lrb]{16}{Values (16-outs)}
|
\end{bytefield}
|
\end{bytefield}
|
\caption{GPIO Control Register}\label{fig:gpioreg}
|
\caption{GPIO Control Register}\label{fig:gpioreg}
|
\end{center}\end{figure}
|
\end{center}\end{figure}
|
is quite simple to use: when read, the top 16--bits indicate
|
is quite simple to use: when read, the top 16--bits indicate
|
the value of the 16--input GPIO pins, whereas the bottom 16--bits indicate
|
the value of the 16--input GPIO pins, whereas the bottom 16--bits indicate
|
the value being placed on the 16--output GPIO pins. To change a GPIO pin,
|
the value being placed on the 16--output GPIO pins. To change a GPIO pin,
|
write the new pin's value to this register, together with setting the
|
write the new pin's value to this register, together with setting the
|
corresponding pin in the upper 16--bits. For example, to set output pin 0,
|
corresponding pin in the upper 16--bits. For example, to set output pin 0,
|
write a {\tt 0x010001} to the GPIO device. To clear output pin 0, write a
|
write a {\tt 0x010001} to the GPIO device. To clear output pin 0, write a
|
{\tt 0x010000}. This makes it possible to adjust some output pins independent
|
{\tt 0x010000}. This makes it possible to adjust some output pins independent
|
of the others.
|
of the others.
|
|
|
The GPIO controller, like the keypad or SPIO controller, will also generate
|
The GPIO controller, like the keypad or SPIO controller, will also generate
|
an interrupt. The GPIO interrupt is generated whenever a GPIO input line
|
an interrupt. The GPIO interrupt is generated whenever a GPIO input line
|
changes. The interrupt is not selective: if any line changes, a GPIO interrupt
|
changes. The interrupt is not selective: if any line changes, a GPIO interrupt
|
will be generated. There are no do not care lines.
|
will be generated. There are no do not care lines.
|
|
|
Of the 16 GPIO inputs and the 16 GPIO outputs, two lines have been taken for
|
Of the 16 GPIO inputs and the 16 GPIO outputs, two lines have been taken for
|
I2C support. GPIO line zero, for both input and output, is an I2C data line,
|
I2C support. GPIO line zero, for both input and output, is an I2C data line,
|
{\tt io\_sda}, and GPIO line one is an I2C clock line, {\tt io\_scl}. If the
|
{\tt io\_sda}, and GPIO line one is an I2C clock line, {\tt io\_scl}. If the
|
output of either of these
|
output of either of these
|
lines is set to zero, the GPIO controller will drive the line. Otherwise,
|
lines is set to zero, the GPIO controller will drive the line. Otherwise,
|
the line is pulled up with a weak resistor so that other devices may
|
the line is pulled up with a weak resistor so that other devices may
|
pull it low. If either line is low, when the output control bit is high,
|
pull it low. If either line is low, when the output control bit is high,
|
it is an indicator that another device is sending data across these wires.
|
it is an indicator that another device is sending data across these wires.
|
|
|
\subsection{UART Data Register}
|
\subsection{UART Data Register}
|
Moving on to the UART \ldots
|
Moving on to the UART \ldots
|
although the UART module within the S6~SoC is highly configurable, as built
|
although the UART module within the S6~SoC is highly configurable, as built
|
the UART can only handle 9600~Baud, 8--data bits, no parity, and one stop bit.
|
the UART can only handle 9600~Baud, 8--data bits, no parity, and one stop bit.
|
Changing this involves changing the constant {\tt uart\_setup} within
|
Changing this involves changing the constant {\tt uart\_setup} within
|
{\tt busmaster.v}. Further, the UART has only a single byte data buffer, so
|
{\tt busmaster.v}. Further, the UART has only a single byte data buffer, so
|
reading from the port has a real--time requirement associated with it--the
|
reading from the port has a real--time requirement associated with it--the
|
data buffer must be emptied before the next value is read.
|
data buffer must be emptied before the next value is read.
|
Attempts to read from this port will either return an 8--bit data value from
|
Attempts to read from this port will either return an 8--bit data value from
|
the port, or if no values are available it will return an {\tt 0x0100}
|
the port, or if no values are available it will return an {\tt 0x0100}
|
indicating that fact. In general, reading from the UART port involves first
|
indicating that fact. In general, reading from the UART port involves first
|
waiting for the interrupt to be ready, second reading from the port itself,
|
waiting for the interrupt to be ready, second reading from the port itself,
|
and then third immediately clearing the interrupt. (The interrupt cannot
|
and then third immediately clearing the interrupt. (The interrupt cannot
|
be cleared while data is waiting.) Writing to the UART port is done in a
|
be cleared while data is waiting.) Writing to the UART port is done in a
|
similar fashion. First, wait until the UART transmit interrupt is asserted,
|
similar fashion. First, wait until the UART transmit interrupt is asserted,
|
second write to the UART port, and then third clear the interrupt. As with
|
second write to the UART port, and then third clear the interrupt. As with
|
the read interrupt, clearing the interrupt prior to writing to the port will
|
the read interrupt, clearing the interrupt prior to writing to the port will
|
have no effect.
|
have no effect.
|
|
|
\section{Debugging Scope}
|
\section{Debugging Scope}
|
The debugging scope consists of two registers, a control register and a data
|
The debugging scope consists of two registers, a control register and a data
|
register. It needs to be internally wired to 32--wires, internal to the S6
|
register. It needs to be internally wired to 32--wires, internal to the S6
|
SoC, that will be of interest later. For further details on how to configure
|
SoC, that will be of interest later. For further details on how to configure
|
and use this scope, please see the {\tt WBSCOPE} project on OpenCores.
|
and use this scope, please see the {\tt WBSCOPE} project on OpenCores.
|
|
|
\section{Internal Configuration Access Port}
|
\section{Internal Configuration Access Port}
|
The Internal Configuration Access Port (ICAP) provides access to the internal
|
The Internal Configuration Access Port (ICAP) provides access to the internal
|
configuration details of the FPGA. This access was designed so as to provide
|
configuration details of the FPGA. This access was designed so as to provide
|
the CPU with the capability to command a different FPGA load. In particular,
|
the CPU with the capability to command a different FPGA load. In particular,
|
the code in Fig.~\ref{fig:reload} should reconfigure the FPGA from any given
|
the code in Fig.~\ref{fig:reload} should reconfigure the FPGA from any given
|
Quad SPI {\tt address}.\footnote{According to Xilinx's technical support, this
|
Quad SPI {\tt address}.\footnote{According to Xilinx's technical support, this
|
will only work if the JTAG port is not busy.}
|
will only work if the JTAG port is not busy.}
|
\begin{figure}\begin{center}\begin{tabbing}
|
\begin{figure}\begin{center}\begin{tabbing}
|
{\tt warmboot(uint32 address) \{} \\
|
{\tt warmboot(uint32 address) \{} \\
|
\hbox to 0.25in{}\={\tt uint32\_t *icape6 = (volatile uint32\_t *)0x{\em <ICAPE port address>};}\\
|
\hbox to 0.25in{}\={\tt uint32\_t *icape6 = (volatile uint32\_t *)0x{\em <ICAPE port address>};}\\
|
\>{\tt icape6[13] = (address<<2)\&0x0ffff;}\\
|
\>{\tt icape6[13] = (address<<2)\&0x0ffff;}\\
|
\>{\tt icape6[14] = ((address>>14)\&0x0ff)|((0x03)<<8);}\\
|
\>{\tt icape6[14] = ((address>>14)\&0x0ff)|((0x03)<<8);}\\
|
\>{\tt icape6[4] = 14;}\\
|
\>{\tt icape6[4] = 14;}\\
|
\>{\em // The CMod~S6 is now reconfiguring itself from the new address.}\\
|
\>{\em // The CMod~S6 is now reconfiguring itself from the new address.}\\
|
\>{\em // If all goes well, this routine will never return.}\\
|
\>{\em // If all goes well, this routine will never return.}\\
|
{\tt \}}
|
{\tt \}}
|
\end{tabbing}
|
\end{tabbing}
|
\caption{Spartan--6 ICAPE Usage}\label{fig:reload}
|
\caption{Spartan--6 ICAPE Usage}\label{fig:reload}
|
\end{center}\end{figure}
|
\end{center}\end{figure}
|
|
|
One subtle problem with this port is that it will not work if the CMod is
|
One subtle problem with this port is that it will not work if the CMod is
|
plugged in to the USB JTAG port. It will only work if the CMod has been
|
plugged in to the USB JTAG port. It will only work if the CMod has been
|
provided with an independent power supply, leaving the USB JTAG unplugged.
|
provided with an independent power supply, leaving the USB JTAG unplugged.
|
|
|
For further details, please see either the {\tt WBICAPETWO} project on OpenCores
|
For further details, please see either the {\tt WBICAPETWO} project on OpenCores
|
as well as Xilinx's ``Spartan-6 FPGA Configuration User Guide''.
|
as well as Xilinx's ``Spartan-6 FPGA Configuration User Guide''.
|
|
|
\section{Real--Time Clock}
|
\section{Real--Time Clock}
|
The Real Time Clock will be included if there is enough area to support it.
|
The Real Time Clock will be included if there is enough area to support it.
|
The four registers correspond to a clock, a timer, a stopwatch, and an alarm.
|
The four registers correspond to a clock, a timer, a stopwatch, and an alarm.
|
If space is tight, the timer and stopwatch, or indeed the entire clock, may be
|
If space is tight, the timer and stopwatch, or indeed the entire clock, may be
|
removed from the design. For further details regarding how to set and use this
|
removed from the design. For further details regarding how to set and use this
|
clock, please see the {\tt RTCCLOCK} project on OpenCores.
|
clock, please see the {\tt RTCCLOCK} project on OpenCores.
|
|
|
There is currently not enough area on the chip to support the Real--Time Clock
|
There is currently not enough area on the chip to support the Real--Time Clock
|
together with all of the other peripherals listed here. You can adjust whether
|
together with all of the other peripherals listed here. You can adjust whether
|
the clock is included or not by adjusting the {\tt `define} lines at the top
|
the clock is included or not by adjusting the {\tt `define} lines at the top
|
of {\tt busmaster.v}. For example, it may be possible to get the RTC back by
|
of {\tt busmaster.v}. For example, it may be possible to get the RTC back by
|
disabling the ICAPE2 interface.
|
disabling the ICAPE2 interface.
|
|
|
\section{On-Chip Block RAM}
|
\section{On-Chip Block RAM}
|
|
|
The block RAM is the fastest memory available to the processor. It is also
|
The block RAM is the fastest memory available to the processor. It is also
|
the {\em only} writeable memory available to the processor. Hence all
|
the {\em only} writeable memory available to the processor. Hence all
|
non-constant program data {\em must} be placed into block RAM. The ZipCPU
|
non-constant program data {\em must} be placed into block RAM. The ZipCPU
|
can also run instructions from the block RAM if extra speed is desired. When
|
can also run instructions from the block RAM if extra speed is desired. When
|
runnning from block RAM, the ZipCPU will nominally take 8~clocks per
|
runnning from block RAM, the ZipCPU will nominally take 8~clocks per
|
instruction, for an effective rate of 8~MIPS. Loads or stores to block RAM
|
instruction, for an effective rate of 8~MIPS. Loads or stores to block RAM
|
will take one instruction longer.
|
will take one instruction longer.
|
|
|
\section{Flash Memory}
|
\section{Flash Memory}
|
The flash memory has been arbitrarily sectioned into three sections, one for
|
The flash memory has been arbitrarily sectioned into three sections, one for
|
a primary configuration, a second section for an alternate configuration file,
|
a primary configuration, a second section for an alternate configuration file,
|
and the third section for any program and data. These regions are shown in
|
and the third section for any program and data. These regions are shown in
|
Tbl.~\ref{tbl:flash-addresses}.
|
Tbl.~\ref{tbl:flash-addresses}.
|
\begin{table}[htbp]
|
\begin{table}[htbp]
|
\begin{center}\begin{tabular}{|p{0.75in}|p{0.75in}|p{0.5in}|p{3.0in}|}\hline
|
\begin{center}\begin{tabular}{|p{0.75in}|p{0.75in}|p{0.5in}|p{3.0in}|}\hline
|
\rowcolor[gray]{0.85} Start & End & & Purpose \\\hline\hline
|
\rowcolor[gray]{0.85} Start & End & & Purpose \\\hline\hline
|
\scalebox{0.9}{\tt 0x400000} & \scalebox{0.9}{\tt 0x43ffff} & R & Primary configuration space\\\hline
|
\scalebox{0.9}{\tt 0x400000} & \scalebox{0.9}{\tt 0x43ffff} & R & Primary configuration space\\\hline
|
\scalebox{0.9}{\tt 0x440000} & \scalebox{0.9}{\tt 0x47ffff} & R & Alternate configuration space\\\hline
|
\scalebox{0.9}{\tt 0x440000} & \scalebox{0.9}{\tt 0x47ffff} & R & Alternate configuration space\\\hline
|
\scalebox{0.9}{\tt 0x480000} & \scalebox{0.9}{\tt 0x7fffff} & R & ZipCPU program memory\\\hline
|
\scalebox{0.9}{\tt 0x480000} & \scalebox{0.9}{\tt 0x7fffff} & R & ZipCPU program memory\\\hline
|
\end{tabular}
|
\end{tabular}
|
\caption{Flash Address Regions}\label{tbl:flash-addresses}
|
\caption{Flash Address Regions}\label{tbl:flash-addresses}
|
\end{center}\end{table}
|
\end{center}\end{table}
|
The host program {\tt zipload} can be used to load a ZipCPU program and
|
The host program {\tt zipload} can be used to load a ZipCPU program and
|
configuration files into this address space. To use it, first load the
|
configuration files into this address space. To use it, first load the
|
alternate configuration into the FPGA. Then pass it, as arguments, the
|
alternate configuration into the FPGA. Then pass it, as arguments, the
|
primary, and alternate if desired, configuration files followed by the ZipCPU
|
primary, and alternate if desired, configuration files followed by the ZipCPU
|
program file. Then, when the primary configuration is loaded again, perhaps
|
program file. Then, when the primary configuration is loaded again, perhaps
|
upon power up, the ZipCPU will automatically start running from it's
|
upon power up, the ZipCPU will automatically start running from it's
|
{\tt RESET\_ADDRESS}, {\tt 0x480000}.
|
{\tt RESET\_ADDRESS}, {\tt 0x480000}.
|
|
|
When running from Flash memory, the ZipCPU will nominally take 52~clocks per
|
When running from Flash memory, the ZipCPU will nominally take 52~clocks per
|
instruction, for an effective speed of about 1.5~MIPS.
|
instruction, for an effective speed of about 1.5~MIPS.
|
|
|
\chapter{Clocks}
|
\chapter{Clocks}
|
|
|
The S6~SoC is designed to run off of one master clock. This clock is derived
|
The S6~SoC is designed to run off of one master clock. This clock is derived
|
from the 8~MHz input clock on the board, by multiplying it up to 80~MHz.
|
from the 8~MHz input clock on the board, by multiplying it up to 80~MHz.
|
|
|
\chapter{IO Ports}
|
\chapter{IO Ports}
|
|
|
See Table.~\ref{tbl:ioports}.
|
See Table.~\ref{tbl:ioports}.
|
\begin{table}[htbp]
|
\begin{table}[htbp]
|
\begin{center}
|
\begin{center}
|
\begin{portlist}
|
\begin{portlist}
|
i\_clk\_8mhz & 1 & Input & Clock\\\hline
|
i\_clk\_8mhz & 1 & Input & Clock\\\hline
|
o\_qspi\_cs\_n & 1 & Output & Quad SPI Flash chip select\\\hline
|
o\_qspi\_cs\_n & 1 & Output & Quad SPI Flash chip select\\\hline
|
o\_qspi\_sck & 1 & Output & Quad SPI Flash clock\\\hline
|
o\_qspi\_sck & 1 & Output & Quad SPI Flash clock\\\hline
|
io\_qspi\_dat & 4 & Input/Output & Four-wire SPI flash data bus\\\hline
|
io\_qspi\_dat & 4 & Input/Output & Four-wire SPI flash data bus\\\hline
|
i\_btn & 2 & Input & Inputs from the two on-board push-buttons\\\hline
|
i\_btn & 2 & Input & Inputs from the two on-board push-buttons\\\hline
|
o\_led & 4 & Output & Outputs controlling the four on-board LED's\\\hline
|
o\_led & 4 & Output & Outputs controlling the four on-board LED's\\\hline
|
o\_pwm & 1 & Output & Audio output, via pulse width modulator\\\hline
|
o\_pwm & 1 & Output & Audio output, via pulse width modulator\\\hline
|
\multicolumn{2}{|l|}{o\_pwm\_shutdown\_n, 1}& Output & Audio output shutdown control\\\hline
|
\multicolumn{2}{|l|}{o\_pwm\_shutdown\_n, 1}& Output & Audio output shutdown control\\\hline
|
o\_pwm\_gain & 1 & Output & Audio output 20~dB gain enable\\\hline
|
o\_pwm\_gain & 1 & Output & Audio output 20~dB gain enable\\\hline
|
i\_uart & 1 & Input & UART receive input\\\hline
|
i\_uart & 1 & Input & UART receive input\\\hline
|
o\_uart & 1 & Output & UART transmit output\\\hline
|
o\_uart & 1 & Output & UART transmit output\\\hline
|
i\_uart\_cts & 1 & Input & \\\hline
|
i\_uart\_cts & 1 & Input & \\\hline
|
o\_uart\_rts & 1 & Output & \\\hline
|
o\_uart\_rts & 1 & Output & \\\hline
|
i\_kp\_row & 4 & Output & Four wires to activate the four rows of the keypad\\\hline
|
i\_kp\_row & 4 & Output & Four wires to activate the four rows of the keypad\\\hline
|
o\_kp\_col & 4 & Output & Return four wires, from the keypads columns \\\hline
|
o\_kp\_col & 4 & Output & Return four wires, from the keypads columns \\\hline
|
i\_gpio & 14 & Output & General purpose logic input lines\\\hline
|
i\_gpio & 14 & Output & General purpose logic input lines\\\hline
|
o\_gpio & 14 & Output & General purpose logic output lines\\\hline
|
o\_gpio & 14 & Output & General purpose logic output lines\\\hline
|
io\_scl & 1 & Input/Output & I2C clock port\\\hline
|
io\_scl & 1 & Input/Output & I2C clock port\\\hline
|
io\_sda & 1 & Input/Output & I2C data port\\\hline
|
io\_sda & 1 & Input/Output & I2C data port\\\hline
|
\end{portlist}
|
\end{portlist}
|
\caption{List of IO ports}\label{tbl:ioports}
|
\caption{List of IO ports}\label{tbl:ioports}
|
\end{center}\end{table}
|
\end{center}\end{table}
|
|
|
\begin{table}
|
\begin{table}
|
\begin{center}
|
\begin{center}
|
\includegraphics[height=7in]{../gfx/pinout.eps}
|
\includegraphics[height=7in]{../gfx/pinout.eps}
|
\caption{Physical Locations of Device I/O Ports}\label{tbl:physicalio}
|
\caption{Physical Locations of Device I/O Ports}\label{tbl:physicalio}
|
\end{center}\end{table}
|
\end{center}\end{table}
|
% Appendices
|
% Appendices
|
% Index
|
% Index
|
\end{document}
|
\end{document}
|
|
|
|
|
|
|