Altifigence Academy

24 / 37 · प्रयोग

अभ्यास: अपनी त्रुटि बताने वाली टेस्टबेंच

DUT, उत्तेजना, संदर्भ और जाँच अलग करके reset, enable और वापसी बिना रेस जाँचें।

कार्यान्वयन और जाँचकर्ता अलग रखें

टेस्टबेंच उत्तेजना देती है, अपेक्षा निकालती है और अंतर बताती है। यह सिमुलेशन कोड है, संश्लेषण का परिपथ नहीं। पैरामीटर पाठ का modulo_tick, modulo_tick.sv में और यह पूरा बेंच tb.sv में रखें। सिंक्रोनस रीसेट जीतता है; enable न हो तो count रहता है और pulse साफ होता है; enable पर modulo N वृद्धि और केवल वापसी पर pulse=1 होता है। भीतर की अवस्था पढ़ने के बजाय पूर्णांक संदर्भ लें।

SystemVerilog
`timescale 1ns/1ps
module tb #(parameter integer N = 5);
  localparam integer CW = (N <= 1) ? 1 : $clog2(N);
  logic clk = 1'b0;
  logic rst = 1'b0;
  logic enable = 1'b0;
  wire [CW-1:0] count;
  wire pulse;
  integer expected_count = 0;
  logic expected_pulse = 1'b0;
  integer checks = 0;
  modulo_tick #(.N(N)) dut (
    .clk(clk), .rst(rst), .enable(enable),
    .count(count), .pulse(pulse)
  );
  always #5 clk = ~clk;

  task automatic step(input logic reset_value, enable_value);
    begin
      @(negedge clk);
      rst = reset_value;
      enable = enable_value;
      if (reset_value) begin
        expected_count = 0;
        expected_pulse = 1'b0;
      end else begin
        expected_pulse = 1'b0;
        if (enable_value) begin
          expected_count = expected_count + 1;
          if (expected_count == N) begin
            expected_count = 0;
            expected_pulse = 1'b1;
          end
        end
      end
      @(posedge clk);
      #1;
      if (count !== CW'(expected_count) || pulse !== expected_pulse)
        $fatal(1, "Mismatch check=%0d count=%0d expected=%0d pulse=%b expected=%b",
          checks, count, expected_count, pulse, expected_pulse);
      checks = checks + 1;
    end
  endtask

  initial begin
    if (N < 1) $fatal(1, "N must be positive");
    step(1'b1, 1'b1);
    repeat (N-1) step(1'b0, 1'b1);
    step(1'b0, 1'b0);
    step(1'b0, 1'b1);
    step(1'b0, 1'b0);
    repeat (2*N+1) step(1'b0, 1'b1);
    step(1'b1, 1'b1);
    step(1'b0, 1'b0);
    $display("PASS N=%0d checks=%0d", N, checks);
    $finish;
  end
  initial begin
    #10000;
    $fatal(1, "Timeout");
  end
endmodule

सक्रिय किनारे की रेस से बचें

Task गिरते किनारे पर इनपुट बदलती है, कैप्चर से आधा चक्र पहले, और बढ़ते किनारे के नॉनब्लॉकिंग अपडेट बाद तुलना करती है। #1, timescale और 10ns क्लॉक वाला शिक्षण अवलोकन विलंब है, भौतिक clock-to-Q, setup या hold विश्लेषण नहीं। पुनः उपयोग वाली व्यवस्था clocking blocks या event-region अनुशासन ले सकती है। पहला रीसेट DUT ज्ञात करता है; संदर्भ शुरू करना DUT शुरू नहीं करता। !== ज्ञात अपेक्षा के सामने X/Z पकड़ता है।

स्पष्ट top से कम्पाइल करें

Icarus लगी shell में:

text
iverilog -g2012 -s tb -o sim.vvp modulo_tick.sv tb.sv
vvp sim.vvp

-P tb.N=1,-P tb.N=2,-P tb.N=5,-P tb.N=8 के साथ अलग कम्पाइल करें। Icarus के आधिकारिक दस्तावेज़ भाषा और top बताते हैं। इस्तेमाल किया संस्करण लिखें, क्योंकि SystemVerilog समर्थन बदलता है।

जानबूझकर विफल करें

तुलना बदलकर एक किनारा जल्दी वापस लाएँ या pulse साफ करने का डिफ़ॉल्ट हटाएँ। कोई परिदृश्य timeout से पहले गैर-शून्य status से विफल होना चाहिए। फिर सही स्रोत लौटाएँ। संबंधित mutation न पकड़ने वाला PASS कमजोर प्रमाण है। Hash, N, कमांड, status, PASS और पहला अंतर लिखें। स्थानीय टेस्ट को DDS निष्पादन न कहें: सामान्य टेस्टबेंच के #delay और initial सीमित एक-क्लॉक लैब इंटरफ़ेस के बराबर नहीं।

आपका चयन इस ब्राउज़र पर लागू होता है। फ़ुटर से कभी भी बदलें।