هل كان لديك سؤال "كيف يعمل المعالج؟". نعم ، نعم ، بالضبط تلك الموجودة في جهاز الكمبيوتر / الكمبيوتر المحمول / الهاتف الذكي. في هذه المقالة ، أريد أن أعطي مثالاً على معالج اخترع ذاتيًا بتصميم في Verilog. Verilog ليست بالضبط لغة البرمجة التي تبدو عليها. هذه هي لغة وصف الأجهزة. لا يتم تنفيذ الشفرة المكتوبة بأي شيء (ما لم تقم بتشغيلها في المحاكي ، بالطبع) ، ولكنها تتحول إلى تصميم الدائرة المادية ، أو في الشكل الذي تدركه FPGA (صفيف بوابة قابلة للبرمجة الميدانية).
إخلاء المسؤولية: هذه المقالة هي نتيجة للعمل على مشروع في الجامعة ، لذلك كان وقت العمل محدودًا وما زالت أجزاء كثيرة من المشروع في المرحلة الأولى من التطوير فقط.
يرجى ملاحظة أن المعالج الذي تم إنشاؤه في هذه المقالة ليس لديه الكثير من القواسم المشتركة مع المعالجات واسعة الانتشار الحديثة ، لكنني حاولت تحقيق هدف مختلف قليلاً من خلال إنشائه.
لفهم عملية البرمجة حقًا ، يجب أن تتخيل كيف تعمل كل أداة من الأدوات المستخدمة: مترجم / مترجم للغة ، آلة افتراضية ، إن وجدت ، رمز وسيط ، وبالطبع المعالج نفسه. في كثير من الأحيان يكون الأشخاص الذين يدرسون البرمجة في المرحلة الأولى لفترة طويلة - يفكرون فقط في كيفية عمل اللغة ومترجمها. غالبًا ما يؤدي ذلك إلى أخطاء لا يعرف المبرمج المبتدئ حلولها ، لأنه ليس لديه فكرة عن مصدر جذور هذه المشاكل. رأيت بنفسي العديد من الأمثلة الحية حيث كان الموقف يشبه الوصف أعلاه ، لذلك قررت أن أحاول إصلاح هذا الموقف وإنشاء مجموعة من الأشياء التي ستساعد المبتدئين على فهم جميع الخطوات.
تتكون هذه المجموعة من:
- فعلا اخترع لغة
- تسليط الضوء على البرنامج المساعد VS Code
- مترجم إليها
- مجموعة التعليمات
- معالج بسيط قادر على تنفيذ هذه المجموعة من التعليمات (مكتوب في Verilog)
أذكرك مرة أخرى أن هذه المقالة لا تصف أي شيء مماثل لمعالج حقيقي حديث ، فهي تصف نموذجًا يسهل فهمه دون الدخول في التفاصيل.
الأشياء التي ستحتاجها إذا كنت ترغب في القيام بذلك بنفسك:
لتشغيل محاكاة وحدة المعالجة المركزية ، تحتاج إلى ModelSim ، والذي يمكنك تنزيله من موقع Intel.
لتشغيل مترجم OurLang ، تحتاج إلى إصدار Java> = 8.
روابط لمشاريع:
https://github.com/IamMaxim/OurCPU
https://github.com/IamMaxim/OurLang
ملحق:
https://github.com/IamMaxim/ourlang-vscode
لبناء جزء فيريلوج ، عادة ما أستخدم سكربت باش:
#/bin/bash vlib work vlog *.v vsim -c testbench_1 -do "run; exit"
ولكن يمكن تكرار ذلك من خلال واجهة المستخدم الرسومية.
من الملائم استخدام Intellij IDEA للعمل مع المترجم. الشيء الرئيسي هو تتبع الوحدات التي تحتاجها الوحدة في التبعيات. لم أنشر ملف .jar الجاهز لفتح الوصول ، لأنني أتوقع أن يقرأ القارئ الكود المصدري للمترجم.
الوحدات التي تم إطلاقها هي مترجم ومترجم. كل شيء واضح مع المترجم ، المترجم هو مجرد محاكاة لـ OurCPU في Java ، لكننا لن نعتبره في هذه المقالة.
مجموعة التعليمات
أعتقد أنه من الأفضل البدء بمجموعة التعليمات.
هناك العديد من معماريات مجموعة التعليمات:
- المكدس هو ما تم وصفه في المقالة. السمة المميزة هي أن جميع المعاملات يتم دفعها إلى المكدس وتبرزها من المكدس ، مما يستبعد على الفور إمكانية موازاة التنفيذ ، ولكنه أحد أبسط الأساليب للعمل مع البيانات.
- قائم على المركم - خلاصة القول هي أنه لا يوجد سوى سجل واحد يخزن قيمة يتم تعديلها عن طريق التعليمات.
- القائم على التسجيل هو ما يتم استخدامه في المعالجات الحديثة ، لأنه يسمح لك بتحقيق أقصى أداء من خلال استخدام العديد من التحسينات ، بما في ذلك موازاة التنفيذ ، وخط الأنابيب ، وما إلى ذلك.
تحتوي مجموعة تعليمات المعالج على 30 تعليمات
بعد ذلك ، أقترح إلقاء نظرة على تنفيذ المعالج:
يتكون الرمز من عدة وحدات:
- وحدة المعالجة المركزية
- ذاكرة الوصول العشوائي
- وحدات لكل تعليمات
ذاكرة الوصول العشوائي هي وحدة تحتوي مباشرة على الذاكرة نفسها ، بالإضافة إلى طريقة للوصول إلى البيانات الموجودة فيها.
CPU - وحدة تحكم مباشرة في تقدم البرنامج: قراءة التعليمات ، نقل التحكم إلى التعليمات المطلوبة ، تخزين السجلات اللازمة (مؤشر للتعليمات الحالية ، إلخ).
تعمل جميع التعليمات تقريبًا مع المكدس فقط ، لذا اتبعها فقط. تحتوي بعض (مثل putw و putb و jmp و jif) على حجة إضافية في التعليمات نفسها. يحتاجون إلى تمرير التعليمات بالكامل حتى يتمكنوا من قراءة البيانات اللازمة.
فيما يلي مخطط عام لكيفية عمل المعالج:

