Simulacijska testna struktura

Testna struktura (ang. Testbench) je strojno opisna koda za preizkušanje modela vezja. V jeziku Verilog je testna struktura modul, ki vključuje testirano vezje in opisuje potek signalov za simulacijo. Enostavna testna struktura določa le časovni potek vhodnih signalov testiranega vezja, tako da preizkušanje poteka s pregledom rezultatov v simulatorju.

Kompleksnejše testne strukture omogočajo uvoz testnih vektorjev iz datotek in prenos rezultatov v izhodne datoteke za primerjavo in analizo z drugimi programskimi orodji. Testna struktura, ki sama preverja delovanje vezja (angl. self-checking), pa vsebuje vzporeden model oz. pravila po katerih avtomatsko preverja funkcionalnost testiranega vezja.

Enostavna testna struktura

Enostavna testna stuktura je Verilog model vezja, ki nima lastnih vhodov in izhodov, vsebuje pa deklaracijo notranjih spremenljivk, signalov in testiranega vezja. Na začetku je običajno določena časovna skala, npr. `timescale 1ns/1ps, ki pove časovno enoto za zapis zakasnitev v vezju (1ns) in časovni korak simulatorja (1ps). Primer testne strukture za preizkus polnega seštevalnika:

`timescale 1ns/1ps

module test_full_adder(); 
 reg a, b, cin;  // spremenljivke za vhode testiranega vezja
 wire s, cout;   // povezave za izhode

// inštanca testiranega vezja
full_adder dut (.a(a), .b(b), .cin(cin), .s(s), .cout(cout));

initial begin 
 a = 0; b = 0; cin = 0; #10; // nastavi vhode, počakaj 10ns
 b = 1; #10;                 // spremeni in počakaj
 a = 1; b = 0; #10;          // itd ..
 b = 1; #10; 
 a = 1; b = 1; cin = 1; #10;
end    

endmodule

Testirano vezje povežemo v testno strukturo tako, da vhode povežemo na notranje spremenljivke in izhode na povezave. Spremenljivkam (reg) v proceduralnem bloku (initial) določimo časovni potek z uporabo zaporednih blokiranih prireditev med katerimi so zapisane zakasnitve. V simulatorju nato pregledamo časovni potek izhodov in ugotovimo, ali vezje deluje pravilno.

Testni vektorji

Logična kombinacija na vseh vhodih se imenuje testni vektor in jo priredimo tako, da združimo signale na levi strani prireditvenega operatorja:

  {a, b, cin} = 3'b000; #10
  {a, b, cin} = 3'b001; #10
  {a, b, cin} = 3'b010; #10

Preizkus vezja z vsemi kombinacijami naredimo tako, da testni vektor določimo z zanko. Takšen preizkus je praktično mogoč le za vezja, ki imajo dovolj majhno število vhodnih signalov.

integer i;

initial begin 
 for (i=0; i<8; i=i+1) begin
  {a, b, cin} = i; #10;
 end
end

Vrednosti testnih vektorjev, ki so zapisane v tekstovni datoteki, preberemo s funkcijo $readmemb(datoteka, zbirka). V datoteki morajo biti zapisane zaporedne binarne vrednosti ločene s presledkom ali z novo vrstico. Funkcija prebere vse vrednosti in jih zapiše v zaporedne elemente zbirke. Primer testne strukture, ki prebere vrednosti iz datoteke in jih pošlje na vhode vezja:

integer i;
reg [2:0] testv[100:0];    // zbirka testnih vektorjev

initial begin
 $readmemb("vektorji.txt", testv);  // beri vektorje
 i = 0;

 forever begin
  {a, b, cin} = testv[i]; #10;      // nastavi vhode
  i = i + 1;
  if (testv[i] === 3'bx) $stop;     // konec vektorjev
 end

Posamezni testni vektor preberemo iz zbirke in pošljemo na vhod vezja v neskončni zanki, ki jo prekinemo, ko preberemo prvo nedefinirano vrednost. Nedefinirano vrednost ugotavljamo z uporabo operatorja ===, sistemska funkcija $stop pa ustavi sumulacijo.