التعريف بـXilinx و لغة الـVHDL الوصفية للهاردوير

عام 0 geek4arab
Spread the love

 

تحدثنا في السابق عن مفهوم اللغات الوصفية للهاردوير Hardware Description Languages (راجع مقدمة إلى اللغات الوصفية للهاردوير)  .. و الآن ندخل إلى أول درس عملي سنقوم بتنفيذه عن طريق اللغات الوصفية للهاردوير .. و سنختار من بين اللغات الوصفية لغة الـVHDL .. و التي هي إختصار لكلمة VHSIC Hardware Description Language .. و أما VHSIC فتعني Very High Speed Integrated Circuit .. و يوجد غيرها الكثير من اللغات الوصفية كالـVerilog و غيرها ..

تذكر .. هدفنا الذي نريد أن نصل إليه هو أن نقوم بتصميم الدوائر الرقمية و الهاردوير بطريقة سهلة بدلاً من القيام بعمل جداول طويلة جداً قد تصل إلى المئات و الألاف من المعطيات .. و ذلك عن طريق اللغات الوصفية التي ستتحول بعد ذلك إلى دوائر رقمية .. و الذي سيقوم بتحويلها برنامج يشبه إلى حدٍ ما المترجم Compiler الذي سيتخدم في اللغات البرمجية ..

البرنامج الذي سوف نقوم بإستخدامه يسمى ISE WebPACK وهو من إنتاج شركة Xilinx و هي شركة ذات شهرة في هذا المجال ..

إدخل إلى هذا الرابط :

http://www.xilinx.com/support/download/index.htm

و قم بتحميل الإصدار الأخير .. و إنتبه إلى أن النسخة التي ستقوم بتنزيلها ستفوق الـ3 جيجا بايت .. و بعد أن تقوم بتثبيتها ستأخذ ما يزيد على الـ10 جيجا بايت ..

و البرنامج مجاني .. فلن تحتاج إلى دفع أي شئ .. و لكن ستحتاج إلى الإشترك في موقعهم http://www.xilinx.com و بالطبع فالإشتراك مجاني أيضاً ..

و كما ذكرنا قبل ذلك .. بما أن التصميم الذي سنقوم بوصفه في يد البرنامج فلنقم بإستغلال هذا الأمر و جعله يقوم بعدة أشياء حول التصميم .. فعلى سبيل المثال ربما يقوم بمحاكاة التصميم لكي ترى هل سيخرج المخرجات Outputs بالشكل الذي كنت تتوقعه أم لا .. و قلنا بأن الإختبار له العديد من الصور .. و المحاكاة Simulation إحدى طرق الإختبار .. و لكن المحاكاة تخرج لك على شاشة الحاسوب ما الذي سيخرجه التصميم إذا ما تم تشغيله بالفعل ..

و لكن هذا ليس كافياً .. نر يد أن نختبر التصميم بالفعل لنرى كيف سيتعامل مع البيئة المحيطة .. فربما مثلاً نريد أن نقوم بتصميم بطاقة الفيديو VGA و نريد أن نختبر ما إذا كانت ستعرض الصور على الشاشة بالفعل أم لا .. أو نريد أن نصمم بطاقة الصوت Sound Card و نريد أن نختبر ما إذا كان سيخرج الصوت بالفعل أم لا .. لا نريد أن يتقصر الأمر على بعض الأصفار و الواحدات تخرج على شاشة الحاسوب تتحدث عن مخرجات التصميم .. نريد أن نرى نتائج بالفعل قبل أن نقوم بعملية التصنيع .. و الحل المتبادر إلى الذهن في هذه الحالة هو أن نقوم بتوصيل كل تلك الدوائر على لوحة التجارب Bread Board و نقوم بتوصيل دوائر البوابات المنطقية Logic Gates Integrated Circuits .. و بما أن هذا الأمر يصعب بل يستحيل كلما إزداد حجم التصميم فإننا نلجأ إلى الرقاقات القابلة للبرمجة Programmable Chips .. المبدأ العام في هذا الأمر هوأنك عندما تقوم ببرمجة تلك الرقاقات فإنها تصبح و كأنها هي التصميم الذي قمت به و تتصرف تماماً كما سيتصرف التصميم .. بعض تلك الرقاقات يحتوي على مجموعة كبيرة من البوابات المنطقية Logic Gates و توجد وصلات بين تلك البوابات .. تلك التوصيلات يمكن أن تشغل و يمكن أن تقفل .. و عندما تقوم ببرمجتها يتم تشغيل التوصيلات و إيقاف البعض الأخر حتى تصبح البوابات المنطقية موصلة ببعضها البعض موافقة للتصميم الذي قمت به .. هذا ما يحدث في بعض الرقاقات و هناك بعض الأساليب و الطرق الأخرى سنحتاج إلى ذكرها لاحقاً إن شاء الله

