惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
IT之家
IT之家
H
Heimdal Security Blog
Jina AI
Jina AI
宝玉的分享
宝玉的分享
博客园 - 【当耐特】
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
爱范儿
爱范儿
T
Tailwind CSS Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Apple Machine Learning Research
Apple Machine Learning Research
有赞技术团队
有赞技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
AWS News Blog
AWS News Blog
C
Cisco Blogs
Cisco Talos Blog
Cisco Talos Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
D
Darknet – Hacking Tools, Hacker News & Cyber Security
The Hacker News
The Hacker News
The Cloudflare Blog
Hugging Face - Blog
Hugging Face - Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Threatpost
S
Securelist
P
Privacy International News Feed
C
CXSECURITY Database RSS Feed - CXSecurity.com
博客园 - 聂微东
博客园 - 叶小钗
J
Java Code Geeks
V
V2EX
博客园 - Franky
Spread Privacy
Spread Privacy
K
Kaspersky official blog
C
Cyber Attacks, Cyber Crime and Cyber Security
Simon Willison's Weblog
Simon Willison's Weblog
Project Zero
Project Zero
大猫的无限游戏
大猫的无限游戏
S
SegmentFault 最新的问题
C
Cybersecurity and Infrastructure Security Agency CISA
C
CERT Recently Published Vulnerability Notes
Latest news
Latest news
NISL@THU
NISL@THU
罗磊的独立博客
W
WeLiveSecurity
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园_首页
V
Visual Studio Blog

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Сравнительный анализ RISC-V микропроцессоров picorv32 и scr1 при использовании в FPGA
nckma · 2026-04-24 · via Все публикации подряд на Хабре

Уровень сложностиСредний

Время на прочтение37 мин

Охват и читатели216

Разработчики FPGA часто сталкиваются с необходимостью внедрения в свой проект софт процессора. Когда-то давно мы могли использовать проприетарные Altera NIOS или Xilinx MicroBlase. Но время идет. В последние годы наблюдается устойчивый тренд перехода производителей ПЛИС в сторону поддержки архитектуры RISC-V.

RISC-V это открытая, расширяемая и бесплатная архитектура набора команд (ISA), которая не требует лицензионных отчислений. Оба FPGA вендора Altera и Xilinx уже довольно давно предлагают и активно разрабатывают поддержку RISC-V в своих новых продуктах, теперь это уже софт процессоры NIOS V и MicroBlase V для FPGA.

Однако, зачем использовать всё ещё проприетарные ядра, если можно использовать Open Source?

