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

15ae47989704644c64dc4fdc919540f8.jpg

Эта статья не является прямым продолжение статьи Время собирать пакеты, но затрагивает связанные темы. Учимся создавать артефакты в рамках концепции Инфраструктура как Артефакт. Будем разворачивать 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 рано или поздно проникнут и туда.

© Habrahabr.ru