VHDL

Da Wikipedia, l'enciclopedia libera.
Curly Brackets.svg

VHDL (VHSIC Hardware Description Language, dove VHSIC è la sigla di Very High Speed Integrated Circuits) è un linguaggio di descrizione dell'hardware (HDL) nato da un progetto del Dipartimento di difesa statunitense. Il VHDL nasce nel 1987 quando diventa lo standard IEEE 1076 e nel 1993 ne esce una versione aggiornata.

È, insieme al Verilog, il linguaggio più usato per la progettazione di sistemi elettronici digitali. È lo strumento fondamentale per la progettazione dei moderni circuiti integrati digitali e le sue applicazioni spaziano dai microprocessori (DSP, acceleratori grafici), alle comunicazioni (cellulari, TV satellitare) all'automobile (navigatori, controllo stabilità) e molte altre.

Caratteristiche distintive[modifica | modifica sorgente]

Il VHDL si presenta per molti versi simile a un vero e proprio linguaggio di programmazione, in particolare ne usa i tipici costrutti quali if...then...else. Tuttavia, essendo un linguaggio che descrive il funzionamento e la struttura di componenti hardware, ha alcune caratteristiche distintive rispetto ai linguaggi software. La principale è la concorrenzialità; con questo termine si indica il fatto che diverse parti di un codice scritto in VHDL, una volta tradotte in un circuito elettronico, funzionano contemporaneamente, in quanto dispongono di hardware dedicato; al contrario, in un linguaggio software, le funzioni descritte dal codice sono generalmente eseguite dall'alto in basso, riga dopo riga, in quanto sono eseguite da un unico processore fisico.

Il VHDL permette di modellare facilmente l'interazione tra i vari blocchi funzionali che compongono un sistema. Queste interazioni sono essenzialmente lo scambio di segnali di controllo e di dati tra i vari oggetti che costituiscono il sistema. In un sistema hardware infatti ogni oggetto da modellizzare, che sia esso una semplice porta logica o un complesso microprocessore, reagisce istantaneamente agli stimoli ai suoi ingressi producendo dei cambiamenti sulle sue uscite. Ogni blocco funzionale, a sua volta, è descritto nella relazione ingressi-uscite, usando i classici costrutti del linguaggi di programmazione (if, for, while).

Utilizzo nella progettazione elettronica[modifica | modifica sorgente]

Le principali fasi di progettazione sono due:

  • nella prima l'oggetto viene descritto come ENTITY, ovvero come il componente viene visto dall'esterno: questa sezione comprende generalmente le porte di comunicazione, i tempi di ritardo, la larghezza dei bus e i parametri di configurazione;
  • nella seconda si progetta la ARCHITECTURE, ovvero l'architettura interna in cui si descrive come il dispositivo funziona; è questa la parte più importante perché ne costituisce la descrizione funzionale vera e propria.

Anche se ognuno può scrivere questa seconda parte come vuole, di solito vengono usati due stili: behavioural o structural. Con il primo, behavioural, si descrive la relazione funzionale ingressi-uscita tramite una funzione o un algoritmo; se invece si usa lo stile structural si rappresenta la struttura interna del dispositivo formata da componenti di più basso livello ed i loro collegamenti (RTL: Register transfer level), ovvero si decide già con quali oggetti realizzare la funzionalità e li si connette tra di loro.

Nella progettazione di un nuovo dispositivo, di solito, si parte da una descrizione behavioural di alto livello, per passare poi ad una descrizione RTL ovvero costituito dai componenti fondamentali digitali come i registri, l'ALU, i bus e le macchine a stati.

L'ultimo passo di traduzione del modello RTL in una netlist è eseguito in maniera automatica da un programma software che si chiama "sintetizzatore". Esempi di sintetizzatori commerciali sono ad esempio Synopsys Design Compiler per gli ASIC e ISE Xilinx o Quartus Altera per le FPGA. Il sintetizzatore produce una netlist ovvero un file vhdl o verilog di istanze di celle della tecnologia su cui viene "mappato" il circuito digitale. La tecnologia è di solito quella delle FPGA o dei circuiti integrati CMOS. Esistono anche sintetizzatori liberi, quali ad esempio Alliance VHDL o MVSIS.

Durante l'esecuzione di tutto il flusso di progettazione si effettuano delle simulazioni per verificare che sia mantenuta la congruenza tra i vari modelli behavioural, RTL e netlist. Per effettuare queste simulazioni si usa un test bench, scritto anch'esso in VHDL, che ha la funzione di generare gli stimoli sugli ingressi del circuito e di verificare la correttezza delle uscite.

