Skip to content

Repository files navigation

ContractHIL-HLS

Open-source repository: https://github.com/BJUT-CS316-LAB/ContractHIL-HLS

ContractHIL-HLS is a contract-aligned multi-agent workflow for practical HLS design. The repository contains two reproducible artifacts:

  1. ai_hls_assistant/: the self-written Python tools and prompt templates used to evaluate direct prompting, contract prompting, and the full ContractHIL-HLS prompt regime on HLS-Eval.
  2. single_bitstream/ and dual_bitstream/: a board-tested ML-KEM-512 + ML-DSA-44 + XOR secure-message accelerator for AMD Kria KV260.

The first artifact reproduces the paper's small-design contract-alignment experiment. The second artifact reproduces the PQC hardware-in-the-loop case study, including single-bitstream and dual-bitstream organizations.

Repository Layout

ai_hls_assistant/      Self-written HLS-Eval prompt templates and Python tools
single_bitstream/      One-bitstream PQC accelerator source, Tcl, and PYNQ host flow
dual_bitstream/        Split KEM and DSA/XOR PQC accelerator source, Tcl, and PYNQ host flow
notebooks/             PYNQ notebook/linear demos for board execution

Generated Vivado/HLS projects, logs, API responses, bitstreams, reports, raw benchmarks, and local board data are intentionally ignored by Git unless they are small source artifacts needed for reproduction.

This repository intentionally keeps only one README file: this root README.md. Subdirectory notes are folded into this document so the GitHub entry point stays unambiguous.

Environment

The workflow was developed with:

  • Python 3.10+
  • Vitis HLS / Vivado 2025.2.x on the build host
  • PYNQ 3.x on AMD Kria KV260 for board execution
  • An OpenAI-compatible Responses API for the LLM-based HLS-Eval runs

Before running HLS or Vivado commands, load the Xilinx environment in your shell, for example:

source /tools/Xilinx/Vivado/2025.2/settings64.sh

For LLM experiments, create a local API configuration:

cp .env.example .env
# edit .env and set OPENAI_API_KEY, OPENAI_MODEL, and OPENAI_RESPONSES_URL

The .env file is ignored by Git.

Reproducing ai_hls_assistant

This path reproduces the HLS-Eval experiment used to test whether contracts improve small HLS design generation. Run the commands from the repository root.

