ARHITEKTURA
===========

*) OPSTE INFORMACIJE

-- 32-bitni RISC procesor (32-bitni registri, 32-bitne magistrale podataka i adresa).
-- Little endian arhitektura
-- Load/Store arhitektura

*) SKUP REGISTARA:

-- 16 32-bitnih registara opste namene: r0-r15
-- 32bitni programski brojac: PC
-- 4bitni statusni registar: PSW (O,S,Z,C)

*) SKUP INSTRUKCIJA:

-- INSTRUKCIJE ZA MEMORIJSKE TRANSFERE:

LDR  reg, adr24 // (ucitava vrednost sa adrese u registar)
LDC  reg, c24   // (ucitava konstantu)
STR  reg, adr24 // (cuva registar na datu adresu)
LDI dest_reg, adr_reg // (ucitava vrednost sa adrese koja je sadrzana u
                          adr_reg)
STI dest_reg, adr_reg // (cuva vrednost registra na adresu koja je
                      //  sadrzana u adr_reg)

KODIRANJE:
       adr + 3  adr + 2   adr + 1   adr
  LDR: aaaaaaaa aaaaaaaa aaaaaaaa 0000rrrr
  LDC: cccccccc cccccccc cccccccc 0001rrrr
  STR: aaaaaaaa aaaaaaaa aaaaaaaa 0010rrrr
  LDI: 00000000 00000000 aaaadddd 10110000  
  STI: 00000000 00000000 aaaadddd 10110001

NAPOMENA: U gornjim instrukcijama, adr24 se mnozi sa 4 (tj. dopisuju
se 2 nule) i dobijena vrednost se tumaci kao oznacen broj u potpunom
komplementu koji se dodaje na PC da bi se dobila adresa operanda.
Drugim recima, u pitanju je relativno adresiranje. S obzirom da se
adresa uvek mnozi sa 4, sledi da ovaj procesor moze da adresira samo
podatke koji su poravnati na adresi koja je deljiva sa 4 u memoriji.

NAPOMENA: Konstanta c24 se takodje tumaci kao broj u potpunom
komplementu.

-- ARITMETICKO LOGICKE INSTRUKCIJE:

CMP r1, r2    //  (r1 - r2)
TST r1, r2    // (r1 & r2)
ADD r1, r2    // (r1 += r2)
ADC r1, r2    // (r1 += r2 + CF)
SUB r1, r2    // (r1 -= r2)
INC r1        // r1++
DEC r1        // r1--
NEG r1        // r1 = -r1
AND r1, r2    // (r1 &= r2)
OR  r1, r2    // (r1 |= r2)
XOR r1, r2    // (r1 ^= r2)
NOT r1        // r1 = ~r1
SHL r1, r2    // (r1 <<= r2)
SHR r1, r2    // (r1 >>= r2)
SAR r1, r2    // (r1 >>>= r2)
MOV r1, r2    // (r1 = r2)


KODIRANJE:
     adr + 3  adr + 2   adr + 1   adr
CMP: 00000000 00000000 ssssdddd 10000000   
TST: 00000000 00000000 ssssdddd 10000001 
ADD: 00000000 00000000 ssssdddd 10000010 
ADC: 00000000 00000000 ssssdddd 10000011 
SUB: 00000000 00000000 ssssdddd 10000100 
INC: 00000000 00000000 0000dddd 10000101 
DEC: 00000000 00000000 0000dddd 10000110 
NEG: 00000000 00000000 0000dddd 10000111 
AND: 00000000 00000000 ssssdddd 10001000 
OR:  00000000 00000000 ssssdddd 10001001 
XOR: 00000000 00000000 ssssdddd 10001010 
NOT: 00000000 00000000 0000dddd 10001011 
SHL: 00000000 00000000 ssssdddd 10001100
SHR: 00000000 00000000 ssssdddd 10001101
SAR: 00000000 00000000 ssssdddd 10001110
MOV: 00000000 00000000 ssssdddd 10001111

NAPOMENA: Ideja je da sve instrukcije budu 32-bitne, sto neke
instrukcije cini nepotrebno dugackim, sa gomilom vodecih nula, ali
pojednostavljuje dizajn samog procesora.


-- INSTRUKCIJE SKOKA SA RELATIVNOM ADRESOM

JMP adr24   // bezuslovni skok    
JE  adr24   // skace ako je =    
JNE adr24   // skace ako je !=
JA  adr24   // skace ako je > (neoznaceno)
JB  adr24   // skace ako je < (neoznaceno)
JAE adr24   // skace ako je >= (neoznaceno)
JBE adr24   // skace ako je <= (neoznaceno)
JL  adr24   // skace ako je < (oznaceno)
JG  adr24   // skace ako je > (oznaceno)
JLE adr24   // skace ako je <= (oznaceno)
JGE adr24   // skace ako je >= (oznaceno)

