Набрасываем на Verilator

Эта статья не является прямым продолжение статьи Время собирать пакеты, но затрагивает связанные темы. Учимся создавать артефакты в рамках концепции Инфраструктура как Артефакт. Будем разворачивать Verilator в Kubernetes.
Сейчас «разучились» собирать пакеты. На рынке десятки компаний которые продают Linux, но они не спешат выкладывать в открытый доступ свою или вернее позаимствованную у Debian или RedHat пакетную базу. Даже если они что-то выкладывают то это будет стандартный набор софта для Postgres on-prem. Поддержкой, а тем более разработкой научного или специализированного приклада российские компании практически не занимаются.
Поэтому DIY — это единственный выход если вы собрались делать конкурентоспособный продукт. Ниже приведен простой пример, который основан на реальных событиях.
Verilator
Verilator — это инструмент, который помогает разработчикам электроники и программистам проверять, как работают их проекты на уровне аппаратного обеспечения, не используя реальные микросхемы. Представьте, что вы создали схему или процессор на языке Verilog (это язык для описания логики работы устройств), но чтобы убедиться, что всё работает правильно, вам нужно протестировать её. Verilator преобразует ваш код Verilog в быстрый C++ код, который можно запустить на компьютере. Это позволяет быстро находить ошибки и тестировать сложные устройства, экономя время и деньги, ведь тестирование на реальном оборудовании занимает гораздо больше ресурсов. Таким образом, Verilator — это как «симулятор» для проверки электронных схем, который делает разработку более эффективной и удобной.
Для установки verilator на Ubuntu понадобятся следующие зависимости:
sudo apt-get install git help2man perl python3 make
sudo apt-get install g++
sudo apt-get install libgz
sudo apt-get install libfl2
sudo apt-get install libfl-dev
sudo apt-get install zlibc zlib1g zlib1g-dev
sudo apt-get install ccache
sudo apt-get install mold
sudo apt-get install libgoogle-perftools-dev numactl
sudo apt-get install perl-doc
sudo apt-get install git autoconf flex bison
Запускаем autoconf для генерации configure скрипта:
autoconf
Запускаем сборку:
make -j `nproc`
Запускаем тесты:
make test
Если все прошло удачно то директории bin появятся следующие файлы:
ls bin/
redirect verilator_bin verilator_ccache_report verilator_coverage_bin_dbg verilator_gantt verilator_profcfunc
verilator verilator_bin_dbg verilator_coverage verilator_difftree verilator_includer
Давайте создадим несложную симуляцию Verilator, чтобы убедится что все работает корректно.
/srv/verilator/sim# ls
fifo.v obj_dir sim_main.cpp
Используйте Verilator для компиляции Verilog-кода и C++ тестового окружения в исполняемый файл симуляции.
/srv/verilator/bin/verilator -Wall --cc fifo.v --exe /srv/verilator/sim/sim_main.cpp
- V e r i l a t i o n R e p o r t: Verilator 5.035 devel rev v5.034-45-g8157f21c3
- Verilator: Built from 0.020 MB sources in 2 modules, into 0.024 MB in 6 C++ files needing 0.000 MB
- Verilator: Walltime 0.005 s (elab=0.000, cvt=0.002, bld=0.000); cpu 0.005 s on 1 threads; alloced 20.074 MB
Симуляция выведет результаты каждого такта в консоль. Вы можете проанализировать вывод, чтобы убедиться в корректности работы вашего дизайна.
cd obj_dir/
root@Hilbert:/srv/verilator/sim/obj_dir# ls
sim_main.d Vfifo___024root__DepSet_h4b9e5f5a__0.cpp Vfifo__ALL.d Vfifo__Syms.cpp
sim_main.o Vfifo___024root__DepSet_hda6b1c72__0.cpp Vfifo__ALL.o Vfifo__Syms.h
verilated.d Vfifo___024root__DepSet_hda6b1c72__0__Slow.cpp Vfifo_classes.mk Vfifo__ver.d
verilated.o Vfifo___024root.h Vfifo.cpp Vfifo__verFiles.dat
verilated_threads.d Vfifo___024root__Slow.cpp Vfifo.h
verilated_threads.o Vfifo__ALL.a Vfifo.mk
Vfifo Vfifo__ALL.cpp Vfifo__pch.h
./Vfifo
Cycle: 0 Data Out: 0 Full: 0 Empty: 1
Cycle: 1 Data Out: 0 Full: 0 Empty: 1
Cycle: 2 Data Out: 0 Full: 0 Empty: 0
Cycle: 3 Data Out: 0 Full: 0 Empty: 0
Cycle: 4 Data Out: 0 Full: 0 Empty: 0
Cycle: 5 Data Out: 0 Full: 0 Empty: 0
Cycle: 6 Data Out: aa Full: 0 Empty: 1
Cycle: 7 Data Out: aa Full: 0 Empty: 1
Cycle: 8 Data Out: aa Full: 0 Empty: 1
Cycle: 9 Data Out: aa Full: 0 Empty: 1
Cycle: a Data Out: aa Full: 0 Empty: 1
Cycle: b Data Out: aa Full: 0 Empty: 1
Cycle: c Data Out: aa Full: 0 Empty: 1
Cycle: d Data Out: aa Full: 0 Empty: 1
Cycle: e Data Out: aa Full: 0 Empty: 1
Cycle: f Data Out: aa Full: 0 Empty: 1
Cycle: 10 Data Out: aa Full: 0 Empty: 1
Cycle: 11 Data Out: aa Full: 0 Empty: 1
Cycle: 12 Data Out: aa Full: 0 Empty: 1
Cycle: 13 Data Out: aa Full: 0 Empty: 1
Упаковка
nfpm — это простой и удобный инструмент для создания пакетов программного обеспечения, таких как .deb (для Debian/Ubuntu) или .rpm (для CentOS/Fedora). Представьте, что вы разработали приложение и хотите распространять его пользователям в виде готового к установке файла. Однако создание таких пакетов может быть сложным процессом, требующим знания специальных команд и структуры файлов. nfpm упрощает эту задачу: он позволяет описать все необходимые данные о вашем приложении (например, название, версию, зависимости и куда нужно скопировать файлы) в одном конфигурационном файле, а затем быстро сгенерировать готовый пакет. Это особенно полезно для разработчиков, которые хотят легко распространять свои программы на Linux-системах, не углубляясь в сложности работы с системными утилитами. Таким образом, nfpm делает процесс упаковки ПО быстрым, понятным и доступным даже для новичков.
Создаем конфиг для nfpm:
name: verilator
arch: amd64
platform: linux
version: 5.035
section: devel
priority: optional
maintainer: Your Name
description: |
Verilator is a fast, free Verilog HDL simulator.
It converts Verilog to a cycle-accurate behavioral model in C++ or SystemC.
Verilator is not a traditional simulator, but a compiler.
vendor: Verilator Project
homepage: https://www.veripool.org/wiki/verilator
license: LGPL-3.0
contents:
- src: bin/verilator
dst: /usr/bin/verilator
depends:
- g++
- make
- perl
- libfl2
- libfl-dev
- zlib1g
- zlib1g-dev
conflicts:
- verilator
replaces:
- verilator
Создаем конфиг для nfpm:
nfpm package --config nfpm.yaml --packager deb --target .
Проверяем пакет:
apt-get install ./verilator_5.035_amd64.deb
Kubernetes
Cимуляция в Verilator может занимать несколько часов и генерировать мегабайты (или даже гигабайты) логов, особенно если ваш дизайн содержит тысячи или миллионы логических элементов (например, процессор, сложный ускоритель или сетевой чип), симуляция будет выполняться медленно, так как Verilator должен эмулировать каждый элемент на каждом такте.
Если у вас есть множество симуляций с разными параметрами (например, тестирование разных конфигураций дизайна), Kubernetes может распределить их по узлам кластера. А если над проектом работает много разработчиков, Kubernetes может помочь организовать выполнение их задач и сбор логов в одном месте.
Все крупные полупроводниковые компании в той или иной роли используют k8s и активно ищут инженеров с опытом работы с k8s. TSMC и ASLM относятся к этим компаниям.
Интеграция с системами мониторинга, такими как Prometheus и Grafana, позволяет отслеживать состояние симуляций и получать уведомления об ошибках.
Логи от всех симуляций могут быть отправлены в централизованную систему, такую как Elasticsearch или Loki. Это упрощает их анализ и поиск.
Но не будем забегать вперед, нам понадобится Docker образ с verilator:
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
build-essential \
git \
perl \
python3 \
make \
g++ \
libfl2 \
libfl-dev \
zlib1g \
zlib1g-dev \
autoconf \
flex \
bison \
help2man \
&& rm -rf /var/lib/apt/lists/*
RUN git clone https://github.com/verilator/verilator /opt/verilator
WORKDIR /opt/verilator
RUN git checkout stable
RUN autoconf && ./configure && make -j$(nproc) && make install
COPY . /sim
WORKDIR /sim
Собираем образ
docker build -t verilator-k8s:latest .
В данном случае будем использовать локальный репозиторий Docker:
docker run -d -p 5000:5000 --name registry registry:2
Тэгируем:
docker tag verilator-k8s:latest localhost:5000/verilator-k8s:latest
Пушим:
docker push localhost:5000/verilator-k8s:latest
Наконец пример deployment манифеста который использует наш образ:
apiVersion: apps/v1
kind: Deployment
metadata:
name: verilator-deployment
spec:
replicas: 5
selector:
matchLabels:
app: verilator
template:
metadata:
labels:
app: verilator
spec:
containers:
- name: verilator-container
image: localhost:5000/verilator-k8s:latest
imagePullPolicy: Always
command: ["bash", "-c", "verilator -Wall --cc sim/fifo.v --exe sim/sim_main.cpp && tail -f /dev/null"]
volumeMounts:
- name: workspace-volume
mountPath: /workspace
volumes:
- name: workspace-volume
hostPath:
path: /srv/verilator/sim
type: Directory
Проверяем запущенные Поды:
kubectl apply -f deployment.yaml
/srv/verilator# kubectl get all
NAME READY STATUS RESTARTS AGE
pod/verilator-deployment-64cd8fdc55-6v724 1/1 Running 0 108s
pod/verilator-deployment-64cd8fdc55-cjznw 1/1 Running 0 108s
pod/verilator-deployment-64cd8fdc55-ll4g5 1/1 Running 0 108s
pod/verilator-deployment-64cd8fdc55-md5xt 1/1 Running 0 108s
pod/verilator-deployment-64cd8fdc55-zfpdz 1/1 Running 0 108s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 443/TCP 3h38m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/verilator-deployment 5/5 5 5 108s
NAME DESIRED CURRENT READY AGE
replicaset.apps/verilator-deployment-64cd8fdc55 5 5 5 108s
проверяем логи:
kubectl logs -f pod/verilator-deployment-64cd8fdc55-zfpdz
- V e r i l a t i o n R e p o r t: Verilator 5.034 2025-02-24 rev v5.034-47-gac3f30ed6
- Verilator: Built from 0.022 MB sources in 2 modules, into 0.024 MB in 6 C++ files needing 0.000 MB
- Verilator: Walltime 0.091 s (elab=0.000, cvt=0.082, bld=0.000); cpu 0.014 s on 1 threads; alloced 9.059 MB
Компании которые работают в сфере полупроводников используется «устаревший» стек технологий. Centos 6 или 7 с устаревшей пакетной базой, далеко не самая свежая инфраструктура и подходы к работе из середины 2000-ых. Здесь каждая ошибка может стоить миллионы, поэтому рисковать они не любят. Но это не значит, что не нужно меняться, современные подходы к инфраструктуре и SDLC рано или поздно проникнут и туда.