هـ (لغة التحقق)

e هي لغة التحقق من الأجهزة (HVL) المصممة خصيصًا لتنفيذ منصات اختبار التحقق المرنة والقابلة لإعادة الاستخدام .

تاريخ

طُوِّر البرنامج لأول مرة عام ١٩٩٢ في إسرائيل على يد يواف هولاندر لبرنامجه Specman . وفي عام ١٩٩٥، أسس شركة InSpec (التي أُعيد تسميتها لاحقًا إلى Verisity ) لتسويق البرنامج . عُرض المنتج لأول مرة في مؤتمر أتمتة التصميم عام ١٩٩٦. [ ١ ] استحوذت شركة Cadence Design Systems لاحقًا على Verisity .

سمات

أهم ميزات e هي:

  • توليد المحفزات العشوائية والمقيدة
  • تعريف وجمع مقياس التغطية الوظيفية
  • لغة زمنية يمكن استخدامها لكتابة التأكيدات
  • لغة برمجة موجهة نحو الجوانب مع إمكانية الانعكاس
  • اللغة محايدة فيما يتعلق بـ DUT حيث يمكنك استخدام منصة اختبار واحدة للتحقق من نموذج SystemC/C++، أو نموذج RTL، أو نموذج على مستوى البوابة، أو حتى DUT موجود في صندوق تسريع الأجهزة (باستخدام منهجية تسريع UVM لـ e ).
  • يمكن إنشاء كود قابل لإعادة الاستخدام بدرجة عالية، خاصة عندما تتم كتابة بيئة الاختبار باتباع منهجية التحقق الشاملة (UVM).
    • كانت تُعرف سابقًا باسم منهجية إعادة الاستخدام الإلكتروني ( e RM)
    • يمكن تنزيل مكتبة UVM الإلكترونية والوثائق من هنا: UVM World

ميزات اللغة

تستخدم لغة البرمجة e منهجية البرمجة الموجهة نحو الجوانب (AOP)، وهي امتداد لمنهجية البرمجة الموجهة نحو الكائنات، مصممة خصيصًا لتلبية احتياجات التحقق الوظيفي . تُعدّ AOP ميزة أساسية تُمكّن المستخدمين من إضافة وظائف إضافية بسهولة إلى الشيفرة البرمجية الحالية دون التأثير عليها. وهذا يُسهّل إعادة استخدام الشيفرة وصيانتها، وهو ما يُعدّ ميزةً هائلة في مجال الأجهزة، حيث تُجرى تعديلات مستمرة على التصاميم لتلبية متطلبات السوق طوال دورة حياة المشروع. كما تُعالج AOP أيضًا المشكلات المتداخلة (الميزات التي تتداخل مع أجزاء مختلفة من الشيفرة) بسهولة، من خلال السماح للمستخدمين بتوسيع مثيلات محددة أو جميع مثيلات بنية معينة لإضافة وظائف جديدة. يمكن للمستخدمين توسيع عدة بنى لإضافة وظائف متعلقة بميزة معينة، وتجميع هذه التوسيعات في ملف واحد إذا رغبوا في ذلك، مما يُتيح تنظيمًا أفضل لتقسيم الملفات.

تعليقات

يتم تضمين الكود القابل للتنفيذ e داخل علامات مقطع الكود <' و '>:

مثال

أي شيء خارج العلامات يعتبر تعليقًا <' توسيع النظام { // هذا تعليق بأسلوب فيريلوج هذا تعليق مكتوب بأسلوب VHDL post_generate() هي أيضًا { out("... وكل شيء آخر داخل العلامات هو كود قابل للتنفيذ."); }; }; > 

الصفوف الدراسية

يحتوي أيضًا على نوعين من الفئات:

  • تُصنّف الفئات الديناميكية باستخدام الكلمة المفتاحية 'struct'. تُستخدم الهياكل لإنشاء بيانات موجودة مؤقتًا فقط، ويمكن إزالتها بواسطة جامع البيانات المهملة.
  • تُسمى الفئات الثابتة بالكلمة المفتاحية "unit". تُستخدم الوحدات لإنشاء بنية منصة الاختبار الدائمة.

قد يحتوي الصنف على حقول، ودوال، ومنافذ، وقيود. يمكن أن تكون الحقول من نوع عدد صحيح، أو عدد حقيقي، أو تعداد، أو سلسلة نصية، أو حتى كائنات مركبة. يُظهر مقطع الكود وحدةً تُسمى 'environment_u' يتم إنشاؤها داخل جذر e 'sys'. يحتوي الصنف environment_u على قائمة من 5 كائنات packet_s، ويحتوي الصنف packet_s على حقلين ودالة.

مثال

