Differences

This shows you the differences between two versions of the page.

Link to this comparison view

ac-is:lab:lab06 [2021/11/07 21:15]
alexandru.predescu
ac-is:lab:lab06 [2023/11/25 19:33] (current)
teodor.dicu [Resurse]
Line 33: Line 33:
 Principalele categorii de instrucțiuni sunt cele aritmetico-logice,​ de control secvențial,​ și respectiv de acces la memorie. Formatul instrucțiunilor RISC are o lungime fixă, cu lungimea unei instrucțiuni în general egală cu lungimea cuvantului de memorie; în cazul CISC, lungimea unei instrucțiuni variază în funcție de formatul instrucțiunii. RISC are un număr mic de moduri de adresare, spre deosebire de CISC, care are un număr mare de moduri de adresare (dar care nu sunt totdeauna utilizate). Principalele categorii de instrucțiuni sunt cele aritmetico-logice,​ de control secvențial,​ și respectiv de acces la memorie. Formatul instrucțiunilor RISC are o lungime fixă, cu lungimea unei instrucțiuni în general egală cu lungimea cuvantului de memorie; în cazul CISC, lungimea unei instrucțiuni variază în funcție de formatul instrucțiunii. RISC are un număr mic de moduri de adresare, spre deosebire de CISC, care are un număr mare de moduri de adresare (dar care nu sunt totdeauna utilizate).
  
-Setul de instrucțiuni RISC este orientat pe regiștri ​(peste 32 de regiștri). Pentru că accesul la memorie e mult mai lent decât lucrul cu regiștrii, RISC încurajează lucrul cu aceștia. Face acest lucru prin creșterea numărului de regiștri ​și prin limitarea explicită a acceselor la memorie. În general instrucțiunile au 2 operanzi (regiștri) și un registru destinație. Ca principiu, arhitectura RISC are mai mulți regiștri generali, în timp ce CISC are mai mulți speciali. Practic toate procesoarele moderne împrumută atât caracteristici CISC, cât și RISC. +Setul de instrucțiuni RISC este orientat pe registre ​(peste 32 de registre). Pentru că accesul la memorie e mult mai lent decât lucrul cu registrele, RISC încurajează lucrul cu aceștia. Face acest lucru prin creșterea numărului de registreși prin limitarea explicită a acceselor la memorie. În general instrucțiunile au 2 operanzi (registre) și un registru destinație. Ca principiu, arhitectura RISC are mai multe registre generale, în timp ce CISC are mai mulți speciali. Practic toate procesoarele moderne împrumută atât caracteristici CISC, cât și RISC. 
  
 În cadrul arhitecturilor RISC există o limitare explicită, și anume: singurul mod de acces la memorie este prin //load// și //store//. Aceasta se deosebește fundamental de CISC care are instrucțiuni cu operanzi locații de memorie. Totuși, deși RISC impune această disciplină de lucru cu memoria, doar 20-25% din codul unui program e reprezentat de loads & stores. ​ În cadrul arhitecturilor RISC există o limitare explicită, și anume: singurul mod de acces la memorie este prin //load// și //store//. Aceasta se deosebește fundamental de CISC care are instrucțiuni cu operanzi locații de memorie. Totuși, deși RISC impune această disciplină de lucru cu memoria, doar 20-25% din codul unui program e reprezentat de loads & stores. ​
Line 123: Line 123:
 După cum se poate observa, cea de-a doua operație aritmetică este ADC, adică adunare cu transport (carry). Semnificația este următoarea:​ dacă de la operația anterioară de adunare a apărut transport, acest transport va trebui propagat în octeții superiori. Astfel, operația ADD, în cazul în care a apărut transport, setează bitul T din registrul IND. Operația ADC realizează suma între operanzi, dar include în calcul și acest bit de transport. ​ După cum se poate observa, cea de-a doua operație aritmetică este ADC, adică adunare cu transport (carry). Semnificația este următoarea:​ dacă de la operația anterioară de adunare a apărut transport, acest transport va trebui propagat în octeții superiori. Astfel, operația ADD, în cazul în care a apărut transport, setează bitul T din registrul IND. Operația ADC realizează suma între operanzi, dar include în calcul și acest bit de transport. ​
  
