OpenCores
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}
 

powered by: WebSVN 2.1.0

© copyright 1999-2022 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.