<' // هذا صنف ديناميكي يحتوي على حقلين struct packet_s { field0: uint (bits: 32); // يُسمى هذا الحقل 'field0' وهو // عدد صحيح غير مُوقّع بعرض 32 بت. field1: byte; // يُطلق على هذا الحقل اسم 'field1' وهو من نوع بايت. // يتم استدعاء هذه الطريقة بمجرد إنشاء كائن packet_s post_generate() هي أيضًا { out(field0); // طباعة قيمة 'field0' }; }; // هذا صنف ثابت يحتوي على قائمة من خمسة هياكل حزم وحدة البيئة_u { my_pkt[5]: قائمة من packet_s؛ }; // sys هو الجذر لكل بيئة e ويقوم بإنشاء كائن 'test_env' توسيع النظام { test_env: environment_u هو مثيل؛ }; > 

التوزيع العشوائي

في هذا الإصدار ، يتم توليد قيم عشوائية لكل حقل افتراضيًا. يمكن التحكم في توليد القيم العشوائية للحقول من خلال قيود صارمة أو قيود مرنة، أو حتى إيقافها تمامًا. تُستخدم القيود المرنة كقيود افتراضية، وقد يتم تجاوزها تلقائيًا بواسطة طبقة الاختبار في حال حدوث تعارض. وإلا، فإنها تعمل كقيد عادي.

مثال

<' struct my_pkt_s { destination_address: uint (bits: 48); // يتم توليد هذا الحقل عشوائيًا وليس له قيود. data_payload : قائمة من البايتات؛ !parity_field : uint (bits: 32); // علامة التعجب '!' تمنع تغيير قيمة حقل التكافؤ عشوائيًا. احتفظ بحجم بيانات الحمولة (data_payload.size()) ضمن النطاق [64..1500]؛ // قيد مرن، يُستخدم لتوفير قيمة عشوائية افتراضية احتفظ بحجم البيانات (data_payload.size()) بحيث لا يكون ضمن النطاق [128..256]؛ // هذا قيد صارم }; > 

التأكيدات

يدعم e التأكيدات باستخدام التعبيرات الزمنية. يُستخدم التعبير الزمني على نفس المستوى النحوي للحقول والأساليب، وبالتالي فهو تصريحي بطبيعته. يصف التعبير الزمني السلوك الزمني.

مثال

<' unit temporal_example_u { event a; // تعريف حدث 'a' الحدث ب؛ // تعريف الحدث 'ب' event c; // تعريف حدث 'c' // يفترض هذا التأكيد أن الدورة التالية بعد الحدث أ تم اكتشاف أن الحدث ب يتبعه الحدث ج. توقع أن يكون @a => {@b;@c} }; > 

التغطية

يدعم النظام تغطية البيانات المصنفة وفقًا للحدث الذي تم أخذ عينة منه، وتُبنى هذه المجموعات داخليًا على عناصر. قد تكون هذه العناصر بسيطة أو معقدة، مثل العناصر المتقاطعة أو العناصر الانتقالية.

مثال