-Un alt exemplu este saltul condiționat. O instrucțiune de tip «if (a=2)» se va implementa astfel:+Un alt exemplu este saltul condiționat. O instrucțiune de tip «if (a==2)» se va implementa astfel:
 <code asm> <code asm>
 CMP RA,2 CMP RA,2
Line 187: Line 187:
 Modurile de adresare permise de calculatorul didactic sunt tipice arhitecturilor CISC, fiind derivate din arhitectura standard x86. În total, procesorul permite 11 moduri de adresare, ceea ce îi conferă o foarte bună flexibilitate în programare. Pentru o mai ușoară înțelegere,​ le vom structura astfel: Modurile de adresare permise de calculatorul didactic sunt tipice arhitecturilor CISC, fiind derivate din arhitectura standard x86. În total, procesorul permite 11 moduri de adresare, ceea ce îi conferă o foarte bună flexibilitate în programare. Pentru o mai ușoară înțelegere,​ le vom structura astfel:
  
 +| **Specificarea operandului** | **Moduri de adresare** |
 | Operandul nu se găseşte în memorie | Adresare directă la registru \\ Adresare imediată | | Operandul nu se găseşte în memorie | Adresare directă la registru \\ Adresare imediată |
 | Operandul e specificat doar prin deplasament | Adresare directă \\ Adresare indirectă | | Operandul e specificat doar prin deplasament | Adresare directă \\ Adresare indirectă |
Line 203: Line 204:
 Operandul se găseşte în RG. Operandul se găseşte în RG.
  
-Exemplu: <code asm>MOV RA,​RB</​code>​+Exemplu: <code asm>MOV RA, RB</​code>​
  
 Instrucțiunea are ca efect încărcarea în registrul RA a valorii din registrul RB. Instrucțiunea are ca efect încărcarea în registrul RA a valorii din registrul RB.
Line 213: Line 214:
 Operandul este specificat în instrucțiune. Operandul este specificat în instrucțiune.
  
-Exemplu: <code asm>MOV RA,​7</​code>​+Exemplu: <code asm>MOV RA, 7</​code>​
  
 Instrucțiunea va avea ca efect încarcarea valorii "​7"​ în registrul RA. "​7"​ poartă numele de operand imediat. Instrucțiunea va avea ca efect încarcarea valorii "​7"​ în registrul RA. "​7"​ poartă numele de operand imediat.
Line 226: Line 227:
 Adresa efectivă este specificată în instrucțiune. Adresa efectivă este specificată în instrucțiune.
  
-Exemplu: <code asm>MOV RA,​[12]</​code>​+Exemplu: <code asm>MOV RA, [12]</​code>​
  
 Instrucțiunea va încărca valorea aflată în memorie la adresa "​12"​ în registrul RA. "​12"​ poarta numele de deplasament. Instrucțiunea va încărca valorea aflată în memorie la adresa "​12"​ în registrul RA. "​12"​ poarta numele de deplasament.
Line 236: Line 237:
 Adresa efectivă se citește din memorie, din locația a cărei adresă este specificată în instrucțiune. Adresa efectivă se citește din memorie, din locația a cărei adresă este specificată în instrucțiune.
  
-Exemplu: <code asm>MOV RA,​[[12]]</​code>​+Exemplu: <code asm>MOV RA, [[12]]</​code>​
  
 Instrucțiunea are ca efect încărcarea valorii aflată la adresa ce se găsește în memorie la adresa "​12"​. Acest mod de adresare seamană foarte bine cu pointerii din C. La adresa "​12"​ se găsește pointer-ul către operand. Instrucțiunea are ca efect încărcarea valorii aflată la adresa ce se găsește în memorie la adresa "​12"​. Acest mod de adresare seamană foarte bine cu pointerii din C. La adresa "​12"​ se găsește pointer-ul către operand.