و تقوم شركة Xilinx بتصميم العديد من تلك الرقاقات .. و عندما نقوم بعمل تصميم جديد في البرنامج الذي سوف نشرحه بعد قليل يجب أن تخبره عن إسم الموديل الذي تريد أن تختبرعليه تصميمك .. بعض الرقاقات تسمى FPGA إختصاراً لـField Programmable Gate Array .. و هي الرقاقات التي من هذا النوع تتميز بالقدرة على إستيعاب تصميمات كبيرة و سرعة عالية ..

و الآن لنبدأ في شرح أساسيات لغة الـVHDL :

و قبل ذلك .. تذكر أن : عادةً في التصميمات الكبيرة و المعقدة .. نقوم بتقسيمها إلى وحدات صغيرة .. فعلى سبيل المثال عندما نقوم بتصميم معالج Processor لن نأتي ببعض الترانزيستورات Transistors و نقوم بتصميم دائرة كبيرة و معقدة .. و لكن سوف نقوم بتقسيمها إلى وحدات و طبقات .. و المعالج يتكون من بعض المسجلات Registers و وحدة المعالجة و المنطق Arithmetic Logic Unit و وحدة التحكم Control Unit و الواجهات الخارجية التي قد تستخدم للتعامل مع الذاكرة Ram أو المدخلات و المخرجات Input/Output Buffer .. ثم نقوم بتصميم كل وحدة و إختبارها وحدها .. فنجد مثلاً أن وحدة المعالجة و المنطق ALU بداخلها وحدات أخرى .. فنجد وحدة تقوم بالجمع و وحدة تقوم بالطرح و وحدة تقوم بالضرب و غير ذلك من الوحدات .. بالإضافة إلى وحدة تقوم بإختيار الناتج المطلوب من بين الوحدات الأخرى حسب العملية الحسابية التي نريد أن نقوم بها و التي سنعرفها عن طريق وحدة التحكم .. و إذا أردنا أن نصمم كل وحدة من تلك الوحدات سنجد بداخلهم بوابات منطقية .. و إذا أردنا تصميم البوابات المنطقية سنجد بداخلها مجموعة من الترانزيستورات و المقاومات .. الشاهد أن من قام بالتصميم الكلي للمعالج لم يهتم بما بداخل الوحدات التي سوف يستخدمها .. فهو قد قام بإستخدام وحدات أخرى لا يدري عنها غير أنها كيان Entity له بعض المدخلات و المخرجات و لا يهمه تكوينها الداخلي Architecture بما أنه سيستخدمها كعنصر Component بداخل تصميمه .. و هكذا الحال مع كل الوحدات .. فمصمم وحدة المعالجة و المنطق إستخدم بعض الوحدات كعناصر Components لا يهمه تكوينها الداخلي Architecture طالما هو ينظر إليها على أنها كيان Entity له مخرجات و مدخلات فقط .. بهذه الطريقة نستطيع تسهيل مهمة التصميم .. يمكننا إختبار كل وحدة بذاتها .. يمكننا إستخدام نفس الوحدة التي تم تصميمها في تصميمات أخرى .. و قد تحدثنا عن هذا الأمر بالتفصيل سابقاً عدة مرات .. و في لغة الـVHDL نتبع إسلوب تقسيم التصميم إلى وحدات و نقوم بتصميم كل وحدة بذاتها و قد نقوم بإستخدام وحدات إخرى تم تصميمها من قبل و هكذا ..