تغطية الوحدة_مثال_u { event cov_event_e; // سيتم ربط جمع بيانات التغطية بهذا الحدث cover cov_event_e is { العنصر أ: عدد صحيح غير موجب (بتات: 4)؛ // يحتوي هذا العنصر على 16 خانة من 0 إلى 15 العنصر ب: منطقي؛ // يحتوي هذا العنصر على خانتين: صحيح وخطأ الضرب التبادلي a، b؛ // يحتوي هذا العنصر على مصفوفة الضرب التبادلي لـ a و b trans b; // هذا العنصر مشتق من العنصر b ويحتوي على أربعة أقسام // الانتقال بين كل تركيبة صحيحة - خاطئة }; }; 

المراسلة والتقارير

يمكن إجراء المراسلة داخل e باستخدام طرق متنوعة.

مثال

وحدة رسالة_مثال_u { example_message_method() is { out("هذه رسالة إخراج غير مشروطة وغير منسقة."); outf("هذه رسالة إخراج منسقة وغير مشروطة معروضة بنظام HEX %x",15); اطبع "هذه رسالة غير مشروطة."؛ رسالة (منخفضة، "هذه رسالة مشروطة، وعادة ما تكون مرتبطة بمسجل الرسائل. ", يمكنك أيضًا دمج السلاسل النصية بهذه الطريقة، بل وإضافة كائنات مثل "،أنا، "في هذا الناتج." ); messagef( LOW, "تم تنسيق هذا الإخراج الشرطي %x.",15 ); }; }; 

التفاعل مع اللغات الأخرى

من المرجح أن يتم تشغيل بيئة اختبار e باستخدام نماذج RTL أو نماذج ذات مستوى أعلى. مع الأخذ في الاعتبار ذلك، فإن e قادر على التفاعل مع VHDL و Verilog و C و C++ و SystemVerilog .

مثال على ربط e <-> Verilog

// هذا الكود موجود في ملف Verilog tb_top.v module testbench_top ; reg a_clk ; always # 5 a_clk = ~ a_clk ; initial begin a_clk = 0 ; end endmodule
هذا الكود موجود في ملف signal_map.e <' وحدة إشارة_خريطة_u { // تعريف منفذ باسم 'a_clk_p' a_clk_p: في منفذ بسيط من البت هو مثيل؛ // اضبط خاصية hdl_path الخاصة بالمنفذ لتشير إلى إشارة 'a_clk' في بيئة الاختبار الرئيسية احتفظ بمسار ملف تعريف المعرف a_clk_p.hdl_path() == "~/testbench_top/a_clk"; }; > 

دعم البرمجة الموجهة نحو الجوانب في e

تتطلب عملية التحقق الوظيفي رفع مستوى تجريد أي تصميم قيد الاختبار (DUT) إلى ما يتجاوز مستوى RTL. هذه الضرورة تستدعي لغة قادرة على تغليف البيانات والنماذج، وهو ما يتوفر بسهولة في لغات البرمجة كائنية التوجه. ولتلبية هذه الحاجة، صُممت لغة e لتكون لغة كائنية التوجه، بالإضافة إلى تعزيزها بآليات موجهة نحو الجوانب، مما يُسهل كتابة بيئات اختبار مرنة وقابلة لإعادة الاستخدام، كما يُساعد مهندسي التحقق من خلال تمكينهم من إصلاح أخطاء RTL المكتشفة دون الحاجة إلى إعادة كتابة أو تعديل أي جزء من قاعدة التعليمات البرمجية الموجودة. تسمح البرمجة الموجهة نحو الجوانب في e لمهندسي التحقق بتنظيم بيئة الاختبار الخاصة بهم في جوانب. وبالتالي، فإن الكائن هو مجموع جميع جوانبه، والتي قد تكون موزعة على ملفات متعددة. توضح الأقسام التالية الآليات الأساسية الموجهة نحو الجوانب في e.

آلية التصنيف الفرعي

يُعدّ التوريث مثالًا بارزًا لما تعجز عنه لغات البرمجة الكائنية التوجه التي تفتقر إلى ميزات البرمجة الموجهة نحو الجوانب. يسمح التوريث لمهندس التحقق بإضافة وظائف إلى فئة مُعرّفة/مُنفّذة مسبقًا دون الحاجة إلى الاشتقاق من فئة أساسية. يُبيّن الكود التالي التنفيذ الأصلي لفئة أساسية وكيفية توسيعها. بمجرد إجراء التوسيع، تحتوي جميع كائنات الفئة الأساسية على هذه التوسيعات أيضًا. عادةً ما تُسبب القيود المُعطاة في النوعين الفرعيين المختلفين تناقضًا، إلا أنه يتم التعامل مع كل نوع فرعي على حدة، وبالتالي يُنتج كل نوع فرعي حسابًا مختلفًا للقيود.

مثال على آلية التصنيف الفرعي

subtyping_example.e <' // يُستخدم تعريف نوع التعداد هذا للإعلان عن النوعين الفرعيين ODD و EVEN نوع ctrl_field_type_t: [فردي، زوجي]؛ وحدة base_ex_u { // حقل النوع الفرعي هو حقل المحدد الذي يتم تطبيق الحساب عليه subtype_field: ctrl_field_type_t; data_word : uint (bits: 32); بت التكافؤ: بت؛ // تحديد النوع الفرعي للنوع الفردي عندما يكون حقل النوع الفرعي ODD هو base_ex_u { // هذا قيد بسيط يقوم بعملية XOR بين بت الفهرس 0 من كلمة البيانات ويزيد تلك القيمة keep parity_bit == (data_word[0:0] ^ data_word[0:0] + 1); }; // تحديد النوع الفرعي EVEN عندما يكون حقل النوع الفرعي EVEN هو base_ex_u { // هذا القيد هو نفسه القيد أعلاه، ولكن الزيادة لا تتم. احتفظ بـ parity_bit == (data_word[0:0] ^ data_word[0:0]); }; }; > 

أساليب التوسيع

يُعطى تعريف الوحدة الأصلي في الملف file1.e. توضح الآلية الموجهة نحو الجوانب المستخدمة في هذا المثال كيفية تنفيذ التعليمات البرمجية قبل وبعد طريقة تم تنفيذها بالفعل.

مثال على توسيع الأسلوب

هذا الكود موجود في الملف file1.e <' وحدة aop_example_u { meth_ext() هي { out("هذا هو التنفيذ الأصلي للطريقة."); }; }; > 
هذا الكود موجود في الملف 2.e <' امتداد aop_example_u { meth_ext() هي الأولى { out("يتم تنفيذ امتداد هذه الطريقة قبل تنفيذ الطريقة الأصلية."); }; meth_ext() هي أيضًا { out("يتم تنفيذ امتداد هذه الطريقة بعد تنفيذ الطريقة الأصلية."); }; }; > 

مراجع

  1. سمير بالنيتكار: التحقق من التصميم باستخدام e ، برنتيس هول بي تي آر. 5 أكتوبر 2003. ISBN 978-0-13-141309-2

مصادر