1 |
7 |
dgisselq |
\documentclass{gqtekspec}
|
2 |
|
|
\usepackage{import}
|
3 |
|
|
\usepackage{bytefield}
|
4 |
|
|
\project{CMod S6 SoC}
|
5 |
|
|
\title{Specification}
|
6 |
|
|
\author{Dan Gisselquist, Ph.D.}
|
7 |
|
|
\email{dgisselq (at) opencores.org}
|
8 |
|
|
\revision{Rev.~0.2}
|
9 |
|
|
\begin{document}
|
10 |
|
|
\pagestyle{gqtekspecplain}
|
11 |
|
|
\titlepage
|
12 |
|
|
\begin{license}
|
13 |
|
|
Copyright (C) \theyear\today, Gisselquist Technology, LLC
|
14 |
|
|
|
15 |
|
|
This project is free software (firmware): you can redistribute it and/or
|
16 |
|
|
modify it under the terms of the GNU General Public License as published
|
17 |
|
|
by the Free Software Foundation, either version 3 of the License, or (at
|
18 |
|
|
your option) any later version.
|
19 |
|
|
|
20 |
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
21 |
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
|
22 |
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
23 |
|
|
for more details.
|
24 |
|
|
|
25 |
|
|
You should have received a copy of the GNU General Public License along
|
26 |
|
|
with this program. If not, see \texttt{http://www.gnu.org/licenses/} for a copy.
|
27 |
|
|
\end{license}
|
28 |
|
|
\begin{revisionhistory}
|
29 |
36 |
dgisselq |
0.2 & 5/14/2016 & Gisselquist & Updated Draft, still not complete \\\hline
|
30 |
7 |
dgisselq |
0.1 & 4/22/2016 & Gisselquist & First Draft \\\hline
|
31 |
|
|
\end{revisionhistory}
|
32 |
|
|
% Revision History
|
33 |
|
|
% Table of Contents, named Contents
|
34 |
|
|
\tableofcontents
|
35 |
|
|
\listoffigures
|
36 |
|
|
\listoftables
|
37 |
|
|
\begin{preface}
|
38 |
|
|
The Zip CPU was built with the express purpose of being an area optimized,
|
39 |
|
|
32--bit FPGA soft processor.
|
40 |
|
|
|
41 |
|
|
The S6~SoC is designed to prove that the ZipCPU has met this goal.
|
42 |
|
|
\end{preface}
|
43 |
|
|
|
44 |
|
|
\chapter{Introduction}
|
45 |
|
|
\pagenumbering{arabic}
|
46 |
|
|
\setcounter{page}{1}
|
47 |
|
|
|
48 |
|
|
This project is ongoing. Any and all files, to include this one, are subject
|
49 |
|
|
to change without notice.
|
50 |
|
|
|
51 |
|
|
This project comes from my desire to demonstrate the Zip CPU's utility in a
|
52 |
|
|
challenging environment. The CMod~S6 board fits this role nicely.
|
53 |
|
|
\begin{enumerate}
|
54 |
36 |
dgisselq |
\item The Spartan--6 LX4 FPGA is very limited in its resources:
|
55 |
7 |
dgisselq |
It only has 2,400 look--up tables (LUTs), and can only support
|
56 |
|
|
a 4,096~Word RAM memory (16 kB).
|
57 |
|
|
\item With only 4kW RAM, the majority of any program will need to be placed into
|
58 |
|
|
and run from flash. (The chip will actually support more, just not
|
59 |
|
|
8k RAM.)
|
60 |
|
|
\item While the chip has enough area for the CPU, it doesn't have enough area
|
61 |
|
|
to include the CPU and \ldots write access to the flash, debug access,
|
62 |
|
|
wishbone command access from the UART, pipelined CPU operations, and
|
63 |
|
|
more. Other solutions will need to be found.
|
64 |
|
|
\end{enumerate}
|
65 |
|
|
|
66 |
|
|
Of course, if someone just wants the functionality of a small, cheap, CPU,
|
67 |
|
|
this project does not fit that role very well. While the S6 is not very
|
68 |
|
|
expensive, it is still an order of magnitude greater than it's CPU competitors
|
69 |
|
|
in price. This includes such CPU's as the Raspberry Pi Zero, or even the
|
70 |
|
|
TeensyLC.
|
71 |
|
|
|
72 |
|
|
If, on the other hand, what you want is a small, cheap, CPU that can be embedded
|
73 |
|
|
within an FPGA without using too much of the FPGA's resources, this project
|
74 |
|
|
will demonstrate that utility and possibility. Alternatively, if you wish to
|
75 |
|
|
study how to get a CPU to work in a small, constrained environment, this project
|
76 |
|
|
may be what you are looking for.
|
77 |
|
|
|
78 |
|
|
\chapter{Architecture}
|
79 |
|
|
Fig.~\ref{fig:architecture}
|
80 |
|
|
\begin{figure}\begin{center}
|
81 |
|
|
\includegraphics[width=5in]{../gfx/s6bones.eps}
|
82 |
|
|
\caption{CMod S6 SoC Architecture: ZipCPU and
|
83 |
|
|
Peripherals}\label{fig:architecture}
|
84 |
|
|
\end{center}\end{figure}
|
85 |
|
|
shows the basic internal architecture of the S6~SoC. In summary, it consists of a CPU
|
86 |
|
|
coupled with a variety of peripherals for the purpose of controlling the
|
87 |
|
|
external peripherals of the S6: flash, LEDs, buttons, and GPIO. External
|
88 |
|
|
devices may also be added on, such as an audio device, an external serial
|
89 |
|
|
port, an external keypad, and an external display. All of these devices
|
90 |
|
|
are then available for the CPU to interact with.
|
91 |
|
|
|
92 |
|
|
If you are familiar with the Zip CPU, you'll notice this architecture provides
|
93 |
|
|
no access to the Zip CPU debug port. There simply wasn't enough room on the
|
94 |
|
|
device. Debugging the ZipCPU will instead need to take place via other means,
|
95 |
|
|
such as dumping all registers and/or memory to the serial port on any reboot.
|
96 |
|
|
|
97 |
|
|
Further, the ZipCPU has no ability to write to flash memory. For this reason,
|
98 |
|
|
there exists an alternate CMod S6~SoC architecture, as shown in
|
99 |
|
|
Fig.~\ref{fig:altarchitecture}.
|
100 |
|
|
\begin{figure}\begin{center}
|
101 |
|
|
\includegraphics[width=5in]{../gfx/altbones.eps}
|
102 |
|
|
\caption{Alternate CMod S6 SoC Architecture: Peripherals, with no
|
103 |
|
|
CPU}\label{fig:altarchitecture}
|
104 |
|
|
\end{center}\end{figure}
|
105 |
|
|
Using this alternate architecture, it should be possible to test the peripherals
|
106 |
|
|
and program the flash memory. Both architectures may be loaded into the flash,
|
107 |
|
|
together with the programming code for the Zip CPU.
|
108 |
|
|
|
109 |
36 |
dgisselq |
The basic approach to loading the board is actually quite simple. Using the
|
110 |
|
|
Digilent ADEPT JTAG configuration program, {\tt djtgcfg}, the alternate
|
111 |
|
|
configuration may be written directly to the device. Once this alternate
|
112 |
|
|
configuration has been loaded, the flash may be examined and programmed.
|
113 |
|
|
This includes programming a primary and alternate configuration into the
|
114 |
|
|
configuration section of the flash. Once complete, the system may then be
|
115 |
|
|
reloaded with the primary configuration file which will contain an image of
|
116 |
|
|
the CPU. The CPU will then begin following the instructions found in flash
|
117 |
|
|
memory.
|
118 |
7 |
dgisselq |
|
119 |
|
|
|
120 |
36 |
dgisselq |
\chapter{Software}
|
121 |
|
|
\section{Directory Structure}
|
122 |
|
|
\begin{itemize}
|
123 |
|
|
\item[{\tt trunk/bench}] Contains software for emulating the S6 without the S6
|
124 |
|
|
present.
|
125 |
|
|
\begin{itemize}
|
126 |
|
|
\item[{\tt trunk/bench/cpp}] All of the bench testing software is
|
127 |
|
|
written in C++, so it is found in this directory. Primary
|
128 |
|
|
among these programs is the {\tt zip\_sim} program which will
|
129 |
|
|
simulate the ZipCPU within the S6--Soc. Specifically, it
|
130 |
|
|
simulates everything at or below the {\tt busmaster.v} level.
|
131 |
7 |
dgisselq |
|
132 |
36 |
dgisselq |
Some, although not all, of the peripherals have been simulated
|
133 |
|
|
and made a part of this simulation. These include the
|
134 |
|
|
Quad--SPI flash, the UART, and the LED's.
|
135 |
|
|
|
136 |
|
|
\end{itemize}
|
137 |
|
|
\item[{\tt trunk/doc}] All of the documentation for the S6SoC project may be
|
138 |
|
|
found in this documentation directory. Specifically, I would commend
|
139 |
|
|
your attention to anything with a {\tt .pdf} extension, as these
|
140 |
|
|
are the completed documents. Among these you should find a copy of the
|
141 |
|
|
GPL copyright under which this software is released, as well as a
|
142 |
|
|
pre--built copy of this document.
|
143 |
|
|
\begin{itemize}
|
144 |
|
|
\item[{\tt trunk/doc/gfx}] Here is where the graphics are located in
|
145 |
|
|
support of this specification document.
|
146 |
|
|
\item[{\tt trunk/doc/src}] And here is where the \LaTeX files are
|
147 |
|
|
kept that were used in building both this document as well as
|
148 |
|
|
the GPL copyright.
|
149 |
|
|
\end{itemize}
|
150 |
|
|
\item[{\tt trunk/rtl}] Verilog files
|
151 |
|
|
\begin{itemize}
|
152 |
|
|
\item[{\tt trunk/rtl/cpu}] Verilog files containing the ZipCPU
|
153 |
|
|
core and peripherals. The toplevel file here is the
|
154 |
|
|
{\tt zipbones.v} file, although some of the peripherals, such
|
155 |
|
|
as the {\tt ziptimer.v} are referenced independently.
|
156 |
|
|
\end{itemize}
|
157 |
|
|
\item[{\tt trunk/sw}] The main software directory, primarily a repository
|
158 |
|
|
for software subdirectories beneath it.
|
159 |
|
|
\begin{itemize}
|
160 |
|
|
\item[{\tt trunk/sw/dev}] This directory holds a variety of
|
161 |
|
|
simple programs for the ZipCPU, such as {\tt helloworld},
|
162 |
|
|
{\tt doorbell} and {\tt doorbell2}, as well as software drivers
|
163 |
|
|
for various peripherals, such as the real--time clock simulator,
|
164 |
|
|
and the keypad and display device drivers.
|
165 |
|
|
\item[{\tt trunk/sw/host}] This directory holds support software which
|
166 |
|
|
can be built on and run on the host machine. Building this
|
167 |
|
|
software will involve adjusting the Makefile so that it knows
|
168 |
|
|
where your local ADEPT installation directory is.\footnote{Many
|
169 |
|
|
of the programs also depend upon the serial number of my CMod
|
170 |
|
|
S6 device. This will need to be adjusted in any new install.}
|
171 |
|
|
Once built, you will find a variety of very useful programs
|
172 |
|
|
within here.
|
173 |
|
|
\item[{\tt trunk/sw/zipos}] This directory contains the source code for
|
174 |
|
|
a rudimentary, very basic, operating system that I
|
175 |
|
|
call the ZipOS.
|
176 |
|
|
\end{itemize}
|
177 |
|
|
\end{itemize}
|
178 |
|
|
|
179 |
|
|
\section{ZipCPU Tool Chain}
|
180 |
|
|
To build programs for the ZipCPU, you will need the ZipCPU toolchain. You
|
181 |
|
|
can find this as part of the ZipCPU project, available at OpenCores. Building
|
182 |
|
|
the ZipCPU project should result in a set of binaries in the
|
183 |
|
|
\hbox{\tt trunk/sw/install/cross-tools/bin} directory. Make this directory
|
184 |
|
|
a part of your path, and you should be able to build the CMod S6 ZipCPU
|
185 |
|
|
software. Specifically, you will need to use {\tt zip-gcc}, {\tt zip-as}
|
186 |
|
|
{\tt zip-ld}, and {\tt zip-cpp}. Other tools, such as {\tt zip-objdump} and
|
187 |
|
|
{\tt zip-readelf}, may also prove to be very useful when trying to figure out
|
188 |
|
|
what is going on within the SoC.
|
189 |
|
|
|
190 |
|
|
\section{Bench Test Software}
|
191 |
|
|
|
192 |
|
|
Bench testing software currently consists of the {\tt zip\_sim} program found
|
193 |
|
|
within {\tt trunk/bench/cpp}. This program requires Verilator to run, and
|
194 |
|
|
simulates in a cycle accurate fashion, the entire S6SoC from {\tt busmaster.v}
|
195 |
|
|
on down. Further, the external Quad--SPI flash memory, UART, and LED's are
|
196 |
|
|
also simulated, although the 2--line display, audio, and keypad are not.
|
197 |
|
|
|
198 |
|
|
\section{Host Software}
|
199 |
|
|
These include:
|
200 |
|
|
\begin{itemize}
|
201 |
|
|
\item {\tt dumpuart}: My current approach to debugging involves
|
202 |
|
|
dumping the state of the registers and memory to the
|
203 |
|
|
UART upon reboot. The dumpuart command found here is
|
204 |
|
|
designed to make certain that the UART is first set
|
205 |
|
|
up correctly at 9600~Baud, and that second everything
|
206 |
|
|
read from the UART is directly sent to both a file and
|
207 |
|
|
to the screen. In this fashion, it is similar to the
|
208 |
|
|
UNIX {\tt tee} program, save for its serial port
|
209 |
|
|
attachment.
|
210 |
|
|
\item {\tt readflash}: As I am loathe to remove anything from
|
211 |
|
|
a device that came factory installed, the
|
212 |
|
|
{\tt readflash} program reads the original installed
|
213 |
|
|
configuration from the flash and dumps it to a file.
|
214 |
|
|
\item {\tt wbregs}
|
215 |
|
|
\item {\tt zipload}: This is the primary program you will need
|
216 |
|
|
to get your software loaded on the CMod. It takes three
|
217 |
|
|
arguments. The first is the name of the primary
|
218 |
|
|
Xilinx configuration file, the second is the name
|
219 |
|
|
of the alternate Xilinx configuration file, and the
|
220 |
|
|
third is the name of the ZipCPU program you wish to
|
221 |
|
|
write to Flash memory.
|
222 |
|
|
|
223 |
|
|
Each of these arguments is optional. For example, if
|
224 |
|
|
only one configuration file is given, the loader will
|
225 |
|
|
load the primary configuration. If only one ZipCPU
|
226 |
|
|
program is given, the program will be loaded into
|
227 |
|
|
the program memory area and the configuration file areas
|
228 |
|
|
will be left untouched.
|
229 |
|
|
\end{itemize}
|
230 |
|
|
\section{ZipCPU Programs}
|
231 |
|
|
\begin{itemize}
|
232 |
|
|
\item {\tt helloworld}: The first program any programmer should build,
|
233 |
|
|
``Hello, world!'' This program sends the string, ``Hello, world!''
|
234 |
|
|
over the UART connection once per second. It is a very valuable
|
235 |
|
|
program because, if you can get this program running, you know you have
|
236 |
|
|
a lot of things working and working correctly. For example, running
|
237 |
|
|
this program means you can run the {\tt zip-gcc} compiler, load
|
238 |
|
|
the auxiliar configuration, load the program info flash memory, load
|
239 |
|
|
the primary configuration, and read from the UART port. It also means
|
240 |
|
|
that you must have the UART port properly configured and wired to your
|
241 |
|
|
CMod board.
|
242 |
|
|
\item {\tt doorbell}: This annoying program verifies the functionality of the
|
243 |
|
|
audio device by playing a doorbell sound to the audio port. It will
|
244 |
|
|
then wait ten seconds, and play the doorbell sound again (and again,
|
245 |
|
|
and again). (It gets old after a while ...)
|
246 |
|
|
\item {\tt doorbell2}: This adds to the functionality of the {\tt doorbell}
|
247 |
|
|
program a wait for keypress, and a display of the current time on the
|
248 |
|
|
2--line display. While almost our fully functional program, this
|
249 |
|
|
does not include any menus to configure the device or set time, since
|
250 |
|
|
it doesn't include any keypad functionality.
|
251 |
|
|
\item {\tt kptest}: A test of whether or not they keypad driver works. When
|
252 |
|
|
run, anytime a key is pressed, the key's value (in hex) will be
|
253 |
|
|
sent to the UART. Further, pressing an `F' on the keypad will also
|
254 |
|
|
send a newline over the UART, in case you wish to keep your lines from
|
255 |
|
|
getting too long.
|
256 |
|
|
\end{itemize}
|
257 |
|
|
\section{ZipOS}
|
258 |
|
|
This operating system is pre--emptive and multitasking, although with many
|
259 |
|
|
limitations. Those familiar with the internals of the Linux kernel may laugh
|
260 |
|
|
that I call this an Operating System at all: it has no memory management unit,
|
261 |
|
|
no paging, no virtual memory, no file I/O access, no network stack, no ability
|
262 |
|
|
to dynamically add or remove tasks, indeed it hardly has any of the things
|
263 |
|
|
most often associated with an Operating System. It does, however, handle
|
264 |
|
|
interrupts, support multiple pre--emptive tasks in a multitasking, timesharing
|
265 |
|
|
fashion, and it supports some very basic and rudimentary system calls. In a
|
266 |
|
|
similar fashion, it does contain just about all of the functionality necessary
|
267 |
|
|
for a multi--tasking microcontroller built around a do--forever loop. For its
|
268 |
|
|
size, I consider it an impressive achievement. You are welcome to disagree
|
269 |
|
|
with me, however.
|
270 |
|
|
|
271 |
|
|
This version of the ZipOS starts in the resetdump.s code, so that upon
|
272 |
|
|
any startup the ZipOS will dump register contents, the BusError register, and
|
273 |
|
|
any scope contents to the UART. This can take some time, so you may wish to
|
274 |
|
|
configure what you really wish to send--if anything. If desired, this will
|
275 |
|
|
also dump the entire memory as well. All of this is quite useful in case the
|
276 |
|
|
ZipCPU encounters a bus error or other sort of error that causes it to hang,
|
277 |
|
|
stall, or reboot, as these registers are very carefully not touched prior to
|
278 |
|
|
being sent to the UART output port.
|
279 |
|
|
|
280 |
|
|
{\tt resetdump.s} also calls a rudimentary bootloader, to load the parts of
|
281 |
|
|
the ZipOS that need to run faster into Block RAM. The choice of what parts
|
282 |
|
|
to load into Block RAM is made on a file by file basis, and found within
|
283 |
|
|
the linker script, {\tt cmodram.ld}.
|
284 |
|
|
|
285 |
|
|
Upon completion, {\tt resetdump.s} calls the entry routine for the O/S,
|
286 |
|
|
{\tt kernel\_entry()} found in {\tt kernel.c}. This is the main task loop for
|
287 |
|
|
the entire O/S, and worth studying if you are interested in understanding how
|
288 |
|
|
the O/S works.
|
289 |
|
|
|
290 |
|
|
The user tasks are found (mostly) within {\tt doorbell.c}, also found in the
|
291 |
|
|
ZipOS directory. This file contains two kernel entry points, {\tt kntasks()},
|
292 |
|
|
which returns the number of tasks the kernel needs to know about, and
|
293 |
|
|
{\tt kinit()}, which builds each of the tasks and connects their file
|
294 |
|
|
descriptors to the various devices they will be referencing.
|
295 |
|
|
\subsection{Traps}
|
296 |
37 |
dgisselq |
The ZipOS supports a variety of traps, listed here:
|
297 |
36 |
dgisselq |
\begin{itemize}
|
298 |
|
|
\item WAIT: Halts the execution of a process until an event takes place, or
|
299 |
|
|
a timeout has been reached. The events that can take place are a
|
300 |
|
|
bitmask of the various interrupts the CPU supports, together with a
|
301 |
|
|
bitmask of the values found in {\tt swint.h}.
|
302 |
|
|
|
303 |
|
|
The timeout value can either be zero, to return immediately with the
|
304 |
|
|
list of events that have taken place, negative, to wait indefinitely,
|
305 |
|
|
or a positive number of milliseconds in order to wait at least that
|
306 |
|
|
time for the event of interest to take place.
|
307 |
|
|
|
308 |
|
|
This also allows a process to sleep for any number of milliseconds.
|
309 |
|
|
|
310 |
|
|
When wait returns, any events returned by the wait have been cleared.
|
311 |
|
|
|
312 |
|
|
The other thing to be aware of is that events may accumulate before the
|
313 |
|
|
wait system call. They will only be returned and cleared, though, if
|
314 |
|
|
the wait call indicates an interest in those events.
|
315 |
|
|
\item CLEAR: This system call works closely with the wait system call.
|
316 |
|
|
Indeed, it is very similar to a wait system call with a zero timeout.
|
317 |
|
|
It clears any of the requested events which may be pending. If given
|
318 |
|
|
a timeout (in milliseconds), it will start a timer and generate a
|
319 |
|
|
{\tt SWINT\_TIMEOUT} event to be sent to this process when the timer
|
320 |
|
|
completes.
|
321 |
|
|
\item POST: Certain devices, such as the real--time clock and the doorbell
|
322 |
|
|
reader, need the ability of being able to post events to any listener
|
323 |
|
|
within the O/S. The POST system call allows them to POST events in
|
324 |
|
|
this manner.
|
325 |
|
|
\item YIELD: This is simply a way of being nice to other processes. This system
|
326 |
|
|
call takes no arguments and simply asks the scheduler to schedule the
|
327 |
|
|
next process. It does not take this process off of the ready to run
|
328 |
|
|
list, so the next process may be this one. However, since the scheduler
|
329 |
|
|
is a round--robin scheduler, it will only return to this process if
|
330 |
|
|
nothing else is available to run.
|
331 |
|
|
\item READ: This is roughly the same system call as the POSIX read() system
|
332 |
|
|
call. It reads some number of memory addresses (words, not octets),
|
333 |
|
|
to the given file descriptor. If the memory requested is unavailable,
|
334 |
|
|
the read will wait until it is available, possibly indefinitely.
|
335 |
|
|
\item WRITE: This is roughly the same system call as the POSIX write() system
|
336 |
|
|
call. It writes some number of memory addresses (words, not octets),
|
337 |
|
|
to the given file descriptor. If nothing is reading from the device,
|
338 |
|
|
the write stall the task forever, otherwise it will only stall the task
|
339 |
|
|
until the data is either written to the receiving task, or copied into
|
340 |
|
|
a memory buffer.
|
341 |
|
|
\item TIME: Returns the number of seconds since startup. Eventually, this will
|
342 |
|
|
return the number of seconds since January 1, 1970, and be identical
|
343 |
|
|
to the UNIX system time() command, but that may not happen on this
|
344 |
|
|
project.
|
345 |
|
|
% \item SEMGET
|
346 |
|
|
% \item SEMPUT
|
347 |
|
|
\item MALLOC: Allocates memory from the system/kernel heap. This is a very
|
348 |
|
|
low overhead memory allocator that, while it does allocate memory,
|
349 |
|
|
cannot free it later. It is nearly 100\% efficient since only
|
350 |
|
|
one memory address, the top of the heap, is used to determine what
|
351 |
|
|
memory has been allocated.
|
352 |
|
|
\item FREE: Not currently implemented.
|
353 |
|
|
\end{itemize}
|
354 |
|
|
\subsection{Scheduler}
|
355 |
|
|
The ZipCPU currently supports only a round--robin scheduler. Tasks are executed
|
356 |
|
|
in the order they were created, as long as they are available to be executed.
|
357 |
|
|
If no tasks are available to be run, the Scheduler will run the idle task which
|
358 |
|
|
puts the CPU to sleep while waiting for an interrupt.
|
359 |
|
|
|
360 |
7 |
dgisselq |
\chapter{Operation}
|
361 |
|
|
|
362 |
|
|
\chapter{Registers}
|
363 |
|
|
There are several address regions on the S6~SoC, as shown in
|
364 |
|
|
Tbl.~\ref{tbl:memregions}.
|
365 |
|
|
\begin{table}[htbp]
|
366 |
|
|
\begin{center}\begin{tabular}{|p{0.75in}|p{0.75in}|p{0.5in}|p{3.0in}|}\hline
|
367 |
|
|
\rowcolor[gray]{0.85} Start & End & & Purpose \\\hline\hline
|
368 |
|
|
\scalebox{0.9}{\tt 0x000100} & \scalebox{0.9}{\tt 0x000107} & R/W & Peripheral I/O Control \\\hline
|
369 |
|
|
\scalebox{0.9}{\tt 0x000200} & \scalebox{0.9}{\tt 0x000201} & R/(W) & Debugging scope\\\hline
|
370 |
|
|
\scalebox{0.9}{\tt 0x000400} & \scalebox{0.9}{\tt 0x00043f} & R/W & Internal Configuration Access Port\\\hline
|
371 |
|
|
\scalebox{0.9}{\tt 0x000800} & \scalebox{0.9}{\tt 0x000803} & R/W & RTC Clock (if present)\\\hline
|
372 |
|
|
\scalebox{0.9}{\tt 0x002000} & \scalebox{0.9}{\tt 0x002fff} & R/W & 16kB On-Chip Block RAM \\\hline
|
373 |
|
|
\scalebox{0.9}{\tt 0x400000} & \scalebox{0.9}{\tt 0x7fffff} & R & 16~MB SPI Flash memory\\\hline
|
374 |
|
|
\end{tabular}
|
375 |
|
|
\caption{Address Regions}\label{tbl:memregions}
|
376 |
|
|
\end{center}\end{table}
|
377 |
|
|
In general, the address regions that are made up of RAM or flash act like
|
378 |
|
|
memory. The RAM can be read and written, and the flash acts like read only
|
379 |
|
|
memory.
|
380 |
|
|
|
381 |
|
|
This isn't quite so true with the other address regions. Accessing the I/O
|
382 |
|
|
region, while it may be read/write, may have side-effects. For example, reading
|
383 |
|
|
from the debugging scope device's data port will read a word from the scope's
|
384 |
|
|
buffer and advance the buffer pointer.
|
385 |
|
|
|
386 |
36 |
dgisselq |
\section{Peripheral I/O Control}
|
387 |
7 |
dgisselq |
Tbl.~\ref{tbl:ioregs}
|
388 |
|
|
\begin{table}[htbp]
|
389 |
|
|
\begin{center}\begin{reglist}
|
390 |
|
|
PIC &\scalebox{0.8}{\tt 0x0100} & 32 & R/W & Interrupt Controller \\\hline
|
391 |
|
|
BUSERR &\scalebox{0.8}{\tt 0x0101} & 32 & R & Last Bus Error Address\\\hline
|
392 |
|
|
TIMA &\scalebox{0.8}{\tt 0x0102} & 32 & R/W & ZipTimer A\\\hline
|
393 |
|
|
TIMB &\scalebox{0.8}{\tt 0x0103} & 32 & R/W & ZipTimer B\\\hline
|
394 |
|
|
PWM &\scalebox{0.8}{\tt 0x0104} & 32 & R/W & PWM Audio Controller\\\hline
|
395 |
36 |
dgisselq |
SPIO &\scalebox{0.8}{\tt 0x0105} & 32 & R/W & Special Purpose I/O, Keypad, LED Controller \\\hline
|
396 |
7 |
dgisselq |
GPIO &\scalebox{0.8}{\tt 0x0106} & 32 & R/W & GPIO Controller \\\hline
|
397 |
|
|
UART &\scalebox{0.8}{\tt 0x0107} & 32 & R/W & UART data\\\hline
|
398 |
|
|
\end{reglist}
|
399 |
|
|
\caption{I/O Peripheral Registers}\label{tbl:ioregs}
|
400 |
|
|
\end{center}\end{table}
|
401 |
|
|
shows the addresses of various I/O peripherals included as part of the SoC.
|
402 |
|
|
|
403 |
36 |
dgisselq |
\subsection{Interrupt Controller}
|
404 |
7 |
dgisselq |
The interrupt controller is identical to the one found with the ZipSystem.
|
405 |
36 |
dgisselq |
The layout of the PIC bits is shown in Fig.~\ref{fig:picreg}.
|
406 |
|
|
\begin{figure}\begin{center}
|
407 |
|
|
\begin{bytefield}[endianness=big]{32}
|
408 |
|
|
\bitheader{0-31} \\
|
409 |
|
|
\bitbox{1}{E}
|
410 |
|
|
\bitbox{15}{Enabled}
|
411 |
|
|
\bitbox{1}{A}
|
412 |
|
|
\bitbox{15}{ACTIVE}
|
413 |
|
|
\\
|
414 |
|
|
\end{bytefield}
|
415 |
|
|
\caption{Programmable Interrupt Control (PIC) Register}\label{fig:picreg}
|
416 |
|
|
\end{center}\end{figure}
|
417 |
|
|
This controller supports up to fifteen interrupts, however only twelve are
|
418 |
|
|
defined within the SoC. If any interrupt line is active, the PIC controller
|
419 |
|
|
will have that bit set among it's active set. Once set, the bit and hence the
|
420 |
|
|
interrupt can only be cleared by writing to the controller. Interrupts can
|
421 |
|
|
also be enabled as well. The enabled bit mask controls which interrupt lines
|
422 |
|
|
are permitted to interrupt the CPU. Hence, just because an interrupt is active
|
423 |
|
|
doesn't mean it will interrupt the CPU--the enabled line must be set as well.
|
424 |
|
|
Finally, then {\tt A} or {\tt ANY} bit will be high if any interrupts are both
|
425 |
|
|
enabled and active, whereas the {\tt E} or global interrupt enable bit can be
|
426 |
|
|
set to allow the PIC to interrupt the CPU or cleared to disable all interrupts.
|
427 |
7 |
dgisselq |
|
428 |
36 |
dgisselq |
To keep operations on this register atomic, most of the bits of this register
|
429 |
|
|
have special meanings upon write. The one exception to this is the global
|
430 |
|
|
interrupt enable bit. On any write, interrupts will be globally enabled or
|
431 |
|
|
disabled based upon the value of this bit. Further, the {\tt ANY} bit is a
|
432 |
|
|
read only bit, so writes to it have no effect.
|
433 |
|
|
|
434 |
|
|
Enabling specific interrupts, via writes to the enable lines, are different.
|
435 |
|
|
To enable a specific interrupt, enable all interrupts and
|
436 |
|
|
set the wire high associated with the specific interrupt you wish to enable.
|
437 |
|
|
Hence writing a {\tt 0x80010000} will enable interrupt line zero, while also
|
438 |
|
|
enabling all previously enabled interrupts.
|
439 |
|
|
To disable a specific interrupt, disable all interrupts and write a one to the
|
440 |
|
|
enable line of the interrupt you wish to disable. In this fashion, writing a
|
441 |
|
|
{\tt 0x00010000} will disable all interrupts and leave interrupt line zero
|
442 |
|
|
disabled when the interrupts are re--enabled later, whereas {\tt 0x07fff0000}
|
443 |
|
|
will disable all specific interrupts.
|
444 |
|
|
|
445 |
|
|
Interrupts are acknowledged in a fashion similar to enabling interrupts. By
|
446 |
|
|
writing a `1' to the active bit mask, the interrupt will be acknowledged and
|
447 |
|
|
reset, whereas writing a `0' leaves the interrupt untouched. In this fashion,
|
448 |
|
|
as individual interrupts are handled, a `1' may be written to this bottom mask
|
449 |
|
|
to clear the interrupt. Be aware, however, that any interrupt acknowledgement
|
450 |
|
|
may also globally enable or disable interrupts.
|
451 |
|
|
|
452 |
|
|
\subsection{Last Bus Error Address}
|
453 |
7 |
dgisselq |
The Bus Error peripheral simply records the address of the last bus error.
|
454 |
|
|
This can be useful when debugging. While the peripheral may only be read,
|
455 |
|
|
setting it is really as easy as creating a bus error and trapping the result.
|
456 |
36 |
dgisselq |
Another use for this is upon any reboot, it is possible to read the address
|
457 |
|
|
of the last bus error and perhaps learn something of what caused the CPU to
|
458 |
|
|
restart.
|
459 |
7 |
dgisselq |
|
460 |
36 |
dgisselq |
\subsection{ZipTimer}
|
461 |
|
|
The S6 Soc contains two ZipTimers, available for the CPU to use. These are
|
462 |
|
|
countdown timers. Writing any non--zero value to them will cause them to
|
463 |
|
|
immediately start counting down from that value towards zero, and to interrupt
|
464 |
|
|
the CPU when they reach zero. Writing a new value while the timer is running
|
465 |
|
|
will cause that new value to automatically load into the CPU and start counting
|
466 |
|
|
from there. Writing a zero to the timer disables the timer, and causes it to
|
467 |
|
|
stop.
|
468 |
7 |
dgisselq |
|
469 |
36 |
dgisselq |
ZipTimer A can be set to auto reload. When set, the timer will automatically
|
470 |
|
|
load it's last set value upon reaching zero and interrupting the CPU. This
|
471 |
|
|
effectively turns it into an interrupt timer if desired. To set this feature,
|
472 |
|
|
write to the timer the number of clock ticks before an interrupt, but also set
|
473 |
|
|
the high order bit. In this fashion, writing a {\tt 0x80013880} will interrupt
|
474 |
|
|
the CPU every millisecond, starting one millisecond after the write takes place
|
475 |
|
|
(assuming an 80~MHz system clock).
|
476 |
7 |
dgisselq |
|
477 |
36 |
dgisselq |
ZipTimer B has been wired for a different purpose. ZipTimer B does not support
|
478 |
|
|
auto reload, nor will it interrupt the CPU. Instead, ZipTimer B has been wired
|
479 |
|
|
as a watchdog timer. When this timer reaches zero, the CPU will be rebooted.
|
480 |
|
|
One way to use this timer would be in conjunction with the ZipTimer A, and to
|
481 |
|
|
write a number to it upon any entry to the interrupt service routine. If given
|
482 |
|
|
enough time, this would cause the CPU to reboot if for any reason it locked up.
|
483 |
|
|
|
484 |
|
|
\subsection{PWM Audio Controller}
|
485 |
|
|
The bit fields of the PWM Audio controller are shown in Fig.~\ref{fig:pwmreg}.
|
486 |
7 |
dgisselq |
\begin{figure}\begin{center}
|
487 |
|
|
\begin{bytefield}[endianness=big]{32}
|
488 |
|
|
\bitheader{0-31} \\
|
489 |
36 |
dgisselq |
\bitbox{10}{Unused}
|
490 |
|
|
\bitbox{1}{S}
|
491 |
|
|
\bitbox{1}{G}
|
492 |
|
|
\bitbox{3}{}
|
493 |
|
|
\bitbox{1}{E}
|
494 |
|
|
\bitbox{16}{Sample}
|
495 |
|
|
\\
|
496 |
|
|
\end{bytefield}
|
497 |
|
|
\caption{PWM Audio Controller Bitfields}\label{fig:pwmreg}
|
498 |
|
|
\end{center}\end{figure}
|
499 |
|
|
This controller has been designed for easy writing. To send a sample to the
|
500 |
|
|
PWM audio controller, simply write the sample to the controller and clear the
|
501 |
|
|
PWM audio interrupt. When the audio interrupts the CPU again, it is ready
|
502 |
|
|
for the next sample.
|
503 |
|
|
|
504 |
|
|
The audio sample rate has been fixed at 8~kHz. While changing this rate is
|
505 |
|
|
easy to do within {\tt busmaster.v}, the rate itself takes some work to keep
|
506 |
|
|
up with, so I wouldn't recommend going much (any) faster.
|
507 |
|
|
|
508 |
|
|
The audio controller supports two additional functionalities, however. The
|
509 |
|
|
first is that the {\tt E} bit will be set upon any read when or if the audio
|
510 |
|
|
controller is ready for another sample. Equivalently, the audio interrupt
|
511 |
|
|
will be asserted.
|
512 |
|
|
|
513 |
|
|
The second functionality has to do with the two auxiliary control bits present
|
514 |
|
|
in the PModAMP2 audio device. These are the gain and shutdown bits. To set
|
515 |
|
|
these bits, write a sample to the controller while also setting the {\tt E}
|
516 |
|
|
bit. When the {\tt E} bit is set upon any write, the shutdown and gain bits
|
517 |
|
|
will also be set. (Be aware, the shutdown bit is negative logic.) Hence, one
|
518 |
|
|
may start this interface by writing a {\tt 0x0310000} to the device, and later
|
519 |
|
|
shut it back off by writing a {\tt 0x010000}.
|
520 |
|
|
|
521 |
|
|
\subsection{Special Purpose I/O}
|
522 |
|
|
|
523 |
|
|
Register {\tt SPIO}, as shown in Fig.~\ref{fig:spioreg},
|
524 |
|
|
\begin{figure}\begin{center}
|
525 |
|
|
\begin{bytefield}[endianness=big]{32}
|
526 |
|
|
\bitheader{0-31} \\
|
527 |
7 |
dgisselq |
\begin{leftwordgroup}{Read}\bitbox[lrt]{16}{Zeros}
|
528 |
|
|
\bitbox[lrt]{4}{Kpad}
|
529 |
|
|
\bitbox[lrt]{4}{Kpad}
|
530 |
|
|
\bitbox[lrt]{2}{00}
|
531 |
|
|
\bitbox[lrt]{2}{Btn}
|
532 |
|
|
\bitbox[lrt]{4}{LED} \\
|
533 |
|
|
\bitbox[lrb]{16}{}
|
534 |
|
|
\bitbox[lrb]{4}{Col Out}
|
535 |
|
|
\bitbox[lrb]{4}{Row In}
|
536 |
|
|
\bitbox[lrb]{2}{}
|
537 |
|
|
\bitbox[lrb]{2}{}
|
538 |
|
|
\bitbox[lrb]{4}{}\end{leftwordgroup} \\
|
539 |
|
|
\begin{leftwordgroup}{Write}\bitbox[lrt]{16}{Ignored}
|
540 |
|
|
\bitbox[lrt]{4}{Col}
|
541 |
|
|
\bitbox[lrt]{4}{Col}
|
542 |
|
|
\bitbox[lrt]{4}{LED}
|
543 |
|
|
\bitbox[lrt]{4}{LED} \\
|
544 |
|
|
\bitbox[lrb]{16}{}
|
545 |
|
|
\bitbox[lrb]{4}{Out}
|
546 |
|
|
\bitbox[lrb]{4}{Enable}
|
547 |
|
|
\bitbox[lrb]{4}{Enable}
|
548 |
|
|
\bitbox[lrb]{4}{}\end{leftwordgroup} \\
|
549 |
|
|
\end{bytefield}
|
550 |
|
|
\caption{SPIO Control Register}\label{fig:spioreg}
|
551 |
|
|
\end{center}\end{figure}
|
552 |
|
|
is a Special Purpose Input/Output (SPIO) register. It is
|
553 |
|
|
designed to control the on-board LED's, buttons, and keypad. Upon any read,
|
554 |
|
|
the register reads the current state of the keypad column output, the keypad
|
555 |
|
|
row input, the buttons and the LED's. Writing is more difficult, in order to
|
556 |
|
|
make certain that parts of these registers can be modified atomically.
|
557 |
|
|
Specifically, to change an LED, write the new value as well as a `1' to the
|
558 |
|
|
corresponding LED change enable bit. The same goes for the keypad column
|
559 |
|
|
output, a `1' needs to be written to the change enable bit in order for a
|
560 |
|
|
new value to be accepted.
|
561 |
|
|
|
562 |
36 |
dgisselq |
As examples, writing a {\tt 0x0ff} to the {\tt SPIO} register will turn all
|
563 |
|
|
LED's on, {\tt 0x0f0} will turn all LED's off, and {\tt 0x011} and {\tt 0x010}
|
564 |
|
|
will turn LED0 on and then off again respectively.
|
565 |
|
|
|
566 |
7 |
dgisselq |
The controller will generate a keypad interrupt whenever any row input is
|
567 |
36 |
dgisselq |
zero, and a button interrupt whenever any button value is a one. This also
|
568 |
|
|
means that, once generated, the interrupt must be disabled until the key or
|
569 |
|
|
button is released.
|
570 |
7 |
dgisselq |
|
571 |
36 |
dgisselq |
\subsection{General Purpose I/O}
|
572 |
7 |
dgisselq |
The General Purpose Input and Output (GPIO) control register, shown in
|
573 |
|
|
Fig.~\ref{fig:gpioreg},
|
574 |
|
|
\begin{figure}\begin{center}
|
575 |
|
|
\begin{bytefield}[endianness=big]{32}
|
576 |
|
|
\bitheader{0-31} \\
|
577 |
|
|
\bitbox[lrtb]{16}{Current Input Vals (x16)}\bitbox[lrt]{16}{Current Output} \\
|
578 |
|
|
\bitbox[lrtb]{16}{Output Change Enable}\bitbox[lrb]{16}{Values (16-outs)}
|
579 |
|
|
\end{bytefield}
|
580 |
|
|
\caption{GPIO Control Register}\label{fig:gpioreg}
|
581 |
|
|
\end{center}\end{figure}
|
582 |
|
|
is quite simple to use: when read, the top 16--bits indicate
|
583 |
|
|
the value of the 16--input GPIO pins, whereas the bottom 16--bits indicate
|
584 |
|
|
the value being placed on the 16--output GPIO pins. To change a GPIO pin,
|
585 |
36 |
dgisselq |
write the new pin's value to this register, together with setting the
|
586 |
7 |
dgisselq |
corresponding pin in the upper 16--bits. For example, to set output pin 0,
|
587 |
|
|
write a {\tt 0x010001} to the GPIO device. To clear output pin 0, write a
|
588 |
|
|
{\tt 0x010000}. This makes it possible to adjust some output pins independent
|
589 |
|
|
of the others.
|
590 |
|
|
|
591 |
|
|
The GPIO controller, like the keypad or SPIO controller, will also generate
|
592 |
|
|
an interrupt. The GPIO interrupt is generated whenever a GPIO input line
|
593 |
36 |
dgisselq |
changes. The interrupt is not selective: if any line changes, a GPIO interrupt
|
594 |
|
|
will be generated. There are no do not care lines.
|
595 |
7 |
dgisselq |
|
596 |
|
|
Of the 16 GPIO inputs and the 16 GPIO outputs, two lines have been taken for
|
597 |
|
|
I2C support. GPIO line zero, for both input and output, is an I2C data line,
|
598 |
36 |
dgisselq |
{\tt io\_sda}, and GPIO line one is an I2C clock line, {\tt io\_scl}. If the
|
599 |
|
|
output of either of these
|
600 |
7 |
dgisselq |
lines is set to zero, the GPIO controller will drive the line. Otherwise,
|
601 |
|
|
the line is pulled up with a weak resistor so that other devices may
|
602 |
|
|
pull it low. If either line is low, when the output control bit is high,
|
603 |
|
|
it is an indicator that another device is sending data across these wires.
|
604 |
|
|
|
605 |
36 |
dgisselq |
\subsection{UART Data Register}
|
606 |
7 |
dgisselq |
Moving on to the UART \ldots
|
607 |
|
|
although the UART module within the S6~SoC is highly configurable, as built
|
608 |
|
|
the UART can only handle 9600~Baud, 8--data bits, no parity, and one stop bit.
|
609 |
36 |
dgisselq |
Changing this involves changing the constant {\tt uart\_setup} within
|
610 |
|
|
{\tt busmaster.v}. Further, the UART has only a single byte data buffer, so
|
611 |
|
|
reading from the port has a real--time requirement associated with it--the
|
612 |
|
|
data buffer must be emptied before the next value is read.
|
613 |
7 |
dgisselq |
Attempts to read from this port will either return an 8--bit data value from
|
614 |
|
|
the port, or if no values are available it will return an {\tt 0x0100}
|
615 |
36 |
dgisselq |
indicating that fact. In general, reading from the UART port involves first
|
616 |
|
|
waiting for the interrupt to be ready, second reading from the port itself,
|
617 |
|
|
and then third immediately clearing the interrupt. (The interrupt cannot
|
618 |
|
|
be cleared while data is waiting.) Writing to the UART port is done in a
|
619 |
|
|
similar fashion. First, wait until the UART transmit interrupt is asserted,
|
620 |
|
|
second write to the UART port, and then third clear the interrupt. As with
|
621 |
|
|
the read interrupt, clearing the interrupt prior to writing to the port will
|
622 |
|
|
have no effect.
|
623 |
7 |
dgisselq |
|
624 |
36 |
dgisselq |
\section{Debugging Scope}
|
625 |
|
|
The debugging scope consists of two registers, a control register and a data
|
626 |
|
|
register. It needs to be internally wired to 32--wires, internal to the S6
|
627 |
|
|
SoC, that will be of interest later. For further details on how to configure
|
628 |
|
|
and use this scope, please see the {\tt WBSCOPE} project on OpenCores.
|
629 |
|
|
|
630 |
|
|
\section{Internal Configuration Access Port}
|
631 |
|
|
The Internal Configuration Access Port (ICAP) provides access to the internal
|
632 |
|
|
configuration details of the FPGA. This access was designed so as to provide
|
633 |
|
|
the CPU with the capability to command a different FPGA load. In particular,
|
634 |
|
|
the code in Fig.~\ref{fig:reload} should reconfigure the FPGA from any given
|
635 |
|
|
Quad SPI {\tt address}.\footnote{According to Xilinx's technical support, this
|
636 |
|
|
will only work if the JTAG port is not busy.}
|
637 |
|
|
\begin{figure}\begin{center}\begin{tabbing}
|
638 |
|
|
{\tt warmboot(uint32 address) \{} \\
|
639 |
|
|
\hbox to 0.25in{}\={\tt uint32\_t *icape6 = (volatile uint32\_t *)0x{\em <ICAPE port address>};}\\
|
640 |
|
|
\>{\tt icape6[13] = (address<<2)\&0x0ffff;}\\
|
641 |
|
|
\>{\tt icape6[14] = ((address>>14)\&0x0ff)|((0x03)<<8);}\\
|
642 |
|
|
\>{\tt icape6[4] = 14;}\\
|
643 |
|
|
\>{\em // The CMod~S6 is now reconfiguring itself from the new address.}\\
|
644 |
|
|
\>{\em // If all goes well, this routine will never return.}\\
|
645 |
|
|
{\tt \}}
|
646 |
|
|
\end{tabbing}
|
647 |
|
|
\caption{Spartan--6 ICAPE Usage}\label{fig:reload}
|
648 |
|
|
\end{center}\end{figure}
|
649 |
|
|
|
650 |
|
|
One subtle problem with this port is that it will not work if the CMod is
|
651 |
|
|
plugged in to the USB JTAG port. It will only work if the CMod has been
|
652 |
|
|
provided with an independent power supply, leaving the USB JTAG unplugged.
|
653 |
|
|
|
654 |
|
|
For further details, please see either the {\tt WBICAPETWO} project on OpenCores
|
655 |
|
|
as well as Xilinx's ``Spartan-6 FPGA Configuration User Guide''.
|
656 |
|
|
|
657 |
|
|
\section{Real--Time Clock}
|
658 |
|
|
The Real Time Clock will be included if there is enough area to support it.
|
659 |
|
|
The four registers correspond to a clock, a timer, a stopwatch, and an alarm.
|
660 |
|
|
If space is tight, the timer and stopwatch, or indeed the entire clock, may be
|
661 |
|
|
removed from the design. For further details regarding how to set and use this
|
662 |
|
|
clock, please see the {\tt RTCCLOCK} project on OpenCores.
|
663 |
|
|
|
664 |
|
|
There is currently not enough area on the chip to support the Real--Time Clock
|
665 |
|
|
together with all of the other peripherals listed here. You can adjust whether
|
666 |
|
|
the clock is included or not by adjusting the {\tt `define} lines at the top
|
667 |
|
|
of {\tt busmaster.v}. For example, it may be possible to get the RTC back by
|
668 |
|
|
disabling the ICAPE2 interface.
|
669 |
|
|
|
670 |
|
|
\section{On-Chip Block RAM}
|
671 |
|
|
|
672 |
|
|
The block RAM is the fastest memory available to the processor. It is also
|
673 |
|
|
the {\em only} writeable memory available to the processor. Hence all
|
674 |
|
|
non-constant program data {\em must} be placed into block RAM. The ZipCPU
|
675 |
|
|
can also run instructions from the block RAM if extra speed is desired. When
|
676 |
|
|
runnning from block RAM, the ZipCPU will nominally take 8~clocks per
|
677 |
|
|
instruction, for an effective rate of 8~MIPS. Loads or stores to block RAM
|
678 |
|
|
will take one instruction longer.
|
679 |
|
|
|
680 |
|
|
\section{Flash Memory}
|
681 |
|
|
The flash memory has been arbitrarily sectioned into three sections, one for
|
682 |
|
|
a primary configuration, a second section for an alternate configuration file,
|
683 |
|
|
and the third section for any program and data. These regions are shown in
|
684 |
|
|
Tbl.~\ref{tbl:flash-addresses}.
|
685 |
|
|
\begin{table}[htbp]
|
686 |
|
|
\begin{center}\begin{tabular}{|p{0.75in}|p{0.75in}|p{0.5in}|p{3.0in}|}\hline
|
687 |
|
|
\rowcolor[gray]{0.85} Start & End & & Purpose \\\hline\hline
|
688 |
|
|
\scalebox{0.9}{\tt 0x400000} & \scalebox{0.9}{\tt 0x43ffff} & R & Primary configuration space\\\hline
|
689 |
|
|
\scalebox{0.9}{\tt 0x440000} & \scalebox{0.9}{\tt 0x47ffff} & R & Alternate configuration space\\\hline
|
690 |
|
|
\scalebox{0.9}{\tt 0x480000} & \scalebox{0.9}{\tt 0x7fffff} & R & ZipCPU program memory\\\hline
|
691 |
|
|
\end{tabular}
|
692 |
|
|
\caption{Flash Address Regions}\label{tbl:flash-addresses}
|
693 |
|
|
\end{center}\end{table}
|
694 |
|
|
The host program {\tt zipload} can be used to load a ZipCPU program and
|
695 |
|
|
configuration files into this address space. To use it, first load the
|
696 |
|
|
alternate configuration into the FPGA. Then pass it, as arguments, the
|
697 |
|
|
primary, and alternate if desired, configuration files followed by the ZipCPU
|
698 |
|
|
program file. Then, when the primary configuration is loaded again, perhaps
|
699 |
|
|
upon power up, the ZipCPU will automatically start running from it's
|
700 |
|
|
{\tt RESET\_ADDRESS}, {\tt 0x480000}.
|
701 |
|
|
|
702 |
|
|
When running from Flash memory, the ZipCPU will nominally take 52~clocks per
|
703 |
|
|
instruction, for an effective speed of about 1.5~MIPS.
|
704 |
|
|
|
705 |
7 |
dgisselq |
\chapter{Clocks}
|
706 |
|
|
|
707 |
|
|
The S6~SoC is designed to run off of one master clock. This clock is derived
|
708 |
|
|
from the 8~MHz input clock on the board, by multiplying it up to 80~MHz.
|
709 |
|
|
|
710 |
|
|
\chapter{IO Ports}
|
711 |
|
|
|
712 |
|
|
See Table.~\ref{tbl:ioports}.
|
713 |
|
|
\begin{table}[htbp]
|
714 |
|
|
\begin{center}
|
715 |
|
|
\begin{portlist}
|
716 |
|
|
i\_clk\_8mhz & 1 & Input & Clock\\\hline
|
717 |
|
|
o\_qspi\_cs\_n & 1 & Output & Quad SPI Flash chip select\\\hline
|
718 |
|
|
o\_qspi\_sck & 1 & Output & Quad SPI Flash clock\\\hline
|
719 |
|
|
io\_qspi\_dat & 4 & Input/Output & Four-wire SPI flash data bus\\\hline
|
720 |
|
|
i\_btn & 2 & Input & Inputs from the two on-board push-buttons\\\hline
|
721 |
|
|
o\_led & 4 & Output & Outputs controlling the four on-board LED's\\\hline
|
722 |
|
|
o\_pwm & 1 & Output & Audio output, via pulse width modulator\\\hline
|
723 |
|
|
\multicolumn{2}{|l|}{o\_pwm\_shutdown\_n, 1}& Output & Audio output shutdown control\\\hline
|
724 |
|
|
o\_pwm\_gain & 1 & Output & Audio output 20~dB gain enable\\\hline
|
725 |
|
|
i\_uart & 1 & Input & UART receive input\\\hline
|
726 |
|
|
o\_uart & 1 & Output & UART transmit output\\\hline
|
727 |
|
|
i\_uart\_cts & 1 & Input & \\\hline
|
728 |
|
|
o\_uart\_rts & 1 & Output & \\\hline
|
729 |
|
|
i\_kp\_row & 4 & Output & Four wires to activate the four rows of the keypad\\\hline
|
730 |
|
|
o\_kp\_col & 4 & Output & Return four wires, from the keypads columns \\\hline
|
731 |
|
|
i\_gpio & 14 & Output & General purpose logic input lines\\\hline
|
732 |
|
|
o\_gpio & 14 & Output & General purpose logic output lines\\\hline
|
733 |
|
|
io\_scl & 1 & Input/Output & I2C clock port\\\hline
|
734 |
|
|
io\_sda & 1 & Input/Output & I2C data port\\\hline
|
735 |
|
|
\end{portlist}
|
736 |
|
|
\caption{List of IO ports}\label{tbl:ioports}
|
737 |
|
|
\end{center}\end{table}
|
738 |
18 |
dgisselq |
|
739 |
|
|
\begin{table}
|
740 |
|
|
\begin{center}
|
741 |
|
|
\includegraphics[height=7in]{../gfx/pinout.eps}
|
742 |
|
|
\caption{Physical Locations of Device I/O Ports}\label{tbl:physicalio}
|
743 |
|
|
\end{center}\end{table}
|
744 |
7 |
dgisselq |
% Appendices
|
745 |
|
|
% Index
|
746 |
|
|
\end{document}
|
747 |
|
|
|
748 |
|
|
|