Ранее в сериале… Ах, да, не все технари уважают сериалы. Тем не менее, слово Simics уже было написано в заголовке и мне не отвертеться от того, что все последующее будет своеобразным практическим продолжением материала «Симуляторы компьютерных систем – похожи ли на реальность» моего коллеги @alex_dzen.          Из этих трех статей мы знаем, что есть такие симуляторы аппаратного обеспечения и ими пользуются серьезные дядьки из больших компаний. Наверное, меня тоже можно отнести к этим «дядькам», но у меня есть одна слабость — на досуге я люблю что-нибудь паять и использую для проектов «несерьезную» среду Arduino, где в качестве процессоров применяется что-нибудь из «несерьезных» Atmel-ARM или ESP32-RISC. И интрига в том, можно ли использовать Simics для небольших и хобби-проектов? Тихо, и без особого шума Intel выпустил общедоступную версию полноплатформенного симулятора Simics. По ссылке, ознакомившись и согласившись с лицензией, можно скачать базовый набор пакетов. В него входят: собственно симулятор, модели процессоров Intel с ядром Nehalem1, чипсета X58, модели нескольких типовых x86 компьютеров, пакет с Clear Linux (подготовленный к запуску в Simics) и некоторый набор учебных материалов. В публичную версию не вошел пакет Simics Eclipse. Однако разработку кода можно вести и в Visual Studio, в Notepad++, есть даже попытки «прикрутить» Simics к Qt Creator. Все это добро разворачивается специальным установщиком Intel, который нужно скачать там же. Если, дочитав до этого места, вы уже решили, что это не для вас, не спешите. Несмотря на кажущийся минимальный набор, да еще и «устаревшие» модели процессоров, базовый пакет вполне самодостаточен, например, для разработки моделей и отладки драйверов устройств на шине PCI, USB1/2/3, I2C/I3C и т. д. Если же вы являетесь полноправным пользователем Xtensa SDK, то несложный интерфейс позволяет подключать к Simics любые процессоры, поддерживаемые Xtensa. А если немного пошарить среди примеров и файлов, то окажется, что можно моделировать и встраиваемые системы на базе RISC-процессоров. Вот это как раз то, что я и искал для себя. Я предлагаю вместе со мной смоделировать небольшую встраиваемую систему на базе RISC-процессора, ПЗУ, ОЗУ. По мере продвижения, я предлагаю добавить в систему защиту памяти, последовательный порт и пару новых инструкций для нашего процессора, позаимствовав их из существующих решений. Чтобы не создавать модель процессора совсем уж с нуля (что, впрочем, вполне возможно даже в публичной версии) мы возьмем модель процессора sample-risc из расширенных примеров. Скопируем ее себе в рабочий каталог Simics Скомпилируем Теперь все готово чтобы собрать простейшую конфигурацию, состоящую из процессора и ОЗУ: Сделаем это прямо из командной строки Simics: И вот, у нас уже работают команды Simics чтения и записи в память: BE — означает, что память у нас «big-endian», как и полагается нашему RISC процессору. Обратите внимание, что строки, указанные в качестве первых параметров Python-функции pre_conf_object(), стали именами объектов в Simics. Прочитанное значение выведено в десятичном формате. Однако, нам привычнее 16-ти разрядная система счисления в контексте электроники и чипов: Память доступна, а значит уже можно вручную оттранслировать и записать в память программу и ее данные ;-) Как это выглядит можно посмотреть в тестах на модель sample-risc. Например, файл s-add.py демонстрирует инструкцию add r1, r2. Чтобы не набирать все вышеприведенные команды каждый раз, давайте создадим компонент, интегрирующий в нашу систему процессор и память. В рабочем каталоге Simics, в подкаталоге modules создадим папку myrisc-comp. И в ней файлы. Файл Makefile:  Файл module_load.py: Этот файл будет загружен и исполнен автоматически при выполнении команды load-module <module>. В нем находится код регистрирующий объекты модели и добавляющий им специфические команды. Мы еще вернемся к module_load.py и с его помощью расширим функционал модели. Файл myrisc_comp.py: В последнем файле мы видим уже знакомые нам команды, создающие те или иные объекты модели. Только вместо вызова pre_conf_object() используется метод add_pre_obj() из класса StandardComponent. Это позволяет вместо плоского набора объектов получить их иерархию. Мы это увидим чуть позже. Скомпилируем: Теперь модель нашего контроллера можно загрузить в Simics тремя командами: Посмотрим, как выглядит иерархия объектов модели контроллера: Но и три команды много ;-) Сделаем отдельный скрипт для запуска модели. В рабочем каталоге Simics, в подкаталоге targets, файл myrisc.simics:  Теперь вся модель может быть загружена одной командой: Подведем промежуточный итог наших усилий. Мы автоматизировали создание нашей модели. Несмотря на то, что, казалось бы, три команды ввести несложно, автоматизация важна с той точки зрения, что создание модели не является самоцелью. Целью является ее многократный запуск при написании и отладке прошивки, при отладке взаимодействия с другими устройствами и системами (возможно, физическими) и, вероятно, даже долговременная работа в качестве замены подсистемы, которая еще не создана в железе.    Осталось проверить что наш контроллер все также позволяет работать с памятью: На этом пока, пожалуй, стоит остановиться чтобы подумать и передохнуть… Но мы ведь с вами не закончили. Вы помните? Нам предстоит, еще как минимум — добавить ПЗУ, защиту памяти и последовательный порт. Не переключайтесь. [1] Intel Core i7©, Intel Xeon 5500©, 5530, Intel Atom© Инженер-разработчик ПО