Icarus Verilog
Οι εντολές που χρειάζεστε για να μεταφράσετε (compile) και για να
"τρέξετε" τον κώδικα που έχετε γράψει σε verilog είναι η "iverilog" και
η "vvp" αντίστοιχα.
iverilog
Η εντολή iverilog μεταφράζει τον κώδικα verilog σε εκτελέσιμο. Όταν
τρέξετε αυτήν την εντολή θα διαπιστώσετε αν έχετε συντακτικά λάθη στον
κώδικα. Αν σας είναι πιο εύκολο στην κατανόηση, μπορείτε να φανταστείτε
ότι η εντολή είναι η αντίστοιχη της iveriloggcc για προγράμματα C.
Για να δείτε στην πράξη τη λειτουργία της εντολής, δημιουργήστε ένα
απλό αρχείο verilog, το οποίο έχει ως σκοπό να τυπώσει το μήνυμα "Hello
world" αφού τρέξει. Ο κώδικας verilog για το παραπάνω είναι ο εξής:
module main;
initial
begin
$display("Hello, World");
$finish ;
end
endmodule
Σώστε το παραπάνω σε ένα αρχείο verilog, πχ hello.v
Μεταφράστε το παραπάνω εκτελώντας την εντολή:
iverilog -o hello hello.v
Το αποτέλεσμα είναι η δημιουργία του εκτελέσιμου αρχείου "hello". Αυτό το αρχείο θα το εκτελέσουμε με την εντολή "vvp"
vvp
Τα εκτελέσιμα αρχεία που παράγει η iverilog, δε μπορούν να τρέξουν "από
μόνα τους". Πρέπει να τα καλέσετε με την εντολή vvp. Για το παράδειγμα
που χρησιμοποιούμε, εκτελέστε:
vvp hello
Θα πρέπει να δείτε στην οθόνη το μήνυμα που είχε σκοπό να εκτυπώσει ο κώδικας verilog και αυτό είναι το:
Hello, World
Το vvp είναι το πρόγραμμα που δημιουργεί και όλα τα απαραίτητα αρχεία
ώστε να δείτε σε περιβάλλον simulation, όπως το GTKWAVE, τι ακριβώς
τιμές παίρνει το κάθε καλώδιο που σας ενδιαφέρει για το κύκλωμά σας.
vcd
Το αρχείο vcd παράγεται καθώς τρέχει ένα simulation του κώδικα verilog
που έχετε γράψει. Επομένως, χρειάζεστε εκτός από τον κώδικα περιγραφής
του κυκλώματος, άλλο ένα αρχείο, το οποίο θέτει σε λειτουργία το
κύκλωμα που έχετε περιγράψει. Αυτό το νέο αρχείο αποτελεί το testbench
του κυκλώματος.
Σαν παράδειγμα θα χρησιμοποιήσουμε την περιγραφή ενός μετρητή σε verilog:
module counter (CLK, CLR, Q);
input CLK, CLR;
output [3:0] Q;
wire [3:0] Q;
reg [3:0] tmp;
always @(posedge CLK or posedge CLR)
begin
if (CLR)
tmp <= 4'b0000;
else
tmp <= tmp + 1'b1;
end
assign Q = tmp;
endmodule
Σώστε τον παραπάνω κώδικα σε ένα αρχείο, πχ counter.v
Το testbench είναι το κύκλωμα που θέτει σε λειτουργία το κύκλωμα και
προσπαθεί να καλύψει όλες τις δυνατές λειτουργίες του. Για το
παράδειγμά μας, αρκεί να κάνουμε reset και να ξεκινήσουμε τους παλμούς
του ρολογιού. Ένα τέτοιο testbench, περιγράφεται από τον παρακάτω
κώδικα:
`timescale 1ns/10ps
module test;
reg CLR = 0;
initial begin
$dumpfile("test.vcd");
$dumpvars(0,test);
# 17 CLR = 1;
# 11 CLR = 0;
# 29 CLR = 1;
# 5 CLR = 0;
# 513 $finish;
end
reg CLK = 0;
always #1 CLK = !CLK;
wire [3:0] Q;
counter c1 (CLK, CLR, Q);
initial
$monitor("At time %t, value = %h (%0d)",
$time, Q, Q);
endmodule // test
Παρατηρήστε ότι το testbench δημιουργεί έναν counter, στη γραμμή
counter c1 (CLK, CLR, Q);
ο οποίος έχει περιγραφεί στο counter.v Επίσης το testbench
ελέγχει τα σήματα εισόδου του counter, δηλαδή το CLR και το CLK.
Παρατηρήστε τη γραμμή
`timescale 1ns/10ps
Η γραμμή αυτή ορίζει ότι οι καθυστερήσεις που αναφέρονται στο αρχείο
έχουν μονάδα μέτρησης το ns. Για παράδειγμα, η προσομείωση θα τελειώσει
μετά από 513+5+29+11+17ns. Επίσης ορίζουμε ότι η μέγιστη ακρίβεια που
μπορούμε να δούμε σε μία κυματομορφή είναι τα 10ps. Προφανώς η ακρίβεια
θα πρέπει να είναι μικρότερη από τη βάση μονάδας μέτρησης. Στο
παράδειγμά μας, έχουμε μονάδα μέτρησης το 1ns και ακρίβεια τα 10ps.
Παρατηρήστε επίσης τις γραμμές
$dumpfile("test.vcd");
$dumpvars(0,test);
Η πρώτη γραμμή ορίζει το όνομα του vcd αρχείου το οποίο θα
χρησιμοποιήσει το GTKWAVE και η δεύτερη γραμμή ορίζει ότι θέλουμε όλες
οι μεταβλητές που ορίζονται από το test και κάτω (συμπεριλαμβανομένου
και του counter επομένως) να εμφανιστούν στο vcd.
Σώστε τον κώδικα του testbench σε ένα αρχείο, πχ test.v
Μεταφράστε τον κώδικα και τρέξτε τον καλώντας τις εντολές:
iverilog test.v counter.v -o counter
vvp counter
Αφού παραχθεί το vcd, μπορούμε να δούμε γραφικά τις τιμές που πήρε το κάθε καλώδιο κατά τη διάρκεια της προσομείωσης.
Περισσότερες πληροφορίες για το icarus verilog μπορείτε να βρείτε εδώ.