From a80fd4bc453162f97d345fe4972f6ace3f6db07e Mon Sep 17 00:00:00 2001 From: Philip Smart <28005720+pdsmart@users.noreply.github.com> Date: Fri, 25 Oct 2019 08:26:14 +0100 Subject: [PATCH] Update README.md --- README.md | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 163 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f99ea83..0c29020 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,168 @@ Some extended instructions are under development (ie. LDIR) an exact opcode valu Implemented Instructions -![alt text](https://github.com/pdsmart/ZPU/blob/master/ImplInstructions.png "Hello") +![alt text](https://github.com/pdsmart/ZPU/blob/master/ImplInstructions.png) + +Instruction Set +| Name | Opcode | | Description | +|------------------|-----------|-----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| BREAKPOINT | 0 | 00000000 | The debugger sets a memory location to this value to set a breakpoint. Once a JTAG-like debugger interface is added, it will be convenient to be able to distinguish between a breakpoint and an illegal(possibly emulated) instruction. | +| IM | 1xxx xxxx | 1xxx xxxx | Pushes 7 bit sign extended integer and sets the a «instruction decode interrupt mask» flag(IDIM). | +| | | | | +| | | | If the IDIM flag is already set, this instruction shifts the value on the stack left by 7 bits and stores the 7 bit immediate value into the lower 7 bits. | +| | | | | +| | | | Unless an instruction is listed as treating the IDIM flag specially, it should be assumed to clear the IDIM flag. | +| | | | | +| | | | To push a 14 bit integer onto the stack, use two consecutive IM instructions. | +| | | | | +| | | | If multiple immediate integers are to be pushed onto the stack, they must be interleaved with another instruction, typically NOP. | +| | | | | +| | | | | +| | | | | +| STORESP | 010x xxxx | 010x xxxx | Pop value off stack and store it in the SP+xxxxx*4 memory location, where xxxxx is a positive integer. | +| LOADSP | 011x xxxx | 011x xxxx | Push value of memory location SP+xxxxx*4, where xxxxx is a positive integer, onto stack. | +| ADDSP | 0001 xxxx | 0001 xxxx | Add value of memory location SP+xxxx*4 to value on top of stack. | +| EMULATE | 001x xxxx | 010x xxxx | Push PC to stack and set PC to 0x0+xxxxx*32. This is used to emulate opcodes. See zpupgk.vhd for list of emulate opcode values used. zpu_core.vhd contains reference implementations of these instructions rather than letting the ZPU execute the EMULATE instruction | +| | | | | +| | | | One way to improve performance of the ZPU is to implement some of the EMULATE instructions. | +| PUSHPC | emulated | emulated | Pushes program counter onto the stack. | +| POPPC | 0000 0100 | 0000 0100 | Pops address off stack and sets PC | +| LOAD | 0000 1000 | 0000 1000 | Pops address stored on stack and loads the value of that address onto stack. | +| | | | | +| | | | Bit 0 and 1 of address are always treated as 0(i.e. ignored) by the HDL implementations and C code is guaranteed by the programming model never to use 32 bit LOAD on non-32 bit aligned addresses(i.e. if a program does this, then it has a bug). | +| STORE | 0000 1100 | 0000 1100 | Pops address, then value from stack and stores the value into the memory location of the address. | +| | | | | +| | | | Bit 0 and 1 of address are always treated as 0 | +| PUSHSP | 0000 0010 | 0000 0010 | Pushes stack pointer. | +| POPSP | 0000 1101 | 0000 1101 | Pops value off top of stack and sets SP to that value. Used to allocate/deallocate space on stack for variables or when changing threads. | +| ADD | 0000 0101 | 0000 0101 | Pops two values on stack adds them and pushes the result | +| AND | 0000 0110 | 0000 0110 | Pops two values off the stack and does a bitwise-and & pushes the result onto the stack | +| OR | 0000 0111 | 0000 0111 | Pops two integers, does a bitwise or and pushes result | +| NOT | 0000 1001 | 0000 1001 | Bitwise inverse of value on stack | +| FLIP | 0000 1010 | 0000 1010 | Reverses the bit order of the value on the stack, i.e. abc->cba, 100->001, 110->011, etc. | +| | | | | +| | | | The raison d'etre for this instruction is mainly to emulate other instructions. | +| NOP | 0000 1011 | 0000 1011 | No operation, clears IDIM flag as side effect, i.e. used between two consecutive IM instructions to push two values onto the stack. | +| PUSHSPADD | 61 | 00111101 | a=sp; | +| | | | b=popIntStack()*4; | +| | | | pushIntStack(a+b); | +| POPPCREL | 57 | 00111001 | setPc(popIntStack()+getPc()); | +| SUB | 49 | 00110001 | int a=popIntStack(); | +| | | | int b=popIntStack(); | +| | | | pushIntStack(b-a); | +| XOR | 50 | | pushIntStack(popIntStack() ^ popIntStack()); | +| LOADB | 51 | | 8 bit load instruction. Really only here for compatibility with C programming model. Also it has a big impact on DMIPS test. | +| | | | | +| | | | pushIntStack(cpuReadByte(popIntStack())&0xff); | +| STOREB | 52 | | 8 bit store instruction. Really only here for compatibility with C programming model. Also it has a big impact on DMIPS test. | +| | | | | +| | | | addr = popIntStack(); | +| | | | val = popIntStack(); | +| | | | cpuWriteByte(addr, val); | +| | | | | +| LOADH | 34 | | 16 bit load instruction. Really only here for compatibility with C programming model. | +| | | | | +| | | | pushIntStack(cpuReadWord(popIntStack())); | +| STOREH | 35 | | 16 bit store instruction. Really only here for compatibility with C programming model. | +| | | | | +| | | | addr = popIntStack(); | +| | | | val = popIntStack(); | +| | | | cpuWriteWord(addr, val); | +| | | | | +| LESSTHAN | 36 | | Signed comparison | +| | | | a = popIntStack(); | +| | | | b = popIntStack(); | +| | | | pushIntStack((a < b) ? 1 : 0); | +| LESSTHANOREQUAL | 37 | | Signed comparison | +| | | | a = popIntStack(); | +| | | | b = popIntStack(); | +| | | | pushIntStack((a <= b) ? 1 : 0); | +| ULESSTHAN | 38 | | Unsigned comparison | +| | | | long a;//long is here 64 bit signed integer | +| | | | long b; | +| | | | a = ((long) popIntStack()) & INTMASK; // INTMASK is unsigned 0x00000000ffffffff | +| | | | b = ((long) popIntStack()) & INTMASK; | +| | | | pushIntStack((a < b) ? 1 : 0); | +| ULESSTHANOREQUAL | 39 | | Unsigned comparison | +| | | | long a;//long is here 64 bit signed integer | +| | | | long b; | +| | | | a = ((long) popIntStack()) & INTMASK; // INTMASK is unsigned 0x00000000ffffffff | +| | | | b = ((long) popIntStack()) & INTMASK; | +| | | | pushIntStack((a <= b) ? 1 : 0); | +| EQBRANCH | 55 | | int compare; | +| | | | int target; | +| | | | target = popIntStack() + pc; | +| | | | compare = popIntStack(); | +| | | | if (compare == 0) | +| | | | { | +| | | | setPc(target); | +| | | | } else | +| | | | { | +| | | | setPc(pc + 1); | +| | | | } | +| NEQBRANCH | 56 | | int compare; | +| | | | int target; | +| | | | target = popIntStack() + pc; | +| | | | compare = popIntStack(); | +| | | | if (compare != 0) | +| | | | { | +| | | | setPc(target); | +| | | | } else | +| | | | { | +| | | | setPc(pc + 1); | +| | | | } | +| MULT | 41 | | Signed 32 bit multiply | +| | | | pushIntStack(popIntStack() * popIntStack()); | +| DIV | 53 | | Signed 32 bit integer divide. | +| | | | a = popIntStack(); | +| | | | b = popIntStack(); | +| | | | if (b == 0) | +| | | | { | +| | | | // undefined | +| | | | } pushIntStack(a / b); | +| MOD | 54 | | Signed 32 bit integer modulo. | +| | | | a = popIntStack(); | +| | | | b = popIntStack(); | +| | | | if (b == 0) | +| | | | { | +| | | | // undefined | +| | | | } | +| | | | pushIntStack(a % b); | +| LSHIFTRIGHT | 42 | | unsigned shift right. | +| | | | long shift; | +| | | | long valX; | +| | | | int t; | +| | | | shift = ((long) popIntStack()) & INTMASK; | +| | | | valX = ((long) popIntStack()) & INTMASK; | +| | | | t = (int) (valX >> (shift & 0x3f)); | +| | | | pushIntStack(t); | +| ASHIFTLEFT | 43 | | arithmetic(signed) shift left. | +| | | | long shift; | +| | | | long valX; | +| | | | shift = ((long) popIntStack()) & INTMASK; | +| | | | valX = ((long) popIntStack()) & INTMASK; | +| | | | int t = (int) (valX << (shift & 0x3f)); | +| | | | pushIntStack(t); | +| ASHIFTRIGHT | 43 | | arithmetic(signed) shift left. | +| | | | long shift; | +| | | | int valX; | +| | | | shift = ((long) popIntStack()) & INTMASK; | +| | | | valX = popIntStack(); | +| | | | int t = valX >> (shift & 0x3f); | +| | | | pushIntStack(t); | +| CALL | 45 | | call procedure. | +| | | | | +| | | | int address = pop(); | +| | | | push(pc + 1); | +| | | | setPc(address); | +| CALLPCREL | 63 | | call procedure pc relative | +| | | | | +| | | | int address = pop(); | +| | | | push(pc + 1); | +| | | | setPc(address+pc); | +| EQ | 46 | | pushIntStack((popIntStack() == popIntStack()) ? 1 : 0); | +| NEQ | 47 | | pushIntStack((popIntStack() != popIntStack()) ? 1 : 0); | +| NEG | 48 | | pushIntStack(-popIntStack()); | #### Hardware Variable Byte Write @@ -206,3 +367,4 @@ The original ZPU uses the Free BSD license and such the Evo is also released und | Flex ZPU repository | https://github.com/robinsonb5/ZPUFlex | | ZPUino and Eco System | http://papilio.cc/index.php?n=Papilio.ZPUinoIntroduction | | Wikipedia ZPU Reference | https://en.wikipedia.org/wiki/ZPU_(microprocessor) | +