EDA Playground'da Dene

Final Testbench

Gün 7: Bitirme Projesi - Bölüm 2 | Tüm bileşenleri bir araya getiren son testbench

Testbench Top (en üst modül), tüm projeyi bir araya getiren statik modüldür. ALU mimarimizin "ana sahnesidir": saat üretir, interface ve DUT'u somutlaştırır, bunları bağlar ve komut satırından seçilen testi başlatır.

Testbench Top ve Mimarideki Yeri

Top, hiyerarşinin en tepesinde yer alır ve sınıf tabanlı doğrulama dünyası ile statik donanım dünyasını birleştirir. Görevleri:

  • Dosyaları dahil etmek: Tüm bileşen sınıflarını `include ile derlemeye dahil eder.
  • Saat üretmek: always #5 clk = ~clk ile 100 MHz'lik saat sağlar.
  • Bağlamak: alu_if aif(clk) interface'ini ve alu dut(...) modülünü oluşturup pinleri arayüze bağlar.
  • Test seçmek: $value$plusargs ile komut satırından (+TEST=...) hangi senaryonun koşacağını belirler.

Komut Satırından Test Seçimi

+TEST=Random_Test veya +TEST=Corner_Test argümanı, simülatöre hangi test sınıfının örnekleneceğini söyler. Bu, polymorphism'in son halkasıdır: ALU_Base_Test test handle'ı türetilmiş bir nesneye (ALU_Random_Test veya ALU_Corner_Test) işaret eder ve test.run() doğru senaryoyu çalıştırır.

Dalga Formu (Waveform) Kaydı

$dumpfile/$dumpvars ile tüm hiyerarşi bir VCD dosyasına kaydedilir; hata ayıklarken sinyalleri görsel olarak incelemeyi sağlar.

Kaynak Kod

// =============================================================================
// GUN 7 KONU 6: Final Testbench Top-Level
// =============================================================================
// =============================================================================

`include "6_2_transaction.sv"
`include "7_5_coverage.sv"
`include "6_3_generator.sv"
`include "6_4_driver.sv"
`include "7_1_monitor.sv"
`include "7_2_scoreboard.sv"
`include "7_3_environment.sv"
`include "7_4_test.sv"
`include "alu_if.sv"

module tb_top_final;

  // Clock generation
  logic clk = 0;
  always #5 clk = ~clk;  // 100MHz (period = 10ns)

  // Interface
  alu_if aif(clk);

  // DUT (Design Under Test)
  alu dut (
    .clk       (aif.clk),
    .rst_n     (aif.rst_n),
    .in_valid  (aif.in_valid),
    .operand_a (aif.operand_a),
    .operand_b (aif.operand_b),
    .opcode    (aif.opcode),
    .out_valid (aif.out_valid),
    .result    (aif.result),
    .flags     (aif.flags)
  );

  // Test selection
  initial begin
    ALU_Base_Test test;
    
    // Declare handles for derived classes
    ALU_Random_Test rand_test;
    ALU_Corner_Test corner_test;
    
    string test_name;

    // Test selection from command line: +TEST=Random_Test
    if (!$value$plusargs("TEST=%s", test_name))
      test_name = "Random_Test";  // Default

    $display("============================================================");
    $display("  ALU VERIFICATION PROJECT - FINAL");
    $display("  Selected Test: %s", test_name);
    $display("============================================================");

    case (test_name)
      "Random_Test": begin
        rand_test = new(aif, aif);
        test = rand_test;
      end
      "Corner_Test": begin
        corner_test = new(aif, aif);
        test = corner_test;
      end
      default: begin
        $display("  Unknown test: %s, Random_Test is being used", test_name);
        rand_test = new(aif, aif);
        test = rand_test;
      end
    endcase

    test.run();

    $display("\n============================================================");
    $display("  SIMULATION COMPLETED");
    $display("============================================================");
    $finish;
  end

  // VCD waveform
  initial begin
    $dumpfile("alu_tb_final.vcd");
    $dumpvars(0, tb_top_final);
  end

endmodule

Kodun Açıklaması

  • **`include direktifleri**: Transaction, coverage, generator, driver, monitor, scoreboard, environment, test ve interface dosyaları derlemeye dahil edilir. Sıralama önemlidir; bir sınıf, kullandığı diğer sınıflardan önce derlenmiş olmalıdır (örneğin coverage, scoreboard'dan önce gelir).
  • Saat üreteci: logic clk = 0; ile başlatılır, always #5 clk = ~clk; her 5 ns'de tersine döner, böylece 10 ns periyot (100 MHz) oluşur.
  • alu_if aif(clk): Interface, üretilen saatle somutlaştırılır.
  • alu dut (...): DUT, tüm pinleri aif arayüzünün ilgili sinyallerine bağlanarak örneklenir.
  • Test seçimi: $value$plusargs("TEST=%s", test_name) komut satırı argümanını okur; yoksa varsayılan "Random_Test" kullanılır. case bloğunda Random_TestALU_Random_Test, Corner_TestALU_Corner_Test örneklenir ve ALU_Base_Test test handle'ına atanır. Bilinmeyen isimde varsayılana düşülür.
  • test.run(): Seçilen testin sanal run() metodu çağrılır; tüm doğrulama akışı buradan başlar. Bitince $finish ile simülasyon sonlandırılır.
  • VCD: $dumpfile("alu_tb_final.vcd") ve $dumpvars(0, tb_top_final) ile tüm hiyerarşi dalga formuna kaydedilir.

Önemli Noktalar

  • `include sırası derleme bağımlılıklarını yansıtmalıdır; yanlış sıra "tanımlanmamış tip" hatalarına yol açar.
  • Test handle'ının taban tip (ALU_Base_Test) olması ve türetilmiş nesneye atanması, çalışma zamanı çok biçimliliğinin (polymorphism) tüm sistemi sürdüğü noktadır.
  • +TEST= argümanı, tek bir derlemeyle farklı senaryoları koşmayı sağlar; regresyon (regression) otomasyonu için idealdir.
  • Saat üreteci interface dışında, top'ta tutulur ve interface'e parametre olarak geçirilir; bu, tek bir saat kaynağının tüm tasarımı beslemesini garanti eder.
  • $dumpvars(0, tb_top_final) sıfır seviyesiyle tüm alt hiyerarşiyi kaydeder; büyük tasarımlarda dosya boyutu için kapsamı daraltmak gerekebilir.