URL
https://opencores.org/ocsvn/s6soc/s6soc/trunk
Subversion Repositories s6soc
[/] [s6soc/] [trunk/] [doc/] [src/] [spec.tex] - Rev 33
Go to most recent revision | Compare with Previous | Blame | View Log
\documentclass{gqtekspec} \usepackage{import} \usepackage{bytefield} \project{CMod S6 SoC} \title{Specification} \author{Dan Gisselquist, Ph.D.} \email{dgisselq (at) opencores.org} \revision{Rev.~0.2} \begin{document} \pagestyle{gqtekspecplain} \titlepage \begin{license} Copyright (C) \theyear\today, Gisselquist Technology, LLC 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 by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. 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. \end{license} \begin{revisionhistory} 0.1 & 4/22/2016 & Gisselquist & First Draft \\\hline \end{revisionhistory} % Revision History % Table of Contents, named Contents \tableofcontents \listoffigures \listoftables \begin{preface} The Zip CPU was built with the express purpose of being an area optimized, 32--bit FPGA soft processor. The S6~SoC is designed to prove that the ZipCPU has met this goal. \end{preface} \chapter{Introduction} \pagenumbering{arabic} \setcounter{page}{1} This project is ongoing. Any and all files, to include this one, are subject to change without notice. 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. \begin{enumerate} \item The Spartan--6 LX4 FPGA is very limited in it's resources: It only has 2,400 look--up tables (LUTs), and can only support a 4,096~Word RAM memory (16 kB). \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 8k RAM.) \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, wishbone command access from the UART, pipelined CPU operations, and more. Other solutions will need to be found. \end{enumerate} 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 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 TeensyLC. 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 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 may be what you are looking for. \chapter{Architecture} Fig.~\ref{fig:architecture} \begin{figure}\begin{center} \includegraphics[width=5in]{../gfx/s6bones.eps} \caption{CMod S6 SoC Architecture: ZipCPU and Peripherals}\label{fig:architecture} \end{center}\end{figure} 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 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 port, an external keypad, and an external display. All of these devices are then available for the CPU to interact with. 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 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. 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 Fig.~\ref{fig:altarchitecture}. \begin{figure}\begin{center} \includegraphics[width=5in]{../gfx/altbones.eps} \caption{Alternate CMod S6 SoC Architecture: Peripherals, with no CPU}\label{fig:altarchitecture} \end{center}\end{figure} 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, together with the programming code for the Zip CPU. The basic approach is simple: up and until the software works, the S6 will power up into the alternate architecture of Fig.~\ref{fig:altarchitecture}. While in this state, the flash may be examined and programmed. Once complete, a UART command to the ICAPE port will tell the S6 to load the (primary) FPGA configuration from an alternate flash location. This alternate location will contain a configuration image containing the CPU. The CPU will then begin following the instructions given to it from the flash. \chapter{Operation} \chapter{Registers} There are several address regions on the S6~SoC, as shown in Tbl.~\ref{tbl:memregions}. \begin{table}[htbp] \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 \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 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 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 \end{tabular} \caption{Address Regions}\label{tbl:memregions} \end{center}\end{table} 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. 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 from the debugging scope device's data port will read a word from the scope's buffer and advance the buffer pointer. \section{Debugging Scope} 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 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. \section{Internal Configuration Access Port} The Internal Configuration Access Port (ICAP) provides access to the internal 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 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 will only work if the JTAG port is not busy.} \begin{figure}\begin{center}\begin{tabbing} {\tt warmboot(uint32 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[14] = ((address>>14)\&0x0ff)|((0x03)<<8);}\\ \>{\tt icape6[4] = 14;}\\ \>{\em // The CMod~S6 is now reconfiguring itself from the new address.}\\ \>{\em // If all goes well, this routine will never return.}\\ {\tt \}} \end{tabbing} \caption{Spartan--6 ICAPE Usage}\label{fig:reload} \end{center}\end{figure} For further details, please see either the {\tt WBICAPETWO} project on OpenCores as well as Xilinx's ``Spartan-6 FPGA Configuration User Guide''. \section{Real--Time Clock} 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. 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 clock, please see the {\tt RTCCLOCK} project on OpenCores. \section{I/O Peripherals} Tbl.~\ref{tbl:ioregs} \begin{table}[htbp] \begin{center}\begin{reglist} 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 TIMA &\scalebox{0.8}{\tt 0x0102} & 32 & R/W & ZipTimer A\\\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 KYPAD &\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 UART &\scalebox{0.8}{\tt 0x0107} & 32 & R/W & UART data\\\hline \end{reglist} \caption{I/O Peripheral Registers}\label{tbl:ioregs} \end{center}\end{table} shows the addresses of various I/O peripherals included as part of the SoC. The interrupt controller is identical to the one found with the ZipSystem. Please read the ZipSystem documentation for how to control this. 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, setting it is really as easy as creating a bus error and trapping the result. The two ZipTimer's are ZipSystem timer's, placed onto this peripheral bus. They are available for the CPU to use. Common uses might include I2C or SPI speed control, or multi--tasking task-swap control. For further details, please see the ZipSystem documentation. Audio Controller Register {\tt KYPAD}, as shown in Fig.~\ref{fig:spioreg}, \begin{figure}\begin{center} \begin{bytefield}[endianness=big]{32} \bitheader{0-31} \\ \begin{leftwordgroup}{Read}\bitbox[lrt]{16}{Zeros} \bitbox[lrt]{4}{Kpad} \bitbox[lrt]{4}{Kpad} \bitbox[lrt]{2}{00} \bitbox[lrt]{2}{Btn} \bitbox[lrt]{4}{LED} \\ \bitbox[lrb]{16}{} \bitbox[lrb]{4}{Col Out} \bitbox[lrb]{4}{Row In} \bitbox[lrb]{2}{} \bitbox[lrb]{2}{} \bitbox[lrb]{4}{}\end{leftwordgroup} \\ \begin{leftwordgroup}{Write}\bitbox[lrt]{16}{Ignored} \bitbox[lrt]{4}{Col} \bitbox[lrt]{4}{Col} \bitbox[lrt]{4}{LED} \bitbox[lrt]{4}{LED} \\ \bitbox[lrb]{16}{} \bitbox[lrb]{4}{Out} \bitbox[lrb]{4}{Enable} \bitbox[lrb]{4}{Enable} \bitbox[lrb]{4}{}\end{leftwordgroup} \\ \end{bytefield} \caption{SPIO Control Register}\label{fig:spioreg} \end{center}\end{figure} is a Special Purpose Input/Output (SPIO) register. It is 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 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. 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 output, a `1' needs to be written to the change enable bit in order for a new value to be accepted. The controller will generate a keypad interrupt whenever any row input is zero, and a button interrupt whenever any button value is a one. The General Purpose Input and Output (GPIO) control register, shown in Fig.~\ref{fig:gpioreg}, \begin{figure}\begin{center} \begin{bytefield}[endianness=big]{32} \bitheader{0-31} \\ \bitbox[lrtb]{16}{Current Input Vals (x16)}\bitbox[lrt]{16}{Current Output} \\ \bitbox[lrtb]{16}{Output Change Enable}\bitbox[lrb]{16}{Values (16-outs)} \end{bytefield} \caption{GPIO Control Register}\label{fig:gpioreg} \end{center}\end{figure} 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 being placed on the 16--output GPIO pins. To change a GPIO pin, write the new pins value to this register, together with setting the 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 {\tt 0x010000}. This makes it possible to adjust some output pins independent of the others. The GPIO controller, like the keypad or SPIO controller, will also generate an interrupt. The GPIO interrupt is generated whenever a GPIO input line changes. 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, and GPIO line one is an I2C clock line. If the output of either of these 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 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. Moving on to the UART \ldots 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. There is a single byte data buffer, so reading from the port has a real--time requirement associated with it. 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} indicating that fact. In a similar fashion, writes to this port will send the lower 8--bits of the write out the serial port. If the port is already busy, a single byte will be buffered. \chapter{Clocks} 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. \chapter{IO Ports} See Table.~\ref{tbl:ioports}. \begin{table}[htbp] \begin{center} \begin{portlist} i\_clk\_8mhz & 1 & Input & Clock\\\hline o\_qspi\_cs\_n & 1 & Output & Quad SPI Flash chip select\\\hline o\_qspi\_sck & 1 & Output & Quad SPI Flash clock\\\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 o\_led & 4 & Output & Outputs controlling the four on-board LED's\\\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 o\_pwm\_gain & 1 & Output & Audio output 20~dB gain enable\\\hline i\_uart & 1 & Input & UART receive input\\\hline o\_uart & 1 & Output & UART transmit output\\\hline i\_uart\_cts & 1 & Input & \\\hline o\_uart\_rts & 1 & Output & \\\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 i\_gpio & 14 & Output & General purpose logic input lines\\\hline o\_gpio & 14 & Output & General purpose logic output lines\\\hline io\_scl & 1 & Input/Output & I2C clock port\\\hline io\_sda & 1 & Input/Output & I2C data port\\\hline \end{portlist} \caption{List of IO ports}\label{tbl:ioports} \end{center}\end{table} \begin{table} \begin{center} \includegraphics[height=7in]{../gfx/pinout.eps} \caption{Physical Locations of Device I/O Ports}\label{tbl:physicalio} \end{center}\end{table} % Appendices % Index \end{document}
Go to most recent revision | Compare with Previous | Blame | View Log