Line 248: Line 249:
 Adresa efectivă se găsește în unul din registrele XA, XB, BA, BB. Adresa efectivă se găsește în unul din registrele XA, XB, BA, BB.
  
-Exemplu: <code asm>MOV RA,​[BA]</​code>​+Exemplu: <code asm>MOV RA, [BA]</​code>​
  
 Instrucțiunea va încărca în RA valoarea aflată în memorie la adresa conținută în BA. Instrucțiunea va încărca în RA valoarea aflată în memorie la adresa conținută în BA.
Line 256: Line 257:
 Adresa efectivă se obține ca sumă a conținutului unui registru de bază cu conținutul unui registru index. Adresa efectivă se obține ca sumă a conținutului unui registru de bază cu conținutul unui registru index.
  
-Exemplu: <code asm>MOV RA,​[BA][XA]</​code>​ sau <code asm>MOV RA,​[BA+XA]</​code>​+Exemplu: <code asm>MOV RA, [BA][XA]</​code>​ sau <code asm>MOV RA, [BA+XA]</​code>​
  
 Instrucțiunile încarcă în RA valoarea aflată în memorie la adresa obținută prin adunarea conținutului registrelor BA și XA. BA, BB poartă numele de registre de bază, iar XA, XB poartă numele de registre index. Întotdeauna suma se va face între un registru bază și unul index. Instrucțiunile încarcă în RA valoarea aflată în memorie la adresa obținută prin adunarea conținutului registrelor BA și XA. BA, BB poartă numele de registre de bază, iar XA, XB poartă numele de registre index. Întotdeauna suma se va face între un registru bază și unul index.
Line 264: Line 265:
 Față de modul precedent de adresare apare deosebirea că registrele index se incrementează după generarea adresei efective. Incrementarea registrului index (XA sau XB) are deci loc după participarea la calculul adresei efective. Față de modul precedent de adresare apare deosebirea că registrele index se incrementează după generarea adresei efective. Incrementarea registrului index (XA sau XB) are deci loc după participarea la calculul adresei efective.
  
-Exemplu: <code asm>MOV RA,​[BA][XA+]</​code>​ sau <code asm>MOV RA,​[BA+XA+]</​code>​+Exemplu: <code asm>MOV RA, [BA][XA+]</​code>​ sau <code asm>MOV RA, [BA+XA+]</​code>​
  
 Aceste instrucțiuni sunt echivalente cu: Aceste instrucțiuni sunt echivalente cu:
 <code asm> <code asm>
-MOV RA,[BA][XA]+MOV RA, [BA][XA]
 INC XA INC XA
 </​code>​ </​code>​
Line 276: Line 277:
 Adresa efectivă se obține prin suma unui registru de bază cu continutul registrului XA. Înaintea generării adresei, registrul XA este decrementat. Adresa efectivă se obține prin suma unui registru de bază cu continutul registrului XA. Înaintea generării adresei, registrul XA este decrementat.
  
-Exemplu: <code asm>MOV RA,​[BA][XA-]</​code>​ sau <code asm>MOV RA, [BA+XA-]</​code>​+Exemplu: <code asm>MOV RA, [BA][XA-]</​code>​ sau <code asm>MOV RA, [BA+XA-]</​code>​
  
 Aceste instrucțiuni sunt echivalente cu: Aceste instrucțiuni sunt echivalente cu:
 <code asm> <code asm>
 DEC XA DEC XA
-MOV RA,[BA][XA]+MOV RA, [BA][XA]
 </​code>​ </​code>​
  
Line 292: Line 293:
 Adresa efectivă se obține prin adunarea unui registru de bază cu un deplasament. Adresa efectivă se obține prin adunarea unui registru de bază cu un deplasament.
  
