This shows you the differences between two versions of the page.
soc:laboratoare:09 [2025/05/14 18:59] mihai_catalin.stan |
soc:laboratoare:09 [2025/05/27 17:37] (current) stefan.maruntis [Semnale de control] |
||
---|---|---|---|
Line 26: | Line 26: | ||
Acest lucru este posibil deoarece controller-ul folosește o memorie ROM pentru a decide ce semnale de control trebuie activate, în funcție de instrucțiunea curentă și stagiul de execuție. Fiecare instrucțiune are 8 biți, iar stagiul are 4 biți, deci ele sunt combinate într-o adresa de 12 biți sub formă IIIIIIII TTTT. De exemplu, pentru instrucțiunea ADD B (codul 80) aflată în stagiul 3, adresa calculată este 803. În acea poziție din ROM este stocat un cuvânt de control de 35 de biți, care indică exact ce semnale trebuie activate în acel moment – cum ar fi B_EN și ALU_LOAD pentru a realiza adunarea. Astfel, ROM-ul acționează că o "harta" pentru execuția fiecărei instrucțiuni, eliminând nevoia unui cod complicat și greu de întreținut, și permițând controller-ului să execute eficient și clar pașii necesari pentru orice instrucțiune, inclusiv verificarea și gestionarea condițiilor de jump. | Acest lucru este posibil deoarece controller-ul folosește o memorie ROM pentru a decide ce semnale de control trebuie activate, în funcție de instrucțiunea curentă și stagiul de execuție. Fiecare instrucțiune are 8 biți, iar stagiul are 4 biți, deci ele sunt combinate într-o adresa de 12 biți sub formă IIIIIIII TTTT. De exemplu, pentru instrucțiunea ADD B (codul 80) aflată în stagiul 3, adresa calculată este 803. În acea poziție din ROM este stocat un cuvânt de control de 35 de biți, care indică exact ce semnale trebuie activate în acel moment – cum ar fi B_EN și ALU_LOAD pentru a realiza adunarea. Astfel, ROM-ul acționează că o "harta" pentru execuția fiecărei instrucțiuni, eliminând nevoia unui cod complicat și greu de întreținut, și permițând controller-ului să execute eficient și clar pașii necesari pentru orice instrucțiune, inclusiv verificarea și gestionarea condițiilor de jump. | ||
+ | |||
+ | ==== Semnale de control ==== | ||
+ | |||
+ | Inainte de a trece la semnalele de control, e important sa stim din laboratorul 8 ca memoria are doi registrii: | ||
+ | * Memory Data Register (MDR) - Un registru ce tine date de care avem nevoie temporar (opcode spre exemplu) in memorie | ||
+ | * Memory Address Register (MAR) - Un registru ce retine o adresa la care dorim sa scriem/sa citim din memoria RAM | ||
+ | |||
+ | De asemenea, semnalele de EN (enable) pot fi analizate cel mai bine in fisierul **SAP2_top.v**. Pe scurt, acestea pun output-ul unui registru pe magistrala. | ||
+ | Intr-un mod sumar, cele 39 de semnale de control pot fi descrise astfel: | ||
+ | |||
+ | ^ Semnal ^ Explicatie ^ | ||
+ | | RET | Folosit doar in instructiunea de RET | | ||
+ | | CALL | Folosit doar in instructiunea de CALL addr | | ||
+ | | RAM_EN_H | Pune octetul superior din RAM[mar] in registrul de date | | ||
+ | | RAM_EN_L | Pune octetul inferior din RAM[mar] in registrul de date | | ||
+ | | RAM_LD | Incarca in RAM[mar] octetul inferior din registrul de date al memoriei | | ||
+ | | MDR_EN | Incarca output-ul memoriei pe magistrala sistemului | | ||
+ | | MDR_LD | Incarca octetul inferior de pe magistrala in octetul inferior al MDR | | ||
+ | | MAR_LD_H | Incarca octetul superior al unei adrese aflate pe magistrala in octetul superior al MAR | | ||
+ | | MAR_LD_L | Incarca octetul inferior al unei adrese aflate pe magistrala in octetul inferior al MAR | | ||
+ | | PC_EN | Pune pe magistrala valoarea program counter-ului | | ||
+ | | PC_LD | Incarca in modulul de program counter valoare de pe magistrala (folosit in instructiunile de jump, care trebuie sa sara la o anumita instructiune) | | ||
+ | | PC_INC | Incrementeaza program counter-ul (util cand avem de citit o valoare imediata pentru instructiunea folosita, precum MVI sau JMP) | | ||
+ | | IR_LD | Incarca in modulul de Instruction Register valoarea de pe magistrala (necesar la fiecare instructiune pentru a stii ce instructiune urmeaza_ | | ||
+ | | ALU_EN | Pune pe magistra rezultatul din UAL (spre exemplu pentru a pune valoarea rezultata din operatia de ADD A in registrul A) | | ||
+ | | ALU_LD | Incarca in ALU a doua valoare necesara operatiei curente | | ||
+ | | ALU_OP_0/1/2/3 | Reprezinta codificarea operatiei curente din ALU (spre exemplu, pentru operatia SUB codificata cu 1, ALU_OP_0 va fi 1, iar restul vor fi 0) | | ||
+ | | FLAG_LD_C/B/A | Incarca in modulul flags.v flag-urile rezultate din ultima operatie a UAL-ului | | ||
+ | | C/B/A_DEC | Decrementeaza valoarea registrului corespunzator | | ||
+ | | C/B/A_INC | Incrementeaza valoarea registrului corespunzator | | ||
+ | | C/B/A_EN | Pune pe magistrala valoarea unui registru | | ||
+ | | C/B/A_LD | Incarca in registrul corespunzator valoarea de pe magistrala | | ||
+ | | IO_A_LD | Incarca in registrul **ioa** (io address) primul bit negat de pe magistrala (util pentru a stii daca vrem sa incarcam octetul superior sau cel inferior in registrul de memoriei al io_module) | | ||
+ | | IO_LD | Incarca in memoria modulului de IO o valoare de pe magistrala. Decizia de a incarca octetul superior sau pe cel inferior este data de valoarea lui ioa | | ||
+ | | IO_EN | Pune pe magistrala output-ul modulului de IO | | ||
+ | | HLT | Incheie executia programului | | ||
+ | | END | Incheie executia instructiunii curente | | ||
+ | |||
+ | Toate aceste semnale sunt scrise in ctrl_rom_io.bin. Ne amintim din laboratorul 8 ca acesta contine cuvinte de control, in care fiecare valoarea reprezinta un semnal, spre exemplul cuvantul 100000000000000000000000000000000000000 indica faptul ca doar semnalul de END este activ. | ||
+ | |||
+ | Adresa din ROM este formata prin concatenarea opcode-ului (8 biti) cu stage-ului (4 biti). Spre exemplu, cuvantul de la adresa 000000010010 (al 18-lea cuvant de control) este format prin concatenarea opcode-ului 00000001 cu stage-ul 0010. Deci acest cuvant de control contine semnalele ce trebuiesc executate de instructiunea codificata cu 8'h01, in stage-ul 2 al executiei. | ||
==== Instrucțiuni ==== | ==== Instrucțiuni ==== | ||
Line 77: | Line 118: | ||
Instrucțiunile pot fi împărțite în 4 categorii în funcție de modul în care adresează memoria în opcode: | Instrucțiunile pot fi împărțite în 4 categorii în funcție de modul în care adresează memoria în opcode: | ||
- | * Direct - Primește adresa de memorie pe care se operează în instrucțiune - ex. STA addr (Store la o anumită adresa) | + | * Direct - Primește adresa de memorie pe care se operează în instrucțiune - ex. STA addr (Store la o anumită adresa) |
- | * Immediate - Primește o valoare constantă direct folosită în instrucțiune - ex. ORI byte (Aplica operatia de OR logic între registrul A și o valoare primită) | + | * Immediate - Primește o valoare constantă direct folosită în instrucțiune - ex. ORI byte (Aplica operatia de OR logic între registrul A și o valoare primită) |
- | * Register - Funcționează pe datele dintr-un registru - ex. DCR A - Decrementează valoare registrului A | + | * Register - Funcționează pe datele dintr-un registru - ex. DCR A - Decrementează valoare registrului A |
- | * Implied - Adresa/Registrul pe care se efectuează instrucțiunea este implicită și nu se modifică - ex. RAL (Shiftează la stânga valoarea din registrul A și o salvează înapoi tot în acesta) | + | * Implied - Adresa/Registrul pe care se efectuează instrucțiunea este implicită și nu se modifică - ex. RAL (Shiftează la stânga valoarea din registrul A și o salvează înapoi tot în acesta) |
Sistemul nostru - SOC-1 - ia 3 ciclii de ceas pentru aducerea instrucțiunii de executat din memorie, deci cea mai scurtă instrucțiune va dura 3 ciclii (NOP). Cele mai lungi instrucțiuni sunt cele care lucrează cu adrese din memoria ROM și ajung până la 9-10 ciclii de ceas (STA - 9 ciclii, CALL - 9 ciclii, LDA - 10 ciclii) | Sistemul nostru - SOC-1 - ia 3 ciclii de ceas pentru aducerea instrucțiunii de executat din memorie, deci cea mai scurtă instrucțiune va dura 3 ciclii (NOP). Cele mai lungi instrucțiuni sunt cele care lucrează cu adrese din memoria ROM și ajung până la 9-10 ciclii de ceas (STA - 9 ciclii, CALL - 9 ciclii, LDA - 10 ciclii) | ||
Instrucțiunile de jump durează 4 sau 8 ciclii de ceas în funcție de rezultatul comparației din controller. Dacă în controller condiția eșuează și jump-ul nu este executat, acesta durează 4 ciclii de ceas. În schimb, dacă acesta este executat, instrucțiunea de jump durează 8 ciclii. | Instrucțiunile de jump durează 4 sau 8 ciclii de ceas în funcție de rezultatul comparației din controller. Dacă în controller condiția eșuează și jump-ul nu este executat, acesta durează 4 ciclii de ceas. În schimb, dacă acesta este executat, instrucțiunea de jump durează 8 ciclii. | ||
+ | |||
+ | ==== Implementarea unei instructiuni ==== | ||
+ | |||
+ | Pentru implementarea unei instructiuni sunt necesari pasii urmatori: | ||
+ | - Intelegerea semnalelor de control | ||
+ | - Determinarea modulelor implicare in executia unei instructiuni si a flow-ului datelor prin acestea | ||
+ | - Prelucrarea datelor in modulele corespunzatoarea (spre exemplu, prelucrarea datelor in UAL in timpul instructiunii de ADD) | ||
+ | - Scrierea semnalelor pentru fiecare stage si modificarea ROM-ului controller-ului cu semnalele corespunzatoare | ||
==== Scrierea și execuția de cod pe SOC-1 ==== | ==== Scrierea și execuția de cod pe SOC-1 ==== | ||
Line 119: | Line 168: | ||
==== Exercitii laborator ==== | ==== Exercitii laborator ==== | ||
- | Task 0: Analizati pe baza sheet-ului de instructiuni cu asistentul/asistenta de laborator secventa de mai sus pentru a determina ce se va intampla de-alungul executiei acesteia. | + | - (0p): Analizati pe baza sheet-ului de instructiuni cu asistentul/asistenta de laborator secventa de mai sus pentru a determina ce se va intampla de-alungul executiei acesteia. |
+ | - (5p) (Branch Group Instructions): Observati cum este implementata instructiunea de JM (Jump Minus) si implementati similar si operatia de JP (Jump Positive) in modulul controller.v. Vom defini opcode-ul instructiunii JP ca fiind 8'hFB. Ulterior, modificati in sap2_ctrl_rom.xlsx semnalele de control necesare fiecarei etape de executie a instructiunii. Dupa ce le-ati modificat, copiati coloana cu semnalele concatenate si puneti-le in ctrl_rom_io.bin. | ||
+ | - (5p) (Arithmetic Group Instructions): Implementati in modulul UAL instrucțiunile CMP B si CMP C, care compara prin scadere valoarea lui A cu a lui B, respectiv C si modifica flag-urile pe baza acestor operatii. Opcode-urile pentru CMP B si CMP C in ALU sunt 8 si 9, iar in ROM si excel sunt 8'h92 si 8'h93. Modificati semnalele si adaugati-le in ctrl_rom_io.bin ca la task-ul de mai sus. | ||
+ | - (0p): Cum va usureaza munca instrucțiunile implementate la task 2 fata de utilizarea unor operatii normale de SUB | ||
+ | - (Bonus) (I/O Group Instructions): Implementati instructiunea de I/O IN data, care se va primi prin intermediul switch-urilor o valoare pe 4 biti pe care o veti stoca in sectiunea LOW a registrului A. Instructiunea de IN poate fi gasita ca 0'hDB. Pentru ajutor puteti vedea si instructiunea de OUT ca 0'hD3. Modificati semnalele si ctrl_rom_io ca la primele 2 task-uri. | ||
- | Task 1 (Branch Group Instructions): Observati cum este implementata instructiunea de JM (Jump Minus) si implementati similar si operatia de JP (Jump Positive) | + | Daca functia concatenate din excel nu este recunoscuta cand deschideti local, incercati folosirea Google Spreadsheets sau OneDrive. |
- | Task 2 (Arithmetic Group Instructions): Implementati instrucțiunile CMP B si CMP C, care compara valoarea lui A cu a lui B, respectiv C si modifica flag-urile pe baza acestor operatii. | + | <spoiler SUB vs CMP> |
- | + | ||
- | Task 2.1: Cum va usureaza munca instrucțiunile implementate la task 2 fata de utilizarea unor operatii normale de SUB | + | |
- | + | ||
- | <spoiler> | + | |
<code> | <code> | ||
MVI A, 5AH | MVI A, 5AH | ||
Line 143: | Line 192: | ||
</spoiler> | </spoiler> | ||
- | Task 3: Implementare XCHG A B: Interschimba valorile din registre A si B. | + | <hidden> |
+ | Pentru fiecare task studentii vor avea de implementat logica instructiunii in modulul corespunzator si de modificat semnalele de control din excel. Mai jos aveti atasata arhiva solutiei. | ||
- | Task 4 (I/O Group Instructions): Implementati instructiunea de I/O IN data, care se va primi prin intermediul switch-urilor o valoare pe 4 biti pe care o veti stoca in sectiunea LOW a registrului A. | + | Pentru operatia de **JP (Jump Positive)**, semnalele vor fi identice cu cele de la Jump Minus, fiind primul task vrem sa vedem ca studentii macar inteleg sumar ce se intampla cu acele semnale. |
- | Task 5 (BONUS): Implementarea POPCNT A. Numara numarul de biti setati pe 1 din registrul A. | + | Pentru operatiile de **CMP**, implementarea va fi identica cu cea a operatiei de SUB, iar semnalele vor fi similare. CMP B difera de SUB B prin faptul ca nu vom mai activa semnalul de A_LOAD (nu vom scrie rezultatul in registrul A). Similar si pentru CMP C. |
+ | |||
+ | In **simulare**, daca operatiile au fost implementate cu succes, se va efectua A = 3, B = 2, CMP, JP, HLT, iar simularea se va opri dupa 280.000ns. Daca nu este recunoscuta instructiunea, va ramane blocat pe aceasta. Daca sunt implementate gresit, nu se va executa JP la adresa 0x0B (HLT) ci se va executa JMP 0x00 (inapoi la inceputul programului). | ||
+ | |||
+ | Pentru a verifica doar functionalitatea lui JP, studentii pot inlocui opcode-ul instructiunii de CMP cu cel al instructiunii de SUB B. Daca JP e implementata corect, simularea se va opri ca mai sus, dupa 280.000ns. | ||
+ | |||
+ | Operatia de **IN byte** este similara cu cea de OUT pe care am dat-o ca referinta. Primele 3 etape sunt identice la toate instructiunile, a 4-a etapa va pune pe magistrala datele din MDR, iar in etapa urmatoare vrem sa le incarcam in IOA (adresa registrului de IO). In urmatoarea (si ultima etapa) vrem sa trimitem datele din IO module (cu IO_EN) si sa le incarcam in registrul A (A_LD). | ||
+ | </hidden> | ||
Pentru mai multe detalii cu privire la instructiunile de mai sus, va recomandam sa cititi din datasheet-ul de mai jos paginile 34-45 | Pentru mai multe detalii cu privire la instructiunile de mai sus, va recomandam sa cititi din datasheet-ul de mai jos paginile 34-45 | ||
Line 154: | Line 211: | ||
[[https://deramp.com/downloads/intel/8080%20Data%20Sheet.pdf]] | [[https://deramp.com/downloads/intel/8080%20Data%20Sheet.pdf]] | ||
+ | <hidden> | ||
+ | {{:soc:laboratoare:sap-2_lab9_solutie.zip | Solutia laboratorului}} | ||
+ | |||
+ | Daca fisierul xdc nu este recunoscut automat, doar dati-i add source din Vivado. | ||
+ | </hidden> | ||
+ | {{:soc:laboratoare:sap-2_lab9_skel.zip | Scheletul laboratorului}} |