سلسلة من الدروس في لغة توصيف العتاد الصلبVHDL
الدرس السادس – ذاكرة المعطيات (الحلقات و المصفوفات)
الحلقات
تستخدم الحلقات في لغة توصيف العتاد الصلب VHDL لتكرار إسناد قيمة إلى شعاع مثلاً أو إلى مصفوفة و توجد ضمن Process.
تقسم الحلقات إلى نوعين:
– حلقات غير مقيدة بشرط FOR.
– حلقات مقيدة بشرط WHILE.
الحلقات غير المقيدة بشرط FOR:
FOR i IN 0 TO 9 LOOP
— some code here
END LOOP;
تتكرر الحلقة السابقة عشر مرات يأخذ فيها i القيم من 0 – 9 .
FOR i IN 9 DOWNTO 0 LOOP
— some code here
END LOOP;
تتكرر الحلقة السابقة عشر مرات أيضاً و يأخذ فيها i القيم من 9 – 0 .
الحلقات مقيدة بشرط WHILE
WHILE (condition) LOOP
— some code here
END LOOP;
تتكرر الحلقة حتى تحقق الشرط condition.
المصفوفات
لتعريف المصفوفات في لغة الـ VHDL يجب المرور بمرحلتين
– تعريف نوع جديد من البيانات لتحديد حجم المصفوفة و نوعها.
TYPE myarray IS ARRAY (0 TO 3) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
– تعريف إشارة Signal من نوع البيانات الجديد المعرف.
SIGNAL X : myarray;
تكون X في هذه الحالة مصفوفة مؤلفة من أربعة أسطر كل سطر هو شعاع من نوع
STD_LOGIC_VECTOR(7 DOWNTO 0)
أي هي مصفوفة بحجم (8 × 4)، يسمى هذا النوع من المصفوفات بالمصفوفات 1D × 1D.
الوصول إلى حجرات المصفوفة
يمكن الوصول إلى المصفوفة سطراً سطراً و ذلك بتحديد رقم السطر
X(رقم السطر)
أو يمكن الوصول إلى كل حجرة على حدا و ذلك بتحديد رقم السطر ثم رقم العمود
X(رقم العمود)(رقم السطر)
بما أننا عرفنا المصفوفة على شكل إشارة SIGNAL فلإسناد قيمة إلى سطر أو حجرة فإننا نستخدم دلالة الإسناد “<= ” و طبعاً يكون حجم البيانات المسندة بحجم السطر إن كنا نتعامل مع أسطر المصفوفة، أو بحجم الحجرة.
الذواكر
آلية عمل الذاكرة RAM
تتألف الذاكرة من مصفوفة من الحجرات الذاكرة التي تمثل كل منها مسجل، يوجد للذاكرة ممر للعناوين و ممر للبيانات المدخلة إلى الذاكرة و آخر للبيانات الخارجة من الذاكرة. يوجد إشارة تحكم خاصة بالقراءة و أخرى خاصة بالكتابة و قد يدمجان في خط واحد.
سنقوم بتوصيف ذاكرة 64 بايت مؤلفة من 64 حجرة ذاكرية كل منها هو مسجل بطول 8 بت (1 بايت). تمتلك هذه الذاكرة ممر عناوين بعرض 3 بت و ممري بيانات كل منهما بعرض 8 بت. يوجد إشارة تحكي وحيدة MemRW بحيث تكون العملية قراءة عندما تكون
MemRW = 1 و تكون العملية كتابة عندما تكون MemRW = 0 .
توصف الذاكرة RAM
1: LIBRARY IEEE;
2: USE IEEE.STD_LOGIC_1164.ALL;
3: USE IEEE.STD_LOGIC_ARITH.ALL;
4: USE IEEE.STD_LOGIC_SIGNED.ALL;
————————————–
5: ENTITY dmemory IS
6: PORT( read_data : OUT STD_LOGIC_VECTOR(7 DOWNTO 0 );
7: address : IN STD_LOGIC_VECTOR( 5 DOWNTO 0 );
8: write_data : IN STD_LOGIC_VECTOR( 7 DOWNTO 0 );
9: MemRW: IN STD_LOGIC;
10: clock, reset : IN STD_LOGIC );
11: END dmemory;
————————————–
12: ARCHITECTURE behavioral OF dmemory IS
13: TYPE memArray IS ARRAY (0 TO 63) OF STD_LOGIC_VECTOR (7 DOWNTO 0);
14: SIGNAL mem : memArray;
15: BEGIN
16: PROCESS (clock,reset)
17: BEGIN
18: IF (clock’event AND clock=’0′)THEN
19: IF(reset=’1′)THEN
20: FOR i IN 63 DOWNTO 0 LOOP
21: mem(i) <= “00000000”;
22: END LOOP;
23: END IF;
24: IF(MemRW = ‘1’) THEN
25: read_data <= mem (CONV_INTEGER(address));
26: ELSE
27: mem (CONV_INTEGER (address)) <= write_data ;
28: END IF;
29: END IF;
30: END PROCESS;
31:END behavioral;
CONV_INTEGER:
تسمح مكتبة IEEE.STD_LOGIC_ARITH بتحويل النوع STD_LOGIC_VECTOR إلى النوع INTTEGER و ذلك اعتماداً على آلية الانتقال من نظام العد الثنائي إلى نظام العد العشري.
المحاكاة
التطبيق على لوحة الاختبار
لاختبار نجاح التصميم و عمله بشكل صحيح فيزيائياً نقوم بعد برمجة شريحة الـ FPGA بإجراء عملية كتابة على إحدى الحجرات الذاكرة ثم القراءة من نفس الحجرة.
الإسناد:
سنقوم بإسناد المداخل و المخارج إلى أقطاب الشريحة و ذلك اعتماداً على مخطط لوحة الاختبار و ربطها مع أقطاب الشريحة الموجود في الملف DE2_115_User_manual.
الإسناد موضح في الجدول التالي :
Description |
FPGA Pin No. |
Signal Name |
Port |
50 MHz clock input |
PIN_Y2 |
CLOCK_50 |
clock |
Push-button[3] |
PIN_R24 |
KEY[3] |
reset |
Slide Switch[17] |
PIN_Y23 |
SW[17] |
MemRW |
Slide Switch[16] |
PIN_Y24 |
SW[16] |
address[2] |
Slide Switch[15] |
PIN_AA22 |
SW[15] |
address[1] |
Slide Switch[14] |
PIN_AA23 |
SW[14] |
address[0] |
Slide Switch[7] |
PIN_AB26 |
SW[7] |
write_data[7] |
Slide Switch[6] |
PIN_AD26 |
SW[6] |
write_data[6] |
Slide Switch[5] |
PIN_AC26 |
SW[5] |
write_data[5] |
Slide Switch[4] |
PIN_AB27 |
SW[4] |
write_data[4] |
Slide Switch[3] |
PIN_AD27 |
SW[3] |
write_data[3] |
Slide Switch[2] |
PIN_AC27 |
SW[2] |
write_data[2] |
Slide Switch[1] |
PIN_AC28 |
SW[1] |
write_data[1] |
Slide Switch[0] |
PIN_AB28 |
SW[0] |
write_data[0] |
LED Red[7] |
PIN_H19 |
LEDR[7] |
read_data[7] |
LED Red[6] |
PIN_J19 |
LEDR[6] |
read_data[6] |
LED Red[5] |
PIN_E18 |
LEDR[5] |
read_data[5] |
LED Red[4] |
PIN_F18 |
LEDR[4] |
read_data[4] |
LED Red[3] |
PIN_F21 |
LEDR[3] |
read_data[3] |
LED Red[2] |
PIN_E19 |
LEDR[2] |
read_data[2] |
LED Red[1] |
PIN_F19 |
LEDR[1] |
read_data[1] |
LED Red[0] |
PIN_G19 |
LEDR[0] |
read_data[0] |
بما أننا أسندنا مدخل الـ reset إلى push button فيجب تعديل التوصيف ليصبح التصفير عند المستوى المنخفض لإشارة reset و ذلك لأن الـ push button تعطي ‘0’(المستوى المنخفض) عند ضغطها و قد عرفنا ذلك من ملف DE2_115_User_manual.