-Exemplu: <code asm>MOV RA,​[BA]+7</​code>​ sau <code ams>MOV RA,​[BA+7]</​code>​+Exemplu: <code asm>MOV RA, [BA]+7</​code>​ sau <code ams>MOV RA, [BA+7]</​code>​
  
 Instrucțiunea încarcă în registrul RA valoarea aflată în memorie la adresa rezultată în urma adunării conținutului registrului de bază cu deplasamentul (7). Instrucțiunea încarcă în registrul RA valoarea aflată în memorie la adresa rezultată în urma adunării conținutului registrului de bază cu deplasamentul (7).
Line 300: Line 301:
 Adresa efectivă se obține prin adunarea unui registru index cu un deplasament. Adresa efectivă se obține prin adunarea unui registru index cu un deplasament.
  
-Exemplu: <code asm>MOV RA,​[XA]+7</​code>​ sau <code asm>MOV RA,​[XA+7]</​code>​+Exemplu: <code asm>MOV RA, [XA]+7</​code>​ sau <code asm>MOV RA, [XA+7]</​code>​
  
 Instrucțiunea încarcă în registrul RA valoarea aflată în memorie la adresa rezultată în urma adunării conținutului registrului de index cu deplasamentul (7). Instrucțiunea încarcă în registrul RA valoarea aflată în memorie la adresa rezultată în urma adunării conținutului registrului de index cu deplasamentul (7).
Line 308: Line 309:
 Adresa efectivă se obține prin adunarea unui registru de bază cu un registru index și cu un deplasament. Adresa efectivă se obține prin adunarea unui registru de bază cu un registru index și cu un deplasament.
  
-Exemplu: <code asm>MOV RA,​[BA][XA]+7</​code>​ sau <code asm>MOV RA,​[BA+XA+7]</​code>​+Exemplu: <code asm>MOV RA, [BA][XA]+7</​code>​ sau <code asm>MOV RA, [BA+XA+7]</​code>​
  
 Instrucțiunea încarcă în registrul RA valoarea aflată în memorie la adresa rezultată în urma adunării conținutului registrului de bază (BA) cu registrul index (XA) și cu deplasamentul (7). Instrucțiunea încarcă în registrul RA valoarea aflată în memorie la adresa rezultată în urma adunării conținutului registrului de bază (BA) cu registrul index (XA) și cu deplasamentul (7).
Line 326: Line 327:
  
   - **(1p)** Explicați conținutul fișierului //​calc_didactic/​calc_didactic.v//​ corelându-l cu schema bloc a calculatorului didactic din secțiunea [[lab06#​Resursele calculatorului didactic|Resursele calculatorului didactic]]. Rulați proiectul pe placa de laborator și urmăriți execuția primei instrucțiuni.   - **(1p)** Explicați conținutul fișierului //​calc_didactic/​calc_didactic.v//​ corelându-l cu schema bloc a calculatorului didactic din secțiunea [[lab06#​Resursele calculatorului didactic|Resursele calculatorului didactic]]. Rulați proiectul pe placa de laborator și urmăriți execuția primei instrucțiuni.
-    * //Hint:// Citiți secțiunea [[#​testare]] pentru informații despre testarea calculatorului didactic pe placa de laborator.+    * //Hint:// Citiți secțiunea [[#​testare]] ​(N/A) pentru informații despre testarea calculatorului didactic pe placa de laborator.
   - **(3p)** Implementați modulul //​register//​ pornind de la declarația din fișierul //​calc_didactic/​register.v//​.   - **(3p)** Implementați modulul //​register//​ pornind de la declarația din fișierul //​calc_didactic/​register.v//​.