و الأن .. قم بعمل مشروع جديد على برنامج الـISE Webpack ..

هنا قمنا بإنشاء مشروع جديد و قمنا بتسميته ..

و هنا نقوم بتحديد إسم الرقاقة التي نريد أن نختبر التصميم عليها .. بالطبع إذا كنت لا تريد أن تختبر على رقاقة قابلة للبرمجة قم بتحديد أي شئ .. و إذا كان لديك واحدة قم بإختيارها هنا .. كما ستقوم بإختيار اللغة التي سوف تصف بها تصميمك في خانة Preferred Language ..

و هكذا نكون قد أنشأنا مشروعاً جديداً .. لنقم الآن بإضافة وحدات إلى التصميم .. قد تكون تلك الوحدة هي التصميم الذي سيتكون من وحدات أخرى بداخله .. و هو ما يسمى بالـTop Module .. و قد يكون مجرد وحدة بداخل التصميم سنستخدمها كعنصر Component بداخل بعض الوحدات الأخرى .. لإنشاء وحدة جديدة .. إضغط بالزر الأيمن على إسم المشروع و إختار New Source ..

قم بإختيار VHDL Module .. أما عن بقية الأشياء هنا .. عندنا VHDL Test Bench نقوم بإسخدامها عندما نقوم بعمل محاكاة للتصميم .. و بالطبع Verilog Module و Verilog Test Fixture لنفس الغرض و لكن بلغة الـVerilog .. يمكن أيضاً تصميم وحدة من الوحدات بإستخدام الرسم Schematic .. بعض الأشياء الأخرى سنتحدث عنها لاحقاً إن شاء الله ..

سنقوم بتصميم ناخب (أو ما يسمى بالـMUX) .. و هو عبارة عن دائرة لها مدخلات متعددة و مخرج واحد .. المطلوب من الوحدة هو أن تقوم بإختيار أي المدخلات سوف يتم إختياره ليكون المخرج .. و يتم التحديد على  أساس مدخل أخر يسمى بالـSelect Line لنقوم بالإختيار على أساسه ..

و هنا نقوم بتحديد المدخلات و المخرجات لتلك الوحدة .. هنا نريد أن نقوم بإختيار ما بين input1 و input2 و input3 و input4 .. بالطبع هنا لدينا أربع إحتمالات .. و هي 00 و 01 و 10 و 11 .. أي إثنان من البتات 2bits للمدخل الذي سيقوم بالإختيار المسمى SelectLine .. و طول كل من المدخلات 16bit .. بداخل الكود يمكن أن نتعامل مع المدخل الواحد ككل .. أي نتعامل مع الـ16bits مرة واحدة فنذكر كلمة input1 هكذا .. و يمكن أن نتعامل مع bit واحد فقط فنقول

input1(4)

و قد جرت العادة على أننا نبدأ العد من الصفر و ليس من الواحد كما يحدث في اللغات البرمجية .. و لهذا السبب قمنا بتحديد طول المدخل أنه من 15 و حتى 0 .. أي 16bit .. إذا كان المدخل به أكثر من bit واحد فإنه يسمى Bus و حينها نقوم بوضع علامة على خانة Bus و نذكر الطول كما فعلنا هنا ..

بهذه الطريقة نقوم بكتابة الكود الوصفي .. نصف به سلوك الدائرة .. و هذا هو الكود الذي يصف وحدة الناخب أو الـMUX

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

entity Multiplexer is

Port ( SelectLine : in  STD_LOGIC_VECTOR (1 downto 0);

input1 : in  STD_LOGIC_VECTOR (15 downto 0);

input2 : in  STD_LOGIC_VECTOR (15 downto 0);

input3 : in  STD_LOGIC_VECTOR (15 downto 0);

input4 : in  STD_LOGIC_VECTOR (15 downto 0);

output : out  STD_LOGIC_VECTOR (15 downto 0));

end Multiplexer;

architecture Behavioral of Multiplexer is

begin

output <= input1 when SelectLine=”00″ else

input2 when SelectLine=”01″ else

input3 when SelectLine=”10″ else input4;

end Behavioral;

