Menu
flag Ar iconالعربيةdown icon

Vectors وArrays في Verilog: الإشارات متعددة البت مشروحة

كيف تُعلن عن إشارات متعددة البت بـ [7:0]، وكيف تأخذ شرائحها، وكيف تجمعها، والفرق بين vector محزوم وarray ذاكرة.

تحتوي هذه الصفحة على محررات قابلة للتشغيل - حرّر، شغّل، وشاهد النتيجة فوراً.

سلك واحد مقابل عدة

حتى الآن كانت كل إشارة رأيناها بت واحدة عرضًا. التصاميم الحقيقية لا تبدو هكذا تقريبًا أبدًا - العناوين 16 أو 32 بت، باصات البيانات 8 أو 64، بكسلات RGB هي 24. يعطيك Verilog آلية واحدة لجعل أي إشارة متعددة البت: أضف نطاقًا بين الأقواس المربعة.

wire [7:0] data;       // 8-bit wire, bit 7 is MSB, bit 0 is LSB
reg  [15:0] address;   // 16-bit reg
output reg [31:0] result; // 32-bit module output

الأرقام بين الأقواس هي مواضع البتات للبتين الأكثر والأقل أهمية. [7:0] يعني "هذه الإشارة لها بتات مرقمة من 7 إلى 0"، وهو ما يساوي 8 بتات إجمالًا. الرقم الأول هو الفهرس العالي. الثاني هو الأدنى.

سترى أحيانًا [0:7] بدلًا من ذلك - نفس عدد البتات، اتجاه معاكس لأغراض التشريح. صيغة [high:low] هي العرف الصناعي الساحق؛ التزم بها ما لم يكن لديك سبب قوي للعدول.

مثال: جامع 8 بت

كل + يجمع vectors بـ 8 بت ويُنتج نتيجة 9 بت. حروف الأرقام مثل 8'd10 تقول "قيمة عشرية بعرض 8 بت تساوي 10" - سنغطّيها في Number Literals.

التشريح: انتقاء البتات

بمجرد أن يكون لديك vector، يمكنك سحب بتات فردية أو نطاقات متتالية:

لا تتعلق كثيرًا بسطر force في testbench - نحتاج فقط طريقة لحقن قيمة لإظهار التشريح. الجزء المهم هو الشرائح نفسها.

بعض القواعد:

  • يجب أن يطابق اتجاه الشريحة الإعلان. إن أعلنت [7:0]، فاشرّح بـ [high:low]. عكس الاتجاه خطأ صياغي.
  • التشريح خارج النطاق يُنتج x (مجهول) في المحاكاة. قد تحذر أداة التركيب أو تُخطئ.
  • اختيار البت مُفهرس من الصفر على الفهرس الذي كتبته - data[0] هي البت المسماة 0، التي (لإعلان [7:0]) هي LSB.

شرائح بقاعدة متغيرة: +: و-:

حاجة شائعة: "أعطني 8 بتات بدءًا من البت N". لا يمكنك كتابة data[N+7:N] مباشرةً لأن Verilog يتطلب أن تكون كلتا نهايتي النطاق ثابتتين. الصياغة التي تحلّ ذلك:

data[base +: width]   // width bits starting at `base`, going UP
data[base -: width]   // width bits starting at `base`, going DOWN

العرض ثابت (نختار 8 بتات في كل مرة)، لكن القاعدة يمكن أن تكون تعبير وقت تشغيل. هذا بالضبط ما تحتاجه للذواكر القابلة للعنونة بالبايت ونقاط شريحة sجلات الإزاحة، وهكذا.

Arrays: خطوة وراء Vectors

vector هو إشارة واحدة متعددة البت. أما array فهي مجموعة من vectors، مفهرسة باستقلال:

reg [31:0] mem [0:1023];

هذا الإعلان نطاقان، والنطاقان يعنيان أشياء مختلفة:

  • [31:0] هو البعد المحزوم (packed) - عرض كل كلمة فردية.
  • [0:1023] هو البعد غير المحزوم (unpacked) - كم كلمة توجد.

إذن mem هي 1024 register مستقلة 32 بت. تصل إلى واحدة بفهرس واحد:

mem[5] = 32'hCAFE_BABE;       // write word 5
data   = mem[address];        // read the word at `address`

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

