OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 72 to Rev 73
    Reverse comparison

Rev 72 → Rev 73

/zipcpu/trunk/doc/spec.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/zipcpu/trunk/doc/iset.html
307,7 → 307,7
<H2>Native Instructions</H2>
The Zip CPU instruction set has one of two basic formats, with a small
number of exceptions. These formats are shown below:
<TABLE border>
<TABLE border align=center>
<TR><TH rowspan=2>Op Code</TH><TH colspan=8>31..24</TH>
<TH colspan=8>23..16</TH>
<TH colspan=8>15..8</TH>
411,17 → 411,36
<TR><TD>5'h1e</TD><TD rowspan=2 colspan=3 align=center><em>Reserved for future use</em></TD></TR>
<TR><TD>5'h1f</TD></TR>
</TABLE>
This leaves three instructions left: NOOP, BREAK, and LOCK. These have opcodes
of <TT>5'h19</TT>, <TT>5'h1a</TT>, and <TT>5'h1c</TT> respectively. They
are carved out of the floating point units opcodes, and differentiated by the
fact that their resulting register is either the CC or PC register. (It never
made sense to do a floating point instruction into the CC or PC register
anyway ...) The BREAK instruction is designed to trap the CPU without ever
entering into the ALU. It is useful for debugging purposes. The LOCK
instruction waits the decode and prefetch pipeline stages to fill with memory
instructions before locking the bus and letting these memory operations
complete. It is designed to support a test and set operation. (Actually,
since the Zip CPU doesn't truly support a LOCK bit on the wishbone bus, what
really happens is that the CYC line is kept high throughout the operation.
This line may be tied to a LOCK line if you would like to use the Zip CPU
with a bus that supports LOCKing.)
 