المبادئ العامة لتصميم الجهاز على مستوى التعليم
أعتقد أن الوقت قد حان للتعرف على الجهاز مباشرة من البرامج نفسها. كما ترى من الرسم البياني أعلاه ، بعد كل تعليمات ، ينتقل العنوان إلى التالي. هذا يعطي دورة خطية للبرنامج. عندما يصبح من الضروري كسر هذه الخطية (الشرط ، الحلقة ، إلخ) ، يتم استخدام تعليمات الفرع (في مجموعة التعليمات لدينا هذه هي jmp و jif).
عند استدعاء الوظائف ، نحتاج إلى حفظ الحالة الحالية لكل شيء ، ولهذا توجد سجلات تنشيط - سجلات تخزن هذه المعلومات. لا ترتبط بالمعالج أو التعليمات بأي شكل من الأشكال ، إنه مجرد مفهوم يستخدمه المترجم عند إنشاء التعليمات البرمجية. يحتوي سجل التفعيل في OurLang على الهيكل التالي:

كما يتبين من هذا الرسم التخطيطي ، يتم أيضًا تخزين المتغيرات المحلية في سجل التنشيط ، والذي يسمح لك بحساب عنوان المتغير في الذاكرة في وقت الترجمة ، بدلاً من وقت التشغيل ، وبالتالي تسريع تنفيذ البرنامج.
بالنسبة للمكالمات الوظيفية ، توفر مجموعة التعليمات الخاصة بنا طرقًا للعمل مع اثنين من السجلات الموجودة في وحدة CPU (مؤشر التشغيل ومؤشر عنوان التنشيط) - putopa / popopa ، putara / popara.
المترجم
الآن دعونا نلقي نظرة على الجزء الأقرب إلى المبرمج النهائي - المترجم. بشكل عام ، يتكون المترجم كبرنامج من 3 أجزاء:
المُسؤول مسؤول عن ترجمة الكود المصدري للبرنامج إلى وحدات معجمية يفهمها المحلل اللغوي.
يقوم المحلل ببناء شجرة بناء مجردة من هذه الوحدات المعجمية.
يمر المجمع من خلال هذه الشجرة ويولد نوعًا من التعليمات البرمجية التي تتكون من تعليمات ذات مستوى منخفض. يمكن أن يكون هذا إما رمزًا ثانويًا أو رمزًا ثنائيًا جاهزًا ليتم تنفيذه بواسطة المعالج.
في مترجم OurLang ، يتم تمثيل هذه الأجزاء على التوالي من خلال الفئات
- Lexer.java
- محلل جافا
- مترجم. جافا
اللغة
إن OurLang في مهدها ، أي أنها تعمل ، ولكن حتى الآن لا توجد أشياء كثيرة فيها وحتى الجزء الأساسي من اللغة لم يتم الانتهاء منه. ولكن لفهم جوهر المترجم ، فإن الحالة الراهنة كافية.
كمثال لبرنامج لفهم بناء الجملة ، يُقترح جزء التعليمات البرمجية هذا (يستخدم أيضًا لاختبار الوظائف):
// single-line comments /* * Multi-line comments */ function print(int arg) { instr(putara, 0); instr(putw, 4); instr(add, 0); instr(lw, 0); instr(printword, 0); } function func1(int arg1, int arg2): int { print(arg1); print(arg2); if (arg1 == 0) { return arg2; } else { return func1(arg1 - 1, arg2); }; } function main() { var i: int; i = func1(1, 10); if (i == 0) { i = 1; } else { i = 2; }; print(i); }
لن أركز على اللغة ، سأتركها لدراستك. من خلال رمز المترجم ، بالطبع ؛).
عند كتابتها ، حاولت عمل كود شرح ذاتي واضح بدون تعليق ، لذلك يجب ألا تكون هناك مشكلة في فهم كود المترجم.
حسنًا ، بالطبع ، الشيء الأكثر إثارة للاهتمام هو كتابة التعليمات البرمجية ، ثم مشاهدة ما يتحول إليه. لحسن الحظ ، يولد مترجم OurLang رمزًا يشبه التجميع مع التعليقات ،
مما يساعد على عدم الخلط بين ما يحدث في الداخل.
أوصي أيضًا بتثبيت ملحق Visual Studio Code ، وسوف يسهل العمل مع اللغة.
حظا سعيدا في تعلم المشروع!