URL
https://opencores.org/ocsvn/tinycpu/tinycpu/trunk
Subversion Repositories tinycpu
[/] [tinycpu/] [trunk/] [docs/] [design.md.txt] - Rev 17
Go to most recent revision | Compare with Previous | Blame | View Log
This is the design of TinyCPU. It's goals are as follows:1. 8-bit registers and operations (8 bit processor)2. 16-bit address bus3. fixed 16-bit instruction length4. use a small amount of "rich" instructions to do powerful things5. 1 instruction per clock cycleRelative moves:In order to provide uesfulness to the segment-carryover feature, there are a few options for moving a "relative" amount to a register, including IP and SPA relative move differs in most of the opcodes in that the relative factor is treated as a signed value.so for instance, amov r0,50mov_relative r0, -10in the ned, r0 will end up being 40. Although this feature won't see much use in general registers, IP and SP are special because of the option of using thesegment-carryover feature. This means that SP and IP, while being 8-bit registers, can function very similar to a 16-bit register, enabling full usage of the available address space.Register list:r0-r5 general purpose registerssp stack pointer (represented as r6)ip instruction pointer register (represented as r7)cs, ds, es, ss segment registers (code segment, data segment, extra segment, stack segment)tr truth register for conditionalsgeneral opcode formatfirst byte:first 4 bits: actual instructionnext 3 bits: (target) registerlast 1 bit: conditionalsecond byte:first 1 bit: second portion of condition (if not immediate) (1 for only if false)next 1 bit: use extra segmentnext 3 bits: other register. If not 3rd register, top bit specifies which register bank, others unusedlast 3 bits: extra opcode information or third register. such as for ADD it could be target=source+third_register...or second byte is immediate valueFor opcodes requiring 3 registers but without room, the target opcode is assume to be the second operation. Such as for AND, target=source AND targetshort list of instructions: (not final, still planning)immediates:1. move reg, immediate2. move [reg], immediate3. push and move reg, immediate (or call immediate)4. push immediate5. move (relative) reg, immediategroups: (limited to 2 registers and no immediates. each group has 8 opcodes)group 1:move(store) [reg],regmove(load) reg,[reg]out reg1,reg2 (output to port reg1 value reg2)in reg1,reg2 (input from port reg2 and store in reg1)pop regpush regmove segmentreg,regmove reg,segmentreggroup 2:and reg1,reg2 (reg1=reg1 and reg2)or reg, regxor reg,regnot reg1,reg2 (reg1=not reg2)left shift reg,regright shift reg,regrotate right reg,regrotate left reg,reggroup 3: comparesis greater than reg1,reg2 (TR=reg1>reg2)is greater or equal to reg,regis less than reg,regis less than or equal to reg,regis equal to reg,regis not equal to reg,regequals 0 regnot equals 0 reggroup 4:push segmentregpop segmentregpush and move reg, reg (or call reg)exchange reg,regexchange reg,segclear TRSet TRgroup 5:increment regdecrement regfar jmp reg1, reg2 (CS=reg1 and IP=reg2)far call reg1,reg2far jmp [reg] (first byte is CS, second byte is IP)push extended segmentreg, reg (equivalent to push seg; push reg)pop extended segmentreg, reg (equivalent to pop reg; pop seg)reset processor (will completely reset the processor to starting state, but not RAM or anything else)group 6:set default register bank to 0 (can be condensed to 1 opcode)set default register bank to 1push extended reg, regpop extended reg,regenable carryover segdisable carryover segmov relative reg, regexchange reg, reg3 register instructions:1. add reg1, reg2, reg3 (reg1=reg2+reg3)2. sub reg1, reg2, reg3opcodes used: 13 of 16. 3 more opcodes available. Decide what to do with the room later.Possible canidates for opcode compression include* Push immediate (room for 3 sub-opcodes)* push and pop reg (room for 7 sub-opcodes each)* equals 0 and not equals 0 (room for 7 sub-opcodes each)* Set TR and Reset TR (room for 64 opcodes each)* increment and decrement reg (room for 7 opcodes each)* enable and disable carry over (room for 7 opcodes each)* set register bank 0 and 1 (room for 64 opcodes each)0 -nop (doesn't do a thing)1 -move immediate (only uses first byte)2 -move3 -push4 -push immediate5 -push and move (or call when acting on ip)6 -compare (is less than, is less than or equal, is greater than, is greater than or equal, is equal, is not equal) (6 conditions room for 2 more in extra)7 -add8 -subtract9 -bitwise operations (xor, or, and, shift right, shift left, not)x -multiply (if room)x -divideconditionals0 -- always1 -- only if truefor only if false, there should basically be another compare or if applicable an always afterwardspushpopmoveaddsublimitations that shouldn't be passed with instructions* Doing 2 memory references* pushing a memory reference (equates to 2 memory references)Note it is possible however to read and write 16bits at one time to the memory to consecutive addresses.segments:DS is used in all "normal" memory referencesSS is used in all push and pop instructionsES is used when the ExtraSegment bit is set for either push/pop or normal memory referencesCS is only used for fetching instructionsSegment carryover:In order to overcome the limitations of only having a 256 byte segment, there is a workaround option to "pretend" that IP is a 16 bit register.When CS carryover is enabled, when IP rollover from 255 to 0 or whatever, CS will be incremented. This makes it so that if you start at address 0:0.you can continue as far as needed into the address space without having to do ugly far jumps at each of the borders.Carryover can only be done on CS and SS. The required circuitry is not implemented for DS or ES due to an extreme level of complexity required for it, alsoit would only lead to unncessarily complex codeAlso of note is that `move relative` implements a "carryover" component. This component will work on either IP or SP, and uses CS and SS respectively.If used on other registers, there will be no carry over functionality, though it can be used as an easy way to add or subtract an immediate from a register.States needed:0. reset1. decode current instruction (All without memory capable within 1 clock cycle)2. increment IP(and SP if needed) and fetch next instruction3. Write 1 register to memory4. Read 1 register from memory5. Write 2 registers to memory6. Read 2 registers from memory7. Write 1 register to memory and setup increment of sp8. Write 2 registers to memory and setup double increment of sp9. Read 1 register from memory and setup decrement of sp10. Read 2 registers from memory and setup double decrement of sp11.registerfile map:0000: general r00001: general r10010: general r20011: general r30100: general r40101: general r50110: SP (r6)0111: IP (r7)1000: second bank r01001: second bank r11010: second bank r21011: second bank r31100: CS1101: DS1110: ES1111: SSBanking works like if(regnumber(2) = '0') then regnumber(3)=regbank; end if;ALU operations00000 and reg1,reg2 (reg1=reg1 and reg2)00001 or reg, reg00010 xor reg,reg00011 not reg1,reg2 (reg1=not reg2)00100 left shift reg,reg (logical)00101 right shift reg,reg (logical)00110 rotate right reg,reg00111 rotate left reg,reg01000 is greater than reg1,reg2 (TR=reg1>reg2)01001 is greater or equal to reg,reg01010 is less than reg,reg01011 is less than or equal to reg,reg01100 is equal to reg,reg01101 is not equal to reg,reg01110 equals 0 reg01111 not equals 0 reg10000 Set TR10001 Reset TR10011 Increment10010 Decrement10100 Add10101 Subtract
Go to most recent revision | Compare with Previous | Blame | View Log
