Что такое симуляция в программировании
В чем разница между симуляцией и эмуляцией
моделирование
пример
В качестве примера рассмотрим симулятор полета. Это выглядит и кажется, что вы летите на самолете, но вы совершенно не связаны с реальностью полета на самолете, и вы можете согнуть или нарушить эти правила, как считаете нужным. Например, летайте на аэробусе А380 вверх ногами между Лондоном и Сиднеем, не ломая его.
эмуляция
пример
Система MAME построена вокруг этой самой предпосылки. Все те старые аркадные системы, о которых давно забыли, которые были реализованы почти полностью на аппаратном уровне или во встроенном программном обеспечении их аппаратных систем, можно эмулировать вплоть до исходных ошибок и сбоев, которые могут произойти, когда вы достигнете максимально возможного балла.
Например, симуляция раннего утреннего трафика исключает имена и, возможно, даже их имена (используя переменную счетчика, а не фактический набор Commuter объектов), но не может игнорировать их скорость прибытия.
И то, и другое означает выполнение чего-то другого.
Разница в том, что «Симуляция» происходит на сознательном уровне (по отношению к пользователю) и обычно дорабатывается, чтобы предвидеть результат реальности, не касаясь самой реальности.
«Эмуляция» происходит на бессознательном уровне и имеет целью заменить базовый компонент другим, который, по отношению к пользователю, работает как старый.
Технически они оба делают одно и то же: делают что-то в среде, которая действует так, как если бы она была реальной.
Концептуально, однако, есть важное отличие.
Предполагается, что симуляция в определенной степени отделена от реального мира; результат симуляции не связан напрямую с тем, что он симулирует. Например, симулятор самолета фактически не летает, а пилот фактически не общается с реальным авиадиспетчером.
Эмуляция, которая часто используется в контексте одной платформы, претендующей на роль другой платформы, гораздо более полная. Таким образом, разработчики Windows Phone могут запускать или отлаживать свои телефонные приложения на компьютере под управлением Windows в эмуляторе, который выглядит как телефон и ведет себя так же. Вы также можете запускать свои старые игры Commodore 64 в эмуляторе.
Слова не точны. На мой взгляд, большинство симуляторов полета больше похожи на эмуляторы, но название пришло из того времени, когда они не были такими захватывающими. Некоторые люди зарезервируют слово эмулятор для кроссплатформенного случая и отвергают его для чего-либо еще. Вы, вероятно, никогда не будете думать неправильно, если будете делать то же самое, когда говорите, но понимаете, что некоторые люди могут немного по-разному определять границу между двумя словами и делают скидку, когда кто-то говорит «это подражание» для действительно точного и полное моделирование.
Симуляторы или симуляторы используют программное обеспечение для создания реплицированной системы, которая очень похожа на целевую модель в отношении ее базовой функциональности (особенно ее основной методологии).
Эмуляторы, с другой стороны, больше внимания уделяют внешнему сходству по сравнению с целевой системой. Это имеет минимальное беспокойство о том, «как» функции имитируются. Эмуляторы, как правило, используются при работе в совершенно другой среде (например, в другой операционной системе) по сравнению с исходной системой.
eLearning Lab
Разница между симуляторами и эмуляторами
17.03.2014
В последнее время в eL-среде всё чаще встречаю статьи, в которых путаются понятия «эмулятор» и «симулятор». Некоторые почему-то упорно отказываются различать эти термины (тем более сейчас весна), вводя тех, кто в этой теме пока ещё не разбирается, в заблуждение. Собственно, данная тема ещё более увлекательная, чем holywar на тему «щёлкать или нажимать».
На первой картинке мы видим 2 скриншота: слева — оригинальная программа, справа — эмулятор этой программы.
На второй картинке тоже 2 скриншота: слева — оригинальная программа, справа — симулятор этой программы.
Разницы между этими скриншотами никакой нет. То есть, визуально симулятор ПО и эмулятор ПО зачастую могут выглядеть одинаково.
Итак, давайте сравним два понятия — эмулятор и симулятор, чтобы понять, в чём заключается различие. Часть формулировок, которые я привёл ниже, были взяты из справочников, а также со специализированных форумов.
Что же такое эмулятор?
Начнём с понятия «эмуляция». Эмуляция — это воспроизведение работы программы или системы (а не какой-то её мизерной части) с сохранением ключевых её свойств и принципов работы. Эмуляция выполняет программный код в привычной для этого кода среде, состоящей из тех же компонентов, что и эмулируемый объект.
В отличие от симуляции, при которой предполагается имитация поведения системы и её интерфейса, термин эмуляция предполагает создание точной модели устройства.
Эмулируются все основные компоненты устройства, в том числе процессор, память и устройства ввода/вывода. Поскольку эмулируется и процессор, совершенно не обязательно чтобы в гостевой системе (эмулируемом устройстве) процессор был того же типа, что и в хост-системе (эмулирующем устройстве). #
IBM, компания, которая ввела термин «эмуляция» определяет её как «новую комбинацию программы, микрокода и оборудования». До 1980-х годов термин «эмуляция» относился исключительно к аппаратной реализации с применением микрокода, тогда как для программной эмуляции использовался термин «симуляция». Например, компьютер, специально разработанный для выполнения программ, написанный для другой архитектуры, являлся эмулятором. С другой стороны симулятором могла бы называться программа для ПК, с помощью которой можно было бы симулировать старые игры для Atari. #
Симуляция — это воспроизведение работы программы-оригинала сугубо виртуально, на движке специальной программы (средство разработки курсов, к примеру). Симуляция лишь имитирует выполнение кода, а не копирует его, всё виртуально на 100%, всё понарошку.
Как правило, симулятор ПО — это имитация лишь отдельных свойств, возможностей или функций симулируемой программы, причём не в полном объёме, а только в том, в каком это необходимо в рамках тех задач, которые были поставлены перед симулятором. Вы как будто бы работаете в настоящей программе, но при этом функционал полностью или почти полностью «фальшивый», как правило» написанный совершенно иначе, чем в оригинале (например, на другом языке программирования). Но зато, работая в симуляторе, вы понимаете, как работать в оригинальной программе, понимаете то, как будет реагировать программа на ваши действия.
Нашёл на просторах инета хороший наглядный пример: подключив к телевизору генератор тестовых сигналов, мы получим эмуляцию приёма этих сигналов, а вставив в телевизор картинку и осветив её лампочкой, мы получим симуляцию приёма сигналов. В результате мы увидим одно и то же — ряд картинок на экране, которые появляются при тестировании сигнала. Но реализация, как вы понимаете, существенно различается.
Симулятор по полноте функций/учитываемых параметров уже, чем эмулятор. Эмулируется объект, а симулируются его свойства, функции или поведение.
Эмулятор ПО — полнофункциональный аналог оригинального ПО, либо его версия, в которой может быть предусмотрен ряд ограничений по функционалу, возможностям и поведению ПО.
Симулятор ПО — модель оригинального ПО, в которой реализуется логика работы этого ПО (частично или полностью), имитируется поведение ПО, копируется его интерфейс.
Программная симуляция микропроцессора. Коробка передач
Интерпретация
«Интерпретатор» — некто (или нечто), совершающий перевод текста или речи с одного языка на другой «на лету». Смысл этого термина приблизительно сохраняется при его переносе в область вычислительной техники. Оригинальные реализации многих языков программирования: Basic, Unix Shell, Rexx, PHP и др. — были интерпретаторами. Характерная их черта — обработка за один раз одной строки программы, написанной на входном языке. Следующая строка будет преобразована (проинтерпретирована) только тогда, когда в этом возникнет необходимость. По этой причине термин «интерпретатор» обычно противопоставляется понятиям «транслятор» и «компилятор», которые обрабатывают более крупные блоки входного языка: процедуры, файлы, модули и т.п.
Цикл работы
Чтение инструкции из памяти
В реальных компьютерах оперативная память размещается достаточно далеко (во многих смыслах) от процессора. Код, как и данные хранится в ней. Требуется доставить порцию машинного кода для последующей обработки в процессор, что и делается на стадии Fetch. Как и в реальных микропроцессорах, имеющих перед памятью более быстрый кэш инструкций, модель может также использовать кэширование ранее прочитанных инструкций. И опять же, как и в реальных системах, чтение памяти вполне может завершиться возникновением исключения, которое необходимо будет просимулировать.
Декодирование
Жуткая схема, но мне она помогла понять, что вообще происходит в AVX3.
Естественно, что унылой ручной работе по вбиванию содержимого таблиц в код часто предпочитают автоматизацию — генерацию кода по описанию, сделанном на специализированном языке. Для сложных архитектур, или же в случаях, когда необходимо иметь общий фреймворк для создания симуляторов множества различных систем, затраты на создание такого языка и инструментов его трансляции окупаются.
Исполнение
Исполнение (execute) состоит из непосредственной симуляции функции уже декодированной инструкции. Это может быть вычисление результата арифметической или логической операции, чтение или запись в память, изменение текущего режима процессора или передача контроля управления при ветвлении или вызове процедуры.
Каждой распознанной инструкции должна соответствовать сервисная процедура (service routine). В самой простой схеме интерпретатора её выбор производится по коду операции инструкции (опкоду) с помощью конструкции множественного выбора — переключателя — используемого языка программирования. В языке Си это оператор switch. Данная схема получила название «переключаемая» (switched):
Существует несколько альтернатив переключаемой схеме интерпретации, характеризующихся большей скоростью работы [10], однако о них я напишу в другой раз.
Как и создание декодера вручную, написание сервисных процедур может оказаться утомительным занятием, особенно если они похожи друг на друга. Например, в системе команд могут быть семейства инструкций, имеющих одинаковый смысл, но различающихся по ширине обрабатываемого вектора и элементов, а также положением обрабатываемых данных (в регистре или в памяти). Руки сами тянутся к методам обобщённого программирования. Или же хочется написать генератор кода, что возьмёт на себя рутину.
Опять же, сервисные процедуры должны быть синхронизованны с декодером: при правке набора команд надо не забывать про добавление/удаление семантики для их симуляции. Поэтому самым разумным оказывается иметь такое совмещённое описание, чтобы из него автоматически производить и декодер, и процедуры, и (до кучи) дизассемблер.
Запись в память
Работа с симулируемой памятью, даже если рассматривать её только с точностью, достаточной для функциональной модели, тоже нетривиальна. Здесь надо учитывать многое: гостевую схему преобразования виртуальных адресов в физические, отношение гостевой системы к выравниванию данных, порядок байт в машинном слове (endianness), попадание доступа в отображённое на память устройство (memory mapped input/output), разрешения страницы на чтение/запись/исполнение, опциональную сегментацию (уфф!)…
Запись или чтение памяти может привести к исключению, которое, как и в случае fetch, необходимо корректно просимулировать.
Продвижение PC
PC (program counter) — регистр, хранящий адрес текущей инструкции. В разных системах и книгах он зовётся по-разному: IP/EIP/RIP, pc, IP… Для «линейных» операций его надо просто продвинуть на длину только что обработанной инструкции. Но для команд ветвления, вызова процедур, программных прерываний он будет меняться более сложным образом, соответствующим их семантике.
Промежуточный итог
Интерпретатор — практически всегда первый тип модели, создаваемый для новой архитектуры процессора. По этой причине их существует великое множество, и перечисление более-менее известных заняло бы много места. Здесь приведу лишь пару примеров: Bochs [6], Zsim [7]. Хочу также порекомендовать FAQ Марата Файзуллина.
Двоичная трансляция
Главное достоинство моделей, основанных на интерпретации — их простота. Главный недостаток — низкая скорость работы.
Как и в случае с языками высокого уровня, для ускорения можно использовать технику, исторически называвшуюся трансляцией, но сейчас чаще именуемую компиляцией. Так, название языка Fortran — это сокращение от FORmula TRANslator.
Вместо того, чтобы тратить время на разбор и исполнение каждой инструкции каждый раз, когда она встречается, можно просто перевести достаточно длинный блок гостевого кода в эквивалентный по смыслу блок машинного хозяйской системы. Затем, при симуляции, достаточно передать управление на него, и он будет исполняться «без замедления». Это идея работает потому, что на практике код, однажды исполненный, скорее всего будет вскоре будет исполнен снова — ведь большую часть времени программы проводят в циклах относительно небольшого размера.
В контексте симуляции данная техника получила название «двоичная трансляция» (ДТ), или «бинарная трансляция» (binary translation). Понятие это очень близко к «компиляции времени исполнения» (just in time compilation, JIT).
Ниже я опишу одну из простых используемых на практике схем.
Капсулы и блоки трансляции
На вход процесса трансляции подаётся группа машинных команд, находящихся рядом (например, на одной странице) и/или исполняющихся последовательно (трасса). Они декодирутся. Затем каждая гостевая инструкция ассоциируется с блоком хозяйского кода, называемого капсулой. Несколько капсул собираются в более крупные образования, именуемые блоками трансляции. Каждый из них может иметь одну или более точек входа, а также несколько мест, из которых управление может его покинуть.
То, что в настоящей аппаратуре делается «железом», в симуляторе должна делать программа. Поэтому длина капсулы в среднем превышает одну инструкцию, которую она призвана представлять.
Читатели, знакомые с организацией компиляторов, почувствуют сходство происходящего в ДТ с компиляцией. Они будут правы: в ДТ можно выделить работу фронтенда, фаз оптимизации и кодогенерации в бэкенде. Хочу подчеркнуть отличия ДТ от компиляции с языков высокого яровня.
Проблема обнаружения кода
Частный случай этой задачи — пересчёт относительных смещений для адресов перехода инструкций ветвления. На рисунке ниже приведён пример, в котором исходный блок кода заканчивается переходом на шесть байт назад. В сгенерированном коде граница инструкций, на которую следует перейти, находится в другом месте.
Самомодифицирующися код
Исполняемый код программ и обрабатываемые ими данные располагаются в одной физической памяти. Поэтому возможно в процессе исполнения изменять машинный код. Это используется, например, операционными системами для загрузки в память приложений и динамических библиотек, полиморфными вирусами для сокрытия своего присутствия. Назовём такую ситуацию самомодифицирующийся код (self-modifying code, SMC). В случае двоичной трансляции это означает, что блоки трансляции могут устаревать — делаться некорректными, если гостевой код, из которого они были получены, изменился.
При симуляции приходится отслеживать все записи в память и помечать затронутые при этом блоки как устаревшие, требующие повторной трансляции. Операция эта занимает некоторое время, поэтому скорость модели на участках программ с SMC будет низкой: исполнение генерированного кода будет часто прерываться на ретрансляцию.
Ограниченность оптимизаций
После сборки блока трансляции из капсул может оказаться, что его можно дополнительно преобразовать. При этом новый блок будет работать быстрее. Это аналогично применению фаз оптимизаций в компиляторах. Но, если есть вероятность того, что результат исполнения блока после трансформации будет отличаться от исходного, то от неё придётся отказаться. Так как в машинном коде часто содержится меньше информации об алгоритме, чем её содержалось в коде исходном, то и спектр оптимизаций в ДТ меньше, чем у компиляции.
Для проведения ряда преобразований необходимо иметь промежуточное представление для блоков трансляции, позволяющее анализировать графы управления и данных, как это делается в компиляторах. Описанная мною выше схема ДТ с капсулами недостаточно гибка для этого.
Промежуточный итог
Более подробно о техниках двоичной трансляции, применяемых для нужд симуляции, можно прочитать в серии постов на Intel Developer Zone:
Часть 1
Часть 2
Часть 3
Пара ссылок на известные мне симуляторы, в которых двоичный транслятор является основным движком для симуляции: SoftSDV [8], оригинальная реализация Qemu [9].
Прямое исполнение и аппаратная поддержка
Важным на практике случаем ДТ является ситуация, когда архитектуры гостя и хозяина совпадают (или почти совпадают). При этом возникает возможность значительно упростить трансляцию — в некоторых случаях она сводится к копированию гостевого кода как хозяйского или даже исполнению его «на месте», без дублирования. Подобные режимы симуляции имеют общее название «прямое исполнение» (direct execution, DEX).
Общая идея
Казалось бы, если программа уже выражена в машинном языке хозяйской системы, достаточно передать управление на её начало. Дальше аппаратура сама с максимальной скоростью будет исполнять инструкции.
Почему это не работает
Аппаратная поддержка
Некоторые микропроцессоры позволяют поддержать прямое исполнение гостевого кода в «песочнице», на аппаратном уровне выполняя работу по перехвату опасных операций. Этот подход лучше двоичной инструментации как по надёжности, так и по скорости работы. Аппаратно поддерживаемое DEX — это виртуализация, использованная для нужд симуляции.
Я постарался осветить классические условия эффективной виртуализации и состояние дел в современных системах в моём посте «Аппаратная виртуализация. Теория, реальность и поддержка в архитектурах процессоров».
Ограничения
Промежуточный итог
Довольно большое число симуляторов используют аппаратную поддержку виртуализации Intel VT-x для своих нужд. Можно упомянуть Wind River Simics, Oracle VirtualBox, Qemu и продукты VMWare.
Собираем всё вместе
Итак, имеются как минимум три подхода: интерпретация, двоичная трансляция и прямое исполнение, — которые можно использовать для создания программных моделей. Резюмирую их сильные и слабые стороны.
Платой за скорость и гибкость является необходимость поддерживать фактически три независимых модели. Вылавливать в них ошибки, устранять «мелкие» различия в поведении, натыкаться на странности реализаций виртуализации разных поколений аппаратуры. В общем, пытаться обуздать трёхглавого Змея Горыныча.
Иван Билибин. Змей Горыныч. 1912.
Заключение
Заинтересовавшихся в вопросах внутреннего устройства программных моделей компьютеров я хочу отослать к учебнику [1]. Электронный вариант второго издания, а также «бета-версия» третьего доступна на сайте курса «Основы программного моделирования».
В этой заметке ни слова не было сказано об ещё одном способе повышения скорости моделирования — параллельном исполнении. Об проблемах, связанных с построением таких симуляторов, и их решениях рассказывается в другой серии постов на Intel Developer Zone: 0, 1, 2, 3.
Симуляторы компьютерных систем – похожи ли на реальность
Простым и доступным языком про основные термины из области симуляторов, а также типы и уровни детализации моделей. Материал для легкого и быстрого знакомства с данным направлением.
Если бы меня спросили про симуляцию некоторое время назад, то первое, что пришло бы в голову – это мой сын, рассказывающий о своем больном животе накануне контрольной в школе. Однако последние десять лет я работаю с симуляторами различных компьютерных систем, от телефонов до серверов, основанных на микропроцессорах, SOC-ах (System-On-Chip) и чипсетах одного из крупнейших производителей (к сожалению, название под NDA), и мое представление о симуляции поменялось. Но обо всем по порядку.
Я уверен, что многие из вас сталкивались с симуляторами, которые часто называют виртуальными машинами, гипервизорами. Кто-то устанавливает Parallels Studio себе на Mac, чтобы запускать Windows из MacOS, кто-то пользуется продуктом от VmWare – Workstation, чтобы иметь еще одну операционную систему (ОС), запущенную внутри уже установленной. Те, кто знаком с Linux, предпочитают KVM и QEMU. Также популярен в народе VirtualBox. Люди, профессионально занимающиеся разработкой аппаратуры на базе ПЛИС (Программируемая Логическая Интегральная Схема), знают про VCS от Synopsys и Mentor Graphics Questa. И все же это лишь небольшая часть того, что можно называть симуляторами.
Что такое симулятор?
Симулятором называют модель, как правило, программную, реального устройства. Соответственно, симуляция – это процесс работы такой модели, повторяющий работу устройства.
В принципе, можно сделать модель любого устройства, но наиболее распространенными являются симуляторы микропроцессорных устройств, то есть устройств, центральным компонентом которых является микропроцессор, и вокруг него уже строится остальная логика. Один из основных вариантов использования симулятора – это запуск программ, предназначенных для этого самого микропроцессора. При этом использование реального устройства по тем или иным причинам затруднительно, например, его может просто еще не существовать, если речь идет о моделировании будущего поколения микропроцессоров.
Airbnb в симуляции – гость и хост
Код, запускаемый внутри симулятора, называют «гостевым кодом», это может быть «гостевая программа» или целая «гостевая операционная система». Сама симулируемая система называется просто «гость». В свою очередь, система, компьютер, где запускается симулятор, называется «хостом» (англ. host), а операционная система, работающая на хосте, в которой запускается симулятор, называется «хостовой ОС».
Таким образом, можно сказать, что симулятор, реализующий определенный набор инструкций гостевой системы, моделирует их, используя имеющиеся в наличии средства хостовой системы.
Симуляция и эмуляция – какое название правильное?
Модель может повторять устройство с разной степенью точности и детализации. Часто это симуляция только внешнего поведения системы, доступного программному коду. Коду ведь «все равно», как именно внутри реализована та или иная инструкция процессора, – главное, чтобы работало. Такой вариант симуляции распространен, не сложен в разработке и довольно быстрый, не тормозит даже на обычных пользовательских компьютерах.
Однако этого недостаточно, если мы хотим узнать, например, сколько времени будет выполняться программа на реальной аппаратуре. Для этого необходимо моделирование не только внешнего поведения, но и повторение внутренней структуры и логики работы. Это тоже может быть выполнено с разной степенью детализации и точности. Такие модели правильнее называть эмуляторами, которые действительно эмулируют устройство, а не «симулируют» результаты.
Создание эмуляторов гораздо сложнее из-за большего объема функциональности, которую необходимо реализовывать в модели. Также они функционируют намного медленнее по сравнению с симуляторами внешнего поведения устройства. С эмуляторами речь вообще не идет о запуске Windows – это может занять годы. Никто не занимается созданием программного эмулятора целиком всей платформы – это очень долго и дорого. Вместо этого эмулируются отдельные компоненты системы, такие как тот же центральный процессор, и на нем запускается лишь часть симуляционного процесса. Возможны различные гибридные схемы, когда часть симулятора является верхнеуровневой моделью, часть низкоуровневой, часть в ПЛИС, а часть вообще реальная железка.
4 уровня детализации симуляции
Как я написал выше, наиболее распространенным является вариант симуляции на уровне инструкций процессора, так называемый ISA (Instruction Set Architecture), или, точнее, результата их выполнения, т.е. без эмуляции всей внутренней логики того, как это происходит в реальном процессоре, и без учета времени выполнения различных инструкций. Именно такие симуляторы называют еще функциональными. Так работают VirtualBox, Vmware Workstation, Wind River Simics, KVM и QEMU. Это позволяет удобно, без лишних дополнительных действий запускать программы, предназначенные для симулируемого устройства. Другими словами, не требуется ни перекомпиляция, ни какие-либо другие манипуляции с запускаемыми программами. В таких случаях говорят, что возможен запуск немодифицированного бинарного кода.
Если говорить про более высокий уровень абстракции, то это будет реализация определенного ABI (Application Binary Interface). В двух словах, ABI описывает бинарный интерфейс взаимодействия двух программ – как правило, пользовательской программы и библиотеки или ОС. ABI покрывает соглашения о вызовах (как передавать параметры и возвращать значения), размеры типов данных, выполнение системных вызовов. Как это работает? Например, если программе, написанной для Linux, необходимо создать дополнительный тред (от англ. thread – нить) выполнения, то вызывается функция pthread_create(). А что, если сделать библиотеку с такой функцией в Windows и реализовать необходимые механизмы связывания приложения и библиотеки (динамической линковки)? В таком случае можно будет запускать Linux приложения из Windows. Windows будет «симулировать» Linux. Именно это и было сделано в Windows subsystem for Linux в Windows 10, что позволяет запускать немодифицированные бинарные Linux приложения в Windows.
Теперь посмотрим, как выглядят более низкоуровневые и детальные уровни симуляции. Это будет уровень микроархитектуры, при котором симулируются реальные внутренние алгоритмы и блоки процессора, такие как декодер инструкций, очереди, блок внеочередной обработки, предсказатель переходов, кэш, планировщик и сами счетные устройства. Такое моделирование позволяет анализировать реальную скорость выполнения программ и, например, оптимизировать их под уже имеющиеся архитектуры. А в случае симуляции прототипов будущих микропроцессоров возможны предсказание и оценка производительности этих устройств.
Ниже уровня микроархитектурной симуляции идет уровень эмуляции логических элементов, из которых и состоят современные чипы. Такие эмуляторы бывают и программными, и аппаратными с использованием ПЛИС. Логика ПЛИС описывается с помощью RTL (Register Transfer Level) на языках Verilog, VHDL и др. После компиляции получается образ (bitstream), который потом прошивается в ПЛИС. Причем для этого необязательно пользоваться паяльником и разбираться в электротехнике. Плата подсоединяется к компьютеру, например, по USB или JTAG интерфейсу, а специальный софт от производителя ПЛИС платы выполняет запись. Стоимость таких плат начинается от десяти долларов за простейшие варианты до миллионов долларов для больших ПЛИС стендов размером со шкаф, используемых в крупных компаниях-производителях чипов. В таких компаниях симуляция с использованием ПЛИС является финальной стадией перед отдачей RTL в производство.
Если речь идет о несложных устройствах, то, имея на руках образ ПЛИС, можно обратиться в специализированные компании, которые сделают настоящее (не ПЛИС) устройство с запрограммированной логикой.
На рисунке ниже показаны описанные уровни симуляции.
Кроме этих уровней моделирования, мне также приходилось сталкиваться с гибридными симуляторами. По сути, они представляют собой соединенные друг с другом симуляторы, моделирующие на разных уровнях разные части системы. Например, необходим анализ пропускной способности новой сетевой карты, работающей вместе с разрабатываемым драйвером для определенной ОС. Такое сетевое устройство, а также ряд смежных устройств, могут быть реализованы сначала на микроархитектурном уровне для предварительного анализа, а потом и в ПЛИС, на уровне логических элементов, для финальных проверок. При этом остальная часть системы, задействованная лишь частично, реализуется на уровне инструкций. Обойтись без нее нельзя, так как она необходима, например, для загрузки ОС, а реализовывать ее на более низком и сложном уровне не имеет смысла.
Так что же на счет сравнения симуляторов и реальности?
Как теперь понятно, нет задачи сделать тот или иной симулятор максимально похожим на реальность. Есть задача, которую ставит бизнес, и симуляция выполняется со той степенью “похожести” на реальность, который является минимально достаточным для решения этой задачи, не тратя при этом лишних денег и времени. В одном случае это может быть простая библиотека, реализующая необходимый бинарный интерфейс (ABI), а в другом не обойтись без детального микроархитектурного симулятора.
Это самая базовая информация о том, что такое симуляторы и какие они бывают. В следующей статье я опишу детали реализации полноплатформенных симуляторов, потактовых моделей и работу с трассами.