Verilog'un C printf Ailesi
Üç system task simülatörün stdout'una yazdırmana izin verir:
$display- bir kez yazdır, bir newline ekle.$write- bir kez yazdır, newline yok.$monitor- izlenen bir sinyal her değiştiğinde otomatik yazdır.
Üçü de bir format string ve bir argüman listesi alır, tıpkı printf gibi. Format specifier'lar benzerdir ama Verilog'a özgüdür.
$display: Varsayılan
$display iş atıdır:
Şuna benzer bir şey göreceksin:
Hello, world.
byte_val = ab
byte_val = 10101011
byte_val = 171
byte_val = 171 (dolgu yok)
multi: nibble=1010 count=42
Notlar:
%d, operand boyutuna dayalı varsayılan bir genişliğe doldurur. 8 bitlik birregiçin, bu 3 karakterdir (255için yer). Önündeki boşluklar tablo çıkışında çirkin görünebilir - bunları bastırmak için%0dkullan.%h,%b,%ovarsayılan olarak benzer dolguya sahiptir. Çoğu testbench kodu, hizalama yararlı olmadığında%0varyantlarını kullanır.- Sondaki newline otomatiktir. Bir
$displayformat string'inin sonuna\nkoyma - boş bir satır alırsın.
Format Specifier'lar
Verilog'un desteklediği set:
| Specifier | Anlam |
|---|---|
%b | binary |
%d | decimal (sinyal signed ise signed) |
%h veya %x | hex |
%o | octal |
%c | tek ASCII karakter (alt 8 bit) |
%s | string |
%t | simülasyon zamanı |
%m | mevcut scope'un hiyerarşik adı |
%% | literal bir % |
%0X | önündeki dolgu yok, %b, %d vb. için |
%b, %d, %h, %o zamanın %95'inde kullanacağın dörttür. %t bir sonraki en yaygın - zaman damgalı bir log satırı istediğin her zaman.
$write: Newline Yok
$write, bir newline eklememesi dışında $display ile aynıdır:
Çıkış:
abc
done
Bir döngü gövdesinden tek bir satır kurmak için kullanışlı:
$write("[");
for (integer i = 0; i < 8; i = i + 1) $write("%h ", arr[i]);
$display("]");
$monitor: Değişiklikte Otomatik Yazdır
$monitor bir izleme listesi kaydeder. Simülatör, format string'de bahsedilen herhangi bir sinyal değiştiğinde tekrar değerlendirir ve yazdırır:
Üç satır göreceksin, her bir giriş değişikliği için bir tane. Her stimulus değişikliğinden sonra manuel olarak $display çağırmaya gerek yok - $monitor bunu yapar.
İki sınırlama:
- Yalnızca bir
$monitoraktif olabilir. Tekrar çağırmak önceki izleme listesini değiştirir. Geçici olarak bastırmak ve tekrar etkinleştirmek için$monitoroffve$monitoronkullan. - Aynı zaman adımındaki değişiklikler tek bir yazdırmada birleşir. Eğer
avebher ikisi de 5 zamanında değişirse, monitor iki kez değil, her iki yeni değerle bir kez tetiklenir.
Her Birini Ne Zaman Kullanmalı
$display: çoğu testbench çıkışı. Stimulus'tan sonra, önemli durum geçişlerinden sonra veya bir örneklemealways @(posedge clk)bloğunun içinde açıkça çağır.$write: bir döngüden veya birkaç küçük parçadan tek bir satır kurmak istediğinde.$monitor: küçük bir sinyal setini sürekli izlemek ve yalnızca değiştiklerinde çıktı görmek istediğinde. İlk debug için kullanışlı; regression script'lerde kullanması zordur çünkü çıktı toplam satır sayısı açısından deterministik değildir.
Çoğu iş akışı için $display her şeyi karşılar. Yalnızca sürekli değişim güdümlü çıktı gerçekten istediğin şey olduğunda $monitor'a uzan.
Zaman ile Çalışma
$time mevcut simülasyon zamanını 64 bitlik bir tamsayı olarak döndürür. %0t ile eşleştir:
$display("%0t zamanında: sinyal değişti", $time);
Çıkış 25 zamanında: sinyal değişti gibi görünür (birim timescale'ine bağlıdır).
Alt-tick hassasiyetine ihtiyacın varsa (nadir), bunun yerine $realtime kullan - bir real döndürür.
%t, simülatörün seçtiği varsayılan genişlikle zamanı otomatik olarak biçimlendirir. %0t dolguyu siler.
Saat Kenarında Örnekleme
Sıralı tasarımları izlemek için temiz bir deyim: döngü başına bir kez yazdıran ayrı bir always @(posedge clk) bloğu:
Bu örnekleme kalıbı saat başına bir log satırını garanti eder - çıktıda pattern-match yapan regression testleri için mükemmel.
Bir Dosyaya Log
$fopen ile bir dosya aç, $fdisplay ile log'la (bu $display gibi çalışır ama bir dosya tanıtıcısına yazar):
integer fd;
initial begin
fd = $fopen("results.txt", "w");
$fdisplay(fd, "test=%s status=%s", test_name, status);
$fclose(fd);
end
$fopen, 32 bitlik bir tanıtıcı döndürür; onu $fdisplay, $fwrite, $fstrobe vb.'nin ilk argümanı olarak ilet. Fonksiyonlar konsol yazdırma kardeşleriyle aksi takdirde aynıdır.
Sırada Ne Var
$display ve arkadaşları sana metin log'ları verir. Görsel debug için - sinyalleri zamanla voltajlar olarak izlemek için - bir VCD waveform istersin. Bir sonraki doc, Dumpfile and VCD, simülasyonunu kaydırarak inceleyebileceğin grafik bir waveform'a dönüştüren iki çağrı olan $dumpfile ve $dumpvars'ı kapsar.
Sıkça Sorulan Sorular
Verilog'da $display ile $monitor arasındaki fark nedir?
$display, çalıştırıldığında bir kez, anında yazdırır - C'deki printf gibi. $monitor bir izleme listesi kaydeder; listedeki herhangi bir sinyal değiştiğinde, biçimlendirilmiş mesaj otomatik olarak yazdırılır. Aynı anda yalnızca bir $monitor aktif olabilir; tekrar çağırmak önceki izleme listesini değiştirir.
Verilog $display hangi format specifier'ları destekler?
Yaygın olanlar: %b (binary), %d (decimal), %h (hex), %o (octal), %c (alt byte'tan tek karakter), %s (string), %t (simülasyon zamanı), %m (hiyerarşik instance adı). Önündeki sıfır dolgusunu atmak için %0d formunu kullan - %d varsayılan bir genişliğe doldurur, %0d dolgu üretmez.
Verilog'da $write nedir?
$write, $display gibidir ama bir newline eklemez. Birden çok çağrıdan bir çıkış satırı kurmak istediğinde kullanışlıdır. Satır sonu $display (argümansız veya sondaki bir newline ile) satırı sonlandırır.
Verilog'da simülasyon zamanını nasıl yazdırırım?
%t format specifier'ı ile $time (veya alt-tick çözünürlüğü için $realtime) kullan: $display("%t zamanında: ...", $time);. Varsayılan dolguyu bastırmak için %0t kullan. Zaman birimlerinin sade tamsayı sayımı için $time ile %0d de çalışır: $display("t=%0d", $time);.