مشروع | رابعا شركة نفط الجنوب مكتوبة في VHDL |
---|---|
مؤلف | ريتشارد جيمس هاو |
حقوق الطبع والنشر | 2013-2019 ريتشارد هاو |
رخصة | معهد ماساتشوستس للتكنولوجيا / LGPL |
بريد إلكتروني | [email protected] |
يطبق هذا المشروع جهاز كمبيوتر صغير الحجم مصممًا لتنفيذ Forth استنادًا إلى وحدة المعالجة المركزية J1. تمت إعادة كتابة المعالج بتنسيق VHDL من شركة Verilog، وتم تمديده قليلاً.
أهداف المشروع هي كما يلي:
وقد تم الانتهاء من كل ثلاثة منها.
معالج H2، مثل J1، عبارة عن معالج قائم على المكدس يقوم بتنفيذ مجموعة تعليمات مناسبة بشكل خاص لـ FORTH.
الهدف الحالي هو لوحة Nexys3، مع Xilinx Spartan-6 XC6LX16-CS324 FPGA، وسيتم استهداف لوحات جديدة في المستقبل حيث تصل هذه اللوحة إلى نهاية عمرها الافتراضي. تتم كتابة VHDL بطريقة عامة، مع استنتاج مكونات الأجهزة بدلاً من إنشاء مثيل لها بشكل صريح، وهذا من شأنه أن يجعل التعليمات البرمجية محمولة إلى حد ما، على الرغم من أن الواجهات الخاصة بمكونات لوحة Nexys3 خاصة بالأجهزة الطرفية الموجودة على تلك اللوحة.
يمكن مشاهدة مقطع فيديو للمشروع قيد التنفيذ، على الأجهزة، هنا:
يمكن أيضًا محاكاة SoC باستخدام محاكي مكتوب بلغة C، كما هو موضح أدناه:
بنية النظام هي كما يلي:
التراخيص المستخدمة من قبل المشروع مختلطة وهي على أساس كل ملف. بالنسبة للكود الخاص بي، أستخدم ترخيص MIT - لذا لا تتردد في استخدامه كما يحلو لك. التراخيص الأخرى المستخدمة هي LGPL وترخيص Apache 2.0، وهي تقتصر على وحدات فردية لذا يمكن إزالتها إذا كان لديك بعض النفور من كود LGPL.
لوحة الهدف الوحيدة المتاحة في الوقت الحالي هي Nexys3، ومن المفترض أن يتغير هذا في المستقبل نظرًا لأن اللوحة حاليًا في نهاية عمرها الافتراضي. اللوحات التالية التي أتطلع إلى دعمها هي خليفتها، Nexys 4، وmyStorm BlackIce (https://mystorm.uk/). تستخدم لوحة myStorm سلسلة أدوات مفتوحة المصدر بالكامل للتوليف والمكان والتوجيه وإنشاء ملفات البت.
تم اختبار البنية تحت نظام Debian Linux، الإصدار 8.
سوف تحتاج إلى:
الأجهزة:
يمكن (أو يمكن) تنزيل Xilinx ISE مجانًا، ولكنه يتطلب التسجيل. يجب أن يكون ISE في طريقك:
PATH=$PATH:/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64;
PATH=$PATH:/opt/Xilinx/14.7/ISE_DS/ISE/lib/lin64;
لإنشاء سلسلة أدوات تعتمد على لغة C:
make embed.hex
لإنشاء ملف بت يمكن وميضه على اللوحة المستهدفة:
make simulation synthesis implementation bitfile
لتحميل ملف bitfile إلى اللوحة المستهدفة:
make upload
لعرض شكل الموجة الناتج عن "إجراء المحاكاة":
make viewer
يمكن استدعاء محاكي CLI المعتمد على لغة C باستخدام:
make run
والذي سيقوم بتجميع ملف المصدر H2 Forth embed.fth، وتشغيل ملف الكائن المجمع ضمن محاكي H2 مع تنشيط مصحح الأخطاء. يمكن تشغيل المحاكي الرسومي باستخدام:
make gui-run
الأمر الذي يتطلب freeglut بالإضافة إلى مترجم C.
مشروع J1 الأصلي متاح في:
يستهدف هذا المشروع نواة J1 الأصلية ويوفر تطبيق eForth (مكتوب باستخدام Gforth كما هو الحال في التجميع الفوقي/التجميع المتقاطع إلى نواة J1). كما يوفر أيضًا محاكيًا للنظام المكتوب بلغة C.
يمكن العثور على مترجم eForth الذي تم بناء المترجم التعريفي عليه على:
أصبح معالج H2 والأجهزة الطرفية المرتبطة به الآن مستقرًا تمامًا، ولكن المصدر دائمًا هو الدليل النهائي لكيفية تصرف التعليمات والأجهزة الطرفية، بالإضافة إلى خريطة التسجيل.
هناك بعض التعديلات على وحدة المعالجة المركزية J1 والتي تشمل:
تتصرف وحدة المعالجة المركزية H2 بشكل مشابه جدًا لوحدة المعالجة المركزية J1، ويمكن قراءة ملف J1 PDF لفهم هذا المعالج بشكل أفضل. المعالج 16 بت مع تعليمات تأخذ دورة ساعة واحدة. يمكن أيضًا تنفيذ معظم كلمات Forth البدائية في دورة واحدة أيضًا، والاستثناء الوحيد الملحوظ هو المتجر ("!")، والذي ينقسم إلى تعليمتين.
تحتوي وحدة المعالجة المركزية على الحالة التالية بداخلها:
يقوم التحميل والتخزين في كتلة ذاكرة الوصول العشوائي (RAM) التي تحتوي على برنامج H2 بتجاهل البت الأدنى، وكل عملية ذاكرة أخرى تستخدم البت الأقل (مثل القفزات والتحميل والتخزين في الأجهزة الطرفية للإدخال/الإخراج). وذلك حتى تتمكن التطبيقات من استخدام أقل بت لعمليات الأحرف عند الوصول إلى ذاكرة الوصول العشوائي الخاصة بالبرنامج.
يتم فك تشفير مجموعة التعليمات بالطريقة التالية:
+---------------------------------------------------------------+
| F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+---------------------------------------------------------------+
| 1 | LITERAL VALUE |
+---------------------------------------------------------------+
| 0 | 0 | 0 | BRANCH TARGET ADDRESS |
+---------------------------------------------------------------+
| 0 | 0 | 1 | CONDITIONAL BRANCH TARGET ADDRESS |
+---------------------------------------------------------------+
| 0 | 1 | 0 | CALL TARGET ADDRESS |
+---------------------------------------------------------------+
| 0 | 1 | 1 | ALU OPERATION |T2N|T2R|N2A|R2P| RSTACK| DSTACK|
+---------------------------------------------------------------+
| F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+---------------------------------------------------------------+
T : Top of data stack
N : Next on data stack
PC : Program Counter
LITERAL VALUES : push a value onto the data stack
CONDITIONAL : BRANCHS pop and test the T
CALLS : PC+1 onto the return stack
T2N : Move T to N
T2R : Move T to top of return stack
N2A : STORE T to memory location addressed by N
R2P : Move top of return stack to PC
RSTACK and DSTACK are signed values (twos compliment) that are
the stack delta (the amount to increment or decrement the stack
by for their respective stacks: return and data)
تحل جميع عمليات ALU محل T:
قيمة | عملية | وصف |
---|---|---|
0 | ت | أعلى المكدس |
1 | ن | انسخ T إلى N |
2 | ت + ن | إضافة |
3 | تي & ن | Bitwise AND |
4 | ممزق | Bitwise أو |
5 | ت ^ ن | XOR بالبت |
6 | ~ت | انعكاس البت |
7 | تي = ن | اختبار المساواة |
8 | ن <ت | المقارنة الموقعة |
9 | ن >> ت | التحول الصحيح المنطقي |
10 | ت - 1 | إنقاص |
11 | ر | أعلى كومة العودة |
12 | [ت] | تحميل من العنوان |
13 | ن << ت | التحول المنطقي لليسار |
14 | عمق | عمق المكدس |
15 | ن ش< ت | مقارنة غير موقعة |
16 | ضبط حالة وحدة المعالجة المركزية | تمكين المقاطعات |
17 | الحصول على حالة وحدة المعالجة المركزية | هل المقاطعات قيد التشغيل؟ |
18 | rالعمق | عمق العودة ستك |
19 | 0= | ت ==0؟ |
20 | معرف وحدة المعالجة المركزية | معرف وحدة المعالجة المركزية |
21 | حرفي | التعليمات الداخلية |
السجلات التي تحمل البادئة "o" هي سجلات الإخراج، وتلك التي لها البادئة "i" هي سجلات الإدخال. تنقسم السجلات إلى قسم الإدخال والإخراج من السجلات ولا تتوافق عناوين سجلات الإدخال والإخراج مع بعضها البعض في جميع الحالات.
تم تنفيذ الأجهزة الطرفية التالية في VHDL SoC للتفاعل مع الأجهزة الموجودة على لوحة Nexys3:
تتميز SoC أيضًا بمجموعة محدودة من المقاطعات التي يمكن تمكينها أو تعطيلها.
خريطة تسجيل الإخراج:
يسجل | عنوان | وصف |
---|---|---|
oUart | 0x4000 | سجل UART |
oVT100 | 0x4002 | الكتابة الطرفية VT100 |
أوليدز | 0x4004 | مخرجات LED |
oTimerCtrl | 0x4006 | التحكم في الموقت |
oMemDout | 0x4008 | إخراج بيانات الذاكرة |
oMemControl | 0x400A | التحكم في الذاكرة / عنوان مرحبا |
oMemAddrLow | 0x400C | عنوان الذاكرة لو |
o7SegLED | 0x400E | 4 × شاشة LED 7 قطاعات |
oIrcMask | 0x4010 | قناع مقاطعة وحدة المعالجة المركزية |
oUartBaudTx | 0x4012 | إعداد ساعة UART Tx Baud |
oUartBaudRx | 0x4014 | إعداد ساعة الباود UART Rx |
سجلات الإدخال:
يسجل | عنوان | وصف |
---|---|---|
iUart | 0x4000 | سجل UART |
iVT100 | 0x4002 | حالة المحطة الطرفية ولوحة المفاتيح PS/2 |
iSwitches | 0x4004 | الأزرار والمفاتيح |
iTimerDin | 0x4006 | قيمة الموقت الحالي |
iMemDin | 0x4008 | إدخال بيانات الذاكرة |
يجب قراءة الوصف التالي للسجلات بالترتيب ووصف كيفية عمل الأجهزة الطرفية أيضًا.
يوجد UART بمعدل باود ثابت وتنسيق (115200، 8 بت، 1 بت توقف) في SoC. يحتوي UART على FIFO بعمق 8 على كل من قنوات RX وTX. يتم تقسيم التحكم في UART عبر oUart وiUart.
لكتابة قيمة إلى UART، قم بتأكيد TXWE مع وضع البيانات في TXDO. يمكن تحليل حالة FIFO من خلال النظر في سجل iUart.
لقراءة قيمة من UART: يمكن التحقق من iUart لمعرفة ما إذا كانت البيانات موجودة في FIFO، وإذا تم تأكيد RXRE في سجل oUart، ففي دورة الساعة التالية ستكون البيانات موجودة في سجل iUart.
يمكن تغيير معدل الباود الخاص بـ UART عن طريق إعادة بناء مشروع VHDL، ولا يمكن تغيير طول البت وبتات التكافؤ وبتات التوقف إلا من خلال تعديلات على uart.vhd
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X |TXWE| X | X |RXRE| X | X | TXDO |
+-------------------------------------------------------------------------------+
TXWE: UART TX Write Enable
RXRE: UART RX Read Enable
TXDO: UART TX Data Output
يحاكي جهاز VGA Text محطة يمكن للمستخدم التحدث إليها عن طريق الكتابة إلى سجل oVT100. وهو يدعم مجموعة فرعية من وظائف محطة VT100. تتصرف الواجهة بشكل يشبه إلى حد كبير الكتابة إلى UART بنفس إشارات الانشغال والتحكم. يتم أخذ الإدخال من لوحة مفاتيح PS/2 المتوفرة على اللوحة، والتي تتصرف مثل آلية RX الخاصة بـ UART.
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X |TXWE| X | X |RXRE| X | X | TXDO |
+-------------------------------------------------------------------------------+
TXWE: VT100 TX Write Enable
RXRE: UART RX Read Enable
TXDO: UART TX Data Output
يوجد على لوحة Nexys3 مجموعة من مصابيح LED الموجودة بجوار المفاتيح، ويمكن تشغيل مصابيح LED هذه (1) أو إيقاف تشغيلها (0) عن طريق الكتابة إلى LEDO. يتوافق كل مؤشر LED هنا مع المفتاح الموجود بجواره.
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X | X | X | X | X | X | X | LEDO |
+-------------------------------------------------------------------------------+
LEDO: LED Output
يمكن التحكم في المؤقت من خلال سجل oTimerCtrl، وهو مؤقت 13 بت يعمل بسرعة 100 ميجا هرتز، ويمكنه بشكل اختياري إنشاء مقاطعات ويمكن قراءة العدد الداخلي للمؤقتات الحالية مرة أخرى باستخدام سجل iTimerDin.
يتم حساب المؤقت بمجرد تأكيد بت TE، وبمجرد وصول المؤقت إلى قيمة TCMP، فإنه يلتف حوله ويمكنه اختياريًا إنشاء مقاطعة عن طريق تأكيد INTE. يؤدي هذا أيضًا إلى تبديل خطوط Q وNQ التي تخرج من المؤقت ويتم توجيهها إلى الدبابيس الموجودة على اللوحة (راجع ملف القيود top.ucf للتعرف على الدبابيس).
يمكن إعادة ضبط المؤقت عن طريق الكتابة إلى RST.
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| TE | RST|INTE| TCMP |
+-------------------------------------------------------------------------------+
TE: Timer Enable
RST: Timer Reset
INTE: Interrupt Enable
TCMP: Timer Compare Value
يحتوي قلب H2 على آلية للمقاطعات، ويجب تمكين المقاطعات أو تعطيلها باستخدام تعليمات. يمكن إخفاء كل مقاطعة باستخدام جزء صغير من IMSK لتمكين تلك المقاطعة المحددة. يعمل الرقم "1" في جزء من IMSK على تمكين تلك المقاطعة المحددة، والتي سيتم تسليمها إلى وحدة المعالجة المركزية إذا تم تمكين المقاطعات داخلها.
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X | X | X | X | X | X | X | IMSK |
+-------------------------------------------------------------------------------+
IMSK: Interrupt Mask
يُستخدم هذا السجل لضبط تردد ساعة الباود وعينة الإرسال فقط.
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| BTXC |
+-------------------------------------------------------------------------------+
BTXC: Baud Clock Settings
يُستخدم هذا السجل لضبط تردد ساعة الباود وعينة الاستقبال فقط.
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| BRXC |
+-------------------------------------------------------------------------------+
BRXC: Baud Clock Settings
سيتم إخراج البيانات إلى العنوان المحدد عند تمكين الكتابة (WE) الصادر في oMemControl.
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| Data Ouput |
+-------------------------------------------------------------------------------+
يحتوي هذا السجل على سجلات التحكم الخاصة بالذاكرة الموجودة على لوحة Nexys3. تحتوي اللوحة على ثلاثة أجهزة ذاكرة وجهازين للذاكرة غير المتطايرة وجهاز يعتمد على ذاكرة الوصول العشوائي المتطايرة. يمكن الوصول إلى الجهازين من خلال واجهة SRAM بسيطة (أحدهما متطاير M45W8MW16، والآخر غير متطاير - NP8P128A13T1760E) ويمكن الوصول إليهما، والثالث هو جهاز ذاكرة قائم على SPI، NP5Q128A13ESFC0E) ولا يمكن الوصول إليه حاليًا.
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| OE | WE | RST|WAIT| RCS| FCS| Address Hi |
+-------------------------------------------------------------------------------+
OE: Output Enable - enable reading from current address into iMemDin
WE: Write Enable - enable writing oMemDout into ram at current address
RST: Reset the Flash memory controller
RCS: RAM Chip Select, Enable Volatile Memory
FCS: Flash Chip Select, Enable Non-Volatile Memory
Address Hi: High Bits of RAM address
OE وWE متنافيان، إذا تم تعيين كلاهما فلن يكون هناك أي تأثير.
وحدة التحكم في الذاكرة قيد التطوير النشط، وقد تتغير الواجهة الخاصة بها.
هذه هي بتات العنوان السفلية لذاكرة الوصول العشوائي.
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| Address Lo |
+-------------------------------------------------------------------------------+
يوجد على لوحة Nexys3 مجموعة من 7 شرائح، مع علامة عشرية (8 قطع حقًا)، والتي يمكن استخدامها للإخراج الرقمي. لا يمكن معالجة قطاعات LED مباشرة. بدلاً من ذلك، يتم تعيين القيمة المخزنة في L8SD إلى قيمة عرض سداسية عشرية (أو قيمة BCD، ولكن هذا يتطلب تجديد SoC وتعديل قيمة عامة في VHDL).
تتوافق القيمة "0" مع الصفر المعروض على مقطع LED، و"15" إلى "F"، وما إلى ذلك.
هناك 4 شاشات على التوالي.
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| L7SD0 | L7SD1 | L7SD2 | L7SD3 |
+-------------------------------------------------------------------------------+
L7SD0: LED 7 Segment Display (leftmost display)
L7SD1: LED 7 Segment Display
L7SD2: LED 7 Segment Display
L7SD3: LED 7 Segment Display (right most display)
يعمل سجل iUart جنبًا إلى جنب مع سجل oUart. تتوفر حالة FIFO التي تخزن مؤقتًا كلاً من إرسال واستقبال البايتات في سجل iUart، بالإضافة إلى أي بايتات مستلمة.
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X | X |TFFL|TFEM| X |RFFL|RFEM| RXDI |
+-------------------------------------------------------------------------------+
TFFL: UART TX FIFO Full
TFEM: UART TX FIFO Empty
RFFL: UART RX FIFO Full
RFEM: UART RX FIFO Empty
RXDI: UART RX Data Input
يعمل سجل iVT100 جنبًا إلى جنب مع سجل oVT100. تتوفر حالة FIFO التي تخزن مؤقتًا كلاً من إرسال واستقبال البايتات في سجل iVT100، بالإضافة إلى أي بايتات مستلمة. إنه يعمل بنفس طريقة تسجيلات iUart/oUart.
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X | X |TFFL|TFEM| X |RFFL|RFEM| 0 | ACHR |
+-------------------------------------------------------------------------------+
TFFL: VGA VT100 TX FIFO Full
TFEM: VGA VT100 TX FIFO Empty
RFFL: PS2 VT100 RX FIFO Full
RFEM: PS2 VT100 RX FIFO Empty
ACHR: New character available on PS2 Keyboard
يحتوي هذا السجل على القيمة الحالية لعداد المؤقتات.
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X | X | TCNT |
+-------------------------------------------------------------------------------+
TCNT: Timer Counter Value
يحتوي iSwitches على خطوط إدخال من مصادر متعددة. تتوافق الأزرار (BUP، وBDWN، وBLFT، وBRGH، وBCNT) مع لوحة D-Pad الموجودة على لوحة Nexys3. المفاتيح (TSWI) هي تلك المذكورة في شاشات OLED، ولكل منها مصباح LED بجانبها.
لقد تم بالفعل إلغاء المفاتيح والأزرار في الأجهزة، لذا لا يلزم معالجتها بشكل أكبر بمجرد قراءتها من هذه السجلات.
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| X | X | X | BUP|BDWN|BLFT|BRGH|BCNT| TSWI |
+-------------------------------------------------------------------------------+
BUP: Button Up
BDWN: Button Down
BLFT: Button Left
BRGH: Button Right
BCNT: Button Center
TSWI: Two Position Switches
إدخال الذاكرة، إما من SRAM أو Flash، مفهرسة بواسطة oMemControl وoMemAddrLow. عند القراءة من الفلاش، قد تكون هذه في الواقع معلومات حالة أو معلومات من جدول الاستعلام.
+-------------------------------------------------------------------------------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+-------------------------------------------------------------------------------+
| Data Input |
+-------------------------------------------------------------------------------+
يتم تعريف إجراءات خدمة المقاطعة التالية:
اسم | رقم | وصف |
---|---|---|
isrNone | 0 | غير مستخدم |
isrxFifoNotEmpty | 1 | UART RX FIFO ليس فارغًا |
isrRxFifoFull | 2 | UART RX FIFI ممتلئ |
isrTxFifoNotEmpty | 3 | UART TX FIFO ليس فارغًا |
isrTxFifoFull | 4 | UART TX FIFO ممتلئ |
isrKbdNew | 5 | شخصية جديدة للوحة المفاتيح PS/2 |
com.isrTimer | 6 | عداد الموقت |
isrDPadButton | 7 | أي حالة تغيير زر D-Pad |
عند حدوث مقاطعة، ويتم تمكين المقاطعات داخل المعالج، يتم إجراء اتصال بالموقع في الذاكرة - الموقع هو نفس رقم ISR. سيقوم ISR ذو الرقم "4" بإجراء مكالمة (وليس قفزة) إلى الموقع "4" داخل الذاكرة، على سبيل المثال.
تتمتع المقاطعات بزمن انتقال لا يقل عن 4-5 دورات قبل أن يتم التصرف بناءً عليها، ويوجد تأخير من دورتين إلى ثلاث دورات في معالج طلب المقاطعة، ثم يجب إجراء الاتصال بموقع ISR في الذاكرة، ثم الاتصال بـ الكلمة التي تنفذ ISR نفسها.
في حالة حدوث مقاطعتين في نفس الوقت، تتم معالجتهما من رقم المقاطعة الأدنى إلى الأعلى.
يتم فقدان المقاطعات عند حدوث مقاطعة بنفس الرقم ولم تتم معالجتها.
يوجد جهاز محاكاة Disassembler وC لـ H2 في برنامج واحد (انظر h2.c). تكمل هذه المحاكاة منصة اختبار VHDL tb.vhd وليست بديلاً عنها. يعمل المترجم التعريفي أعلى مترجم eForth وهو موجود داخل الملفات embed.c وembed.blk. المترجم الفوقي (لغة رابعة للمترجم المتقاطع) هو برنامج رابع يستخدم لإنشاء صورة eForth التي يتم تشغيلها على الهدف.
سلسلة الأدوات في حالة تغير مستمر حاليًا، ومن المحتمل أن يكون هناك المزيد من التكامل بين h2.c وembed.c، إلى جانب تغيير Embed Virtual Machine إلى جهاز يشبه إلى حد كبير وحدة المعالجة المركزية H2 مع الهدف طويل المدى المتمثل في إنشاء استضافة ذاتية نظام.
لبناء كليهما، هناك حاجة إلى مترجم C، وسيقوم هدف البناء "h2" ببناء الملف القابل للتنفيذ، وسيقوم h2 و "embed" ببناء المترجم التعريفي:
make h2 embed
ويمكن تشغيله على الملف المصدر embed.fth باستخدام هدف الإنشاء:
make run
ملف الصنع غير مطلوب:
Linux:
cc -std=c99 h2.c -o h2 # To build the h2 executable
cc -std=c99 embed.c -o embed # To build the embed VM executable
./embed embed.blk embed.hex embed.fth # Create the target eForth image
./h2 -h # For a list of options
./h2 -r embed.hex # Run the assembled file
Windows:
gcc -std=c99 h2.c -o h2.exe # Builds the h2.exe executable
gcc -std=c99 embed.c -o embed.exe # Builds the embed.exe executable
embed.exe embed.blk embed.hex embed.fth # Create the target eForth iamge
h2.exe -h # For a list of options
h2.exe -r embed.hex # Run the assembled file
قائمة خيارات سطر الأوامر المتاحة:
- stop processing options, following arguments are files
-h print a help message and exit
-v increase logging level
-d disassemble input files (default)
-D full disassembly of input files
-T Enter debug mode when running simulation
-r run hex file
-L # load symbol file
-s # number of steps to run simulation (0 = forever)
-n # specify NVRAM block file (default is nvram.blk)
file* file to process
تم إصدار هذا البرنامج بموجب ترخيص MIT، فلا تتردد في استخدامه وتعديله كما يحلو لك. مع الحد الأدنى من التعديل، ينبغي أن يكون قادرًا على تجميع البرامج لنواة J1 الأصلية.
يعمل المترجم التعريفي أعلى الجهاز الظاهري المضمن، وهو جهاز افتراضي 16 بت ينحدر في الأصل من وحدة المعالجة المركزية H2. يتضمن المشروع نظام تجميع ميتا يسمح لصورة eForth بإنشاء صورة eForth جديدة مع التعديلات. تم تكييف هذا النظام للاستخدام مع H2، والذي حل محل المترجم المتقاطع المكتوب بلغة C، والذي سمح بإنشاء الصورة الأولى لـ H2.
المترجم التعريفي هو برنامج Forth عادي، وهو موجود ضمن embed.fth. يتم بعد ذلك استخدام برنامج Forth للمترجم الفوقي لإنشاء صورة eForth قادرة على العمل على هدف H2.
لمزيد من المعلومات حول التجميع الفوقي في Forth، راجع:
يأخذ المفكك ملفًا نصيًا يحتوي على البرنامج المجمع، والذي يتكون من أرقام سداسية عشرية 16 بت. ومن ثم يحاول تفكيك التعليمات. يمكن أيضًا تغذيته بملف رموز يمكن إنشاؤه بواسطة المجمّع ومحاولة العثور على المواقع التي تشير إليها القفزات والاستدعاءات.
يتم استخدام المفكك بواسطة برنامج نصي tcl يسمى GTKwave، فهو يحول تتبع تعليمات H2 من سلسلة من الأرقام إلى التعليمات ووجهات الفروع التي تمثلها. وهذا يجعل تصحيح أخطاء VHDL أسهل بكثير.
يُظهر الأثر الأرجواني التعليمات المفككة.
يقوم جهاز المحاكاة في لغة C بتنفيذ نواة H2 ومعظم SoC. إن عملية الإدخال/الإخراج الخاصة بالمحاكي ليست دقيقة للدورة، ولكن يمكن استخدامها لتشغيل البرامج وتصحيح أخطائها مع الحصول على نتائج مشابهة جدًا لكيفية تصرف الأجهزة. يعد هذا أسرع بكثير من إعادة إنشاء ملف البت المستخدم لفلاش FPGA.
يتضمن جهاز المحاكاة أيضًا مصحح أخطاء، والذي تم تصميمه ليكون مشابهًا لبرنامج DEBUG.COM المتوفر في DOS. يمكن استخدام مصحح الأخطاء لتفكيك أجزاء من الذاكرة وفحص حالة الأجهزة الطرفية وتفريغ أقسام الذاكرة على الشاشة. يمكن استخدامه أيضًا لتعيين نقاط توقف وخطوة واحدة وتشغيل الكود حتى يتم الوصول إلى نقطة توقف.
لتشغيل مصحح الأخطاء، يجب توفير ملف سداسي عشري أو ملف مصدر:
# -T turns debugging mode on
./h2 -T -r file.hex # Run simulator
يمكن تعزيز كلا وضعي التشغيل بملف الرموز، الذي يسرد أماكن وجود المتغيرات والتسميات والوظائف مع المركز المجمع.
عندما يتم إعطاء خيار "-T"، سيتم إدخال وضع التصحيح قبل تنفيذ المحاكاة. يجب أن تظهر مطالبة ويجب أن يبدو سطر الأوامر كما يلي:
$ ./h2 -T -R h2.fth
Debugger running, type 'h' for a list of command
debug>
يمكن تعيين نقاط التوقف إما بشكل رمزي أو حسب موقع البرنامج، ويتم استخدام الأمر 'b' لتعيين نقاط التوقف:
يمكن إدخال الأرقام بالنظام الثماني (بادئة الرقم بـ "0") أو بالنظام الست عشري (بالبادئة بـ "0x") أو بالنظام العشري. على سبيل المثال، تقوم أوامر التصحيح الثلاثة التالية بتعيين نقطة توقف في نفس الموقع:
debug> b 16
debug> b 0x10
debug> b 020
يمكن استخدام "k" لسرد نقاط التوقف الحالية التي تم تعيينها:
debug> k
0x0010
يؤدي هذا إلى تعيين نقطة توقف عندما تكون الوظيفة "مفتاح؟" يسمى:
debug> b key?
يمكن إيقاف الوظائف والتسميات، وهذا يتطلب إما تحديد ملف رموز في سطر الأوامر أو تجميعه وتشغيله لاستخدامه في ملف مصدر، وليس ملفًا سداسيًا عشريًا. يمكن استخدام ملفات الرموز على الملفات المصدرية أو على الملفات السداسية.
يمكن إعطاء الأمر s لخطوة واحدة، على الرغم من أنه لن يحدث الكثير إذا تم إيقاف تشغيل التتبع (يتم إيقاف التتبع بشكل افتراضي). يمكن تشغيل التتبع أو إيقافه باستخدام الأمر 't':
debug> s
debug> s
debug> t
trace on
debug> s
0001: pc(089a) inst(4889) sp(0) rp(0) tos(0000) r(0000) call 889 init
debug> s
0002: pc(0889) inst(807a) sp(0) rp(1) tos(0000) r(089b) 7a
debug> s
0003: pc(088a) inst(e004) sp(1) rp(1) tos(007a) r(089b) 6004
يُنصح بإيقاف تشغيل التتبع عند تشغيل إصدار الأمر "c" أو المتابعة.
ال '.' يمكن استخدام الأمر لعرض الحالة الداخلية لنواة H2:
debug> .
Return Stack:
0000: 0000 08aa 0883 017b 0000 031b 0000 ffb0 0000 02eb ffb5 0210 0167 0167
0167 0167
0010: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000
Variable Stack:
tos: 0000
0001: 0000 0000 0000 0001 0004 0005 0000 ffb0 0000 0000 0000 0000 0000 0000
0000 0000
0011: 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
0000 0000
pc: 0538
rp: 0001
dp: 0000
ie: false
ويمكن استخدام الأمر "p" لعرض حالة الأجهزة الطرفية التي تمت محاكاتها:
debug> p
LEDS: 00
VGA Cursor: 0005
VGA Control: 007a
Timer Control: 8032
Timer: 001b
IRC Mask: 0000
UART Input: 6c
LED 7seg: 0005
Switches: 00
LFSR: 40ba
Waiting: false
للحصول على قائمة كاملة بالأوامر، استخدم الأمر "h".
تتضمن الطرق الأخرى للدخول إلى وضع تصحيح الأخطاء وضع توجيه المجمّع ".break" في التعليمات البرمجية المصدر (يعمل هذا فقط إذا تم استخدام أمر التجميع والتشغيل على الملفات المصدر، وليس على الملفات السداسية عشرية)، والضغط على حرف الهروب عندما يكون جهاز المحاكاة قيد التشغيل. محاولة قراءة البيانات عبر لوحة مفاتيح UART أو PS/2 المحاكية (سيتم تمرير الهروب إلى جهاز المحاكاة، ولكنه يقوم أيضًا بتنشيط وضع التصحيح).
يمكن تجميع برنامج منفصل واختباره تحت Linux و Windows. يحاكي هذا الأجهزة الطرفية للوحة Nexys3 التي تتعامل معها شركة SoC، ولكنه يوفر بيئة رسومية، على عكس الأداة المساعدة لسطر الأوامر. من الأسهل التفاعل مع الجهاز ومعرفة ما يفعله، لكن جلسات تصحيح الأخطاء تكون أقل تحكمًا. يتطلب وفرة مجانية.
فيما يلي صورة لجلسة قيد التشغيل في محاكي واجهة المستخدم الرسومية:
يمكن أن يتم البناء مع
make gui
والجري:
make gui-run
أو:
./gui h2.hex (on Linux)
gui.exe h2.hex (on Windows)
يجب أن يعمل إصدار Linux عندما يتم تثبيت حزمة التطوير للتخمة المجانية على نظامك، وقد يتطلب إصدار Windows إجراء تغييرات على نظام البناء و/أو التثبيت اليدوي للمترجم والمكتبات والرؤوس.
الخريطة الرئيسية الحالية هي:
Up Activate Up D-Pad Button, Release turns off
Down Activate Down D-Pad Button, Release turns off
Left Activate Left D-Pad Button, Release turns off
Right Activate Right D-Pad Button, Release turns off
F1 - F8 Toggle Switch On/Off, F1 is left most, F8 Right Most
F11 Toggle UART/PS2 Keyboard Input
F12 Toggle Debugging Information
Escape Quit simulator
تتم إعادة توجيه كافة مفاتيح لوحة المفاتيح الأخرى إلى إدخال لوحة المفاتيح UART أو PS/2.
يمكن النقر فوق أزرار Switches وD-Pad لتشغيلها، ويتم تشغيل المفاتيح بالنقرات اليسرى وإيقاف تشغيلها بالنقرات اليمنى. يتم تشغيل أزرار D-Pads بنقرة فوقها ويتم إيقاف تشغيلها بتحرير المفتاح في أي مكان على الشاشة.
تم تصميم مكونات VHDL المستخدمة في هذا النظام لتكون قابلة لإعادة الاستخدام ومحمولة عبر سلاسل الأدوات والبائعين المختلفين. يتم استنتاج مكونات الأجهزة، مثل كتلة ذاكرة الوصول العشوائي، ولا يتم إنشاء مثيل لها بشكل صريح. تم تصميم المكونات أيضًا لتكون عامة قدر الإمكان، مع توفر معظمها بعرض قابل للتحديد. قد يتم المبالغة في ذلك، ولكن لسوء الحظ لا يزال العديد من البائعين لا يدعمون معيار VHDL-2008.
ملف | رخصة | مؤلف | وصف |
---|---|---|---|
util.vhd | معهد ماساتشوستس للتكنولوجيا | ريتشارد جي هاو | مجموعة من المكونات العامة |
h2.vhd | معهد ماساتشوستس للتكنولوجيا | ريتشارد جي هاو | H2 رابعا وحدة المعالجة المركزية الأساسية |
uart.vhd | معهد ماساتشوستس للتكنولوجيا | ريتشارد جي هاو | UART TX/RX (وقت التشغيل قابل للتخصيص) |
vga.vhd | إل جي بي إل 3.0 | خافيير الخامس جارسيا | وضع النص شاشة VGA 80x40 |
ريتشارد جي هاو | (ومحاكي محطة VT100) | ||
kbd.vhd | ؟؟؟؟ | سكوت لارسون | لوحة مفاتيح بي اس/2 |
تم وصف اللغة الشبيهة باللغة الرابعة الزائفة المستخدمة كمجمع أعلاه، والتطبيق الذي يعمل فعليًا على نواة Forth هو في حد ذاته مترجم Forth. يصف هذا القسم المترجم Forth الذي يعمل على H2 Core، وهو موجود في embed.fth.
المهام:
هناك العديد من اللغات المستخدمة في هذا المشروع، وكلها تختلف جذريًا عن بعضها البعض وتتطلب مجموعة خاصة بها من معايير الترميز وأدلة الأسلوب.
أسماء الإشارة الشائعة:
clk - The system clock
rst - A reset signal for the module
we - Write Enable
re - Read Enable
di - Data In
din - Data In
do - Data Out
dout - Data Out
control - Generally an input to a register, the documentation
for the module will need to be consulted to find out
what each bit means
signal_we - The write enable for 'signal'
signal_i - This is an input signal
signal_o - This is an output signal
بشكل عام، لا يتم استخدام اللواحق "_i" و"_o"، ويتم الاحتفاظ بالوحدات قصيرة ويتم اختيار الأسماء بحيث يكون معناها واضحًا. يمكن إعادة النظر في هذه القاعدة بمجرد نمو المشروع.
ينبغي للمكونات:
constant N: positive := 4;
signal a: std_logic_vector(N - 1 downto 0) := (others => '1');
بدلاً من:
signal a: std_logic_vector(3 downto 0) := x"F";
قواعد النمط هي كما يلي:
مثال على إرشادات التنسيق، يصف سجل عرض عشوائي بسيط:
-- Lots of comments about what the unit does should go
-- here. Describe the waveforms, states and use ASCII
-- art where possible.
library ieee, work;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all; -- numeric_std not std_logic_arith
entity reg is -- generic and port indented one tab, their parameters two
generic (
N: positive); -- Generic parameters make for a generic component
port (
clk: in std_logic; -- standard signal names
rst: in std_logic; --
we: in std_logic;
di: in std_logic_vector(N - 1 downto 0);
do: out std_logic_vector(N - 1 downto 0)); -- note the position of ");
end entity; -- "end entity", not "end reg"
architecture rtl of reg is
signal r_c, r_n: std_logic_vector(N - 1 downto 0) := (others => '0');
begin
do <= r_c;
process(rst, clk)
begin
if rst = '1' then -- asynchronous reset
r_c <= (others => '0');
elsif rising_edge(clk) then -- rising edge, not "clk'event and clk = '1'"
r_c <= r_n;
end if;
end process;
process(r_c, di, we)
begin
r_n <= r_c;
if we = '1' then
r_n <= di;
end if;
end process;
end; -- "end" or "end architecture"
هناك الكثير من كود C المستخدم في هذا المشروع، والذي يستخدم لإنشاء سلسلة أدوات لنواة H2 ولمحاكاة النظام.
ليس هناك ما يثير الدهشة بشأن كود C هنا، لذا يجب التعامل مع بعض الاستثناءات.
static const char *alu_op_to_string(uint16_t instruction) {
/* notice also that the 'case' clauses are inline with the
* switch selector */
switch (ALU_OP(instruction)) {
case ALU_OP_T: return "T";
case ALU_OP_N: return "N";
case ALU_OP_T_PLUS_N: return "T+N";
case ALU_OP_T_AND_N: return "T&N";
case ALU_OP_T_OR_N: return "T|N";
case ALU_OP_T_XOR_N: return "T^N";
case ALU_OP_T_INVERT: return "~T";
case ALU_OP_T_EQUAL_N: return "N=T";
case ALU_OP_N_LESS_T: return "T>N";
case ALU_OP_N_RSHIFT_T: return "N>>T";
case ALU_OP_T_DECREMENT: return "T-1";
case ALU_OP_R: return "R";
case ALU_OP_T_LOAD: return "[T]";
case ALU_OP_N_LSHIFT_T: return "N<N";
case ALU_OP_ENABLE_INTERRUPTS: return "seti";
case ALU_OP_INTERRUPTS_ENABLED: return "iset?";
case ALU_OP_RDEPTH: return "rdepth";
case ALU_OP_T_EQUAL_0: return "0=";
case ALU_OP_CPU_ID: return "cpu-id";
default: return "unknown";
}
}
if (foo)
bar();
else
baz();
picocom --omap delbs -b 115200 -e b /dev/ttyUSB1