ربط المنافذ بالاسم
جزء من قسم الأساسيات في رحلة Verilog على Coddy — الدرس 34 من 90.
في الدرس السابق، تعلمت كيفية إنشاء مثيل لوحدة (instantiate a module) عن طريق تمرير الإشارات بنفس الترتيب الذي تظهر به المنافذ في تعريف الوحدة. هذا يعمل، ولكن لديه مشكلة: الترتيب مهم.
إذا قمت بخلط الترتيب عن طريق الخطأ، فستتصل الإشارات بالمنافذ الخاطئة. قد يكون من الصعب تصحيح هذا الخطأ.
مشكلة التعيين بالترتيب
module or_gate (
input in1,
input in2,
output result
);
assign result = in1 | in2;
endmodule
// التعيين بالترتيب - يجب أن يتطابق الترتيب
or_gate or1 (input_a, input_b, output_y); // صحيح
or_gate or1 (input_b, input_a, output_y); // خطأ! تم تبديل المدخلاتيربط السطر الثاني input_b بـ in1 و input_a بـ in2 — وهو خطأ برمجِي خفي يسهل التغاضي عنه.
الحل: تعيين المنافذ بالاسم
يستخدم تعيين المنافذ بالاسم اسم المنفذ لإجراء الاتصالات. الترتيب لا يهم لأن كل اتصال يتم تسميته بشكل صريح.
الصيغة:
module_name instance_name (
.port_name(signal),
.port_name(signal)
);تشير النقطة . قبل اسم المنفذ إلى أننا نشير إلى منفذ داخل الوحدة (module). الإشارة الموجودة داخل الأقواس هي ما نقوم بتوصيله به.
مثال
or_gate or1 (
.in1(input_a),
.in2(input_b),
.result(output_y)
);هذا يوضح صراحة:
- المنفذ
in1يحصل على الإشارةinput_a - المنفذ
in2يحصل على الإشارةinput_b - المنفذ
resultيحصل على الإشارةoutput_y
الترتيب لا يهم
مع تعيين المنافذ بالاسم (port mapping by name)، يمكنك كتابة التوصيلات بأي ترتيب:
// الثلاثة جميعها متطابقة
or_gate or1 (
.in1(input_a),
.in2(input_b),
.result(output_y)
);
or_gate or1 (
.result(output_y),
.in1(input_a),
.in2(input_b)
);
or_gate or1 (
.in2(input_b),
.result(output_y),
.in1(input_a)
);جميعها تقوم بنفس الشيء تماماً لأن كل توصيلة لها تسمية محددة.
التحدي
أكمل عملية الاستنساخ (instantiation) عن طريق إضافة توصيلات المنافذ المفقودة باستخدام ربط المنافذ بالاسم (port mapping by name).
ما يجب القيام به:
- قم بتوصيل المنفذ
clkبالإشارةclock_signal - قم بتوصيل المنفذ
data_inبالإشارةinput_data - قم بتوصيل المنفذ
data_outبالإشارةoutput_data
ورقة مرجعية
يستخدم تعيين المنافذ بالاسم صيغة .port_name(signal)، مما يجعل الترتيب غير مهم:
module_name instance_name (
.port_name(signal),
.port_name(signal)
);مثال:
or_gate or1 (
.in1(input_a),
.in2(input_b),
.result(output_y)
);تشير النقطة . قبل اسم المنفذ إلى منفذ داخل الوحدة (module)؛ والإشارة الموجودة بين قوسين هي ما يتصل به. وعلى عكس التعيين بالترتيب، يمكن إدراج التوصيلات بأي ترتيب دون التسبب في أخطاء.
جرّب بنفسك
module register (
input clk,
input [7:0] data_in,
output reg [7:0] data_out
);
always @(posedge clk) begin
data_out <= data_in;
end
endmodule
module top (
input clock_signal,
input [7:0] input_data,
output [7:0] output_data
);
register reg1 (
// TODO: أضف تعيينات المنافذ باستخدام صيغة .port(signal)
);
endmoduleيتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس الأساسيات
4المعاملات - الجزء الأول
المعاملات الحسابيةمعامل باقي القسمة (Modulo)معاملات المقارنةملخص - رياضيات بسيطةمعاملات Bitwise7التعيين والبوابات المنطقية
التعيين المستمرالتعيين باستخدام العملياتالبوابات الأساسية المدمجةبوابات AND و OR و NOTبوابات XOR و XNORمراجعة - دارة البوابات المنطقية5المعاملات - الجزء الثاني
المعاملات المنطقيةمعاملات الاختزالمعاملات الإزاحةمعامل الدمجالمعامل الشرطيمراجعة - تحدي المعاملات3أنظمة العد
التمثيل الثنائيالأعداد محددة الحجمالأعداد غير محددة الحجمالأعداد السالبةالقيم الخاصة X و Zمراجعة - تنسيقات الأعداد6الوحدات
هيكل الوحدةمنافذ الإدخال والإخراجمنافذ Inoutاستدعاء الوحداتربط المنافذ بالاسمربط المنافذ بالترتيبمراجعة - بناء وحدة