Menu
flag Ar iconالعربيةdown icon

$display و$monitor في Verilog: الطباعة من testbench

كيف تعمل $display و$write و$monitor - مُحدّدات التنسيق التي ستستخدمها، الفرق بينها، ومتى تكون كل واحدة هي الأداة الصحيحة.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

عائلة C printf في Verilog

ثلاث مهام نظام تتيح لك الطباعة إلى stdout للمحاكي:

  • $display - تطبع مرة، تُلحق سطرًا جديدًا.
  • $write - تطبع مرة، بلا سطر جديد.
  • $monitor - تطبع تلقائيًا في كل مرة تتغير فيها إشارة مُراقبة.

كل الثلاث تأخذ سلسلة تنسيق وقائمة حجج، مثل printf تمامًا. محددات التنسيق مشابهة لكنها خاصة بـ Verilog.

$display: الافتراضي

$display هو حصان العمل:

سترى شيئًا مثل:

Hello, world.
byte_val  = ab
byte_val  = 10101011
byte_val  = 171
byte_val  = 171 (no padding)
multi: nibble=1010 count=42

ملاحظات:

  • %d يحشو إلى عرض افتراضي مبني على حجم المعامل. لـ reg 8 بت، هذا 3 أحرف (مكان لـ 255). المسافات البادئة قد تبدو قبيحة في الخرج الجدولي - استخدم %0d لقمعها.
  • %h و%b و%o لها حشو مشابه افتراضيًا. معظم شيفرة testbench تستخدم متغيرات %0 عندما لا تكون المحاذاة مفيدة.
  • السطر الجديد في النهاية تلقائي. لا تضع \n في نهاية سلسلة تنسيق $display - ستحصل على سطر فارغ.

محددات التنسيق

المجموعة التي يدعمها Verilog:

المحددالمعنى
%bثنائي
%dعشري (signed إن كانت الإشارة signed)
%h أو %xست عشري
%oثُماني
%cحرف ASCII واحد (البتات 8 السفلى)
%sسلسلة
%tزمن المحاكاة
%mالاسم الهرمي للنطاق الحالي
%%% حرفي
%0Xبلا حشو بادئ، لأي من %b، %d، إلخ.

%b و%d و%h و%o هي الأربعة التي ستستخدمها 95% من الوقت. %t هو الأكثر شيوعًا بعد ذلك - أي وقت تريد سطر سجل مختوم بالزمن.

$write: بلا سطر جديد

$write مطابقة لـ $display باستثناء أنها لا تُلحق سطرًا جديدًا:

الخرج:

abc
done

مفيد لبناء سطر واحد من جسم حلقة:

$write("[");
for (integer i = 0; i < 8; i = i + 1) $write("%h ", arr[i]);
$display("]");

$monitor: طباعة تلقائية عند التغيير

$monitor تسجّل قائمة مراقبة. يُعيد المحاكي التقييم ويطبع كلما تغيّرت أي إشارة مذكورة في سلسلة التنسيق:

سترى ثلاثة أسطر، واحد لكل تغيير في المدخلات. لا حاجة لاستدعاء $display يدويًا بعد كل تغيير تحفيز - $monitor يفعل ذلك.

قيدان:

  • يمكن أن يكون $monitor واحد نشطًا. استدعاؤها مرة أخرى يستبدل قائمة المراقبة السابقة. استخدم $monitoroff و$monitoron لتعطيل وإعادة تفعيل مؤقت.
  • التغييرات داخل نفس الخطوة الزمنية تنهار إلى طباعة واحدة. إن تغيّر a وb كلاهما عند الزمن 5، يُطلق المراقب مرة بكلا القيمتين الجديدتين، لا مرتين.

متى تستخدم كل واحدة

  • $display: معظم خرج testbench. استدعِها صراحةً بعد التحفيز، بعد انتقالات الحالة المهمة، أو داخل كتلة always @(posedge clk) للأخذ بالعينات.
  • $write: عندما تريد بناء سطر واحد من حلقة أو عدة قطع صغيرة.
  • $monitor: عندما تريد تتبّع مجموعة صغيرة من الإشارات باستمرار ورؤية الخرج فقط عندما تتغير. مفيد للتنقيح الأولي؛ أصعب للاستخدام في سكربتات regression لأن الخرج غير حتمي بعدد الأسطر الإجمالي.