KODIRANJE:
     adr + 3  adr + 2   adr + 1   adr
JMP: aaaaaaaa aaaaaaaa aaaaaaaa 01000000 
JE:  aaaaaaaa aaaaaaaa aaaaaaaa 01000001 
JNE: aaaaaaaa aaaaaaaa aaaaaaaa 01000010   
JA:  aaaaaaaa aaaaaaaa aaaaaaaa 01000011   
JB:  aaaaaaaa aaaaaaaa aaaaaaaa 01000100   
JAE: aaaaaaaa aaaaaaaa aaaaaaaa 01000101   
JBE: aaaaaaaa aaaaaaaa aaaaaaaa 01000110   
JG:  aaaaaaaa aaaaaaaa aaaaaaaa 01000111   
JL:  aaaaaaaa aaaaaaaa aaaaaaaa 01001000   
JGE: aaaaaaaa aaaaaaaa aaaaaaaa 01001001   
JLE: aaaaaaaa aaaaaaaa aaaaaaaa 01001010   

NAPOMENA: Adresa adr24 se tumaci na isti nacin kao i kod LDR i STR
instrukcija (relativno adresiranje).


-- INSTRUKCIJE SKOKA SA ADRESOM U REGISTRU

Znacenje ovih instrukcija je analogno prethodnim,
ali se (apsolutna) adresa zadaje u nekom registru

JMPI reg
JEI  reg       
JNEI reg
JAI  reg
JBI  reg
JAEI reg
JBEI reg
JLI  reg
JGI  reg
JLEI reg
JGEI reg

KODIRANJE:

       adr + 3  adr + 2   adr + 1   adr
JMPI: 00000000 00000000 rrrr0000 11000000 
JEI:  00000000 00000000 rrrr0000 11000001 
JNEI: 00000000 00000000 rrrr0000 11000010 
JAI:  00000000 00000000 rrrr0000 11000011 
JBI:  00000000 00000000 rrrr0000 11000100 
JAEI: 00000000 00000000 rrrr0000 11000101 
JBEI: 00000000 00000000 rrrr0000 11000110 
JGI:  00000000 00000000 rrrr0000 11000111 
JLI:  00000000 00000000 rrrr0000 11001000 
JGEI: 00000000 00000000 rrrr0000 11001001 
JLEI: 00000000 00000000 rrrr0000 11001010 


-- INSTRUKCIJA ZAUSTAVLJANJA:

HALT // prekida rad procesora, tj. dovodi ga u zavrsno stanje

KODIRANJE:
      adr + 3  adr + 2   adr + 1   adr
HALT: 00000000 00000000 00000000 11111111


*) FLEGOVI PROCESORA (REGISTAR PSW)

Azuriraju se samo prilikom izvrsavanja aritmetickih instrukcija

   -- z: aktivira se kada je rezultat operacije 0
   -- s: aktivira se kada je najvisi bit rezultata 1
   -- o: aktivira se kada se detektuje oznaceno prekoracenje
         pri sabiranju, oduzimanju i pomeranju u levo
   -- c: aktivira se kada se detektuje prekoracenje pri
         sabiranju, oduzimanju, kao i kada je poslednji
	 istisnuti bit prilikom pomeranja jednak 1
   

*) PRIMERI PROGRAMA U ASEMBLERU OPISANOG PROCESORA

Sledeci primer racuna maksimum niza brojeva koji je
konstantno zadat u data sekciji svojom adresom (array).
Napomenimo da se instrukcija oblika:

ldc r1, array

cesto ne moze prevesti kao jedna masinska instrukcija, jer nama treba
apsolutna adresa, a instrukcija moze sadrzati samo 24-bitnu konstantu
koja moze biti pomeraj u odnosu na adresu tekuce instrukcije.
Zbog toga asembler ovu instrukciju prevodi u niz instrukcija kojima
se najpre ucita neka manja konstanta na osnovu koje se aritmetickim
instrukcijama preracunava apsolutna adresa.

.data

array: .int 5, 2, 7, 12, -5, 8, 1

result: .int 0

.text

start:
    ldc r1, array # ucitavamo adresu pocetka niza
    ldc r2, 7 # ucitavamo duzinu niza
    ldc r3, 0 # ucitavamo 0 u r3 (zbog poredjenja)
    ldc r5, 4 # ucitacamo 4 u r5 (zbog dodavanja)
    ldc r6, 1 # ucitavamo 1 u r6

    ldi r4, r1 # ucitavamo *r1, tj. 0-ti elem. niza 
    add r1, r5  # r1+=4
    sub r2, r6  # r2--
sledeci:
    cmp r2, r3    # ako je r2 == 0
    je poslednji

    ldi r8, r1 # ucitavamo *r1, tj. tekuci elem.

    cmp r8, r4  # poredimo tekuci i najveci
    jg veci
    jmp preskoci
