ARM CPU Project

From ScienceZero
Revision as of 17:18, 13 May 2016 by Bjoern (Talk | contribs)

Jump to: navigation, search

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

Plan

  • Start with emulation in software

Instruction set for ARM2

Programming model

After system reset, the ARM begins processing at address &0, with interrupts disabled and in SVC mode. This address is the location of the Reset Vector, which should be a branch to the reset code.

Modes

Mode                   Short  MM    Description                               Shadow registers
User mode              usr    0b00  Normal program execution, no privileges   None
Fast interrupt Request fiq    0b01  Fast interrupt handling                   R8 - R14
Interrupt request      irq    0b10  Normal interrupt handling                 R13, R14
Supervisor             svc    0b11  Privileged mode for the operating system  R13, R14

Hardware vectors

0x00  Reset                      B     branchThru0error
0x04  Undefined instruction      LDR   PC,UndHandler
0x08  SWI                        B     decodeSWI
0x0C  Prefetch abort             LDR   PC,PabHandler
0x10  Data abort                 LDR   PC,DabHandler
0x14  Address exception          LDR   PC,AexHandler
0x18  IRQ                        B     handleIRQ
0x1C  FIQ                        FIQ   code --> 0xFB

Registers

R0-R12
 General purpose
R13 (SP)
 General purpose, commonly used as stack pointer
R14 (LR)
 Link register, PC is copied to R14 by Branch-link instructions
 Can be used as general purpose if correctly saved and restored

R15 (PC)
 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 2 LSBs are always zero.
M Mode

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 bitwise instructions

opcode<cond><S> 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.
"S" is default behaviour

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><B> 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
Set the processor to SVC mode, and then the processor jumps to the reset vector at address 0x8.
The R14_svc will be corrupted if you execute a SWI in SVC mode.

Instruction set binary representation

Documentation