ورقة Verilog المرجعية
آخر تحديث
بنية الوحدة والمنافذ
الوحدة هي اللبنة الأساسية - لها اسم وقائمة منافذ.
| الصياغة | المعنى |
|---|---|
module adder(...); ... endmodule | تعريف وحدة وجسمها |
input clk; | منفذ إدخال |
output q; | منفذ إخراج |
output reg q; | إخراج يُغذّى من كتلة always |
input [7:0] data; | ناقل إدخال 8-بت (متّجه) |
inout sda; | منفذ ثنائي الاتجاه |
adder u1 (.a(x), .b(y), .sum(s)); | إنشاء نسخة من وحدة بمنافذ مسمّاة |
أنواع البيانات
wire ينمذج اتصالًا؛ و reg يحمل قيمة يسندها الكود الإجرائي.
| العنصر | وظيفته |
|---|---|
wire w; | شبكة (net) تُقاد بـ assign أو بإخراج وحدة |
reg r; | يحمل قيمة مُسندة داخل كتلة always/initial |
wire [3:0] bus; | متّجه 4-بت (البتات من 3 نزولًا إلى 0) |
reg [7:0] count; | سجلّ 8-بت |
bus[2] | تحديد بت واحد |
bus[3:1] | تحديد شريحة من البتات (part-select) |
reg mem [0:255]; | ذاكرة: مصفوفة من السجلّات |
parameter WIDTH = 8; | ثابت مسمّى للوحدة |
حرفيات الأرقام
الصيغة هي <size>'<base><value> - الحجم بالبتات، والقاعدة b/o/d/h.
| الصياغة | المعنى |
|---|---|
4'b1010 | ثنائي 4-بت، القيمة 10 |
8'hFF | ست عشري 8-بت، القيمة 255 |
8'hff | المثل - أرقام الست عشري لا تميّز حالة الأحرف |
16'd255 | عشري 16-بت، القيمة 255 |
3'o7 | ثماني 3-بت، القيمة 7 |
8'b1010_1100 | الشرطات السفلية تجمّع الأرقام لسهولة القراءة |
1'bx | قيمة بت غير معروفة (x) |
1'bz | قيمة بت عالية الممانعة (z) |
العوامل
عوامل ثنائية ومنطقية ومقارنة واختزال.
| العامل | وظيفته |
|---|---|
& | ^ ~ | ثنائي: AND و OR و XOR و NOT |
&& || ! | منطقي: AND و OR و NOT (تُرجع بتًا واحدًا) |
== != < > <= >= | عوامل المقارنة |
<< >> | الإزاحة لليسار ولليمين |
+ - * / % | العوامل الحسابية |
&bus | اختزال AND (AND لكل البتات) |
|bus | اختزال OR (OR لكل البتات) |
^bus | اختزال XOR (تماثل كل البتات) |
{a, b} | الدمج (concatenation)؛ {4{1'b1}} يكرّر إلى 4'b1111 |
الإسناد المستمر
assign يقود wire باستمرار - استخدمه للمنطق التوافقي.
| الصياغة | المعنى |
|---|---|
assign y = a & b; | قُد y بنتيجة AND لـ a و b |
assign sum = a + b; | احسب مجموعًا باستمرار |
assign y = sel ? a : b; | الشرطي الثلاثي - مالتيبلكسر 2-إلى-1 |
assign {c, s} = a + b; | التقاط الحمل والمجموع معًا |
assign y = ~en; | قُد سلكًا من إشارة معكوسة |
الكتل الإجرائية
always و initial تُشغّلان العبارات؛ وقائمة الحساسية تتحكم في الزمن.
| الصياغة | المعنى |
|---|---|
always @(*) begin ... end | منطق توافقي (عند أيّ تغيّر في الإدخال) |
always @(posedge clk) | يعمل عند كل حافة ساعة صاعدة (تتابعي) |
always @(negedge clk) | يعمل عند كل حافة ساعة هابطة |
always @(posedge clk or posedge rst) | كتلة مزامَنة بإعادة تعيين غير متزامنة |
initial begin ... end | يعمل مرة واحدة عند الزمن 0 (للاختبار والمحاكاة فقط) |
begin ... end | تجميع عدة عبارات |
#10 | تأخير 10 وحدات زمنية (محاكاة فقط) |
الحاجب مقابل غير الحاجب
استخدم = للمنطق التوافقي، و <= للمنطق التتابعي المزامَن.
| الصياغة | المعنى |
|---|---|
a = b; | حاجب - يُنفَّذ بالترتيب وفورًا |
a <= b; | غير حاجب - تُقرأ كل الأطراف اليمنى أولًا ثم تُسنَد |
always @(*) y = a & b; | توافقي: استخدم الحاجب = |
always @(posedge clk) q <= d; | قلّاب (flip-flop): استخدم غير الحاجب <= |
مزج = و <= في كتلة واحدة | تجنّبه - مصدر شائع للأخطاء |
التحكم في التدفق
الشروط والتفرّعات متعددة المسارات داخل الكتل الإجرائية.
| الصياغة | المعنى |
|---|---|
if (cond) ... else ... | عبارة شرطية |
if (a) x = 1; else x = 0; | if/else على سطر واحد |
case (sel) ... endcase | تفرّع متعدد المسارات على قيمة |
2'b00: y = a; | بند case |
default: y = 0; | بند case احتياطي |
for (i = 0; i < 8; i = i + 1) | حلقة (غالبًا داخل generate أو المحاكاة) |
repeat (4) @(posedge clk); | تكرار عبارة N مرة |
الأنماط الشائعة
لبنات تكتبها مرارًا وتكرارًا، بالإضافة إلى مهام الاختبار (testbench).
| النمط | الصياغة |
|---|---|
| قلّاب D | always @(posedge clk) q <= d; |
| سجلّ مع إعادة تعيين | always @(posedge clk) if (rst) q <= 0; else q <= d; |
| عدّاد | always @(posedge clk) count <= count + 1; |
| سجلّ حالة FSM | always @(posedge clk) state <= next_state; |
| منطق الحالة التالية لـ FSM | always @(*) case (state) ... endcase |
| طباعة قيمة | $display("q = %b", q); |
| الطباعة عند التغيّر | $monitor("t=%0t q=%b", $time, q); |
| إنهاء المحاكاة | $finish; |
كل جزء من صياغة Verilog قد تحتاجه، على صفحة واحدة. ورقة Verilog المرجعية هذه هي مرجع سريع للغة وصف العتاد - تعريف الوحدات والمنافذ، واختيار أنواع البيانات، وكتابة المنطق التوافقي والتتابعي، وأنماط كتلة always التي تصف الدوائر الحقيقية.
الصياغة هنا هي Verilog قياسية (IEEE 1364) وتعمل في المحاكيات الشائعة مثل Icarus Verilog و Verilator. انسخ ما تحتاجه، أو جرّبه مباشرة في playground الخاص بـ Verilog - اكتب وحدة، وحاكِها، وشاهد المخرجات في متصفحك.
الأسئلة الشائعة حول ورقة Verilog المرجعية
هل ورقة Verilog المرجعية هذه مجانية؟
ما الفرق بين wire و reg؟
wire اتصالًا فيزيائيًا ويجب أن يُقاد باستمرار - بعبارة assign أو بإخراج وحدة - لذا تستخدمه للشبكات التوافقية. أمّا reg فيحتفظ بقيمته حتى يغيّرها الكود الإجرائي، لذا تستخدمه لأيّ شيء يُسنَد داخل كتلة always أو initial. ورغم الاسم، فإن reg لا يصبح دائمًا سجلًّا عتاديًا؛ بل يعني فقط أن القيمة تُضبَط إجرائيًا.ما الفرق بين الإسناد الحاجب وغير الحاجب؟
=) فورًا وبالترتيب، مثل عبارة برمجية عادية، لذا استخدمه للمنطق التوافقي في كتل always @(*). أمّا الإسناد غير الحاجب (<=) فيُقيّم كل الأطراف اليمنى أولًا ثم يحدّث الأطراف اليسرى معًا، ما ينمذج القلّابات (flip-flops) بشكل صحيح - لذا استخدمه في كتل always @(posedge clk) المزامَنة. ومزج الاثنين في كتلة واحدة مصدر كلاسيكي لأخطاء المحاكاة.