mercoledì 10 luglio 2013

FPGA: I Testbench

 

Verificare manualmente i propri design creando le forme d’onda di stimolo in ModelSim può risultare un’operazione lunga e faticosa, soprattutto se è necessario ripetere più volte i test ad ogni modifica. Il transcript di ModelSim, una console che permette di inserire testualmente le azioni da eseguire, può alleviare il problema ma esiste un’alternativa migliore da utilizzare sistematicamente.

Nel paradigma di sviluppo software esiste il concetto di unit-test, un semplice programma il cui scopo è verificare se un componente si comporta come desiderato. Gli uni-test sono scritti manualmente dal programmatore e per verificare la correttezza di una funzione possono ad esempio presentare in ingresso alcuni dati e confrontare il risultato con dati noti.

Nel mondo della progettazione di sistemi elettronici digitali in VHDL esiste un concetto simile, il test-bench, un’entità VHDL non sintetizzabile ma eseguibile da un simulatore che si occupa di presentare degli stimoli di ingresso a delle entità ed eventualmente verificarne l’evoluzione delle uscite. Il linguaggio VHDL presenta un’ampia varietà di costrutti non sintetizzabili che ci potranno venire in aiuto nella stesura dei test.

Ecco un esempio di testbench per l’entità HelloHw creata nell’articolo precedente (con conteggio del contatore fino a 10 e non 50.000.000 per abbreviare i tempi di simulazione):


library IEEE;
use IEEE.std_logic_1164.all;

entity HelloHwTB is
end HelloHwTB;

architecture TBImpl of HelloHwTB is
    component HelloHw
        port
        (       
            clock    : in  STD_LOGIC;
            reset    : in  STD_LOGIC;               
            led        : buffer STD_LOGIC
        );
    end component;
    signal clock, reset, led: std_logic;   
begin

    uut: HelloHw port map(
        clock => clock,
        led => led,
        reset => reset
    );
   
    clock_proc: process
    begin
        clock <= '0';
        wait for 10 ns;
       
        clock <= '1';
        wait for 10 ns;
    end process;
   
    reset_proc: process
    begin
        reset <= '0';
        wait for 10 ns;
        reset <= '1';
        wait;
    end process;
   
    stim_proc: process
    begin        
        wait for 10 ns;
        assert led = '0';  -- after reset low output
        wait for 181 ns;
        assert led = '1';  -- after reset one cycle less (count to 9)
        wait for 200 ns;
        assert led = '0';
        wait for 200 ns;
        assert led = '1';
        wait;
    end process;
 
end TBImpl;


Il nostro testbench sarà sostanzialmente un’entità vuota chiamata HelloHwTB come è possibile vedere dalle prime righe di codice, l’implementazione istanzierà il componente HelloHw e creerà dei segnali da collegare (mappare) al componente tramite l’istruzione port map

Il test consisterà in tre processi eseguiti parallelamente:

- un processo clock_proc che avrà il compito di generare il clock (in questo caso 50 MHz)

- un processo reset_proc che inizialmente resetterà il componente e che poi resterà in attesa indefinitivamente

- un processo stim_proc che si occuperò di controllare le uscite dopo un certo periodo per verificare se corrispondenti ai valori desiderati, i primi 10 ns sono per attendere il reset del componente dopodiché si verificherà (in malo modo per semplicità) che assuma alternativamente i valori 0 ed 1 dopo. Da notare che il primo ciclo dopo il reset sarà più breve di 20ns.

Si notino le istruzioni wait for per attendere un intervallo temporale e l’istruzione assert per verificare una condizione logica e nel caso non fosse verificata generare un errore nel simulatore.

Per poter eseguire il test aggiungiamo un file VHDL al nostro progetto col codice del testbench sopra riportato

set

Scegliamo il menù Assignements / Settings, raggiungibile come evidenziato dall’immagine anche da barra degli strumenti ed arriviamo alla categoria EDA Tool Settings / Simulation dove sceglieremo come Compile test bench nella sezione NativeLink settings il nostro testbench premendo sul pulsante Test Benches. NativeLink è il sistema di scambio dati tra Quartus e programmi di terze parti,

SettingsSimulation

Nell finestra che apparirà dovremmo ricordarci di impostare il periodo di simulazione a 1000 ns (o un tempo ragionevole) per evitare di simulare un periodo troppo lungo non utile alla verifica del componente. In alternativa sarebbe stato possibile modificare il testbench per fermare il clock dopo il periodo di test e scegliere la voce Run simulation until all vector stimuli are used

NewTestBenchSettings

Dopo aver confermato compiliamo il nostro progetto (Analysis & Synthesis) ed eseguiamo la RTL Simulation, senza compiere ulteriori azioni una volta aperto ModelSim verranno simulati nel modo descritto i nostri segnali

sim

Nella finestra Transcript non sarà presente nessun errore, segno che gli assert sono stati “onorati” e che il nostro design funziona come abbiamo “previsto”. Nel caso di errori messaggi come

# ** Error: Assertion violation.
#    Time: 190 ns  Iteration: 0  Instance: /hellohwtb

Ci informeranno in quale istanza ed istante si è verificata la violazione.

In casi semplici è sempre consigliato controllare manualmente le forme d’onda per identificare eventuali discrepanze dal risultato che si voleva ottenere. In situazioni più complicate è possibile leggere gli input dei test da dei file e registrare i risultati ottenuti.

Nessun commento:

Posta un commento