veci:
    mov r4, r8  # ako je veci, sada je on novi najveci
preskoci:
    add r1, r5  # r1+=4
    sub r2, r6  # r2--
    jmp sledeci
poslednji:
    str r4, result
    halt

Jednostavan primer koji sabira dva cela broja:

.data
x: .int 6
y: .int 11
z: .int 0
.text
start:
   ldr r0, x
   ldr r1, y
   add r0, r1
   str r0, z
   halt

Izracunavanje maksimuma dva broja:

.data
x: .int 6
y: .int 11
z: .int 0
.text
start:
   ldr r0, x
   ldr r1, y
   cmp r0, r1
   jl Y
   jmp X
Y:
   mov r0, r1
X:
   str r0, z 
   halt

Izracunavanje NZD-a dva broja:

while(x != y)
{
  if(x > y)
   x = x - y;
  else
   y = y - x;
}


.data
x: .int 12
y: .int 18
z: .int 0
.text
start:
   ldr r0, x
   ldr r1, y
petlja:
   cmp r0, r1
   je kraj_petlje
   ja x_vece
   sub r1, r0
   jmp petlja
x_vece:
   sub r0, r1
   jmp petlja   
kraj_petlje:
   str r0, z

*) ORGANIZACIJA PROCESORA

Procesor ima:

-- dve interne 32-bitne magistrale za transfer podataka (A i B)
-- 32-bitnu ALU jedinicu sa 16 operacija
-- 32-bitni registar MAR koji je povezan na magistralu adresa
-- 32-bitni registar MDR koji je povezan na magistralu podataka
-- Kolo sa registrima opste namene
-- Instrukcioni 16-bitni registar IR (sadrzi OPC i kodove registara po potrebi)
-- 32-bitni PC registar
-- 4-bitni PSW registar
-- 32-bitni AC registar (akumulator za privremeno cuvanje rezultata ALU jedinice)
-- Kontrolnu jedinicu


*) MAGISTRALA 

  -) U nasem modelu racunara imacemo jednu sinhronu paralelnu razdvojenu
     magistralu sa 32-bitnom magistralom podataka i 32-bitnom adresnom
     magistralom.

  -) Postoje sledeci kontrolni signali:

     *) bus_request: ovaj signal master uredjaj (u nasem primeru
     	procesor) salje kolu za arbitrazu magistrale, zahtevajuci
     	pristup magistrali. Podrazumevano je 0 (nema zahteva za
     	magistralom), a postavlja se na 1 kada zelimo da dobijemo
     	pristup magistrali. Ovaj signal se po protokolu postavlja na
     	uzlaznoj ivici casovnika. Iskljucuje se kada master dobije
	pristup magistrali (tj. kada stigne bus_grant signal).

     *) bus_grant: ovaj signal kolo za arbitrazu magistrale salje
        master uredjaju, kako bi ga obavestio da mu je dodeljena
        magistrala. Podrazumevano je 0, a dobija vrednost 1 kada je
        magistrala dodeljena procesoru. Kolo za arbitrazu ne sme
        dodeliti magistralu drugom uredjaju dokle god je transakcija u
        toku (sto se vidi na osnovu bus_in_use signala). Dakle, u
        pitanju je politika oslobadjanja magistrale bez preuzimanja
        (non-preemptive), pri cemu master oslobadja magistralu cim
        zavrsi transakciju. bus_grant signal se ukljucuje na silaznoj
        ivici casovnika, a iskljucuje se na sledecoj silaznoj ivici (u
        tom trenutku je transakcija vec zapocela).

     *) bus_in_use: ovaj signal master postavlja na magistralu da
        bi ostalim uredjajima (i arbitru) naznacio da je zapoceo
	transakciju. Ovaj signal ostaje ukljucen dokle god se ne
	zavrsi transakcija. Ukljucuje se na negativnoj ivici casovnika
	(na prvoj sledecoj negativnoj ivici nakon sto arbitar
	ukljuci bus_grant signal).

     *) bus_command: ovaj signal master salje slave-u da naznaci da
     	li je u pitanju operacija citanja ili pisanja (0 za citanje,
	1 za pisanje). Podrazumevano ima vrednost z. Ukljucuje se
	kad i bus_in_use signal, na negativnoj ivici casovnika i
	ukljucen je dokle god traje transakcija. 

     *) bus_wait: ovaj signal slave salje masteru preko magistrale
        ukoliko nije u stanju da izvrsi trazenu operaciju na prvoj
        sledecoj uzlaznoj ivici nakon zapocetka transakcije (sto je
        podrazumevano ponasanje). bus_wait = 1 znaci da se mora cekati
        jos jedan ciklus (ubacivanjem stanja cekanja u konacni automat
        mastera) da bi se tek na sledecoj uzlaznoj ivici ponovo
        proverio status bus_wait signala. bus_wait = 0 znaci da je
        operacija uspesno izvrsena i da mozemo da zavrsimo
        transakciju.



