Assertions (SVA)
Gün 5: Arayüzler, Assertion ve Coverage | Immediate ve Concurrent assertion'lar, property, sequence
Bu derste SystemVerilog Assertions (SVA) ile tasarımın doğru davranıp davranmadığını otomatik olarak nasıl denetleyeceğimizi öğreneceğiz. immediate ve concurrent assertion farkını, sequence ve property yapılarını ve cover kullanımını ele alacağız.
Assertion Nedir, Neden Kullanılır?
Assertion, tasarımın uyması gereken bir kuralı biçimsel olarak ifade eden ve simülasyon sırasında sürekli denetleyen bir ifadedir. Kural ihlal edildiği anda assertion başarısız olur ve mesaj basar. Faydaları:
- Hatayı kaynağında yakalar: Hata, etkisi çıkışa yansımadan, oluştuğu saatte raporlanır.
- Belgeleme görevi görür: Protokol kuralları kodun içinde okunabilir biçimde yazılı durur.
- Kapsam ölçer:
coverile belirli senaryoların gerçekten test edildiğini doğrularsınız.
Immediate ve Concurrent Assertion Farkı
- Immediate assertion: Prosedürel bir blok içinde (
always,initial) yürütülür ve o anda, bir yazılımififadesi gibi anlık değerlendirilir. Zamansal davranış denetlemez. - Concurrent assertion: Bir saat olayına göre çalışır (
@(posedge clk)), birden fazla saat çevrimine yayılan zamansal ilişkileri kontrol eder.propertyvesequenceile kurulur.
Property, Sequence ve Operatörler
sequence: Zaman içindeki sinyal desenlerini tarif eder.##[1:3]"1 ila 3 çevrim sonra",[*4]"4 ardışık çevrim boyunca" anlamına gelir.property: Bir koşulun sonucunu tanımlar.|->(overlapping) tetikleme ile sonucu aynı çevrimde,|=>(non-overlapping) ise sonraki çevrimde bekler.disable iff (!rst_n): Reset aktifken assertion'ı devre dışı bırakır; reset sırasındaki sahte ihlalleri önler.$fell/$rose: Bir sinyalin düşen/yükselen kenarını yakalar.
Kaynak Kod
// =============================================================================
// GUN 5 - Konu 4: SystemVerilog Assertions (SVA) - Immediate ve Concurrent
// =============================================================================
module assertions;
logic clk = 0;
always #5 clk = ~clk;
logic rst_n;
logic req;
logic gnt;
logic valid;
logic ready;
logic [7:0] data;
logic error;
// Basit DUT davranisi
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
gnt <= 0;
ready <= 0;
error <= 0;
end else begin
gnt <= req; // 1 cycle gecikme ile grant
ready <= valid; // 1 cycle gecikme ile ready
error <= (data == 8'hFF); // 0xFF durumunda hata
end
end
// =========================================================================
// IMMEDIATE ASSERTIONS: Prosedurel blok icinde, aninda kontrol
// =========================================================================
always @(posedge clk) begin
if (rst_n) begin
// Basit immediate assertion
assert_valid_data: assert (data !== 8'hxx)
else $warning("[%0t] Data belirsiz (x)!", $time);
// Error ve valid ayni anda aktif olmamali
assert_no_error_valid: assert (!(error && valid))
else $error("[%0t] Error ve valid ayni anda aktif!", $time);
end
end
// =========================================================================
// SEQUENCE TANIMLARI: Zamansal davranislar icin yapi taslari
// =========================================================================
sequence s_handshake;
valid ##[1:3] ready;
endsequence
sequence s_burst;
valid [*4]; // 4 ardisik cycle boyunca valid
endsequence
// =========================================================================
// CONCURRENT ASSERTIONS: Zamansal iliskileri kontrol eder
// =========================================================================
// Property: req -> sonraki cycle gnt gelmeli
property p_req_gnt;
@(posedge clk) disable iff (!rst_n)
req |=> gnt;
endproperty
// Property: valid kalktiginda 1-3 cycle icinde ready gelmeli
property p_valid_ready;
@(posedge clk) disable iff (!rst_n)
valid |-> ##[1:3] ready;
endproperty
// Property: Reset durumunda tum cikislar sifir olmali
property p_reset_check;
@(posedge clk)
!rst_n |-> !gnt && !ready && !error;
endproperty
// Property: Req dustugunde sonraki cycle gnt de dusmeli
property p_req_deassert;
@(posedge clk) disable iff (!rst_n)
$fell(req) |=> $fell(gnt);
endproperty
// --- SEQUENCE KULLANAN YENI PROPERTY'LER ---
// s_handshake kullanan property: Handshake gerceklestiginde hata (error) olmamali
property p_handshake_no_error;
@(posedge clk) disable iff (!rst_n)
s_handshake |-> !error;
endproperty
// s_burst kullanan property: 4 valid'lik burst isleminden sonra gnt gelmeli
property p_burst_leads_to_gnt;
@(posedge clk) disable iff (!rst_n)
s_burst |-> ##[1:5] gnt;
endproperty
// =========================================================================
// ASSERTION'LARI ETKINLESTIRME (ASSERT & COVER)
// =========================================================================
assert property (p_req_gnt)
else $error("[%0t] REQ->GNT ihlali!", $time);
assert property (p_valid_ready)
else $error("[%0t] VALID->READY ihlali!", $time);
assert property (p_reset_check)
else $error("[%0t] Reset kontrol ihlali!", $time);
assert property (p_handshake_no_error)
else $error("[%0t] Handshake sequence sirasinda hata olustu!", $time);
assert property (p_burst_leads_to_gnt)
else $error("[%0t] Burst tamamlandi ancak grant gelmedi!", $time);
// Cover: Bu durumun gerceklestigini dogrula
cover property (p_req_gnt)
$display("[%0t] COVER: req->gnt gozlemlendi", $time);
// Sequence'larin gerceklesip gerceklesmedigini dogrudan takip etme
cover property (@(posedge clk) s_handshake)
$display("[%0t] COVER: Handshake sequence (s_handshake) tamamlandi", $time);
cover property (@(posedge clk) s_burst)
$display("[%0t] COVER: Burst sequence (s_burst) tamamlandi", $time);
// =========================================================================
// TEST UYARICILARI (STIMULUS)
// =========================================================================
initial begin
$display("=== SystemVerilog Assertions (SVA) ===\n");
rst_n = 0; req = 0; valid = 0; data = 0;
#20;
rst_n = 1;
#10;
// Normal req/gnt
$display("--- Normal REQ/GNT ---");
@(posedge clk); req = 1;
@(posedge clk); @(posedge clk);
req = 0;
#20;
// Valid/Ready handshake
$display("--- VALID/READY Handshake ---");
@(posedge clk); valid = 1; data = 8'hAB;
@(posedge clk); @(posedge clk);
valid = 0;
#30;
// Hata durumu
$display("--- Hata Testi (data=0xFF) ---");
@(posedge clk); valid = 1; data = 8'hFF;
@(posedge clk); valid = 0; data = 0;
#30;
// YENI: Burst durumu
$display("--- Burst Testi (4 ardisik valid) ---");
@(posedge clk);
req = 1; // p_burst_leads_to_gnt property'sini saglamak icin req tetikleniyor
valid = 1; data = 8'h11;
@(posedge clk); valid = 1; data = 8'h22; req = 0;
@(posedge clk); valid = 1; data = 8'h33;
@(posedge clk); valid = 1; data = 8'h44;
@(posedge clk); valid = 0;
#40;
$display("\n=== SVA Sonu ===");
$finish;
end
endmodule
Kodun Açıklaması
- DUT davranışı: İlk
always @(posedge clk or negedge rst_n)bloğu basit bir tasarımı modeller:gnt <= req(1 çevrim gecikmeli grant),ready <= valid(1 çevrim gecikmeli ready) veerror <= (data == 8'hFF)(0xFF'te hata). - Immediate assertion'lar:
assert_valid_data,data'nın belirsiz (x) olmadığını anlık kontrol eder ve ihlalde$warningüretir.assert_no_error_valid,errorilevalid'in aynı anda aktif olmadığını denetler, ihlalde$errorverir. sequence s_handshake:valid ##[1:3] ready—valid'ten 1-3 çevrim sonrareadygelmesini tarif eder.sequence s_burst:valid [*4]—valid'in 4 ardışık çevrim sürdüğü deseni tanımlar.- Concurrent property'ler:
p_req_gnt:req |=> gnt—req'ten bir sonraki çevrimdegntgelmeli.p_valid_ready:valid |-> ##[1:3] ready—valid'ten sonra 1-3 çevrim içindereadygelmeli.p_reset_check:!rst_n |-> !gnt && !ready && !error— reset sırasında tüm çıkışlar sıfır olmalı (burada bilinçli olarakdisable iffyoktur).p_req_deassert:$fell(req) |=> $fell(gnt)—reqdüştüğünde sonraki çevrimdegntde düşmeli.p_handshake_no_error:s_handshake |-> !error— el sıkışma tamamlandığında hata olmamalı.p_burst_leads_to_gnt:s_burst |-> ##[1:5] gnt— 4'lük burst sonrası 1-5 çevrim içindegntgelmeli.
- Etkinleştirme: Her property
assert property (...) else $error(...)ile denetlenir. Ayrıcacover property (...)ifadeleri (p_req_gnt,s_handshake,s_burst) ilgili senaryonun gerçekten oluştuğunu raporlar. - Stimulus (
initialbloğu): Reset uygulanır; sırasıyla normalreq/gnt,valid/readyel sıkışma,data=0xFFhata senaryosu ve 4 ardışıkvalid'lik burst testleri yürütülür. Burst testindereqbilinçli tetiklenir, çünküp_burst_leads_to_gntgntüretimini gerektirir.
Önemli Noktalar
|->ve|=>ayrımı:|->sonucu aynı çevrimde,|=>ise bir sonraki çevrimde bekler. Yanlış seçim, doğru tasarımı bile başarısız assertion ile raporlatır.disable iffile reset koruması: Reset sırasında çıkışlar geçersizdir;disable iff (!rst_n)olmadan reset her assertion'ı sahte şekilde tetikleyebilir. Dikkat:p_reset_checkbilerek bu korumayı kullanmaz, çünkü amacı tam da reset davranışını doğrulamaktır.coverile boş test tuzağından kaçının: Bir assertion'ın hiç ihlal edilmemesi, senaryonun test edildiği anlamına gelmez.cover propertysenaryonun gerçekten gerçekleştiğini kanıtlar.- Sequence'ler yeniden kullanılır:
s_handshakeves_burstbirden çok property içinde tekrar kullanılır; bu, bakımı kolaylaştırır. - Immediate vs concurrent yerleşimi: Immediate assertion'lar prosedürel blok içinde anlık; concurrent assertion'lar modül düzeyinde saat tabanlı çalışır. İhtiyaca göre doğru türü seçin.