58 / 63 · Konsep
Verifikasi FIFO dan memori dengan scoreboard independen
Tulis scoreboard tanpa pointer DUT dan rencanakan batas, reset, validitas, serta baca belum diinisialisasi.
Pelajaran dapat dibaca gratis. Daftar untuk menyimpan progres.
Bangun jawaban dengan cara berbeda dari DUT
Verifikator membandingkan kontrak dengan DUT. Menyalin rptr dan wptr dapat mengulangi kesalahan pointer. ScoreboardScoreboard Keadaan acuan lingkungan verifikasi yang membandingkan data harapan dan keluaran nyata menurut urutan. Dihitung independen dari keadaan internal implementasi. independen hanya menyimpan urutan logis FIFOFIFO Antrean yang mengeluarkan data masuk pertama lebih dahulu. Aturan penuh, kosong, dan baca/tulis bersamaan merupakan bagian kontrak. Selengkapnya dalam queue SystemVerilog: tambahkan di belakang untuk push diterima, keluarkan depan untuk pop diterima.
Silangkan kosong/antara/penuh dengan tanpa permintaan/push/pop/keduanya. Tambahkan wrap berulang, pop berurutan, serta reset ketika data tersisa. Catat cakupan, seed acak, dan masukan gagal agar dapat direproduksi.
Hitung penerimaan harapan dari ukuran queue lama , bukan full atau occupancy DUT.
Ambil head lama sebelum menambahkan data baru agar head pertukaran saat penuh terjaga. Bandingkan dout hanya jika diharapkan.
Testbench lengkap
Testbench ini dikompilasi bersama fifo4 pelajaran sebelumnya. Ia memakai delay dan queue untuk verifikasi. Masukan berubah pada tepi turun; 1ps setelah tepi naik, pembaruan nonblockingNonblocking Penugasan <= pada RTL sekuensial: sisi kanan dievaluasi lalu pembaruan dijadwalkan, sehingga register pada tepi sama menghitung dari keadaan lama. Selengkapnya DUT dibandingkan.
module tb_fifo4;
timeunit 1ns;
timeprecision 1ps;
typedef logic [7:0] word_t;
logic clk=0, rst=1, push=0, pop=0;
word_t din=0, dout;
logic dout_valid, full, empty;
logic [2:0] occupancy;
word_t model[$], expected;
bit expect_pop, expect_push;
fifo4 dut (.*);
always #5ns clk = ~clk;
always @(posedge clk) begin
if (rst) begin
model.delete();
expect_pop = 0;
end else begin
expect_pop = pop && (model.size() != 0);
expect_push = push && ((model.size() < 4) || expect_pop);
if (expect_pop) expected = model.pop_front();
if (expect_push) model.push_back(din);
end
#1ps;
assert (dout_valid === expect_pop)
else $fatal(1, "valid mismatch");
if (expect_pop)
assert (dout === expected)
else $fatal(1, "data mismatch");
assert (int'(occupancy) === model.size())
else $fatal(1, "count mismatch");
assert (empty === (model.size() == 0))
else $fatal(1, "empty mismatch");
assert (full === (model.size() == 4))
else $fatal(1, "full mismatch");
end
task automatic step(input bit r, p, o, input word_t d);
@(negedge clk);
rst=r; push=p; pop=o; din=d;
endtask
initial begin
step(0,0,1,0);
step(0,1,1,8'hA0);
for (int i=1; i<4; i++)
step(0,1,0,word_t'(160+i));
step(0,1,0,8'hEE);
step(0,1,1,8'hB0);
repeat (5) step(0,0,1,0);
repeat (3) begin
for (int i=0; i<4; i++) step(0,1,0,word_t'(i));
repeat (4) step(0,0,1,0);
end
step(0,1,0,8'h5A);
step(1,1,1,8'hFF);
step(0,0,1,0);
repeat (100)
step(0,bit'($urandom_range(1,0)),bit'($urandom_range(1,0)),
word_t'($urandom));
repeat (4) step(0,0,1,0);
@(negedge clk);
$display("PASS");
$finish;
end
endmoduleTepi naik pertama rst=1 mengosongkan DUT dan model. === membandingkan ketat termasuk X. Saat valid=0, dout belum diinisialisasi tidak dibandingkan; valid yang X tetap gagal. Empat pop terakhir memeriksa semua data tersisa. PASS adalah pesan setelah eksekusi nyata dengan semua assertion lolos; keberadaan kode bukan bukti eksekusi.
Sebelum menambah B0, simpan head lama A0 sebagai harapan. Yang dibandingkan adalah urutan logis data, bukan pointer atau slot fisik.
- Antrean lama: [A0, A1, A2, A3]
- Nilai harapan pop: Simpan head lama A0
- Terapkan push: [A1, A2, A3, B0]
- Perbandingan respons: Saat valid=1, dout=A0
Memeriksa scoreboard melalui batas
Dengan [A0,A1,A2,A3], push EE saja ditolak karena ukuran 4. Pada permintaan simultan berikutnya, simpan expected=A0 lalu tambahkan B0 menjadi [A1,A2,A3,B0]. Jika DUT langsung mengeluarkan B0, assertion data gagal. Saat kosong, dua permintaan memberi expect_pop=0,expect_push=1: simpan tanpa membandingkan keluaran. Selama reset, abaikan permintaan, kosongkan queue, dan periksa valid=0.
Untuk memori, gunakan array acuan per alamat dan tabel initialized. Pada read-first, simpan harapan sebelum menerapkan penulisan ke memori acuan. Untuk bypass register fileRegister Rangkaian penyimpan beberapa bit keadaan. Register sinkron mata kuliah ini menangkap masukan yang ditentukan pada tepi clock. Selengkapnya, pilih wr_data saat konflik lalu terapkan penulisan ke acuan. Tentukan apakah baca belum diinisialisasi dilarang atau hasilnya tidak terdefinisi; jangan sembarangan menetapkan 0 sebagai jawaban. Memori beralamat memerlukan verifikator tersendiri.
Suntikkan cacat terpisah: keluaran data baru pada pop penuh, count naik saat pertukaran simultan, valid aktif pada pop kosong. Masing-masing harus menggagalkan pemeriksaan terkait. Ini dan cakupan tiap batas mengungkap kekurangan tes. Penempatan RAM dan timing diperiksa melalui sintesis serta analisis timing terpisah.
Coba sendiri
Scoreboard menambah push dahulu lalu memakai ukuran baru untuk mengizinkan pop. Apa kesalahannya saat kosong dengan dua permintaan? Kapan harapan disimpan saat penuh? Nilai juga aturan yang selalu memeriksa dout=0 setelah reset.
Baca penjelasan
Saat kosong, scoreboard keliru menganggap elemen baru langsung boleh di-pop sehingga expect_pop=1. Penerimaan harus memakai ukuran sebelum tepi: hanya push diterima, valid=0. Saat penuh, simpan lalu keluarkan head lama sebelum menambah data baru. Reset tidak mewajibkan dout=0: periksa valid=0 serta queue/occupancy kosong. Bandingkan data jika expect_pop=1 dan valid DUT secara terpisah; tanpa itu, valid yang selalu nol dapat lolos.