This is an old revision of the document!


0. Friendly reminders

Cum citim un datasheet? ATTiny20

Interpretare documentație instrucțiune

Interpretare documentație instrucțiune

Mai jos avem reprezentarea binară a instrucțiunii add R5, R3:

Bit index 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Bit value 0 0 0 1 1 1 1 1 0 1 0 1 0 0 1 1
Bit significance opcode Rd Rr Rd Rr

Fiindcă register file-ul procesorului nostru (ATtiny20) are doar 16 registre, putem ignora biții Rr si Rd de pe pozițiile 9 și 8 (Atmel garantează că, din motive de compatibilitate, vor fi mereu setați pe 1, sau, echivalent, vor fi folosite numai registrele R16R31). Așadar, instrucțiunile add R21, R19 și add R5, R3 sunt echivalente în implementarea noastră.

Mereu filtrați de la instrucțiunile cele mai particulare (cele care au partea constanta cea mai mare) până la cele mai generale (au partea constanta mai mica). Adică? dintre opcode-ul 1) 0000_1111_1010_0101 și opcode-ul 2) 1111_0101_10rr_rddd mai particulara este 1.

Veți observa că în datasheet veți găsi opcode-uri pe 16 și pe 32 de biți (pentru instrucțiuni). În cadrul laboratoarelor de CN veți folosi doar instrucțiuni pe 16 biți, deoarece am ales să implementăm o versiune mai restrânsă a procesorului, care nu are acces la toate resursele sale. De exemplu: nu avem 32 de registre locale, ci doar 16.

1. Overview

1.1. Legătura memorie-microprocesor. System bus

Pentru a asigura comunicația dintre procesor, memorie și periferice le vom interconecta pe toate într-o topologie de tip magistrala. Aceasta este un mediu partajat de comunicație, în sensul că există un singur set de semnale (de control, date și adrese) la care au acces toate modulele conectate (spre deosebire de o topologie punct-la-punct unde există o legătură separată între fiecare modul care dorește să comunice cu altul).

Magistrala de sistem este, pe scurt, o magistrală care conectează procesorul de memoria principala și de periferice. Magistrala de sistem trebuie sa aibă, în general, 3 componente:

  • linii de control
  • linii de adrese
  • linii de date





Soluții conflicte pe magistrală

Soluții conflicte pe magistrală