The committed ai_hls_assistant/ tree contains only:

  • benchmarks/hlseval/tools/*.py: local preparation, prompting, scoring, and independent synthesis scripts.
  • benchmarks/hlseval/prompts/*.md: direct, contract, and ContractHIL-HLS prompt templates plus the fixed method-prior pack.

It does not commit the HLS-Eval checkout itself, generated task JSON files, model request/response logs, result summaries, or generated HLS workspaces.

1. Fetch HLS-Eval

The raw HLS-Eval benchmark is external and is not committed into this repository. Clone it under the ignored raw/ directory:

git clone https://github.com/stefanpie/hls-eval.git \
  ai_hls_assistant/benchmarks/hlseval/raw

2. Prepare the Locally Executable Task Set

python3 ai_hls_assistant/benchmarks/hlseval/tools/prepare_full.py

This creates the locally executable full_valid task set under ai_hls_assistant/benchmarks/hlseval/generated_tasks/.

3. Dry Run Prompt Rendering

Use a dry run first to verify task discovery and prompt rendering without sending API requests:

python3 ai_hls_assistant/benchmarks/hlseval/tools/run_stage1_llm.py \
  --task-set full_valid \
  --regimes baseline_hlseval,nl_structured_hlseval,nl_structured_lit_hlseval \
  --repeats 5 \
  --dry-run \
  --output-dir ai_hls_assistant/benchmarks/hlseval/results/dryrun_full94_contracthil

4. Run the Full LLM Experiment

python3 ai_hls_assistant/benchmarks/hlseval/tools/run_stage1_llm.py \
  --task-set full_valid \
  --regimes baseline_hlseval,nl_structured_hlseval,nl_structured_lit_hlseval \
  --repeats 5 \
  --workers 3 \
  --resume \
  --output-dir ai_hls_assistant/benchmarks/hlseval/results/hlseval_contracthil_full94_pass5

Prompt regimes:

  • baseline_hlseval: direct HLS-Eval prompt.
  • nl_structured_hlseval: natural language lowered into a structured contract.
  • nl_structured_lit_hlseval: structured contract plus the fixed HLS method-prior pack, corresponding to the full ContractHIL-HLS prompt regime.

5. Score Parse, Compile, Testbench, and Synthesis

python3 ai_hls_assistant/benchmarks/hlseval/tools/score_stage1_outputs.py \
  --task-set full_valid \
  --results-dir ai_hls_assistant/benchmarks/hlseval/results/hlseval_contracthil_full94_pass5 \
  --run-hls \
  --timeout-s 180

python3 ai_hls_assistant/benchmarks/hlseval/tools/run_independent_csynth.py \
  --results-dir ai_hls_assistant/benchmarks/hlseval/results/hlseval_contracthil_full94_pass5 \
  --task-dir ai_hls_assistant/benchmarks/hlseval/generated_tasks/full_valid

Main metrics:

  • Can Parse: generated HLS C/C++ can be extracted.
  • Can Compile: C simulation compilation succeeds.
  • Can Pass TB: C simulation/testbench passes.
  • Can Synth: Vitis HLS synthesis succeeds.
  • pass@1: the first candidate succeeds.
  • pass@5: at least one of five candidates succeeds.

Generated tasks are written under ai_hls_assistant/benchmarks/hlseval/generated_tasks/; generated results are written under ai_hls_assistant/benchmarks/hlseval/results/. Both directories are ignored by Git.

Reproducing the PQC Accelerator

The PQC artifact implements an ML-KEM-512 + ML-DSA-44 + XOR secure-message flow. The single-bitstream design is the functional baseline. The dual-bitstream design is the hardware-in-the-loop case-study result used in the paper.

Single-Bitstream Baseline

Run C simulation:

g++ -std=c++17 -O2 -Wno-unknown-pragmas -Isingle_bitstream/hls/include \
  single_bitstream/hls/top/pqc_accel.cpp \
  single_bitstream/hls/tb/tb_pqc_accel.cpp \
  -o /tmp/pqc_single_tb
/tmp/pqc_single_tb

Run HLS and build the KV260 bitstream:

vitis-run --mode hls --tcl single_bitstream/hls/scripts/run_hls_single_seq.tcl
vivado -mode batch -source single_bitstream/vivado/scripts/build_single_seq_bitstream.tcl

Expected generated outputs:

single_bitstream/vivado/final/design_1_wrapper.bit
single_bitstream/vivado/final/design_1_wrapper.hwh
single_bitstream/vivado/final/design_1_wrapper.xclbin
single_bitstream/vivado/reports/

Run the PYNQ host flow on KV260:

python3 single_bitstream/host/pynq_flow.py \
  --bit single_bitstream/vivado/final/design_1_wrapper.bit \
  --xclbin single_bitstream/vivado/final/design_1_wrapper.xclbin

Dual-Bitstream HIL Design

Run C simulation for the KEM and DSA/XOR IPs:

g++ -std=c++17 -O2 -Wno-unknown-pragmas -Idual_bitstream/hls/include \
  dual_bitstream/hls/top/pqc_kem_accel.cpp \
  dual_bitstream/hls/tb/tb_pqc_kem_accel.cpp \
  -o /tmp/pqc_kem_tb
/tmp/pqc_kem_tb

g++ -std=c++17 -O2 -Wno-unknown-pragmas -Idual_bitstream/hls/include \
  dual_bitstream/hls/top/pqc_dsa_accel.cpp \
  dual_bitstream/hls/tb/tb_pqc_dsa_accel.cpp \
  -o /tmp/pqc_dsa_tb
/tmp/pqc_dsa_tb

Run HLS and build both bitstreams:

vitis-run --mode hls --tcl dual_bitstream/hls/scripts/run_hls_kem.tcl
vivado -mode batch -source dual_bitstream/vivado/scripts/build_kem_bitstream.tcl

vitis-run --mode hls --tcl dual_bitstream/hls/scripts/run_hls_dsa.tcl
vivado -mode batch -source dual_bitstream/vivado/scripts/build_dsa_bitstream.tcl

Expected generated outputs:

dual_bitstream/vivado/kem/final/design_1_wrapper.bit
dual_bitstream/vivado/kem/final/design_1_wrapper.hwh
dual_bitstream/vivado/dsa/final/design_1_wrapper.bit
dual_bitstream/vivado/dsa/final/design_1_wrapper.hwh

Run the dual-bitstream PYNQ host flow:

python3 dual_bitstream/host/pynq_split_flow.py \
  --kem-bit dual_bitstream/vivado/kem/final/design_1_wrapper.bit \
  --dsa-bit dual_bitstream/vivado/dsa/final/design_1_wrapper.bit

For a step-by-step demo in the original operator order 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7, use:

python3 notebooks/pqc_dual_8mode_demo_linear.py

The dual flow stages public keys, secret keys, ciphertexts, signatures, and message buffers in DDR before switching bitstreams, so a reloaded bitstream does not depend on stale PL-local state.

PYNQ Notebook Layout

If you prefer notebook execution, copy the generated *.bit and *.hwh files to the board with this layout:

/root/jupyter_notebooks/ContractHIL-HLS/
  notebooks/pqc_8mode_demo.ipynb
  notebooks/pqc_dual_8mode_demo.ipynb
  notebooks/plaintext.txt
  single_bitstream/design_1_wrapper.bit
  single_bitstream/design_1_wrapper.hwh
  dual_bitstream/kem/design_1_wrapper.bit
  dual_bitstream/kem/design_1_wrapper.hwh
  dual_bitstream/dsa/design_1_wrapper.bit
  dual_bitstream/dsa/design_1_wrapper.hwh

To change the plaintext without editing notebooks, place plaintext.json next to the notebook:

{"plaintext": "your message here"}

or:

{"plaintext_hex": "48656c6c6f"}

Open-Source Hygiene

Before committing, check:

git status --short --ignored

The following should remain ignored:

  • .env and API keys
  • raw HLS-Eval data, generated task JSON files, and generated LLM responses
  • logs/, reports/, .Xil/
  • regenerated Vitis HLS and Vivado project directories
  • *.bit, *.hwh, *.xsa, *.xclbin, *.dcp, and routed reports
  • local board-reference data under reference/ and helper scratch under tools/

Only source code, prompt templates, notebooks, Tcl scripts, and this root documentation should be committed.

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages