Verilog'da "Zaman" Ne Anlama Gelir
Verilog'da yerleşik bir saniye kavramı yoktur. Simülatör "zaman birimleri" ilerletir - keyfi tamsayı tick'leri - ve kodun bunlardan N tanesini beklemek için #N kullanır. `timescale direktifi bu tick'leri gerçek zamana eşler.
`timescale 1ns / 1ps
module test;
initial begin
$display("t = %0t", $time); // 0
#5;
$display("t = %0t", $time); // 5 ns
#1.5;
$display("t = %0t", $time); // 6500 ps (veya 6.5 ns)
$finish;
end
endmodule
İki parametre:
- Birim (ilk sayı):
#1'in ne demek olduğu.1ns, bir tick'in bir nanosaniye olduğunu söyler. - Hassasiyet (ikinci sayı): simülasyonun bu birim içinde zamanı ne kadar ince izlediği.
1ps, kesirli gecikmelerin picosaniyelere yuvarlandığını söyler.
Hassasiyet birimden daha kaba olamaz (1ps / 1ns yasadışıdır). Yaygın seçimler:
1ns / 1ps- de facto standart. Her şey nanosaniyede, kapı gecikmeleri için sub-nanosaniye hassasiyet.1ps / 1ps- aşırı hızlı devreleri modellerken veya her gecikme sub-nanosaniye olduğunda.1us / 1ns- yavaş, gömülü ölçekli simülasyonlar için (UART byte süreleri, yavaş protokoller).
Nereye Konulur
`timescale bir compiler directive'tir, modül seviyesi bir yapı değil. Bir dosyanın en üstüne, herhangi bir module'den önce gider:
`timescale 1ns / 1ps
module foo(...);
// ...
endmodule
Scope'u "bu noktadan itibaren derleme sırasında, bir sonraki `timescale veya derleme sonuna kadar"dır. Bunun ince bir içerimi var: açık bir `timescale'ı olmayan bir dosya, daha önce derlenen dosyanın ne tanımladığını miras alır ki bu derleyicinin dosyaları okuma sırasına bağlıdır. Sürprizden kaçın: her dosyanın üstüne `timescale koy.
Bu doc'lardaki browser editör senin için varsayılan bir timescale ayarlar (genellikle 1ns / 1ps), bu yüzden önceki doc'lardaki örnekler bir tane tanımlamadan çalıştı. Gerçek bir projede açık olurdun.
Pratikte #delay
`timescale 1ns / 1ps sonrasında:
#5 // 5 ns bekle
#100 // 100 ns bekle
#1.5 // 1.5 ns bekle (hassasiyet izin verir)
#0.001 // 1 ps bekle (hassasiyetin hemen üzerinde)
#0 // sıfır gecikme; aynı anda olayları sıralamak için kullanışlı
Bir initial veya always bloğunun içinde, #N prosedürel akışı N zaman birimi bloklar. Simülatör bu bloğu duraklatır (diğer eşzamanlı bloklar çalışmaya devam eder) ve gecikme sonrası devam eder.
Bir atamayı bir gecikmeyle önekleyebilirsin:
#10 a = 1; // 10 ns bekle, sonra ata
data <= #2 new_value; // non-blocking atamayı şimdi 2 ns'den planla
İlk form testbench zımbası. İkincisi (gecikmeli non-blocking) yayılım gecikmesini modellemek için gate-level simülasyonda kullanılır.
Bir Saat Üretme
Klasik kalıp:
`timescale 1ns / 1ps
module test;
reg clk = 0;
always #5 clk = ~clk;
// ...
endmodule
Timescale 1ns / 1ps ile #5 5 ns'dir. Saat her 5 ns flip eder, 10 ns periyot verir - bir 100 MHz saat. Frekansı değiştirmek için gecikmeyi değiştir:
| Yarı-periyot | Periyot | Frekans |
|---|---|---|
#1 | 2 ns | 500 MHz |
#2.5 | 5 ns | 200 MHz |
#5 | 10 ns | 100 MHz |
#10 | 20 ns | 50 MHz |
#25 | 50 ns | 20 MHz |
#50 | 100 ns | 10 MHz |
Kesirli bir yarı-periyot (#2.5) istiyorsan, hassasiyetinin desteklemesi gerekir - 1ps hassasiyet 0.001 ns'ye kadar her şeyi işler, bu yüzden makul herhangi bir frekans iyidir.
Dosyalar Arasında Timescale'leri Karıştırma
Gerçek bir tasarımın çok dosyası vardır ve bunlar farklı timescale'ler tanımlayabilir. Simülatör, o dosyadaki gecikmeleri yorumlamak için her dosyanın kendi timescale'ini kullanır. module_a.v `timescale 1ns / 1ps derse ve #5 kullanırsa, bu 5 ns'dir. module_b.v `timescale 1us / 1ns derse ve #5 kullanırsa, bu 5 us'dir.
Bu çoğunlukla görünmezdir çünkü simülatör ne olursa olsun global bir zaman ekseni sunar - ama iki dosyadaki aynı #N'in çılgınca farklı şeyler ifade edebileceği anlamına gelir. Düzeltme: bir timescale seç (endüstri standardı 1ns / 1ps) ve onu her dosyanın üstüne koy. Karıştırma.
Gecikmeler Sentezlenebilir Değildir
Önemli nokta: #delay yalnızca simülasyon için vardır. Sentez aracı şunu okur:
// Sentezlenebilir RTL'de - YANLIŞ
always @(posedge clk) begin
out <= #2 in;
end
…ve ya #2'yi yok sayar (çoğu araç) ya da yapıyı reddeder (daha katı linter'lar). Gerçek donanımın zamanlaması saat ve kapı yayılım gecikmesi tarafından belirlenir - her ikisi de kaynak koda görünmez.
Kural: #'i yalnızca testbench'lerde kullan. Sentezlenebilir RTL'in # gecikmesi yoktur. Sentezlenebilir kodda bir gecikme istediğini bulursan, aslında saatte sayan bir counter istiyorsun - gerçek donanım böyle "bekler".
$time vs $realtime
Mevcut simülasyon zamanını okumanın iki yolu:
$time, mevcut timescale'in birimi cinsinden 64 bitlik bir integer döndürür.$realtime, mevcut timescale'in birimi cinsinden birrealdöndürür, ama tam hassasiyetle.
Testbench loglaması için, $time neredeyse her zaman yeterlidir. Print ifadelerinde sub-tick hassasiyetine ihtiyacın olduğunda $realtime'a uzan.
Pratik İpuçları
- Her dosyanın üstüne
`timescale'ı her zaman tanımla.1ns / 1psgüvenli varsayılandır. #delay'i yalnızca testbench'lerde kullan. Sentezlenebilir kodda yokluğunu statik bir kural olarak ele al.- Saat periyotlarını hedef frekansına eşle. 50 MHz bir tasarımı simüle ediyorsan, 20 ns saat periyodu kullan - uyuşmayan periyotlar timing-hassas hataları maskeleyebilir.
- Döngü-sayılmış stimulus için
#yerine@(posedge clk)kullan. Saat periyodundaki değişikliklere karşı dayanıklıdır.
Sırada Ne Var
Artık bu Verilog tutorial'larındaki her doc'u gördün. Dil temellerinden (wire vs reg, modüller, operatörler), prosedürel bloklar ve akış kontrolü, senkron tasarım ve state machine'lere ve sonunda her şeyin çalıştığını kanıtlayan testbench tooling'e. Bir şey kurma zamanı - bu doc'ların yanındaki playground, baştan beri kullandığımız aynı simülatördür, çizdiğin herhangi bir modül için hazır.
Sıkça Sorulan Sorular
Verilog'da `timescale 1ns / 1ps ne anlama gelir?
Simülatöre 'bu dosyadaki bir zaman birimi bir nanosaniyedir ve zamanlar picosaniye hassasiyetle izlenir' der. O direktiften sonra, #5 5 ns bekler, #1.5 1.5 ns bekler (picosaniyelere yuvarlanır) ve $time nanosaniye olarak raporlanır. İlk sayı birimdir; ikincisi hassasiyettir.
Her Verilog dosyasında `timescale gerekir mi?
En iyi uygulama: evet. Direktifin scope'u bir sonraki \timescale'de veya derlemenin sonunda biter, bu yüzden bir tanesi olmayan dosyalar daha önce derlenen dosyanın ne tanımladığını miras alır. Bu zamanlamayı build'ler arasında deterministik olmaktan çıkarır. Her kaynak dosyanın üstüne `timescale 1ns / 1ps` koy - en yaygın gelenek bu - ve asla sürpriz almazsın.
Verilog'da #5 ne anlama gelir?
#5, simülasyon zamanını 5 zaman birimi ilerletir. Birim aktif \timescaledirektifinden gelir.`timescale 1ns / 1psile#5, 5 nanosaniyedir. `timescale 1us / 1nsile#5, 5 mikrosaniyedir. Sayı kesirli olabilir - hassasiyet birimden daha ince ise #1.5` çalışır.
Verilog'da #delay sentezlenebilir mi?
Hayır. #delay yalnızca simülasyonu etkiler - sentez aracı onu yok sayar veya reddeder. Gerçek donanımın zamanlaması, # ifadelerinden değil, saat sinyalinden ve kapıların yayılım gecikmesinden gelir. #'i testbench'lerde özgürce kullan; asla sentezlenebilir RTL'de yazma.