VHDL

linguaggio di descrizione hardware

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

Esempio di codice VHDL

È, 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), comunicazioni (cellulari, TV satellitare), automobili (navigatori, controllo di stabilità) a molte altre.

Caratteristiche distintive

modifica

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 sequenzialmente, riga dopo riga, in quanto dispongono di 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 modellare, sia esso una semplice porta logica o un complesso microprocessore, reagisce istantaneamente ai cambiamenti di stato dei propri ingressi producendo dei cambiamenti sulle proprie 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

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

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 almeno uno tra i segnali clock e reset cambia 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

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                      -- si richiamano delle porte logiche NAND
    port (a, b, c : in std_logic;      -- con 3 ingressi (nand3)
          q : out std_logic);
  end component;

  component nand2
    port (a, b : in std_logic;         -- o 2 ingressi (nand2)
          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

Collegamenti esterni

modifica
Controllo di autoritàLCCN (ENsh89002702 · J9U (ENHE987007546559905171