<H2>Derived Instructions</H2>
<TABLE border>
<TR><TH>Mapped</TH><TH>Actual</TH><TH WIDTH=65%>Notes</TH></TR>
<TR><TD valign=top>ABS Rx</TD><TD>TST -1,Rx<BR>NEG.LT Rx</TD><TD>Absolute
value, depends upon the derived NEG instruction below.</TD></TR>
<TR><TD valign=top>ADD Ra,Rx<BR>
ADDC Rb,Ry</TD><TD valign=top>ADD Ra,Rx<BR>ADD.C $1,Ry<BR>ADD Rb,Ry</TD><TD valign=top>Add with carry</TD></TR>
<TR><TD valign=top rowspan=2>BRA.cond +/-$Addr</TD><TD>
<TR><TD valign=top rowspan=3>BRA.cond +/-$Addr</TD><TD>
MOV.cond $Addr+PC,PC</TD><TD>Branch/jump on condition. Works for 14 bit address offsets.</TD></TR>
<TR><TD>ADD.cond $Addr,PC<TD>Branch/jump on condition that works for 18-bit
offsets, although it does set the flags.</TD></TR>
<TR><TD>LDI $Addr,Rx<BR>
ADD.cond Rx,PC</TD><TD>Branch/jump on condition. Works for
23 bit address offsets, but costs a register, an extra instruction,
and setsthe flags.</TD></TR>
23 bit address offsets, but costs a register and an extra one (or
two) instruction(s).</TD></TR>
<TR><TD valign=top>BNC PC+$Addr</TD><TD>
TEST $Carry,CC<BR>
MOV.Z PC+$addr,PC</TD>
437,18 → 456,11
<TR><TD valign=top>IRET</TD><TD>OR $GIE,CC</TD><TD>Also an RTU instruction
(Return to Userspace)</TD></TR>
<TR><TD valign=top>JMP R6+$Addr</TD><TD>MOV $Addr(R6),PC</TD><TD>&nbsp;</TD></TR>
<TR><TD valign=top rowspan=2>JSR PC+$Addr</TD><TD>
SUB $1,SP<BR>
MOV $3+PC,R0<BR>
STO R0,1(SP)<BR>
MOV $Addr+PC,PC<br>
ADD $1,SP</TD><TD>Jump to Subroutine.</TD></TR>
<TR><TD>MOV $3+PC,R12<BR>MOV $addr+PC,PC</TD><TD>This is the high speed
version of the call, necessitating a register to hold the last
PC address. In its favor, this method doesn't suffer the mandatory
memory access of the other approach.</TD></TR>
<TR><TD valign=top>JTU</TD><TD>OR $GIE,CC</TD><TD>Also known as a JUMP-To-USER
space command, also known as IRET.</TD></TR>
<TR><TD valign=top>JSR PC+$Addr</TD><TD>MOV $3+PC,R12<BR>MOV $addr+PC,PC</TD>
<TD>Jump to subroutine.
Note that this high speed version of a JSR call needs a register to
hold the last PC address. In its favor, it doesn't suffer the mandatory
memory access of the more traditional approach.</TD></TR>
<TR><TD valign=top>LDI.l $val,Rx</TD><TD>
LDIHI HIBITS($val),Rx<BR>
LDILO LOBITS($val),Rx</TD><TD>Sadly, there's not enough instruction
455,7 → 467,11
space to load a complete immediate value into any register.
Therefore, fully loading any register takes two cycles.
The LDIHI (load immediate high) and LDILO (load immediate low)
instructions have been created to facilitate this.</TD></TR>
instructions have been created to facilitate this.
Further, the assembler will quietly turn any LDI #x,Rx
instruction into this instruction if either #x doesn't fit
within the 23--bit immediate operand field, or if the
instruction is conditional.</TD></TR>
<TR><TD valign=top>LOD.b $addr,Rx</TD><TD>
LDI $addr,Ra<BR>
LDI $addr,Rb<BR>
486,7 → 502,7
LDIHI.C $8000h,Rz<BR>
LSR $1,Rx<BR>
OR Rz,Rx</TD><TD>Logical shift right with carry</TD></TR>
<TR><TD valign=top>NEG Rx</TD><TD>XOR $-1,Rx<BR>ADD $1,Rx</TD><TD>&nbsp;</TD></TR>
<TR><TD valign=top>NEG.C Rx</TD><TD>XOR.C $-1,Rx<BR>ADD.C $1,Rx</TD><TD>Negate, may be conditional</TD></TR>
<TR><TD valign=top>NOOP</TD><TD>NOOP</TD><TD>While there are many
operations that do nothing, such as MOV Rx,Rx, or OR $0,Rx, these
operations have consequences in that they might stall the bus if
493,26 → 509,29
Rx isn't ready yet. For this reason, we have a dedicated NOOP
instruction.</TD></TR>
<TR><TD valign=top>NOT Rx</TD><TD>XOR $-1,Rx</TD><TD>&nbsp;</TD></TR>
<TR><TD valign=top>POP Rx</TD><TD>LOD $-1(SP),Rx<BR>ADD $1,SP</TD><TD>Note
that for interrupt purposes, one can never depend upon the value at
(SP). Hence you read from it, then increment it, lest having
incremented it firost something then comes along and writes to that
value before you can read the result.</TD></TR>
<TR><TD valign=top>POP Rx</TD><TD>LOD (SP),Rx<BR>ADD $1,SP</TD>
<TD rowspan=2>Note
that for pipelining purposes, it helps to coalesce all the ADD (SUB)
operations into one after (before) a group of LOD (STO) instructions,
and then to do the operations in sequential order. This will guarantee
a pipelined memory operation.</TD></TR>
<TR><TD valign=top>PUSH Rx</TD><TD>
SUB $1,SP<BR>
STO Rx,$1(SP)</TD><TD>&nbsp;</TD></TR>
<TR><TD valign=top>RESET</TD><TD>STO $1,$watchdog(R12)<BR>NOOP<BR>NOOP</TD><TD>
This depends upon the peripheral base address being in R12.
<P>Another opportunity might be to jump to the reset address from within
supervisor mode.
SUB 1,SP<BR>
STO Rx,(SP)</TD></TR>
<TR><TD valign=top>RESET</TD><TD>LDI 1,R0<BR>STO R0,$watchdog(R12)<BR>NOOP<BR>NOOP</TD><TD>
This depends upon the peripheral base address already being in R12.
<P>Another opportunity might be to jump to the reset address from
within supervisor mode.
</TD></TR>
<TR><TD valign=top rowspan=2>RET</TD><TD>LOD $-1(SP),R0<BR>
MOV $-1+SP,SP<BR>
MOV R0,PC</TD><TD>An alternative might be to LOD $-1(SP),PC, followed
by depending upon the calling program to ADD $1,SP.</TD></TR>
<TR><TD>MOV R12,PC</TD><TD>This is the high(er) speed version, that doesn't
touch the stack. As such, it doesn't suffer a stall on memory
read/write to the stack.</TD></TR>
<TR><TD valign=top>RET</TD><TD>MOV R12,PC</TD><TD>
Recall that the JSR command left the address to return to in the
register set. Were that register R12, this returns us back to where
we came from. Unlike the traditional RETN structure of some other
architectures, this instruction doesn't suffer a stall on memory
read from the stack.</TD></TR>
<TR><TD valign=top>RTU</TD><TD>OR $GIE,CC</TD><TD>Also known as a Return-To-USER
space command, sometimes known as IRET (interrupt return) in
other architectures.</TD></TR>
<TR><TD valign=top>STEP Rr,Rt</TD><TD>LSR $1,Rr<BR>XOR.C Rt,Rr</TD><TD>Step a
Galois implementation of a Linear Feedback Shift Register, Rr, using
taps Rt</TD></TR>
539,19 → 558,12
XOR Rx,Ry<BR>
XOR Ry,Rx</TD><TD>While no extra registers are needed, this example
does take 3-clocks.</TD></TR>
<TR><TD valign=top>TRAP #X</TD><TD>LDILO $x,CC</TD><TD>
This approach uses the unused bits of the CC register as a TRAP
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
register value, you could equivalently load $x into the register and
then MOV it into the CC register.
<TR><TD valign=top>TRAP #X</TD><TD valign=top>LDILO $x,R0<BR>AND ~$GIE,CC</TD><TD>
This approach uses R0 as a TRAP address. It works because anytime
a user lowers the GIE flag a trap bit is also set within the CC
register. Therefore, upon entering the supervisor state, the CPU only
needs to check this bit to know that it got there via a TRAP. The
trap could be made conditional by making the AND conditional.
</TD></TR>
<TR><TD valign=top>TST Rx</TD><TD>TST $-1,Rx</TD><TD valign=top>Set the
condition codes based upon Rx. Could also do a CMP $0,Rx,
/zipcpu/trunk/doc/src/spec.tex
978,9 → 978,10
signed address offsets.\\\hline
{\tt BRA.Cond +/-\$Addr}
& \parbox[t]{1.5in}{\tt LDI \$Addr,Rx \\ ADD.cond Rx,PC}
& Branch/jump on condition. Works for
23 bit address offsets, but costs a register, an extra instruction,
and sets the flags. \\\hline
& Branch/jump on condition. Works for 23 bit address offsets, but
costs a register and an extra instruction. With LDIHI and LDILO
this can be made to work anywhere in the 32-bit address space, but yet
cost an additional instruction still. \\\hline
{\tt BNC PC+\$Addr}
& \parbox[t]{1.5in}{\tt Test \$Carry,CC \\ MOV.Z PC+\$Addr,PC}
& Example of a branch on an unsupported

powered by: WebSVN 2.1.0

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