Welcome to the NEWCAS tutorial on integrating Large Language Models (LLMs) into the hardware design, synthesis, and verification lifecycle. In this tutorial, we will use an LLM to design an integer square root module, simulate it, optimize its area, and verify its coverage using industry-standard open-source tools.
Before we begin, ensure your system has the required open-source hardware tools installed: Yosys (synthesis), Icarus Verilog & Verilator (simulation), and Cocotb (Python-based verification).
Open your terminal and run:
# Install hardware tools via Homebrew
brew install yosys icarus-verilog verilator
# Install Python verification libraries
pip install pytest cocotb
Open your terminal and run:
# Install hardware tools via APT
sudo apt update
sudo apt install yosys icarus-verilog verilator gtkwave
# Install Python verification libraries
pip install pytest cocotb
To synthesize our hardware design and calculate its physical area, we need a standard cell library.
- Download the
gscl45nm.lib(Generic Standard Cell Library, 45nm). - Download the baseline testbench provided for this tutorial:
problem1_tb.v. - Place both files in your working directory.
We will start by asking an LLM (like Gemini) to generate our baseline Verilog module. First you need to select an LLM.Find your match based on the first letter of your name!
| First Letter | Assigned AI Platform |
|---|---|
| A, B, C, F, G | |
| D, E, H, I, J, K | |
| L, M, N, O, P, Q, R | |
| S, T, U, V, W, X, Y, Z |
As you progress in your design, make sure to track your metrics using this form
After logging into your selected LLM, Copy and paste the following prompt into the LLM:
Prompt for LLM: Write a combinational Verilog module named
signed_isqrtto compute the integer square root of$x$ , where$x$ is an input signed 16-bit integer and the output$y$ is an unsigned 8-bit integer. Specifications:
x: Signed 16-bit input representing the value for integer square root computation (operational range: -32,768 to +32,767). Negative values should be handled as special cases and output 0.y: Unsigned 8-bit output containing the computed integer square root value (operational range: 0 to 181 for valid positive inputs, 0 for negative inputs).
You can experiment with Chain-of-Thought (CoT) techniques here. For example, you can modify your prompt to be as follows.
Prompt for LLM: You are an expert digital IC design engineer. Your task is to design a Verilog module for [INSERT SPECIFICATION from earlier].
To ensure the design is synthesizable and bug-free, you must think step-by-step. Do not output the final Verilog code until you have completed the following steps:
- Signal Analysis: List all I/O ports with names, directions, and bit-widths.
- Block Diagram & Architecture: Describe the internal registers, counters, and data paths needed.
- FSM Breakdown (if applicable): Define the states, next-state logic conditions, and output logic.
- Timing & Edge Considerations: Explicitly state how reset (sync vs async) and clock edges are handled.
- Before Verilog Generation List assumptions, invariants, safety properties, reset behavior, and List clock-domain assumptions.
- Verilog Generation: Finally, provide the complete, well-commented Verilog code based only on the steps above.
Next Steps:
- Save the generated Verilog code into a file named
signed_isqrt.v.
Before synthesizing, we must ensure the LLM's design is functionally correct. We will use Verilator to compile and run the provided testbench against the generated design.
Run the following commands in your terminal:
# Compile the design and testbench
verilator -Wno-LATCH -Wno-WIDTH --binary --top-module signed_isqrt_tb problem1_tb.v signed_isqrt.v
# Execute the compiled simulation
./obj_dir/Vsigned_isqrt_tb
Inspect the out, and make sure everything is marked "SUCCESS".
Iterative Debugging (manual Agentic flow for generation):
If the testbench reports failures, copy the terminal errors and paste them back into the LLM. Ask it to analyze the failure and provide a corrected signed_isqrt.v file. Repeat this until the testbench prints SUCCESS.
Once the design is functionally correct, we will synthesize it using Yosys to map the behavioral Verilog to actual logic gates and measure its silicon area.
- Create a script file named
synth.ysand add the following Yosys commands:
# Read the design file
read_verilog signed_isqrt.v
# Check design hierarchy
hierarchy -check -top signed_isqrt
# Generic synthesis and optimization
proc; opt; opt; techmap; opt
# Map flip-flops and logic to the 45nm library
dfflibmap -liberty gscl45nm.lib
abc -liberty gscl45nm.lib
# Generate statistics (Area)
stat -liberty gscl45nm.lib
# Write out the synthesized netlist
write_verilog signed_isqrt_syn.v
- Run the script:
yosys -s synth.ys
- Look at the terminal output for the
Chip areastatistic.
LLM Optimization terative Debugging (manual Agentic flow for area optimization):
- Go back to your LLM and prompt:
Here is my working Verilog code and design area. Optimize the algorithm to use fewer hardware resources (smaller area) while maintaining functional correctness"
- Replace your code, re-verify with Verilator (Step 4), and re-run Yosys to see how much the LLM reduced your design area!
- Try various prompting and CoT strategies to further reduce the area, until you cannot get further improvements. For example, try
You are a hardware synthesis and optimization expert. Your goal is to optimize the provided Verilog code to minimize design area (LUTs, registers, and gate count) without changing its functional behavior.
Follow these steps strictly before writing any modified code:
- Resource Identification: Analyze the current code and list every hardware resource it will infer (e.g., how many adders, multipliers, comparators, and registers of what bit-widths).
- Resource Sharing Analysis: Identify operations that do not happen simultaneously. Can we reuse a single adder or multiplier across different FSM states using a multiplexer?
- Bit-Width Pruning: Look at every register, counter, and wire. Are there variables where the maximum possible value is smaller than the allocated bit-width?
- Logic Simplification: Identify redundant states in the FSM, unused default branches, or mathematical expressions that can be simplified using boolean algebra.
- Optimized Verilog: Rewrite the Verilog code incorporating all the area-saving strategies identified above. Include comments explaining where resources were shared.
- Replace your code, re-verify with Verilator (Part 4 in this tutorial), and re-run Yosys to see how much the LLM reduced your design area!
Testbenches rarely test every possible edge case on the first try. We will use Verilator's coverage tools to see what lines of code the testbench missed.
- Run Verilator with coverage flags enabled:
verilator -Wno-LATCH -Wno-WIDTH --binary -j 0 --coverage --coverage-line --coverage-toggle --top-module signed_isqrt_tb problem1_tb.v signed_isqrt.v
./obj_dir/Vsigned_isqrt_tb
verilator_coverage --annotate report coverage.dat
- Check the generated
report/directory to see which lines of Verilog were not triggered. LLM Prompt (manual Agentic flow for coverage improvement): - Ask the LLM to write additional Verilog test cases targeting the uncovered lines, append them to
problem1_tb.v, and re-test to achieve 100% coverage.
Writing testbenches in pure Verilog can be tedious. Cocotb allows us to write hardware testbenches using Python, taking advantage of Python's math libraries for reference models.
Ask the LLM to generate the Python environment:
Prompt for LLM: Write a Python testbench using cocotb for a combinational Verilog module named
signed_isqrtto compute the integer square root of$x$ , where$x$ is an input signed 16-bit integer and the output$y$ is an unsigned 8-bit integer. Include directed edge cases and randomized testing. Also, create the standard cocotb Makefile for the Icarus Verilog simulator.
Execution:
- Save the Python code to
test_signed_isqrt.py. - Save the Makefile code to
Makefile. (Ensure theMODULEandTOPLEVELvariables in the Makefile correctly match your filenames). - Run the simulation using Icarus Verilog:
make SIM=icarus
- If there are any
0.00ns ERROR gpifailures, copy the traceback to the LLM and ask it to fix any port naming mismatches!