DIAGRAM SIGNALA ZA OPERACIJU CITANJA:

MASTER:    Start  GrantWait BusComm   BusWait   End
                 T1        T2        T3        T4        T5
                  ____      ____      ____      ____      ____
 clk:          __|    |____|    |____|    |____|    |____|    |____|

                  _________
bus_request:   __|         |________________________________________
      
                       _________
bus_grant:     _______|         |___________________________________
                                 _________
bus_in_use:    _________________|         |_________________________

bus_command:   zzzzzzzzzzzzzzzzzz_________zzzzzzzzzzzzzzzzzzzzzzzzzz

addr:          zzzzzzzzzzzzzzzzzz---------zzzzzzzzzzzzzzzzzzzzzzzzzz

data:          zzzzzzzzzzzzzzzzzzzzzzz---------zzzzzzzzzzzzzzzzzzzzz
                                      
bus_wait:      _____________________________________________________

SLAVE:                        Idle      Done     Idle


DIAGRAM SIGNALA ZA OPERACIJU CITANJA SA STANJEM CEKANJA:

MASTER:    Start  GrantWait  BusComm   BusWait  BusWait   End
                 T1        T2        T3        T4        T5
                  ____      ____      ____      ____      ____
 clk:          __|    |____|    |____|    |____|    |____|    |____|

                  _________
bus_request:   __|         |________________________________________
      
                       _________
bus_grant:     _______|         |___________________________________
                                 ___________________
bus_in_use:    _________________|                   |_______________

bus_command:   zzzzzzzzzzzzzzzzzz___________________zzzzzzzzzzzzzzzz

addr:          zzzzzzzzzzzzzzzzzz-------------------zzzzzzzzzzzzzzzz

data:          zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz---------zzzzzzzzzzz
                                       ________
bus_wait:      _______________________|        |____________________

SLAVE:                        Idle       Work      Done      Idle



DIAGRAM SIGNALA ZA OPERACIJU PISANJA:

MASTER:    Start  GrantWait  BusComm   BusWait   End
                 T1        T2        T3        T4        T5
                  ____      ____      ____      ____      ____
 clk:          __|    |____|    |____|    |____|    |____|    |____|

                  _________
bus_request:   __|         |________________________________________
      
                       _________
bus_grant:     _______|         |___________________________________
                                 _________
bus_in_use:    _________________|         |_________________________
                                 _________
bus_command:   zzzzzzzzzzzzzzzzzz         zzzzzzzzzzzzzzzzzzzzzzzzzz

addr:          zzzzzzzzzzzzzzzzzz---------zzzzzzzzzzzzzzzzzzzzzzzzzz

data:          zzzzzzzzzzzzzzzzzz---------zzzzzzzzzzzzzzzzzzzzzzzzzz
                
bus_wait:      _____________________________________________________

SLAVE:                         Idle     Done    Idle



DIAGRAM SIGNALA ZA OPERACIJU PISANJA SA STANJEM CEKANJA:

MASTER:    Start  GrantWait BusComm   BusWait   BusWait   End
                 T1        T2        T3        T4        T5
                  ____      ____      ____      ____      ____
 clk:          __|    |____|    |____|    |____|    |____|    |____|

                  _________
bus_request:   __|         |________________________________________
      
                       _________
bus_grant:     _______|         |___________________________________
                                 ___________________
bus_in_use:    _________________|                   |_______________
                                 ___________________
bus_command:   zzzzzzzzzzzzzzzzzz                   zzzzzzzzzzzzzzzz

addr:          zzzzzzzzzzzzzzzzzz-------------------zzzzzzzzzzzzzzzz

data:          zzzzzzzzzzzzzzzzzz-------------------zzzzzzzzzzzzzzzz
                                      _________
bus_wait:      ______________________|         |____________________

SLAVE:                         Idle     Work      Done     Idle



NAPOMENA: Stanje Start moze biti bilo koje stanje automata koje
prethodi zahtevu za transfer. Stanje End moze biti bilo koje stanje
koje sledi nakon uspesno zavrsenog transfera. U najprostijem modelu,
operacija citanja se obavlja u dva slucaja:

1) Dohvatanje instrukcije
2) Dohvatanje operanada

Pisanje u memoriju se vrsi u slucaju upisivanja rezultata
izracunavanja u memoriju.

MEMORIJA:

*) U pitanju je jednostavan model 4GB memorije. Memorija je bajt
adresibilna, ali podrazumeva da su svi transferi poravnati na adresi
koja je deljiva sa 4, pa se najniza dva bita adrese ignorisu
(podrazumeva se da su nule). 