في البداية نقوم بذكر المكتبات التي سوف نستخدمها .. بمعنى أخر .. يوجد بتلك المكتبات وحدات جاهزة .. و البرنامج الذي سيقوم بتصميم الدائرة سيستخدم فقط الوحدات المعرفة بداخل المكتبات التي ذكرتها في الأعلى .. و سنذكر المزيد من التفاصيل حول هذا الأمر لاحقاً إن شاء الله ..

في بداية وصفنا لهذه الوحدة .. قمنا بوصف المدخلات و المخرجات .. و قبل ذلك قمنا بتعريف الوحدة التي نريدها على أنها كيان Entity لا نعرفه عنه سوى أنه مربع مصمط به مدخلات و مخرجات فقط .. نذكر كلمة entity ثم إسمها الذي أسميناه لها ثم كلمة is ..  و بين سطر  entity Multiplexer is و بين end Multiplexer ذكرنا المدخلات و المخرجات .. نكتب كلمة Port ثم بين قوسين نذكر كل المدخلات و المخرجات .. فعلى سبيل المثال المدخل الأول إسمه SelectLine .. ثم نقطتان .. ثم هل هو مدخل أم مخرج حيث نقول in أو out .. ثم هل هو مكون من bit واحد أم هو Bus به عدد من البتات bits .. فإذا كان عبارة عن Bus نقول STD_LOGIC_VECTOR ثم بين قوسين نذكر حجمه .. و إذا كان المدخل bit واحد فإننا نقول STD_LOGIC فقط .. و بين كل تعريف لكل مدخل أو مخرج نضع فاصلة منقوطة .. فهناك فاصلة منقوطة بين تعريف SelectLine و input1 .. و هناك فاصلة منقوطة بين تعريف input1 و input2 .. حتى نصل إلى تعريف input4 نضع فاصلة منقوطة بينه و بين تعريف output .. ثم نغلق القوس .. ثم نضع فاصلة منقوطة لتغلق عبارة Port .. ثم ننهي تعريف الكيان Entity بكلمة end يتبعها إسم الكيان .. ثم فاصلة منقوطة ..

هكذا نكون قد قمنا بتعريف الكيان .. نريد أن نصف التكوين الداخلي لهذا الكيان الآن .. سنقوم بإعطاء إسم لهذا التكوين الداخلي .. و قد جرى العرف على أن يتم تسمية التكوين الداخلي أو ما يعرف بالـArchitecture بإسم Behavioral .. فقمنا بتعريف التكوين فقلنا Architecture ثم إسمه و الذي إقترحنا أن يكون Behavioral .. ثم نذكر إسم الكيان الذي نريد أن يكون به هذا التكوين فنقول of ثم إسم الـEntity و الذي كان Multiplexer .. ثم is begin حتى نبدأ في وصف التكوين الداخلي .. و بعد أن ننتهي من وصفه ننهي الأمر بكلمة end ثم إسم التكوين ثم فاصلة منقوطة ..

و في أثناء وصفنا للتكوين بين begin و end كنا نريد أن نصف حال المخرج الذي أسميناه output .. فقلنا أن output بقيمة input1 إذا كان المدخل SelectLine بقيمة 00 و إذا لم يكن ذلك فسيكون output بقيمة input2 إذا كان SelectLine بقيمة 01 .. فإذا لم يكن كذلك فسيكون Output بقيمة input3 إذا كان SelectLine بقيمة 10 و إذا لم يتحقق أي شرط من الشروط السابقة فسيكون output بقيمة input4 .. هذا ما يسمى بالـWhen Statement .. قلنا بأن هذه الوحدة التي نقوم بوصفها تجعلنا نقوم بالإختيار من بين مدخلات عديدة .. و الإختيار الذي سنقوم به سيكون على حسب المدخل SelectLine .. الإختيار الذي سيقع سيخرج في المخرج output .. و في وصفنا لسلوك المخرج المدعو output ذكرنا إسمه و بعدها الرمز

<=