-    ​* Semnalele ''​oe''​ și ''​we''​ reprezintă //Output Enable//, respectiv //Write Enable//.  +    * //​Hint:// ​Revedeți [[.:lab05#Depozitarea informației digitale: Registrul| laboratorul ​5]]. 
-      * ''​oe''​ controleaza ieșirea registrului. Când ''​oe''​ este //high// ieșirea este activă având valoarea memorată de registru. Când ''​oe''​ este //low// ieșirea va fi 0. :!: Acest semnal trebuie să fie **asincron**:​ modificarea lui va avea efect imediat asupra ieșirii și nu se va aștepta tranziția semnalului de ceas. +    * //Hint:// Pentru testarea pe placă ​(N/A) revedeţi [[..:​tutoriale:​5-ise-programare| tutorialul]] de programare. Asignarea pinilor I/O este deja realizată în fișierul .ucf din schelet.
-      * ''​we'' ​ controlează scrierea în registru. Când ''​we''​ este //high// registrul va memora valoarea aflată în semnalul de intrare. Când ''​we''​ este //low// valoarea registrului nu se va modifica, ignorând practic semnalul de intrare. :!: Acest semnal trebuie să fie **sincron**:​ modificarea valorii memorate de registru se face doar în momentul tranziției semnalului de ceas. +
-    * Semnalul ''​disp_out''​ este folosit pentru afișare/​debugging pe display, iar valoarea acestuia trebuie să fie cea memorată de registru în momentul curent. În mod normal acest semnal nu este prezent într-un calculator. :!: Acest semnal **nu trebuie** să fie afectat de ''​oe'',​ valoarea disponibilă pe ''​disp_out''​ fiind în orice moment egală cu valoarea memorată de registru. +
-    * Semnalul de reset ''​rst''​ este activ pe //high// (1). +
-    ​* //​Hint:// ​Puteți folosi operatorul condiţional (revedeţi [[.:lab02#operatori| laboratorul ​2]]) +
-    * //Hint:// Pentru testarea pe placă revedeţi [[..:​tutoriale:​5-ise-programare| tutorialul]] de programare. Asignarea pinilor I/O este deja realizată în fișierul .ucf din schelet.+
   - **(3p)** Implementați modulul //​registers//,​ care reprezintă bancul celor 8 registre generale, pornind de la declarația din fișierul //​calc_didactic/​registers.v//​.   - **(3p)** Implementați modulul //​registers//,​ care reprezintă bancul celor 8 registre generale, pornind de la declarația din fișierul //​calc_didactic/​registers.v//​.
     * Semnalul ''​addr''​ identifică registrul selectat (dintre cele 8) pentru citire/​scriere. Corespondența dintre valoarea lui ''​addr''​ și registrul selectat este dată de prima și, respectiv ultima coloană a celui de-al doilea tabel din {{..:​resurse:​cheat-sheet.pdf| cheat-sheet}}.     * Semnalul ''​addr''​ identifică registrul selectat (dintre cele 8) pentru citire/​scriere. Corespondența dintre valoarea lui ''​addr''​ și registrul selectat este dată de prima și, respectiv ultima coloană a celui de-al doilea tabel din {{..:​resurse:​cheat-sheet.pdf| cheat-sheet}}.
Line 341: Line 337:
   - **(3p)** Implementați în unitatea de comandă etapa de //fetch// a execuției unei instrucțiuni.   - **(3p)** Implementați în unitatea de comandă etapa de //fetch// a execuției unei instrucțiuni.
  
 +{{ :​ac-is:​lab:​lab06:​fetch.png?​200 | Diagrama de stări}}
  
  
