كتلة Always
جزء من قسم الأساسيات في رحلة Verilog على Coddy — الدرس 46 من 90.
الـ procedural block هو كتلة من الكود حيث تُنفذ البيانات واحدة تلو الأخرى، بالتتابع — تمامًا كما في لغات البرمجة المكتوبة مثل C أو Python. تحتوي Verilog على اثنين من الـ procedural blocks: initial (يعمل مرة واحدة) و always (يعمل بشكل مستمر). لنبدأ بـ always block.
يعمل الكتلة always بشكل مستمر — حيث يتكرر إلى الأبد بمجرد بدء المحاكاة. يُستخدم لوصف العتاد (hardware) الذي يحتاج إلى الاستمرار في التشغيل، مثل القلابات (flip-flops)، العدادات (counters)، والمنطق التجميعي (combinational logic).
الصياغة الأساسية:
always @(sensitivity_list) begin
// الكود الذي يعمل بشكل متكرر
endتحدد @(sensitivity_list) للكتلة متى يتم التنفيذ. بدونها (ومع عدم وجود تأخير مثل #5 بالداخل)، ستتكرر الكتلة إلى اللانهائية وتتسبب في تعليق المحاكاة.
مثال على block الـ always: Counter
فيما يلي مثال على كيفية استخدام block الـ always لإنشاء counter.
module counter (
input clk,
output reg [3:0] count
);
always @(posedge clk) count <= count + 1;
endmoduleكيف يعمل هذا الكود
| الجزئية | المعنى |
|---|---|
always | قم بتشغيل هذا الكود بشكل مكرر، إلى الأبد |
@(posedge clk) | انتظر حتى ينتقل الكلوك من 0 إلى 1 (الحافة الصاعدة) |
count <= count + 1 | خذ القيمة الحالية لـ count، وأضف إليها 1، ثم أعد خزنها |
تُنفَّذ الـ block عند كل rising edge لـ clock. في كل مرة، يزداد count بمقدار 1.
تُخبر قائمة الحساسية (sensitivity list) @(posedge clk) الدالة بالتنفيذ فقط عند حواف الإشارة المرجعية (clock edges)، وليس بشكل مستمر. وبدون ذلك، ستعمل الحلقة إلى الأبد دون أي تأخير.
Always Block مع إشارات متعددة
يمكنك إدراج إشارات محددة:
always @(a or b) begin
out = a & b;
endيعمل هذا عندما يتغير a أو b.
التحدي
أضف كتلة always المفقودة لجعل هذه وحدة module تعمل.
كيف تعمل:
- عند كل حافة صاعدة لـ
clock، يتم تبديل قيمةout1(تتغير) من 0 إلى 1 أو من 1 إلى 0 - يتبع
out2القيمة الخاصة بـout1(نفس قيمةout1)
ما يجب فعله:
- أضف كتلة
always @(posedge clk) - في الداخل، اجعل
out1يتبدل (استخدمout1 = ~out1) - اجعل
out2مساوياً لـout1
جرّب بنفسك
module toggler (
input clk,
output reg out1,
output reg out2
);
initial begin
out1 = 0;
out2 = 0;
end
// TODO: أضف always block مع posedge clk
// out1 يتبدل مع كل clock
// out2 يتبع out1
endmoduleيتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.
جميع دروس الأساسيات
4المعاملات - الجزء الأول
المعاملات الحسابيةمعامل باقي القسمة (Modulo)معاملات المقارنةملخص - رياضيات بسيطةمعاملات Bitwise7التعيين والبوابات المنطقية
التعيين المستمرالتعيين باستخدام العملياتالبوابات الأساسية المدمجةبوابات AND و OR و NOTبوابات XOR و XNORمراجعة - دارة البوابات المنطقية5المعاملات - الجزء الثاني
المعاملات المنطقيةمعاملات الاختزالمعاملات الإزاحةمعامل الدمجالمعامل الشرطيمراجعة - تحدي المعاملات3أنظمة العد
التمثيل الثنائيالأعداد محددة الحجمالأعداد غير محددة الحجمالأعداد السالبةالقيم الخاصة X و Zمراجعة - تنسيقات الأعداد6الوحدات
هيكل الوحدةمنافذ الإدخال والإخراجمنافذ Inoutاستدعاء الوحداتربط المنافذ بالاسمربط المنافذ بالترتيبمراجعة - بناء وحدة9الكتل الإجرائية
كتلة Alwaysكتلة Initialقائمة التحسسالإسناد الحاجبالإسناد غير الحاجبمراجعة - Always مقابل Initial