Laboratorul 00 - Recapitulare

În acest laborator vom recapitula noțiuni învățate la SOC și ne vom familiariza cu programul Vivado.

În acest laborator sunt prezentate foarte pe scurt elementele esențiale ale limbajului Verilog. Pentru informații mai detaliate, vă recomandăm laboratoarele 1 și 2 de la SOC:

Vivado

Vivado Design Suite e un pachet software dezvoltat de compania Xilinx (achiziționată de AMD) pentru a programa FPGA-uri.

Vivado permite editarea, simularea și sintetizarea codului de descriere hardware (HDL) pe plăcuța Nexys A7 folosită în laborator.

Ghid de instalare Vivado

Official DocNav Guide: Vivado Getting Started

Verilog

Verilog este un HDL (Hardware Description Language) folosit pentru specificarea formală a circuitelor electronice digitale.

Modulul este unitatea de bază a limbajului Verilog. Definește interfața (intrările și ieșirile) și comportamentul unui circuit electronic. Putem descrie comportamentul unui modul în trei moduri:

  • Descriere structurală: specificând structura internă a modulului folosind primitive (porți logice) și alte module
  • Descriere la nivel flux de date: specificând relațiile dintre intrări și ieșiri sub forma unor expresii
  • Descriere procedurală: specificând funcționarea în mod algoritmic
module A(input in, output out);
    not(out, in);
endmodule
 
module B(input in, output out);
    assign out = ~in;
endmodule
 
module C(input in, output reg out);
    always @(*)
    begin
        out = ~in;
    end
end

În Verilog putem folosi două tipuri de date:

  • wire: reprezintă conexiuni fizice între componente, se folosesc pentru transmisia semnalelor și nu au capacitate de reținere a informației
  • reg: folosite pentru a stoca date, care persistă chiar dacă registrul este deconectat
wire a;
wire [7:0] b;
reg c;
reg [0:7] d;

Pentru a controla ce date se află pe fire sau în registre, avem la dispoziție mai multe tipuri de atribuiri:

  • Atribuiri continue (assign): reprezintă relații directe între semnalele, funcționează doar pe wire
  • Atribuiri blocante (=): sunt folosite pentru descrierea logicii combinaționale, executându-se secvențial, funcționează doar pe reg
  • Atribuiri non-blocante (<=): sunt folosite pentru descrierea logicii secvențiale, executându-se în paralel, funcționează doar pe reg
module A(input in);
    wire a;
    reg b;
    reg c;
 
    assign a = in;
 
    always @(*)
    begin
        b = in;
    end
 
    always @(*)
    begin
        c <= in;
     end
endmodule

Dacă alegem descrierea procedurală avem la dispoziție două blocuri speciale:

  • initial: va fi executat o singură dată și se folosește în simulări pentru inițializarea circuitului. Acest bloc nu ajunge să fie sintetizat în circuitul propriu-zis.
  • always: va fi executat de fiecare dată la apariția unui eveniment. Este similar funcției de tratare a unei întreruperi - când întreruperea apare în sistem, funcția se execută. @(*) este echivalent cu orice eveniment.

Pentru o listă completă a blocurilor procedurale ce pot fi folosite în limbajul verilog, consultați laboratorul 2 de la SOC.

Logică combinațională și secvențială

Circuitele logice combinaționale sunt circuitele reprezentate prin porți logice ce aplică o funcție pe intrări. Valorile de ieșire depind doar de valorile de intrare, nu și de stări de reactie (feedback), iar cand starea unei intrări se schimbă, se reflectă imediat la ieșiri.

Circuit combinațional

Spre deosebire de circuitele logice combinaționale, la cele secvențiale valorile de ieșire nu mai depind exclusiv de starea curentă a intrărilor, ci și de stările anterioare ale circuitului.

Circuit Secvențial

Pentru mai multe informații despre circuitele logice, consultați laboratorul 0 de SOC.

Automate cu stări finite (FSM)

Un automat finit este, în sensul cel mai abstract, un model de calculabilitate. Trăsătura fundamentală a automatelor finite este faptul că se află, la orice moment de timp, într-una dintr-un număr finit de stări posibile. De asemenea, în anumite condiţii, ele pot executa tranziţii între aceste stări. Astfel, un automat este descris de: intrări, ieșiri, stări și tranziții.

În funcție de relația dintre intrare, ieșire și starea curentă există două tipuri de automate: Mealy și Moore. La automatele Mealy, ieşirea depinde de starea curentă şi de input-ul curent. Astfel, o ieșire corespunde unei tranziții.

Diagramă automat Mealy

La automatele Moore, pe de altă parte, ieșirea este determinată exclusiv de starea în care se află.

Diagramă automat Moore

Pentru mai multe informații despre FSM, consultați laboratorul 4 de SOC.

TL;DR

  • Verilog
    • Modul
      • Descriere structurală
      • Descriere flux de date
      • Descriere procedurală
        • initial
        • always
    • wire vs reg
    • Atribuiri continue (assign), blocante (=) și non-blocante (<=)
    • Simulare
  • Circuite combinaționale
    • Ieșirile depind doar de intrările de la momentul respectiv
  • Circuite secvențiale
    • Ieșirile depind de intrările de la momentul respectiv, dar și de stările anterioare are modulului
  • Automate cu stări
    • Mealy (ieșirea depinde de starea curentă și intrarea curentă)
    • Moore (ieșirea depinde de starea curentă)

Exerciții

Pentru rezolvarea exercițiilor va trebui să aveți instalat programul Vivado pe laptopul personal (urmați acest tutorial de instalare) sau să vă logați pe Linux pe calculatoarele din laborator.

Task 01 (5p) Creați un proiect în Vivado care aprinde un led (e.g. H17) de pe plăcuța Nexys A7 la apăsarea unui buton (e.g. N17).

Pentru a ușura procesul de debug, înainte de a sintetiza cod Verilog pe FPGA putem simula codul adăugând un fișier pentru test (Tutorial: Cum se simulează un modul?).

Exemplu fisier de testare

Exemplu fisier de testare

`timescale 1ns / 1ps
 
module task01_tb();
 
    reg in = 0;
    wire out;
 
    initial begin
        in = 1;     // set input "in" to 1
        #200;       // delay 200 ns
        in = 0;     // set input "in" to 0
        #200;       // delay 200 ns
        in = 1;     // set input "in" to 1
        #200;       // delay 200 ns
        in = 0;     // set input "in" to 0
    end
 
    task01 task01_instance(
      .in(in),
      .out(out)
    );
 
endmodule

După simularea cu succes a modulului, putem să generăm bitstreamul pe care îl vom pune plăcuța FPGA. Tutorial: Cum se încarcă pe FPGA?

Task 02 (5p) Implementați un modul UAL ``ual.v``.

Modulul va primi la intrare 2 numere (pe 4 biți) (a și b) și indicatorul unei operații ce se va efectua asupra numerelor (sel - pe 2 biti).

Ieșirea modului (result) va fi un număr pe 4 sau 5 biți ce reprezintă rezultatul aplicării operației asupra numerelor a și b. Pentru valorile intrării sel avem urmatoarele operatii:

  • (1p) 0 : AND
  • (1p) 1 : XOR
  • (1p) 2 : OR
  • (2p) 3 : ADD (În acest caz puteți folosi o ieșire de 5 biți)

Exemplu de mapare a porturilor pe plăcuță: (click pe imagine pentru zoom in)

Folosiți acest fișier: Nexys-A7-100T-Master.xdc

Resurse

apm/laboratoare/00.txt · Last modified: 2024/02/29 15:06 (external edit)
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