-===== Testare =====+/* * Semnalele ''​oe''​ și ''​we''​ reprezintă //Output Enable//, respectiv //Write Enable//.  
 +      * ''​oe''​ controleaza ieșirea registrului. Când ''​oe''​ este //high// ieșirea este activă având valoarea memorată de registru. Când ''​oe''​ este //low// ieșirea va fi 0. :!: Acest semnal trebuie să fie **asincron**:​ modificarea lui va avea efect imediat asupra ieșirii și nu se va aștepta tranziția semnalului de ceas. 
 +      * ''​we'' ​ controlează scrierea în registru. Când ''​we''​ este //high// registrul va memora valoarea aflată în semnalul de intrare. Când ''​we''​ este //low// valoarea registrului nu se va modifica, ignorând practic semnalul de intrare. :!: Acest semnal trebuie să fie **sincron**:​ modificarea valorii memorate de registru se face doar în momentul tranziției semnalului de ceas. 
 +    * Semnalul ''​disp_out''​ este folosit pentru afișare/​debugging pe display, iar valoarea acestuia trebuie să fie cea memorată de registru în momentul curent. În mod normal acest semnal nu este prezent într-un calculator. :!: Acest semnal **nu trebuie** să fie afectat de ''​oe'',​ valoarea disponibilă pe ''​disp_out''​ fiind în orice moment egală cu valoarea memorată de registru. 
 +    * Semnalul de reset ''​rst''​ este activ pe //high// (1). 
 +    * //Hint:// Puteți folosi operatorul condiţional (revedeţi [[.:​lab02#​operatori| laboratorul 2]]) 
 +*/ 
 + 
 +===== Testare ​(N/A) =====
  
 Testarea implementării se face pe placa de laborator, scheletul de cod conținând deja o variantă binară a tuturor modulelor necesare pentru functionare. Această variantă binară este înlocuită automat în momentul în care completați conținutul modulelor cerute cu implementarea voastră. Testarea implementării se face pe placa de laborator, scheletul de cod conținând deja o variantă binară a tuturor modulelor necesare pentru functionare. Această variantă binară este înlocuită automat în momentul în care completați conținutul modulelor cerute cu implementarea voastră.
Line 366: Line 371:
 ===== Resurse ===== ===== Resurse =====
   * {{.:​lab06:​lab6_skel.zip|Schelet de cod}}   * {{.:​lab06:​lab6_skel.zip|Schelet de cod}}
-  * {{.:​lab06:​sol:​lab6_sol.zip|Soluție laborator}} (disponibilă începând cu 09.11.2019) 
   * <​html><​a class="​media mediafile mf_pdf"​ href="/​ac/​wiki/​lab/​lab06?​do=export_pdf">​PDF laborator</​a></​html>​   * <​html><​a class="​media mediafile mf_pdf"​ href="/​ac/​wiki/​lab/​lab06?​do=export_pdf">​PDF laborator</​a></​html>​
   * {{..:​resurse:​cheat-sheet.pdf|Cheat-sheet calculator didactic}}   * {{..:​resurse:​cheat-sheet.pdf|Cheat-sheet calculator didactic}}
   * {{..:​resurse:​ac5.pdf|Arhitectura calculatorului didactic}}   * {{..:​resurse:​ac5.pdf|Arhitectura calculatorului didactic}}
- 
- 
-===== Resurse ===== 
   * <​html><​a class="​media mediafile mf_pdf"​ href="​https://​ocw.cs.pub.ro/​courses/​ac-is/​lab/​lab06?​do=export_pdf">​PDF laborator</​a></​html> ​   * <​html><​a class="​media mediafile mf_pdf"​ href="​https://​ocw.cs.pub.ro/​courses/​ac-is/​lab/​lab06?​do=export_pdf">​PDF laborator</​a></​html> ​
 +  * {{.:​lab06:​sol:​lab6_sol.zip|Soluție laborator}}
  
- +<ifauth @ac-is>
-<ifauth @user>+
 ---- ----
 +  * {{.:​lab06:​sol:​lab6_sol.zip|Soluție laborator}}
   * [[ac-is:​internal:​guidelines|Ghid asistent]]   * [[ac-is:​internal:​guidelines|Ghid asistent]]
 </​ifauth>​ </​ifauth>​
  
  
ac-is/lab/lab06.1636312548.txt.gz · Last modified: 2021/11/07 21:15 by alexandru.predescu
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