ARM CPU Project
From ScienceZero
Contents
Goals
- Implement an ARM on a FPGA - Artix 7
- Useful completeness - Full data processing instruction set, maybe simplified in other areas
- Useful Performance - 25 MHz ARM3 or higher
Instruction set for ARM2
Hardware vectors
&00 Reset B branchThru0error &04 Undefined instruction LDR PC,UndHandler &08 SWI B decodeSWI &0C Prefetch abort LDR PC,PabHandler &10 Data abort LDR PC,DabHandler &14 Address exception LDR PC,AexHandler &18 IRQ B handleIRQ &1C FIQ FIQ code --> &FB
Register 15 (PC)
R15 NZCVIFAAAAAAAAAAAAAAAAAAAAAAAAMM 31 0 N Negative flag Z Zero flag C Carry flag V Overflow flag I Interrupt request disable F Fast interrupt request disable A Address bits. The 2LSBs are always zero, so they are used as mode bits. MM Mode Private registers 00 User mode (USR mode) 01 Fast interrupt processing mode (FIQ mode) R8-R14 10 Interrupt processing mode (IRQ mode) R13,R14 11 Supervisor mode (SVC mode) R13,R14
The instruction set
<> Optional. (x|y) Either x or y but not both. #exp Expression. Rn Register number(0-15). shift indicates one of the following: ASL (Rn|#exp) Arithmetic shift left by contents of Rn or #exp LSL (Rn|#exp) Logical shift left. ASR (Rn|#exp) Arithmetic shift right. LSR (Rn|#exp) Logical shift right. ROR (Rn|#exp) Rotate right. RRX Rotate right one bit with extend. LSB->C C->MSB ASL and LSL are the same, but LSL is preferred. #exp has a range of 0-31.
Condition codes
AL Always This is the default CC Carry clear C=0 CS Carry set C=1 EQ Equal Z=1 GE Greater than or equal N=V GT Greater than N=V and Z=0 HI Higher (unsigned) C=1 and Z=0 LE Less than or equal N<>V or Z=1 LS Lower or same (unsigned) C=0 or Z=1 LT Less than N<>V MI Negative N=1 NE Not equal Z=0 NV Never **Do not use**, NOP = MOV R0,R0 PL Positive N=0 VC Overflow clear V=0 VS Overflow set V=1 LO Lower (unsigned) same as CC HS Higher/same (unsigned) same as CS
Arithmetic and logical instructions
opcode<cond>Rd,<Rn>,(#exp|Rm<,shift>) #exp has a range of X ROR N*2 X=0-255 N=0-15 ADC Add with carry Rd=Rn+Rm+C ADD Add Rd=Rn+Rm SBC Subtract with carry Rd=Rn-Rm-(1-C) SUB Subtract Rd=Rn-Rm RSC Reverse subtract with carry Rd=Rm-Rn-(1-C) RSB Reverse subtract Rd=Rm-Rn AND Bitwise AND Rd=Rn AND Rm BIC Bitwise AND NOT Rd=Rn AND (NOT Rm) ORR Bitwise OR Rd=Rn OR Rm EOR Bitwise EOR Rd=Rn EOR Rm MOV Move Rd=Rm
Comparisons
opcode<cond><S|P> Rn,(#exp|Rm<,shift>) CMN Compare Rn+Rm CMP Compare Rn-Rm TEQ Test equal Rn EOR Rm TST Test Rn AND Rm "P" can set the PSR to a given value if in a privileged mode.
Multiply instructions
MUL<cond><S> Rd,Rm,Rs Multiply Rd=Rm*Rs MLA<cond><S> Rd,Rm,Rs,Rn Multiply-accumulate Rd=Rm*Rs+Rn Integer multiplication returns 32LSB of product of two 32bit operands. Rd must not be R15 or same as Rm. Timing is dependent of Rs. If "S" is given, N and Z are set on the result, C and V are undefined.
Branching instructions
B<cond> expression Branch, PC+=expression BL<cond> expression Branch and link, R14=PC+4&PSR & PC+=expression
Single register/memory swap instruction (ARM3 or higher)
SWP<cond> Rdest,Rsrc,[Rbase]
Single register load/store instructions
LDR<cond><B><T> Rd,(address|#exp) #exp has a range of +-4095 bytes. STR<cond><B><T> Rd,(address|#exp) "B" Byte transfer. "T" Force address translation from a privileged mode. (Not pre-index!)
Address syntax
"!" update Rn after use pre-index post-index [Rn] [Rn,#exp]<!> [Rn],#exp [Rn,<->Rm]<!> [Rn],<->Rm [Rn,<->Rm,shift #s]<!> [Rn],<->Rm,shift #s
The PSR is never modified. The PSR flags are not used if Rn=R15. (PC is 8 bytes ahead, pipelining!) The PSR flags are used when the PC is used as Rm.
Multiple load/store instructions
LDM<cond>type Rn<!>,{Rlist}<^> STM<cond>type Rn<!>,{Rlist}<^> "!" update Rn after use For a load with R15 in the list "^" forces update of the PSR. Otherwise "^" forces the load/store to access the User mode registers. Rn is taken from the current bank, so update of Rn goes to the User bank. Rlist is a list of register to transfer in a low to high order. type DA Decrement Rn After EA Empty Ascending stack DB Decrement Rn Before ED Empty Descending stack IA Increment Rn After FA Full Ascending stack IB Increment Rn Before FD Full Descending stack
In an empty stack the stack pointer points to first free slot. In a full stack the SP points to the last data item written to it. An ascending stack grows from low to high memory addresses. A descending stack grows from high to low memory addresses.
You can always load the base register(Rn). Only if Rn is the lowest register then the original Rn is stored.
This will only have effect if you use "!".
If R15 is in the Rlist:
The PSR is saved with the PC, the PC is 12 bytes ahead. The PSR is only loaded if you use "^", the mode decides what to update.
If R15 is used as Rn:
The PSR is used as a part of the address!. Write back is switched off.
SWI instruction
SWI<cond> <expression> Software interrupt used for system calls The R14_svc will be corrupted if you execute a SWI in SVC mode.
Instruction set binary representation
=Documentation=