chore: remove obsolete files and directories from the repository
Browse files- POSTER_CONTENT.md +0 -97
- WEB_APP_GUIDE.md +0 -439
- designs/simple_counter/config.tcl +0 -27
- designs/simple_counter/src/simple_counter.v +0 -16
- designs/simple_counter/src/simple_counter_tb.v +0 -63
- smart_nic_prompt.txt +0 -13
- tests/test_reliability_contracts.py +0 -123
- tests/test_vlsi_tools_temp_paths.py +0 -83
- verify_fixes.py +0 -90
- web/README.md +0 -73
POSTER_CONTENT.md
DELETED
|
@@ -1,97 +0,0 @@
|
|
| 1 |
-
# Research Poster Content: AgentIC & Defense Challenges
|
| 2 |
-
|
| 3 |
-
## Title
|
| 4 |
-
**AgentIC: Autonomous Sovereign Silicon Design Framework for Defense Applications**
|
| 5 |
-
|
| 6 |
-
## Abstract
|
| 7 |
-
Modern defense systems are critically dependent on advanced semiconductors. However, reliance on foreign EDA tools and fabrication supply chains introduces severe risks, including Hardware Trojans, backdoors, and strategic denial of technology. Validating the "Trust" in hardware is expensive and time-consuming. **AgentIC** is a novel, AI-driven "Text-to-Silicon" framework designed to democratize and accelerate the design of secure, sovereign silicon. By leveraging specialized coding Large Language Models (LLMs) like **Qwen Coder** and open-source EDA tools (OpenLane), AgentIC automates the RTL-to-GDSII flow, ensuring design secrecy and reducing the "Time-to-Tactical-Edge" for custom hardware solutions.
|
| 8 |
-
|
| 9 |
-
---
|
| 10 |
-
|
| 11 |
-
## 1. Problem Statement: The Defense Silicon Gap
|
| 12 |
-
|
| 13 |
-
### A. Supply Chain Vulnerability
|
| 14 |
-
* **Dependency:** Over 90% of advanced chips and EDA tools are controlled by non-domestic entities.
|
| 15 |
-
* **Risk:** In conflict scenarios, access to critical components can be cut off (Sanctions/Blockades).
|
| 16 |
-
|
| 17 |
-
### B. Hardware Security Threats
|
| 18 |
-
* **Trojans:** Malicious logic inserted during design or fabrication (e.g., "Kill Switches" or data exfiltration backdoors).
|
| 19 |
-
* **Opaque IP:** Using closed-source "Black Box" IP cores makes it impossible to verify full security coverage.
|
| 20 |
-
|
| 21 |
-
### C. Obsolescence & Agility
|
| 22 |
-
* **Legacy Systems:** Maintaining aging military hardware requires obsolete chips that are no longer manufactured.
|
| 23 |
-
* **Slow Development:** Traditional ASIC design cycles take 18-24 months, too slow for evolving asymmetric threats.
|
| 24 |
-
|
| 25 |
-
---
|
| 26 |
-
|
| 27 |
-
## 2. Proposed Solution: The AgentIC Framework
|
| 28 |
-
|
| 29 |
-
AgentIC serves as a **Sovereign Design Companion**, allowing defense engineers to generate verified, physically layout-ready silicon from high-level natural language specifications.
|
| 30 |
-
|
| 31 |
-
### Key Pillars:
|
| 32 |
-
1. **AI-Agent Crew:** Specialized AI agents act as the Design Team (Architect, RTL Coder, Verification Engineer).
|
| 33 |
-
2. **Self-Correction:** Closed-loop feedback mechanism where agents fix their own compilation and simulation errors.
|
| 34 |
-
3. **Local & Resilient:** Support for on-premises LLM deployment (e.g., Qwen Coder on air-gapped servers) with **Robust Fallback** (Cloud → Local) to ensure operational continuity.
|
| 35 |
-
4. **Open Source Flow:** output is compatible with the OpenLane/SkyWater 130nm PDK, ensuring a fully auditable toolchain.
|
| 36 |
-
|
| 37 |
-
---
|
| 38 |
-
|
| 39 |
-
## 3. Methodology & Architecture
|
| 40 |
-
|
| 41 |
-
### The Workflow
|
| 42 |
-
1. **Prompt:** User inputs specs (e.g., *"Design a secure AES-256 accelerator with side-channel attack masking"*).
|
| 43 |
-
2. **Design Agent:** Generates SystemVerilog RTL.
|
| 44 |
-
3. **Verification Agent:** Generates a self-checking testbench (randomized stimuli + assertion checking).
|
| 45 |
-
4. **Simulation & Loop:**
|
| 46 |
-
* Runs `iverilog` simulation.
|
| 47 |
-
* If fail: Agents read logs -> Patch Code -> Re-run.
|
| 48 |
-
* If pass: Proceed to hardening.
|
| 49 |
-
5. **Physical Design:** Automates OpenLane scripts to generate GDSII.
|
| 50 |
-
|
| 51 |
-
### Sovereign Tech Stack
|
| 52 |
-
* **Logic:** Custom AI Agents powered by **Qwen Coder** (Primary) / Llama 3 (Backup)
|
| 53 |
-
* **Simulation:** Icarus Verilog (Open Source)
|
| 54 |
-
* **Layout:** OpenLane (Open Source)
|
| 55 |
-
* **PDK:** SkyWater 130nm (Open Google/SkyWater)
|
| 56 |
-
|
| 57 |
-
---
|
| 58 |
-
|
| 59 |
-
## 4. Addressing Defense Challenges (Analysis)
|
| 60 |
-
|
| 61 |
-
| Challenge | AgentIC Solution |
|
| 62 |
-
| :--- | :--- |
|
| 63 |
-
| **IP Theft / Secrecy** | **Local Inference:** Prompts run on secure, air-gapped servers. No cloud APIs required. |
|
| 64 |
-
| **Trojan Insertion** | **Auditable Code:** AI generates human-readable SystemVerilog, not binary blobs. Easier to review. |
|
| 65 |
-
| **Rapid Field Deployment** | **Speed:** Reduces design-to-layout time from months to days for auxiliary chips. |
|
| 66 |
-
| **Talent Shortage** | **Force Multiplier:** Allows non-expert systems engineers to create functional hardware blocks. |
|
| 67 |
-
|
| 68 |
-
---
|
| 69 |
-
|
| 70 |
-
## 5. Case Study: Secure Processor Recovery
|
| 71 |
-
|
| 72 |
-
**Experiment:**
|
| 73 |
-
We tasked AgentIC to design a "Secure Lockout Mechanism" for a processor (a common need for tamper-proof hardware).
|
| 74 |
-
|
| 75 |
-
* **Input:** "Create a state machine that locks the system after 3 failed 4-digit PIN attempts."
|
| 76 |
-
* **Result:**
|
| 77 |
-
1. Agent generated an FSM (Finite State Machine) correctly handling transitions.
|
| 78 |
-
2. Initial bug: Reset logic was inverted.
|
| 79 |
-
3. **Auto-Fix:** Verification agent caught the timeout error, and the Designer agent corrected the polarity in `always_ff`.
|
| 80 |
-
4. **Final Output:** Clean, LVS-clean GDSII layout ready for fabrication.
|
| 81 |
-
|
| 82 |
-
---
|
| 83 |
-
|
| 84 |
-
## 6. Conclusion & Future Work
|
| 85 |
-
|
| 86 |
-
AgentIC demonstrates that Generative AI can bridge the gap between secure requirements and physical silicon. By keeping the "Brain" of the design process local and using open tools, India can achieve true **Atmanirbhar** status in the strategic semiconductor sector.
|
| 87 |
-
|
| 88 |
-
**Future Roadmap:**
|
| 89 |
-
* Integration with formal verification tools for mathematical security proofs.
|
| 90 |
-
* Support for FPGA bitstream generation for rapid field updates.
|
| 91 |
-
|
| 92 |
-
---
|
| 93 |
-
|
| 94 |
-
## References
|
| 95 |
-
1. *The OpenLane Project Documentation*
|
| 96 |
-
2. *Qwen Coder / Llama 3 Technical Reports*
|
| 97 |
-
3. *Defense Advanced Research Projects Agency (DARPA) POSH Program*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
WEB_APP_GUIDE.md
DELETED
|
@@ -1,439 +0,0 @@
|
|
| 1 |
-
# AgentIC Web App — Complete Guide
|
| 2 |
-
|
| 3 |
-
> **How the premium chip design web interface was built and how every piece fits together.**
|
| 4 |
-
|
| 5 |
-
---
|
| 6 |
-
|
| 7 |
-
## Table of Contents
|
| 8 |
-
|
| 9 |
-
1. [What Was Built](#what-was-built)
|
| 10 |
-
2. [Architecture Overview](#architecture-overview)
|
| 11 |
-
3. [Backend — `server/api.py`](#backend--serverapipy)
|
| 12 |
-
4. [Orchestrator Hook — `src/agentic/orchestrator.py`](#orchestrator-hook--srcagenticorchestratorpy)
|
| 13 |
-
5. [Frontend — `web/src/`](#frontend--websrc)
|
| 14 |
-
6. [LLM Selection](#llm-selection)
|
| 15 |
-
7. [Where Data Is Saved](#where-data-is-saved)
|
| 16 |
-
8. [Training Data Auto-Export](#training-data-auto-export)
|
| 17 |
-
9. [Cancel a Build](#cancel-a-build)
|
| 18 |
-
10. [Running the App](#running-the-app)
|
| 19 |
-
11. [API Reference](#api-reference)
|
| 20 |
-
|
| 21 |
-
---
|
| 22 |
-
|
| 23 |
-
## What Was Built
|
| 24 |
-
|
| 25 |
-
The original AgentIC was a **CLI-only tool**: you typed a command and watched logs scroll by. We transformed it into a full-stack web application with:
|
| 26 |
-
|
| 27 |
-
| Feature | Description |
|
| 28 |
-
|---|---|
|
| 29 |
-
| **NLP Prompt UI** | Type a chip description in plain English, hit Launch |
|
| 30 |
-
| **Live Build Monitor** | See every stage of the build pipeline in real-time as it runs |
|
| 31 |
-
| **Cancel Button** | Stop a running build from the browser |
|
| 32 |
-
| **Chip Summary** | After completion, view die area, WNS, power, gate count, RTL preview |
|
| 33 |
-
| **Browser Notifications** | Get a popup when the build finishes, even if you've switched tabs |
|
| 34 |
-
| **Training Auto-Export** | Every build is appended to a JSONL file for fine-tuning VeriReason |
|
| 35 |
-
| **Claude-style Theme** | Warm off-white (#F7F4EF), terracotta accent (#C96442), zero neon |
|
| 36 |
-
|
| 37 |
-
---
|
| 38 |
-
|
| 39 |
-
## Architecture Overview
|
| 40 |
-
|
| 41 |
-
```
|
| 42 |
-
┌─────────────────────┐ HTTP / SSE ┌──────────────────────┐
|
| 43 |
-
│ Browser (Vite UI) │ ◄────────────────────────► │ FastAPI Backend │
|
| 44 |
-
│ localhost:5173 │ │ localhost:8000 │
|
| 45 |
-
│ │ │ │
|
| 46 |
-
│ DesignStudio.tsx │ POST /build │ _run_agentic_build() │
|
| 47 |
-
│ BuildMonitor.tsx │ GET /build/stream/{id} │ (background thread) │
|
| 48 |
-
│ ChipSummary.tsx │ POST /build/cancel/{id} │ │
|
| 49 |
-
│ │ GET /build/result/{id} │ BuildOrchestrator │
|
| 50 |
-
└─────────────────────┘ │ (orchestrator.py) │
|
| 51 |
-
└──────────────────────┘
|
| 52 |
-
│
|
| 53 |
-
▼
|
| 54 |
-
~/OpenLane/designs/<name>/
|
| 55 |
-
training/agentic_sft_data.jsonl
|
| 56 |
-
```
|
| 57 |
-
|
| 58 |
-
**Key concept: Server-Sent Events (SSE)**
|
| 59 |
-
Instead of the frontend constantly asking "are we done yet?", the backend *pushes* updates to the browser the moment they happen. This is called SSE (Server-Sent Events) — it's like a one-way live stream from server → browser over a normal HTTP connection.
|
| 60 |
-
|
| 61 |
-
---
|
| 62 |
-
|
| 63 |
-
## Backend — `server/api.py`
|
| 64 |
-
|
| 65 |
-
### The Job Store
|
| 66 |
-
|
| 67 |
-
```python
|
| 68 |
-
JOB_STORE: Dict[str, Dict[str, Any]] = {}
|
| 69 |
-
```
|
| 70 |
-
|
| 71 |
-
This is an **in-memory dictionary** that holds the state of every build job. Each entry looks like:
|
| 72 |
-
|
| 73 |
-
```python
|
| 74 |
-
{
|
| 75 |
-
"status": "running", # queued | running | cancelling | done | failed | cancelled
|
| 76 |
-
"design_name": "my_counter",
|
| 77 |
-
"current_state": "RTL_GEN", # current orchestrator stage
|
| 78 |
-
"events": [...], # list of all events emitted so far
|
| 79 |
-
"result": {...}, # filled in at the end
|
| 80 |
-
"cancelled": False, # cancel flag checked by the build thread
|
| 81 |
-
"created_at": 1709123456,
|
| 82 |
-
}
|
| 83 |
-
```
|
| 84 |
-
|
| 85 |
-
> ⚠️ **The Job Store is in RAM only.** It resets when the server restarts. The actual chip files (RTL, GDSII, logs) are on disk in `~/OpenLane/designs/` and persist permanently.
|
| 86 |
-
|
| 87 |
-
---
|
| 88 |
-
|
| 89 |
-
### `_get_llm()` — Smart LLM Selection
|
| 90 |
-
|
| 91 |
-
```python
|
| 92 |
-
def _get_llm():
|
| 93 |
-
configs = [
|
| 94 |
-
("NVIDIA Nemotron Cloud", NEMOTRON_CONFIG), # tries first
|
| 95 |
-
("Backup GLM5 Cloud", GLM5_CONFIG), # second
|
| 96 |
-
("VeriReason Local", LOCAL_CONFIG), # last resort
|
| 97 |
-
]
|
| 98 |
-
for name, cfg in configs:
|
| 99 |
-
# skip cloud if no API key
|
| 100 |
-
# try to instantiate LLM
|
| 101 |
-
# return first one that works
|
| 102 |
-
```
|
| 103 |
-
|
| 104 |
-
This mirrors the exact same logic as the CLI's `get_llm()`. So when you click **Launch** in the browser, it uses **the same LLM priority** as running `python main.py build` from the terminal.
|
| 105 |
-
|
| 106 |
-
With your `.env` file having `NVIDIA_API_KEY` set → it always picks **Nemotron Cloud first**.
|
| 107 |
-
|
| 108 |
-
---
|
| 109 |
-
|
| 110 |
-
### `_emit_event()` — Pushing Events
|
| 111 |
-
|
| 112 |
-
```python
|
| 113 |
-
def _emit_event(job_id, event_type, state, message, step=0):
|
| 114 |
-
event = {"type": ..., "state": ..., "message": ..., "timestamp": ...}
|
| 115 |
-
JOB_STORE[job_id]["events"].append(event)
|
| 116 |
-
```
|
| 117 |
-
|
| 118 |
-
Every time something happens in the build (a state change, a log message, an error), this function is called. It appends a structured event to the job's event list. The SSE stream then picks these up and sends them to the browser.
|
| 119 |
-
|
| 120 |
-
**Event types:**
|
| 121 |
-
- `checkpoint` — an important milestone (e.g. "Starting RTL generation")
|
| 122 |
-
- `transition` — the orchestrator moved to a new state (e.g. `RTL_GEN → VERIFICATION`)
|
| 123 |
-
- `log` — a regular log message
|
| 124 |
-
- `error` — something went wrong
|
| 125 |
-
- `done` / `stream_end` — build finished
|
| 126 |
-
|
| 127 |
-
---
|
| 128 |
-
|
| 129 |
-
### `_run_agentic_build()` — Background Thread
|
| 130 |
-
|
| 131 |
-
```python
|
| 132 |
-
def _run_agentic_build(job_id, design_name, description, ...):
|
| 133 |
-
llm, llm_name = _get_llm()
|
| 134 |
-
|
| 135 |
-
def event_sink(event: dict):
|
| 136 |
-
# receives events from the orchestrator
|
| 137 |
-
_emit_event(job_id, ...)
|
| 138 |
-
|
| 139 |
-
orchestrator = BuildOrchestrator(
|
| 140 |
-
...,
|
| 141 |
-
event_sink=event_sink, # the live hook
|
| 142 |
-
)
|
| 143 |
-
orchestrator.run()
|
| 144 |
-
|
| 145 |
-
# after build finishes:
|
| 146 |
-
result = _build_result_summary(orchestrator, ...)
|
| 147 |
-
_export_training_record(...) # save to JSONL
|
| 148 |
-
```
|
| 149 |
-
|
| 150 |
-
This runs in a **separate Python thread** (via `threading.Thread`) so the API doesn't block. When you call `POST /build`, it starts this thread immediately and returns `job_id` to the browser — the browser then connects to the SSE stream to receive live updates.
|
| 151 |
-
|
| 152 |
-
---
|
| 153 |
-
|
| 154 |
-
### SSE Stream — `GET /build/stream/{job_id}`
|
| 155 |
-
|
| 156 |
-
```python
|
| 157 |
-
async def event_generator():
|
| 158 |
-
sent_index = 0
|
| 159 |
-
while True:
|
| 160 |
-
events = JOB_STORE[job_id]["events"]
|
| 161 |
-
while sent_index < len(events):
|
| 162 |
-
yield f"data: {json.dumps(events[sent_index])}\n\n"
|
| 163 |
-
sent_index += 1
|
| 164 |
-
if job["status"] in ("done", "failed", "cancelled"):
|
| 165 |
-
yield f"data: {json.dumps({'type': 'stream_end', ...})}\n\n"
|
| 166 |
-
break
|
| 167 |
-
await asyncio.sleep(0.4) # poll every 400ms
|
| 168 |
-
```
|
| 169 |
-
|
| 170 |
-
The browser holds this connection open. Every 400ms the server checks if there are new events and sends them. When the build finishes, it sends a `stream_end` event and closes the connection.
|
| 171 |
-
|
| 172 |
-
---
|
| 173 |
-
|
| 174 |
-
### Training Export — `_export_training_record()`
|
| 175 |
-
|
| 176 |
-
```python
|
| 177 |
-
record = {
|
| 178 |
-
"instruction": "Design a digital chip: <your prompt>",
|
| 179 |
-
"input": "<architecture spec>", # chip spec written by the LLM
|
| 180 |
-
"output": "<RTL verilog code>", # generated RTL
|
| 181 |
-
"success": True/False,
|
| 182 |
-
"metrics": {"wns": ..., "area": ...},
|
| 183 |
-
"build_log_excerpt": "...", # first 8000 chars of build log
|
| 184 |
-
"source": "agentic_web_build",
|
| 185 |
-
}
|
| 186 |
-
# appended to: training/agentic_sft_data.jsonl
|
| 187 |
-
```
|
| 188 |
-
|
| 189 |
-
Every completed build (success or failure) is saved as one line in `training/agentic_sft_data.jsonl`. This is **SFT (Supervised Fine-Tuning) format** — exactly what `training/generate_reasoning.py` expects. You can use it to fine-tune VeriReason to get better at the kinds of chips you build.
|
| 190 |
-
|
| 191 |
-
---
|
| 192 |
-
|
| 193 |
-
## Orchestrator Hook — `src/agentic/orchestrator.py`
|
| 194 |
-
|
| 195 |
-
### What Changed
|
| 196 |
-
|
| 197 |
-
Only **3 things** were added (all backward-compatible — the CLI is unaffected):
|
| 198 |
-
|
| 199 |
-
**1. New `event_sink` parameter in `__init__`:**
|
| 200 |
-
```python
|
| 201 |
-
def __init__(self, ..., event_sink=None):
|
| 202 |
-
self.event_sink = event_sink # None when called from CLI
|
| 203 |
-
```
|
| 204 |
-
|
| 205 |
-
**2. In `log()` — fires on every log message:**
|
| 206 |
-
```python
|
| 207 |
-
def log(self, message, refined=False):
|
| 208 |
-
# ... existing logging ...
|
| 209 |
-
if self.event_sink is not None:
|
| 210 |
-
self.event_sink({"type": "checkpoint" if refined else "log",
|
| 211 |
-
"state": self.state.name, "message": message})
|
| 212 |
-
```
|
| 213 |
-
|
| 214 |
-
**3. In `transition()` — fires on every state change:**
|
| 215 |
-
```python
|
| 216 |
-
def transition(self, new_state):
|
| 217 |
-
# ... existing logic ...
|
| 218 |
-
if self.event_sink is not None:
|
| 219 |
-
self.event_sink({"type": "transition",
|
| 220 |
-
"state": new_state.name, "message": f"▶ {new_state.value}"})
|
| 221 |
-
```
|
| 222 |
-
|
| 223 |
-
**Why this approach?** The orchestrator has 3000+ lines. Instead of rewriting it, we added a single "callback hook". When the orchestrator calls `self.log(...)` or `self.transition(...)`, the hook fires and sends the event to the web backend. The CLI never passes `event_sink`, so it gets `None` and nothing changes for existing CLI users.
|
| 224 |
-
|
| 225 |
-
---
|
| 226 |
-
|
| 227 |
-
## Frontend — `web/src/`
|
| 228 |
-
|
| 229 |
-
### Three-Phase Flow
|
| 230 |
-
|
| 231 |
-
The UI works as a **state machine with 3 phases**:
|
| 232 |
-
|
| 233 |
-
```
|
| 234 |
-
Phase 1: prompt ──► Phase 2: building ──► Phase 3: done
|
| 235 |
-
(type desc) (watch build) (see results)
|
| 236 |
-
```
|
| 237 |
-
|
| 238 |
-
All managed in `DesignStudio.tsx` with a single `phase` state variable.
|
| 239 |
-
|
| 240 |
-
---
|
| 241 |
-
|
| 242 |
-
### `DesignStudio.tsx` — The Controller
|
| 243 |
-
|
| 244 |
-
This is the **parent component** that owns all state and coordinates the 3 phases.
|
| 245 |
-
|
| 246 |
-
**Key state variables:**
|
| 247 |
-
```typescript
|
| 248 |
-
const [phase, setPhase] = useState('prompt'); // which screen to show
|
| 249 |
-
const [jobId, setJobId] = useState(''); // the server-side job ID
|
| 250 |
-
const [events, setEvents] = useState([]); // all SSE events received
|
| 251 |
-
const [jobStatus, setJobStatus] = useState('queued');
|
| 252 |
-
const [result, setResult] = useState(null); // final chip data
|
| 253 |
-
```
|
| 254 |
-
|
| 255 |
-
**How the SSE connection works:**
|
| 256 |
-
```typescript
|
| 257 |
-
const es = new EventSource(`http://localhost:8000/build/stream/${jobId}`);
|
| 258 |
-
es.onmessage = (evt) => {
|
| 259 |
-
const data = JSON.parse(evt.data);
|
| 260 |
-
if (data.type === 'stream_end') {
|
| 261 |
-
// build finished — fetch full result
|
| 262 |
-
fetchResult(jobId, data.status);
|
| 263 |
-
} else {
|
| 264 |
-
setEvents(prev => [...prev, data]); // add to the timeline
|
| 265 |
-
}
|
| 266 |
-
};
|
| 267 |
-
```
|
| 268 |
-
|
| 269 |
-
`EventSource` is a **built-in browser API** — no extra library needed. It automatically reconnects if the connection drops.
|
| 270 |
-
|
| 271 |
-
---
|
| 272 |
-
|
| 273 |
-
### `BuildMonitor.tsx` — The Live View
|
| 274 |
-
|
| 275 |
-
Shows the **checkpoint timeline** (pipeline stages) and the **live terminal log**.
|
| 276 |
-
|
| 277 |
-
**Checkpoint timeline logic:**
|
| 278 |
-
- Loops through all 14 pipeline stages (INIT → SUCCESS)
|
| 279 |
-
- If `state < currentState` → show green checkmark (done)
|
| 280 |
-
- If `state === currentState` → show spinning ring (active)
|
| 281 |
-
- If `state > currentState` → show empty circle (pending)
|
| 282 |
-
|
| 283 |
-
**Cancel button:**
|
| 284 |
-
```typescript
|
| 285 |
-
const handleCancel = async () => {
|
| 286 |
-
await axios.post(`http://localhost:8000/build/cancel/${jobId}`);
|
| 287 |
-
};
|
| 288 |
-
```
|
| 289 |
-
Sends a POST request to the backend, which sets `JOB_STORE[job_id]["cancelled"] = True`. The build thread checks this flag between orchestrator steps and exits gracefully.
|
| 290 |
-
|
| 291 |
-
> **Note:** Python threads can't be killed mid-operation. The cancel takes effect **after the current step finishes**. If the LLM is in the middle of generating RTL, it will finish that generation, then stop before the next step.
|
| 292 |
-
|
| 293 |
-
---
|
| 294 |
-
|
| 295 |
-
### `ChipSummary.tsx` — The Results Page
|
| 296 |
-
|
| 297 |
-
Displays after the build completes:
|
| 298 |
-
- **Silicon metrics** (WNS, die area, power, gate count) from `~/OpenLane/designs/<name>/runs/.../metrics.csv`
|
| 299 |
-
- **Architecture spec** — the text spec the LLM wrote for your chip
|
| 300 |
-
- **RTL preview** — first 1200 chars of the generated Verilog
|
| 301 |
-
- **Convergence table** — WNS/TNS/congestion across OpenLane iterations
|
| 302 |
-
- **Error details** — if the build failed
|
| 303 |
-
|
| 304 |
-
---
|
| 305 |
-
|
| 306 |
-
### `index.css` — Claude-Inspired Theme
|
| 307 |
-
|
| 308 |
-
The design tokens mirror Claude.ai's visual language:
|
| 309 |
-
|
| 310 |
-
```css
|
| 311 |
-
:root {
|
| 312 |
-
--bg: #F7F4EF; /* warm off-white parchment */
|
| 313 |
-
--accent: #C96442; /* Claude's terracotta orange */
|
| 314 |
-
--text: #1A1817; /* near-black ink */
|
| 315 |
-
--border: #E2DDD7; /* warm light grey */
|
| 316 |
-
}
|
| 317 |
-
```
|
| 318 |
-
|
| 319 |
-
No neon, no glassmorphism, no glows. Cards have a 1px warm border and a soft `box-shadow`. Typography is Inter (same as Claude). The terminal inside the Build Monitor uses the dark theme (`var(--text)` background with `#D4CFC8` text) as a deliberate contrast island.
|
| 320 |
-
|
| 321 |
-
---
|
| 322 |
-
|
| 323 |
-
## LLM Selection
|
| 324 |
-
|
| 325 |
-
```
|
| 326 |
-
Browser clicks "Launch"
|
| 327 |
-
│
|
| 328 |
-
▼
|
| 329 |
-
POST /build
|
| 330 |
-
│
|
| 331 |
-
▼
|
| 332 |
-
_get_llm() tries in order:
|
| 333 |
-
1. NVIDIA Nemotron (if NVIDIA_API_KEY is set in .env) ← your setup uses this
|
| 334 |
-
2. GLM5 Cloud (if above fails)
|
| 335 |
-
3. VeriReason Local (last resort — Ollama at localhost:11434)
|
| 336 |
-
│
|
| 337 |
-
▼
|
| 338 |
-
BuildOrchestrator(llm=<chosen llm>, event_sink=...)
|
| 339 |
-
```
|
| 340 |
-
|
| 341 |
-
The first log line in the Build Monitor terminal will always say which LLM was selected:
|
| 342 |
-
```
|
| 343 |
-
🤖 LLM selected: NVIDIA Nemotron Cloud
|
| 344 |
-
```
|
| 345 |
-
|
| 346 |
-
---
|
| 347 |
-
|
| 348 |
-
## Where Data Is Saved
|
| 349 |
-
|
| 350 |
-
| Data | Location | Persists after restart? |
|
| 351 |
-
|---|---|---|
|
| 352 |
-
| Job status & events | RAM (`JOB_STORE`) | ❌ No |
|
| 353 |
-
| Chip RTL code | `~/OpenLane/designs/<name>/src/<name>.v` | ✅ Yes |
|
| 354 |
-
| Testbench | `~/OpenLane/designs/<name>/src/<name>_tb.v` | ✅ Yes |
|
| 355 |
-
| Build log | `~/OpenLane/designs/<name>/<name>.log` | ✅ Yes |
|
| 356 |
-
| GDSII layout | `~/OpenLane/designs/<name>/runs/<run>/results/final/` | ✅ Yes |
|
| 357 |
-
| Metrics CSV | `~/OpenLane/designs/<name>/runs/<run>/reports/metrics.csv` | ✅ Yes |
|
| 358 |
-
| **Training JSONL** | `AgentIC/training/agentic_sft_data.jsonl` | ✅ Yes, appended |
|
| 359 |
-
|
| 360 |
-
---
|
| 361 |
-
|
| 362 |
-
## Training Data Auto-Export
|
| 363 |
-
|
| 364 |
-
After every build (success **or** failure), this record is appended to `training/agentic_sft_data.jsonl`:
|
| 365 |
-
|
| 366 |
-
```jsonl
|
| 367 |
-
{
|
| 368 |
-
"instruction": "Design a digital chip: 8-bit counter with synchronous reset",
|
| 369 |
-
"input": "# Architecture Spec\n## Module: counter\n...",
|
| 370 |
-
"output": "module counter (\n input clk, rst_n, en,\n...",
|
| 371 |
-
"success": true,
|
| 372 |
-
"metrics": {"wns": "0.12", "area": "0.003 mm²", ...},
|
| 373 |
-
"build_log_excerpt": "[INIT] Initializing workspace\n[SPEC] ...",
|
| 374 |
-
"source": "agentic_web_build"
|
| 375 |
-
}
|
| 376 |
-
```
|
| 377 |
-
|
| 378 |
-
**How to use it for fine-tuning VeriReason:**
|
| 379 |
-
```bash
|
| 380 |
-
# Existing script — reads training/agentic_sft_data.jsonl automatically
|
| 381 |
-
python training/generate_reasoning.py
|
| 382 |
-
|
| 383 |
-
# Then fine-tune
|
| 384 |
-
python training/train_verireason.py
|
| 385 |
-
```
|
| 386 |
-
|
| 387 |
-
The format is **Alpaca-style SFT**: `instruction` + `input` + `output`. This is the standard format used by Unsloth, LLaMA-Factory, and most fine-tuning frameworks.
|
| 388 |
-
|
| 389 |
-
---
|
| 390 |
-
|
| 391 |
-
## Cancel a Build
|
| 392 |
-
|
| 393 |
-
**From the browser:** Click the **✕ Cancel** button in the Build Monitor header.
|
| 394 |
-
|
| 395 |
-
**From the terminal:**
|
| 396 |
-
```bash
|
| 397 |
-
curl -X POST http://localhost:8000/build/cancel/<job_id>
|
| 398 |
-
```
|
| 399 |
-
|
| 400 |
-
**What happens:**
|
| 401 |
-
1. Backend sets `JOB_STORE[job_id]["cancelled"] = True`
|
| 402 |
-
2. The build thread checks this flag after each orchestrator step
|
| 403 |
-
3. The thread exits, logs `"🛑 Build cancelled by user."`
|
| 404 |
-
4. The SSE stream closes, the UI transitions to Phase 3 (results page) showing cancellation
|
| 405 |
-
|
| 406 |
-
---
|
| 407 |
-
|
| 408 |
-
## Running the App
|
| 409 |
-
|
| 410 |
-
**Backend** (port 8000):
|
| 411 |
-
```bash
|
| 412 |
-
source .venv-agentic/bin/activate
|
| 413 |
-
python -m uvicorn server.api:app --host 0.0.0.0 --port 8000 --reload
|
| 414 |
-
```
|
| 415 |
-
|
| 416 |
-
**Frontend** (port 5173):
|
| 417 |
-
```bash
|
| 418 |
-
cd web
|
| 419 |
-
node node_modules/vite/bin/vite.js --host 0.0.0.0 --port 5173
|
| 420 |
-
```
|
| 421 |
-
|
| 422 |
-
Open **http://localhost:5173** → you land directly on the Design Studio.
|
| 423 |
-
|
| 424 |
-
---
|
| 425 |
-
|
| 426 |
-
## API Reference
|
| 427 |
-
|
| 428 |
-
| Method | Endpoint | What it does |
|
| 429 |
-
|---|---|---|
|
| 430 |
-
| `POST` | `/build` | Start a build. Body: `{design_name, description, skip_openlane, full_signoff}`. Returns `{job_id}` |
|
| 431 |
-
| `GET` | `/build/stream/{job_id}` | SSE stream of live build events |
|
| 432 |
-
| `GET` | `/build/status/{job_id}` | Poll current status + all events |
|
| 433 |
-
| `GET` | `/build/result/{job_id}` | Get final chip summary (only when done/failed) |
|
| 434 |
-
| `POST` | `/build/cancel/{job_id}` | Request graceful cancellation |
|
| 435 |
-
| `GET` | `/jobs` | List all jobs in the current session |
|
| 436 |
-
| `GET` | `/designs` | List all chip designs on disk |
|
| 437 |
-
| `GET` | `/signoff/{name}` | Run signoff check on an existing design |
|
| 438 |
-
| `GET` | `/metrics/{name}` | Get OpenLane metrics for a design |
|
| 439 |
-
| `GET` | `/` | Health check |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
designs/simple_counter/config.tcl
DELETED
|
@@ -1,27 +0,0 @@
|
|
| 1 |
-
set ::env(DESIGN_NAME) "simple_counter"
|
| 2 |
-
set ::env(VERILOG_FILES) "$::env(DESIGN_DIR)/src/simple_counter.v"
|
| 3 |
-
|
| 4 |
-
# Die size 200um x 200um
|
| 5 |
-
set ::env(DIE_AREA) "0 0 200 200"
|
| 6 |
-
set ::env(FP_SIZING) absolute
|
| 7 |
-
|
| 8 |
-
# Core utilization
|
| 9 |
-
set ::env(FP_CORE_UTIL) 20
|
| 10 |
-
set ::env(PL_TARGET_DENSITY) 0.3
|
| 11 |
-
|
| 12 |
-
# Power Grid Settings
|
| 13 |
-
set ::env(FP_PDN_VPITCH) 50
|
| 14 |
-
set ::env(FP_PDN_HPITCH) 50
|
| 15 |
-
set ::env(FP_PDN_VOFFSET) 5
|
| 16 |
-
set ::env(FP_PDN_HOFFSET) 5
|
| 17 |
-
|
| 18 |
-
# Power Pins / Voltage Sources
|
| 19 |
-
set ::env(VDD_NETS) [list {vccd1}]
|
| 20 |
-
set ::env(GND_NETS) [list {vssd1}]
|
| 21 |
-
set ::env(SYNTH_USE_PG_PINS_DEFINES) "USE_POWER_PINS"
|
| 22 |
-
|
| 23 |
-
# Technology Setup
|
| 24 |
-
set ::env(PDK) "sky130A"
|
| 25 |
-
set ::env(STD_CELL_LIBRARY) "sky130_fd_sc_hd"
|
| 26 |
-
set ::env(CLOCK_PORT) "clk"
|
| 27 |
-
set ::env(CLOCK_PERIOD) "10.0"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
designs/simple_counter/src/simple_counter.v
DELETED
|
@@ -1,16 +0,0 @@
|
|
| 1 |
-
module simple_counter (
|
| 2 |
-
input wire clk,
|
| 3 |
-
input wire rst_n,
|
| 4 |
-
input wire enable,
|
| 5 |
-
output reg [7:0] count
|
| 6 |
-
);
|
| 7 |
-
|
| 8 |
-
always @(posedge clk or negedge rst_n) begin
|
| 9 |
-
if (!rst_n) begin
|
| 10 |
-
count <= 8'b0;
|
| 11 |
-
end else if (enable) begin
|
| 12 |
-
count <= count + 1'b1;
|
| 13 |
-
end
|
| 14 |
-
end
|
| 15 |
-
|
| 16 |
-
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
designs/simple_counter/src/simple_counter_tb.v
DELETED
|
@@ -1,63 +0,0 @@
|
|
| 1 |
-
`timescale 1ns / 1ps
|
| 2 |
-
|
| 3 |
-
module simple_counter_tb;
|
| 4 |
-
|
| 5 |
-
// Inputs
|
| 6 |
-
reg clk;
|
| 7 |
-
reg rst_n;
|
| 8 |
-
reg enable;
|
| 9 |
-
|
| 10 |
-
// Outputs
|
| 11 |
-
wire [7:0] count;
|
| 12 |
-
|
| 13 |
-
// Instantiate the Unit Under Test (UUT)
|
| 14 |
-
simple_counter uut (
|
| 15 |
-
.clk(clk),
|
| 16 |
-
.rst_n(rst_n),
|
| 17 |
-
.enable(enable),
|
| 18 |
-
.count(count)
|
| 19 |
-
);
|
| 20 |
-
|
| 21 |
-
// Clock generation
|
| 22 |
-
initial begin
|
| 23 |
-
clk = 0;
|
| 24 |
-
forever #5 clk = ~clk; // 100MHz clock
|
| 25 |
-
end
|
| 26 |
-
|
| 27 |
-
// Test Sequence
|
| 28 |
-
initial begin
|
| 29 |
-
// Initialize Inputs
|
| 30 |
-
rst_n = 0;
|
| 31 |
-
enable = 0;
|
| 32 |
-
|
| 33 |
-
// Monitoring
|
| 34 |
-
$monitor("Time=%0t | rst_n=%b | enable=%b | count=%d", $time, rst_n, enable, count);
|
| 35 |
-
|
| 36 |
-
// Reset
|
| 37 |
-
#20;
|
| 38 |
-
rst_n = 1;
|
| 39 |
-
#20;
|
| 40 |
-
|
| 41 |
-
// Enable Counter
|
| 42 |
-
enable = 1;
|
| 43 |
-
#200;
|
| 44 |
-
|
| 45 |
-
// Disable Counter
|
| 46 |
-
enable = 0;
|
| 47 |
-
#50;
|
| 48 |
-
|
| 49 |
-
// Reset again
|
| 50 |
-
rst_n = 0;
|
| 51 |
-
#20;
|
| 52 |
-
|
| 53 |
-
$display("TEST PASSED");
|
| 54 |
-
$finish;
|
| 55 |
-
end
|
| 56 |
-
|
| 57 |
-
// Waveform dump for GTKWave
|
| 58 |
-
initial begin
|
| 59 |
-
$dumpfile("simple_counter.vcd");
|
| 60 |
-
$dumpvars(0, simple_counter_tb);
|
| 61 |
-
end
|
| 62 |
-
|
| 63 |
-
endmodule
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
smart_nic_prompt.txt
DELETED
|
@@ -1,13 +0,0 @@
|
|
| 1 |
-
Design a high-performance networking chip for a smart NIC (Network Interface Card) with the following features:
|
| 2 |
-
|
| 3 |
-
1. Packet Parser: Hardware module to parse Ethernet, IPv4/IPv6, TCP/UDP headers, and extract fields (src/dst MAC, IP, ports, protocol, flags, etc.) at line rate (≥100Gbps). Support programmable parsing rules for custom protocols.
|
| 4 |
-
2. QoS Engine: Implement multi-queue packet scheduling with strict priority and weighted fair queuing (WFQ). Support per-flow rate limiting, traffic shaping, and dynamic queue mapping based on parsed header fields. Provide statistics counters for each queue and flow.
|
| 5 |
-
3. Crypto Accelerator: Integrate a hardware crypto engine supporting AES-GCM (128/256), ChaCha20-Poly1305, and SHA-2 hashing. Enable inline encryption/decryption and authentication for selected flows, with key/context management and low-latency operation.
|
| 6 |
-
4. AXI/PCIe Interface: Expose a high-bandwidth AXI or PCIe interface for DMA to host memory. Support descriptor-based packet I/O and interrupt coalescing.
|
| 7 |
-
5. Control/Status: Provide a register interface for configuration (parsing rules, QoS policies, crypto keys), status monitoring, and error reporting.
|
| 8 |
-
|
| 9 |
-
Constraints:
|
| 10 |
-
- Target 28nm or 14nm process, area < 10mm², power < 2W.
|
| 11 |
-
- Verilog RTL, synthesizable, with testbenches for all modules.
|
| 12 |
-
- Formal verification for packet parser and crypto engine.
|
| 13 |
-
- VCD waveform output for key scenarios.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tests/test_reliability_contracts.py
DELETED
|
@@ -1,123 +0,0 @@
|
|
| 1 |
-
import sys
|
| 2 |
-
import contextlib
|
| 3 |
-
import unittest
|
| 4 |
-
from unittest import mock
|
| 5 |
-
from pathlib import Path
|
| 6 |
-
|
| 7 |
-
REPO_ROOT = Path(__file__).resolve().parents[1]
|
| 8 |
-
SRC_ROOT = REPO_ROOT / "src"
|
| 9 |
-
if str(SRC_ROOT) not in sys.path:
|
| 10 |
-
sys.path.insert(0, str(SRC_ROOT))
|
| 11 |
-
|
| 12 |
-
from agentic.contracts import FailureClass, extract_json_object, infer_failure_class, validate_agent_payload
|
| 13 |
-
from agentic.orchestrator import BuildOrchestrator, BuildState
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
class ReliabilityContractsTest(unittest.TestCase):
|
| 17 |
-
def _make_orchestrator(self) -> BuildOrchestrator:
|
| 18 |
-
orch = BuildOrchestrator(
|
| 19 |
-
name="demo",
|
| 20 |
-
desc="demo design",
|
| 21 |
-
llm=object(),
|
| 22 |
-
verbose=False,
|
| 23 |
-
)
|
| 24 |
-
orch.logger = mock.Mock()
|
| 25 |
-
orch.state = BuildState.VERIFICATION
|
| 26 |
-
orch.artifacts["rtl_code"] = (
|
| 27 |
-
"module demo(input logic clk, input logic rst_n, output logic y);\n"
|
| 28 |
-
"assign y = clk;\n"
|
| 29 |
-
"endmodule\n"
|
| 30 |
-
)
|
| 31 |
-
orch.artifacts["rtl_path"] = "/tmp/demo.v"
|
| 32 |
-
return orch
|
| 33 |
-
|
| 34 |
-
def test_extract_json_object_from_fenced_text(self):
|
| 35 |
-
raw = 'noise\n```json\n{"class":"B","root_cause":"bad"}\n```\n'
|
| 36 |
-
parsed = extract_json_object(raw)
|
| 37 |
-
self.assertEqual(parsed, {"class": "B", "root_cause": "bad"})
|
| 38 |
-
|
| 39 |
-
def test_validate_agent_payload_missing_keys(self):
|
| 40 |
-
errors = validate_agent_payload({"class": "A"}, ["class", "root_cause"])
|
| 41 |
-
self.assertEqual(errors, ["Missing required key 'root_cause'."])
|
| 42 |
-
|
| 43 |
-
def test_infer_failure_class(self):
|
| 44 |
-
cls = infer_failure_class(
|
| 45 |
-
producer="llm_fixer",
|
| 46 |
-
raw_output="This is not valid json",
|
| 47 |
-
diagnostics=["Missing required key 'root_cause'."],
|
| 48 |
-
)
|
| 49 |
-
self.assertEqual(cls, FailureClass.LLM_FORMAT_ERROR)
|
| 50 |
-
|
| 51 |
-
def test_transition_resets_retry_count(self):
|
| 52 |
-
orch = self._make_orchestrator()
|
| 53 |
-
orch.retry_count = 3
|
| 54 |
-
orch.transition(BuildState.FORMAL_VERIFY)
|
| 55 |
-
self.assertEqual(orch.retry_count, 0)
|
| 56 |
-
|
| 57 |
-
def test_required_artifact_handoff_raises(self):
|
| 58 |
-
orch = self._make_orchestrator()
|
| 59 |
-
with self.assertRaises(RuntimeError):
|
| 60 |
-
orch._consume_handoff("tb_regen_context", consumer="VERIFICATION", required=True)
|
| 61 |
-
|
| 62 |
-
def test_parse_structured_agent_json_rejects_prose(self):
|
| 63 |
-
orch = self._make_orchestrator()
|
| 64 |
-
result = orch._parse_structured_agent_json(
|
| 65 |
-
agent_name="VerificationAnalyst",
|
| 66 |
-
raw_output="The issue is likely in the RTL.",
|
| 67 |
-
required_keys=["class", "root_cause"],
|
| 68 |
-
)
|
| 69 |
-
self.assertFalse(result.ok)
|
| 70 |
-
self.assertEqual(result.failure_class, FailureClass.LLM_FORMAT_ERROR)
|
| 71 |
-
|
| 72 |
-
def test_validate_rtl_candidate_rejects_hierarchy_rewrite(self):
|
| 73 |
-
orch = self._make_orchestrator()
|
| 74 |
-
previous = (
|
| 75 |
-
"module demo(input logic clk, output logic y); assign y = clk; endmodule\n"
|
| 76 |
-
"module demo_helper(input logic a, output logic b); assign b = a; endmodule\n"
|
| 77 |
-
)
|
| 78 |
-
candidate = "module demo(input logic clk, output logic y); assign y = clk; endmodule\n"
|
| 79 |
-
issues = orch._validate_rtl_candidate(candidate, previous)
|
| 80 |
-
self.assertTrue(any("module inventory" in issue for issue in issues))
|
| 81 |
-
|
| 82 |
-
def test_validate_tb_candidate_requires_waveform_and_name(self):
|
| 83 |
-
orch = self._make_orchestrator()
|
| 84 |
-
issues = orch._validate_tb_candidate("module wrong_tb; initial begin $finish; end endmodule")
|
| 85 |
-
self.assertTrue(any("TB module name" in issue for issue in issues))
|
| 86 |
-
self.assertTrue(any("dumpfile" in issue for issue in issues))
|
| 87 |
-
|
| 88 |
-
def test_tb_regen_context_bypasses_golden_tb(self):
|
| 89 |
-
orch = self._make_orchestrator()
|
| 90 |
-
orch.artifacts["golden_tb"] = "module counter_tb; endmodule"
|
| 91 |
-
orch.artifacts["golden_template"] = "counter"
|
| 92 |
-
orch._set_artifact(
|
| 93 |
-
"tb_regen_context",
|
| 94 |
-
'{"issue":"pin mismatch"}',
|
| 95 |
-
producer="test",
|
| 96 |
-
consumer="VERIFICATION",
|
| 97 |
-
required=True,
|
| 98 |
-
blocking=True,
|
| 99 |
-
)
|
| 100 |
-
generated_tb = """module demo_tb;
|
| 101 |
-
initial begin
|
| 102 |
-
$dumpfile("demo_wave.vcd");
|
| 103 |
-
$dumpvars(0, demo_tb);
|
| 104 |
-
$display("TEST FAILED");
|
| 105 |
-
$display("TEST PASSED");
|
| 106 |
-
$finish;
|
| 107 |
-
end
|
| 108 |
-
endmodule
|
| 109 |
-
"""
|
| 110 |
-
|
| 111 |
-
with mock.patch("agentic.orchestrator.get_testbench_agent", return_value=object()), \
|
| 112 |
-
mock.patch("agentic.orchestrator.Task", side_effect=lambda **kwargs: kwargs), \
|
| 113 |
-
mock.patch.object(orch, "_kickoff_with_timeout", return_value=generated_tb) as kickoff, \
|
| 114 |
-
mock.patch("agentic.orchestrator.console.status", return_value=contextlib.nullcontext()), \
|
| 115 |
-
mock.patch("agentic.orchestrator.write_verilog", return_value="/tmp/demo_tb.v"), \
|
| 116 |
-
mock.patch("agentic.orchestrator.run_tb_static_contract_check", side_effect=RuntimeError("stop_after_generation")):
|
| 117 |
-
with self.assertRaisesRegex(RuntimeError, "stop_after_generation"):
|
| 118 |
-
orch.do_verification()
|
| 119 |
-
self.assertTrue(kickoff.called)
|
| 120 |
-
|
| 121 |
-
|
| 122 |
-
if __name__ == "__main__":
|
| 123 |
-
unittest.main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tests/test_vlsi_tools_temp_paths.py
DELETED
|
@@ -1,83 +0,0 @@
|
|
| 1 |
-
import os
|
| 2 |
-
import subprocess
|
| 3 |
-
import sys
|
| 4 |
-
import tempfile
|
| 5 |
-
import unittest
|
| 6 |
-
from pathlib import Path
|
| 7 |
-
from unittest import mock
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
REPO_ROOT = Path(__file__).resolve().parents[1]
|
| 11 |
-
SRC_ROOT = REPO_ROOT / "src"
|
| 12 |
-
if str(SRC_ROOT) not in sys.path:
|
| 13 |
-
sys.path.insert(0, str(SRC_ROOT))
|
| 14 |
-
|
| 15 |
-
from agentic.tools import vlsi_tools
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
class TempPathRewriteTests(unittest.TestCase):
|
| 19 |
-
def test_rewrite_temp_paths_replaces_absolute_and_basename_forms(self):
|
| 20 |
-
original = "/workspace/designs/counter8/src/counter8.v"
|
| 21 |
-
staged = "/tmp/tmpabc/counter8.v"
|
| 22 |
-
staged_map = {original: staged}
|
| 23 |
-
|
| 24 |
-
rewritten_abs = vlsi_tools._rewrite_temp_paths(
|
| 25 |
-
f"%Error: {staged}:12:3: syntax error",
|
| 26 |
-
staged_map,
|
| 27 |
-
)
|
| 28 |
-
rewritten_base = vlsi_tools._rewrite_temp_paths(
|
| 29 |
-
"%Error: counter8.v:12:3: syntax error",
|
| 30 |
-
staged_map,
|
| 31 |
-
)
|
| 32 |
-
|
| 33 |
-
self.assertIn(original, rewritten_abs)
|
| 34 |
-
self.assertIn(original, rewritten_base)
|
| 35 |
-
self.assertNotIn("/tmp/tmpabc", rewritten_abs)
|
| 36 |
-
self.assertNotIn("/tmp/tmpabc", rewritten_base)
|
| 37 |
-
|
| 38 |
-
def test_rewrite_result_paths_sanitizes_all_text_fields(self):
|
| 39 |
-
original = "/workspace/designs/counter8/src/counter8.v"
|
| 40 |
-
staged = "/tmp/tmpxyz/counter8.v"
|
| 41 |
-
staged_map = {original: staged}
|
| 42 |
-
payload = {
|
| 43 |
-
"stdout": f"warning in {staged}:4:1",
|
| 44 |
-
"stderr": "counter8.v:7:2: syntax error",
|
| 45 |
-
"diagnostics": [
|
| 46 |
-
f"%Error: {staged}:9:9: bad token",
|
| 47 |
-
"counter8.v:10:11: width warning",
|
| 48 |
-
],
|
| 49 |
-
}
|
| 50 |
-
|
| 51 |
-
sanitized = vlsi_tools._rewrite_result_paths(payload, staged_map)
|
| 52 |
-
|
| 53 |
-
for text in [sanitized["stdout"], sanitized["stderr"], *sanitized["diagnostics"]]:
|
| 54 |
-
self.assertIn(original, text)
|
| 55 |
-
self.assertNotIn("/tmp/tmpxyz", text)
|
| 56 |
-
|
| 57 |
-
def test_run_syntax_check_returns_original_path_in_legacy_message(self):
|
| 58 |
-
with tempfile.TemporaryDirectory() as src_dir:
|
| 59 |
-
rtl_path = os.path.join(src_dir, "counter8.v")
|
| 60 |
-
with open(rtl_path, "w", encoding="utf-8") as f:
|
| 61 |
-
f.write("module counter8; endmodule\n")
|
| 62 |
-
|
| 63 |
-
seen = {}
|
| 64 |
-
|
| 65 |
-
def fake_run(cmd, capture_output, text, timeout, cwd=None):
|
| 66 |
-
seen["cwd"] = cwd
|
| 67 |
-
return subprocess.CompletedProcess(
|
| 68 |
-
cmd,
|
| 69 |
-
1,
|
| 70 |
-
stdout="",
|
| 71 |
-
stderr=f"%Error: {cwd}/counter8.v:12:3: syntax error\n",
|
| 72 |
-
)
|
| 73 |
-
|
| 74 |
-
with mock.patch("agentic.tools.vlsi_tools.subprocess.run", side_effect=fake_run):
|
| 75 |
-
ok, message = vlsi_tools.run_syntax_check(rtl_path)
|
| 76 |
-
|
| 77 |
-
self.assertFalse(ok)
|
| 78 |
-
self.assertIn(rtl_path, message)
|
| 79 |
-
self.assertNotIn(seen["cwd"], message)
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
if __name__ == "__main__":
|
| 83 |
-
unittest.main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
verify_fixes.py
DELETED
|
@@ -1,90 +0,0 @@
|
|
| 1 |
-
import re
|
| 2 |
-
import os
|
| 3 |
-
import sys
|
| 4 |
-
|
| 5 |
-
# Add src to path
|
| 6 |
-
sys.path.append(os.path.abspath("src"))
|
| 7 |
-
|
| 8 |
-
from agentic.tools import vlsi_tools
|
| 9 |
-
|
| 10 |
-
def check_duplicates(file_path):
|
| 11 |
-
print(f"Checking for duplicates in {file_path}...")
|
| 12 |
-
with open(file_path, 'r') as f:
|
| 13 |
-
content = f.read()
|
| 14 |
-
|
| 15 |
-
# Find all function definitions
|
| 16 |
-
funcs = re.findall(r'^def\s+(\w+)\s*\(', content, re.MULTILINE)
|
| 17 |
-
seen = set()
|
| 18 |
-
dupes = []
|
| 19 |
-
for f in funcs:
|
| 20 |
-
if f in seen:
|
| 21 |
-
dupes.append(f)
|
| 22 |
-
seen.add(f)
|
| 23 |
-
|
| 24 |
-
if dupes:
|
| 25 |
-
print(f"FAILED: Found duplicate functions: {dupes}")
|
| 26 |
-
return False
|
| 27 |
-
print("PASSED: No duplicate functions found.")
|
| 28 |
-
return True
|
| 29 |
-
|
| 30 |
-
def test_validate_rtl():
|
| 31 |
-
print("\nTesting validate_rtl_for_synthesis logic...")
|
| 32 |
-
|
| 33 |
-
# Sample RTL with undriven signals (active high and low)
|
| 34 |
-
rtl = """
|
| 35 |
-
module test_module (
|
| 36 |
-
input clk,
|
| 37 |
-
input rst_n
|
| 38 |
-
);
|
| 39 |
-
reg [7:0] data_reg;
|
| 40 |
-
wire valid_signal;
|
| 41 |
-
wire [3:0] active_low_b;
|
| 42 |
-
wire enable_n;
|
| 43 |
-
|
| 44 |
-
always @(posedge clk) begin
|
| 45 |
-
if (enable_n) begin
|
| 46 |
-
data_reg <= 8'h00;
|
| 47 |
-
end
|
| 48 |
-
end
|
| 49 |
-
|
| 50 |
-
assign valid_signal = 1'b1; // Driven
|
| 51 |
-
|
| 52 |
-
// active_low_b is used in expression but not driven
|
| 53 |
-
wire check = &active_low_b;
|
| 54 |
-
endmodule
|
| 55 |
-
"""
|
| 56 |
-
|
| 57 |
-
# Write to temp file
|
| 58 |
-
test_file = "temp_test.v"
|
| 59 |
-
with open(test_file, 'w') as f:
|
| 60 |
-
f.write(rtl)
|
| 61 |
-
|
| 62 |
-
try:
|
| 63 |
-
fixed, report = vlsi_tools.validate_rtl_for_synthesis(test_file)
|
| 64 |
-
|
| 65 |
-
with open(test_file, 'r') as f:
|
| 66 |
-
fixed_rtl = f.read()
|
| 67 |
-
|
| 68 |
-
print(f"Report:\n{report}")
|
| 69 |
-
|
| 70 |
-
# Checks
|
| 71 |
-
if "active_low_b = {4{1'b1}}" in fixed_rtl:
|
| 72 |
-
print("PASSED: active_low_b tied to 1s")
|
| 73 |
-
else:
|
| 74 |
-
print(f"FAILED: active_low_b fix incorrect. Content:\n{fixed_rtl}")
|
| 75 |
-
|
| 76 |
-
if "enable_n = 1'b1" in fixed_rtl:
|
| 77 |
-
print("PASSED: enable_n tied to 1")
|
| 78 |
-
else:
|
| 79 |
-
print(f"FAILED: enable_n fix incorrect. Content:\n{fixed_rtl}")
|
| 80 |
-
|
| 81 |
-
finally:
|
| 82 |
-
if os.path.exists(test_file):
|
| 83 |
-
os.remove(test_file)
|
| 84 |
-
|
| 85 |
-
if __name__ == "__main__":
|
| 86 |
-
vlsi_path = "src/agentic/tools/vlsi_tools.py"
|
| 87 |
-
if check_duplicates(vlsi_path):
|
| 88 |
-
test_validate_rtl()
|
| 89 |
-
else:
|
| 90 |
-
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
web/README.md
DELETED
|
@@ -1,73 +0,0 @@
|
|
| 1 |
-
# React + TypeScript + Vite
|
| 2 |
-
|
| 3 |
-
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
| 4 |
-
|
| 5 |
-
Currently, two official plugins are available:
|
| 6 |
-
|
| 7 |
-
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
|
| 8 |
-
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
| 9 |
-
|
| 10 |
-
## React Compiler
|
| 11 |
-
|
| 12 |
-
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
|
| 13 |
-
|
| 14 |
-
## Expanding the ESLint configuration
|
| 15 |
-
|
| 16 |
-
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
|
| 17 |
-
|
| 18 |
-
```js
|
| 19 |
-
export default defineConfig([
|
| 20 |
-
globalIgnores(['dist']),
|
| 21 |
-
{
|
| 22 |
-
files: ['**/*.{ts,tsx}'],
|
| 23 |
-
extends: [
|
| 24 |
-
// Other configs...
|
| 25 |
-
|
| 26 |
-
// Remove tseslint.configs.recommended and replace with this
|
| 27 |
-
tseslint.configs.recommendedTypeChecked,
|
| 28 |
-
// Alternatively, use this for stricter rules
|
| 29 |
-
tseslint.configs.strictTypeChecked,
|
| 30 |
-
// Optionally, add this for stylistic rules
|
| 31 |
-
tseslint.configs.stylisticTypeChecked,
|
| 32 |
-
|
| 33 |
-
// Other configs...
|
| 34 |
-
],
|
| 35 |
-
languageOptions: {
|
| 36 |
-
parserOptions: {
|
| 37 |
-
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
| 38 |
-
tsconfigRootDir: import.meta.dirname,
|
| 39 |
-
},
|
| 40 |
-
// other options...
|
| 41 |
-
},
|
| 42 |
-
},
|
| 43 |
-
])
|
| 44 |
-
```
|
| 45 |
-
|
| 46 |
-
You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
|
| 47 |
-
|
| 48 |
-
```js
|
| 49 |
-
// eslint.config.js
|
| 50 |
-
import reactX from 'eslint-plugin-react-x'
|
| 51 |
-
import reactDom from 'eslint-plugin-react-dom'
|
| 52 |
-
|
| 53 |
-
export default defineConfig([
|
| 54 |
-
globalIgnores(['dist']),
|
| 55 |
-
{
|
| 56 |
-
files: ['**/*.{ts,tsx}'],
|
| 57 |
-
extends: [
|
| 58 |
-
// Other configs...
|
| 59 |
-
// Enable lint rules for React
|
| 60 |
-
reactX.configs['recommended-typescript'],
|
| 61 |
-
// Enable lint rules for React DOM
|
| 62 |
-
reactDom.configs.recommended,
|
| 63 |
-
],
|
| 64 |
-
languageOptions: {
|
| 65 |
-
parserOptions: {
|
| 66 |
-
project: ['./tsconfig.node.json', './tsconfig.app.json'],
|
| 67 |
-
tsconfigRootDir: import.meta.dirname,
|
| 68 |
-
},
|
| 69 |
-
// other options...
|
| 70 |
-
},
|
| 71 |
-
},
|
| 72 |
-
])
|
| 73 |
-
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|