В этой статье я сравниваю два Open Source RISC-V микропроцессора:
1) picorv32 от компании YoSys (https://github.com/YosysHQ/picorv32) и
2) scr1 от Syntacore (https://github.com/syntacore/scr1)

Что буду сравнивать? Производительность софт ядер и занимаемые ресурсы в ПЛИС.
Как правильно сравнить? Использовать единую тестовую программу написанную на языке C, например Dhrystone, и скомпилированную в бинарный файл, или HEX файл и запускаемую в двух архитектурно одинаковых SOC, но с разными ядрами RISC-V.

Интересно, что в исходниках picorv32 есть тест Dhrystone и в исходниках scr1 есть тест Dhrystone, но у них хоть и похожие, но всё же разные файлы по содержимому! Кроме этого, разработчики этих ядер ссылаются на разные тулчейны для сборки. Согласитесь, что не совсем верно собирать единую прошивку разными компиляторами. Для чистоты эксперимента я буду использовать один компилятор взятый вот отсюда: https://syntacore.com/tools/development-tools У меня получится одна "прошивка" для двух разных SOC и тогда это будет самое объективное сравнение.

Еще одно замечание: RISC-V архитектура подразумевает конфигурируемость. Если мало ресурсов в ПЛИС, то можно использовать урезанную версию процессора и у него будет к примеру не 32 регистра общего назначения, а только 16. Или можно сделать версию процессора без умножителя. Вариантов конфигураций процессора может быть довольно много, но чтобы сильно не заморачиваться я остановился на двух конфигурациях:

  1. минимальная, 16 регистров, без аппаратного умножителя, но с поддержкой сжатых инструкций

  2. максимальная, 32 регистра, с умножителем, с поддержкой сжатых инструкций.

Таким образом, мои тесты коснутся двух разных ядер в двух разных конфигурациях.

Запускать эти SOC я буду на платах Марсоход3 с чипом FPGA MAX10 50K логических элементов и на плате Марсоход3бис с чипом FPGA MAX10 8K логических элементов.

Кроме этого, я буду запускать тестбенчи для всех этих четырех случаев.

Исходники моего проекта для сравнения ядер находятся на github https://github.com/marsohod4you/riscv-compare Учтите, что этот проект включает в себя субмодули git для каждого из ядер scr1 и picorv32.

Ключевые особенности проекта PicoRV32, YosysHQ

PicoRV32 — это компактное и гибкое ядро процессора, реализующее архитектуру RISC-V (RV32IMC) и предназначенное для использования в FPGA и ASIC. Основные особенности:

  • Оптимизация по размеру и частоте.

  • Гибкая конфигурация: поддерживает разные варианты системы команд — RV32E, RV32I, RV32IC, RV32IM, RV32IMC.

  • Можно отключать регистры x16…x31, инструкции RDCYCLE[H], RDTIME[H], RDINSTRET[H], что уменьшает размер ядра.

  • Интерфейсы: доступны три варианта ядра с разными шинами — простой native-интерфейс, AXI4-Lite (picorv32_axi) и Wishbone (picorv32_wb), что облегчает интеграцию в различные системы.

Опциональные возможности:

  • Встроенный контроллер прерываний IRQ.

  • Интерфейс сопроцессора (PCPI) для расширения системы команд.

  • Поддержка аппаратных умножителя/делителя и barrel-shifter.

  • Возможность выбора между одно- и двухпортовой организацией регистрового файла для баланса между скоростью и размером.

  • Тестирование и поддержка: в проекте есть множество тестбенчей, примеры SoC, готовые прошивки и скрипты для сборки и симуляции (Icarus Verilog, GtkWave), а также подробные инструкции по сборке и запуску на различных платах.

  • Лицензия: ядро распространяется по лицензии ISC (аналог MIT/BSD), что позволяет свободное использование в коммерческих и открытых проектах.

Применение: хорошо подходит как вспомогательный процессор в FPGA/ASIC, для образовательных целей, прототипирования SoC и встраиваемых решений.

Предполагаемое использование микропроцессора в FPGA совместно с внешней SPI Flash памятью, где хранится программа. Встроенная в SOC статическая память, по умолчанию всего 1 килобайт служит кэшем / scratchpad для внешней flash памяти. Таким образом не нужно заботиться о минимизации размера кода пользовательских программ.

Вот типовая блок схема SOC, которую рекомендует YosysHQ:

Рекомендуемая схема SOC с подключением внешней FLASH

Рекомендуемая схема SOC с подключением внешней FLASH

В своём же проекте для сравнения характеристик picorv32 и scr1 я буду делать совсем не так, а гораздо проще. У меня не будет внешней флэш памяти, а всю тестовую программу Dhrystone я размещу в статической памяти ПЛИС 32 килобайта в адресном пространстве микропроцессора по адресу ноль. При включении процессора он будет сразу читать и исполнять команды с адреса ноль. Никаких прерываний я не буду использовать. Вот такая будет моя простая система на кристалле:

Моя picorv32 soc

Моя picorv32 soc

В моей простейшей SOC на основе picorv32 будет только процессор, и на шине данных статическая память программ и данных, последовательный порт, регистр 7ми сегментного индикатора и регистр на запись используемый во время симуляции. Когда программа запишет в этот регистр что ни будь - симулятор остановит свою работу.

На семи-сегментном индикаторе я буду отображать результат измерения производительности в Dhrystone.

Ключевые особенности проекта SCR1

Syntacore SCR1 — это высококачественное открытое ядро микроконтроллера, совместимое с архитектурой RISC-V, разработанное и поддерживаемое компанией Syntacore, сейчас Yadro. Основные особенности проекта:

  • Открытая лицензия: ядро распространяется по лицензии SHL, что позволяет неограниченное коммерческое использование, что редко встречается среди ядер, поддерживаемых коммерческими компаниями.

  • Поддержка архитектурных расширений: реализует базовый набор команд RV32I или RV32E с возможностью подключения расширений RVM (умножение/деление) и RVC (сжатые инструкции).

  • Режимы привилегий: поддерживает только машинный режим привилегий (Machine mode), что характерно для микроконтроллерных ядер.

  • Конвейер: 2–4 стадии, в зависимости от конфигурации, что позволяет балансировать между производительностью и площадью.

  • Интерфейсы: 32-битный внешний интерфейс AXI4 или AHB-Lite для интеграции с периферией и памятью.

  • Интегрированный программируемый контроллер прерываний (до 16 линий IRQ);

  • Отладочная подсистема с интерфейсом JTAG;

  • Опциональная тесно связанная память (TCM) для ускорения доступа к критичным данным.

  • Язык описания: написан на SystemVerilog, что обеспечивает хорошую переносимость и поддержку в современных EDA-средах.

  • Оптимизация: ядро оптимизировано по площади и энергопотреблению, подходит для MCU-класса и встраиваемых решений.

  • Гибкая конфигурация: доступны три предопределённые конфигурации (MAX, BASE, MIN), а также множество параметров для тонкой настройки под конкретные задачи.

  • Верификация и документация: проект сопровождается обширной документацией, тестовыми наборами (включая тесты на соответствие RISC-V ISA, Dhrystone, CoreMark), а также примерами для быстрого старта.

  • Поддержка симуляторов и платформ: совместим с основными промышленными симуляторами (Verilator, ModelSim, VCS, NCSim),

  • Поддерживается сборка и запуск на популярных отладочных платах (Arty, Nexys 4 DDR, DE10-Lite и др.).

  • Экосистема: к ядру прилагается SDK с загрузчиком, поддержкой Zephyr RTOS, примерами программного обеспечения и руководствами пользователя. SCR1 — одно из самых популярных открытых ядер RISC-V для микроконтроллеров, широко используемое как в образовательных, так и в коммерческих проектах.

Российский RISC-V микроконтроллер Амур кажется использует очень похожее ядро, возможно это же самое (но это не точно).

Свою SOC на основе SCR1 я так же делаю минимально возможной. В процессоре уже есть встроенная TCM (Tightly Coupled Memory) память. С помощью кастомной конфигурации проекта я устанавливаю её размер в 32К и размещаю её по адресу ноль. Мой процессор так же будет стартовать с адреса ноль прямо в TCM. Прерывания я не использую. На внешней шине ставлю по тем же адресам последовательный порт, регистр семи-сегментного индикатора и регистр останова при симуляции:

Моя scr1 SOC

Моя scr1 SOC

Таким образом, архитектурно обе проектируемые мною SOC будут идентичными:

// 8K 32bit words = 32Kbytes memory localparam 
MEM_SIZE = (1024*32); //at address zero 
localparam SERIAL_PORT_ADDR = 32’h1000_0000; 
localparam SEG7_PORT_ADDR = 32’h1000_0004; 
localparam SIMSTOP_PORT_ADDR = 32’h1000_1000;

Компилируем программу Dhrystone

Склонируйте мой проект с github вместе с субмодулями:

git clone --recurse-submodules https://github.com/marsohod4you/riscv-compare.git

Перейдите в директорию Си проекта:

cd riscv-compare/dhrystone-fw/

Возможно вам потребуется исправить в скрипте build.sh строку export PATH=$PATH: и добавить туда именно ваши пути к тулчейну risc-v и к питону. Напомню, что я использую тулчейн взятый вот здесь: https://syntacore.com/tools/development-tools

Запустите скрипт build.sh с параметром EC или IM. Эти параметры как раз будут определять какой код генерировать. EC это для процессора с минимальной конфигурацией, embedded, компилятор gcc будет использовать только 16 регистров, не будет использовать операции умножения, но будет использовать сжатый код. Сжатый код позволяет использовать короткие 16ти битные команды процессора если это возможно. Это позволяет экономить место программы. При этом 32х битные инструкции конечно всё еще доступны.

Если задать параметр IM, то скрипт будет генерировать код с учетом наличия 32х регистров и используя команды умножения если нужно.

Компилирую скриптом:

./build.sh IM

./build.sh EC

После компиляции появятся новые директории riscv-compare/dhrystone/done_ec и riscv-compare/dhrystone/done_im. В них результирующие файлы и вы можете поизучать их. В файле dhry.dump например можно посмотреть ассемблерный код полученный в результате сборки. Обратите внимание, что в файле riscv-compare/dhrystone/done_im/dhry.dump вы найдёте гораздо большее число используемых регистров. Кроме того, там будет использование команд типа mulhu, а в EC дампе вместо этого вы встретите вызов подпрограмм типа jal <__mulsi3>.

Файлы используемые для симуляции и для сборки FPGA проекта это обычно *.hex. Эти файлы так же создаются.

Этот же скрипт скопирует результирующие файлы куда нужно и для симуляции и для проектов Quartus Prime для компиляции FPGA проектов.

Симуляция работы SOC с RISC-V ядрами.

Симулировать проект picorv32 SOC очень просто даже с помощью Icarus Verilog - но он должен быть заранее установлен у вас. Это возможно потому, что всё ядро описано на Verilog HDL. И всё ядро это один файл picorv32.v.

Перейдите в папку riscv-compare/FPGA/m3-picorv32/sim и запустите скрипт симулятора опять же с параметром EC или IM:

cd ./riscv-compare/FPGA/m3-picorv32/sim ./simulate.sh IM

Этот скрипт и компилирует и симулирует. В результате вы сможете увидеть вот такой вывод:

$ ./simulate.sh IM
Simulate for CPU with mul/dev and 32 regs
Firmware Boot File exists: dhry_im.hex
Simulation with FW Boot File for CPU with MUL/DIV instructions number of REGs=32
Simulation Config for CPU with MUL/DIV and number of REGs=32
VCD info: dumpfile testbench.vcd opened for output.
START

Dhrystone Benchmark, Version 2.1 (Language: C)

Program compiled without 'register' attribute

Execution starts, 500 runs through Dhrystone
Execution ends

Final values of the variables used in the benchmark:

Int_Glob:            5
        should be:   5
Bool_Glob:           1
        should be:   1
Ch_1_Glob:           A
        should be:   A
Ch_2_Glob:           B
        should be:   B
Arr_1_Glob[8]:       7
        should be:   7
Arr_2_Glob[8][7]:    510
        should be:   Number_Of_Runs + 10
Ptr_Glob->
  Ptr_Comp:          12540
        should be:   (implementation-dependent)
  Discr:             0
        should be:   0
  Enum_Comp:         2
        should be:   2
  Int_Comp:          17
        should be:   17
  Str_Comp:          DHRYSTONE PROGRAM, SOME STRING
        should be:   DHRYSTONE PROGRAM, SOME STRING
Next_Ptr_Glob->
  Ptr_Comp:          12540
        should be:   (implementation-dependent), same as above
  Discr:             0
        should be:   0
  Enum_Comp:         1
        should be:   1
  Int_Comp:          18
        should be:   18
  Str_Comp:          DHRYSTONE PROGRAM, SOME STRING
        should be:   DHRYSTONE PROGRAM, SOME STRING
Int_1_Loc:           5
        should be:   5
Int_2_Loc:           13
        should be:   13
Int_3_Loc:           7
        should be:   7
Enum_Loc:            1
        should be:   1
Str_1_Loc:           DHRYSTONE PROGRAM, 1'ST STRING
        should be:   DHRYSTONE PROGRAM, 1'ST STRING
Str_2_Loc:           DHRYSTONE PROGRAM, 2'ND STRING
        should be:   DHRYSTONE PROGRAM, 2'ND STRING

BeginTime 57844 EndTime 789033 UserTime 731189
Number_Of_Runs= 500, HZ= 1000000
Time: begin= 57844, end= 789033, diff= 731189
Microseconds for one run through Dhrystone: 1462
Dhrystones per Second:                      683
Cycles_Per_Instruction: 5.623
Seg4x7 register Written 00000683
DONE
../soc.v:135: $finish called at 963340000000 (1ps)

Если есть желание, можно детально рассмотреть все сигналы в проекте с помощью gtkwave и сгенерированного testbench.vcd файла.

Симулировать scr1 проект не так просто. Scr1 написан на SystemVerilog и Icarus его почти не поддерживает. Здесь нужен Verilator. Проще всего его конечно установить и использовать в среде Linux.

Я так же приготовил скрипт для симуляции.

Перейдите в директорию riscv-compare/FPGA/m3-scr1/sim и запустите скрипт симуляции

cd ./riscv-compare/FPGA/m3-scr1/sim ./simulate.sh IM

Скрипт последовательно и компилирует и симулирует используя Verilator. Вывод скрипта содержит вот такой длинный текст:

Скрытый текст

Simulate for CPU with mul/dev and 32 regs Firmware Boot File exists: dhry32_im.hex


*** Patching SCR1 project… ***


Patching SCR1 project done…


*** Compile with Verilator… ***


rm: cannot remove ‘obj_dir’: Is a directory %Warning-TIMESCALEMOD: …/…/m3-scr1/max10.v:4:8: Timescale missing on this module as other modules have it (IEEE 1800-2023 3.14.2.3) 4 | module max10( | ^~~~~ …/…/common/generic_fifos/rtl/verilog/generic_fifo_dc_gray.v:123:8: … Location of module with timescale 123 | module generic_fifo_dc_gray( rd_clk, wr_clk, rst, clr, din, we, | ^~~~~~~~~~~~~~~~~~~~ … For warning description see https://verilator.org/warn/TIMESCALEMOD?v=5.037 … Use “/* verilator lint_off TIMESCALEMOD /" and lint_on around source to disable this message. %Warning-TIMESCALEMOD: …/…/common/sserial.v:3:8: Timescale missing on this module as other modules have it (IEEE 1800-2023 3.14.2.3) 3 | module sserial( | ^~~~~~~ …/…/common/generic_fifos/rtl/verilog/generic_fifo_dc_gray.v:123:8: … Location of module with timescale 123 | module generic_fifo_dc_gray( rd_clk, wr_clk, rst, clr, din, we, | ^~~~~~~~~~~~~~~~~~~~ %Warning-TIMESCALEMOD: …/…/common/generic_fifos/rtl/verilog/generic_dpram.v:99:8: Timescale missing on this module as other modules have it (IEEE 1800-2023 3.14.2.3) 99 | module generic_dpram( | ^~~~~~~~~~~~~ …/…/common/generic_fifos/rtl/verilog/generic_fifo_dc_gray.v:123:8: … Location of module with timescale 123 | module generic_fifo_dc_gray( rd_clk, wr_clk, rst, clr, din, we, | ^~~~~~~~~~~~~~~~~~~~ %Warning-TIMESCALEMOD: …/…/…/FPGA/m3-scr1/seg4x7.v:1:8: Timescale missing on this module as other modules have it (IEEE 1800-2023 3.14.2.3) 1 | module seg4x7( | ^~~~~~ …/…/m3-scr1/max10.v:197:1: … note: In file included from ‘max10.v’ …/…/common/generic_fifos/rtl/verilog/generic_fifo_dc_gray.v:123:8: … Location of module with timescale 123 | module generic_fifo_dc_gray( rd_clk, wr_clk, rst, clr, din, we, | ^~~~~~~~~~~~~~~~~~~~ %Warning-IMPLICIT: …/…/m3-scr1/max10.v:108:30: Signal definition not found, creating implicitly: ‘tdo’ : … Suggested alternative: ‘tdi’ 108 | .tdo (tdo ), | ^~~ … For warning description see https://verilator.org/warn/IMPLICIT?v=5.037 … Use "/ verilator lint_off IMPLICIT /" and lint_on around source to disable this message. %Warning-IMPLICIT: …/…/m3-scr1/max10.v:109:30: Signal definition not found, creating implicitly: ‘tdo_en’ 109 | .tdo_en (tdo_en ), | ^~~~~~ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_hdu.svh:21:25: Operator VAR ‘SCR1_HDU_DEBUGCSR_ADDR_SPAN’ expects 32 bits on the Initial value, but Initial value’s VARREF ‘SCR1_CSR_ADDR_HDU_MSPAN’ generates 12 bits. : … note: In instance ‘max10’ 21 | localparam int unsigned SCR1_HDU_DEBUGCSR_ADDR_SPAN = SCR1_CSR_ADDR_HDU_MSPAN; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_top.sv:17:1: … note: In file included from ‘scr1_pipe_top.sv’ … For warning description see https://verilator.org/warn/WIDTHEXPAND?v=5.037 … Use "/ verilator lint_off WIDTHEXPAND /" and lint_on around source to disable this message. %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dmi.sv:70:41: Operator ADD expects 32 or 5 bits on the RHS, but RHS’s VARREF ‘SCR1_DBG_DMI_OP_WIDTH’ generates 2 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dmi’ 70 | localparam DMI_OP_HI = DMI_OP_LO + SCR1_DBG_DMI_OP_WIDTH - 1; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_dm.svh:19:76: Operator ADD expects 6 bits on the LHS, but LHS’s VARREF ‘SCR1_DBG_DMI_OP_WIDTH’ generates 2 bits. : … note: In instance ‘max10’ 19 | parameter SCR1_DBG_DMI_DR_DMI_ACCESS_WIDTH = SCR1_DBG_DMI_OP_WIDTH + | ^ …/…/…/riscv-cores/scr1/src/core/scr1_tapc_synchronizer.sv:11:1: … note: In file included from ‘scr1_tapc_synchronizer.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_hdu.svh:123:99: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_HDU_DBGCSR_OFFS_DPC’ generates 2 bits. : … note: In instance ‘max10’ 123 | localparam bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_HDU_DBGCSR_ADDR_DPC = SCR1_CSR_ADDR_HDU_MBASE + SCR1_HDU_DBGCSR_OFFS_DPC; | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_top.sv:17:1: … note: In file included from ‘scr1_pipe_top.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_hdu.svh:124:99: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_HDU_DBGCSR_OFFS_DSCRATCH0’ generates 2 bits. : … note: In instance ‘max10’ 124 | localparam bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_HDU_DBGCSR_ADDR_DSCRATCH0 = SCR1_CSR_ADDR_HDU_MBASE + SCR1_HDU_DBGCSR_OFFS_DSCRATCH0; | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_top.sv:17:1: … note: In file included from ‘scr1_pipe_top.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_csr.svh:120:65: Operator SHIFTL expects 32 bits on the LHS, but LHS’s VARREF ‘SCR1_MISA_MXL_32’ generates 2 bits. : … note: In instance ‘max10’ 120 | parameter bit [32-1:0] SCR1_CSR_MISA = (SCR1_MISA_MXL_32 << (32-2)) | ^~ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_tracelog.sv:9:1: … note: In file included from ‘scr1_tracelog.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_csr.svh:84:96: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_IPIC_CISV’ generates 3 bits. : … note: In instance ‘max10’ 84 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_CISV = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_CISV ); | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_tracelog.sv:9:1: … note: In file included from ‘scr1_tracelog.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_csr.svh:85:96: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_IPIC_CICSR’ generates 3 bits. : … note: In instance ‘max10’ 85 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_CICSR = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_CICSR); | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_tracelog.sv:9:1: … note: In file included from ‘scr1_tracelog.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_csr.svh:86:96: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_IPIC_IPR’ generates 3 bits. : … note: In instance ‘max10’ 86 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_IPR = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_IPR ); | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_tracelog.sv:9:1: … note: In file included from ‘scr1_tracelog.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_csr.svh:87:96: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_IPIC_ISVR’ generates 3 bits. : … note: In instance ‘max10’ 87 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_ISVR = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_ISVR ); | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_tracelog.sv:9:1: … note: In file included from ‘scr1_tracelog.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_csr.svh:88:96: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_IPIC_EOI’ generates 3 bits. : … note: In instance ‘max10’ 88 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_EOI = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_EOI ); | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_tracelog.sv:9:1: … note: In file included from ‘scr1_tracelog.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_csr.svh:89:96: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_IPIC_SOI’ generates 3 bits. : … note: In instance ‘max10’ 89 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_SOI = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_SOI ); | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_tracelog.sv:9:1: … note: In file included from ‘scr1_tracelog.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_csr.svh:90:96: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_IPIC_IDX’ generates 3 bits. : … note: In instance ‘max10’ 90 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_IDX = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_IDX ); | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_tracelog.sv:9:1: … note: In file included from ‘scr1_tracelog.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_csr.svh:91:96: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_IPIC_ICSR’ generates 3 bits. : … note: In instance ‘max10’ 91 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_ICSR = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_ICSR ); | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_tracelog.sv:9:1: … note: In file included from ‘scr1_tracelog.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_hdu.svh:122:99: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_HDU_DBGCSR_OFFS_DCSR’ generates 2 bits. : … note: In instance ‘max10’ 122 | localparam bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_HDU_DBGCSR_ADDR_DCSR = SCR1_CSR_ADDR_HDU_MBASE + SCR1_HDU_DBGCSR_OFFS_DCSR; | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_top.sv:17:1: … note: In file included from ‘scr1_pipe_top.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_hdu.svh:125:99: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_HDU_DBGCSR_OFFS_DSCRATCH1’ generates 2 bits. : … note: In instance ‘max10’ 125 | localparam bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_HDU_DBGCSR_ADDR_DSCRATCH1 = SCR1_CSR_ADDR_HDU_MBASE + SCR1_HDU_DBGCSR_OFFS_DSCRATCH1; | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_top.sv:17:1: … note: In file included from ‘scr1_pipe_top.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_tdu.svh:36:99: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_CSR_ADDR_TDU_OFFS_TSELECT’ generates 3 bits. : … note: In instance ‘max10’ 36 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TDU_TSELECT = SCR1_CSR_ADDR_TDU_MBASE + SCR1_CSR_ADDR_TDU_OFFS_TSELECT; | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_top.sv:21:1: … note: In file included from ‘scr1_pipe_top.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_tdu.svh:37:99: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_CSR_ADDR_TDU_OFFS_TDATA1’ generates 3 bits. : … note: In instance ‘max10’ 37 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TDU_TDATA1 = SCR1_CSR_ADDR_TDU_MBASE + SCR1_CSR_ADDR_TDU_OFFS_TDATA1; | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_top.sv:21:1: … note: In file included from ‘scr1_pipe_top.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_tdu.svh:38:99: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_CSR_ADDR_TDU_OFFS_TDATA2’ generates 3 bits. : … note: In instance ‘max10’ 38 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TDU_TDATA2 = SCR1_CSR_ADDR_TDU_MBASE + SCR1_CSR_ADDR_TDU_OFFS_TDATA2; | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_top.sv:21:1: … note: In file included from ‘scr1_pipe_top.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_tdu.svh:39:99: Operator ADD expects 12 bits on the RHS, but RHS’s VARREF ‘SCR1_CSR_ADDR_TDU_OFFS_TINFO’ generates 3 bits. : … note: In instance ‘max10’ 39 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TDU_TINFO = SCR1_CSR_ADDR_TDU_MBASE + SCR1_CSR_ADDR_TDU_OFFS_TINFO; | ^ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_top.sv:21:1: … note: In file included from ‘scr1_pipe_top.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_tdu.svh:72:25: Operator VAR ‘SCR1_TDU_MCONTROL_TYPE_VAL’ expects 4 bits on the Initial value, but Initial value’s CONST ‘2’h2’ generates 2 bits. : … note: In instance ‘max10’ 72 | SCR1_TDU_MCONTROL_TYPE_VAL = 2’d2; | ^~~~~~~~~~~~~~~~~~~~~~~~~~ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_top.sv:21:1: … note: In file included from ‘scr1_pipe_top.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_tdu.svh:78:25: Operator VAR ‘SCR1_TDU_MCONTROL_MASKMAX_VAL’ expects 6 bits on the Initial value, but Initial value’s CONST ‘1’h0’ generates 1 bits. : … note: In instance ‘max10’ 78 | SCR1_TDU_MCONTROL_MASKMAX_VAL = 1’b0; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_top.sv:21:1: … note: In file included from ‘scr1_pipe_top.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_tdu.svh:98:25: Operator VAR ‘SCR1_TDU_ICOUNT_TYPE_VAL’ expects 4 bits on the Initial value, but Initial value’s CONST ‘2’h3’ generates 2 bits. : … note: In instance ‘max10’ 98 | SCR1_TDU_ICOUNT_TYPE_VAL = 2’d3; | ^~~~~~~~~~~~~~~~~~~~~~~~ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_top.sv:21:1: … note: In file included from ‘scr1_pipe_top.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/includes/scr1_tdu.svh:101:25: Operator VAR ‘SCR1_TDU_ICOUNT_RESERVEDB_VAL’ expects 2 bits on the Initial value, but Initial value’s CONST ‘1’h0’ generates 1 bits. : … note: In instance ‘max10’ 101 | SCR1_TDU_ICOUNT_RESERVEDB_VAL = 1’b0; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_top.sv:21:1: … note: In file included from ‘scr1_pipe_top.sv’ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ialu.sv:409:30: Operator COND expects 64 bits on the Conditional False, but Conditional False’s SIGNED generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_exu.i_ialu’ 409 | assign mul_res = mdu_cmd_mul ? mul_op1 mul_op2 : $signed(‘0); | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ialu.sv:467:23: Operator COND expects 32 bits on the Conditional True, but Conditional True’s REPLICATE generates 2 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_exu.i_ialu’ 467 | ? {‘0, div_quo_bit} | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ialu.sv:506:40: Operator COND expects 33 bits on the Conditional True, but Conditional True’s SIGNED generates 2 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_exu.i_ialu’ 506 | : mdu_fsm_idle ? $signed({div_op1_is_neg, exu2ialu_main_op1_i[32-1]}) | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ialu.sv:596:58: Operator XOR expects 32 bits on the LHS, but LHS’s SEL generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_exu.i_ialu’ 596 | ialu2exu_main_res_o = 32’(~(main_sum_flags.s ^ main_sum_flags.o)); | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ialu.sv:596:58: Operator XOR expects 32 bits on the RHS, but RHS’s SEL generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_exu.i_ialu’ 596 | ialu2exu_main_res_o = 32’(~(main_sum_flags.s ^ main_sum_flags.o)); | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_ipic.sv:396:38: Operator COND expects 5 bits on the Conditional False, but Conditional False’s CONST ‘1’h0’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_ipic’ 396 | : ipic_eoi_req ? irq_eoi_req_vd ? {1’b0, irq_eoi_req_idx} | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_exu.sv:939:26: Operator COND expects 32 bits on the Conditional False, but Conditional False’s REPLICATE generates 6 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_exu’ 939 | ? mprf2exu_rs1_data_i | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_hdu.sv:550:43: Operator EQ expects 32 bits on the LHS, but LHS’s VARREF ‘pbuf_addr_ff’ generates 3 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_hdu’ 550 | assign pbuf_addr_end = (pbuf_addr_ff == (SCR1_HDU_PBUF_ADDR_SPAN-1)); | ^~ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_hdu.sv:711:24: Operator ASSIGNDLY expects 3 bits on the Assign RHS, but Assign RHS’s CONST ‘1’h0’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_hdu’ 711 | csr_dcsr_cause <= 1’b0; | ^~ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ifu.sv:450:79: Operator SUB expects 32 bits on the LHS, but LHS’s VARREF ‘q_wptr’ generates 3 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_ifu’ 450 | assign q_free_h_next = SCR1_IFU_Q_FREE_H_W’(SCR1_IFU_Q_SIZE_HALF - (q_wptr - q_rptr_next)); | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ifu.sv:450:79: Operator SUB expects 32 bits on the RHS, but RHS’s VARREF ‘q_rptr_next’ generates 3 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_ifu’ 450 | assign q_free_h_next = SCR1_IFU_Q_FREE_H_W’(SCR1_IFU_Q_SIZE_HALF - (q_wptr - q_rptr_next)); | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ifu.sv:531:89: Operator ADD expects 4 bits on the RHS, but RHS’s VARREF ‘imem_handshake_done’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_ifu’ 531 | : {imem_addr_ff[32-1:6], imem_addr_ff[5:2] + imem_handshake_done}; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ifu.sv:529:89: Operator ADD expects 30 bits on the RHS, but RHS’s VARREF ‘imem_handshake_done’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_ifu’ 529 | assign imem_addr_next = exu2ifu_pc_new_req_i ? exu2ifu_pc_new_i[32-1:2] + imem_handshake_done | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ifu.sv:530:97: Operator ADD expects 30 bits on the RHS, but RHS’s VARREF ‘imem_handshake_done’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_ifu’ 530 | : &imem_addr_ff[5:2] ? imem_addr_ff + imem_handshake_done | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ifu.sv:553:74: Operator SUB expects 3 bits on the LHS, but LHS’s VARREF ‘imem_handshake_done’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_ifu’ 553 | assign imem_pnd_txns_cnt_next = imem_pnd_txns_cnt + (imem_handshake_done - imem_resp_received); | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ifu.sv:553:74: Operator SUB expects 3 bits on the RHS, but RHS’s VARREF ‘imem_resp_received’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_ifu’ 553 | assign imem_pnd_txns_cnt_next = imem_pnd_txns_cnt + (imem_handshake_done - imem_resp_received); | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ifu.sv:581:87: Operator SUB expects 3 bits on the RHS, but RHS’s VARREF ‘imem_handshake_done’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_ifu’ 581 | assign imem_resp_discard_cnt_next = exu2ifu_pc_new_req_i ? imem_pnd_txns_cnt_next - imem_handshake_done | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_tdu.sv:173:33: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS’s REPLICATE generates 4 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_tdu’ 173 | tdu2csr_rdata_o = {'0, csr_tselect_ff}; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_tdu.sv:226:40: Bit extraction of var[31:0] requires 5 bit index, not 4 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_tdu’ 226 | tdu2csr_rdata_o[SCR1_TDU_MCONTROL_TYPE_VAL] = 1’b1; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_tdu.sv:231:36: Bit extraction of var[31:0] requires 5 bit index, not 4 bits. : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_tdu’ 231 | tdu2csr_rdata_o[SCR1_TDU_ICOUNT_TYPE_VAL] = 1’b1; | ^ %Warning-WIDTHEXPAND: …/…/common/generic_fifos/rtl/verilog/generic_dpram.v:334:16: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS’s VARREF ‘start’ generates 4 bits. : … note: In instance ‘max10.u_sserial.u_serial_fifo.u0’ 334 | for (rnum=start;rnum<=finish;rnum=rnum+1) | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dm.sv:465:64: Operator ASSIGN expects 9 bits on the Assign RHS, but Assign RHS’s VARREF ‘DMSTATUS_RESERVEDC’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dm’ 465 | SCR1_DBG_DMSTATUS_RESERVEDC_LO] = DMSTATUS_RESERVEDC; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dm.sv:468:64: Operator ASSIGN expects 2 bits on the Assign RHS, but Assign RHS’s VARREF ‘DMSTATUS_RESERVEDB’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dm’ 468 | SCR1_DBG_DMSTATUS_RESERVEDB_LO] = DMSTATUS_RESERVEDB; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dm.sv:486:64: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS’s VARREF ‘DMSTATUS_VERSION’ generates 2 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dm’ 486 | SCR1_DBG_DMSTATUS_VERSION_LO] = DMSTATUS_VERSION; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dm.sv:497:64: Operator ASSIGN expects 10 bits on the Assign RHS, but Assign RHS’s VARREF ‘DMCONTROL_HARTSELLO’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dm’ 497 | SCR1_DBG_DMCONTROL_HARTSELLO_LO] = DMCONTROL_HARTSELLO; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dm.sv:499:64: Operator ASSIGN expects 10 bits on the Assign RHS, but Assign RHS’s VARREF ‘DMCONTROL_HARTSELHI’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dm’ 499 | SCR1_DBG_DMCONTROL_HARTSELHI_LO] = DMCONTROL_HARTSELHI; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dm.sv:501:64: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS’s VARREF ‘DMCONTROL_RESERVEDA’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dm’ 501 | SCR1_DBG_DMCONTROL_RESERVEDA_LO] = DMCONTROL_RESERVEDA; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dm.sv:508:64: Operator ASSIGN expects 3 bits on the Assign RHS, but Assign RHS’s VARREF ‘ABSTRACTCS_RESERVEDD’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dm’ 508 | SCR1_DBG_ABSTRACTCS_RESERVEDD_LO] = ABSTRACTCS_RESERVEDD; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dm.sv:512:64: Operator ASSIGN expects 11 bits on the Assign RHS, but Assign RHS’s VARREF ‘ABSTRACTCS_RESERVEDC’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dm’ 512 | SCR1_DBG_ABSTRACTCS_RESERVEDC_LO] = ABSTRACTCS_RESERVEDC; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dm.sv:518:64: Operator ASSIGN expects 4 bits on the Assign RHS, but Assign RHS’s VARREF ‘ABSTRACTCS_RESERVEDA’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dm’ 518 | SCR1_DBG_ABSTRACTCS_RESERVEDA_LO] = ABSTRACTCS_RESERVEDA; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dm.sv:525:64: Operator ASSIGN expects 8 bits on the Assign RHS, but Assign RHS’s VARREF ‘HARTINFO_RESERVEDB’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dm’ 525 | SCR1_DBG_HARTINFO_RESERVEDB_LO] = HARTINFO_RESERVEDB; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dm.sv:529:64: Operator ASSIGN expects 3 bits on the Assign RHS, but Assign RHS’s VARREF ‘HARTINFO_RESERVEDA’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dm’ 529 | SCR1_DBG_HARTINFO_RESERVEDA_LO] = HARTINFO_RESERVEDA; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dm.sv:756:49: Operator EQ expects 8 bits on the RHS, but RHS’s VARREF ‘ABS_CMD_HARTREG’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dm’ 756 | assign abs_cmd_hartreg_vd = (abs_cmd_type == ABS_CMD_HARTREG) & abs_cmd_regvalid; | ^~ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dm.sv:757:49: Operator EQ expects 8 bits on the RHS, but RHS’s VARREF ‘ABS_CMD_HARTMEM’ generates 2 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dm’ 757 | assign abs_cmd_hartmem_vd = (abs_cmd_type == ABS_CMD_HARTMEM) & abs_cmd_memvalid; | ^~ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dm.sv:1135:40: Operator AND expects 3 bits on the LHS, but LHS’s CASTWRAP generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dm’ 1135 | & (~dmi2dm_wdata_i[SCR1_DBG_ABSTRACTCS_CMDERR_HI: | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dmi.sv:101:47: Operator EQ expects 2 bits on the RHS, but RHS’s CONST ‘1’h1’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dmi’ 101 | assign tapc_dtmcs_sel = (tapcsync2dmi_ch_id_i == 1’d1); | ^~ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dmi.sv:108:21: Bit extraction of var[40:0] requires 6 bit index, not 5 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dmi’ 108 | tap_dr_rdata[DTMCS_RESERVEDB_HI:DTMCS_RESERVEDB_LO] = 'b0; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dmi.sv:109:21: Bit extraction of var[40:0] requires 6 bit index, not 5 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dmi’ 109 | tap_dr_rdata[DTMCS_DMIHARDRESET] = 'b0; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dmi.sv:110:21: Bit extraction of var[40:0] requires 6 bit index, not 5 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dmi’ 110 | tap_dr_rdata[DTMCS_DMIRESET] = 'b0; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dmi.sv:111:21: Bit extraction of var[40:0] requires 6 bit index, not 5 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dmi’ 111 | tap_dr_rdata[DTMCS_RESERVEDA] = 'b0; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dmi.sv:112:21: Bit extraction of var[40:0] requires 6 bit index, not 5 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dmi’ 112 | tap_dr_rdata[DTMCS_IDLE_HI:DTMCS_IDLE_LO] = 'b0; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dmi.sv:113:21: Bit extraction of var[40:0] requires 6 bit index, not 5 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dmi’ 113 | tap_dr_rdata[DTMCS_DMISTAT_HI:DTMCS_DMISTAT_LO] = 'b0; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dmi.sv:114:21: Bit extraction of var[40:0] requires 6 bit index, not 5 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dmi’ 114 | tap_dr_rdata[DTMCS_ABITS_HI :DTMCS_ABITS_LO] = SCR1_DBG_DMI_ADDR_WIDTH; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dmi.sv:115:21: Bit extraction of var[40:0] requires 6 bit index, not 5 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dmi’ 115 | tap_dr_rdata[DTMCS_VERSION_LO] = 1’b1; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dmi.sv:119:21: Bit extraction of var[40:0] requires 6 bit index, not 5 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dmi’ 119 | tap_dr_rdata[DMI_OP_HI :DMI_OP_LO] = 'b0; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dmi.sv:156:28: Operator ASSIGN expects 7 bits on the Assign RHS, but Assign RHS’s CONST ‘1’h0’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dmi’ 156 | dmi2dm_addr_o = 1’b0; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dmi.sv:157:28: Operator ASSIGN expects 32 bits on the Assign RHS, but Assign RHS’s CONST ‘1’h0’ generates 1 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dmi’ 157 | dmi2dm_wdata_o = 1’b0; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dmi.sv:160:35: Bit extraction of var[40:0] requires 6 bit index, not 5 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dmi’ 160 | dmi2dm_req_o = tap_dr_ff[DMI_OP_HI :DMI_OP_LO] != 2’b00; | ^ %Warning-WIDTHEXPAND: …/…/…/riscv-cores/scr1/src/core/scr1_dmi.sv:161:35: Bit extraction of var[40:0] requires 6 bit index, not 5 bits. : … note: In instance ‘max10.i_top.i_core_top.i_dmi’ 161 | dmi2dm_wr_o = tap_dr_ff[DMI_OP_HI :DMI_OP_LO] == 2’b10; | ^ %Warning-WIDTHTRUNC: …/…/common/sserial.v:57:4: Logical operator IF expects 1 bit on the If, but If’s VARREF ‘serial_cnt’ generates 4 bits. : … note: In instance ‘max10.u_sserial’ 57 | if(serial_cnt) | ^~ … For warning description see https://verilator.org/warn/WIDTHTRUNC?v=5.037 … Use "/ verilator lint_off WIDTHTRUNC /" and lint_on around source to disable this message. %Warning-UNSIGNED: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_idu.sv:928:30: Comparison is constant due to unsigned arithmetic : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_idu’ 928 | ((idu2exu_cmd_o.ialu_cmd >= SCR1_IALU_CMD_NONE) & | ^~ … For warning description see https://verilator.org/warn/UNSIGNED?v=5.037 … Use "/ verilator lint_off UNSIGNED /" and lint_on around source to disable this message. %Warning-UNSIGNED: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ifu.sv:788:28: Comparison is constant due to unsigned arithmetic : … note: In instance ‘max10.i_top.i_core_top.i_pipe_top.i_pipe_ifu’ 788 | (imem_resp_discard_cnt >= 0) & (imem_resp_discard_cnt <= imem_pnd_txns_cnt) | ^~ %Warning-CASEINCOMPLETE: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ifu.sv:426:9: Case values incompletely covered (example pattern 0x0) 426 | case (q_wr_size) | ^~~~ … For warning description see https://verilator.org/warn/CASEINCOMPLETE?v=5.037 … Use "/ verilator lint_off CASEINCOMPLETE /" and lint_on around source to disable this message. %Warning-CASEINCOMPLETE: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ialu.sv:352:9: Case values incompletely covered (example pattern 0x3) 352 | case (mdu_fsm_ff) | ^~~~ %Warning-CASEINCOMPLETE: …/…/…/riscv-cores/scr1/src/core/pipeline/scr1_pipe_ialu.sv:634:13: Case values incompletely covered (example pattern 0x3) 634 | case (mdu_fsm_ff) | ^~~~ %Warning-CASEINCOMPLETE: …/…/…/riscv-cores/scr1/src/core/scr1_dm.sv:821:5: Case values incompletely covered (example pattern 0xd) 821 | case (abs_fsm_ff) | ^~~~ %Warning-MULTIDRIVEN: …/…/…/riscv-cores/scr1/src/core/scr1_tapc_synchronizer.sv:60:17: Signal has multiple driving blocks with different clocking: ‘max10.i_top.i_core_top.i_tapc_synchronizer.dmi_ch_capture_sync’ …/…/…/riscv-cores/scr1/src/core/scr1_tapc_synchronizer.sv:126:9: … Location of first driving block 126 | dmi_ch_capture_sync[2:1] <= {dmi_ch_capture_sync[1], dmi_ch_capture_sync[0]}; | ^~~~~~~~~~~~~~~~~~~ …/…/…/riscv-cores/scr1/src/core/scr1_tapc_synchronizer.sv:113:9: … Location of other driving block 113 | dmi_ch_capture_sync[0] <= '0; | ^~~~~~~~~~~~~~~~~~~ … For warning description see https://verilator.org/warn/MULTIDRIVEN?v=5.037 … Use "/ verilator lint_off MULTIDRIVEN /" and lint_on around source to disable this message. %Warning-MULTIDRIVEN: …/…/…/riscv-cores/scr1/src/core/scr1_tapc_synchronizer.sv:61:17: Signal has multiple driving blocks with different clocking: ‘max10.i_top.i_core_top.i_tapc_synchronizer.dmi_ch_shift_sync’ …/…/…/riscv-cores/scr1/src/core/scr1_tapc_synchronizer.sv:127:9: … Location of first driving block 127 | dmi_ch_shift_sync[2:1] <= {dmi_ch_shift_sync[1], dmi_ch_shift_sync[0]}; | ^~~~~~~~~~~~~~~~~ …/…/…/riscv-cores/scr1/src/core/scr1_tapc_synchronizer.sv:114:9: … Location of other driving block 114 | dmi_ch_shift_sync[0] <= '0; | ^~~~~~~~~~~~~~~~~ %Warning-MULTIDRIVEN: …/…/…/riscv-cores/scr1/src/top/scr1_timer.sv:65:53: Signal has multiple driving blocks with different clocking: ‘max10.i_top.i_timer.rtc_sync’ …/…/…/riscv-cores/scr1/src/top/scr1_timer.sv:204:13: … Location of first driving block 204 | rtc_sync[3:1] <= rtc_sync[2:0]; | ^~~~~~~~ …/…/…/riscv-cores/scr1/src/top/scr1_timer.sv:194:13: … Location of other driving block 194 | rtc_sync[0] <= ~rtc_sync[0]; | ^~~~~~~~ %Warning-UNOPTFLAT: …/…/common/generic_fifos/rtl/verilog/generic_fifo_dc_gray.v:153:24: Signal unoptimizable: Circular combinational logic: ‘max10.u_sserial.u_serial_fifo.rp_bin_x’ 153 | wire [aw:0] wp_bin_x, rp_bin_x; | ^~~~~~~~ … For warning description see https://verilator.org/warn/UNOPTFLAT?v=5.037 … Use "/ verilator lint_off UNOPTFLAT /” and lint_on around source to disable this message. …/…/common/generic_fifos/rtl/verilog/generic_fifo_dc_gray.v:153:24: Example path: max10.u_sserial.u_serial_fifo.rp_bin_x …/…/common/generic_fifos/rtl/verilog/generic_fifo_dc_gray.v:278:17: Example path: ASSIGNW …/…/common/generic_fifos/rtl/verilog/generic_fifo_dc_gray.v:153:24: Example path: max10.u_sserial.u_serial_fifo.rp_bin_x

  • V e r i l a t i o n R e p o r t: Verilator 5.037 devel rev v5.036-174-g17c2512d0

  • Verilator: Built from 16.261 MB sources in 41 modules, into 1.835 MB in 12 C++ files needing 0.001 MB

  • Verilator: Walltime 0.212 s (elab=0.022, cvt=0.122, bld=0.000); cpu 0.206 s on 1 threads; alloced 34.949 MB g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -Os -c -o tb.o /home/nick/fpga/riscv-compare/FPGA/m3-scr1/sim/tb.cpp g++ -Os -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -c -o verilated.o /usr/local/share/verilator/include/verilated.cpp g++ -Os -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -c -o verilated_threads.o /usr/local/share/verilator/include/verilated_threads.cpp g++ -Os -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -x c+±header Vmax10__pch.h -o Vmax10__pch.h.fast.gch g++ -Os -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -include Vmax10__pch.h.fast -c -o Vmax10.o Vmax10.cpp g++ -Os -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -include Vmax10__pch.h.fast -c -o Vmax10___024root__DepSet_h093b22e1__0.o Vmax10___024root__DepSet_h093b22e1__0.cpp g++ -Os -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -include Vmax10__pch.h.fast -c -o Vmax10___024root__DepSet_hedb980a7__0.o Vmax10___024root__DepSet_hedb980a7__0.cpp g++ -Os -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -include Vmax10__pch.h.fast -c -o Vmax10___024root__DepSet_hedb980a7__1.o Vmax10___024root__DepSet_hedb980a7__1.cpp g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -x c+±header Vmax10__pch.h -o Vmax10__pch.h.slow.gch g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -include Vmax10__pch.h.slow -c -o Vmax10__ConstPool_0.o Vmax10__ConstPool_0.cpp g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -include Vmax10__pch.h.slow -c -o Vmax10___024root__Slow.o Vmax10___024root__Slow.cpp g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -include Vmax10__pch.h.slow -c -o Vmax10___024root__DepSet_h093b22e1__0__Slow.o Vmax10___024root__DepSet_h093b22e1__0__Slow.cpp g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -include Vmax10__pch.h.slow -c -o Vmax10___024root__DepSet_hedb980a7__0__Slow.o Vmax10___024root__DepSet_hedb980a7__0__Slow.cpp g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -include Vmax10__pch.h.slow -c -o Vmax10___024root__DepSet_hedb980a7__1__Slow.o Vmax10___024root__DepSet_hedb980a7__1__Slow.cpp g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -include Vmax10__pch.h.slow -c -o Vmax10___024unit__Slow.o Vmax10___024unit__Slow.cpp g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -include Vmax10__pch.h.slow -c -o Vmax10___024unit__DepSet_hc138aaae__0__Slow.o Vmax10___024unit__DepSet_hc138aaae__0__Slow.cpp g++ -I. -MMD -I/usr/local/share/verilator/include -I/usr/local/share/verilator/include/vltstd -DVM_COVERAGE=0 -DVM_SC=0 -DVM_TIMING=0 -DVM_TRACE=0 -DVM_TRACE_FST=0 -DVM_TRACE_VCD=0 -DVM_TRACE_SAIF=0 -faligned-new -fcf-protection=none -Wno-bool-operation -Wno-shadow -Wno-sign-compare -Wno-subobject-linkage -Wno-tautological-compare -Wno-uninitialized -Wno-unused-but-set-parameter -Wno-unused-but-set-variable -Wno-unused-parameter -Wno-unused-variable -include Vmax10__pch.h.slow -c -o Vmax10__Syms.o Vmax10__Syms.cpp echo “” > Vmax10__ALL.verilator_deplist.tmp g++ tb.o verilated.o verilated_threads.o Vmax10__ALL.a -pthread -lpthread -latomic -o Vmax10 rm Vmax10__ALL.verilator_deplist.tmp


*** Start Simulator ***


Testbench started! TCM memory content from start address 0: 00000093 00000113 00000193 00000213 00000293 00000313 00000393 00000413 START

Dhrystone Benchmark, Version 2.1 (Language: C)

Program compiled without ‘register’ attribute

Execution starts, 500 runs through Dhrystone Execution ends

Final values of the variables used in the benchmark:

Int_Glob: 5 should be: 5 Bool_Glob: 1 should be: 1 Ch_1_Glob: A should be: A Ch_2_Glob: B should be: B Arr_1_Glob[8]: 7 should be: 7 Arr_2_Glob[8][7]: 510 should be: Number_Of_Runs + 10 Ptr_Glob-> Ptr_Comp: 12540 should be: (implementation-dependent) Discr: 0 should be: 0 Enum_Comp: 2 should be: 2 Int_Comp: 17 should be: 17 Str_Comp: DHRYSTONE PROGRAM, SOME STRING should be: DHRYSTONE PROGRAM, SOME STRING Next_Ptr_Glob-> Ptr_Comp: 12540 should be: (implementation-dependent), same as above Discr: 0 should be: 0 Enum_Comp: 1 should be: 1 Int_Comp: 18 should be: 18 Str_Comp: DHRYSTONE PROGRAM, SOME STRING should be: DHRYSTONE PROGRAM, SOME STRING Int_1_Loc: 5 should be: 5 Int_2_Loc: 13 should be: 13 Int_3_Loc: 7 should be: 7 Enum_Loc: 1 should be: 1 Str_1_Loc: DHRYSTONE PROGRAM, 1’ST STRING should be: DHRYSTONE PROGRAM, 1’ST STRING Str_2_Loc: DHRYSTONE PROGRAM, 2’ND STRING should be: DHRYSTONE PROGRAM, 2’ND STRING

BeginTime 19201 EndTime 245752 UserTime 226551
Number_Of_Runs= 500, HZ= 1000000
Time: begin= 19201, end= 245752, diff= 226551
Microseconds for one run through Dhrystone: 453
Dhrystones per Second: 2207
Cycles_Per_Instruction: 1.742
Seg4x7 register Written 00002207 DONE

…/…/m3-scr1/max10.v:182: Verilog $finish Testbench finished!

Обратите внимание, что в конце симуляции лог выдаёт число Dhrystones per Second и у разных ядер это число разное! Для SOC с процессором SCR1 в конфигурации IM это число 2207.

Компиляция проектов FPGA scr1 и picorv32 SOC.

Проекты SOC для picorv32 и для scr1 находятся в папках riscv-compare/FPGA/m3-picorv32 и riscv-compare/FPGA/m3-scr1 соответственно. Нужно запустить САПР Quartus Prime, перейти в нужную папку и открыть проект.

После того, как откроете проект нужно выбрать ревизию проекта через меню квартуса Project -> Revisions. Например, для SOC Scr1 есть четыре мною определенных ревизий для двух плат Марсоход3 и Марсоход3бис - они отличаются установленным чипом MAX10 и количеством имеющихся в нем логических элементов 50 тысяч или 8 тысяч. Для каждой из плат определено так же какая конфигурация процессора будет использована минимальная EC или максимальная IM.

Всего 4 ревизии проекта описаны в файле max10.qpf (Quartus Project File):

QUARTUS_VERSION = "23.1"
DATE = "19:24:25 April 23, 2026"

# Revisions

PROJECT_REVISION = "max10_8K_ec"
PROJECT_REVISION = "max10_50K_im"
PROJECT_REVISION = "max10_50K_ec"
PROJECT_REVISION = "max10_8K_im"

Выбираете интересующую вас ревизию, компилируете для вашей платы и загружаете в ПЛИС.

На семи-сегментном индикаторе платы вы увидите значение Dhrystone теста:

FPGA плата Марсоход3, SCR1 IM, Dhrystone 2207

FPGA плата Марсоход3, SCR1 IM, Dhrystone 2207

К плате можно подключиться через последовательный порт на скорости 12Мбит/сек и тогда можно увидеть вывод всей программы Dhrystone в консоли Putty:

Putty serial console to RISC-V Scr1, config  IM

Putty serial console to RISC-V Scr1, config IM

Как вы можете заметить, результат симуляции с Verilator и запуск в реальной плате Марсоход3 отображают в консоли и на семи-сегментном индикаторе одно и то же число измеренной производительности 2207!

В среде квартус есть полезные отчеты компилятора из которых мы узнаем максимальную частоту Fmax, которую возможно использовать на ядре и которую обещает Quartus, а так же количество использованных ресурсов FPGA: регистров, памяти, умножителей и так далее. Например, вот Resource Usage by Entity:

Quartus Compilation Report, Usage by Entity

Quartus Compilation Report, Usage by Entity

Отсюда и из других отчетов я буду брать значения для итоговой таблицы измерений.

Итоговая таблица измерений.

Вот диаграмма Fmax для разных проектов, как её рапортует САПР Quartus:

Fmax Chart

Fmax Chart

Из этой таблицы и диаграммы видно, что видимо ядро scr1 более сложное, оно содержит больше логики и требует больше регистров. Соответственно и максимальная возможная тактовая частота для моей FPGA получается ниже. При всём при этом, это ядро явно быстрее, так как выполняет инструкции за меньшее число тактов процессора.

Ниже я приведу построенные по этой таблице диаграммы производительности.

Dhry Chart

Dhry Chart

Диаграмма производительности ядер scr1 и picorv32 в единицах измерения Dhrystone. Интересно, что процессор scr1 в минимальной конфигурации EC почти не уступает максимальной конфигурации IM, но так, как Fmax проекта у EC оказалась выше, то в целом его можно быстрее разогнать и даже обойти в производительности конфигурацию IM.

Ну и видно, что процессор scr1 явно выигрывает по производительности у picorv32 даже в пересчёте на Fmax.

Мои FPGA проекты подают на ядро процессора 20МГц. Значит пересчет на Fmax будет Dhry/20*Fmax. Вот так я это считаю.

Ну и по ресурсам. Конечно, picorv32 оказывается более компактным:

Resource Usage

Resource Usage

Ядру picorv32 нужно меньше логики и регистров для нормального функционирования.

В целом результат ожидаемый. Более сложная архитектура scr1 позволяет улучшить производительность, но она требует больших ресурсов в FPGA.

Ну и в конце я хотел бы добавить, что мне одинаково симпатичны оба ядра и scr1 и picorv32. Они несомненно могут быть использованы во встраиваемых приложениях. Ну а какое ядро использовать в проектах уже решать вам.

Ещё хотел бы добавить, что одна из важных и интересных особенностей процессора scr1 это настоящая поддержка JTAG отладки. Через JTAG можно вести отладку программ работающих прямо в процессоре с помощью отладчика GDB. И для этого на самом деле даже и плата не нужна. Я уже написал, как вести отладку ядра scr1 работающего под симулятором Verilator через виртуальный JTAG.

Однако учтите, что сейчас в моем проекте я подключил к линиям JTAG просто константы ноль, то есть они не работают и значит компилятор выбросил из анализа всю связанную логику. С работающим JTAG процессор scr1 будет занимать гораздо больше места в ПЛИС.

Что касается ядра микроконтроллера picorv32, то его довольно просто запустить даже на платах с ограниченными ресурсами. Например, я запускал это ядро на плате Марсоход3WG2 с микросхемой ПЛИС от Gowin. Исходники этого проекта так же есть на Github.