vxkyyy commited on
Commit
6b6699d
·
0 Parent(s):

Initial commit of AgentIC

Browse files
.gitignore ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Python
2
+ __pycache__/
3
+ *.pyc
4
+ *.pyo
5
+ *.pyd
6
+ .Python
7
+ env/
8
+ venv/
9
+ .env
10
+ .venv
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # AgentIC Specific
28
+ # Ignore massive run logs or temporary build artifacts if they end up here
29
+ runs/
30
+ *.log
31
+ *.vcd
32
+ work/
33
+ transcript
34
+
35
+ # System
36
+ .DS_Store
37
+ Thumbs.db
38
+
39
+ # OpenLane outputs (if copied here)
40
+ # Uncomment the line below if you don't want to version control large GDS files
41
+ # *.gds
AZURE_STUDENT_GUIDE.md ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ☁️ Azure Student Developer Pack Guide for AgentIC
2
+
3
+ Since your local PC is overheating, moving to Azure is the perfect solution. With the **Microsoft Azure Student Pack**, you get **$100 credit** and free access to specific services.
4
+
5
+ This guide will help you create a **Virtual Machine (VM)** to run OpenLane and AgentIC without burning your laptop.
6
+
7
+ ## 1. Create the Virtual Machine (VM)
8
+ The "hectic" part is the OpenLane build process (compiling 30,000 transistors!).
9
+
10
+ 1. Log in to the [Azure Portal](https://portal.azure.com).
11
+ 2. Click **"Create a resource"** > **"Virtual Machine"**.
12
+ 3. **Basics Tab**:
13
+ * **Subscription**: Azure for Students.
14
+ * **Resource Group**: Create new (e.g., `rg-agentic`).
15
+ * **Virtual Machine Name**: `vm-agentic`.
16
+ * **Region**: Pick one close to you (e.g., East US).
17
+ * **Image**: **Ubuntu Server 22.04 LTS - x64 Gen2**.
18
+ * **Size**: **Standard D4s v3** (4 vCPUs, 16 GiB memory).
19
+ * *Note:* This costs about ~$0.18/hour. Since you have $100 credits, you can run this for ~500 hours.
20
+ * *Important:* Remember to **STOP** the VM when you aren't using it to save credits!
21
+ 4. **Administrator Account**:
22
+ * **Authentication type**: SSH public key.
23
+ * **Username**: `azureuser`.
24
+ * **Key source**: Generate new key pair.
25
+ 5. **Review + create** > **Create**.
26
+ * Download the private key (`.pem` file) when prompted. Keep it safe!
27
+
28
+ ## 2. Connect to the Cloud
29
+ 1. Open your local terminal (Git Bash or WSL).
30
+ 2. Move the key to a safe place and secure it:
31
+ ```bash
32
+ mv ~/Downloads/vm-agentic_key.pem ~/.ssh/
33
+ chmod 400 ~/.ssh/vm-agentic_key.pem
34
+ ```
35
+ 3. Connect (replace `YOUR_VM_IP` with the Public IP from Azure Portal):
36
+ ```bash
37
+ ssh -i ~/.ssh/vm-agentic_key.pem azureuser@YOUR_VM_IP
38
+ ```
39
+
40
+ ## 3. Install the Environment (One-Time Setup)
41
+ Copy and paste this block into your Azure SSH terminal to install everything:
42
+
43
+ ```bash
44
+ # Update and Install Docker
45
+ sudo apt-get update
46
+ sudo apt-get install -y docker.io python3-pip python3-venv git make
47
+ sudo usermod -aG docker $USER
48
+ newgrp docker
49
+
50
+ # Setup OpenLane
51
+ git clone https://github.com/The-OpenROAD-Project/OpenLane.git ~/OpenLane
52
+ cd ~/OpenLane
53
+ # This download is heavy (~2GB), but it runs on Azure's fast internet!
54
+ make pull-openlane
55
+
56
+ # Get your AgentIC code
57
+ # (You can clone your repo, or we create a fresh one)
58
+ mkdir -p ~/AgentIC
59
+ ```
60
+
61
+ ## 4. Solving the "Thinking" Heat (The LLM)
62
+ Running Ollama (DeepSeek) locally is what heats up your GPU. On an Azure CPU VM, it will be slow.
63
+ **Recommendation:** Use the **DeepSeek API** instead. It costs pennies and offloads the "brain" work to DeepSeek's servers.
64
+
65
+ 1. Get an API Key from [platform.deepseek.com](https://platform.deepseek.com).
66
+ 2. On the Azure VM, export it:
67
+ ```bash
68
+ export OPENAI_API_KEY="sk-..." # Your DeepSeek Key
69
+ export OPENAI_API_BASE="https://api.deepseek.com"
70
+ export LLM_MODEL="deepseek-chat"
71
+ ```
72
+
73
+ ## 5. Running the Flow
74
+ Now, your laptop stays cool while Azure does the work.
75
+
76
+ ```bash
77
+ # On Azure VM
78
+ cd ~/AgentIC
79
+ python3 main.py build --name cloud_chip --desc "An 8-bit counter"
80
+ ```
81
+
82
+ ## 6. Retrieving the Result
83
+ When finished, download the GDS file to your laptop to view it:
84
+
85
+ ```bash
86
+ # On Local Laptop
87
+ scp -i ~/.ssh/vm-agentic_key.pem azureuser@YOUR_VM_IP:~/AgentIC/cloud_chip.gds ./
88
+ ```
CLOUD_DEPLOY.md ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Cloud Migration Guide for AgentIC + OpenLane
2
+
3
+ This guide explains how to move your local AI-to-GDSII flow to a cloud provider (AWS, GCP, Azure, Lambda Labs, or RunPod).
4
+
5
+ ## 1. Hardware Requirements
6
+ OpenLane and Local LLMs are resource-intensive. Do not use a "Free Tier" (t2.micro) instance.
7
+
8
+ * **CPU**: 4 vCPUs minimum (8 recommended for Place & Route).
9
+ * **RAM**: 16 GB minimum (32 GB recommended).
10
+ * **Storage**: 50 GB SSD minimum (Docker images + PDKs take ~30GB).
11
+ * **GPU**: NVIDIA T4 (16GB VRAM) or better recommended if running Ollama locally.
12
+
13
+ ## 2. Setup Script (Ubuntu 22.04 / 24.04)
14
+ Run these commands on your new cloud instance to replicate your environment.
15
+
16
+ ### A. Install System Dependencies
17
+ ```bash
18
+ sudo apt-get update && sudo apt-get install -y \
19
+ docker.io \
20
+ python3-pip \
21
+ python3-venv \
22
+ git \
23
+ make \
24
+ curl \
25
+ iverilog
26
+
27
+ # Add user to docker group (avoids sudo for docker)
28
+ sudo usermod -aG docker $USER
29
+ newgrp docker
30
+ ```
31
+
32
+ ### B. Install Ollama (for DeepSeek)
33
+ If you have a GPU, install the Nvidia Container Toolkit first. If CPU-only, just run:
34
+ ```bash
35
+ curl -fsSL https://ollama.com/install.sh | sh
36
+
37
+ # Pull the model
38
+ ollama pull deepseek-r1
39
+ ```
40
+
41
+ ### C. Clone & Setup Your Workspace
42
+ ```bash
43
+ # Clone OpenLane (Infrastructure)
44
+ git clone https://github.com/The-OpenROAD-Project/OpenLane.git ~/OpenLane
45
+ cd ~/OpenLane
46
+ make pull-openlane # Downloads the heavy Docker images
47
+
48
+ # Clone AgentIC (Your Logic)
49
+ # (Assuming you push your local code to a git repo first)
50
+ git clone <YOUR_GITHUB_REPO_URL> ~/AgentIC
51
+
52
+ # Setup Python Env
53
+ cd ~/AgentIC
54
+ python3 -m venv agentic_env
55
+ source agentic_env/bin/activate
56
+ pip install -r requirements.txt
57
+ ```
58
+
59
+ ## 3. Remote Access
60
+ To view your designs (GDSII files) or access the terminal easily, use VS Code Remote - SSH.
61
+
62
+ 1. In local VS Code: Install "Remote - SSH" extension.
63
+ 2. Connect to `ssh user@your-cloud-ip`.
64
+ 3. Open the folder `/home/user/AgentIC`.
65
+
66
+ ## 4. Modified Flow for Cloud (Headless)
67
+ Since you won't have a GUI window for `klayout` or unnecessary graphics:
68
+
69
+ 1. Run the build command normally:
70
+ ```bash
71
+ python main.py build --name cloud_adder --desc "8-bit adder"
72
+ ```
73
+ 2. **Viewing Results**: Do not try to open KLayout on the server. Instead, use the `scp` command to copy the final GDS file to your local machine:
74
+ ```bash
75
+ # Run this on your LOCAL machine
76
+ scp user@your-cloud-ip:~/OpenLane/designs/cloud_adder/runs/agentrun/results/final/gds/cloud_adder.gds ./
77
+ ```
COOL_MODE.md ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 🔥 Cooling Down: How to Run Locally Safely
2
+
3
+ **No, your computer will not "blast".**
4
+ Modern CPUs and GPUs have safety sensors. If they get too hot (usually 100°C+), they will automatically slow down ("thermal throttle") or shut off the computer to prevent damage.
5
+
6
+ However, running a 5GB model like `deepseek-r1` pins your processor to 100% usage, which generates max heat.
7
+
8
+ ## Solution: Use a "Lighter" Brain
9
+ Since you need to run strictly locally ($0 cost), the best way to reduce heat is to use a **smaller model**.
10
+
11
+ A 1.5B or 3B model requires **much less math** per second than a 7B/8B model. It will run faster and generate less heat.
12
+
13
+ ### Recommended Models for Coding (Low Heat)
14
+ 1. **DeepSeek Coder 1.3B** (Tiny, very fast, decent at Verilog)
15
+ 2. **Qwen 2.5 Coder 3B** (Excellent balance of smarts and speed)
16
+
17
+ ### How to Switch
18
+ 1. **Open Terminal and Pull a Tiny Model:**
19
+ ```bash
20
+ # Try the 1.3 Billion parameter version (approx 700MB - 1GB)
21
+ ollama pull deepseek-coder:1.3b
22
+
23
+ # OR try Qwen 3B (approx 2GB) - Better quality
24
+ ollama pull qwen2.5-coder:3b
25
+ ```
26
+
27
+ 2. **Update AgentIC to use it:**
28
+ Open `src/agentic/config.py` and change `LLM_MODEL`:
29
+ ```python
30
+ # LLM_MODEL = "ollama/deepseek-r1" <-- Comment this out (Heat: High)
31
+ LLM_MODEL = "ollama/deepseek-coder:1.3b" # <-- Use this (Heat: Low)
32
+ ```
33
+
34
+ 3. **Physical Tips:**
35
+ * Prop up the back of your laptop for airflow.
36
+ * Use a cooling pad if you have one.
README.md ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AgentIC Workflow Guide
2
+
3
+ This document outlines the automated chip design workflow using **AgentIC** and **OpenLane**.
4
+
5
+ ## Logic Flow
6
+
7
+ The system transforms natural language descriptions into physical GDSII manufacturing files through a multi-step agentic pipeline.
8
+
9
+ ```mermaid
10
+ graph TD
11
+ User[User Command] -->|main.py build| A[AgentIC]
12
+ A -->|Step 1: Generated RTL| B(VLSI Design Agent)
13
+ B -->|vicky_adder.v| C{Syntax Check}
14
+ C -->|Pass| D(Verification Agent)
15
+ C -->|Fail| Z[Error / Retry]
16
+ D -->|vicky_adder_tb.v| E{Simulation}
17
+ E -->|Pass| F[OpenLane Integration]
18
+ E -->|Fail| Z
19
+
20
+ subgraph OpenLane Infrastructure
21
+ F -->|Docker Mount| G[OpenLane Flow]
22
+ G -->|flow.tcl| H[Synthesis yosys]
23
+ H --> I[Floorplan]
24
+ I --> J[Placement]
25
+ J --> K[Routing]
26
+ K --> L[GDSII Layout]
27
+ end
28
+
29
+ L -->|Output| M[Final GDSII & Reports]
30
+ ```
31
+
32
+ ## Directory Structure & Important Files
33
+
34
+ The workspace is consolidated into two main components:
35
+
36
+ ### 1. AgentIC ( The "Brain" )
37
+ Controls the process.
38
+ - **`main.py`**: The entry point.
39
+ - **`src/agentic/`**: The core Python package.
40
+ - **`agents/`**: AI engineer definitions.
41
+ - **`tools/`**: Interfaces to VLSI tools.
42
+ - **`config.py`**: Configuration settings (paths, LLMs).
43
+ - **`scripts/verify_design.sh`**: A helper script for verification.
44
+
45
+ ### 2. OpenLane ( The "Muscle" )
46
+ The execution engine.
47
+ - **`designs/simple_counter`**: **CRITICAL**. Used as a configuration template for all new AI designs.
48
+ - **`designs/<your_design>`**: Where your new chips will be created.
49
+ - **`flow.tcl`**: The main script run by the Docker container.
50
+
51
+ ## How to Run
52
+
53
+ ### 1. Build a new chip
54
+ ```bash
55
+ cd ~/AgentIC
56
+ python main.py build --name vicky_adder --desc "A 4-bit adder with carry out"
57
+ ```
58
+
59
+ ### 2. Verify an existing chip
60
+ ```bash
61
+ cd ~/AgentIC
62
+ python main.py verify vicky_adder
63
+ ```
64
+
65
+ ## Maintenance
66
+ - **Do not delete** `OpenLane/designs/simple_counter` - it is needed for config generation.
67
+ - **Do not delete** the `OpenLane` root files - they are mounted into the Docker container.
app.py ADDED
@@ -0,0 +1,128 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import os
3
+ import pandas as pd
4
+ import subprocess
5
+ import glob
6
+
7
+ # Configuration
8
+ OPENLANE_ROOT = os.environ.get("OPENLANE_ROOT", os.path.expanduser("~/OpenLane"))
9
+ DESIGNS_DIR = os.path.join(OPENLANE_ROOT, "designs")
10
+
11
+ st.set_page_config(page_title="AgentIC Dashboard", page_icon="チップ", layout="wide")
12
+
13
+ st.title("🤖 AgentIC: AI Chip Design Studio")
14
+ st.markdown("Monitor your AI-generated silicon designs and metrics.")
15
+
16
+ # --- Sidebar: Project Selection ---
17
+ if not os.path.exists(DESIGNS_DIR):
18
+ st.error(f"OpenLane Design Directory not found at: {DESIGNS_DIR}")
19
+ st.stop()
20
+
21
+ designs = [d for d in os.listdir(DESIGNS_DIR) if os.path.isdir(os.path.join(DESIGNS_DIR, d))]
22
+ # Filter out standard openlane designs if needed, keeping it simple for now
23
+ selected_design = st.sidebar.selectbox("Select Design", designs)
24
+
25
+ # --- Main Content ---
26
+
27
+ if selected_design:
28
+ design_path = os.path.join(DESIGNS_DIR, selected_design)
29
+
30
+ # 1. Source Code Viewer
31
+ st.header(f"📦 Design: {selected_design}")
32
+
33
+ verilog_path = os.path.join(design_path, "src", f"{selected_design}.v")
34
+ if os.path.exists(verilog_path):
35
+ with open(verilog_path, "r") as f:
36
+ code = f.read()
37
+ with st.expander("Show Verilog Source", expanded=False):
38
+ st.code(code, language="verilog")
39
+ else:
40
+ st.warning("No Verilog source found.")
41
+
42
+ # 2. Build Status & Metrics
43
+ st.subheader("🏭 Fabrication Status")
44
+
45
+ # Check for GDS
46
+ # Note: AgentIC uses tag "agentrun", but users might use others.
47
+ # We look for the most recent run or 'agentrun'
48
+ runs_dir = os.path.join(design_path, "runs")
49
+ gds_path = None
50
+ report_path = None
51
+
52
+ if os.path.exists(runs_dir):
53
+ # Prefer 'agentrun' if it exists, else latest
54
+ if os.path.exists(os.path.join(runs_dir, "agentrun")):
55
+ run_name = "agentrun"
56
+ else:
57
+ # find latest run
58
+ all_runs = sorted(glob.glob(os.path.join(runs_dir, "*")), key=os.path.getmtime, reverse=True)
59
+ run_name = os.path.basename(all_runs[0]) if all_runs else None
60
+
61
+ if run_name:
62
+ st.info(f"Viewing Run: **{run_name}**")
63
+
64
+ # GDS Path
65
+ possible_gds = os.path.join(runs_dir, run_name, "results", "final", "gds", f"{selected_design}.gds")
66
+ if os.path.exists(possible_gds):
67
+ gds_path = possible_gds
68
+ st.success("✅ GDSII Layout Generated")
69
+
70
+ # Download Button
71
+ with open(gds_path, "rb") as f:
72
+ st.download_button(
73
+ label="⬇️ Download GDSII File",
74
+ data=f,
75
+ file_name=f"{selected_design}.gds",
76
+ mime="application/octet-stream"
77
+ )
78
+ else:
79
+ st.warning("⚠️ No GDSII file found in this run.")
80
+
81
+ # Metrics (CSV)
82
+ # OpenLane typically stores metrics in reports/metrics.csv
83
+ possible_csv = os.path.join(runs_dir, run_name, "reports", "metrics.csv")
84
+ if os.path.exists(possible_csv):
85
+ try:
86
+ df = pd.read_csv(possible_csv)
87
+ # Transpose for better reading if it's a single row
88
+ st.dataframe(df.T)
89
+ except Exception as e:
90
+ st.error(f"Could not read metrics CSV: {e}")
91
+ else:
92
+ st.info("No metrics.csv report found.")
93
+ else:
94
+ st.info("No runs found for this design.")
95
+ else:
96
+ st.info("No runs directory found.")
97
+
98
+ # --- New Design Creator ---
99
+ st.markdown("---")
100
+ st.subheader("✨ Create New Design")
101
+
102
+ with st.form("new_design_form"):
103
+ new_name = st.text_input("Design Name (no spaces)", "my_new_chip")
104
+ new_desc = st.text_area("Description", "A 8-bit shift register with enable signal.")
105
+ submitted = st.form_submit_button("🚀 Launch AI Designer")
106
+
107
+ if submitted:
108
+ if " " in new_name:
109
+ st.error("Design name cannot contain spaces.")
110
+ else:
111
+ cmd = ["python3", "main.py", "build", "--name", new_name, "--desc", new_desc]
112
+
113
+ with st.spinner("AI is thinking and building... (This generally takes 5-10 mins)"):
114
+ # We run this from the AgentIC root
115
+ process = subprocess.run(
116
+ cmd,
117
+ cwd=os.path.dirname(os.path.abspath(__file__)),
118
+ capture_output=True,
119
+ text=True
120
+ )
121
+
122
+ if process.returncode == 0:
123
+ st.success(f"Design '{new_name}' created successfully!")
124
+ st.text_area("Build Output", process.stdout, height=200)
125
+ st.rerun()
126
+ else:
127
+ st.error("Build failed.")
128
+ st.text_area("Error Log", process.stderr, height=200)
main.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ import sys
3
+ import os
4
+
5
+ # Add src to path so we can import the package
6
+ sys.path.insert(0, os.path.join(os.path.dirname(__file__), "src"))
7
+
8
+ from agentic.cli import app
9
+
10
+ if __name__ == "__main__":
11
+ app()
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ crewai
2
+ crewai-tools
3
+ langchain_openai
4
+ typer
5
+ rich
6
+ streamlit
7
+ pandas
scripts/verify_design.sh ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ # Usage: ./verify_design.sh <design_name>
4
+
5
+ if [ -z "$1" ]; then
6
+ echo "Usage: ./verify_design.sh <design_name>"
7
+ exit 1
8
+ fi
9
+
10
+ DESIGN=$1
11
+ OPENLANE_ROOT=~/OpenLane
12
+ DESIGN_DIR=$OPENLANE_ROOT/designs/$DESIGN
13
+
14
+ echo "========================================"
15
+ echo "Verifying Design: $DESIGN"
16
+ echo "========================================"
17
+
18
+ # 1. Functional Verification (RTL Simulation)
19
+ echo "[1] Functional Verification (Icarus Verilog)"
20
+ if [ -f "$DESIGN_DIR/src/${DESIGN}_tb.v" ]; then
21
+ echo " Found Testbench: ${DESIGN}_tb.v"
22
+ cd $DESIGN_DIR/src
23
+ iverilog -o sim ${DESIGN}.v ${DESIGN}_tb.v
24
+ if [ $? -eq 0 ]; then
25
+ echo " Compilation Successful."
26
+ echo " Running Simulation..."
27
+ vvp sim > simulation.log
28
+ cat simulation.log
29
+ echo " (Check output above for expected behavior)"
30
+ else
31
+ echo " [ERROR] Compilation Failed."
32
+ fi
33
+ cd $OPENLANE_ROOT
34
+ else
35
+ echo " [WARNING] No testbench found at $DESIGN_DIR/src/${DESIGN}_tb.v"
36
+ echo " Please create one to run functional simulation."
37
+ fi
38
+
39
+ echo ""
40
+ echo "========================================"
41
+
42
+ # 2. Physical Verification (OpenLane Reports)
43
+ echo "[2] Physical Verification (Latest Run)"
44
+ LATEST_RUN=$(ls -td $DESIGN_DIR/runs/* | head -1)
45
+
46
+ if [ -z "$LATEST_RUN" ]; then
47
+ echo " [ERROR] No runs found for $DESIGN."
48
+ else
49
+ echo " Checking run: $(basename $LATEST_RUN)"
50
+
51
+ # Check DRC
52
+ DRC_RPT=$(find $LATEST_RUN -name "*drc.rpt" | head -1)
53
+ if [ -f "$DRC_RPT" ]; then
54
+ echo " --- DRC Report ($(basename $DRC_RPT)) ---"
55
+ COUNT=$(grep -c "violation" $DRC_RPT)
56
+ if [ "$COUNT" -eq "0" ]; then
57
+ # Some reports might use different format, check content
58
+ grep "Count: 0" $DRC_RPT > /dev/null
59
+ if [ $? -eq 0 ]; then
60
+ echo " [PASS] No DRC Violations found."
61
+ else
62
+ # Print last few lines
63
+ tail -n 5 $DRC_RPT
64
+ fi
65
+ else
66
+ echo " [FAIL] Found potential violations."
67
+ tail -n 5 $DRC_RPT
68
+ fi
69
+ else
70
+ echo " [WARNING] DRC Report not found."
71
+ fi
72
+
73
+ echo ""
74
+
75
+ # Check LVS
76
+ LVS_RPT=$(find $LATEST_RUN -name "*lvs.log" | head -1)
77
+ if [ -f "$LVS_RPT" ]; then
78
+ echo " --- LVS Report ($(basename $LVS_RPT)) ---"
79
+ if grep -q "Total errors = 0" $LVS_RPT; then
80
+ echo " [PASS] LVS Clean. Layout matches Schematic."
81
+ else
82
+ echo " [FAIL] LVS Mismatch."
83
+ grep "Total errors" $LVS_RPT
84
+ fi
85
+ else
86
+ echo " [WARNING] LVS Report not found."
87
+ fi
88
+ fi
89
+
90
+ echo "========================================"
91
+ echo "Verification Complete."
src/agentic/__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ """
2
+ AgentIC - AI-Driven Chip Design Framework
3
+ """
4
+ __version__ = "0.1.0"
src/agentic/agents/__init__.py ADDED
File without changes
src/agentic/agents/designer.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # agents/designer.py
2
+ from crewai import Agent
3
+ from ..config import LLM_MODEL
4
+
5
+ def get_designer_agent():
6
+ return Agent(
7
+ role='VLSI Design Engineer',
8
+ goal='Create optimized Verilog for {design_input}',
9
+ backstory='Specialist in ECE from Lucknow University. Expert in Sky130 PDK.',
10
+ # IMPORTANT: Use the "ollama/" prefix so CrewAI doesn't look for OpenAI
11
+ llm=LLM_MODEL,
12
+ verbose=True,
13
+ allow_delegation=False
14
+ )
src/agentic/agents/testbench_designer.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # agents/testbench_designer.py
2
+ from crewai import Agent
3
+
4
+ def get_testbench_agent(llm):
5
+ """Returns an agent specialized in writing Verilog testbenches."""
6
+ return Agent(
7
+ role='Verification Engineer',
8
+ goal='Create comprehensive Verilog testbenches for {design_name}',
9
+ backstory='''Expert in digital verification with deep knowledge of
10
+ Verilog simulation. Focuses on edge cases, reset behavior, and
11
+ timing checks. Always includes $monitor, $dumpfile, and $finish.''',
12
+ llm=llm,
13
+ verbose=True,
14
+ allow_delegation=False
15
+ )
src/agentic/cli.py ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ AgentIC - Natural Language to GDSII Pipeline
4
+ =============================================
5
+ Uses CrewAI + Ollama (DeepSeek) to generate chips from natural language.
6
+
7
+ Usage:
8
+ python main.py build --name counter --desc "8-bit counter with enable and reset"
9
+ """
10
+
11
+ import os
12
+ import sys
13
+ import typer
14
+ from rich.console import Console
15
+ from rich.panel import Panel
16
+ from rich.progress import Progress, SpinnerColumn, TextColumn
17
+ from crewai import Agent, Task, Crew, LLM
18
+
19
+ # Local imports
20
+ from .config import OPENLANE_ROOT, LLM_MODEL, LLM_BASE_URL, LLM_API_KEY
21
+ from .tools.vlsi_tools import (
22
+ write_verilog,
23
+ run_syntax_check,
24
+ run_simulation,
25
+ run_openlane,
26
+ run_verification
27
+ )
28
+
29
+ # --- INITIALIZE ---
30
+ app = typer.Typer()
31
+ console = Console()
32
+
33
+ # Setup Brain
34
+ def get_llm():
35
+ """Returns the LLM instance for agents."""
36
+ return LLM(
37
+ model=LLM_MODEL,
38
+ base_url=LLM_BASE_URL,
39
+ api_key=LLM_API_KEY
40
+ )
41
+
42
+ # --- THE BUILD COMMAND ---
43
+ @app.command()
44
+ def build(
45
+ name: str = typer.Option(..., "--name", "-n", help="Design name (e.g., counter)"),
46
+ desc: str = typer.Option(..., "--desc", "-d", help="Natural language description")
47
+ ):
48
+ """Build a chip from natural language description."""
49
+
50
+ console.print(Panel(
51
+ f"[bold cyan]AgentIC: Natural Language → GDSII[/bold cyan]\n"
52
+ f"Design: [yellow]{name}[/yellow]\n"
53
+ f"Description: {desc}",
54
+ title="🚀 Starting Pipeline"
55
+ ))
56
+
57
+ llm = get_llm()
58
+
59
+ # ===== STEP 1: Generate RTL =====
60
+ console.print("\n[bold yellow]━━━ Step 1/5: Generating Verilog RTL ━━━[/bold yellow]")
61
+
62
+ rtl_agent = Agent(
63
+ role='VLSI Design Engineer',
64
+ goal=f'Create synthesizable Verilog for: {desc}',
65
+ backstory='Expert in digital design with Sky130 PDK experience.',
66
+ llm=llm,
67
+ verbose=False
68
+ )
69
+
70
+ rtl_task = Task(
71
+ description=f'''Design a Verilog module named "{name}" that implements: {desc}
72
+
73
+ CRITICAL REQUIREMENTS:
74
+ - Module name must be exactly "{name}"
75
+ - Use VERILOG-2005 ONLY (NOT SystemVerilog)
76
+ - Use "always @(*)" NOT "always_comb"
77
+ - Use "reg" for outputs in combinational logic
78
+ - Include clock (clk) and active-low reset (rst_n) if sequential
79
+ - Return ONLY the Verilog code wrapped in ```verilog fences
80
+ - NO explanations, NO comments about the code
81
+
82
+ Example format:
83
+ ```verilog
84
+ module {name}(...);
85
+ ...
86
+ endmodule
87
+ ```
88
+ ''',
89
+ expected_output='Complete Verilog-2005 module code in markdown fence',
90
+ agent=rtl_agent
91
+ )
92
+
93
+ with console.status("[cyan]AI is designing your chip...[/cyan]"):
94
+ rtl_result = Crew(agents=[rtl_agent], tasks=[rtl_task]).kickoff()
95
+
96
+ rtl_path = write_verilog(name, str(rtl_result))
97
+ console.print(f" ✓ RTL saved to: [green]{rtl_path}[/green]")
98
+
99
+ # ===== STEP 2: Syntax Check RTL =====
100
+ console.print("\n[bold yellow]━━━ Step 2/5: Syntax Verification ━━━[/bold yellow]")
101
+
102
+ success, errors = run_syntax_check(rtl_path)
103
+ if not success:
104
+ console.print(f"[bold red]✗ SYNTAX ERROR:[/bold red]\n{errors}")
105
+ raise typer.Exit(1)
106
+ console.print(" ✓ Verilog syntax is [green]valid[/green]")
107
+
108
+ # ===== STEP 3: Generate Testbench =====
109
+ console.print("\n[bold yellow]━━━ Step 3/5: Generating Testbench ━━━[/bold yellow]")
110
+
111
+ # Read the generated RTL for context
112
+ with open(rtl_path, 'r') as f:
113
+ rtl_code = f.read()
114
+
115
+ tb_agent = Agent(
116
+ role='Verification Engineer',
117
+ goal=f'Create a testbench for {name}',
118
+ backstory='Expert in Verilog verification and simulation.',
119
+ llm=llm,
120
+ verbose=False
121
+ )
122
+
123
+ tb_task = Task(
124
+ description=f'''Create a Verilog-2005 testbench for this module:
125
+
126
+ ```verilog
127
+ {rtl_code}
128
+ ```
129
+
130
+ CRITICAL REQUIREMENTS:
131
+ - Module name must be "{name}_tb"
132
+ - Use VERILOG-2005 ONLY (NOT SystemVerilog)
133
+ - Use explicit port connections: .clk(clk), .a(a), etc.
134
+ - Use integer delays like #5 or #10, NOT #5ns or #10ns
135
+ - Clock: forever #5 clk = ~clk (inside initial block)
136
+ - Put $monitor INSIDE an initial block
137
+ - Use $dumpfile("{name}.vcd") and $dumpvars(0, {name}_tb)
138
+ - End with $finish
139
+ - Return ONLY the testbench code wrapped in ```verilog fences
140
+
141
+ Example structure:
142
+ ```verilog
143
+ module {name}_tb;
144
+ reg clk, rst_n;
145
+ // declare inputs as reg, outputs as wire
146
+
147
+ {name} uut(.clk(clk), .rst_n(rst_n), ...);
148
+
149
+ initial begin
150
+ clk = 0;
151
+ forever #5 clk = ~clk;
152
+ end
153
+
154
+ initial begin
155
+ $dumpfile("{name}.vcd");
156
+ $dumpvars(0, {name}_tb);
157
+ $monitor(...);
158
+ // test sequence
159
+ $finish;
160
+ end
161
+ endmodule
162
+ ```
163
+ ''',
164
+ expected_output='Complete Verilog-2005 testbench in markdown fence',
165
+ agent=tb_agent
166
+ )
167
+
168
+ with console.status("[cyan]AI is creating testbench...[/cyan]"):
169
+ tb_result = Crew(agents=[tb_agent], tasks=[tb_task]).kickoff()
170
+
171
+ tb_path = write_verilog(name, str(tb_result), is_testbench=True)
172
+ console.print(f" ✓ Testbench saved to: [green]{tb_path}[/green]")
173
+
174
+ # ===== STEP 4: Run Simulation =====
175
+ console.print("\n[bold yellow]━━━ Step 4/5: Running Simulation ━━━[/bold yellow]")
176
+
177
+ sim_success, sim_output = run_simulation(name)
178
+ if not sim_success:
179
+ console.print(f"[bold red]✗ SIMULATION FAILED:[/bold red]\n{sim_output}")
180
+ raise typer.Exit(1)
181
+
182
+ # Show last few lines of simulation
183
+ sim_lines = sim_output.strip().split('\n')
184
+ for line in sim_lines[-5:]:
185
+ console.print(f" [dim]{line}[/dim]")
186
+ console.print(" ✓ Simulation [green]passed[/green]")
187
+
188
+ # ===== STEP 5: Run OpenLane =====
189
+ console.print("\n[bold yellow]━━━ Step 5/5: Running OpenLane (RTL → GDSII) ━━━[/bold yellow]")
190
+ console.print(" [dim]This may take 5-10 minutes...[/dim]")
191
+
192
+ # Create config.tcl from template
193
+ template_config = f"{OPENLANE_ROOT}/designs/simple_counter/config.tcl"
194
+ new_config = f"{OPENLANE_ROOT}/designs/{name}/config.tcl"
195
+
196
+ if os.path.exists(template_config) and not os.path.exists(new_config):
197
+ with open(template_config, 'r') as f:
198
+ content = f.read().replace("simple_counter", name)
199
+ with open(new_config, 'w') as f:
200
+ f.write(content)
201
+ console.print(f" ✓ Config created from template")
202
+
203
+ ol_success, ol_result = run_openlane(name)
204
+
205
+ if ol_success:
206
+ console.print(f" ✓ GDSII generated: [green]{ol_result}[/green]")
207
+ else:
208
+ console.print(f"[bold red]✗ OpenLane failed[/bold red]")
209
+ console.print(f" Error: {ol_result[:500]}...")
210
+ raise typer.Exit(1)
211
+
212
+ # ===== FINAL: Summary =====
213
+ console.print("\n" + "="*50)
214
+ console.print(Panel(
215
+ f"[bold green]✓ CHIP GENERATION COMPLETE![/bold green]\n\n"
216
+ f"Design: [cyan]{name}[/cyan]\n"
217
+ f"GDSII: [yellow]{ol_result}[/yellow]\n\n"
218
+ f"Run verification: [dim]python main.py verify {name}[/dim]",
219
+ title="🎉 Success"
220
+ ))
221
+
222
+
223
+ @app.command()
224
+ def verify(name: str = typer.Argument(..., help="Design name to verify")):
225
+ """Run verification on an existing design."""
226
+ console.print(f"[yellow]Running verification for {name}...[/yellow]")
227
+ output = run_verification(name)
228
+ console.print(output)
229
+
230
+
231
+ if __name__ == "__main__":
232
+ app()
src/agentic/config.py ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+
3
+ # Paths
4
+ WORKSPACE_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
5
+ OPENLANE_ROOT = os.environ.get("OPENLANE_ROOT", os.path.expanduser("~/OpenLane"))
6
+ DESIGNS_DIR = os.path.join(OPENLANE_ROOT, "designs")
7
+ SCRIPTS_DIR = os.path.join(WORKSPACE_ROOT, "scripts")
8
+
9
+ # LLM Configuration
10
+ LLM_MODEL = os.environ.get("LLM_MODEL", "ollama/deepseek-r1")
11
+ LLM_BASE_URL = os.environ.get("LLM_BASE_URL", "http://localhost:11434")
12
+ LLM_API_KEY = os.environ.get("OPENAI_API_KEY", "NA")
13
+
14
+ # Tool Settings
15
+ PDK_ROOT = os.environ.get('PDK_ROOT', os.path.expanduser('~/.ciel'))
16
+ OPENLANE_IMAGE = "ghcr.io/the-openroad-project/openlane:ff5509f65b17bfa4068d5336495ab1718987ff69-amd64"
src/agentic/tools/__init__.py ADDED
File without changes
src/agentic/tools/vlsi_tools.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # tools/vlsi_tools.py
2
+ import os
3
+ import subprocess
4
+ from ..config import OPENLANE_ROOT, SCRIPTS_DIR, PDK_ROOT, OPENLANE_IMAGE
5
+
6
+ def write_verilog(design_name, code, is_testbench=False):
7
+ """Writes Verilog code to the OpenLane design directory."""
8
+ suffix = "_tb" if is_testbench else ""
9
+ path = f"{OPENLANE_ROOT}/designs/{design_name}/src/{design_name}{suffix}.v"
10
+ os.makedirs(os.path.dirname(path), exist_ok=True)
11
+
12
+ # Clean LLM output (remove markdown fences, think tags, etc.)
13
+ clean_code = code
14
+
15
+ # Remove <think> tags if present (DeepSeek-R1 reasoning)
16
+ if "<think>" in clean_code:
17
+ import re
18
+ clean_code = re.sub(r'<think>.*?</think>', '', clean_code, flags=re.DOTALL)
19
+
20
+ # Extract code from markdown fences
21
+ if "```verilog" in clean_code:
22
+ clean_code = clean_code.split("```verilog")[1].split("```")[0].strip()
23
+ elif "```v" in clean_code:
24
+ clean_code = clean_code.split("```v")[1].split("```")[0].strip()
25
+ elif "```" in clean_code:
26
+ # Find the code block
27
+ parts = clean_code.split("```")
28
+ for i, part in enumerate(parts):
29
+ if i % 2 == 1 and "module" in part: # Odd indices are inside fences
30
+ clean_code = part.strip()
31
+ # Remove language identifier if present
32
+ lines = clean_code.split('\n')
33
+ if lines[0].strip() in ['verilog', 'v', 'systemverilog']:
34
+ clean_code = '\n'.join(lines[1:])
35
+ break
36
+
37
+ # Ensure we have a module
38
+ if "module" not in clean_code:
39
+ # Try to find module in original
40
+ if "module" in code:
41
+ start = code.find("module")
42
+ end = code.rfind("endmodule")
43
+ if end > start:
44
+ clean_code = code[start:end+9] # +9 for "endmodule"
45
+
46
+ # Sanitize model artifacts and fix common issues
47
+ import re
48
+ # Remove model tokens like <|begin▁of▁sentence|>
49
+ clean_code = re.sub(r'<[|\|][^>]+[|\|]>', '', clean_code)
50
+ # Fix SystemVerilog to Verilog-2005
51
+ clean_code = clean_code.replace('always_comb', 'always @(*)')
52
+ clean_code = clean_code.replace('always_ff', 'always')
53
+ clean_code = clean_code.replace('logic', 'reg')
54
+ # Fix time units: #5ns -> #5, #10ps -> #10
55
+ clean_code = re.sub(r'#(\d+)(ns|ps|us|ms|s)\b', r'#\1', clean_code)
56
+ # Fix wildcard port connections (SystemVerilog)
57
+ clean_code = re.sub(r'\(\s*\.\*\s*\)', '', clean_code)
58
+ # Remove any leftover special chars
59
+ clean_code = re.sub(r'[▁|]', '', clean_code)
60
+
61
+ with open(path, "w") as f:
62
+ f.write(clean_code)
63
+ return path
64
+
65
+ def run_syntax_check(file_path):
66
+ """Runs iverilog syntax check."""
67
+ result = subprocess.run(
68
+ ["iverilog", "-t", "null", file_path],
69
+ capture_output=True, text=True
70
+ )
71
+ return result.returncode == 0, result.stderr
72
+
73
+ def run_simulation(design_name):
74
+ """Compiles and runs the testbench simulation."""
75
+ src_dir = f"{OPENLANE_ROOT}/designs/{design_name}/src"
76
+ rtl_file = f"{src_dir}/{design_name}.v"
77
+ tb_file = f"{src_dir}/{design_name}_tb.v"
78
+ sim_out = f"{src_dir}/sim"
79
+
80
+ # Compile
81
+ compile_result = subprocess.run(
82
+ ["iverilog", "-o", sim_out, rtl_file, tb_file],
83
+ capture_output=True, text=True
84
+ )
85
+ if compile_result.returncode != 0:
86
+ return False, f"Compilation failed:\n{compile_result.stderr}"
87
+
88
+ # Run
89
+ run_result = subprocess.run(
90
+ ["vvp", sim_out],
91
+ capture_output=True, text=True,
92
+ timeout=30
93
+ )
94
+ return True, run_result.stdout
95
+
96
+ def run_openlane(design_name):
97
+ """Triggers the OpenLane flow via Docker."""
98
+ os.chdir(OPENLANE_ROOT)
99
+
100
+ # Direct Docker command (non-interactive)
101
+ cmd = [
102
+ "docker", "run", "--rm",
103
+ "-v", f"{OPENLANE_ROOT}:/openlane",
104
+ "-v", f"{PDK_ROOT}:{PDK_ROOT}",
105
+ "-e", f"PDK_ROOT={PDK_ROOT}",
106
+ "-e", "PDK=sky130A",
107
+ OPENLANE_IMAGE,
108
+ "./flow.tcl", "-design", design_name, "-tag", "agentrun", "-overwrite"
109
+ ]
110
+
111
+ process = subprocess.run(
112
+ cmd,
113
+ capture_output=True,
114
+ text=True,
115
+ timeout=900 # 15 min timeout
116
+ )
117
+
118
+ # Check if GDS was created
119
+ gds_path = f"{OPENLANE_ROOT}/designs/{design_name}/runs/agentrun/results/final/gds/{design_name}.gds"
120
+ success = os.path.exists(gds_path)
121
+
122
+ return success, gds_path if success else process.stderr
123
+
124
+ def run_verification(design_name):
125
+ """Runs the verify_design.sh script."""
126
+ script_path = os.path.join(SCRIPTS_DIR, "verify_design.sh")
127
+
128
+ result = subprocess.run(
129
+ ["bash", script_path, design_name],
130
+ capture_output=True,
131
+ text=True
132
+ )
133
+ return result.stdout