URL
https://opencores.org/ocsvn/zipcpu/zipcpu/trunk
Subversion Repositories zipcpu
Compare Revisions
- This comparison shows the changes necessary to convert path
/zipcpu/trunk/doc/src
- from Rev 24 to Rev 23
- ↔ Reverse comparison
Rev 24 → Rev 23
/spec.tex
48,7 → 48,7
\title{Specification} |
\author{Dan Gisselquist, Ph.D.} |
\email{dgisselq (at) opencores.org} |
\revision{Rev.~0.2} |
\revision{Rev.~0.1} |
\begin{document} |
\pagestyle{gqtekspecplain} |
\titlepage |
70,19 → 70,18
copy. |
\end{license} |
\begin{revisionhistory} |
0.2 & 8/19/2015 & Gisselquist & Still Draft, more complete \\\hline |
0.1 & 8/17/2015 & Gisselquist & Incomplete First Draft \\\hline |
\end{revisionhistory} |
% Revision History |
% Table of Contents, named Contents |
\tableofcontents |
\listoffigures |
% \listoffigures |
\listoftables |
\begin{preface} |
Many people have asked me why I am building the Zip CPU. ARM processors are |
good and effective. Xilinx makes and markets Microblaze, Altera Nios, and both |
have better toolsets than the Zip CPU will ever have. OpenRISC is also |
available, RISC--V may be replacing it. Why build a new processor? |
available. Why build a new processor? |
|
The easiest, most obvious answer is the simple one: Because I can. |
|
134,8 → 133,7
\begin{itemize} |
\item A 32-bit CPU: All registers are 32-bits, addresses are 32-bits, |
instructions are 32-bits wide, etc. |
\item A RISC CPU. There is no microcode for executing instructions. All |
instructions are designed to be completed in one clock cycle. |
\item A RISC CPU. There is no microcode for executing instructions. |
\item A Load/Store architecture. (Only load and store instructions |
can access memory.) |
\item Wishbone compliant. All peripherals are accessed just like |
144,12 → 142,7
common bus.) |
\item A pipelined architecture, having stages for {\bf Prefetch}, |
{\bf Decode}, {\bf Read-Operand}, the {\bf ALU/Memory} |
unit, and {\bf Write-back}. See Fig.~\ref{fig:cpu} |
\begin{figure}\begin{center} |
\includegraphics[width=3.5in]{../gfx/cpu.eps} |
\caption{Zip CPU internal pipeline architecture}\label{fig:cpu} |
\end{center}\end{figure} |
for a diagram of this structure. |
unit, and {\bf Write-back} |
\item Completely open source, licensed under the GPL.\footnote{Should you |
need a copy of the Zip CPU licensed under other terms, please |
contact me.} |
162,9 → 155,8
\item {\bf Extenal Debug:} Once placed upon an FPGA, some external means is |
still necessary to debug this CPU. That means that there needs to be |
an external register that can control the CPU: reset it, halt it, step |
it, and tell whether it is running or not. My chosen interface |
includes a second register similar to this control register. This |
second register allows the external controller or debugger to examine |
it, and tell whether it is running or not. Another register is placed |
similar to this register, to allow the external controller to examine |
registers internal to the CPU. |
|
\item {\bf Internal Debug:} Being able to run a debugger from within |
177,12 → 169,6
that would've been at the break point initially, and then to |
replace the break after passing it. |
|
Incidentally, this break messes with the prefetch cache and the |
pipeline: if you change an instruction partially through the pipeline, |
the whole pipeline needs to be cleansed. Likewise if you change |
an instruction in memory, you need to make sure the cache is reloaded |
with the new instruction. |
|
\item {\bf Prefetch Cache:} My original implementation had a very |
simple prefetch stage. Any time the PC changed the prefetch would go |
and fetch the new instruction. While this was perhaps this simplest |
203,28 → 189,24
interrupts), as well as handing it a parameter such as identifying |
which O/S function was called. |
|
My initial approach to building a trap instruction was to create an external |
peripheral which, when written to, would generate an interrupt and could |
return the last value written to it. In practice, this approach didn't work |
at all: the CPU executed two instructions while waiting for the |
trap interrupt to take place. Since then, I've decided to keep the rest of |
the CC register for that purpose so that a write to the CC register, with the |
GIE bit cleared, could be used to execute a trap. This has other problems, |
though, primarily in the limitation of the uses of the CC register. In |
particular, the CC register is the best place to put CPU state information and |
to ``announce'' special CPU features (floating point, etc). So the trap |
instruction still switches to interrupt mode, but the CC register is not |
nearly as useful for telling the supervisor mode processor what trap is being |
executed. |
My initial approach to building a trap instruction was to create |
an external peripheral which, when written to, would generate an |
interrupt and could return the last value written to it. This failed |
timing requirements, however: the CPU executed two instructions while |
waiting for the trap interrupt to take place. Since then, I've |
decided to keep the rest of the CC register for that purpose so that a |
write to the CC register, with the GIE bit cleared, could be used to |
execute a trap. |
|
Modern timesharing systems also depend upon a {\bf Timer} interrupt |
to handle task swapping. For the Zip CPU, this interrupt is handled |
external to the CPU as part of the CPU System, found in {\tt zipsystem.v}. |
The timer module itself is found in {\tt ziptimer.v}. |
to handle task swapping. For the Zip CPU, this interrupt is handled |
external to the CPU as part of the CPU System, found in |
{\tt zipsystem.v}. The timer module itself is found in |
{\tt ziptimer.v}. |
|
\item {\bf Pipeline Stalls:} My original plan was to not support pipeline |
stalls at all, but rather to require the compiler to properly schedule |
all instructions so that stalls would never be necessary. After trying |
instructions so that stalls would never be necessary. After trying |
to build such an architecture, I gave up, having learned some things: |
|
For example, in order to facilitate interrupt handling and debug |
231,11 → 213,10
stepping, the CPU needs to know what instructions have finished, and |
which have not. In other words, it needs to know where it can restart |
the pipeline from. Once restarted, it must act as though it had |
never stopped. This killed my idea of delayed branching, since what |
would be the appropriate program counter to restart at? The one the |
CPU was going to branch to, or the ones in the delay slots? This |
also makes the idea of compressed instruction codes difficult, since, |
again, where do you restart on interrupt? |
never stopped. This killed my idea of delayed branching, since |
what would be the appropriate program counter to restart at? |
The one the CPU was going to branch to, or the ones in the |
delay slots? |
|
So I switched to a model of discrete execution: Once an instruction |
enters into either the ALU or memory unit, the instruction is |
247,7 → 228,7
PC address, the stages preceeding are all wiped clean. |
|
The discrete execution model allows such things as sleeping: if the |
CPU is put to ``sleep,'' the ALU and memory stages stall and back up |
CPU is put to "sleep", the ALU and memory stages stall and back up |
everything before them. Likewise, anything that has entered the ALU |
or memory stage when the CPU is placed to sleep continues to completion. |
To handle this logic, each pipeline stage has three control signals: |
256,12 → 237,6
is stalled. This allows the pipeline to fill any time a later stage |
stalls. |
|
This approach is also different from other pipeline approaches. Instead |
of keeping the entire pipeline filled, each stage is treated |
independently. Therefore, individual stages may move forward as long |
as the subsequent stage is available, regardless of whether the stage |
behind it is filled. |
|
\item {\bf Verilog Modules:} When examining how other processors worked |
here on open cores, many of them had one separate module per pipeline |
stage. While this appeared to me to be a fascinating and commendable |
288,38 → 263,25
|
\chapter{CPU Architecture}\label{chap:arch} |
|
The Zip CPU supports a set of two operand instructions, where the second operand |
The Zip CPU supports a set of two operand instructions, where the first operand |
(always a register) is the result. The only exception is the store instruction, |
where the first operand (always a register) is the source of the data to be |
stored. |
|
\section{Simplified Bus} |
The bus architecture of the Zip CPU is that of a simplified WISHBONE bus. |
It has been simplified in this fashion: all operations are 32--bit operations. |
The bus is neither little endian nor bit endian. For this reason, all words |
are 32--bits. All instructions are also 32--bits wide. Everything has been |
built around the 32--bit word. |
|
\section{Register Set} |
The Zip CPU supports two sets of sixteen 32-bit registers, a supervisor |
and a user set as shown in Fig.~\ref{fig:regset}. |
\begin{figure}\begin{center} |
\includegraphics[width=3.5in]{../gfx/regset.eps} |
\caption{Zip CPU Register File}\label{fig:regset} |
\end{center}\end{figure} |
The supervisor set is used in interrupt mode when interrupts are disabled, |
whereas the user set is used otherwise. Of this register set, the Program |
Counter (PC) is register 15, whereas the status register (SR) or condition |
code register |
and a user set. The supervisor set is used in interrupt mode, whereas |
the user set is used otherwise. Of this register set, the Program Counter (PC) |
is register 15, whereas the status register (SR) or condition code register |
(CC) is register 14. By convention, the stack pointer will be register 13 and |
noted as (SP)--although there is nothing special about this register other |
than this convention. |
noted as (SP)--although the instruction set allows it to be anything. |
The CPU can access both register sets via move instructions from the |
supervisor state, whereas the user state can only access the user registers. |
|
The status register is special, and bears further mention. The lower |
10 bits of the status register form a set of CPU state and condition codes. |
Writes to other bits of this register are preserved. |
8 bits of the status register form a set of condition codes. Writes to other |
bits are preserved, and can be used as part of the trap architecture--examined |
by the O/S upon any interrupt, cleared before returning. |
|
Of the eight condition codes, the bottom four are the current flags: |
Zero (Z), |
352,12 → 314,11
of course. |
|
|
The eighth bit is a break enable bit. This controls whether a break |
instruction in user mode will halt the processor for an external debugger |
(break enabled), or whether the break instruction will simply send send the |
CPU into interrupt mode. Encountering a break in supervisor mode will |
halt the CPU independent of the break enable bit. This bit can only be set |
within supervisor mode. |
The eighth bit is a break enable bit. This |
controls whether a break instruction will halt the processor for an |
external debuggerr (break enabled), or whether the break instruction |
will simply set the STEP bit and send the CPU into interrupt mode. |
This bit can only be set within supervisor mode. |
|
This functionality was added to enable an external debugger to |
set and manage breakpoints. |
366,9 → 327,6
arithmetic for the next instruction will be sent to a floating point unit. |
Such a unit may later be added as an extension to the Zip CPU. If the |
CPU does not support floating point instructions, this bit will never be set. |
The instruction set could also be simply extended to allow other data types |
in this fashion, such as two by 16--bit vector operations or four by 8--bit |
vector operations. |
|
The tenth bit is a trap bit. It is set whenever the user requests a soft |
interrupt, and cleared on any return to userspace command. This allows the |
375,7 → 333,7
supervisor, in supervisor mode, to determine whether it got to supervisor |
mode from a trap or from an external interrupt or both. |
|
These status register bits are summarized in Tbl.~\ref{tbl:ccbits}. |
The status register bits are shown below: |
\begin{table} |
\begin{center} |
\begin{tabular}{l|l} |
391,9 → 349,8
1 & C, or carry bit.\\\hline |
0 & Z, or zero bit. \\\hline |
\end{tabular} |
\caption{Condition Code / Status Register Bits}\label{tbl:ccbits} |
\end{center}\end{table} |
|
\end{center} |
\end{table} |
\section{Conditional Instructions} |
Most, although not quite all, instructions are conditionally executed. From |
the four condition code flags, eight conditions are defined. These are shown |
407,7 → 364,7
3'h2 & {\tt .NE} & Only execute when 'Z' is not set \\ |
3'h3 & {\tt .GE} & Greater than or equal ('N' not set, 'Z' irrelevant) \\ |
3'h4 & {\tt .GT} & Greater than ('N' not set, 'Z' not set) \\ |
3'h5 & {\tt .LT} & Less than ('N' set) \\ |
3'h5 & {\tt .LT} & Less than ('N' not set) \\ |
3'h6 & {\tt .C} & Carry set\\ |
3'h7 & {\tt .V} & Overflow set\\ |
\end{tabular} |
414,12 → 371,12
\caption{Conditions for conditional operand execution}\label{tbl:conditions} |
\end{center} |
\end{table} |
There is no condition code for less than or equal, not C or not V. Sorry, |
I ran out of space in 3--bits. Using these conditions will take an extra |
instruction. (Ex: \hbox{\tt TST \$4,CC;} \hbox{\tt STO.NZ R0,(R1)}) |
There is no condition code for less than or equal, not C or not V. Using |
these conditions will take an extra instruction. |
(Ex: \hbox{\tt TST \$4,CC;} \hbox{\tt STO.NZ R0,(R1)}) |
|
\section{Operand B} |
Many instruction forms have a 21-bit source ``Operand B'' associated with them. |
Many instruction forms have a 21-bit source "Operand B" associated with them. |
This Operand B is either equal to a register plus a signed immediate offset, |
or an immediate offset by itself. This value is encoded as shown in |
Tbl.~\ref{tbl:opb}. |
426,18 → 383,11
\begin{table}\begin{center} |
\begin{tabular}{|l|l|l|}\hline |
Bit 20 & 19 \ldots 16 & 15 \ldots 0 \\\hline |
1'b0 & \multicolumn{2}{l|}{20--bit Signed Immediate value} \\\hline |
1'b1 & 4-bit Register & 16--bit Signed immediate offset \\\hline |
1'b0 & \multicolumn{2}{l|}{Signed Immediate value} \\\hline |
1'b1 & 4-bit Register & 16-bit Signed immediate offset \\\hline |
\end{tabular} |
\caption{Bit allocation for Operand B}\label{tbl:opb} |
\end{center}\end{table} |
|
Sixteen and twenty bit immediates don't make sense for all instructions. For |
example, what is the point of a 20--bit immediate when executing a 16--bit |
multiply? Likewise, why have a 16--bit immediate when adding to a logical |
or arithmetic shift? In these cases, the extra bits are reserved for future |
instruction possibilities. |
|
\section{Address Modes} |
The ZIP CPU supports two addressing modes: register plus immediate, and |
immediate address. Addresses are therefore encoded in the same fashion as |
448,35 → 398,36
taking two or more clocks per instruction, these addressing modes have been |
removed from the realm of possibilities. This means that the Zip CPU has no |
native way of executing push, pop, return, or jump to subroutine operations. |
Each of these instructions can be emulated with a set of instructions from the |
existing set. |
|
\section{Move Operands} |
The previous set of operands would be perfect and complete, save only that |
the CPU needs access to non--supervisory registers while in supervisory mode. |
Therefore, the MOV instruction is special and offers access to these registers |
\ldots when in supervisory mode. To keep the compiler simple, the extra bits |
are ignored in non-supervisory mode (as though they didn't exist), rather than |
being mapped to new instructions or additional capabilities. The bits |
indicating which register set each register lies within are the A-Usr and |
B-Usr bits. When set to a one, these refer to a user mode register. When set |
to a zero, these refer to a register in the current mode, whether user or |
supervisor. Further, because a load immediate instruction exists, there is no |
move capability between an immediate and a register: all moves come from either |
a register or a register plus an offset. |
the CPU needs access to non--supervisory registers while in supervisory |
mode. Therefore, the MOV instruction is special and offers access |
to these registers ... when in supervisory mode. To keep the compiler |
simple, the extra bits are ignored in non-supervisory mode (as though |
they didn't exist), rather than being mapped to new instructions or |
additional capabilities. The bits indicating which register set each |
register lies within are the A-Usr and B-Usr bits. When set to a one, |
these refer to a user mode register. When set to a zero, these refer |
to a register in the current mode, whether user or supervisor. |
Further, because |
a load immediate instruction exists, there is no move capability between |
an immediate and a register: all moves come from either a register or |
a register plus an offset. |
|
This actually leads to a bit of a problem: since the MOV instruction encodes |
which register set each register is coming from or moving to, how shall a |
compiler or assembler know how to compile a MOV instruction without knowing |
the mode of the CPU at the time? For this reason, the compiler will assume |
all MOV registers are supervisor registers, and display them as normal. |
Anything with the user bit set will be treated as a user register. The CPU |
will quietly ignore the supervisor bits while in user mode, and anything |
marked as a user register will always be valid. (Did I just say that in the |
last paragraph?) |
This actually leads to a bit of a problem: since the MOV instruction |
encodes which register set each register is coming from or moving to, |
how shall a compiler or assembler know how to compile a MOV instruction |
without knowing the mode of the CPU at the time? For this reason, |
the compiler will assume all MOV registers are supervisor registers, |
and display them as normal. Anything with the user bit set will |
be treated as a user register. The CPU will quietly ignore the |
supervisor bits while in user mode, and anything marked as a user |
register will always be valid. |
|
\section{Multiply Operations} |
The Zip CPU supports two Multiply operations, a |
While the Zip CPU instruction set supports multiply operations, they are not |
yet fully supported by the CPU. Two Multiply operations are supported, a |
16x16 bit signed multiply (MPYS) and the same but unsigned (MPYU). In both |
cases, the operand is a register plus a 16-bit immediate, subject to the |
rule that the register cannot be the PC or CC registers. The PC register |
512,7 → 463,7
& \multicolumn{3}{l|}{Cond.} |
& \multicolumn{21}{l|}{Operand B} |
& Yes \\\hline |
TST(And) & \multicolumn{4}{l|}{4'h1} |
BTST(And) & \multicolumn{4}{l|}{4'h1} |
& \multicolumn{4}{l|}{D. Reg} |
& \multicolumn{3}{l|}{Cond.} |
& \multicolumn{21}{l|}{Operand B} |
647,14 → 598,14
\end{center}\end{table} |
|
As you can see, there's lots of room for instruction set expansion. The |
NOOP and BREAK instructions are the only instructions within one particular |
24--bit hole. Likewise, the subtract leaves half of its space open, since a |
subtract immediate is the same as an add with a negated immediate. This |
spaces are reserved for future enhancements. |
NOOP and BREAK instructions leave 24~bits of open instruction address |
space, minus the two instructions NOOP and BREAK. The Subtract leaves half |
of its space open, since a subtract immediate is the same as an add with a |
negated immediate. |
|
\section{Derived Instructions} |
The ZIP CPU supports many other common instructions, but not all of them |
are single cycle instructions. The derived instruction tables, |
are single instructions. The derived instruction tables, |
Tbls.~\ref{tbl:derived-1}, \ref{tbl:derived-2}, and~\ref{tbl:derived-3}, |
help to capture some of how these other instructions may be implemented on |
the ZIP CPU. Many of these instructions will have assembly equivalents, |
666,9 → 617,9
& \parbox[t]{1.5in}{Add Ra,Rx\\ADD.C \$1,Ry\\Add Rb,Ry} |
& Add with carry \\\hline |
BRA.Cond +/-\$Addr |
& \hbox{Mov.cond \$Addr+PC,PC} |
& Branch or jump on condition. Works for 15--bit |
signed address offsets.\\\hline |
& Mov.cond \$Addr+PC,PC |
& Branch or jump on condition. Works for 14 bit |
address offsets.\\\hline |
BRA.Cond +/-\$Addr |
& \parbox[t]{1.5in}{LDI \$Addr,Rx \\ ADD.cond Rx,PC} |
& Branch/jump on condition. Works for |
708,8 → 659,7
STO R0,1(SP) \\ |
MOV \$Addr+PC,PC \\ |
ADD \$1,SP} |
& Jump to Subroutine. Note the required cleanup instruction after |
returning. \\\hline |
& Jump to Subroutine. \\\hline |
JSR PC+\$Addr |
& \parbox[t]{1.5in}{MOV \$3+PC,R12 \\ MOV \$addr+PC,PC} |
&This is the high speed |
746,8 → 696,7
the bus, so it therefore takes more work to do. |
|
Note also that in this example, \$Addr is a byte-wise address, where |
all other addresses in this document are 32-bit wordlength addresses. |
For this reason, |
all other addresses are 32-bit wordlength addresses. For this reason, |
we needed to drop the bottom two bits. This also limits the address |
space of character accesses using this method from 16 MB down to 4MB.} |
\\\hline |
792,9 → 741,11
|
Another opportunity might be to jump to the reset address from within |
supervisor mode.}\\\hline |
RET & \parbox[t]{1.5in}{LOD \$-1(SP),PC} |
& Note that this depends upon the calling context to clean up the |
stack, as outlined for the JSR instruction. \\\hline |
RET & \parbox[t]{1.5in}{LOD \$-1(SP),R0 \\ |
MOV \$-1+SP,SP \\ |
MOV R0,PC} |
& An alternative might be to LOD \$-1(SP),PC, followed |
by depending upon the calling program to ADD \$1,SP. \\\hline |
\end{tabular} |
\caption{Derived Instructions, continued}\label{tbl:derived-2} |
\end{center}\end{table} |
840,7 → 791,12
TRAP \#X |
& LDILO \$x,CC |
& This approach uses the unused bits of the CC register as a TRAP |
address. The user will need to make certain |
address. If these bits are zero, no trap has occurred. Unlike my |
previous approach, which was to use a trap peripheral, this approach |
has no delay associated with it. To work, the supervisor will need |
to clear this register following any trap, and the user will need to |
be careful to only set this register prior to a trap condition. |
Likewise, when setting this value, the user will need to make certain |
that the SLEEP and GIE bits are not set in \$x. LDI would also work, |
however using LDILO permits the use of conditional traps. (i.e., |
trap if the zero flag is set.) Should you wish to trap off of a |
856,6 → 812,7
& Or \$SLEEP,CC |
& Wait 'til interrupt. In an interrupts disabled context, this |
becomes a HALT instruction. |
</TABLE> |
\end{tabular} |
\caption{Derived Instructions, continued}\label{tbl:derived-3} |
\end{center}\end{table} |
870,9 → 827,7
\item {\bf Decode}: Decode instruction into op code, register(s) to read, and |
immediate offset. |
\item {\bf Read Operands}: Read registers and apply any immediate values to |
them. There is no means of detecting or flagging arithmetic overflow |
or carry when adding the immediate to the operand. This stage will |
stall if any source operand is pending. |
them. This stage will stall if any source operand is pending. |
A proper optimizing compiler, therefore, will schedule an instruction |
between the instruction that produces the result and the instruction |
that uses it. |
886,8 → 841,6
\item Issuing an instruction to the memory while the memory is busy will |
stall the bus. If the bus deadlocks, only a reset will |
release the CPU. (Watchdog timer, anyone?) |
\item The Zip CPU currently has no means of reading and acting on any |
error conditions on the bus. |
\end{itemize} |
\item {\bf Write-Back}: Conditionally write back the result to register set, |
applying the condition. This routine is bi-re-entrant: either the |
894,10 → 847,6
memory or the simple instruction may request a register write. |
\end{enumerate} |
|
The Zip CPU does not support out of order execution. Therefore, if the memory |
unit stalls, every other instruction stalls. Memory stores, however, can take |
place concurrently with ALU operations, although memory writes cannot. |
|
\section{Pipeline Logic} |
How the CPU handles some instruction combinations can be telling when |
determining what happens in the pipeline. The following lists some examples: |
1042,57 → 991,7
|
|
\chapter{Peripherals}\label{chap:periph} |
|
While the previous chapter describes a CPU in isolation, the Zip System |
includes a minimum set of peripherals as well. These peripherals are shown |
in Fig.~\ref{fig:zipsystem} |
\begin{figure}\begin{center} |
\includegraphics[width=3.5in]{../gfx/system.eps} |
\caption{Zip System Peripherals}\label{fig:zipsystem} |
\end{center}\end{figure} |
and described here. They are designed to make |
the Zip CPU more useful in an Embedded Operating System environment. |
|
\section{Interrupt Controller} |
|
Perhaps the most important peripheral within the Zip System is the interrupt |
controller. While the Zip CPU itself can only handle one interrupt, and has |
only the one interrupt state: disabled or enabled, the interrupt controller |
can make things more interesting. |
|
The Zip System interrupt controller module supports up to 15 interrupts, all |
controlled from one register. Bit~31 of the interrupt controller controls |
overall whether interrupts are enabled (1'b1) or disabled (1'b0). Bits~16--30 |
control whether individual interrupts are enabled (1'b0) or disabled (1'b0). |
Bit~15 is an indicator showing whether or not any interrupt is active, and |
bits~0--15 indicate whether or not an individual interrupt is active. |
|
The interrupt controller has been designed so that bits can be controlled |
individually without having any knowledge of the rest of the controller |
setting. To enable an interrupt, write to the register with the high order |
global enable bit set and the respective interrupt enable bit set. No other |
bits will be affected. To disable an interrupt, write to the register with |
the high order global enable bit cleared and the respective interrupt enable |
bit set. To clear an interrupt, write a `1' to that interrupts status pin. |
Zero's written to the register have no affect, save that a zero written to the |
master enable will disable all interrupts. |
|
As an example, suppose you wished to enable interrupt \#4. You would then |
write to the register a {\tt 0x80100010} to enable interrupt \#4 and to clear |
any past active state. When you later wish to disable this interrupt, you would |
write a {\tt 0x00100010} to the register. As before, this both disables the |
interrupt and clears the active indicator. This also has the side effect of |
disabling all interrupts, so a second write of {\tt 0x80000000} may be necessary |
to re-enable any other interrupts. |
|
The Zip System currently hosts two interrupt controllers, a primary and a |
secondary. The primary interrupt controller has one interrupt line which may |
come from an external interrupt controller, and one interrupt line from the |
secondary controller. Other primary interrupts include the system timers, |
the jiffies interrupt, and the manual cache interrupt. The secondary interrupt |
controller maintains an interrupt state for all of the processor accounting |
counters. |
|
\section{Counter} |
|
The Zip Counter is a very simple counter: it just counts. It cannot be |
1113,8 → 1012,7
reloads its last start time on any interrupt. Hence, to mark seconds, one |
might set the timer to 100~million (the number of clocks per second), and |
set the high bit. Ever after, the timer will interrupt the CPU once per |
second (assuming a 100~MHz clock). This reload capability also limits the |
maximum timer value to $2^{31}-1$, rather than $2^{32}-1$. |
second (assuming a 100~MHz clock). |
|
\section{Watchdog Timer} |
|
1134,12 → 1032,12
can request to be put to sleep until a certain number of `jiffies' have |
elapsed. Using this interface, the CPU can read the number of `jiffies' |
from the peripheral (it only has the one location in address space), add the |
sleep length to it, and write the result back to the peripheral. The zipjiffies |
sleep length to it, and write teh result back to the peripheral. The zipjiffies |
peripheral will record the value written to it only if it is nearer the current |
counter value than the last current waiting interrupt time. If no other |
interrupts are waiting, and this time is in the future, it will be enabled. |
(There is currently no way to disable a jiffie interrupt once set, other |
than to disable the interrupt line in the interrupt controller.) The processor |
than to disable the register in the interrupt controller.) The processor |
may then place this sleep request into a list among other sleep requests. |
Once the timer expires, it would write the next Jiffy request to the peripheral |
and wake up the process whose timer had expired. |
1159,60 → 1057,10
should be sorted, and the next alarm in terms of Jiffies should be written |
to the register. |
|
\section{Manual Cache} |
|
The manual cache is an experimental setting that may not remain with the Zip |
CPU for very long. It is designed to facilitate running from FLASH or ROM |
memory, although the pipe cache really makes this need obsolete. The manual |
cache works by copying data from a wishbone address (range) into the cache |
register, and then by making that memory available as memory to the Zip System. |
It is a {\em manual cache} because the processor must first specify what |
memory to copy, and then once copied the processor can only access the cache |
memory by the cache memory location. There is no transparency. It is perhaps |
best described as a combination DMA controller and local memory. |
|
Worse, this cache is likely going to be removed from the ZipSystem. Having used |
the ZipSystem now for some time, I have yet to find a need or use for the manual |
cache. I will likely replace this peripheral with a proper DMA controller. |
|
\chapter{Operation}\label{chap:ops} |
|
\chapter{Registers}\label{chap:regs} |
|
The ZipSystem registers fall into two categories, ZipSystem internal registers |
accessed via the ZipCPU shown in Tbl.~\ref{tbl:zpregs}, |
\begin{table}[htbp] |
\begin{center}\begin{reglist} |
PIC & {\tt 0xc0000000} & 32 & R/W & Primary Interrupt Controller \\\hline |
WDT & {\tt 0xc0000001} & 32 & R/W & Watchdog Timer \\\hline |
CCHE & {\tt 0xc0000002} & 32 & R/W & Manual Cache Controller \\\hline |
CTRIC & {\tt 0xc0000003} & 32 & R/W & Secondary Interrupt Controller \\\hline |
TMRA & {\tt 0xc0000004} & 32 & R/W & Timer A\\\hline |
TMRB & {\tt 0xc0000005} & 32 & R/W & Timer B\\\hline |
TMRC & {\tt 0xc0000006} & 32 & R/W & Timer C\\\hline |
JIFF & {\tt 0xc0000007} & 32 & R/W & Jiffies \\\hline |
MTASK & {\tt 0xc0000008} & 32 & R/W & Master Task Clock Counter \\\hline |
MMSTL & {\tt 0xc0000008} & 32 & R/W & Master Stall Counter \\\hline |
MPSTL & {\tt 0xc0000008} & 32 & R/W & Master Pre--Fetch Stall Counter \\\hline |
MICNT & {\tt 0xc0000008} & 32 & R/W & Master Instruction Counter\\\hline |
UTASK & {\tt 0xc0000008} & 32 & R/W & User Task Clock Counter \\\hline |
UMSTL & {\tt 0xc0000008} & 32 & R/W & User Stall Counter \\\hline |
UPSTL & {\tt 0xc0000008} & 32 & R/W & User Pre--Fetch Stall Counter \\\hline |
UICNT & {\tt 0xc0000008} & 32 & R/W & User Instruction Counter\\\hline |
Cache & {\tt 0xc0100000} & & & Base address of the Cache memory\\\hline |
\end{reglist} |
\caption{Zip System Internal/Peripheral Registers}\label{tbl:zpregs} |
\end{center}\end{table} |
and the two debug registers showin in Tbl.~\ref{tbl:dbgregs}. |
\begin{table}[htbp] |
\begin{center}\begin{reglist} |
ZIPCTRL & 0 & 32 & R/W & Debug Control Register \\\hline |
ZIPDATA & 1 & 32 & R/W & Debug Data Register \\\hline |
\end{reglist} |
\caption{Zip System Debug Registers}\label{tbl:dbgregs} |
\end{center}\end{table} |
|
|
\chapter{Wishbone Datasheet}\label{chap:wishbone} |
The Zip System supports two wishbone accesses, a slave debug port and a master |
port for the system itself. These are shown in Tbl.~\ref{tbl:wishbone-slave} |
1221,7 → 1069,6
\begin{wishboneds} |
Revision level of wishbone & WB B4 spec \\\hline |
Type of interface & Slave, Read/Write, single words only \\\hline |
Address Width & 1--bit \\\hline |
Port size & 32--bit \\\hline |
Port granularity & 32--bit \\\hline |
Maximum Operand Size & 32--bit \\\hline |
1247,8 → 1094,7
\begin{center} |
\begin{wishboneds} |
Revision level of wishbone & WB B4 spec \\\hline |
Type of interface & Master, Read/Write, single cycle or pipelined\\\hline |
Address Width & 32--bit bits \\\hline |
Type of interface & Master, Read/Write, sometimes pipelined \\\hline |
Port size & 32--bit \\\hline |
Port granularity & 32--bit \\\hline |
Maximum Operand Size & 32--bit \\\hline |
1270,14 → 1116,13
\caption{Wishbone Datasheet for the CPU as Master}\label{tbl:wishbone-master} |
\end{center}\end{table} |
I do not recommend that you connect these together through the interconnect. |
Rather, the debug port of the CPU should be accessible regardless of the state |
of the master bus. |
|
You may wish to notice that neither the {\tt ERR} nor the {\tt RETRY} wires |
have been implemented. What this means is that the CPU is currently unable |
to detect a bus error condition, and so may stall indefinitely (hang) should |
it choose to access a value not on the bus, or a peripheral that is not |
yet properly configured. |
The big thing to notice is that both the real time clock and the real time |
date modules act as wishbone slaves, and that all accesses to the registers of |
either module are 32--bit reads and writes. The address bus does not offer |
byte level, but rather 32--bit word level resolution. Select lines are not |
implemented. Bit ordering is the normal ordering where bit~31 is the most |
significant bit and so forth. |
|
\chapter{Clocks}\label{chap:clocks} |
|