فئات هندسة الكترونية عادة ما تمليه باستخدام الأدوات الشعبية، لذلك أقضي دائمًا بضع ساعات في البحث عن عملي البرمجيات الحرة. لهذا السبب ، قررت مشاركة ما يلي توجيه. |
تركيب ما يلزم
لتجميع ومحاكاة برامجنا ، سنستخدم GHDL ، وهو مترجم مجاني يعتمد على GCC. لمشاهدة نتائج المحاكاة ، سنستخدم GTKWAVE. كمحرر ، أوصي بـ Geany لأنه يتعرف على جميع لغات البرمجة تقريبًا.
sudo apt-get install ghdl gtkwave geany
مثال على المشروع
دعنا نستخدم هذا المقارنة كمثال:
قبل إنشاء مشروع ، لنبدأ بإنشاء مجلد حيث سيتم استضافة جميع الملفات. في هذه الحالة ، / home / user / vhdl. هناك سنقوم بحفظ الكود المصدري لبرامجنا بامتداد .vhd.
ثم نكتب برنامجنا باستخدام Geany ، كما هو موضح في لقطة الشاشة.
نقوم بحفظه كمقارنه.
الآن سنحتاج إلى إنشاء إشارات للمحاكاة. للقيام بذلك ، سنقوم بإنشاء مكون يستخدم الكتلة السابقة وسوف نحدد الإشارات.
الخطوط أ <= "0011" بعد 0 نانوثانية ، "0111" بعد 5 نانو ثانية ، "0111" بعد 10 نانو ثانية ؛ هي تلك التي تقوم بتكوين إشارات الإدخال في الوقت المناسب
نقوم بحفظ الملفات في / home / user / vhdl. ثم نفتح Terminal ونجمع:
ghdl -a قارن. vhd
إذا لم تكن هناك رسائل خطأ ، فإن التجميع يكون ناجحًا.
الآن نقوم بتجميع "المكون"
ghdl -a قارن_tb.vhd
في حالة عدم وجود أخطاء ، نقوم بإنشاء الملف القابل للتنفيذ:
ghdl -e قارن_tb
أخيرًا ، يبقى إجراء المحاكاة وحفظ النتائج في الملف المسمى "Compare.vcd"
ghdl -r قارن_vcd - قارن
لمشاهدة النتائج سنستخدم gtkwave:
gtkwave قارن
بمجرد الفتح ، استخدم مفتاح Ctrl والماوس للإشارة إلى الإشارات التي تهمنا واضغط على إدراج. ثم انقر نقرًا مزدوجًا فوق المتجهات لرؤية الإشارات المنفصلة. ثم انقر بزر الماوس الأيمن على الإشارات لاختيار التنسيق (ثنائي ، عشري ، ثماني ، عشري ، إلخ)
إذا لزم الأمر ، فإن زر العدسة المكبرة الذي يحتوي على مربع في المنتصف يضبط الرسم البياني على الشاشة.
ALU: وحدة حسابية ومنطق
حسنًا ، لنقم الآن بشيء أكثر إثارة للاهتمام: وحدة ALU (وحدة الأخلاق المنطقية والمنطقية). ستكون وحدة منطقية ووحدة حسابية ومضاعف.
محرك منطقي (LoU.vhdl)
مكتبة ieee ؛ استخدم IEEE.STD_LOGIC_1164.all ؛ استخدم IEEE.NUMERIC_STD.all ؛
كيان لو هو
PORT (المرجع 1: في std_logic_vector (7 DOWNTO 0) ؛
المرجع 2: في std_logic_vector (7 DOWNTO 0) ؛
العملية: IN std_logic_vector (3 DOWNTO 0) ؛
الدقة: OUT std_logic_vector (7 DOWNTO 0)) ؛
نهاية لو ؛
الهندسة المعمارية synth2 من لو هو
SIGNAL a، b: UNSIGNED (op1'range) ؛
SIGNAL c: UNSIGNED (res'range) ؛
ابدأ
عملية (أ ، ب ، عملية)
ابدأ
عملية CASE هي
عندما "0000" => c <= RESIZE ((وليس a) ، c'length) ؛
عندما "0001" => c <= RESIZE ((a and b)، c'length) ؛
عندما "0010" => c <= RESIZE ((a or b)، c'length) ؛
عندما "0011" => c <= RESIZE ((a xor b)، c'length) ؛
عندما "0100" => c <= RESIZE ((a nand b)، c'length) ؛
عندما "0101" => c <= RESIZE ((a or b)، c'length) ؛
عندما يكون الآخرون => فارغ ؛
نهاية القضية ؛
إنهاء العملية؛
أ <= غير موقعة (المرجع 1) ؛
ب <= غير موقع (المرجع 2) ؛
الدقة <= std_logic_vector (c) ؛
نهاية synth2 ؛
وحدة حسابية (ArU.vhd)
مكتبة ieee ؛ استخدم IEEE.STD_LOGIC_1164.all ؛ استخدم IEEE.NUMERIC_STD.all ؛
كيان آرو هو
PORT (المرجع 1: في std_logic_vector (7 DOWNTO 0) ؛
المرجع 2: في std_logic_vector (7 DOWNTO 0) ؛
العملية: IN std_logic_vector (3 DOWNTO 0) ؛
الدقة: OUT std_logic_vector (7 DOWNTO 0)) ؛
نهاية آرو ؛
تركيب معماري من aru IS
SIGNAL a، b: UNSIGNED (op1'range) ؛
SIGNAL c: UNSIGNED (res'range) ؛
ابدأ
عملية (أ ، ب ، عملية)
ابدأ
عملية CASE هي
عندما "0000" => c <= RESIZE ((a + b)، c'length) ؛
عندما "0001" => c <= RESIZE ((a - b)، c'length) ؛
عندما "0010" => c <= RESIZE ((a * b)، c'length) ؛
عندما "0011" => c <= RESIZE ((a / b)، c'length) ؛
عندما "0100" => c <= RESIZE ((a + "1")، c'length) ؛
عندما "0101" => c <= RESIZE ((b + "1")، c'length) ؛
عندما يكون الآخرون => فارغ ؛
نهاية القضية ؛
إنهاء العملية؛
أ <= غير موقعة (المرجع 1) ؛
ب <= غير موقع (المرجع 2) ؛
الدقة <= std_logic_vector (c) ؛
موالفة النهاية ؛
معدد (muxVector.vhd)
مكتبة ieee ؛ استخدم IEEE.STD_LOGIC_1164.all ؛ استخدم IEEE.NUMERIC_STD.all ؛
كيان muxVector هو
PORT (من ARU: IN std_logic_vector (7 DOWNTO 0) ؛
fromLOU: في std_logic_vector (7 DOWNTO 0) ؛
التبديل: IN std_logic ؛
الإخراج: خارج std_logic_vector (7 DOWNTO 0)) ؛
نهاية mux
تغيير العمارة في muxVector IS
ابدأ
مع تحديد التبديل
الإخراج <= من ARU عند '0' ، من LOU عند الآخرين ؛
تغيير النهاية ؛
مكون ALU (aluComponent.vhd)
مكتبة ieee ؛ استخدم IEEE.STD_LOGIC_1164.all ؛ استخدم IEEE.NUMERIC_STD.all ؛
ENTITY alu مكون هو
إنهاء aluComponent ؛
مدخلات الهندسة المعمارية مكونات aluComponent IS
عنصر aru
PORT (المرجع 1: في std_logic_vector (7 DOWNTO 0) ؛
المرجع 2: في std_logic_vector (7 DOWNTO 0) ؛
العملية: IN std_logic_vector (3 DOWNTO 0) ؛
الدقة: OUT std_logic_vector (7 DOWNTO 0)) ؛
المكون النهائي
عنصر لو
PORT (المرجع 1: في std_logic_vector (7 DOWNTO 0) ؛
المرجع 2: في std_logic_vector (7 DOWNTO 0) ؛
العملية: IN std_logic_vector (3 DOWNTO 0) ؛
الدقة: OUT std_logic_vector (7 DOWNTO 0)) ؛
المكون النهائي
عنصر muxVector
PORT (من ARU: IN std_logic_vector (7 DOWNTO 0) ؛
fromLOU: في std_logic_vector (7 DOWNTO 0) ؛
التبديل: IN std_logic ؛
الإخراج: خارج std_logic_vector (7 DOWNTO 0)) ؛
المكون النهائي
خرج الإشارة ARU: std_logic_vector (7 DOWNTO 0) ؛
SIGNAL outputLOU: std_logic_vector (7 DOWNTO 0) ؛
تبديل الإشارة: std_logic ؛
عملية الإشارة: std_logic_vector (3 DOWNTO 0) ؛
خرج الإشارة: std_logic_vector (7 DOWNTO 0) ؛
الإشارة أ: std_logic_vector (7 DOWNTO 0) ؛
الإشارة ب: std_logic_vector (7 DOWNTO 0) ؛
ابدأ
u0: خريطة منفذ aru (A ، B ، عملية ، ARU مخرج) ؛
u1: lou PORT MAP (A ، B ، عملية ، إخراج LOU) ؛
u2: muxVector PORT MAP (الإخراج ARU ، الإخراج LOU ، التبديل ، الإخراج) ؛
أ <= "00000011" بعد 0 نانو ثانية ، "00000111" بعد 5 نانو ثانية ، "00000111" بعد 10 نانو ثانية ، "00001001" بعد 15 نانو ثانية ، "00000000" بعد 20 نانو ثانية ، "00000101" بعد 25 نانو ثانية ، "00001111" بعد 30 ns ، "00000101" بعد 35 نانوثانية ؛
B <= "00000010" بعد 0 نانوثانية ، "00000100" بعد 5 نانو ثانية ، "00000010" بعد 10 نانو ثانية ، "00000011" بعد 15 نانو ثانية ، "00000100" بعد 20 نانو ثانية ، "00000110" بعد 25 نانو ثانية ، "00001111" بعد 30 ns ، "00000011" بعد 35 نانوثانية ؛
التبديل <= '1' بعد 0 ns ، '0 ′ بعد 5 ns ،' 1 ′ بعد 10 ns ، '0' بعد 15 ns ، '1 ′ بعد 20 ns ،' 0 ′ بعد 25 ns ، '1 ′ بعد 30 ns ، '0 ′ بعد 35 نانوثانية ،' 1 ′ بعد 40 نانوثانية ؛
معالجة <= "0000" بعد 0 نانوثانية ، "0001" بعد 5 نانوثانية ، "0010" بعد 10 نانوثانية ، "0011" بعد 15 نانوثانية ، "0100" بعد 20 نانوثانية ، "0101" بعد 25 نانوثانية ، "0110" بعد 30 نانوثانية ؛
END المدخلات_aluComponent ؛
لكي لا نضيع الوقت في تجميع الأمر بأمر أثناء العمل في البرنامج ، نقوم بحفظ ملف يسمى compilar.sh بالمحتوى التالي في نفس المجلد:
ghdl -a lou.vhd && ghdl -a aru.vhd && ghdl -a muxVector.vhd && ghdl -a aluComponente.vhd && ghdl -e aluComponente && ghdl -r aluComponent --vcd = alu & componente.wave
افتح محطة ، أدخل المجلد وقم بتشغيل البرنامج النصي:
cd / home / user / vhdl sh compile.sh
إذا لم تكن هناك أخطاء ، فسيفتح gtkwave ويمكننا رؤية الإشارات:
كانت هذه الأدوات مفيدة جدًا وأسهل في الاستخدام من الأدوات الاحتكارية التي نستخدمها في الفصل ، والتي يستغرق تجميعها وقتًا طويلاً بشكل مثير للريبة. مع ghdl ، يستغرق تبديل النوافذ وقتًا أطول من التحويل.
مزيد من المعلومات حول VHDL
لأولئك الجدد على vhdl ، هنا لديهم مثال أساسي لمنكر.
مثال على فيديو:
http://www.youtube.com/watch?v=feVMXsyLSOU
تذكر أن أحدث إصدارات Ubuntu لا تحتوي على GHDL في مستودعاتها. يمكن تنزيل هذا لنظام التشغيل Linux / Windows من صفحة المشروع:
http://ghdl.free.fr/site/pmwiki.php?n=Main.Download
هل هناك أي طريقة تعطيك بها GTKWave دائرة البوابة التي تمثلها؟