تشريح ثابت محدد الحجم
ثابت Verilog له ما يصل إلى ثلاثة أجزاء:
8'b1010_1100
│ │ │
│ │ └─ digits in the chosen base
│ └─── base specifier: b (binary), h (hex), d (decimal), o (octal)
└────── width in bits (decimal)
قراءة من اليسار: "قيمة 8 بت، مكتوبة بالنظام الثنائي، أرقامها 10101100". هذه 172 عشريًا، 0xAC ست عشريًا، نفس البتات بأي طريقة كتبتها. العرض يخبر المترجم بعدد البتات بالضبط لتخصيصها؛ والقاعدة تخبره كيف يُفسّر الأرقام.
الشرطات السفلية فواصل بصرية. 32'b1010_1100_0011_0101 هي نفسها 32'b1010110000110101. استخدمها.
القواعد الأربع
ست عشري (h) هو المعيار لأي شيء أعرض من 4 بت. ثنائي (b) هو المعيار عندما تريد قراءة أنماط بتات مباشرة. عشري (d) للعدد ذي المعنى للبشر. ثُماني (o) موجود لكنك لن تراه تقريبًا أبدًا.
أرقام Hex غير حساسة لحالة الأحرف: 8'hAB و8'hab متطابقان.
ماذا يحدث عندما لا تتسع القيمة؟
إن لم تملأ أرقامك العرض المُعلن، يُمدّد Verilog بالأصفار يسارًا:
8'b101 // equivalent to 8'b00000101 (= 5)
8'hF // equivalent to 8'h0F (= 15)
إن تجاوزت أرقامك العرض المُعلن، يُقصّر Verilog البتات العالية مع تحذير:
4'hFF // truncates to 4'hF, simulator warns
4'b10000 // truncates to 4'b0000
التحذير صديقك. لا تُخمده.
محدد الحجم مقابل غير محدد
ثابت بدون عرض:
'd10 // unsized, takes default size (≥32 bits)
10 // also unsized - no base means decimal
الثوابت غير محددة الحجم تُفترض 32 بت في معظم الأدوات. هذا مصدر فئة كاملة من الأخطاء:
reg [7:0] count;
if (count == -1) ... // -1 is unsized 32-bit; comparison gets weird
الإصلاح هو كتابة 8'hFF بدلًا من -1، أو 8'd255، أو {8{1'b1}}. حدد دائمًا حجم الثوابت عندما تُستخدم في تعابير حساسة للعرض.
المكان الوحيد الذي تكون فيه الثوابت غير محددة الحجم لا بأس بها هو عدّادات الأعداد الصحيحة في حلقات for في testbench، حيث يكون الـ integer واسعًا كفاية ولا يحدث شيء مفاجئ.
الثوابت signed
افتراضيًا، الثوابت محددة الحجم unsigned:
8'd255 // unsigned 255
8'b1111_1111 // unsigned 255 - same bit pattern, just written differently
إن أردت تفسير الثابت كـ signed، أضف s بعد علامة الاقتباس:
8'sd10 // signed 10
8'sb1111_1111 // signed -1 (two's complement)
علم s يهم لـ:
- عوامل
<<<و>>>(الإزاحات الحسابية) - تُمدّد إشارة المعاملات signed. - عوامل المقارنة على تعابير signed مختلطة.
- تحويلات
$signed/$unsigned.
لمعظم الحسابات العادية على إشارات bus، ستترك s.
ثوابت بـ X وZ
رقم حرفي يمكن أن يكون x (مجهول) أو z (معاوقة عالية):
8'bx اختصار لـ "كل البتات الـ 8 مجهولة" - تنتشر القيمة لتملأ العرض المُعلن. أرقام x شائعة في حالات default لآلات الحالة وفي التهيئة. نغطّي الدلالات في قيم X وZ.
أين تظهر الثوابت محددة الحجم في الممارسة
بمجرد أن تبدأ كتابة modules حقيقية، تظهر الثوابت محددة الحجم في كل مكان:
// Bus widths
input wire [31:0] addr;
wire [31:0] zero = 32'h0;
wire [31:0] all_ones = 32'hFFFF_FFFF;
// State encodings
localparam IDLE = 3'd0;
localparam BUSY = 3'd1;
localparam DONE = 3'd2;
// Masks
wire is_msb_set = data & 32'h8000_0000;
// Comparisons
if (counter == 8'd255) ...
// Reset values
always @(posedge clk) begin
if (reset) data_out <= 8'd0;
else data_out <= data_in;
end
النمط ثابت: اكتب العرض، اكتب القاعدة، اكتب الأرقام. كل ثابت تلجأ إليه له نفس الشكل.
جولة اختبار
لديك الآن كل ما تحتاجه لكتابة أي ثابت قد يريده module من Verilog. القطعة الأخيرة من قصة أنواع البيانات هي ما يحدث عندما لا تكون الإشارة 0 أو 1 نظيفة - قيمتا x وz.
الأسئلة الشائعة
ماذا يعني 8'b1010 في Verilog؟
إنه ثابت ثنائي محدد الحجم: قيمة 8 بت تمثيلها الثنائي 00001010. الرقم قبل علامة الاقتباس هو العرض بالبتات؛ الحرف بعد علامة الاقتباس هو القاعدة (b ثنائي، h ست عشري، d عشري، o ثُماني)؛ الأرقام بعدها هي القيمة. يُحشى الثابت بالأصفار يسارًا إن لم تملأ الأرقام العرض.
ما الفرق بين الأرقام محددة الحجم وغير محددة الحجم في Verilog؟
الثابت محدد الحجم مثل 8'd10 بعرض 8 بت بالضبط. أما الثابت غير المحدد مثل 'd10 أو مجرد 10 فيُفترض افتراضيًا 32 بت، وهو عادةً أكثر مما يلزم. خلط ثوابت غير محددة الحجم في تعابير حساسة للعرض يُسبّب أخطاء خفية - فضّل ثوابت محددة الحجم في كل مكان خارج شيفرة الاختبار المؤقتة.
كيف تكتب رقمًا ست عشريًا في Verilog؟
استخدم محدد القاعدة 'h: 8'hFF قيمة 8 بت تساوي 255. أرقام hex غير حساسة لحالة الأحرف؛ 8'hff و8'hFF متطابقان. يمكنك تجميع الأرقام بشرطات سفلية لتحسين القراءة: 32'hDEAD_BEEF. الشرطات السفلية يتجاهلها المُحلّل.
كيف تعمل الشرطات السفلية في أرقام Verilog؟
الشرطات السفلية فواصل بصرية يتجاهلها المُحلّل. 32'b1010_1100_0011_0101 هي نفسها القيمة 32'b1010110000110101 بالضبط لكنها أسهل بكثير للقراءة. أول حرف بعد بادئة القاعدة لا يمكن أن يكون شرطة سفلية، لكن يمكنك وضعها في أي مكان آخر في سلسلة الأرقام.
كيف تكتب رقمًا signed في Verilog؟
أضف s بعد علامة الاقتباس: 8'sd10 هو 10 عشري بـ 8 بت signed، و8'sb1111_1111 هو -1 signed. افتراضيًا، الثوابت محددة الحجم unsigned؛ تعديل s يعكس ذلك. معظم الحسابات تستخدم معاملات unsigned - استخدم signed فقط عندما تحتاج فعلًا قيمًا سالبة تنتشر عبر < و>>> وعوامل مماثلة.