În general, pentru comunicația mai multor module pe o magistrala, trebuie stabilit un protocol de comunicație (trebuie evitată situația în care există mai mulți vorbitori concomitenți pe aceeași linie, fiindcă acest gen de conflicte pot duce la scurtcircuite și alte probleme de natură electrică. În practică, există un bus master și mai mulți bus slaves. Nu întâmplător, în cazul nostru bus master va fi CPU-ul iar, momentan, singurul slave de pe system bus este memoria.

Ierarhii de magistrale

Ierarhii de magistrale

În sistemele desktop, system bus, adică o singură magistrala general-purpose, a fost demult înlocuita cu o ierarhie de magistrale (unele locale, altele externe) de viteze si lățimi de bandă diferite. Astfel, pentru asigurarea conectivității la memorie, un CPU x86 folosește un memory controller hub, care se ocupă de interfațarea propriu-zisă (generarea semnalelor de control) pentru memoria SDRAM conectată pe placa de bază.

Istoric, acest controller de memorie s-a aflat pe un chip extern procesorului, dar situat pe placa de baza în apropierea acestuia, numit Northbridge. Magistrala de mare viteza dintre CPU și Northbridge se numește Front-side bus (sau FSB, pe scurt) pentru sistemele Intel, sau EV6, pentru implementarea cu același rol de la AMD.


1.2. Moduri de adresare

Modurile de adresare a memoriei descriu metoda prin care este calculată adresa efectivă a datelor accesate, folosind informații constante și/sau conținute în registre. Pentru a fi mai flexibil pentru programatori un ISA va implementa mai multe moduri de adresare a memoriei, fiecare cu avantaje și dezavantaje. Aceste moduri pot fi folosite prin diferite instrucțiuni. Mai departe ne vom uita peste modurile de adresare a memoriei de date disponibile pe arhitectura AVR.

Spațiul de adrese

Organizarea spatiului de adresa pe ATTiny20

Figura precedentă descrie organizarea spațiului de adresă pentru ATTiny20. Memoria RAM ocupă o mică parte din acest spațiu de la adresa MEM_START_ADDR = 0x40 la MEM_STOP_ADDR = 0xBF. Astfel, memoria RAM este responsabilă de tratarea citirii/scrierii pentru orice adresă primită din acest interval.

1.2.1. Adresare directa

Adresa de memorie dorită se află chiar în corpul instrucțiunii. Un exemplu de instrucțiune ce folosește adresare directa este LDS (16-bit).

LDS (16-bit)

Biții marcați cu k formează o constantă ce reprezintă adresa de memorie de unde sunt citite datele, iar aceste date sunt scrise în registrul Rd.

Exemplu LDS (16-bit)

1.2.2. Adresare indirectă

Adresa de memorie dorită se află în registrul X, Y sau Z. O instrucțiune ce folosește adresare indirectă cu deplasament este LDD (i).

Conform datasheet-ului când ne referim la registrul X, Y sau Z ne referim de fapt la grupări de câte doua registre:

  • Registrul X reprezintă concatenarea registrelor R27:R26
  • Registrul Y reprezintă concatenarea registrelor R29:R28
  • Registrul Z reprezintă concatenarea registrelor R31:R30

Există desigur și variații Adresare indirectă cu offset: Adresa de memorie dorită se află în registrul Y sau Z, la care se adaugă un deplasament găsit în corpul instrucțiunii. O instrucțiune ce folosește adresare indirectă cu deplasament este LDD (iv).

LDD

Biții marcați cu q formează o constantă ce reprezintă deplasamentul ce trebuie adăugat adresei de memorie găsită în registrul Y sau Z. Datele sunt scrie în registrul Rd.

Adresare indirectă cu pre-decrementare

Adresa de memorie dorită se afla în registrul X, Y sau Z, care este decrementată înainte de a fi folosită. O instrucțiune ce folosește adresare indirectă cu deplasament este LDD (iii).

Adresare indirectă cu post-incrementare

Adresa de memorie dorita se afla în registrul X, Y sau Z, care este incrementata după ce este folosită. O instrucțiune ce folosește adresare indirectă cu deplasament este LDD (ii).

2.1 Memoria procesorului

Procesorul pe care îl implementăm la laborator are o arhitectura de tip Harvard. Asta înseamnă că vom avea 2 memorii separate pentru instrucțiuni și date.

  • Memoria de instrucțiuni este de tip ROM (2048 bytes) și se găsește în rom.v
    • adresele sunt pe 8 biți
    • datele au 16 biți (adică lungimea unei instrucțiuni)
  • Memoria de date este un SRAM sincron de tip pipeline (128 bytes) și se găsește în sram.v
    • adresele sunt pe 7 biți
    • datele au 8 biți (= dimensiunea unui registru)

Procesorul lucrează cu 16 registre “general purpose” de 8 biți. Teoretic există 32 registre, însă implementarea noastră nu va folosi niciodată primele 16. Astfel când scriem cod AVR vom putea folosi numai registrele din intervalul R16 → R31.

Totuși, după cum ați văzut în laboratorul trecut, nu vom lucra direct cu aceste registre, ci vom folosi registrul sursa Rr și registrul sursă/destinație Rd. Aceștia în spate adresează cele 16 registre. Puteți vedea acest lucru în sursa register_file.v în care este implementat un Dual Port SRAM. Acesta garantează accesul concomitent (într-un ciclu de ceas) atât la Rd, cât și la Rr.

Driver-ul de memorie pentru modulul dual_port_sram este reg_file_interface_unit definit în fișierul reg_file_interface_unit.v. Aici vom seta biții de CS, WE si OE, precum și liniile de date și adrese ce sunt necesare pentru lucrul cu memoria.

Accesul la o memorie SRAM cu magistrala de date multiplexată se face prin setarea următorilor biți:

  • CS : chip select stabilește dacă chip-ul este activ sau nu;
  • WE : write enable când este activ, se scriu date în RAM;
  • OE : output enable când este activ și nu se scrie în RAM, se citesc date din RAM;

În cazul memoriei Dual Port SRAM din laborator, vom avea acești biți atât pentru Rd, cât și pentru Rr (rr_cs, rd_cs, etc). Similar, vor exista linii de date și adrese distincte pentru fiecare dintre Rd si Rr.

Reluat: Veți observa în datasheet menționate o serie de registre index: X, Y și Z. Acestea corespund unor perechi de registre generale astfel: XH:XL (R27:R26), YH:YL (R29:R28) și ZH:ZL (R31:R30). În scheletul de cod, aceste registre index sunt definite ca macro-uri în fișierul defines.vh.

2.2 Semnale importante în scheletul de cod

Fata de laboratorul anterior, veți găsi o serie de semnale noi ce au fost adăugate unor modulelor procesorului nostru pentru a putea permite implementarea instrucțiunilor de lucru cu memoria. În această secțiune va fi explicat pe scurt rolul acestor semnale noi și utilitatea lor.

  1. decode.v
    • opcode_imd - asemănător lui opcode_rr și opcode_rd, acest semnal va reține valoarea decodificata din instrucțiune a valorilor imediate folosite de unele instrucțiuni.
  2. reg_file_interface_unit.v
    • rr_addr & rd_addr - ieșirile modulului care spun ce adresă folosim pentru RD si RR pentru operația curenta. Valorile acestor adrese trebuie stabilite în funcție de tipul operației (scriere sau citire) dar și de modul în care aceasta codifica adresa (indirect, printr-un alt registru sau direct prin OPCODE). O astfel de ieșire este activă doar dacă bit-ul CS corespunzător uneia dintre cele doua este activ.
    • internal_rr_addr & internal_rd_addr - fire de “lucru” în cadrul modului folosite pentru a determina ce adresă se asignează pe ieșirile rr_addr respectiv rd_addr.
    • signals - un registru ai cărui biți reprezintă ce fel de operație (READ sau WRITE) se execută asupra memoriei sau registrelor (RD, RR sau MEM). Semnificația fiecărui bit din acest registru se poate găsi în defines.vh.
  3. control_unit.v
    • writeback_value - valoarea ce trebuie salvată în memorie la finalul ultimului stagiu de pipeline. În funcție de tipul operației, trebuie asignat semnalul corespunzător. Spre exemplu, operațiile UAL atribuie ALU_OUT_BUFFER.
    • bus_data - valoarea aflata pe magistrala de data în urma ultimei operații de citire din memorie.
    • alu_rr - valoarea curenta stocata în registrul RR.
    • alu_rd - valoarea curenta stocata în registrul RD.

2.3 Instrucțiunile ATTiny pentru acces la memorie

Instrucțiunile pe care le veți implementa în acest laborator diferă putin de cele UAL pe care le-ați întâlnit pana acum. În aceasta secțiune va fi explicat pe scurt cum trebuie citit si interpretat datasheet-ul în cazul acestor instrucțiuni.

  1. LDI - Fata de instrucțiunile obișnuite, LDI introduce un nou operator: K. K reprezinta o valoare constanta pe 8 biți ce este salvata în registrul RD.
  2. LDD - Aceasta instrucțiune este un load indirect și folosește registrul special Y pentru a specifica adresa de memorie de la care se face citirea. În datasheet, veți găsi 4 codificări distincte pentru aceasta operație. Acest tip de LOAD poate modifica valoarea adresei înainte sau după accesarea efectiva a registrului. Cele 4 variante descrise in datasheet sunt:
    • LDD Rd, Y - in aceasta varianta, adresa din registrul Y este nemodificata în urma execuției
    • LDD Rd, Y+ - Post increment; adresa este incrementata după ce se face accesul
    • LDD Rd, -Y - Pre increment; adresa este decrementată înainte de a se face accesul
    • LDD Rd, (Y+q) - Displacement; adresa de la care se citește este specificata de registrul Y plus un deplasament (o constanta pe 6 biți codificata în instrucțiune)
  3. LDS - Instrucțiune pentru load direct din spațiul de date în registru. Asemănător cu LDI, aceasta instrucțiune codifica o constanta k, însă aceasta are o semnificație cu totul diferita. Aici, k codifica adresa din spațiul de date de la care se va face operația de load. Formula pentru calculul acestei adrese o găsim în datasheet: ADDR[7:0] = (~INST[8], INST[8], INST[10], INST[9], INST[3], INST[2], INST[1], INST[0]). biții 10, 9, 8, 3, 2, 1, 0 din instrucțiune reprezinta biții ce îl codifica pe k.
  4. STS - Scrie dintr-un registru la o adresa în memorie. Calculul adresei se face la fel ca cel pentru LDS.
  5. MOV - Copiază valoarea unui registru într-un alt registru. Codificarea acestei instrucțiuni este similara cu cea a instrucțiunilor UAL.

Instrucțiunile prezentate pot fi grupate și după tipurile de memorie intre care transfera date, astfel:

  • REG-REG: MOV
  • MEM-REG: LDD, LDS, STS
  • REG-IMMEDIATE: LDI
cn2/laboratoare/03/continut.1635097182.txt.gz · Last modified: 2021/10/24 20:39 by george_mircea.grosu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0