Matriklinumber: 999999-le vastava funktsioonide süsteemi tõeväärtus-tabel oleks järgmine:
0000 1-00 0001 01-0 0010 11-1 0011 0-01 0100 1110 0101 1010 0110 -111 0111 01-0 1000 0011 1001 -10- 1010 -0-1 1011 1001 1100 11-0 1101 0-10 1110 -000 1111 1011
Seda tabelit kirjeldav SystemVerilog kood oleks järgmine (vt. ka faili):
module fs_table (input x1, x2, x3, x4, output y1, y2, y3, y4);
logic [1:4] out_word;
always_comb
case ({x1,x2,x3,x4})
4'b0000 : out_word = 4'b1z00;
4'b0001 : out_word = 4'b01z0;
4'b0010 : out_word = 4'b11z1;
4'b0011 : out_word = 4'b0z01;
4'b0100 : out_word = 4'b1110;
4'b0101 : out_word = 4'b1010;
4'b0110 : out_word = 4'bz111;
4'b0111 : out_word = 4'b01z0;
4'b1000 : out_word = 4'b0011;
4'b1001 : out_word = 4'bz10z;
4'b1010 : out_word = 4'bz0z1;
4'b1011 : out_word = 4'b1001;
4'b1100 : out_word = 4'b11z0;
4'b1101 : out_word = 4'b0z10;
4'b1110 : out_word = 4'bz000;
default : out_word = 4'b1011;
endcase
assign {y1,y2,y3,y4} = out_word;
endmodule
Andmetüüp logic on 4-valentne ja väärtus z tähistab määramatust (signaal out_word).
Lihtsa testpingi SystemVerilog kood oleks järgmine (vt. ka faili):
`timescale 1 ns / 1 ns
module test_single;
logic [1:4] xi = 0;
logic y1, y2, y3, y4;
// Sequence 0000 ... 1111
initial begin
repeat (16) #10 xi++;
$stop;
end
fs_table u1 (xi[1], xi[2], xi[3], xi[4], y1, y2, y3, y4);
endmodule
Kõige lihtsam ModelSim'i kasutamise juhend oleks alljärgnev
(keerukam juhend on
siin):
- käsk "cad" abil valida Mentor Graphics (nt. 2);
- käsk "vsim" paneb simulaatori tööle;
- simulaatori töötades "File->New->Library..." abil luua teek
"work" (kui pole varem loodud);
- "Compile->Compile..." abil kompileerida nii funktsioonide süsteem kui
ka testpink;
- "Simulate->Start Simulation..." alt valida "work" seest "test" (veenduda,
et "Enable optimization" oleks lubatud); lisaks tuleb "Optimization
Options..." seest valida "Apply full visibility to all modules (full debug
mode)", sest muidu optimeeritakse osad signaalid välja;
- aktiveerige alam-aken "Objects" ja "Add->To Wave->Signal in Design"
lisab kõik signaalid lainekuju aknasse;
- simulaatori käsureal "run -all" teostab simuleerimise;
- aktiveerige alam-aken "Wave" ja menüüst "Wave->Zoom->Zoom
Full" täidab akna ühtlaselt tulemustega.
Võrrelge tulemusi lähteülesandega.
Korrake seda sama (kompileerimine & simuleerimine) espresso tulemusest saadud funktsioonide süsteemiga (vt. ka faili):
module fs_espresso (input x1, x2, x3, x4, output y1, y2, y3, y4);
assign y1 = ((!x1) & x2 & (!x3) & x4) |
(x2 & (!x3) & (!x4)) |
((!x1) & (!x4)) | (x1 & x3);
assign y2 = !( ((!x1) & x2 & (!x3) & x4) |
(x1 & (!x2) & (!x4)) | (x1 & x3) );
assign y3 = (x2 & (!x3) & (!x4)) | (x2 & x4) |
((!x1) & x3 & (!x4)) | (x1 & (!x2) & (!x4));
assign y4 = (x1 & x3 & x4) | ((!x2) & x3) |
((!x1) & x3 & (!x4)) | (x1 & (!x2) & (!x4));
endmodule
Pange testpingis komponent fs_table asemele fs_espr ja simuleerige uuesti. Võrrelge tulemusi lähteülesandega (simulatsiooniga).
Korrake seda sama ka loogika-tehete tasemel oleva (optimeeritud) skeemiga (vt. ka faili):
module fs_opti (input x1, x2, x3, x4, output y1, y2, y3, y4); logic x2i, t1i, t2i, t3x, t3i, t4i, t5i, t6; logic t7, t8x, t8, t68i, t9i, t19, t197i; assign x2i = !(x2 & x2); assign t1i = t4i | x1 | x3; assign t2i = !(x1 & x3 & x4); assign t3x = !(x3 | x4); assign t3i = !(x2 & t3x); assign t4i = !(x2 & x4); assign t5i = !(x2i & x3); assign t6 = t7 & x3; assign t7 = !(x1 | x4); assign t8x = !(x2 | x4); assign t8 = x1 & t8x; assign t68i = !(t6 | t8); assign t9i = !(x1 & x3); assign t19 = !(t1i & t9i); assign t197i = !(t19 | t7); assign y1 = !(t197i & t3i); assign y2 = !(t19 | t8); assign y3 = !(t3i & t4i & t68i); assign y4 = !(t2i & t5i & t68i); endmodule
Pange testpingis komponendiks fs_opti ja simuleerige uuesti. Võrrelge tulemusi lähteülesandega (simulatsiooniga).
Oluliselt mugavam oleks, kui saaks omavahel võrrelda mitut eri etappi sama simulatsiooni käigus. Heaks näiteks on alljärgnev testpink, mis lubav korraga simuleerida kolme disaini (algne tabel, espresso tulemus ja optimeeritud skeem). Lisaks sisaldab testpink ka kontrollivat funktsiooni - kolme komponendi v&ljundid tüürivat vastavat kontroll-signaali, mis erinevuse korral saab vigase väärtuse (x) ja punase värvuse (signaalid y1x, y2x, y3x ja y4x). Sama kood on ka failist leitav:
`timescale 1 ns / 1 ns
module test_bench;
logic [1:4] xi = 0;
wire y1a, y1b, y1c, y1x;
wire y2a, y2b, y2c, y2x;
wire y3a, y3b, y3c, y3x;
wire y4a, y4b, y4c, y4x;
// Sequence 0000 ... 1111
initial begin
repeat (16) #10 xi++;
$stop;
end
// Truth table
fs_table u1 (xi[1], xi[2], xi[3], xi[4], y1a, y2a, y3a, y4a);
assign y1x=y1a, y2x=y2a, y3x=y3a, y4x=y4a;
// Espresso result
fs_espresso u2 (xi[1], xi[2], xi[3], xi[4], y1b, y2b, y3b, y4b);
assign y1x=y1b, y2x=y2b, y3x=y3b, y4x=y4b;
// Optimized circuit
fs_opti u3 (xi[1], xi[2], xi[3], xi[4], y1c, y2c, y3c, y4c);
assign y1x=y1c, y2x=y2c, y3x=y3c, y4x=y4c;
endmodule
Võrrelge tulemusi eelnevate simulatsioonidega. Signaalide y1a, y1b ja y1c, y2a, y2b ja y2c, y3a, y3b ja y3c ning y4a, y4b ja y4c õige järjekord on tagatud nende deklrareermise järjekorraga SystemVerilog failis. Selle tulemusena on hästi näha, kuidas väärtused eri mudelitel kokku langevad. Üksikud punased piigid tekivad omistamise viitest, sest signaalid läheva sisendist väljunditesse läbi erineva arvu omistamiste.
Kui simulatsioonide tulemused ei klapi, tuleks viga üles otsida. Toodud näites on "ära unustatud" üks inversioon ja viga on näha nendes väljundites, mis seda signaali kasutasid. Vt ka faili (signaal t68i):
module fs_opti (input x1, x2, x3, x4, output y1, y2, y3, y4); logic x2i, t1i, t2i, t3x, t3i, t4i, t5i, t6; logic t7, t8x, t8, t68i, t9i, t19, t197i; assign x2i = !(x2 & x2); assign t1i = t4i | x1 | x3; assign t2i = !(x1 & x3 & x4); assign t3x = !(x3 | x4); assign t3i = !(x2 & t3x); assign t4i = !(x2 & x4); assign t5i = !(x2i & x3); assign t6 = t7 & x3; assign t7 = !(x1 | x4); assign t8x = !(x2 | x4); assign t8 = x1 & t8x; //assign t68i = !(t6 | t8); assign t68i = (t6 | t8); assign t9i = !(x1 & x3); assign t19 = !(t1i & t9i); assign t197i = !(t19 | t7); assign y1 = !(t197i & t3i); assign y2 = !(t19 | t8); assign y3 = !(t3i & t4i & t68i); assign y4 = !(t2i & t5i & t68i); endmodule
Varasem silumisnäidis annab ehk ettekujutuse, kuidas seda põhjalikuma analüüsi abil teha. See on küll tehtud vanema näidislahenduse jaoks ja VHDL-s, kui vea otsimise põhimõte jääb siiski samaks...