لمعظم سير العمل، $display تغطي كل شيء. ألجأ إلى $monitor فقط عندما يكون الخرج المستمر مدفوعًا بالتغيير هو ما تريد فعلًا.

العمل مع الزمن

$time تُرجع زمن المحاكاة الحالي كعدد صحيح 64 بت. اقرنها مع %0t:

$display("at %0t: signal flipped", $time);

الخرج يبدو مثل at 25: signal flipped (الوحدة تعتمد على timescale لديك).

إن احتجت دقة sub-tick (نادر)، استخدم $realtime بدلًا من ذلك - يُرجع real.

%t يُنسّق الزمن تلقائيًا بعرض افتراضي يختاره المحاكي. %0t يجرّد الحشو.

أخذ العينات على حافة Clock

اصطلاح نظيف لمراقبة التصاميم التسلسلية: كتلة always @(posedge clk) منفصلة تطبع مرة لكل دورة:

نمط أخذ العينات هذا يضمن سطر سجل واحد لكل clock - مثالي لاختبارات regression التي تطابق نمطًا على الخرج.

التسجيل إلى ملف

افتح ملفًا بـ $fopen، سجّل بـ $fdisplay (الذي يعمل مثل $display لكنه يكتب إلى file handle):

integer fd;
initial begin
    fd = $fopen("results.txt", "w");
    $fdisplay(fd, "test=%s status=%s", test_name, status);
    $fclose(fd);
end

$fopen يُرجع handle 32 بت؛ مرّره كأول حجة لـ $fdisplay و$fwrite و$fstrobe وهكذا. الدوال متطابقة فيما عدا ذلك مع أشقائها الطابعين للـ console.

ماذا بعد

$display وأخواتها يعطيانك سجلات نصية. للتنقيح البصري - مراقبة الإشارات كجهد عبر الزمن - تريد VCD waveform. المستند التالي، Dumpfile وVCD، يغطي $dumpfile و$dumpvars، الاستدعاءان اللذان يحوّلان محاكاتك إلى waveform رسومي يمكنك التمرير خلاله.

الأسئلة الشائعة

ما الفرق بين $display و$monitor في Verilog؟

$display تطبع مرة، فورًا، عند تنفيذها - مثل printf في C. $monitor تسجّل قائمة مراقبة؛ كلما تغيّرت أي إشارة في القائمة، تُطبع الرسالة المُنسّقة تلقائيًا. يمكن أن يكون $monitor واحد نشطًا في كل مرة؛ استدعاؤها مرة أخرى يستبدل قائمة المراقبة السابقة.

ما محددات التنسيق التي يدعمها Verilog $display؟

الشائعة: %b (ثنائي)، %d (عشري)، %h (ست عشري)، %o (ثُماني)، %c (حرف واحد من البايت السفلى)، %s (سلسلة)، %t (زمن المحاكاة)، %m (الاسم الهرمي للنسخة). استخدم شكل %0d لإسقاط حشو الأصفار البادئة - %d يحشو إلى عرض افتراضي، %0d ينتج بلا حشو.

ما هي $write في Verilog؟

$write مثل $display لكنها لا تُلحق سطرًا جديدًا. مفيدة عندما تريد بناء سطر خرج من عدة استدعاءات. $display نهاية السطر (بلا حجج أو بسطر جديد لاحق) ينهي السطر.

كيف أطبع زمن المحاكاة في Verilog؟

استخدم $time (أو $realtime لدقة sub-tick) مع محدد تنسيق %t: $display("at time %t: ...", $time);. استخدم %0t لقمع الحشو الافتراضي. لعدّاد عدد صحيح عادي من وحدات الزمن، %0d مع $time يعمل أيضًا: $display("t=%0d", $time);.

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن