ما هو SystemC ولماذا نستخدمه في الأنظمة المدمجة؟
نُشر في
- أنظمة مدمجة
- معلوماتية
- SystemC
- علوم
- لغة c/c++

دليل هندسي مبسّط للمبتدئين حول نمذجة العتاد المتوازي، ومحاكاة الزمن الفيزيائي، وتكامل العتاد مع البرمجيات باستخدام لغة C++ القياسية.
جدول المحتويات
- لماذا يحتاج مهندسو الأنظمة المدمجة إلى عتاد افتراضي؟
- ما هو SystemC؟
- لماذا نستخدم SystemC في الأنظمة المدمجة؟
- تثبيت SystemC على نظام لينكس
- مثال تطبيقي: نمذجة نظام مراقبة حرارية مدمج
- الخلاصة
- المراجع
1. لماذا يحتاج مهندسو الأنظمة المدمجة إلى عتاد افتراضي؟
يُعرَّف النظام المدمج (Embedded System) بأنه وحدة حوسبة مخصصة لأداء وظيفة محددة في العالم الواقعي، غالباً ضمن قيود صارمة تتعلق بالزمن الحقيقي وحجم الذاكرة واستهلاك الطاقة. بدءاً من وحدات التحكم في المكابح المانعة للانغلاق في السيارات والأجهزة الطبية القابلة للارتداء، وصولاً إلى الحساسات الصناعية ومنظمات الحرارة الذكية، يجمع كل منتج مدمج بين عالمين مترابطين بشدة: العتاد الرقمي المخصص (المعالجات، والمؤقتات، ونواقل البيانات، والحساسات) والبرمجيات المدمجة (البرمجيات الثابتة Firmware، وتعريفات العتاد، وأنظمة التشغيل في الزمن الحقيقي).
تقليدياً، كان هذا الترابط الوثيق يخلق عنق زجاجة مكلفاً للغاية؛ إذ يستغرق تصميم وتصنيع شريحة متكاملة (SoC) أو لوحة إلكترونية مطبوعة أشهراً طويلة. فإذا اضطر مهندسو البرمجيات إلى الانتظار حتى تصل الرقائق الفيزيائية من المصنع قبل اختبار سطر واحد من الشيفرة، فإن اكتشاف خلل في التكامل بين العتاد والبرمجيات في مرحلة متأخرة قد يفرض إعادة تصميم باهظة للعتاد. تتغلب الفرق الهندسية الحديثة على هذه المعضلة عبر النمذجة الافتراضية (Virtual Prototyping): أي بناء نموذج برمجي قابل للتنفيذ يحاكي العتاد بدقة، بحيث يتمكن مصممو المعمارية ومطورو البرمجيات من تصميم النظام الكامل واختباره وتنقيحه على حاسوب عادي قبل تصنيع الشريحة الفيزيائية بوقت طويل. وهذه تحديداً هي المهمة التي صُمِّمت مكتبة SystemC من أجلها.
2. ما هو SystemC؟
إن SystemC هي مكتبة أصناف مفتوحة المصدر بلغة C++ مزودة بنواة محاكاة قائمة على الأحداث المنفصلة، وتُستخدم للنمذجة على مستوى الأنظمة الإلكترونية (ESL)، والتصميم المشترك للعتاد والبرمجيات، والتحقق المعماري. انطلقت هذه التقنية عام 1999 عبر مبادرة Open SystemC Initiative (التي أصبحت اليوم جزءاً من منظمة Accellera Systems Initiative)، وهي ليست مجرد عُرف صناعي غير رسمي، بل معيار دولي رسمي معتمد من معهد مهندسي الكهرباء والإلكترونيات تحت مسمى IEEE Std 1666 (وأحدث إصداراته هو المعيار IEEE Std 1666-2023 المبني على معيار C++17 الحديث).
ولأن SystemC مبنية بالكامل كمكتبة C++ قياسية وليست لغة احتكارية منفصلة، فلست بحاجة إلى مترجم عتاد خاص لتشغيلها؛ إذ يستطيع أي مترجم C++ قياسي — مثل GCC أو Clang — تحويل نموذج العتاد والبرمجيات المكتوب بـ SystemC مباشرة إلى ملف تنفيذي سريع يعمل كمحاكٍ متكامل.
2.1 الفرق بين SystemC ولغة C/C++ المدمجة: تصحيح التباس شائع
إذا كنت مبتدئاً في مجال الأنظمة المدمجة، فمن الضروري التمييز بوضوح بين لغة C/C++ المدمجة (Embedded C/C++) وبين SystemC:
لغة C/C++ المدمجة (برمجيات الهدف Firmware): تُترجم عبر الترجمة المتقاطعة (Cross-Compilation) إلى شيفرة آلة وتُحمَّل مباشرة داخل المتحكم الدقيق الفعلي (مثل STM32 أو AVR أو ESP32) لتعمل داخل المنتج النهائي.
مكتبة SystemC (نمذجة النظام ومحاكاته): تُترجم وتُشغَّل على حاسوب التطوير أو الخادم من أجل محاكاة مكونات العتاد ذاتها — كنبضات الساعة، وأسلاك الإشارات، ونواقل الذاكرة، والحساسات، والمسرّعات الرقمية — أثناء عملها جنباً إلى جنب مع البرمجيات الثابتة.
قد تتساءل: لماذا لا يمكننا نمذجة العتاد الرقمي بسهولة باستخدام لغة C++ العادية وحدها؟ تنفّذ لغة C++ القياسية التعليمات بشكل تسلسلي (تعليمة تلو الأخرى) ولا تمتلك مفهوماً مدمجاً لدورات الساعة الفيزيائية. في المقابل، تعمل الدارات الرقمية الحقيقية بالتوازي (التزامن) — حيث تستجيب عشرات الكتل العتادية المستقلة معاً في النانوثانية ذاتها — وتعتمد كلياً على الزمن الفيزيائي. تزوّد SystemC لغة C++ بكلتا القدرتين: التوازي العتادي التعاوني وخط زمني افتراضي دقيق للمحاكاة.
2.2 اللبنات المعمارية الأساسية
يتألف كل نموذج في SystemC من خمسة مفاهيم جوهرية ضمن فضاء الأسماء sc_core:
الوحدات (
SC_MODULE): كتل بنائية مستقلة تمثّل مكونات العتاد أو النظام (مثل مؤقت، أو واجهة حساس، أو موجّه ناقل بيانات) ويمكن تداخلها هرمياً.المنافذ والقنوات (
sc_in، وsc_out، وsc_signal، وsc_fifo): واجهات محددة الأنواع وأسلاك اتصال أو طوابير بيانات تربط الوحدات ببعضها بنظافة دون الحاجة إلى ربط مؤشرات داخلية مباشرة بينها.العمليات المتزامنة (
SC_METHODوSC_THREAD): دوال أعضاء تجدولها نواة المحاكاة لتقليد التنفيذ المتوازي في العتاد؛ فالدالةSC_METHODتُستثار عند وقوع حدث وتعود فوراً دون توقف، بينما تعملSC_THREADكخيط تعاوني يمكنه تعليق تنفيذه عبر الزمن المحاكى باستخدامwait().الزمن المحاكى والأحداث (
sc_timeوsc_event): ساعة عتاد افتراضية تتتبع وحدات الزمن من الفيمتوثانية (SC_FS) حتى الثواني (SC_SEC)، بمعزل تام عن سرعة معالج حاسوبك الشخصي.نقطة انطلاق المحاكاة (
sc_mainوsc_start): تعرّف مكتبة SystemC دالة C++ الأساسيةmain()داخلياً لتهيئة النواة، ثم تستدعي دالتكsc_main()لتوصيل الوحدات وتشغيل المحاكاة عبرsc_start().
قبل التعمق أكثر، تأمّل مدى بساطة ووضوح وحدة عتادية زمنية متكاملة في SystemC الحديث:
#include <iostream>
#include <systemc>
using namespace sc_core;
SC_MODULE(Heartbeat) {
SC_CTOR(Heartbeat) {
SC_THREAD(run); // Register a concurrent hardware thread
}
void run() {
while (true) {
std::cout << "LED toggle at " << sc_time_stamp() << '\n';
wait(500, SC_MS); // Pause this module for 500 ms of simulated time
}
}
};
int sc_main(int, char*[]) {
Heartbeat led("led"); // Instantiate hardware block
sc_start(1500, SC_MS); // Simulate 1.5 seconds of hardware time
return 0;
}
عند ترجمة هذا البرنامج وتشغيله، ينتهي تنفيذه في أقل من ميلي ثانية واحدة من الزمن الحقيقي على حاسوبك، ومع ذلك تتدرج ساعة المحاكاة الداخلية بدقة عبر اللحظات 0 s و500 ms و1 s من زمن العتاد الافتراضي.
3. لماذا نستخدم SystemC في الأنظمة المدمجة؟
3.1 مستويات التجريد: لماذا تتفوق محاكاة SystemC في السرعة؟
يصمم مهندسو العتاد الرقمي الدارات تقليدياً باستخدام لغات توصيف العتاد (HDLs) مثل VHDL أو Verilog أو SystemVerilog عند مستوى نقل المسجلات (RTL). يصف مستوى RTL كل تبدّل في إشارة سلك وكل حافة نبضة ساعة — وهو أمر لا غنى عنه عند تصنيع الترانزستورات الفعلية، لكنه مفرط في التفصيل عندما ترغب في إقلاع نظام تشغيل أو اختبار برمجيات مدمجة عالية المستوى؛ إذ قد تستغرق محاكاة ثوانٍ معدودة لمعالج مدمج بتفاصيل RTL الكاملة ساعات طويلة.
ومن المفاهيم الخاطئة الشائعة الاعتقاد بأن SystemC أسرع من VHDL أو Verilog لمجرد أنها تستخدم نواة محاكاة قائمة على الأحداث؛ ففي الواقع تعتمد محاكيات VHDL وVerilog أيضاً على أنوية أحداث منفصلة. إنما تحقق SystemC تفوقها الهائل في السرعة — إذ تكون غالباً أسرع بنحو 100× إلى 1,000× من مستوى RTL — لأنها تتيح النمذجة على مستوى المعاملات (TLM-2.0) المدمجة مباشرة في المعيار IEEE Std 1666. فبدلاً من محاكاة عشرات الانتقالات الفردية لإشارات العناوين والبيانات والمصافحة نبضةً بنبضة، ينقل نموذج TLM حزمة ذاكرة كاملة عبر استدعاء دالة C++ واحد (b_transport) مع الاحتفاظ بتقديرات التأخير الزمني الواقعية.
| مستوى التجريد | اللغة الشائعة | دقة التوقيت والاتصال | الاستخدام الرئيسي في الأنظمة المدمجة |
|---|---|---|---|
| مستوى نقل المسجلات (RTL) | Verilog, VHDL, SystemVerilog | دقة على مستوى النبضة والأطراف (كل سلك وحافة ساعة) | التصنيع السيليكوني والتحقق العتادي على مستوى البوابات |
| نمذجة TLM تقريبية التوقيت | SystemC + TLM-2.0 | معاملات ناقل متعددة المراحل مع التنافس وزمن الاستجابة | تحليل معمارية نواقل SoC والتحكيم والأداء |
| نمذجة TLM مرنة التوقيت | SystemC + TLM-2.0 | معاملات باستدعاء واحد (b_transport) مع توقيت إجمالي |
النماذج الافتراضية والتطوير المبكر للبرمجيات الثابتة وأنظمة التشغيل |
3.2 أبرز التطبيقات في دورة تطوير الأنظمة المدمجة
النمذجة الافتراضية (تطوير البرمجيات المبكر Shift-Left): يكتب مهندسو البرمجيات الثابتة تعريفات العتاد، ومقاطعات الخدمة، ومهام RTOS وينقّحونها على منصة SystemC افتراضية قبل وصول اللوحات الفيزيائية بأشهر.
استكشاف فضاء التصميم (Design Space Exploration): يقارن مهندسو المعمارية بين خيارات النظام المرشحة — مثل أحجام الذاكرة المخبئية، أو عمق مخازن DMA، أو طوبولوجيا النواقل — تحت أحمال عمل واقعية لتحسين زمن الاستجابة وكفاءة الطاقة مبكراً.
تقسيم المهام بين العتاد والبرمجيات (Hardware-Software Partitioning): نظراً لكتابة نماذج العتاد وخوارزميات البرمجيات معاً بلغة C++، تستطيع الفرق قياس أداء المهام كثيفة الحساب (مثل ترشيح الإشارات، أو التحكم بالمحركات، أو التشفير) وتحديد ما ينبغي تنفيذه برمجياً على المعالج مقابل نقله إلى مسرّع عتادي مخصص.
التحقق قبل التصنيع السيليكوني (النماذج المرجعية الذهبية): تبني فرق التحقق نماذج سلوكية نظيفة بـ SystemC لتعمل كمرجع موثوق تُقارن به تصاميم RTL المعقدة المكتوبة بـ Verilog أو VHDL تلقائياً.
التوليف عالي المستوى (High-Level Synthesis - HLS): تستطيع أدوات أتمتة التصميم المتخصصة تحويل أجزاء قابلة للتوليف من شيفرة SystemC/C++ الخوارزمية مباشرة إلى توصيفات عتادية بمستوى RTL لشرائح FPGA وASIC.
4. تثبيت SystemC على نظام لينكس
يُعدّ نظام لينكس البيئة الأساسية لسلاسل أدوات الأنظمة المدمجة وأتمتة التصميم الإلكتروني (EDA). نوضّح فيما يلي طريقتين موثوقتين لإعداد SystemC على لينكس: تثبيت سريع بخطوة واحدة عبر مدير الحزم للتجربة الفورية، وبناء رسمي من المصدر باستخدام CMake للحصول على أحدث إصدار من SystemC 3.0+ (IEEE Std 1666-2023)، والذي يتطلب مترجماً يدعم C++17 (مثل GCC 9.3+ أو Clang 13+) وأداة CMake 3.16+.
4.1 الخيار أ: التثبيت السريع عبر مدير الحزم (Ubuntu / Debian)
في توزيعات Ubuntu وDebian الحديثة، يمكن تثبيت ملفات الترويسة والمكتبة المشتركة الخاصة بـ Accellera SystemC مباشرة من المستودعات الرسمية للنظام:
sudo apt update
sudo apt install -y build-essential cmake libsystemc-dev
4.2 الخيار ب: بناء SystemC 3.0+ من الشيفرة المصدرية باستخدام CMake
إذا كانت توزيعتك توفر إصداراً أقدم أو أردت الحصول على أحدث المزايا الرسمية من Accellera، فقم ببناء SystemC من المصدر باستخدام CMake. يضمن تمرير الخيار -DCMAKE_INSTALL_LIBDIR=lib توحيد مسار مجلد المكتبة عبر مختلف توزيعات لينكس:
# 1. Install build prerequisites
sudo apt update && sudo apt install -y build-essential cmake git
# 2. Clone the official Accellera SystemC repository (release 3.0.2)
git clone --branch 3.0.2 --depth 1 https://github.com/accellera-official/systemc.git
cd systemc
# 3. Configure an out-of-source CMake build (C++17 required for SystemC 3.0+)
cmake -B build \
-DCMAKE_CXX_STANDARD=17 \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$HOME/systemc" \
-DCMAKE_INSTALL_LIBDIR=lib
# 4. Compile in parallel and install to ~/systemc
cmake --build build -j"$(nproc)"
cmake --install build
إذا ثبّتَّ المكتبة في المسار $HOME/systemc (الخيار ب) وكنت تخطط لترجمة البرامج مباشرة عبر g++ من الطرفية، فأضف مسارات التثبيت إلى ملف إعدادات الصدفة:
echo 'export SYSTEMC_HOME="$HOME/systemc"' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH="$SYSTEMC_HOME/lib:${LD_LIBRARY_PATH}"' >> ~/.bashrc
source ~/.bashrc
5. مثال تطبيقي: نمذجة نظام مراقبة حرارية مدمج
لمشاهدة كيف تنمذج SystemC التفاعل بين العتاد ووحدة التحكم عملياً، سنبني نظام حماية حرارية مبسّطاً — شبيهاً بالأنظمة التي تراقب خلايا البطاريات في المركبات الكهربائية أو وحدات التغذية:
طرفية الحساس (
TemperatureSensor): تستخدم عمليةSC_THREADلأخذ قراءة حرارة كل10 msمن الزمن المحاكى وإرسال القيمة عبر منفذ خرج (sc_out<int>).متحكم التبريد المدمج (
CoolingController): يستخدم عمليةSC_METHODحساسة لتغيّرات منفذ الدخل (sc_in<int>)، فيفعّل إشارة تشغيل مروحة التبريد (sc_out<bool>) كلما بلغت درجة الحرارة75 °Cأو تجاوزتها.الربط على المستوى الأعلى (
sc_main): ينشئ نسختين من الوحدتين، ويربط منافذهما عبر قنواتsc_signal، ثم يشغّل المحاكاة لمدة60 ms.
#include <iostream>
#include <systemc>
using namespace sc_core;
// 1. Hardware Peripheral Module: Periodic Temperature Sensor
SC_MODULE(TemperatureSensor) {
sc_out<int> temp_out;
SC_CTOR(TemperatureSensor) {
SC_THREAD(sample_loop);
}
void sample_loop() {
const int readings[] = {65, 72, 78, 81, 70};
for (int temp : readings) {
wait(10, SC_MS); // Advance simulated time by 10 ms
temp_out.write(temp); // Drive new reading onto signal wire
}
}
};
// 2. Embedded Controller Module: Reacts to Sensor Updates
SC_MODULE(CoolingController) {
sc_in<int> temp_in;
sc_out<bool> fan_enable;
static constexpr int THRESHOLD_C = 75;
SC_CTOR(CoolingController) {
SC_METHOD(evaluate_temperature);
sensitive << temp_in; // Trigger whenever temp_in changes
dont_initialize(); // Wait for the first real sensor event
}
void evaluate_temperature() {
int current_temp = temp_in.read();
bool turn_on = (current_temp >= THRESHOLD_C);
fan_enable.write(turn_on);
std::cout << "[" << sc_time_stamp() << "] "
<< "Temp: " << current_temp << " C -> Cooling Fan: "
<< (turn_on ? "ON" : "OFF") << '\n';
}
};
// 3. Top-Level Entry Point: Wire Modules and Start Simulation
int sc_main(int, char*[]) {
sc_signal<int> temp_wire;
sc_signal<bool> fan_wire;
TemperatureSensor sensor("sensor");
CoolingController controller("controller");
sensor.temp_out(temp_wire);
controller.temp_in(temp_wire);
controller.fan_enable(fan_wire);
sc_start(60, SC_MS); // Run simulation for 60 ms
return 0;
}
5.1 ترجمة المحاكاة وتشغيلها
احفظ الشيفرة أعلاه باسم thermal_monitor.cpp بجانب ملف CMakeLists.txt التالي، والذي يعمل تلقائياً سواء ثبّتَّ المكتبة عبر حزمة APT (الخيار أ) أو بنيتها من المصدر (الخيار ب):
cmake_minimum_required(VERSION 3.16)
project(thermal_monitor LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(SystemCLanguage QUIET CONFIG)
add_executable(thermal_monitor thermal_monitor.cpp)
if(SystemCLanguage_FOUND)
target_link_libraries(thermal_monitor PRIVATE SystemC::systemc)
else()
target_link_libraries(thermal_monitor PRIVATE systemc)
endif()
ترجم المحاكاة وشغّلها باستخدام CMake (أو مباشرة بأمر واحد عبر g++):
# Build with CMake (append -DCMAKE_PREFIX_PATH="$HOME/systemc" if built from source)
cmake -B build && cmake --build build
./build/thermal_monitor
# Alternative: Compile directly in one command with g++
# For Option A (APT package):
g++ -std=c++17 -Wall -Wextra thermal_monitor.cpp -lsystemc -o thermal_monitor && ./thermal_monitor
# For Option B (Source build in $SYSTEMC_HOME):
# g++ -std=c++17 -Wall -Wextra -I"$SYSTEMC_HOME/include" -L"$SYSTEMC_HOME/lib" -Wl,-rpath,"$SYSTEMC_HOME/lib" thermal_monitor.cpp -lsystemc -o thermal_monitor && ./thermal_monitor
عند تشغيل الملف التنفيذي نحصل على سجل المحاكاة المختوم زمنياً كما يلي:
SystemC 3.0.2-Accellera --- Nov 5 2025 12:44:46
Copyright (c) 1996-2025 by all Contributors,
ALL RIGHTS RESERVED
[10 ms] Temp: 65 C -> Cooling Fan: OFF
[20 ms] Temp: 72 C -> Cooling Fan: OFF
[30 ms] Temp: 78 C -> Cooling Fan: ON
[40 ms] Temp: 81 C -> Cooling Fan: ON
[50 ms] Temp: 70 C -> Cooling Fan: OFF
لاحظ ثلاثة سلوكيات عتادية جوهرية جرى تمثيلها بنظافة في خمسين سطراً فقط من لغة C++ القياسية:
التحكم في التهيئة الأولية: يمنع استدعاء
dont_initialize()داخلCoolingControllerإجراء فحص مبكر عند اللحظة0 sقبل أن يُصدر الحساس قراءته الأولى عند10 ms.تزامن خالٍ من الاستقصاء المستمر (Zero-Polling): خلافاً لحلقات الانتظار المشغولة في البرمجيات التسلسلية، لا تستهلك دالة
evaluate_temperature()أي جهد محاكاة إلا عندما تتغير قيمة السلكtemp_wireفعلياً — تماماً كمقارن عتادي أو خط مقاطعة.معمارية مفصولة الارتباط: لا تعرف أي وحدة تفاصيل الوحدة الأخرى؛ بل تتواصلان حصرياً عبر منافذ محددة الأنواع مربوطة بقنوات
sc_signalداخلsc_main()، مما يسهّل تسجيل المخططات الموجية أو استبدال المتحكم ببرمجيات ثابتة حقيقية.
6. الخلاصة
بالنسبة للمبتدئين في ميدان الأنظمة المدمجة، تمثّل SystemC (المعيار IEEE Std 1666) الجسر العملي الذي يصل هندسة البرمجيات بتصميم العتاد الرقمي. فبفضل إثرائها للغة C++ القياسية بالهرمية العتادية، والعمليات المتزامنة، وقنوات الاتصال المهيكلة، والزمن الفيزيائي المحاكى، تمنح الفرق الهندسية القدرة على استكشاف المعماريات، والتحقق من الطرفيات، وتطوير البرمجيات الثابتة على نماذج افتراضية سريعة قبل تصنيع الرقائق الفعلية بوقت طويل.
وبعد إتقانك بناء وحدات SC_MODULE التركيبية مثل مراقب الحرارة أعلاه، تشمل الخطوات التالية الطبيعية تسجيل الإشارات في ملفات موجية بصيغة VCD عبر (sc_create_vcd_trace_file) لفحصها بصرياً في أداة GTKWave، واستكشاف مقابس TLM-2.0 لنمذجة نواقل المعالجات بسرعة فائقة.
7. المراجع
IEEE Standards Association & Accellera Systems Initiative. (2023). IEEE Standard for Standard SystemC Language Reference Manual (IEEE Std 1666-2023). Available via the IEEE GET Program: https://systemc.org/
Accellera Systems Initiative. SystemC Standards and Proof-of-Concept Library Downloads. https://www.accellera.org/downloads/standards/systemc
Accellera Systems Initiative. Official SystemC Open-Source Reference Implementation (GitHub Repository). https://github.com/accellera-official/systemc
Black, D. C., Donovan, J., Bunton, B., & Keist, A. (2010). SystemC: From the Ground Up (2nd ed.). Springer. https://doi.org/10.1007/978-0-387-69958-5
Grötker, T., Liao, S., Martin, G., & Swan, S. (2002). System Design with SystemC. Springer / Kluwer Academic Publishers. https://doi.org/10.1007/b116588
التعليقات 0
لا توجد تعليقات بعد.
اكتب تعليقاً