INFRASTRUCTURE · CI/CD

ai-in-ci-cd

An AI review step inside a self-hosted pipeline. A push to GitLab starts a job on a runner in another machine; the runner lints, simulates and synthesizes the design, then hands the diff to a local Qwen3.8 model, and the findings come back as a comment on the merge request. Three ordinary machines, no cloud service, and no line of RTL leaves the network.

company network outbound traffic: 0 B
Engineer git push idle
GitLab self-hosted · server A idle
Runner gitlab-runner · server B idle
Qwen3.8 local inference · GPU server idle
engineer@laptop

        
!42 · uart_tx: add parity
  1. lint
  2. simulation
  3. synthesis
  4. ai-review

What runs where #

The pipeline is split across machines a small team usually already has, or can add without a data-centre budget. Each one does one job, and they only talk to each other.

gitlab-server

Self-hosted GitLab holds the repositories and the merge requests. When a change is pushed it creates a pipeline and queues its jobs; at the end it shows the results and the review comment where the engineers already work.

  • GitLab CE
  • merge requests
  • job artifacts

runner

A separate machine with gitlab-runner and the open-source FPGA tools. It checks out the change, runs lint, simulation and synthesis, collects the diff and the logs, and asks the model for a review. Vendor tools can live here too when licences allow.

  • Verilator
  • Icarus Verilog
  • Yosys
  • Docker or shell executor

model-server

Qwen3.8 served on a GPU workstation behind an OpenAI-compatible API. It receives the diff, the tool reports and the team's written rules, and answers with structured findings. The firewall gives it no route to the internet.

  • Qwen3.8
  • OpenAI-compatible API
  • no outbound traffic

The pipeline file #

The AI step is one more job in .gitlab-ci.yml. It only runs once the deterministic checks have passed, so the model reviews a design that already builds and simulates, and its output is a comment, never a merge.

stages: [lint, sim, synth, review]

lint:
  stage: lint
  tags: [fpga]
  script:
    - verilator --lint-only -Wall rtl/*.v

sim:
  stage: sim
  tags: [fpga]
  script:
    - make -C tb sim            # iverilog + vvp, self-checking testbenches

synth:
  stage: synth
  tags: [fpga]
  script:
    - yosys -s scripts/synth.ys | tee synth.log

ai-review:
  stage: review
  tags: [fpga]
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  variables:
    LLM_URL: http://gpu-01.lan:8000/v1   # internal address only
    LLM_MODEL: qwen3.8
  script:
    - git diff origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME... -- rtl tb > change.diff
    - ai-review --diff change.diff --rules docs/rtl_rules.md
                --logs synth.log --post-to-mr
  artifacts:
    paths: [review/]

Why it suits a small team #

The code stays in-house

Model, runner and repository are on your machines. Customer IP and NDAs are not a reason to stay away from AI.

No per-seat subscriptions

One GPU workstation serves the whole team's pipelines. The cost is the hardware and the power, not a licence per engineer.

Reviews that never get skipped

Every merge request gets a first pass against the team's own rules, so the human reviewer starts from the questions that matter.

Built from open pieces

GitLab, gitlab-runner, open FPGA tools and an open-weights model. Nothing is locked to one vendor, and the team can maintain it.

See it running #

The pieces are all open source, and the posts on the blog describe most of them. If you would rather see the whole pipeline working, on an example design or on one of yours, leave a few details and you will get a reply to arrange a short demo.