Concetti fondamentali[modifica | modifica sorgente]

I costrutti del VHDL si possono dividere in due classi: i costrutti paralleli e i costrutti sequenziali.

I costrutti paralleli sono eseguiti ogni volta che almeno uno degli ingressi cambia stato; l'esempio più semplice è la descrizione di una porta AND:

Z <= A and B; 
-- se A o B cambiano valore, Z assume il nuovo valore dopo un intervallo infinitesimo delta (questo per differenziare il tipo di dato
--signal dal tipo di dato variabile). Se Z fosse una variabile, cambierebbe istantaneamente

Per descrivere funzioni più complesse si usano i processi; per esempio per descrivere un flip-flop si scrive:

FLIPFLOP : Process (clock, reset)
-- Il processo viene eseguito se clock o reset cambiano valore 
begin
if (reset='1') then
  Q <= '0';
elsif (clock'event and clock='1') then
  Q <= D;
end if;
end process;

Tutti i processi presenti in un codice VHDL agiscono come se fossero in funzione contemporaneamente. Ad esempio, supponendo di avere molti processi che descrivono ciascuno un flip-flop come quello precedente, con uguale clock di comando per tutti, quando si ha il fronte di salita del clock si deve immaginare che tutti i processi siano eseguiti contemporaneamente, in modo "concorrenziale". Nel caso di un simulatore software, poiché un computer esegue un numero limitato di operazioni contemporanee, quando non una sola alla volta, si tiene traccia dello stato iniziale e si simulano i processi in sequenza calcolando l'effetto che avrebbero avuto se fossero stati paralleli.

I costrutti sequenziali sono eseguiti riga dopo riga come nei linguaggi per il software. Ad esempio tutti i costrutti all'interno di un processo sono eseguiti sequenzialmente (vedi esempio sopra). Fanno parte dei comandi sequenziali il if...then...else, il case, il for...loop e altri.

Esempio finale[modifica | modifica sorgente]

Un esempio di programma in VHDL: il flip-flop tipo JK sincrono

  LIBRARY ieee;
  USE ieee.std_logic_1164.ALL;
 
  ENTITY jk_ff IS
  GENERIC (prop_delay : Time := 10 ns);   -- tempo di propagazione
  PORT (clk: IN STD_LOGIC;                -- segnale di clock
        j: IN STD_LOGIC;
        k: IN STD_LOGIC;
        q: OUT STD_LOGIC;                 -- l'uscita
        q_n: OUT STD_LOGIC);              -- l'uscita negata
  END jk_ff;
 
  ARCHITECTURE behavioural OF jk_ff IS
      SIGNAL outp : STD_LOGIC;
  BEGIN
     ff:PROCESS(clk)   
     BEGIN
        IF (clk'EVENT and clk='1') THEN
           IF (j='1' and k='0') THEN
              outp <= '1';
           ELSIF (j='0' and k='1') THEN
              outp <= '0';
           ELSIF (j='0' and k='0') THEN
              null;
           ELSIF (j='1' and k='1') THEN
              outp <= NOT outp;
           END IF;
        END IF;
     END PROCESS ff;
 
     q   <= outp  AFTER prop_delay;
     q_n <= NOT q AFTER prop_delay;
  END behavioural;
 
  ARCHITECTURE structural OF jk_ff IS
    COMPONENT nand3                       -- qui richiamo delle porte
      PORT (a: IN STD_LOGIC;              -- logiche NAND
            b: IN STD_LOGIC;              -- con 2 ingressi (nand2)
            c: IN STD_LOGIC;              -- o 3 ingressi (nand3)
            q: OUT STD_LOGIC);
    END COMPONENT;
 
    COMPONENT nand2
      PORT (a: IN STD_LOGIC;
            b: IN STD_LOGIC;
            q: OUT STD_LOGIC);
    END COMPONENT;
 
    SIGNAL sgn_1, sgn_2: STD_LOGIC;       -- si definiscono i segnali interni
 
    BEGIN                                 -- si descrivono le connessioni
      nand3_a: nand3 PORT MAP (a=>j, b=>clk, c=>q_n, q=>sgn_1);
      nand3_b: nand3 PORT MAP (a=>k, b=>clk, c=>q, q=>sgn_2);
      nand2_a: nand2 PORT MAP (a=>sgn_1, b=>q_n, q=>q);
      nand2_b: nand2 PORT MAP (a=>sgn_2, b=>q, q=>q_n);
  END structural;

Altri progetti[modifica | modifica sorgente]

Collegamenti esterni[modifica | modifica sorgente]