ثم نذكر الحالات التي سيكون عليها .. و بعد ذلك كل حالة نذكر الشرط الذي سيجعل تلك الحالة تقع .. نذكر الشرط بعد كلمة when يتعبها كلمة else يتبعها ذكر حالة أخرى مع شرط أخر .. أو إذا كانت الحالة الأخيرة ستحدث إذا لم تتحقق أي من الشروط الأخرى فإننا لا نذكر عبارة when بعدها و نقوم بوضع فاصلة منقوطة في النهاية ..

من الممكن أن تكون هذه الوحدة هي عبارة عن عنصر سنقوم بإستخدامه في وحدة أخرى .. و من الممكن أن تكون هي التصميم كله .. و في هذه الحالة تسمى الـTop Module .. و هذا البرنامج يعتبر أن أول وحدة قمنا بإنشائها هي الـTop Module .. و إذا أردت تغيير الـTop Module قد بتحديده من القائمة التي في أيسر النافذة و إضغط بالزر الأيمن و إختار Set as Top Module ..

إنظر إلى القائمة التي تحتها ..

قم بتشغيل Check Syntax حتى تتأكد من صحة الكود الوصفي الذي كتبته ..

إذا كانت الوحدة التي قمت بتحديدها في القائمة التي فوق هذه القائمة هي الوحدة الرئيسية أو الـTop Module فحينها يمكنك أن تجعل البرنامج يعرض لك الرسم التوضيحي Schematic للتصميم أو للدائرة ككل .. و الرسم التوضيحي هذا له نوعين .. النوع الأول هو رسم الغرض منه أن تفهم التصميم .. لذا فهو رسم مقروء واضح لكل من يراه .. فعلى سبيل المثال إذا كان هناك مدخل به أكثر من bit واحد .. أو ما يسمى بالـBus فإنه سيرسمه على أنه مدخل واحد و ربما يكتب تحته عدد الـbits لهذا المدخل .. لن تجده مثلاً يقوم برسمه 16 مرة .. و النوع الأخر هو رسم للدائرة بكل تفاصيلها .. ليس الغرض منه أن تفهم .. إنما الغرض منه أن يعطيك الدائرة بما فيها من تفاصيل لكي تقوم بتصنيعها أو توصيلها بنفسك أو أي شئ من هذا .. و يدعم هذا البرنامج هذين النوعين من الرسوم .. إذا ضغطت على View RTL Schematic فإنه سيظهر لك النوع الأول .. و إذا ضغطت على View Technology Schematic فسيظر لك النوع الثاني ..

هنا سنقوم بعرض الرسم التوضيحي للتصميم .. في القائمة اليسرى ستجد التصميم بكل طبقاته .. ستجد في الأعلى التصميم كله كوحدة واحدة .. يندرج منه العديد من الوحدات بداخل تلك الوحدة .. و إذا قمت بفتح أي من الوحدات ستجد بداخلها وحدات أخرى تندرج منها .. و أنت ربما لا تريد أن تظهر كل الطبقات .. تريد أن تظهر التصميم على أنه وحدة واحدة .. أو تريد أن تظهر تفاصيل بعض الوحدات و تتجاهل تفاصيل وحدات أخرى .. و لهذا السبب ستقوم بتحديد ماذا تريد أن تراه .. قم بتحديده في القائمة اليسرى ثم إضغط Add ثم Create Schematic ..

و هنا قمنا بإظهار الرسم التوضيحي .. نلاحظ هنا أن البرنامج إستنتج من خلال الكود أننا كنا نريد أن نضع ناخب (MUX) .. فقام برسمه في التصميم بالرمز المعروف له .. و هذا أمر سنعتاد عليه .. أحياناً سنجده يستنتج بنفسه أننا كنا نقصد عمل دائرة جمع Adder أو طرح Subtracter أو ضرب Multiplier أو كنا نريد أن نضع ذاكرة Ram .. فكلما إستنتج وجود شئٍ ما سيقوم بوضعه في الرسم بالرمز المعروف له .. و إذا لم يستنتج أننا نقصد شئ معروف فسيقوم بوضعه كمربع مليء بالبوابات المنطقية ..

و هكذا نكون قد إنتهينا من وصف هذه الدائرة .. و لندع المحاكاة و برمجة رقاقات الـFPGA للمرة القادمة ..

الكاتب geek4arab

geek4arab

مواضيع متعلقة

التعليقات مغلقة