packed مقابل unpacked: لماذا يهم

الانقسام بين الأبعاد packed وunpacked يظهر في كل مكان. معرفة أيهما أيهما يوفّر كثيرًا من التنقيح:

  • vector محزوم هو إشارة واحدة. يمكنك التعامل مع الكل كرقم: data + 1 يعمل، data == 32'h0 يعمل، data[7:0] يعمل.
  • array غير محزوم هو إشارات كثيرة. لا يمكنك التعامل مع الكل كرقم: mem + 1 خطأ صياغي. عليك انتقاء كلمة محددة أولًا.

أبعاد packed متعددة شرعية أيضًا:

reg [3:0][7:0] regs;   // 4 bytes packed together into a 32-bit signal

regs[0] بايت (البايت الأدنى). regs ككل 32 بت. SystemVerilog يستخدم هذا بكثافة.

أبعاد unpacked متعددة تُنشئ ذاكرة 2D:

reg [31:0] frame [0:479][0:639];  // 480x640 of 32-bit pixels

تصل إلى بكسل واحد بـ frame[y][x]. هكذا يبدو buffer الصورة في HDL.

ماذا بعد

تستطيع الآن إعلان ومعالجة أي إشارة بأي عرض تحتاجه. المستند التالي - Parameters - يُظهر كيف تجعل تلك العروض قابلة للضبط بحيث يعمل نفس module بـ 8 بت في نسخة و32 بت في أخرى. ثم سننتقل إلى قواعد كتابة الأرقام الحرفية (8'b1010_1100، 32'hDEAD_BEEF)، وقيم x/z التي تظهر كلما لم يكن شيء مَقُودًا.

الأسئلة الشائعة

ما هو vector في Verilog؟

vector هو إشارة متعددة البت. تُعلن عن واحد بإضافة نطاق إلى wire أو reg: wire [7:0] data هو سلك 8 بتات. الأرقام بين القوسين هي مواضع البتات - في هذه الحالة البت 7 هي الأكثر أهمية والبت 0 هي الأقل. يمكنك تشريح بتات فردية (data[3]) أو نطاقات متتالية (data[7:4]).

ماذا يعني [7:0] في Verilog؟

[7:0] يُعلن عن نطاق من البت 7 إلى البت 0، شاملًا - إشارة 8 بت مع البت 7 كأكثر بت أهمية. الرقم الأول هو الفهرس العالي، والثاني هو الأدنى. يمكنك أيضًا كتابة [0:7] لفهرسة little-endian، لكن صيغة [high:low] هي الأكثر شيوعًا بكثير في شيفرة الصناعة.

كيف تأخذ شريحة من البتات في Verilog؟

استخدم الفهرسة بين الأقواس. data[3] يختار بت واحدة. data[7:4] يختار البتات العليا الأربع كـ vector 4 بت. الشريحة يجب أن تكون بنفس اتجاه الإعلان - إن أعلنت [7:0]، فاشرّح بـ [high:low]. SystemVerilog يضيف أيضًا data[3 +: 4] لشرائح ذات قاعدة متغيرة وعرض ثابت.

ما الفرق بين packed وunpacked array في Verilog؟

packed array هو bus متصل واحد - reg [31:0] word هو إشارة 32 بت واحدة. أما unpacked array (أو 'ذاكرة') فهي مجموعة من كلمات مستقلة - reg [31:0] mem [0:1023] هي 1024 register مستقلة كل منها 32 بت. يمكنك قراءة أو كتابة كلمة كاملة من unpacked array لكن لا يمكنك التعامل مع الكل كإشارة واحدة.

كيف تُعلن عن ذاكرة في Verilog؟

reg [31:0] mem [0:1023]; تُعلن عن ذاكرة 1024 مدخلًا، كل منها 32 بت عرضًا. المجموعة الأولى من الأقواس هي عرض الكلمة (packed)؛ والثانية هي عدد الكلمات (unpacked). صل إلى مدخل بـ mem[address]، ويمكنك قراءة أو كتابة شريحة من ذلك المدخل بـ mem[address][7:0] بمجرد تفعيل فهرسة SystemVerilog-2005.

Coddy programming languages illustration

تعلّم البرمجة مع Coddy

ابدأ الآن