
محاكي مجموعة تعليمات RISC-V وظيفي يدعم امتدادات متعددة (RV32/64، V، التشفير) مع وضع تصحيح تفاعلي، وتكامل GDB، ونمذجة على مستوى التعليمات للتطوير المشترك بين العتاد والبرمجيات واستكشاف المعمارية.
Spike، محاكي مجموعة تعليمات RISC-V، ينفذ نموذجًا وظيفيًا لواحد أو أكثر من harts RISC-V. سُمي على اسم المسمار الذهبي المستخدم للاحتفال بإكمال السكة الحديدية العابرة للقارات في الولايات المتحدة.
يدعم Spike ميزات مجموعة تعليمات RISC-V التالية:
تُنَسَّخ المشاريع بشكل أساسي للإشارة إلى متى تم توسيع واجهة برمجة التطبيقات أو جعلها غير متوافقة. وبهذه الروح، يهدف Spike إلى اتباع مخطط الإصدارات SemVer، حيث تزداد أرقام الإصدار الرئيسية عند إجراء تغييرات غير متوافقة مع الإصدارات السابقة في واجهة برمجة التطبيقات؛ وتزداد أرقام الإصدار الفرعية عند إضافة واجهات برمجة تطبيقات جديدة؛ وتزداد أرقام إصدار التصحيح عند إصلاح الأخطاء بطريقة متوافقة مع الإصدارات السابقة.
واجهة برمجة التطبيقات العامة الرئيسية لـ Spike هي مجموعة تعليمات RISC-V. واجهة C++ الخاصة بـ Spike الداخلية لا تُعتبر واجهة برمجة تطبيقات عامة في هذا الوقت، وسيتم إجراء تغييرات غير متوافقة مع الإصدارات السابقة على هذه الواجهة دون زيادة رقم الإصدار الرئيسي.
نفترض أن متغير البيئة RISCV مضبوط على مسار تثبيت أدوات RISC-V.
$ apt-get install device-tree-compiler
$ apt-get install libboost-regex-dev libboost-system-dev
$ mkdir build
$ cd build
$ ../configure --prefix=$RISCV
$ make
$ [sudo] make install
إذا كان نظامك يستخدم مدير الحزم yum، يمكنك استبدال
yum install dtc بالخطوة الأولى.
يمكنك تخطي الخطوة الثانية إذا لم تكن بحاجة إلى استخدام الإدخال/الإخراج عبر socket لوضع التصحيح التفاعلي.
قم بتثبيت bash، gmake، dtc، واستخدم clang.
$ pkg_add bash gmake dtc
$ exec bash
$ export CC=cc; export CXX=c++
$ mkdir build
$ cd build
$ ../configure --prefix=$RISCV
$ gmake
$ [doas] make install
قم بتثبيت spike (انظر خطوات البناء)، riscv-gnu-toolchain، و riscv-pk.
اكتب برنامج C قصير وسمه hello.c. ثم، قم بتجميعه إلى ملف RISC-V ELF ثنائي باسم hello:
$ riscv64-unknown-elf-gcc -o hello hello.c
الآن يمكنك محاكاة البرنامج فوق proxy kernel:
$ spike pk hello
إضافة تعليمة إلى المحاكي تتطلب خطوتين:
وصف السلوك الوظيفي للتعليمة في الملف riscv/insns/<new_instruction_name>.h. افحص التعليمات الأخرى في ذلك الدليل كنقطة بداية.
أضف رمز العملية وقناع رمز العملية إلى riscv/opcodes.h. بدلاً من ذلك، أضفه إلى حزمة riscv-opcodes، وستقوم بذلك نيابة عنك:
$ cd ../riscv-opcodes
$ vi opcodes // add a line for the new instruction
$ make install
أضف التعليمة إلى riscv/riscv.mk.in. وإلا، فلن يتم تضمين التعليمة في البناء وستُعامل كتعليمة غير قانونية.
أعد بناء المحاكي.
لاستدعاء وضع التصحيح التفاعلي، شغّل spike مع -d:
$ spike -d pk hello
لمشاهدة محتويات سجل عدد صحيح (0 للنواة 0):
: reg 0 a0
لمشاهدة محتويات سجل النقطة العائمة:
: fregs 0 ft0
أو:
: fregd 0 ft0
اعتمادًا على ما إذا كنت ترغب في طباعة السجل بدقة مفردة أو مزدوجة.
لمشاهدة محتويات موقع ذاكرة (عنوان فيزيائي بالنظام الست عشري):
: mem 2020
لمشاهدة محتويات الذاكرة بعنوان افتراضي (0 للنواة 0):
: mem 0 2020
يمكنك التقدم بتعليمة واحدة بالضغط على مفتاح الإدخال. يمكنك أيضًا التنفيذ حتى الوصول إلى مساواة مرغوبة:
: until pc 0 2020 (stop when pc=2020)
: until reg 0 mie a (stop when register mie=0xa)
: until mem 2020 50a9907311096993 (stop when mem[2020]=50a9907311096993)
بدلاً من ذلك، يمكنك التنفيذ طالما أن المساواة صحيحة:
: while mem 2020 50a9907311096993
يمكنك متابعة التنفيذ إلى أجل غير مسمى بواسطة:
: r
في أي نقطة أثناء التنفيذ (حتى بدون -d)، يمكنك الدخول إلى
وضع التصحيح التفاعلي باستخدام <control>-<c>.
لإنهاء المحاكاة من موجه التصحيح، اضغط <control>-<c> أو:
: q
بديل لوضع التصحيح التفاعلي هو الاتصال باستخدام gdb. لأن spike يحاول أن يكون مثل الأجهزة الحقيقية، تحتاج أيضًا إلى OpenOCD للقيام بذلك. سنستخدم برنامج الاختبار التالي:
$ cat rot13.c
#include <stdio.h>
char text[] = "Vafgehpgvba frgf jnag gb or serr!";
// Don't use the stack, because sp isn't set up.
volatile int wait = 1;
int main()
{
int i = 0;
while (text[i]) {
char lower = text[i] | 32;
if (lower >= 'a' && lower <= 'm')
text[i] += 13;
else if (lower > 'm' && lower <= 'z')
text[i] -= 13;
i++;
}
done:
printf("decoded text: %s\n", text);
}
$ riscv64-unknown-elf-gcc -g -Og --specs=semihost.specs -o rot13 rot13.c
لتصحيح هذا البرنامج، قم أولاً بتشغيل spike وإخباره بالاستماع لـ OpenOCD:
$ spike --rbb-port=9824 -m0x10000:0x20000 rot13
Listening for remote bitbang connection on port 9824.
...
في shell منفصل شغّل OpenOCD مع ملف التكوين المناسب:
$ cat spike.cfg
adapter driver remote_bitbang
remote_bitbang host localhost
remote_bitbang port 9824
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0xdeadbeef
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
gdb report_data_abort enable