vxkyyy commited on
Commit
754da81
·
1 Parent(s): a6e26f9

fix: Remove unused vars to fix Vercel strict TS build

Browse files
.gitignore CHANGED
@@ -46,3 +46,19 @@ Thumbs.db
46
  temp_*.svg
47
  designs/*/src/sim
48
  .venv-agentic/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  temp_*.svg
47
  designs/*/src/sim
48
  .venv-agentic/
49
+
50
+ # Node / Frontend
51
+ node_modules/
52
+ web/node_modules/
53
+ web/dist/
54
+ web/.vite/
55
+ dist/
56
+
57
+ # Temporary / test scripts
58
+ *.tmp
59
+ global_reqs.tmp
60
+ venv_reqs.tmp
61
+ nodesource_setup.sh
62
+ test_import.py
63
+ test_signoff.py
64
+ test_signoff2.py
docs/AZURE_STUDENT_GUIDE.md DELETED
@@ -1,88 +0,0 @@
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
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
server/api.py CHANGED
@@ -81,6 +81,8 @@ def _get_llm():
81
  temperature=1.0,
82
  top_p=1.0,
83
  max_completion_tokens=16384,
 
 
84
  extra_body=extra,
85
  )
86
  return llm, name
@@ -476,8 +478,8 @@ def get_metrics(design_name: str):
476
  @app.get("/signoff/{design_name}")
477
  def get_signoff_report(design_name: str):
478
  try:
479
- from agentic.tools.vlsi_tools import signoff_check_tool
480
- success, report = signoff_check_tool.func(design_name)
481
- return {"success": success, "report": report}
482
  except Exception as e:
483
  raise HTTPException(status_code=500, detail=str(e))
 
81
  temperature=1.0,
82
  top_p=1.0,
83
  max_completion_tokens=16384,
84
+ max_tokens=16384,
85
+ timeout=300,
86
  extra_body=extra,
87
  )
88
  return llm, name
 
478
  @app.get("/signoff/{design_name}")
479
  def get_signoff_report(design_name: str):
480
  try:
481
+ from agentic.tools.vlsi_tools import check_physical_metrics
482
+ metrics, report = check_physical_metrics(design_name)
483
+ return {"success": metrics is not None, "report": report}
484
  except Exception as e:
485
  raise HTTPException(status_code=500, detail=str(e))
src/agentic/cli.py CHANGED
@@ -1,23 +1,23 @@
1
- #!/usr/bin/env python3
2
- """
3
- AgentIC - Natural Language to GDSII Pipeline
4
- =============================================
5
- Uses CrewAI + LLM (DeepSeek/Llama/Groq) to generate chips from natural language.
6
-
7
-
8
- Usage:
9
- python main.py build --name counter --desc "8-bit counter with enable and reset"
10
- """
11
-
12
- import os
13
- import re
14
- import sys
15
- import typer
16
- from rich.console import Console
17
- from rich.panel import Panel
18
- from rich.progress import Progress, SpinnerColumn, TextColumn
19
- from crewai import Agent, Task, Crew, LLM
20
-
21
  # Local imports
22
  from .config import (
23
  OPENLANE_ROOT,
@@ -33,83 +33,85 @@ from .config import (
33
  COVERAGE_FALLBACK_POLICY_DEFAULT,
34
  COVERAGE_PROFILE_DEFAULT,
35
  )
36
- from .agents.designer import get_designer_agent
37
- from .agents.testbench_designer import get_testbench_agent
38
- from .agents.verifier import get_verification_agent, get_error_analyst_agent
39
- from .tools.vlsi_tools import (
40
- write_verilog,
41
- write_config,
42
- run_syntax_check,
43
- syntax_check_tool,
44
- read_file_content,
45
- read_file_tool,
46
- run_simulation,
47
- run_openlane,
48
- run_verification,
49
- SecurityCheck,
50
- write_sby_config,
51
- run_formal_verification,
52
- check_physical_metrics,
53
  run_lint_check,
54
  run_gls_simulation,
55
  signoff_check_tool,
56
  startup_self_check,
57
  )
58
-
59
- # --- INITIALIZE ---
60
- app = typer.Typer()
61
- console = Console()
62
-
63
- # Setup Brain
64
  def get_llm():
65
- """Returns the LLM instance. Strict 3-Model Policy:
66
- 1. NVIDIA Nemotron Cloud (Primary)
67
- 2. NVIDIA Qwen Cloud (High Perf)
68
- 3. VeriReason Local (Fallback)
69
- """
70
-
71
  configs = [
72
  ("NVIDIA Nemotron Cloud", NEMOTRON_CONFIG),
73
  ("Backup GLM5 Cloud", GLM5_CONFIG),
74
  ("VeriReason Local", LOCAL_CONFIG),
75
  ]
76
-
77
- for name, cfg in configs:
78
- key = cfg.get("api_key", "")
79
- # For Cloud, skip if no key.
80
- if "Cloud" in name and (not key or key.strip() == "" or key == "mock-key"):
81
- console.print(f"[dim]⏭ {name}: No valid API key set, skipping.[/dim]")
82
- continue
83
-
84
- try:
85
- console.print(f"[dim]Testing {name}...[/dim]")
86
- # Add extra parameters for reasoning models
87
- extra_t = {}
88
- if "nemotron" in cfg["model"].lower():
89
- extra_t = {
90
- "reasoning_budget": 16384,
91
- "chat_template_kwargs": {"enable_thinking": True}
92
- }
93
- elif "glm5" in cfg["model"].lower():
94
- extra_t = {
95
- "chat_template_kwargs": {"enable_thinking": True, "clear_thinking": False}
96
- }
97
-
98
- llm = LLM(
99
- model=cfg["model"],
100
- base_url=cfg["base_url"],
101
- api_key=key if key and key != "NA" else "mock-key", # Local LLMs might use mock-key
102
- temperature=1.0,
103
- top_p=1.0,
104
- max_completion_tokens=16384,
105
- extra_body=extra_t
106
- )
107
- console.print(f"[green]✓ Using {name} ({cfg['model']})[/green]")
108
- return llm
109
- except Exception as e:
110
- console.print(f"[yellow]⚠ {name} init failed: {e}[/yellow]")
111
-
112
- # Critical Failure if both fail
 
 
113
  console.print(f"[bold red]CRITICAL: No valid LLM backend found.[/bold red]")
114
  console.print(f"Please set [bold]NVIDIA_API_KEY[/bold] for Cloud or configure [bold]LLM_BASE_URL[/bold] for Local.")
115
  raise typer.Exit(1)
@@ -126,321 +128,319 @@ def run_startup_diagnostics(strict: bool = True):
126
  console.print(f" [red]✗ {check.get('tool')}[/red] -> {check.get('resolved')}")
127
  if strict:
128
  raise typer.Exit(1)
129
-
130
-
131
- @app.command()
132
- def simulate(
133
- name: str = typer.Option(..., "--name", "-n", help="Design name (e.g., counter)"),
134
- max_retries: int = typer.Option(5, "--max-retries", "-r", min=0, help="Max auto-fix retries for failures"),
135
- show_thinking: bool = typer.Option(True, "--show-thinking", help="Print DeepSeek <think> reasoning")
136
- ):
137
- """Run simulation on an existing design with AUTO-FIX loop."""
138
- console.print(Panel(
139
- f"[bold cyan]AgentIC: Manual Simulation + Auto-Fix Mode[/bold cyan]\n"
140
- f"Design: [yellow]{name}[/yellow]",
141
- title="🚀 Starting Simulation"
142
- ))
143
-
144
- llm = get_llm()
145
-
146
- def log_thinking(raw_text: str, step: str):
147
- """Emit DeepSeek <think> content."""
148
- if not show_thinking: return
149
- # Simple logging for sim tool
150
- pass
151
-
152
- from .agents.verifier import get_error_analyst_agent
153
- from .tools.vlsi_tools import syntax_check_tool, read_file_tool
154
-
155
- rtl_path = f"{OPENLANE_ROOT}/designs/{name}/src/{name}.v"
156
- tb_path = f"{OPENLANE_ROOT}/designs/{name}/src/{name}_tb.v"
157
-
158
- def _fix_with_llm(agent_role: str, goal: str, prompt: str) -> str:
159
- # Give the agent TOOLS to self-correct
160
- fix_agent = Agent(
161
- role=agent_role,
162
- goal=goal,
163
- backstory='Expert in SystemVerilog and verification.',
164
- llm=llm,
165
- verbose=show_thinking,
166
- tools=[syntax_check_tool, read_file_tool]
167
- )
168
- fix_task = Task(
169
- description=prompt,
170
- expected_output='Corrected SystemVerilog code in a ```verilog fence',
171
- agent=fix_agent
172
- )
173
- with console.status(f"[cyan]AI is fixing ({agent_role})...[/cyan]"):
174
- result = str(Crew(agents=[fix_agent], tasks=[fix_task]).kickoff())
175
- return result
176
-
177
- sim_success, sim_output = run_simulation(name)
178
- sim_tries = 0
179
-
180
- while not sim_success and sim_tries < max_retries:
181
- sim_tries += 1
182
- console.print(f"[bold red]✗ SIMULATION FAILED (attempt {sim_tries}/{max_retries})[/bold red]")
183
- sim_output_text = sim_output or ""
184
-
185
- # 1) If compilation failed, fix TB first.
186
- if "Compilation failed:" in sim_output_text or "syntax error" in sim_output_text:
187
- fix_tb_prompt = f'''Fix this SystemVerilog testbench so it compiles and avoids directionality errors.
188
-
189
- CRITICAL FIXING RULES:
190
- 1. **Unresolved Wires**: If you see "Unable to assign to unresolved wires", it means you are driving a DUT OUTPUT. Stop driving it!
191
- 2. **Signal Directions**:
192
- - Check the DUT definition.
193
- - If a port is `output` in DUT, it is a `wire` in TB (Read-Only).
194
- - If a port is `input` in DUT, it is a `reg/logic` in TB (Write-Only).
195
- 3. **Format**: Return ONLY corrected testbench code inside ```verilog fences.
196
-
197
- Simulation output / errors:
198
- {sim_output_text}
199
-
200
- Current RTL (do not modify unless absolutely necessary):
201
- ```verilog
202
- {read_file_content(rtl_path)}
203
- ```
204
-
205
- Current testbench:
206
- ```verilog
207
- {read_file_content(tb_path)}
208
- ```
209
- '''
210
- fixed_tb = _fix_with_llm('Verification Engineer', f'Fix testbench for {name}', fix_tb_prompt)
211
- result_path = write_verilog(name, fixed_tb, is_testbench=True)
212
- if isinstance(result_path, str) and result_path.startswith("Error:"):
213
- sim_output = f"Failed to write fixed TB: {result_path}"
214
- continue
215
- tb_path = result_path
216
- sim_success, sim_output = run_simulation(name)
217
- continue
218
-
219
- # 2) Logic or Runtime Errors
220
- if "TEST FAILED" in sim_output_text or "TEST PASSED" not in sim_output_text:
221
-
222
- # AI-Based Error Classification
223
- analyst = get_error_analyst_agent(llm, verbose=False)
224
- analysis_task = Task(
225
- description=f'''Analyze this Verification Failure.
226
- Error Log:
227
- {sim_output_text}
228
- Is this a:
229
- A) TESTBENCH_ERROR (Syntax, $monitor usage, race condition, compilation fail)
230
- B) RTL_LOGIC_ERROR (Mismatch, Wrong State, Functional Failure)
231
- Reply with ONLY "A" or "B".''',
232
- expected_output='Single letter A or B',
233
- agent=analyst
234
- )
235
- analysis = str(Crew(agents=[analyst], tasks=[analysis_task]).kickoff()).strip()
236
-
237
- is_tb_issue = "A" in analysis
238
-
239
- if is_tb_issue:
240
- console.print("[yellow] -> [Analyst] Root Cause: Testbench Error. Fixing TB...[/yellow]")
241
- fix_tb_logic_prompt = f'''Fix the Testbench logic/syntax. The simulation failed or generated runtime errors.
242
-
243
- CRITICAL FIXING RULES:
244
- 1. **Timing is USUALLY THE PROBLEM**: If "TEST FAILED" appears, the testbench is checking outputs TOO EARLY.
245
- - Count the FSM states in the RTL. Wait at least (num_states + 10) clock cycles.
246
- - Use `repeat(25) @(posedge clk);` minimum before checking ANY output.
247
- - If there's a `done` or `valid` signal, use `while(!done) @(posedge clk);`
248
- 2. **Race Conditions**: Add `#1` delays after clock edges before sampling.
249
- 3. **Reset**: Ensure reset is held for at least 4 clock cycles.
250
- 4. **Between Tests**: Wait for FSM to return to IDLE with `repeat(10) @(posedge clk);`
251
- 5. **Format**: Return ONLY corrected testbench code inside ```verilog fences.
252
-
253
- Simulation Error/Output:
254
- {sim_output_text}
255
-
256
- Current RTL (Reference - count the FSM states):
257
- ```verilog
258
- {read_file_content(rtl_path)}
259
- ```
260
-
261
- Current Testbench (To Fix - increase wait cycles):
262
- ```verilog
263
- {read_file_content(tb_path)}
264
- ```
265
- '''
266
- fixed_tb = _fix_with_llm('Verification Engineer', f'Fix testbench logic for {name}', fix_tb_logic_prompt)
267
- result_path = write_verilog(name, fixed_tb, is_testbench=True)
268
- if isinstance(result_path, str) and result_path.startswith("Error:"):
269
- sim_output = f"Failed to write fixed TB: {result_path}"
270
- continue
271
- tb_path = result_path
272
- sim_success, sim_output = run_simulation(name)
273
- continue
274
-
275
- else:
276
- console.print("[yellow] -> Detecting Design Logic mismatch. Fixing RTL...[/yellow]")
277
- fix_rtl_prompt = f'''The simulation did not pass. Fix the RTL (module "{name}") so that the testbench passes.
278
-
279
- CRITICAL REQUIREMENTS:
280
- - **NO CONVERSATION**: Return ONLY the code inside ```verilog fences. Do NOT write "Thought:", "Here is the code", or any explanation.
281
- - Keep module name exactly "{name}"
282
- - SystemVerilog only
283
- - Keep ports: clk, rst_n (active-low) present
284
- - **MAINTAIN DESIGN INTENT**: Do NOT simplify the logic to pass the test case.
285
- - If the design is an NPU or Processor, do NOT replace complex logic with simple static assignments.
286
- - You must fix the BUGS in the implementation, not delete the implementation.
287
- - If the testbench expects a result after N cycles, ensure your pipeline matches that latency.
288
- - Return ONLY corrected RTL code inside ```verilog fences
289
-
290
- Simulation output:
291
- {sim_output_text}
292
-
293
- Current testbench (do not change in this step):
294
- ```verilog
295
- {read_file_content(tb_path)}
296
- ```
297
-
298
- Current RTL:
299
- ```verilog
300
- {read_file_content(rtl_path)}
301
- ```
302
- '''
303
- fixed_rtl = _fix_with_llm('VLSI Design Engineer', f'Fix RTL behavior for {name}', fix_rtl_prompt)
304
- rtl_path = write_verilog(name, fixed_rtl)
305
-
306
- # Check syntax of fix
307
- success, errors = run_syntax_check(rtl_path)
308
- if not success:
309
- sim_output = f"RTL fix introduced syntax error:\n{errors}"
310
- continue
311
-
312
- sim_success, sim_output = run_simulation(name)
313
- continue
314
-
315
- if not sim_success:
316
- console.print(f"[bold red]✗ SIMULATION FAILED:[/bold red]\n{sim_output}")
317
- raise typer.Exit(1)
318
-
319
- sim_lines = sim_output.strip().split('\n')
320
- for line in sim_lines[-20:]: # Print last 20 lines of log
321
- console.print(f" [dim]{line}[/dim]")
322
- console.print(" ✓ Simulation [green]passed[/green]")
323
-
324
-
325
- def _generate_config_tcl(design_name: str, rtl_file: str) -> str:
326
- """Auto-generate OpenLane config.tcl based on design complexity.
327
-
328
- Reads the RTL file to estimate size and generates appropriate
329
- die area, clock period, and synthesis settings.
330
- """
331
- # Estimate design complexity from file size
332
- try:
333
- with open(rtl_file, 'r') as f:
334
- rtl_content = f.read()
335
- line_count = len(rtl_content.strip().split('\n'))
336
- except IOError:
337
- line_count = 100 # Fallback
338
-
339
- # Scale parameters based on complexity
340
- if line_count < 100:
341
- # Small: counter, shift register, PWM
342
- die_size, util, clock_period = 300, 50, "10"
343
- elif line_count < 300:
344
- # Medium: FIFO, UART, SPI, FSM
345
- die_size, util, clock_period = 500, 40, "15"
346
- else:
347
- # Large: TMR, AES, processors
348
- die_size, util, clock_period = 800, 35, "20"
349
-
350
- return f'''# Auto-generated by AgentIC for {design_name}
351
- set ::env(DESIGN_NAME) "{design_name}"
352
- set ::env(VERILOG_FILES) "$::env(DESIGN_DIR)/src/{design_name}.v"
353
- set ::env(CLOCK_PORT) "clk"
354
- set ::env(CLOCK_PERIOD) "{clock_period}"
355
-
356
- # Floorplanning (scaled for ~{line_count} lines of RTL)
357
- set ::env(FP_SIZING) "absolute"
358
- set ::env(DIE_AREA) "0 0 {die_size} {die_size}"
359
- set ::env(FP_CORE_UTIL) {util}
360
- set ::env(PL_TARGET_DENSITY) {util / 100 + 0.05:.2f}
361
-
362
- # Synthesis
363
- set ::env(SYNTH_STRATEGY) "AREA 0"
364
- set ::env(MAX_FANOUT_CONSTRAINT) 8
365
-
366
- # Routing
367
- set ::env(GRT_OVERFLOW_ITERS) 64
368
-
369
- # PDK
370
- set ::env(PDK) "{PDK}"
371
- '''
372
-
373
-
374
- @app.command()
375
- def harden(
376
- name: str = typer.Option(..., "--name", "-n", help="Design name (e.g., counter)"),
377
- ):
378
- """Run OpenLane hardening (RTL -> GDSII) on an existing design."""
379
- console.print(Panel(
380
- f"[bold cyan]AgentIC: Manual Hardening Mode[/bold cyan]\n"
381
- f"Design: [yellow]{name}[/yellow]",
382
- title="🚀 Starting OpenLane"
383
- ))
384
-
385
- new_config = f"{OPENLANE_ROOT}/designs/{name}/config.tcl"
386
- rtl_file = f"{OPENLANE_ROOT}/designs/{name}/src/{name}.v"
387
-
388
- if not os.path.exists(new_config):
389
- if not os.path.exists(rtl_file):
390
- console.print(f"[bold red]✗ RTL file not found: {rtl_file}[/bold red]")
391
- raise typer.Exit(1)
392
-
393
- # Auto-generate config.tcl based on design size
394
- config_content = _generate_config_tcl(name, rtl_file)
395
- os.makedirs(os.path.dirname(new_config), exist_ok=True)
396
- with open(new_config, 'w') as f:
397
- f.write(config_content)
398
- console.print(f" ✓ Config auto-generated: [green]{new_config}[/green]")
399
-
400
- # Ask for background execution
401
- run_bg = typer.confirm("OpenLane hardening can take 10-30+ minutes. Run in background?", default=True)
402
-
403
- if run_bg:
404
- console.print(" [dim]Launching background process...[/dim]")
405
- else:
406
- console.print(" [dim]Running OpenLane (this may take 10-30 minutes)...[/dim]")
407
-
408
- ol_success, ol_result = run_openlane(name, background=run_bg)
409
-
410
- if ol_success:
411
- if run_bg:
412
- console.print(f" [green]{ol_result}[/green]")
413
- console.print(f" [dim]Monitor logs: tail -f {OPENLANE_ROOT}/designs/{name}/harden.log[/dim]")
414
- console.print(" [yellow]Note: Run manual signoff check after background job completes.[/yellow]")
415
- return
416
- console.print(f" ✓ GDSII generated: [green]{ol_result}[/green]")
417
-
418
- # --- Strict Signoff Check ---
419
- console.print(Panel(
420
- f"[bold cyan]Running Signoff Checks (STA/Power)...[/bold cyan]",
421
- title="🔍 Fabrication Readiness"
422
- ))
423
- success, report = signoff_check_tool(name)
424
- if success:
425
- console.print(f"[bold green]✅ SIGNOFF PASSED[/bold green]")
426
- console.print(report)
427
- else:
428
- console.print(f"[bold red]❌ SIGNOFF FAILED[/bold red]")
429
- console.print(report)
430
- raise typer.Exit(1)
431
-
432
- else:
433
- console.print(f"[bold red]✗ OpenLane failed[/bold red]")
434
- console.print(f" Error: {ol_result[:500]}...")
435
- raise typer.Exit(1)
436
-
437
- # --- THE BUILD COMMAND ---
438
- @app.command()
439
  def build(
440
  name: str = typer.Option(..., "--name", "-n", help="Design name (e.g., counter)"),
441
  desc: str = typer.Option(..., "--desc", "-d", help="Natural language description"),
442
  max_retries: int = typer.Option(5, "--max-retries", "-r", min=0, help="Max auto-fix retries for RTL/TB/sim failures"),
443
- skip_openlane: bool = typer.Option(False, "--skip-openlane", help="Stop after simulation (no RTL→GDSII hardening)"),
444
  show_thinking: bool = typer.Option(False, "--show-thinking", help="Print DeepSeek <think> reasoning for each generation/fix step"),
445
  full_signoff: bool = typer.Option(False, "--full-signoff", help="Run full industry signoff (formal + coverage + regression + DRC/LVS)"),
446
  min_coverage: float = typer.Option(80.0, "--min-coverage", help="Minimum line coverage percentage to pass verification"),
@@ -456,18 +456,18 @@ def build(
456
  coverage_fallback_policy: str = typer.Option(COVERAGE_FALLBACK_POLICY_DEFAULT, "--coverage-fallback-policy", help="Coverage fallback policy: fail_closed, fallback_oss, skip"),
457
  coverage_profile: str = typer.Option(COVERAGE_PROFILE_DEFAULT, "--coverage-profile", help="Coverage profile: balanced, aggressive, relaxed"),
458
  ):
459
- """Build a chip from natural language description (Autonomous Orchestrator 2.0)."""
460
-
461
- from .orchestrator import BuildOrchestrator
462
-
463
- console.print(Panel(
464
- f"[bold cyan]AgentIC: Natural Language → GDSII[/bold cyan]\n"
465
- f"Design: [yellow]{name}[/yellow]\n"
466
- f"Description: {desc}\n"
467
- f"{'[bold green]Full Industry Signoff Enabled[/bold green]' if full_signoff else ''}",
468
- title="🚀 Starting Autonomous Orchestrator"
469
- ))
470
-
471
  tb_gate_mode = tb_gate_mode.lower().strip()
472
  if tb_gate_mode not in {"strict", "relaxed"}:
473
  raise typer.BadParameter("--tb-gate-mode must be one of: strict, relaxed")
@@ -490,12 +490,12 @@ def build(
490
 
491
  run_startup_diagnostics(strict=strict_gates)
492
  llm = get_llm()
493
-
494
- orchestrator = BuildOrchestrator(
495
- name=name,
496
- desc=desc,
497
- llm=llm,
498
- max_retries=max_retries,
499
  verbose=show_thinking,
500
  skip_openlane=skip_openlane,
501
  full_signoff=full_signoff,
@@ -512,17 +512,17 @@ def build(
512
  coverage_fallback_policy=coverage_fallback_policy,
513
  coverage_profile=coverage_profile,
514
  )
515
-
516
- orchestrator.run()
517
-
518
- @app.command()
519
- def verify(name: str = typer.Argument(..., help="Design name to verify")):
520
- """Run verification on an existing design."""
521
- console.print(f"[yellow]Running verification for {name}...[/yellow]")
522
- output = run_verification(name)
523
- console.print(output)
524
-
525
-
526
-
527
- if __name__ == "__main__":
528
  app()
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ AgentIC - Natural Language to GDSII Pipeline
4
+ =============================================
5
+ Uses CrewAI + LLM (DeepSeek/Llama/Groq) to generate chips from natural language.
6
+
7
+
8
+ Usage:
9
+ python main.py build --name counter --desc "8-bit counter with enable and reset"
10
+ """
11
+
12
+ import os
13
+ import re
14
+ import sys
15
+ import typer
16
+ from rich.console import Console
17
+ from rich.panel import Panel
18
+ from rich.progress import Progress, SpinnerColumn, TextColumn
19
+ from crewai import Agent, Task, Crew, LLM
20
+
21
  # Local imports
22
  from .config import (
23
  OPENLANE_ROOT,
 
33
  COVERAGE_FALLBACK_POLICY_DEFAULT,
34
  COVERAGE_PROFILE_DEFAULT,
35
  )
36
+ from .agents.designer import get_designer_agent
37
+ from .agents.testbench_designer import get_testbench_agent
38
+ from .agents.verifier import get_verification_agent, get_error_analyst_agent
39
+ from .tools.vlsi_tools import (
40
+ write_verilog,
41
+ write_config,
42
+ run_syntax_check,
43
+ syntax_check_tool,
44
+ read_file_content,
45
+ read_file_tool,
46
+ run_simulation,
47
+ run_openlane,
48
+ run_verification,
49
+ SecurityCheck,
50
+ write_sby_config,
51
+ run_formal_verification,
52
+ check_physical_metrics,
53
  run_lint_check,
54
  run_gls_simulation,
55
  signoff_check_tool,
56
  startup_self_check,
57
  )
58
+
59
+ # --- INITIALIZE ---
60
+ app = typer.Typer()
61
+ console = Console()
62
+
63
+ # Setup Brain
64
  def get_llm():
65
+ """Returns the LLM instance. Strict 3-Model Policy:
66
+ 1. NVIDIA Nemotron Cloud (Primary)
67
+ 2. NVIDIA Qwen Cloud (High Perf)
68
+ 3. VeriReason Local (Fallback)
69
+ """
70
+
71
  configs = [
72
  ("NVIDIA Nemotron Cloud", NEMOTRON_CONFIG),
73
  ("Backup GLM5 Cloud", GLM5_CONFIG),
74
  ("VeriReason Local", LOCAL_CONFIG),
75
  ]
76
+
77
+ for name, cfg in configs:
78
+ key = cfg.get("api_key", "")
79
+ # For Cloud, skip if no key.
80
+ if "Cloud" in name and (not key or key.strip() == "" or key == "mock-key"):
81
+ console.print(f"[dim]⏭ {name}: No valid API key set, skipping.[/dim]")
82
+ continue
83
+
84
+ try:
85
+ console.print(f"[dim]Testing {name}...[/dim]")
86
+ # Add extra parameters for reasoning models
87
+ extra_t = {}
88
+ if "nemotron" in cfg["model"].lower():
89
+ extra_t = {
90
+ "reasoning_budget": 16384,
91
+ "chat_template_kwargs": {"enable_thinking": True}
92
+ }
93
+ elif "glm5" in cfg["model"].lower():
94
+ extra_t = {
95
+ "chat_template_kwargs": {"enable_thinking": True, "clear_thinking": False}
96
+ }
97
+
98
+ llm = LLM(
99
+ model=cfg["model"],
100
+ base_url=cfg["base_url"],
101
+ api_key=key if key and key != "NA" else "mock-key", # Local LLMs might use mock-key
102
+ temperature=1.0,
103
+ top_p=1.0,
104
+ max_completion_tokens=16384,
105
+ max_tokens=16384,
106
+ timeout=300,
107
+ extra_body=extra_t
108
+ )
109
+ console.print(f"[green]✓ Using {name} ({cfg['model']})[/green]")
110
+ return llm
111
+ except Exception as e:
112
+ console.print(f"[yellow]⚠ {name} init failed: {e}[/yellow]")
113
+
114
+ # Critical Failure if both fail
115
  console.print(f"[bold red]CRITICAL: No valid LLM backend found.[/bold red]")
116
  console.print(f"Please set [bold]NVIDIA_API_KEY[/bold] for Cloud or configure [bold]LLM_BASE_URL[/bold] for Local.")
117
  raise typer.Exit(1)
 
128
  console.print(f" [red]✗ {check.get('tool')}[/red] -> {check.get('resolved')}")
129
  if strict:
130
  raise typer.Exit(1)
131
+
132
+
133
+ @app.command()
134
+ def simulate(
135
+ name: str = typer.Option(..., "--name", "-n", help="Design name (e.g., counter)"),
136
+ max_retries: int = typer.Option(5, "--max-retries", "-r", min=0, help="Max auto-fix retries for failures"),
137
+ show_thinking: bool = typer.Option(True, "--show-thinking", help="Print DeepSeek <think> reasoning")
138
+ ):
139
+ """Run simulation on an existing design with AUTO-FIX loop."""
140
+ console.print(Panel(
141
+ f"[bold cyan]AgentIC: Manual Simulation + Auto-Fix Mode[/bold cyan]\n"
142
+ f"Design: [yellow]{name}[/yellow]",
143
+ title="🚀 Starting Simulation"
144
+ ))
145
+
146
+ llm = get_llm()
147
+
148
+ def log_thinking(raw_text: str, step: str):
149
+ """Emit DeepSeek <think> content."""
150
+ if not show_thinking: return
151
+ # Simple logging for sim tool
152
+ pass
153
+
154
+
155
+ rtl_path = f"{OPENLANE_ROOT}/designs/{name}/src/{name}.v"
156
+ tb_path = f"{OPENLANE_ROOT}/designs/{name}/src/{name}_tb.v"
157
+
158
+ def _fix_with_llm(agent_role: str, goal: str, prompt: str) -> str:
159
+ # Give the agent TOOLS to self-correct
160
+ fix_agent = Agent(
161
+ role=agent_role,
162
+ goal=goal,
163
+ backstory='Expert in SystemVerilog and verification.',
164
+ llm=llm,
165
+ verbose=show_thinking,
166
+ tools=[syntax_check_tool, read_file_tool]
167
+ )
168
+ fix_task = Task(
169
+ description=prompt,
170
+ expected_output='Corrected SystemVerilog code in a ```verilog fence',
171
+ agent=fix_agent
172
+ )
173
+ with console.status(f"[cyan]AI is fixing ({agent_role})...[/cyan]"):
174
+ result = str(Crew(agents=[fix_agent], tasks=[fix_task]).kickoff())
175
+ return result
176
+
177
+ sim_success, sim_output = run_simulation(name)
178
+ sim_tries = 0
179
+
180
+ while not sim_success and sim_tries < max_retries:
181
+ sim_tries += 1
182
+ console.print(f"[bold red]✗ SIMULATION FAILED (attempt {sim_tries}/{max_retries})[/bold red]")
183
+ sim_output_text = sim_output or ""
184
+
185
+ # 1) If compilation failed, fix TB first.
186
+ if "Compilation failed:" in sim_output_text or "syntax error" in sim_output_text:
187
+ fix_tb_prompt = f'''Fix this SystemVerilog testbench so it compiles and avoids directionality errors.
188
+
189
+ CRITICAL FIXING RULES:
190
+ 1. **Unresolved Wires**: If you see "Unable to assign to unresolved wires", it means you are driving a DUT OUTPUT. Stop driving it!
191
+ 2. **Signal Directions**:
192
+ - Check the DUT definition.
193
+ - If a port is `output` in DUT, it is a `wire` in TB (Read-Only).
194
+ - If a port is `input` in DUT, it is a `reg/logic` in TB (Write-Only).
195
+ 3. **Format**: Return ONLY corrected testbench code inside ```verilog fences.
196
+
197
+ Simulation output / errors:
198
+ {sim_output_text}
199
+
200
+ Current RTL (do not modify unless absolutely necessary):
201
+ ```verilog
202
+ {read_file_content(rtl_path)}
203
+ ```
204
+
205
+ Current testbench:
206
+ ```verilog
207
+ {read_file_content(tb_path)}
208
+ ```
209
+ '''
210
+ fixed_tb = _fix_with_llm('Verification Engineer', f'Fix testbench for {name}', fix_tb_prompt)
211
+ result_path = write_verilog(name, fixed_tb, is_testbench=True)
212
+ if isinstance(result_path, str) and result_path.startswith("Error:"):
213
+ sim_output = f"Failed to write fixed TB: {result_path}"
214
+ continue
215
+ tb_path = result_path
216
+ sim_success, sim_output = run_simulation(name)
217
+ continue
218
+
219
+ # 2) Logic or Runtime Errors
220
+ if "TEST FAILED" in sim_output_text or "TEST PASSED" not in sim_output_text:
221
+
222
+ # AI-Based Error Classification
223
+ analyst = get_error_analyst_agent(llm, verbose=False)
224
+ analysis_task = Task(
225
+ description=f'''Analyze this Verification Failure.
226
+ Error Log:
227
+ {sim_output_text}
228
+ Is this a:
229
+ A) TESTBENCH_ERROR (Syntax, $monitor usage, race condition, compilation fail)
230
+ B) RTL_LOGIC_ERROR (Mismatch, Wrong State, Functional Failure)
231
+ Reply with ONLY "A" or "B".''',
232
+ expected_output='Single letter A or B',
233
+ agent=analyst
234
+ )
235
+ analysis = str(Crew(agents=[analyst], tasks=[analysis_task]).kickoff()).strip()
236
+
237
+ is_tb_issue = "A" in analysis
238
+
239
+ if is_tb_issue:
240
+ console.print("[yellow] -> [Analyst] Root Cause: Testbench Error. Fixing TB...[/yellow]")
241
+ fix_tb_logic_prompt = f'''Fix the Testbench logic/syntax. The simulation failed or generated runtime errors.
242
+
243
+ CRITICAL FIXING RULES:
244
+ 1. **Timing is USUALLY THE PROBLEM**: If "TEST FAILED" appears, the testbench is checking outputs TOO EARLY.
245
+ - Count the FSM states in the RTL. Wait at least (num_states + 10) clock cycles.
246
+ - Use `repeat(25) @(posedge clk);` minimum before checking ANY output.
247
+ - If there's a `done` or `valid` signal, use `while(!done) @(posedge clk);`
248
+ 2. **Race Conditions**: Add `#1` delays after clock edges before sampling.
249
+ 3. **Reset**: Ensure reset is held for at least 4 clock cycles.
250
+ 4. **Between Tests**: Wait for FSM to return to IDLE with `repeat(10) @(posedge clk);`
251
+ 5. **Format**: Return ONLY corrected testbench code inside ```verilog fences.
252
+
253
+ Simulation Error/Output:
254
+ {sim_output_text}
255
+
256
+ Current RTL (Reference - count the FSM states):
257
+ ```verilog
258
+ {read_file_content(rtl_path)}
259
+ ```
260
+
261
+ Current Testbench (To Fix - increase wait cycles):
262
+ ```verilog
263
+ {read_file_content(tb_path)}
264
+ ```
265
+ '''
266
+ fixed_tb = _fix_with_llm('Verification Engineer', f'Fix testbench logic for {name}', fix_tb_logic_prompt)
267
+ result_path = write_verilog(name, fixed_tb, is_testbench=True)
268
+ if isinstance(result_path, str) and result_path.startswith("Error:"):
269
+ sim_output = f"Failed to write fixed TB: {result_path}"
270
+ continue
271
+ tb_path = result_path
272
+ sim_success, sim_output = run_simulation(name)
273
+ continue
274
+
275
+ else:
276
+ console.print("[yellow] -> Detecting Design Logic mismatch. Fixing RTL...[/yellow]")
277
+ fix_rtl_prompt = f'''The simulation did not pass. Fix the RTL (module "{name}") so that the testbench passes.
278
+
279
+ CRITICAL REQUIREMENTS:
280
+ - **NO CONVERSATION**: Return ONLY the code inside ```verilog fences. Do NOT write "Thought:", "Here is the code", or any explanation.
281
+ - Keep module name exactly "{name}"
282
+ - SystemVerilog only
283
+ - Keep ports: clk, rst_n (active-low) present
284
+ - **MAINTAIN DESIGN INTENT**: Do NOT simplify the logic to pass the test case.
285
+ - If the design is an NPU or Processor, do NOT replace complex logic with simple static assignments.
286
+ - You must fix the BUGS in the implementation, not delete the implementation.
287
+ - If the testbench expects a result after N cycles, ensure your pipeline matches that latency.
288
+ - Return ONLY corrected RTL code inside ```verilog fences
289
+
290
+ Simulation output:
291
+ {sim_output_text}
292
+
293
+ Current testbench (do not change in this step):
294
+ ```verilog
295
+ {read_file_content(tb_path)}
296
+ ```
297
+
298
+ Current RTL:
299
+ ```verilog
300
+ {read_file_content(rtl_path)}
301
+ ```
302
+ '''
303
+ fixed_rtl = _fix_with_llm('VLSI Design Engineer', f'Fix RTL behavior for {name}', fix_rtl_prompt)
304
+ rtl_path = write_verilog(name, fixed_rtl)
305
+
306
+ # Check syntax of fix
307
+ success, errors = run_syntax_check(rtl_path)
308
+ if not success:
309
+ sim_output = f"RTL fix introduced syntax error:\n{errors}"
310
+ continue
311
+
312
+ sim_success, sim_output = run_simulation(name)
313
+ continue
314
+
315
+ if not sim_success:
316
+ console.print(f"[bold red]✗ SIMULATION FAILED:[/bold red]\n{sim_output}")
317
+ raise typer.Exit(1)
318
+
319
+ sim_lines = sim_output.strip().split('\n')
320
+ for line in sim_lines[-20:]: # Print last 20 lines of log
321
+ console.print(f" [dim]{line}[/dim]")
322
+ console.print(" ✓ Simulation [green]passed[/green]")
323
+
324
+
325
+ def _generate_config_tcl(design_name: str, rtl_file: str) -> str:
326
+ """Auto-generate OpenLane config.tcl based on design complexity.
327
+
328
+ Reads the RTL file to estimate size and generates appropriate
329
+ die area, clock period, and synthesis settings.
330
+ """
331
+ # Estimate design complexity from file size
332
+ try:
333
+ with open(rtl_file, 'r') as f:
334
+ rtl_content = f.read()
335
+ line_count = len(rtl_content.strip().split('\n'))
336
+ except IOError:
337
+ line_count = 100 # Fallback
338
+
339
+ # Scale parameters based on complexity
340
+ if line_count < 100:
341
+ # Small: counter, shift register, PWM
342
+ die_size, util, clock_period = 300, 50, "10"
343
+ elif line_count < 300:
344
+ # Medium: FIFO, UART, SPI, FSM
345
+ die_size, util, clock_period = 500, 40, "15"
346
+ else:
347
+ # Large: TMR, AES, processors
348
+ die_size, util, clock_period = 800, 35, "20"
349
+
350
+ return f'''# Auto-generated by AgentIC for {design_name}
351
+ set ::env(DESIGN_NAME) "{design_name}"
352
+ set ::env(VERILOG_FILES) "$::env(DESIGN_DIR)/src/{design_name}.v"
353
+ set ::env(CLOCK_PORT) "clk"
354
+ set ::env(CLOCK_PERIOD) "{clock_period}"
355
+
356
+ # Floorplanning (scaled for ~{line_count} lines of RTL)
357
+ set ::env(FP_SIZING) "absolute"
358
+ set ::env(DIE_AREA) "0 0 {die_size} {die_size}"
359
+ set ::env(FP_CORE_UTIL) {util}
360
+ set ::env(PL_TARGET_DENSITY) {util / 100 + 0.05:.2f}
361
+
362
+ # Synthesis
363
+ set ::env(SYNTH_STRATEGY) "AREA 0"
364
+ set ::env(MAX_FANOUT_CONSTRAINT) 8
365
+
366
+ # Routing
367
+ set ::env(GRT_OVERFLOW_ITERS) 64
368
+
369
+ # PDK
370
+ set ::env(PDK) "{PDK}"
371
+ '''
372
+
373
+
374
+ @app.command()
375
+ def harden(
376
+ name: str = typer.Option(..., "--name", "-n", help="Design name (e.g., counter)"),
377
+ ):
378
+ """Run OpenLane hardening (RTL -> GDSII) on an existing design."""
379
+ console.print(Panel(
380
+ f"[bold cyan]AgentIC: Manual Hardening Mode[/bold cyan]\n"
381
+ f"Design: [yellow]{name}[/yellow]",
382
+ title="🚀 Starting OpenLane"
383
+ ))
384
+
385
+ new_config = f"{OPENLANE_ROOT}/designs/{name}/config.tcl"
386
+ rtl_file = f"{OPENLANE_ROOT}/designs/{name}/src/{name}.v"
387
+
388
+ if not os.path.exists(new_config):
389
+ if not os.path.exists(rtl_file):
390
+ console.print(f"[bold red]✗ RTL file not found: {rtl_file}[/bold red]")
391
+ raise typer.Exit(1)
392
+
393
+ # Auto-generate config.tcl based on design size
394
+ config_content = _generate_config_tcl(name, rtl_file)
395
+ os.makedirs(os.path.dirname(new_config), exist_ok=True)
396
+ with open(new_config, 'w') as f:
397
+ f.write(config_content)
398
+ console.print(f" ✓ Config auto-generated: [green]{new_config}[/green]")
399
+
400
+ # Ask for background execution
401
+ run_bg = typer.confirm("OpenLane hardening can take 10-30+ minutes. Run in background?", default=True)
402
+
403
+ if run_bg:
404
+ console.print(" [dim]Launching background process...[/dim]")
405
+ else:
406
+ console.print(" [dim]Running OpenLane (this may take 10-30 minutes)...[/dim]")
407
+
408
+ ol_success, ol_result = run_openlane(name, background=run_bg)
409
+
410
+ if ol_success:
411
+ if run_bg:
412
+ console.print(f" ✓ [green]{ol_result}[/green]")
413
+ console.print(f" [dim]Monitor logs: tail -f {OPENLANE_ROOT}/designs/{name}/harden.log[/dim]")
414
+ console.print(" [yellow]Note: Run manual signoff check after background job completes.[/yellow]")
415
+ return
416
+ console.print(f" GDSII generated: [green]{ol_result}[/green]")
417
+
418
+ # --- Strict Signoff Check ---
419
+ console.print(Panel(
420
+ f"[bold cyan]Running Signoff Checks (STA/Power)...[/bold cyan]",
421
+ title="🔍 Fabrication Readiness"
422
+ ))
423
+ success, report = signoff_check_tool(name)
424
+ if success:
425
+ console.print(f"[bold green]✅ SIGNOFF PASSED[/bold green]")
426
+ console.print(report)
427
+ else:
428
+ console.print(f"[bold red]❌ SIGNOFF FAILED[/bold red]")
429
+ console.print(report)
430
+ raise typer.Exit(1)
431
+
432
+ else:
433
+ console.print(f"[bold red]✗ OpenLane failed[/bold red]")
434
+ console.print(f" Error: {ol_result[:500]}...")
435
+ raise typer.Exit(1)
436
+
437
+ # --- THE BUILD COMMAND ---
438
+ @app.command()
 
 
439
  def build(
440
  name: str = typer.Option(..., "--name", "-n", help="Design name (e.g., counter)"),
441
  desc: str = typer.Option(..., "--desc", "-d", help="Natural language description"),
442
  max_retries: int = typer.Option(5, "--max-retries", "-r", min=0, help="Max auto-fix retries for RTL/TB/sim failures"),
443
+ skip_openlane: bool = typer.Option(False, "--skip-openlane", help="Stop after simulation (no RTL→GDSII hardening)"),
444
  show_thinking: bool = typer.Option(False, "--show-thinking", help="Print DeepSeek <think> reasoning for each generation/fix step"),
445
  full_signoff: bool = typer.Option(False, "--full-signoff", help="Run full industry signoff (formal + coverage + regression + DRC/LVS)"),
446
  min_coverage: float = typer.Option(80.0, "--min-coverage", help="Minimum line coverage percentage to pass verification"),
 
456
  coverage_fallback_policy: str = typer.Option(COVERAGE_FALLBACK_POLICY_DEFAULT, "--coverage-fallback-policy", help="Coverage fallback policy: fail_closed, fallback_oss, skip"),
457
  coverage_profile: str = typer.Option(COVERAGE_PROFILE_DEFAULT, "--coverage-profile", help="Coverage profile: balanced, aggressive, relaxed"),
458
  ):
459
+ """Build a chip from natural language description (Autonomous Orchestrator 2.0)."""
460
+
461
+ from .orchestrator import BuildOrchestrator
462
+
463
+ console.print(Panel(
464
+ f"[bold cyan]AgentIC: Natural Language → GDSII[/bold cyan]\n"
465
+ f"Design: [yellow]{name}[/yellow]\n"
466
+ f"Description: {desc}\n"
467
+ f"{'[bold green]Full Industry Signoff Enabled[/bold green]' if full_signoff else ''}",
468
+ title="🚀 Starting Autonomous Orchestrator"
469
+ ))
470
+
471
  tb_gate_mode = tb_gate_mode.lower().strip()
472
  if tb_gate_mode not in {"strict", "relaxed"}:
473
  raise typer.BadParameter("--tb-gate-mode must be one of: strict, relaxed")
 
490
 
491
  run_startup_diagnostics(strict=strict_gates)
492
  llm = get_llm()
493
+
494
+ orchestrator = BuildOrchestrator(
495
+ name=name,
496
+ desc=desc,
497
+ llm=llm,
498
+ max_retries=max_retries,
499
  verbose=show_thinking,
500
  skip_openlane=skip_openlane,
501
  full_signoff=full_signoff,
 
512
  coverage_fallback_policy=coverage_fallback_policy,
513
  coverage_profile=coverage_profile,
514
  )
515
+
516
+ orchestrator.run()
517
+
518
+ @app.command()
519
+ def verify(name: str = typer.Argument(..., help="Design name to verify")):
520
+ """Run verification on an existing design."""
521
+ console.print(f"[yellow]Running verification for {name}...[/yellow]")
522
+ output = run_verification(name)
523
+ console.print(output)
524
+
525
+
526
+
527
+ if __name__ == "__main__":
528
  app()
src/agentic/orchestrator.py CHANGED
@@ -29,6 +29,7 @@ from .agents.designer import get_designer_agent
29
  from .agents.testbench_designer import get_testbench_agent
30
  from .agents.verifier import get_verification_agent, get_error_analyst_agent, get_regression_agent
31
  from .agents.doc_agent import get_doc_agent
 
32
  from .tools.vlsi_tools import (
33
  write_verilog,
34
  run_syntax_check,
@@ -46,7 +47,6 @@ from .tools.vlsi_tools import (
46
  parse_drc_lvs_reports,
47
  parse_sta_signoff,
48
  parse_power_signoff,
49
- check_physical_metrics,
50
  run_cdc_check,
51
  generate_design_doc,
52
  convert_sva_to_yosys,
@@ -78,6 +78,7 @@ class BuildState(enum.Enum):
78
  FORMAL_VERIFY = "Formal Property Verification"
79
  COVERAGE_CHECK = "Coverage Analysis"
80
  REGRESSION = "Regression Testing"
 
81
  FLOORPLAN = "Floorplanning"
82
  HARDENING = "GDSII Hardening"
83
  CONVERGENCE_REVIEW = "Convergence Review"
@@ -179,9 +180,9 @@ class BuildOrchestrator:
179
  self.tb_repair_fail_count = 0
180
  self.tb_failure_fingerprint_history: Dict[str, int] = {}
181
  self.tb_recovery_counts: Dict[str, int] = {}
182
- self.artifacts = {} # Store paths to gathered files
183
- self.history = [] # Log of state transitions and errors
184
- self.errors = [] # List of error messages
185
 
186
  def setup_logger(self):
187
  """Sets up a file logger for the build process."""
@@ -405,6 +406,8 @@ class BuildOrchestrator:
405
  self.do_coverage_check()
406
  elif self.state == BuildState.REGRESSION:
407
  self.do_regression()
 
 
408
  elif self.state == BuildState.FLOORPLAN:
409
  self.do_floorplan()
410
  elif self.state == BuildState.HARDENING:
@@ -1133,7 +1136,7 @@ endclass
1133
  def _kickoff_with_timeout(self, agents: List[Agent], tasks: List[Task], timeout_s: int) -> str:
1134
  timeout_s = max(1, int(timeout_s))
1135
  if not hasattr(signal, "SIGALRM"):
1136
- return str(Crew(agents=agents, tasks=tasks).kickoff())
1137
 
1138
  def _timeout_handler(signum, frame):
1139
  raise TimeoutError(f"Crew kickoff exceeded {timeout_s}s timeout")
@@ -1142,7 +1145,7 @@ endclass
1142
  signal.signal(signal.SIGALRM, _timeout_handler)
1143
  signal.alarm(timeout_s)
1144
  try:
1145
- return str(Crew(agents=agents, tasks=tasks).kickoff())
1146
  finally:
1147
  signal.alarm(0)
1148
  signal.signal(signal.SIGALRM, prev_handler)
@@ -1405,12 +1408,12 @@ LOGIC DECOUPLING HINT:
1405
  {self.artifacts.get('logic_decoupling_hint', 'N/A')}
1406
 
1407
  CRITICAL RULES:
1408
- 1. Module name must be "{self.name}"
1409
  2. Async active-low reset `rst_n`
1410
- 3. Flatten ports (no multi-dim arrays on ports)
1411
  4. **IMPLEMENT EVERYTHING**: Do not leave any logic as "to be implemented" or "simplified".
1412
- 5. **VERIFY CONNECTIVITY**: Ensure all sub-modules (if any) are correctly connected.
1413
- 6. Return code in ```verilog fence
1414
  """,
1415
  expected_output='Verilog Code',
1416
  agent=rtl_agent
@@ -2235,7 +2238,7 @@ CRITICAL:
2235
  elif self.skip_openlane:
2236
  self.transition(BuildState.SUCCESS)
2237
  else:
2238
- self.transition(BuildState.FLOORPLAN)
2239
  return
2240
  if self.strict_gates:
2241
  self.log("Coverage infra failure is blocking under strict mode.", refined=True)
@@ -2247,7 +2250,7 @@ CRITICAL:
2247
  elif self.skip_openlane:
2248
  self.transition(BuildState.SUCCESS)
2249
  else:
2250
- self.transition(BuildState.FLOORPLAN)
2251
  return
2252
 
2253
  if not coverage_data.get("ok", False):
@@ -2258,7 +2261,7 @@ CRITICAL:
2258
 
2259
  coverage_checks = {
2260
  "line": line_pct >= float(thresholds["line"]),
2261
- "branch": branch_pct >= float(thresholds["branch"]),
2262
  "toggle": toggle_pct >= float(thresholds["toggle"]),
2263
  "functional": functional_pct >= float(thresholds["functional"]),
2264
  }
@@ -2282,7 +2285,7 @@ CRITICAL:
2282
  self.log(
2283
  (
2284
  "Coverage PASSED "
2285
- f"(line>={thresholds['line']:.1f}, branch>={thresholds['branch']:.1f}, "
2286
  f"toggle>={thresholds['toggle']:.1f}, functional>={thresholds['functional']:.1f})"
2287
  ),
2288
  refined=True,
@@ -2292,11 +2295,11 @@ CRITICAL:
2292
  elif self.skip_openlane:
2293
  self.transition(BuildState.SUCCESS)
2294
  else:
2295
- self.transition(BuildState.FLOORPLAN)
2296
  return
2297
 
2298
  self.retry_count += 1
2299
- coverage_max_retries = min(self.max_retries, 2)
2300
  if self.retry_count > coverage_max_retries:
2301
  if getattr(self, "best_tb_backup", None) and os.path.exists(self.best_tb_backup):
2302
  self.log(f"Restoring Best Testbench ({self.best_coverage:.1f}%) before proceeding.", refined=True)
@@ -2312,7 +2315,7 @@ CRITICAL:
2312
  elif self.skip_openlane:
2313
  self.transition(BuildState.SUCCESS)
2314
  else:
2315
- self.transition(BuildState.FLOORPLAN)
2316
  return
2317
 
2318
  self.log(
@@ -2327,7 +2330,7 @@ CRITICAL:
2327
  tb_agent = get_testbench_agent(self.llm, f"Improve coverage for {self.name}", verbose=self.verbose, strategy=self.strategy.name)
2328
 
2329
  improve_prompt = f"""The current testbench for "{self.name}" does not meet coverage thresholds.
2330
- Thresholds: {thresholds}
2331
  Current Coverage Data: {coverage_data}
2332
 
2333
  Current RTL:
@@ -2341,8 +2344,9 @@ CRITICAL:
2341
  ```
2342
 
2343
  Create an IMPROVED self-checking testbench that:
2344
- 1. Tests all FSM states (not just happy path)
2345
- 2. Exercises all conditional branches (if/else, case)
 
2346
  3. Tests reset behavior mid-operation
2347
  4. Tests boundary values (max/min inputs)
2348
  5. Includes back-to-back operations
@@ -2512,7 +2516,49 @@ CRITICAL:
2512
  if self.skip_openlane:
2513
  self.transition(BuildState.SUCCESS)
2514
  else:
2515
- self.transition(BuildState.FLOORPLAN)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2516
 
2517
  def do_floorplan(self):
2518
  """Generate floorplan artifacts and feed hardening with spatial intent."""
@@ -2625,12 +2671,15 @@ REASONING: <1-line explanation>""",
2625
  )
2626
 
2627
  floorplan_tcl = os.path.join(src_dir, f"{self.name}_floorplan.tcl")
 
 
2628
  with open(floorplan_tcl, "w") as f:
2629
  f.write(
2630
  f"set ::env(DESIGN_NAME) \"{self.name}\"\n"
2631
  f"set ::env(PDK) \"{self.pdk_profile.get('pdk', PDK)}\"\n"
2632
  f"set ::env(STD_CELL_LIBRARY) \"{self.pdk_profile.get('std_cell_library', 'sky130_fd_sc_hd')}\"\n"
2633
  f"set ::env(VERILOG_FILES) [glob $::env(DESIGN_DIR)/src/{self.name}.v]\n"
 
2634
  "set ::env(FP_SIZING) \"absolute\"\n"
2635
  f"set ::env(DIE_AREA) \"0 0 {die} {die}\"\n"
2636
  f"set ::env(FP_CORE_UTIL) {util}\n"
 
29
  from .agents.testbench_designer import get_testbench_agent
30
  from .agents.verifier import get_verification_agent, get_error_analyst_agent, get_regression_agent
31
  from .agents.doc_agent import get_doc_agent
32
+ from .agents.sdc_agent import get_sdc_agent
33
  from .tools.vlsi_tools import (
34
  write_verilog,
35
  run_syntax_check,
 
47
  parse_drc_lvs_reports,
48
  parse_sta_signoff,
49
  parse_power_signoff,
 
50
  run_cdc_check,
51
  generate_design_doc,
52
  convert_sva_to_yosys,
 
78
  FORMAL_VERIFY = "Formal Property Verification"
79
  COVERAGE_CHECK = "Coverage Analysis"
80
  REGRESSION = "Regression Testing"
81
+ SDC_GEN = "Timing Constraints Generation"
82
  FLOORPLAN = "Floorplanning"
83
  HARDENING = "GDSII Hardening"
84
  CONVERGENCE_REVIEW = "Convergence Review"
 
180
  self.tb_repair_fail_count = 0
181
  self.tb_failure_fingerprint_history: Dict[str, int] = {}
182
  self.tb_recovery_counts: Dict[str, int] = {}
183
+ self.artifacts: Dict[str, Any] = {} # Store paths to gathered files
184
+ self.history: List[Dict[str, Any]] = [] # Log of state transitions and errors
185
+ self.errors: List[str] = [] # List of error messages
186
 
187
  def setup_logger(self):
188
  """Sets up a file logger for the build process."""
 
406
  self.do_coverage_check()
407
  elif self.state == BuildState.REGRESSION:
408
  self.do_regression()
409
+ elif self.state == BuildState.SDC_GEN:
410
+ self.do_sdc_gen()
411
  elif self.state == BuildState.FLOORPLAN:
412
  self.do_floorplan()
413
  elif self.state == BuildState.HARDENING:
 
1136
  def _kickoff_with_timeout(self, agents: List[Agent], tasks: List[Task], timeout_s: int) -> str:
1137
  timeout_s = max(1, int(timeout_s))
1138
  if not hasattr(signal, "SIGALRM"):
1139
+ return str(Crew(agents=agents, tasks=tasks).kickoff()) # type: ignore
1140
 
1141
  def _timeout_handler(signum, frame):
1142
  raise TimeoutError(f"Crew kickoff exceeded {timeout_s}s timeout")
 
1145
  signal.signal(signal.SIGALRM, _timeout_handler)
1146
  signal.alarm(timeout_s)
1147
  try:
1148
+ return str(Crew(agents=agents, tasks=tasks).kickoff()) # type: ignore
1149
  finally:
1150
  signal.alarm(0)
1151
  signal.signal(signal.SIGALRM, prev_handler)
 
1408
  {self.artifacts.get('logic_decoupling_hint', 'N/A')}
1409
 
1410
  CRITICAL RULES:
1411
+ 1. Top-level module name MUST be "{self.name}"
1412
  2. Async active-low reset `rst_n`
1413
+ 3. Flatten ports on the TOP module (no multi-dim arrays on top-level ports). Internal modules can use them.
1414
  4. **IMPLEMENT EVERYTHING**: Do not leave any logic as "to be implemented" or "simplified".
1415
+ 5. **MODULAR HIERARCHY**: For complex designs, break them into smaller sub-modules. Output ALL modules in your response.
1416
+ 6. Return code in ```verilog fence.
1417
  """,
1418
  expected_output='Verilog Code',
1419
  agent=rtl_agent
 
2238
  elif self.skip_openlane:
2239
  self.transition(BuildState.SUCCESS)
2240
  else:
2241
+ self.transition(BuildState.SDC_GEN)
2242
  return
2243
  if self.strict_gates:
2244
  self.log("Coverage infra failure is blocking under strict mode.", refined=True)
 
2250
  elif self.skip_openlane:
2251
  self.transition(BuildState.SUCCESS)
2252
  else:
2253
+ self.transition(BuildState.SDC_GEN)
2254
  return
2255
 
2256
  if not coverage_data.get("ok", False):
 
2261
 
2262
  coverage_checks = {
2263
  "line": line_pct >= float(thresholds["line"]),
2264
+ "branch": branch_pct >= 95.0, # Industry Standard Coverage Closure
2265
  "toggle": toggle_pct >= float(thresholds["toggle"]),
2266
  "functional": functional_pct >= float(thresholds["functional"]),
2267
  }
 
2285
  self.log(
2286
  (
2287
  "Coverage PASSED "
2288
+ f"(line>={thresholds['line']:.1f}, branch>=95.0, "
2289
  f"toggle>={thresholds['toggle']:.1f}, functional>={thresholds['functional']:.1f})"
2290
  ),
2291
  refined=True,
 
2295
  elif self.skip_openlane:
2296
  self.transition(BuildState.SUCCESS)
2297
  else:
2298
+ self.transition(BuildState.SDC_GEN)
2299
  return
2300
 
2301
  self.retry_count += 1
2302
+ coverage_max_retries = min(self.max_retries, 5) # Increased for closure loop
2303
  if self.retry_count > coverage_max_retries:
2304
  if getattr(self, "best_tb_backup", None) and os.path.exists(self.best_tb_backup):
2305
  self.log(f"Restoring Best Testbench ({self.best_coverage:.1f}%) before proceeding.", refined=True)
 
2315
  elif self.skip_openlane:
2316
  self.transition(BuildState.SUCCESS)
2317
  else:
2318
+ self.transition(BuildState.SDC_GEN)
2319
  return
2320
 
2321
  self.log(
 
2330
  tb_agent = get_testbench_agent(self.llm, f"Improve coverage for {self.name}", verbose=self.verbose, strategy=self.strategy.name)
2331
 
2332
  improve_prompt = f"""The current testbench for "{self.name}" does not meet coverage thresholds.
2333
+ TARGET: Industry Standard >95.0% Branch Coverage.
2334
  Current Coverage Data: {coverage_data}
2335
 
2336
  Current RTL:
 
2344
  ```
2345
 
2346
  Create an IMPROVED self-checking testbench that:
2347
+ 1. Achieves >95% branch coverage by hitting all missing branches.
2348
+ 2. Tests all FSM states (not just happy path)
2349
+ 3. Exercises all conditional branches (if/else, case)
2350
  3. Tests reset behavior mid-operation
2351
  4. Tests boundary values (max/min inputs)
2352
  5. Includes back-to-back operations
 
2516
  if self.skip_openlane:
2517
  self.transition(BuildState.SUCCESS)
2518
  else:
2519
+ self.transition(BuildState.SDC_GEN)
2520
+
2521
+ def do_sdc_gen(self):
2522
+ """Generate Synthesis Design Constraints (.sdc) for OpenLane."""
2523
+ src_dir = f"{OPENLANE_ROOT}/designs/{self.name}/src"
2524
+ os.makedirs(src_dir, exist_ok=True)
2525
+ sdc_path = os.path.join(src_dir, f"{self.name}.sdc")
2526
+
2527
+ self.log("Generating SDC Timing Constraints...", refined=True)
2528
+ sdc_agent = get_sdc_agent(self.llm, "Generate Synthesis Design Constraints", self.verbose)
2529
+
2530
+ arch_spec = self.artifacts.get('spec', 'No spec generated.')
2531
+ sdc_task = Task(
2532
+ description=f"""Generate an SDC file for module '{self.name}'.
2533
+
2534
+ Architecture Specification:
2535
+ {arch_spec}
2536
+
2537
+ REQUIREMENTS:
2538
+ 1. Identify the clock port and requested frequency/period.
2539
+ 2. If unspecified, assume 100MHz (10.0ns period).
2540
+ 3. Output ONLY the raw SDC constraints. DO NOT output code blocks or markdown wrappers (no ```sdc).
2541
+ """,
2542
+ expected_output="Raw SDC constraints text cleanly formatted.",
2543
+ agent=sdc_agent
2544
+ )
2545
+
2546
+ with console.status("[bold cyan]Generating Timing Constraints (SDC)...[/bold cyan]"):
2547
+ sdc_content = str(Crew(agents=[sdc_agent], tasks=[sdc_task]).kickoff()).strip()
2548
+
2549
+ # Clean up potential markdown wrappers created by LLM anyway
2550
+ if sdc_content.startswith("```"):
2551
+ lines = sdc_content.split("\n")
2552
+ if len(lines) > 2:
2553
+ sdc_content = "\n".join(lines[1:-1])
2554
+
2555
+ with open(sdc_path, "w") as f:
2556
+ f.write(sdc_content)
2557
+
2558
+ self.artifacts["sdc_path"] = sdc_path
2559
+ self.log(f"SDC Constraints generated: {sdc_path}", refined=True)
2560
+
2561
+ self.transition(BuildState.FLOORPLAN)
2562
 
2563
  def do_floorplan(self):
2564
  """Generate floorplan artifacts and feed hardening with spatial intent."""
 
2671
  )
2672
 
2673
  floorplan_tcl = os.path.join(src_dir, f"{self.name}_floorplan.tcl")
2674
+ sdc_injection = f"set ::env(BASE_SDC_FILE) \"$::env(DESIGN_DIR)/src/{self.name}.sdc\"\n" if "sdc_path" in self.artifacts else ""
2675
+
2676
  with open(floorplan_tcl, "w") as f:
2677
  f.write(
2678
  f"set ::env(DESIGN_NAME) \"{self.name}\"\n"
2679
  f"set ::env(PDK) \"{self.pdk_profile.get('pdk', PDK)}\"\n"
2680
  f"set ::env(STD_CELL_LIBRARY) \"{self.pdk_profile.get('std_cell_library', 'sky130_fd_sc_hd')}\"\n"
2681
  f"set ::env(VERILOG_FILES) [glob $::env(DESIGN_DIR)/src/{self.name}.v]\n"
2682
+ f"{sdc_injection}"
2683
  "set ::env(FP_SIZING) \"absolute\"\n"
2684
  f"set ::env(DIE_AREA) \"0 0 {die} {die}\"\n"
2685
  f"set ::env(FP_CORE_UTIL) {util}\n"
src/agentic/tools/vlsi_tools.py CHANGED
@@ -8,6 +8,7 @@ from collections import Counter, defaultdict, deque
8
  from typing import Dict, Any, List, Tuple
9
  import shutil
10
  from crewai.tools import tool
 
11
  from ..config import (
12
  OPENLANE_ROOT,
13
  SCRIPTS_DIR,
@@ -249,7 +250,7 @@ def write_verilog(design_name: str, code: str, is_testbench: bool = False, suffi
249
  stripped = line.strip()
250
  if not stripped or stripped.startswith('`') or stripped.startswith('//'):
251
  filtered_lines.append(line)
252
- clean_code = '\n'.join(filtered_lines) + clean_code[module_pos:]
253
 
254
  # --- VALIDATION ---
255
  if "module" not in clean_code:
@@ -280,8 +281,38 @@ def write_verilog(design_name: str, code: str, is_testbench: bool = False, suffi
280
  if not clean_code.endswith("\n"):
281
  clean_code += "\n"
282
 
283
- with open(path, "w") as f:
284
- f.write(clean_code)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  return path
286
  except IOError as e:
287
  return f"Error: Failed to write Verilog file {path}: {str(e)}"
@@ -295,11 +326,18 @@ def run_syntax_check(file_path: str) -> tuple:
295
  return False, f"File not found: {file_path}"
296
 
297
  try:
 
 
 
 
 
 
 
298
  # --lint-only: check syntax and basic semantics
299
  # --sv: force SystemVerilog parsing
300
  # --timing: support delays
301
  # -Wno-fatal: don't crash on warnings (unless they are errors)
302
- cmd = ["verilator", "--lint-only", "--sv", "--timing", "-Wno-fatal", file_path]
303
 
304
  result = subprocess.run(
305
  cmd,
@@ -323,8 +361,14 @@ def run_lint_check(file_path: str) -> tuple:
323
  if not os.path.exists(file_path):
324
  return False, f"File not found: {file_path}"
325
 
 
 
 
 
 
 
326
  # Use --lint-only with sensible warnings (not -Wall, which flags unused signals as errors)
327
- cmd = ["verilator", "--lint-only", "-Wno-UNUSED", "-Wno-PINMISSING", "-Wno-CASEINCOMPLETE", "--timing", file_path]
328
 
329
  try:
330
  result = subprocess.run(
@@ -629,7 +673,7 @@ def convert_sva_to_yosys(sva_content: str, module_name: str) -> str:
629
  """
630
  port_match = re.search(r'module\s+\w+_sva\s*\((.*?)\);', sva_content, re.DOTALL)
631
  if not port_match:
632
- return None
633
 
634
  ports_section = port_match.group(1)
635
  port_lines = []
@@ -1239,6 +1283,9 @@ def run_simulation(design_name: str) -> tuple:
1239
  if not os.path.exists(tb_file):
1240
  return False, f"Testbench file not found: {tb_file}"
1241
 
 
 
 
1242
  # Compile & Build using Verilator --binary
1243
  # --binary: Build a binary executable
1244
  # -j 0: Use all cores
@@ -1252,7 +1299,7 @@ def run_simulation(design_name: str) -> tuple:
1252
  "--timing",
1253
  "--assert",
1254
  "-Wno-fatal", # Don't error out on warnings
1255
- rtl_file, tb_file,
1256
  "--top-module", f"{design_name}_tb",
1257
  "--Mdir", obj_dir,
1258
  "-o", "sim_exec"
@@ -1645,7 +1692,7 @@ def parse_congestion_metrics(design_name: str, run_tag: str = "agentrun") -> Dic
1645
  continue
1646
  overflow_triplet = m.group("overflow").split("/")
1647
  total_over = int(overflow_triplet[-1].strip())
1648
- result["layers"].append(
1649
  {
1650
  "layer": m.group("layer"),
1651
  "usage_pct": float(m.group("usage")),
@@ -1874,6 +1921,9 @@ def run_verilator_coverage(design_name: str, rtl_file: str, tb_file: str, covera
1874
  except OSError:
1875
  pass
1876
 
 
 
 
1877
  compile_cmd = [
1878
  "verilator",
1879
  "--binary",
@@ -1881,7 +1931,7 @@ def run_verilator_coverage(design_name: str, rtl_file: str, tb_file: str, covera
1881
  "--sv",
1882
  "--timing",
1883
  "-Wno-fatal",
1884
- rtl_file,
1885
  tb_file,
1886
  "--top-module",
1887
  f"{design_name}_tb",
@@ -1991,7 +2041,10 @@ def run_iverilog_coverage(design_name: str, rtl_file: str, tb_file: str, coverag
1991
  result["total_signals"] = len(signals)
1992
  signal_set = set(signals)
1993
 
1994
- compile_cmd = ["iverilog", "-g2012", "-o", sim_out, rtl_file, tb_file]
 
 
 
1995
  try:
1996
  comp = subprocess.run(compile_cmd, capture_output=True, text=True, timeout=120, cwd=src_dir)
1997
  except FileNotFoundError:
@@ -2281,8 +2334,8 @@ def parse_drc_lvs_reports(design_name: str) -> tuple:
2281
  if drc_files:
2282
  drc_path = _best_report_path(drc_files, "drc")
2283
  try:
2284
- with open(drc_path, 'r') as f:
2285
- drc_content = f.read()
2286
  details['drc_report'] = drc_content[:2000] # Truncate for readability
2287
 
2288
  # Count violations
@@ -2311,8 +2364,8 @@ def parse_drc_lvs_reports(design_name: str) -> tuple:
2311
  if lvs_files:
2312
  lvs_path = _best_report_path(lvs_files, ".lvs")
2313
  try:
2314
- with open(lvs_path, 'r') as f:
2315
- lvs_content = f.read()
2316
  details['lvs_report'] = lvs_content[:2000]
2317
 
2318
  # Prefer explicit numeric result when available.
@@ -2664,7 +2717,7 @@ def parse_sta_signoff(design_name: str) -> dict:
2664
  if worst_hold == float("inf"):
2665
  worst_hold = 0.0
2666
 
2667
- timing_met = all((c["setup_slack"] >= 0.0 and c["hold_slack"] >= 0.0) for c in corners)
2668
  top_paths = sorted(top_paths, key=lambda x: x.get("slack", 0.0))[:10]
2669
 
2670
  return {
@@ -2722,8 +2775,8 @@ def parse_power_signoff(design_name: str) -> dict:
2722
 
2723
  if power_report and os.path.exists(power_report):
2724
  result["power_report"] = power_report
2725
- with open(power_report, "r", errors="ignore") as f:
2726
- content = f.read()
2727
  total_match = re.search(r"Total\\s+([\\d.eE+\\-]+)\\s+([\\d.eE+\\-]+)\\s+([\\d.eE+\\-]+)\\s+([\\d.eE+\\-]+)", content)
2728
  if total_match:
2729
  result["internal_power_w"] = float(total_match.group(1))
@@ -2771,7 +2824,7 @@ def parse_power_signoff(design_name: str) -> dict:
2771
  result["irdrop_max_vgnd"] = _parse_irdrop(vgnd_path)
2772
 
2773
  # 5% of 1.8V ~= 90mV
2774
- result["power_ok"] = result["irdrop_max_vpwr"] <= 0.09 and result["irdrop_max_vgnd"] <= 0.09
2775
  return result
2776
  except Exception:
2777
  return result
 
8
  from typing import Dict, Any, List, Tuple
9
  import shutil
10
  from crewai.tools import tool
11
+ from typing import cast
12
  from ..config import (
13
  OPENLANE_ROOT,
14
  SCRIPTS_DIR,
 
250
  stripped = line.strip()
251
  if not stripped or stripped.startswith('`') or stripped.startswith('//'):
252
  filtered_lines.append(line)
253
+ clean_code = '\n'.join(filtered_lines) + '\n' + clean_code[module_pos:]
254
 
255
  # --- VALIDATION ---
256
  if "module" not in clean_code:
 
281
  if not clean_code.endswith("\n"):
282
  clean_code += "\n"
283
 
284
+ # --- MULTI-FILE RTL HIERARCHY SPLITTING ---
285
+ if not is_testbench and "module" in clean_code:
286
+ import glob
287
+ # Remove old RTL files to prevent stale modules from breaking build
288
+ src_dir = os.path.dirname(path)
289
+ for old_rt in glob.glob(os.path.join(src_dir, "*.v")):
290
+ if not old_rt.endswith("_tb.v") and "regression" not in old_rt:
291
+ try:
292
+ os.remove(old_rt)
293
+ except OSError:
294
+ pass
295
+
296
+ # Find all modules
297
+ modules = re.findall(r'(module\s+([a-zA-Z0-9_]+).*?endmodule)', clean_code, re.DOTALL)
298
+ if len(modules) > 1:
299
+ # If multiple modules exist, write them to separate files
300
+ for mod_code, mod_name in modules:
301
+ mod_path = os.path.join(src_dir, f"{mod_name}.v")
302
+ with open(mod_path, "w") as f:
303
+ f.write(mod_code + "\n")
304
+
305
+ # Make sure the requested path exists so syntax check doesn't fail
306
+ if not os.path.exists(path):
307
+ with open(path, "w") as f:
308
+ f.write(f"// Main module {design_name} likely defined in other files\n")
309
+ else:
310
+ with open(path, "w") as f:
311
+ f.write(clean_code)
312
+ else:
313
+ with open(path, "w") as f:
314
+ f.write(clean_code)
315
+
316
  return path
317
  except IOError as e:
318
  return f"Error: Failed to write Verilog file {path}: {str(e)}"
 
326
  return False, f"File not found: {file_path}"
327
 
328
  try:
329
+ # Gather all RTL files to support multi-file compilation
330
+ import glob
331
+ src_dir = os.path.dirname(file_path)
332
+ rtl_files = [f for f in glob.glob(os.path.join(src_dir, "*.v")) if not f.endswith("_tb.v") and "regression" not in f]
333
+ if file_path not in rtl_files and os.path.exists(file_path):
334
+ rtl_files.append(file_path)
335
+
336
  # --lint-only: check syntax and basic semantics
337
  # --sv: force SystemVerilog parsing
338
  # --timing: support delays
339
  # -Wno-fatal: don't crash on warnings (unless they are errors)
340
+ cmd = ["verilator", "--lint-only", "--sv", "--timing", "-Wno-fatal"] + rtl_files
341
 
342
  result = subprocess.run(
343
  cmd,
 
361
  if not os.path.exists(file_path):
362
  return False, f"File not found: {file_path}"
363
 
364
+ import glob
365
+ src_dir = os.path.dirname(file_path)
366
+ rtl_files = [f for f in glob.glob(os.path.join(src_dir, "*.v")) if not f.endswith("_tb.v") and "regression" not in f]
367
+ if file_path not in rtl_files and os.path.exists(file_path):
368
+ rtl_files.append(file_path)
369
+
370
  # Use --lint-only with sensible warnings (not -Wall, which flags unused signals as errors)
371
+ cmd = ["verilator", "--lint-only", "-Wno-UNUSED", "-Wno-PINMISSING", "-Wno-CASEINCOMPLETE", "--timing"] + rtl_files
372
 
373
  try:
374
  result = subprocess.run(
 
673
  """
674
  port_match = re.search(r'module\s+\w+_sva\s*\((.*?)\);', sva_content, re.DOTALL)
675
  if not port_match:
676
+ return ""
677
 
678
  ports_section = port_match.group(1)
679
  port_lines = []
 
1283
  if not os.path.exists(tb_file):
1284
  return False, f"Testbench file not found: {tb_file}"
1285
 
1286
+ import glob
1287
+ rtl_files = [f for f in glob.glob(os.path.join(src_dir, "*.v")) if not f.endswith("_tb.v") and "regression" not in f]
1288
+
1289
  # Compile & Build using Verilator --binary
1290
  # --binary: Build a binary executable
1291
  # -j 0: Use all cores
 
1299
  "--timing",
1300
  "--assert",
1301
  "-Wno-fatal", # Don't error out on warnings
1302
+ *rtl_files, tb_file,
1303
  "--top-module", f"{design_name}_tb",
1304
  "--Mdir", obj_dir,
1305
  "-o", "sim_exec"
 
1692
  continue
1693
  overflow_triplet = m.group("overflow").split("/")
1694
  total_over = int(overflow_triplet[-1].strip())
1695
+ cast(list, result["layers"]).append(
1696
  {
1697
  "layer": m.group("layer"),
1698
  "usage_pct": float(m.group("usage")),
 
1921
  except OSError:
1922
  pass
1923
 
1924
+ import glob
1925
+ rtl_files = [f for f in glob.glob(os.path.join(src_dir, "*.v")) if not f.endswith("_tb.v") and "regression" not in f]
1926
+
1927
  compile_cmd = [
1928
  "verilator",
1929
  "--binary",
 
1931
  "--sv",
1932
  "--timing",
1933
  "-Wno-fatal",
1934
+ *rtl_files,
1935
  tb_file,
1936
  "--top-module",
1937
  f"{design_name}_tb",
 
2041
  result["total_signals"] = len(signals)
2042
  signal_set = set(signals)
2043
 
2044
+ import glob
2045
+ rtl_files = [f for f in glob.glob(os.path.join(src_dir, "*.v")) if not f.endswith("_tb.v") and "regression" not in f]
2046
+
2047
+ compile_cmd = ["iverilog", "-g2012", "-o", sim_out, *rtl_files, tb_file]
2048
  try:
2049
  comp = subprocess.run(compile_cmd, capture_output=True, text=True, timeout=120, cwd=src_dir)
2050
  except FileNotFoundError:
 
2334
  if drc_files:
2335
  drc_path = _best_report_path(drc_files, "drc")
2336
  try:
2337
+ with open(drc_path, 'r') as f_rpt:
2338
+ drc_content = f_rpt.read()
2339
  details['drc_report'] = drc_content[:2000] # Truncate for readability
2340
 
2341
  # Count violations
 
2364
  if lvs_files:
2365
  lvs_path = _best_report_path(lvs_files, ".lvs")
2366
  try:
2367
+ with open(lvs_path, 'r') as f_rpt:
2368
+ lvs_content = f_rpt.read()
2369
  details['lvs_report'] = lvs_content[:2000]
2370
 
2371
  # Prefer explicit numeric result when available.
 
2717
  if worst_hold == float("inf"):
2718
  worst_hold = 0.0
2719
 
2720
+ timing_met = all((float(c["setup_slack"]) >= 0.0 and float(c["hold_slack"]) >= 0.0) for c in corners) # type: ignore
2721
  top_paths = sorted(top_paths, key=lambda x: x.get("slack", 0.0))[:10]
2722
 
2723
  return {
 
2775
 
2776
  if power_report and os.path.exists(power_report):
2777
  result["power_report"] = power_report
2778
+ with open(power_report, "r", errors="ignore") as f_rpt:
2779
+ content = f_rpt.read()
2780
  total_match = re.search(r"Total\\s+([\\d.eE+\\-]+)\\s+([\\d.eE+\\-]+)\\s+([\\d.eE+\\-]+)\\s+([\\d.eE+\\-]+)", content)
2781
  if total_match:
2782
  result["internal_power_w"] = float(total_match.group(1))
 
2824
  result["irdrop_max_vgnd"] = _parse_irdrop(vgnd_path)
2825
 
2826
  # 5% of 1.8V ~= 90mV
2827
+ result["power_ok"] = float(result["irdrop_max_vpwr"]) <= 0.09 and float(result["irdrop_max_vgnd"]) <= 0.09 # type: ignore
2828
  return result
2829
  except Exception:
2830
  return result
training/agentic_sft_data.jsonl CHANGED
@@ -75,3 +75,6 @@
75
  {"job_id": "36e08ecb-87b9-41a6-8599-c8ba38188712", "timestamp": 1772030529, "design_name": "8bit_risc_cpu_with", "instruction": "Design a digital chip: 8-bit RISC CPU with Harvard architecture", "input": "\n# 8‑bit RISC CPU – Micro‑Architecture Specification (MAS)\n\n> **Doc.** : 8‑bit_risc_cpu_with – Harvard‑architecture, single‑issue, 2‑stage pipeline \n> **Author** : Chief System Architect – *Your Name* \n> **Date** : 2025‑11‑02 \n> **Version** : 1.0 \n\n--- \n\n## 1. I/O Interface \n\n| Port | Width | Direction | Description | Timing / Control | Reset State |\n|------|-------|-----------|-------------|------------------|--------------|\n| `clk` | 1 | Input | System clock – positive‑edge triggered. | – | Idle (no action) |\n| `rst_n` | 1 | Input | Active‑low asynchronous reset. | – | All registers forced to `0`; PC = `0x00` |\n| `enable` | 1 | Input | Chip‑enable; when `0` the core is put in *sleep* (no state change). | – | Same as reset when disabled |\n| `addr` | 16 | Output | Address bus to **Instruction Memory** (Harvard separate I‑space). | – | Output the current PC value |\n| `data_in` | 8 | Input | Data bus from **Data Memory** (load/store operand). | – | – |\n| `data_out` | 8 | Output | Data bus to **Data Memory** (write operand). | – | – |\n| `we_mem` | 1 | Output | Memory‑Write Enable – asserted when a store instruction is in the MEM stage. | – | `0` (idle) |\n| `re_mem` | 1 | Output | Memory‑Read Enable – asserted when a load instruction is in the MEM stage. | – | `0` (idle) |\n| `irq` | 1 | Input | External interrupt request (level‑triggered). | – | De‑asserted |\n| `irq_ack` | 1 | Output | Interrupt‑acknowledge pulse (generated in the WRITE‑BACK stage). | – | `0` |\n| `ready` | 1 | Output | Indicates the core is ready for a new instruction fetch (pipeline flush not in progress). | – | `1` after reset release |\n\n### Timing Assumptions \n\n* All control signals are **registered** (registered on the rising edge of `clk`). \n* Memory accesses complete **within the same clock cycle** (single‑cycle read/write). \n* Interrupt latency = 1 cycle (acknowledge asserted one cycle after `irq` is seen and pipeline is not stalled). \n\n--- \n\n## 2. Internal Registers & FSM States \n\n#", "output": "module eightbit_risc_cpu_with #(\n parameter ADDR_WIDTH = 16,\n parameter DATA_WIDTH = 8,\n parameter INSTR_DEPTH = 16\n) (\n input logic clk,\n input logic rst_n, // asynchronous active‑low reset\n input logic enable, // chip enable (0 = sleep)\n\n // Instruction address output (to Instruction Memory)\n output logic [ADDR_WIDTH-1:0] addr,\n\n // Data interface to Data Memory\n input logic [DATA_WIDTH-1:0] data_in, // data from Data Memory\n output logic [DATA_WIDTH-1:0] data_out, // data to Data Memory\n output logic we_mem, // memory write enable\n output logic re_mem, // memory read enable\n\n // Interrupt interface\n input logic irq, // external interrupt request (level)\n output logic irq_ack, // interrupt acknowledge pulse\n output logic ready // core ready for new fetch\n);\n\n // -----------------------------------------------------------\n // I/O Policy – No shadowing of ports\n // -----------------------------------------------------------\n // Internal signals – all declared with `logic` (SystemVerilog)\n // -----------------------------------------------------------\n\n // Index width for ROM access\n localparam IDX_W = $clog2(INSTR_DEPTH);\n\n // FSM definition (3‑bit encoding – matches state count)\n typedef enum logic [2:0] {\n S_IDLE = 3'd0,", "success": false, "strategy": "SystemVerilog Modular (Modern)", "metrics": {}, "coverage": {}, "build_log_excerpt": "[INIT] Starting Build Process for '8bit_risc_cpu_with' using SystemVerilog Modular (Modern)\n[INIT] Logging initialized to /home/vickynishad/OpenLane/designs/8bit_risc_cpu_with/8bit_risc_cpu_with.log\n[INIT] PDK profile: sky130 (PDK=sky130A, LIB=sky130_fd_sc_hd)\n[INIT] Transitioning: INIT -> SPEC\n[SPEC] Architecture Plan Generated\n[SPEC] Transitioning: SPEC -> RTL_GEN\n[RTL_GEN] No golden template match. Generating from scratch.\n[RTL_GEN] Hierarchical synthesis planner: disabled.\n[RTL_GEN] Transitioning: RTL_GEN -> RTL_FIX\n[RTL_FIX] Fixing Code (Attempt 1/5)\n[RTL_FIX] Fixing Code (Attempt 2/5)\n[RTL_FIX] Syntax Check Passed (Verilator)\n[RTL_FIX] Lint Check Passed (Verilator)\n[RTL_FIX] Pre-synthesis auto-fix applied.\n[RTL_FIX] Syntax Check Passed (Verilator)\n[RTL_FIX] Lint Check Passed (Verilator)\n[RTL_FIX] Semantic rigor gate failed. Routing back to RTL fix.\n[RTL_FIX] Fixing Code (Attempt 3/5)\n[RTL_FIX] Syntax Check Passed (Verilator)\n[RTL_FIX] Lint Check Passed (Verilator)\n[RTL_FIX] Transitioning: RTL_FIX -> VERIFICATION\n[VERIFICATION] Generating Testbench...\n[VERIFICATION] TB generation stalled/failed (signal only works in main thread of the main interpreter). Using deterministic fallback TB.\n[VERIFICATION] TB static gate: PASS (diag: 8bit_risc_cpu_with_tb_static_gate_attempt1.json)\n[VERIFICATION] TB compile gate: FAIL (diag: 8bit_risc_cpu_with_tb_compile_gate_attempt1.json)\n[VERIFICATION] Verifying with existing Testbench (Attempt 0).\n[VERIFICATION] TB static gate: FAIL (diag: 8bit_risc_cpu_with_tb_static_gate_attempt2.json)\n[VERIFICATION] TB gate failed; applied deterministic auto-repair.\n[VERIFICATION] Verifying with existing Testbench (Attempt 0).\n[VERIFICATION] TB static gate: FAIL (diag: 8bit_risc_cpu_with_tb_static_gate_attempt3.json)\n[VERIFICATION] TB gate failed; forcing LLM TB regeneration with structured diagnostics.\n[VERIFICATION] Generating Testbench...\n[VERIFICATION] TB generation stalled/failed (signal only works in main thread of the main interpreter). Using deterministic fallback TB.\n[VERIFICATION] TB static gate: PASS (diag: 8bit_risc_cpu_with_tb_static_gate_attempt4.json)\n[VERIFICATION] TB compile gate: FAIL (diag: 8bit_risc_cpu_with_tb_compile_gate_attempt2.json)\n[VERIFICATION] Repeated TB compile fingerprint detected. Failing closed.", "source": "agentic_web_build"}
76
  {"job_id": "05223be4-69db-4e20-85c3-07c4038f0b42", "timestamp": 1772031476, "design_name": "axi4_dma_engine_with", "instruction": "Design a digital chip: AXI4 DMA engine with 4 channels", "input": "\n# **## Module: axi4_dma_engine_with**\n\nThe RTL entity that implements a **four‑channel AXI‑4 master‑side DMA engine**. The top‑level module name **must** be `axi4_dma_engine_with`. All ports, parameters, and internal blocks are defined to support a production‑ready AXI‑4 compliant DMA engine suitable for integration into an SoC.\n\n---\n\n# **## Chip Family** \n**AXI** – The device belongs to the AXI‑4 interconnect family (AXI4‑Stream/AXI4‑Lite/AXI4‑Full). It provides a high‑performance memory transfer subsystem by bridging the AXI master interface to internal descriptor‑based channels.\n\n---\n\n# **## Port List**\n\n| Port | Direction | Bits | Name | Purpose |\n|------|-----------|------|------|---------|\n| `clk` | Input | 1 | Clock | System clock for all logic (positive‑edge triggered). |\n| `rst_n` | Input | 1 | Asynchronous active‑low reset | Global reset; clears all state machines, registers, and FIFO pointers. |\n| **AXI‑Master Interface** |\n| `awaddr` | Output | `ADDR_WIDTH` | Address Write Channel address |\n| `awvalid` | Output | 1 | Write address valid |\n| `awready` | Input | 1 | Write address ready |\n| `wdata` | Output | `DATA_WIDTH` | Write data payload |\n| `wstrb` | Output | `DATA_WIDTH/8` | Byte lane strobes |\n| `wvalid` | Output | 1 | Write data valid |\n| `wready` | Input | 1 | Write data ready |\n| `bresp` | Output | 2 | Write response (OKAY, SLVERR, etc.) |\n| `bvalid` | Output | 1 | Write response valid |\n| `bready` | Input | 1 | Write response ready |\n| `araddr` | Output | `ADDR_WIDTH` | Read address channel address |\n| `arvalid` | Output | 1 | Read address valid |\n| `arready` | Input | 1 | Read address ready |\n| `rdata` | Input | `DATA_WIDTH` | Read data returned |\n| `rresp` | Input | 2 | Read response |\n| `rvalid` | Input | 1 | Read data valid |\n| `rready` | Output | 1 | Read data ready |\n| **DMA Control & Status** |\n| `ch0_cfg` | Input | `CH_CFG_BITS` | Channel‑0 configuration (enable, direction, burst, etc.) |\n| `ch1_cfg` | Input | `CH_CFG_BITS` | Channel‑1", "output": "module axi4_dma_engine_with #(\n // -----------------------------------------------------------------\n // Parameters (all have default values as specified in the spec)\n // -----------------------------------------------------------------\n parameter int DATA_WIDTH = 32; // AXI data bus width\n parameter int ADDR_WIDTH = 32; // AXI address bus width\n parameter int NUM_CH = 4; // Number of DMA channels\n parameter int CH_CFG_BITS = 8; // Config register width per channel\n parameter int DESC_BITS = 16; // Width of descriptor address pointer\n parameter int DESC_COUNT_MAX = 1024; // Max descriptors per channel\n parameter int FIFO_DEPTH = 8; // Depth of per‑channel descriptor FIFO\n parameter string RESET_STYLE = \"SYNC\"; // \"SYNC\" or \"ASYNC\"\n parameter string INTERFACE_STYLE = \"AXI4_FULL\"; // Enforces full handshake\n parameter logic SUPPORTS_BURST = 1'b1; // Enable burst transfers\n parameter int MAX_BURST_LEN = 16; // Max beats per burst\n parameter string ERROR_POLICY = \"HALT_AND_REPORT\" // Error handling policy\n)(\n // -----------------------------------------------------------------\n // Clock and asynchronous active‑low reset\n // -----------------------------------------------------------------\n input logic clk,\n input logic ", "success": false, "strategy": "SystemVerilog Modular (Modern)", "metrics": {}, "coverage": {}, "build_log_excerpt": "[INIT] Starting Build Process for 'axi4_dma_engine_with' using SystemVerilog Modular (Modern)\n[INIT] Logging initialized to /home/vickynishad/OpenLane/designs/axi4_dma_engine_with/axi4_dma_engine_with.log\n[INIT] PDK profile: sky130 (PDK=sky130A, LIB=sky130_fd_sc_hd)\n[INIT] Transitioning: INIT -> SPEC\n[SPEC] Architecture Plan Generated\n[SPEC] Transitioning: SPEC -> RTL_GEN\n[RTL_GEN] No golden template match. Generating from scratch.\n[RTL_GEN] Hierarchical synthesis planner: disabled.\n[RTL_GEN] Transitioning: RTL_GEN -> RTL_FIX\n[RTL_FIX] Fixing Code (Attempt 1/5)\n[RTL_FIX] File Write Error in FIX stage: Error: No Verilog 'module' definition found in the provided code. Please ensure you output the full Verilog code inside ```verilog``` fences.\n[RTL_FIX] Retrying fix (LLM output was unparsable).\n[RTL_FIX] Detected repeated syntax/lint failure fingerprint. Failing closed.", "source": "agentic_web_build"}
77
  {"job_id": "aefbc11b-69f4-4d60-842d-6691200babda", "timestamp": 1772031756, "design_name": "uart_controller_at_115200", "instruction": "Design a digital chip: UART controller at 115200 baud", "input": "\n## Module: uart_controller_at_115200 \n\n## Chip Family \n**UART** – a classic serial‑communication peripheral that implements a full‑featured asynchronous transmitter and receiver operating at a fixed 115 200 baud rate. \n\n--- \n\n## Port List \n\n| Direction | Bit‑Width | Signal Name | Purpose |\n|-----------|----------|-------------|------------------------------------------------|\n| Input | 1 | `clk` | System clock (positive‑edge triggered). |\n| Input | 1 | `rst_n` | Asynchronous active‑low reset. |\n| Input | 1 | `tx_load` | Pulse to load new data onto the transmitter. |\n| Input | 8 | `tx_data` | Data byte to be transmitted. |\n| Input | 1 | `rx_valid` | (unused on the input side – kept as a reserved input for future extensions.) |\n| Output | 1 | `txd` | UART transmit line (idles high). |\n| Output | 1 | `rxd` | UART receive line (sampled on positive edges). |\n| Output | 1 | `tx_done` | Pulses high for one clock cycle when the transmitter finishes a frame. |\n| Output | 1 | `rx_error` | Flags overrun/parity/framing error on receive. |\n| Output | 8 | `rx_data` | Received data byte (valid when `rx_valid` is high). |\n\nAll ports are one‑bit wide except where noted; each signal name follows the exact spelling shown above. \n\n--- \n\n## Parameters \n\n| Parameter | Type | Default Value | Meaning / Usage |\n|-----------|------|---------------|-----------------|\n| `DATA_WIDTH` | `int` | `8` | Width of the data bus used for TX and RX payloads. |\n| `SYSTEM_CLK_FREQ` | `int` | `30_000_000` | Frequency of `clk` in Hz. Chosen to enable an exact integer divider for 115 200 baud when `OVERSAMPLE = 16`. |\n| `BAUD_RATE` | `int` | `115200` | Target baud rate (fixed for this instance). |\n| `OVERSAMPLE` | `int` | `16` | Number of samples per bit; standard for UART‑v2. |\n| `DIVIDER_WIDTH` | `int` | `8` | Width of the baud‑rate divider counter. |\n| `FIFO_DEP", "output": "", "success": false, "strategy": "SystemVerilog Modular (Modern)", "metrics": {}, "coverage": {}, "build_log_excerpt": "[INIT] Starting Build Process for 'uart_controller_at_115200' using SystemVerilog Modular (Modern)\n[INIT] Logging initialized to /home/vickynishad/OpenLane/designs/uart_controller_at_115200/uart_controller_at_115200.log\n[INIT] PDK profile: sky130 (PDK=sky130A, LIB=sky130_fd_sc_hd)\n[INIT] Transitioning: INIT -> SPEC\n[SPEC] Architecture Plan Generated\n[SPEC] Transitioning: SPEC -> RTL_GEN\n[RTL_GEN] No golden template match. Generating from scratch.\n[RTL_GEN] File Write Error: Error: No Verilog 'module' definition found in the provided code. Please ensure you output the full Verilog code inside ```verilog``` fences.", "source": "agentic_web_build"}
 
 
 
 
75
  {"job_id": "36e08ecb-87b9-41a6-8599-c8ba38188712", "timestamp": 1772030529, "design_name": "8bit_risc_cpu_with", "instruction": "Design a digital chip: 8-bit RISC CPU with Harvard architecture", "input": "\n# 8‑bit RISC CPU – Micro‑Architecture Specification (MAS)\n\n> **Doc.** : 8‑bit_risc_cpu_with – Harvard‑architecture, single‑issue, 2‑stage pipeline \n> **Author** : Chief System Architect – *Your Name* \n> **Date** : 2025‑11‑02 \n> **Version** : 1.0 \n\n--- \n\n## 1. I/O Interface \n\n| Port | Width | Direction | Description | Timing / Control | Reset State |\n|------|-------|-----------|-------------|------------------|--------------|\n| `clk` | 1 | Input | System clock – positive‑edge triggered. | – | Idle (no action) |\n| `rst_n` | 1 | Input | Active‑low asynchronous reset. | – | All registers forced to `0`; PC = `0x00` |\n| `enable` | 1 | Input | Chip‑enable; when `0` the core is put in *sleep* (no state change). | – | Same as reset when disabled |\n| `addr` | 16 | Output | Address bus to **Instruction Memory** (Harvard separate I‑space). | – | Output the current PC value |\n| `data_in` | 8 | Input | Data bus from **Data Memory** (load/store operand). | – | – |\n| `data_out` | 8 | Output | Data bus to **Data Memory** (write operand). | – | – |\n| `we_mem` | 1 | Output | Memory‑Write Enable – asserted when a store instruction is in the MEM stage. | – | `0` (idle) |\n| `re_mem` | 1 | Output | Memory‑Read Enable – asserted when a load instruction is in the MEM stage. | – | `0` (idle) |\n| `irq` | 1 | Input | External interrupt request (level‑triggered). | – | De‑asserted |\n| `irq_ack` | 1 | Output | Interrupt‑acknowledge pulse (generated in the WRITE‑BACK stage). | – | `0` |\n| `ready` | 1 | Output | Indicates the core is ready for a new instruction fetch (pipeline flush not in progress). | – | `1` after reset release |\n\n### Timing Assumptions \n\n* All control signals are **registered** (registered on the rising edge of `clk`). \n* Memory accesses complete **within the same clock cycle** (single‑cycle read/write). \n* Interrupt latency = 1 cycle (acknowledge asserted one cycle after `irq` is seen and pipeline is not stalled). \n\n--- \n\n## 2. Internal Registers & FSM States \n\n#", "output": "module eightbit_risc_cpu_with #(\n parameter ADDR_WIDTH = 16,\n parameter DATA_WIDTH = 8,\n parameter INSTR_DEPTH = 16\n) (\n input logic clk,\n input logic rst_n, // asynchronous active‑low reset\n input logic enable, // chip enable (0 = sleep)\n\n // Instruction address output (to Instruction Memory)\n output logic [ADDR_WIDTH-1:0] addr,\n\n // Data interface to Data Memory\n input logic [DATA_WIDTH-1:0] data_in, // data from Data Memory\n output logic [DATA_WIDTH-1:0] data_out, // data to Data Memory\n output logic we_mem, // memory write enable\n output logic re_mem, // memory read enable\n\n // Interrupt interface\n input logic irq, // external interrupt request (level)\n output logic irq_ack, // interrupt acknowledge pulse\n output logic ready // core ready for new fetch\n);\n\n // -----------------------------------------------------------\n // I/O Policy – No shadowing of ports\n // -----------------------------------------------------------\n // Internal signals – all declared with `logic` (SystemVerilog)\n // -----------------------------------------------------------\n\n // Index width for ROM access\n localparam IDX_W = $clog2(INSTR_DEPTH);\n\n // FSM definition (3‑bit encoding – matches state count)\n typedef enum logic [2:0] {\n S_IDLE = 3'd0,", "success": false, "strategy": "SystemVerilog Modular (Modern)", "metrics": {}, "coverage": {}, "build_log_excerpt": "[INIT] Starting Build Process for '8bit_risc_cpu_with' using SystemVerilog Modular (Modern)\n[INIT] Logging initialized to /home/vickynishad/OpenLane/designs/8bit_risc_cpu_with/8bit_risc_cpu_with.log\n[INIT] PDK profile: sky130 (PDK=sky130A, LIB=sky130_fd_sc_hd)\n[INIT] Transitioning: INIT -> SPEC\n[SPEC] Architecture Plan Generated\n[SPEC] Transitioning: SPEC -> RTL_GEN\n[RTL_GEN] No golden template match. Generating from scratch.\n[RTL_GEN] Hierarchical synthesis planner: disabled.\n[RTL_GEN] Transitioning: RTL_GEN -> RTL_FIX\n[RTL_FIX] Fixing Code (Attempt 1/5)\n[RTL_FIX] Fixing Code (Attempt 2/5)\n[RTL_FIX] Syntax Check Passed (Verilator)\n[RTL_FIX] Lint Check Passed (Verilator)\n[RTL_FIX] Pre-synthesis auto-fix applied.\n[RTL_FIX] Syntax Check Passed (Verilator)\n[RTL_FIX] Lint Check Passed (Verilator)\n[RTL_FIX] Semantic rigor gate failed. Routing back to RTL fix.\n[RTL_FIX] Fixing Code (Attempt 3/5)\n[RTL_FIX] Syntax Check Passed (Verilator)\n[RTL_FIX] Lint Check Passed (Verilator)\n[RTL_FIX] Transitioning: RTL_FIX -> VERIFICATION\n[VERIFICATION] Generating Testbench...\n[VERIFICATION] TB generation stalled/failed (signal only works in main thread of the main interpreter). Using deterministic fallback TB.\n[VERIFICATION] TB static gate: PASS (diag: 8bit_risc_cpu_with_tb_static_gate_attempt1.json)\n[VERIFICATION] TB compile gate: FAIL (diag: 8bit_risc_cpu_with_tb_compile_gate_attempt1.json)\n[VERIFICATION] Verifying with existing Testbench (Attempt 0).\n[VERIFICATION] TB static gate: FAIL (diag: 8bit_risc_cpu_with_tb_static_gate_attempt2.json)\n[VERIFICATION] TB gate failed; applied deterministic auto-repair.\n[VERIFICATION] Verifying with existing Testbench (Attempt 0).\n[VERIFICATION] TB static gate: FAIL (diag: 8bit_risc_cpu_with_tb_static_gate_attempt3.json)\n[VERIFICATION] TB gate failed; forcing LLM TB regeneration with structured diagnostics.\n[VERIFICATION] Generating Testbench...\n[VERIFICATION] TB generation stalled/failed (signal only works in main thread of the main interpreter). Using deterministic fallback TB.\n[VERIFICATION] TB static gate: PASS (diag: 8bit_risc_cpu_with_tb_static_gate_attempt4.json)\n[VERIFICATION] TB compile gate: FAIL (diag: 8bit_risc_cpu_with_tb_compile_gate_attempt2.json)\n[VERIFICATION] Repeated TB compile fingerprint detected. Failing closed.", "source": "agentic_web_build"}
76
  {"job_id": "05223be4-69db-4e20-85c3-07c4038f0b42", "timestamp": 1772031476, "design_name": "axi4_dma_engine_with", "instruction": "Design a digital chip: AXI4 DMA engine with 4 channels", "input": "\n# **## Module: axi4_dma_engine_with**\n\nThe RTL entity that implements a **four‑channel AXI‑4 master‑side DMA engine**. The top‑level module name **must** be `axi4_dma_engine_with`. All ports, parameters, and internal blocks are defined to support a production‑ready AXI‑4 compliant DMA engine suitable for integration into an SoC.\n\n---\n\n# **## Chip Family** \n**AXI** – The device belongs to the AXI‑4 interconnect family (AXI4‑Stream/AXI4‑Lite/AXI4‑Full). It provides a high‑performance memory transfer subsystem by bridging the AXI master interface to internal descriptor‑based channels.\n\n---\n\n# **## Port List**\n\n| Port | Direction | Bits | Name | Purpose |\n|------|-----------|------|------|---------|\n| `clk` | Input | 1 | Clock | System clock for all logic (positive‑edge triggered). |\n| `rst_n` | Input | 1 | Asynchronous active‑low reset | Global reset; clears all state machines, registers, and FIFO pointers. |\n| **AXI‑Master Interface** |\n| `awaddr` | Output | `ADDR_WIDTH` | Address Write Channel address |\n| `awvalid` | Output | 1 | Write address valid |\n| `awready` | Input | 1 | Write address ready |\n| `wdata` | Output | `DATA_WIDTH` | Write data payload |\n| `wstrb` | Output | `DATA_WIDTH/8` | Byte lane strobes |\n| `wvalid` | Output | 1 | Write data valid |\n| `wready` | Input | 1 | Write data ready |\n| `bresp` | Output | 2 | Write response (OKAY, SLVERR, etc.) |\n| `bvalid` | Output | 1 | Write response valid |\n| `bready` | Input | 1 | Write response ready |\n| `araddr` | Output | `ADDR_WIDTH` | Read address channel address |\n| `arvalid` | Output | 1 | Read address valid |\n| `arready` | Input | 1 | Read address ready |\n| `rdata` | Input | `DATA_WIDTH` | Read data returned |\n| `rresp` | Input | 2 | Read response |\n| `rvalid` | Input | 1 | Read data valid |\n| `rready` | Output | 1 | Read data ready |\n| **DMA Control & Status** |\n| `ch0_cfg` | Input | `CH_CFG_BITS` | Channel‑0 configuration (enable, direction, burst, etc.) |\n| `ch1_cfg` | Input | `CH_CFG_BITS` | Channel‑1", "output": "module axi4_dma_engine_with #(\n // -----------------------------------------------------------------\n // Parameters (all have default values as specified in the spec)\n // -----------------------------------------------------------------\n parameter int DATA_WIDTH = 32; // AXI data bus width\n parameter int ADDR_WIDTH = 32; // AXI address bus width\n parameter int NUM_CH = 4; // Number of DMA channels\n parameter int CH_CFG_BITS = 8; // Config register width per channel\n parameter int DESC_BITS = 16; // Width of descriptor address pointer\n parameter int DESC_COUNT_MAX = 1024; // Max descriptors per channel\n parameter int FIFO_DEPTH = 8; // Depth of per‑channel descriptor FIFO\n parameter string RESET_STYLE = \"SYNC\"; // \"SYNC\" or \"ASYNC\"\n parameter string INTERFACE_STYLE = \"AXI4_FULL\"; // Enforces full handshake\n parameter logic SUPPORTS_BURST = 1'b1; // Enable burst transfers\n parameter int MAX_BURST_LEN = 16; // Max beats per burst\n parameter string ERROR_POLICY = \"HALT_AND_REPORT\" // Error handling policy\n)(\n // -----------------------------------------------------------------\n // Clock and asynchronous active‑low reset\n // -----------------------------------------------------------------\n input logic clk,\n input logic ", "success": false, "strategy": "SystemVerilog Modular (Modern)", "metrics": {}, "coverage": {}, "build_log_excerpt": "[INIT] Starting Build Process for 'axi4_dma_engine_with' using SystemVerilog Modular (Modern)\n[INIT] Logging initialized to /home/vickynishad/OpenLane/designs/axi4_dma_engine_with/axi4_dma_engine_with.log\n[INIT] PDK profile: sky130 (PDK=sky130A, LIB=sky130_fd_sc_hd)\n[INIT] Transitioning: INIT -> SPEC\n[SPEC] Architecture Plan Generated\n[SPEC] Transitioning: SPEC -> RTL_GEN\n[RTL_GEN] No golden template match. Generating from scratch.\n[RTL_GEN] Hierarchical synthesis planner: disabled.\n[RTL_GEN] Transitioning: RTL_GEN -> RTL_FIX\n[RTL_FIX] Fixing Code (Attempt 1/5)\n[RTL_FIX] File Write Error in FIX stage: Error: No Verilog 'module' definition found in the provided code. Please ensure you output the full Verilog code inside ```verilog``` fences.\n[RTL_FIX] Retrying fix (LLM output was unparsable).\n[RTL_FIX] Detected repeated syntax/lint failure fingerprint. Failing closed.", "source": "agentic_web_build"}
77
  {"job_id": "aefbc11b-69f4-4d60-842d-6691200babda", "timestamp": 1772031756, "design_name": "uart_controller_at_115200", "instruction": "Design a digital chip: UART controller at 115200 baud", "input": "\n## Module: uart_controller_at_115200 \n\n## Chip Family \n**UART** – a classic serial‑communication peripheral that implements a full‑featured asynchronous transmitter and receiver operating at a fixed 115 200 baud rate. \n\n--- \n\n## Port List \n\n| Direction | Bit‑Width | Signal Name | Purpose |\n|-----------|----------|-------------|------------------------------------------------|\n| Input | 1 | `clk` | System clock (positive‑edge triggered). |\n| Input | 1 | `rst_n` | Asynchronous active‑low reset. |\n| Input | 1 | `tx_load` | Pulse to load new data onto the transmitter. |\n| Input | 8 | `tx_data` | Data byte to be transmitted. |\n| Input | 1 | `rx_valid` | (unused on the input side – kept as a reserved input for future extensions.) |\n| Output | 1 | `txd` | UART transmit line (idles high). |\n| Output | 1 | `rxd` | UART receive line (sampled on positive edges). |\n| Output | 1 | `tx_done` | Pulses high for one clock cycle when the transmitter finishes a frame. |\n| Output | 1 | `rx_error` | Flags overrun/parity/framing error on receive. |\n| Output | 8 | `rx_data` | Received data byte (valid when `rx_valid` is high). |\n\nAll ports are one‑bit wide except where noted; each signal name follows the exact spelling shown above. \n\n--- \n\n## Parameters \n\n| Parameter | Type | Default Value | Meaning / Usage |\n|-----------|------|---------------|-----------------|\n| `DATA_WIDTH` | `int` | `8` | Width of the data bus used for TX and RX payloads. |\n| `SYSTEM_CLK_FREQ` | `int` | `30_000_000` | Frequency of `clk` in Hz. Chosen to enable an exact integer divider for 115 200 baud when `OVERSAMPLE = 16`. |\n| `BAUD_RATE` | `int` | `115200` | Target baud rate (fixed for this instance). |\n| `OVERSAMPLE` | `int` | `16` | Number of samples per bit; standard for UART‑v2. |\n| `DIVIDER_WIDTH` | `int` | `8` | Width of the baud‑rate divider counter. |\n| `FIFO_DEP", "output": "", "success": false, "strategy": "SystemVerilog Modular (Modern)", "metrics": {}, "coverage": {}, "build_log_excerpt": "[INIT] Starting Build Process for 'uart_controller_at_115200' using SystemVerilog Modular (Modern)\n[INIT] Logging initialized to /home/vickynishad/OpenLane/designs/uart_controller_at_115200/uart_controller_at_115200.log\n[INIT] PDK profile: sky130 (PDK=sky130A, LIB=sky130_fd_sc_hd)\n[INIT] Transitioning: INIT -> SPEC\n[SPEC] Architecture Plan Generated\n[SPEC] Transitioning: SPEC -> RTL_GEN\n[RTL_GEN] No golden template match. Generating from scratch.\n[RTL_GEN] File Write Error: Error: No Verilog 'module' definition found in the provided code. Please ensure you output the full Verilog code inside ```verilog``` fences.", "source": "agentic_web_build"}
78
+ {"job_id": "7b3059c5-022e-42a4-a082-c0c0f0f0bf23", "timestamp": 1772035035, "design_name": "axi4_dma_engine_with", "instruction": "Design a digital chip: AXI4 DMA engine with 4 channels", "input": "\n## Module: axi4_dma_engine_with \n\n--- \n\n## Chip Family \n**AXI4 DMA Engine** – a multi‑channel, AXI‑4 compliant Direct Memory Access engine. The core is an AXI master that can initiate independent read and write transactions on each of four channels. \n\n--- \n\n## Port List \n\n| Port | Direction | Bit‑Width | Purpose |\n|------|-----------|-----------|---------|\n| `clk` | Input | 1 | System clock. |\n| `rst_n` | Input | 1 | Asynchronous active‑low reset. |\n| `start_i` | Input | 4 | Start transaction for each of the 4 channels. |\n| `stop_i` | Input | 4 | Abort transaction for each of the 4 channels. |\n| `done_o` | Output | 4 | Transaction‑complete flag per channel. |\n| `err_o` | Output | 4 | Error flag per channel (decode or timeout). |\n| **AXI‑4 Master Interface** (shared by all channels) | | | |\n| `axi_awaddr` | Input | 32 | Address for Write (AW) channel. |\n| `axi_awvalid` | Input | 1 | Valid signal for write address. |\n| `axi_awready` | Output | 1 | Ready to accept write address. |\n| `axi_wdata` | Input | 32 | Write data bus. |\n| `axi_wstrb` | Input | 4 | Byte‑lane strobe (1‑bit per 8‑bit). |\n| `axi_wlast` | Input | 1 | Last beat of a burst. |\n| `axi_wvalid` | Output | 1 | Valid signal for write data. |\n| `axi_wready` | Input | 1 | Ready to accept write data. |\n| `axi_bresp` | Output | 2 | Write response (OKAY, SLVERR, DECERR). |\n| `axi_bvalid` | Output | 1 | Valid response on write channel. |\n| `axi_bready` | Input | 1 | Ready to accept write response. |\n| `axi_araddr` | Input | 32 | Address for Read (AR) channel. |\n| `axi_arvalid` | Input | 1 | Valid signal for read address. |\n| `axi_arready` | Output | 1 | Ready to accept read address. |\n| `axi_rdata` | Output | 32 | Read data bus. |\n| `axi_rresp` | Output | 2 | Read response. |\n| `axi_rvalid` | Output | 1 | Valid signal for read data. |\n| `axi_rready` | Input | 1 | Ready to accept read data. |\n| `irq_o` | Output | 1 | Interrupt request to host (active‑high). |\n\n*All AXI‑4 signals are **shared** among the f", "output": "`timescale 1ns / 1psmodule name matches spec: axi4_dma_engine_with\n * -------------------------------------------------------\n * Features:\n * – 4 independent AXI‑4 master channels\n * – Start/Stop control per channel\n * – Simple descriptor fetch (addr, length, flags)\n * – Write‑burst up to MAX_BURST_LEN beats\n * – Write‑response checking (b.resp == OKAY)\n * – Completion interrupt (irq_o)\n * – Asynchronous active‑low reset (rst_n)\n * – All parameters are configurable via parameters below\n * – Production‑ready coding style (always_ff, logic, enum, no placeholders)\n ******************************************************************************************/\n\nmodule axi4_dma_engine_with #(\n parameter int DATA_WIDTH = 32,\n parameter int ADDR_WIDTH = 32,\n parameter int NUM_CHANNELS = 4,\n parameter int MAX_BURST_LEN = 16,\n parameter int DESCRIPTOR_DEPTH = 1024,\n parameter int RESET_SYNC = 0, // 0 = async reset, 1 = sync reset\n parameter string INITIAL_FSM_STATE = \"IDLE\"\n) (\n // System & Reset\n input logic clk,\n input logic rst_n, // async active‑low\n\n // Channel Control Interface\n input logic [NUM_CHANNELS-1:0] start_i,\n input logic [NUM_CHANNELS-1:0] stop_i,\n output logic [NUM_CHANNELS-1:0] done_o,\n output logic [NUM_CHANNELS-1:0] err_o,\n\n // Shared AXI‑4 Master Interface\n output logic [ADDR_WIDTH-1:0] axi_aw", "success": false, "strategy": "SystemVerilog Modular (Modern)", "metrics": {}, "coverage": {}, "build_log_excerpt": "[INIT] Starting Build Process for 'axi4_dma_engine_with' using SystemVerilog Modular (Modern)\n[INIT] Logging initialized to /home/vickynishad/OpenLane/designs/axi4_dma_engine_with/axi4_dma_engine_with.log\n[INIT] PDK profile: sky130 (PDK=sky130A, LIB=sky130_fd_sc_hd)\n[INIT] Transitioning: INIT -> SPEC\n[SPEC] Architecture Plan Generated\n[SPEC] Transitioning: SPEC -> RTL_GEN\n[RTL_GEN] No golden template match. Generating from scratch.\n[RTL_GEN] Hierarchical synthesis planner: disabled.\n[RTL_GEN] Transitioning: RTL_GEN -> RTL_FIX\n[RTL_FIX] Fixing Code (Attempt 1/5)\n[RTL_FIX] File Write Error in FIX stage: Error: No Verilog 'module' definition found in the provided code. Please ensure you output the full Verilog code inside ```verilog``` fences.\n[RTL_FIX] Retrying fix (LLM output was unparsable).\n[RTL_FIX] Detected repeated syntax/lint failure fingerprint. Failing closed.", "source": "agentic_web_build"}
79
+ {"job_id": "f6dc0268-20c7-4291-97b9-187e908e324c", "timestamp": 1772036669, "design_name": "axi4_dma_engine_with", "instruction": "Design a digital chip: AXI4 DMA engine with 4 channels", "input": "\n## Module: axi4_dma_engine_with \n\n## Chip Family \n**AXI4‑DMA Engine** – A high‑performance, AXI‑4‑stream‑compatible Direct‑Memory Access controller. \nThe core belongs to the **AXI peripheral** family; it implements a multi‑channel, AXI‑4 master/target datapath surrounding a compact state‑machine that services four independent DMA channels.\n\n--- \n\n## Port List \n\n| Port Name | Direction | Bit‑Width | Purpose |\n|-----------|-----------|-----------|---------|\n| `clk` | Input | 1 | System clock. All synchronous logic samples on the rising edge. |\n| `rst_n` | Input | 1 | Asynchronous active‑low reset. When asserted the entire engine goes to the **IDLE** reset state. |\n| `axi_araddr` | Input | `ADDR_WIDTH` | Address channel (read) address bus. |\n| `axi_arvalid` | Input | 1 | Valid signal for a read address transaction. |\n| `axi_arready` | Output | 1 | Ready signal for a read address transaction. |\n| `axi_rdata` | Output | `DATA_WIDTH` | Read data returned by the AXI slave. |\n| `axi_rresp` | Output | 2 | Response code for the read transaction (OKAY, SLVERR, etc.). |\n| `axi_rvalid` | Output | 1 | Valid signal indicating that `axi_rdata`/`axi_rresp` are meaningful. |\n| `axi_rready` | Input | 1 | Ready signal for the read data channel. |\n| `axi_awaddr` | Input | `ADDR_WIDTH` | Address channel (write) address bus. |\n| `axi_awvalid` | Input | 1 | Valid signal for a write address transaction. |\n| `axi_awready` | Output | 1 | Ready signal for a write address transaction. |\n| `axi_wdata` | Input | `DATA_WIDTH` | Write data bus supplied by the master. |\n| `axi_wstrb` | Input | `DATA_BYTES` (`DATA_WIDTH/8`) | Byte‑lane strobe signals. |\n| `axi_wvalid` | Input | 1 | Valid signal indicating that `axi_wdata`/`axi_wstrb` are driven. |\n| `axi_wready` | Output | 1 | Ready signal for the write data channel. |\n| `axi_bresp` | Output | 2 | Response code for a write‐back transaction. |\n| `axi_bvalid` | Output | 1 | Valid signal indicating that `axi_bresp` is available. |\n| `axi_bready` |", "output": "", "success": false, "strategy": "SystemVerilog Modular (Modern)", "metrics": {}, "coverage": {}, "build_log_excerpt": "[INIT] Starting Build Process for 'axi4_dma_engine_with' using SystemVerilog Modular (Modern)\n[INIT] Logging initialized to /home/vickynishad/OpenLane/designs/axi4_dma_engine_with/axi4_dma_engine_with.log\n[INIT] PDK profile: sky130 (PDK=sky130A, LIB=sky130_fd_sc_hd)\n[INIT] Transitioning: INIT -> SPEC\n[SPEC] Architecture Plan Generated\n[SPEC] Transitioning: SPEC -> RTL_GEN\n[RTL_GEN] No golden template match. Generating from scratch.\n[RTL_GEN] File Write Error: Error: No Verilog 'module' definition found in the provided code. Please ensure you output the full Verilog code inside ```verilog``` fences.", "source": "agentic_web_build"}
80
+ {"job_id": "3772ce69-1eb1-4fd7-9786-7bd93c1a0e28", "timestamp": 1772037059, "design_name": "axi4_dma_engine_with", "instruction": "Design a digital chip: AXI4 DMA engine with 4 channels", "input": "\n## Module: axi4_dma_engine_with \n\n## Chip Family \n**AXI** – This block is a dedicated AXI‑4 peripheral that implements a multi‑channel Direct Memory Access (DMA) engine. It is classified under the AXI family because its primary purpose is to act as an AXI‑4 slave that coordinates memory transfers on behalf of other system masters, while exposing a fully‑featured AXI‑4 interface for configuration and status.\n\n---\n\n## Port List \n\n| Direction | Name | Width | Purpose |\n|-----------|---------------------|-------|------------------------------------------------------------|\n| Input | `aclk` | 1 | System clock for the DMA engine (single‑cycle synchronous logic). |\n| Input | `aresetn` | 1 | Active‑low asynchronous reset for all logic. |\n| Input | `s_axi_awaddr` | 32 | Address for AXI write‑address channel. |\n| Input | `s_axi_awvalid` | 1 | Valid signal for write‑address channel. |\n| Output | `s_axi_awready` | 1 | Ready signal for write‑address channel. |\n| Input | `s_axi_wdata` | 32 | Write data bus. |\n| Input | `s_axi_wstrb` | 4 | Byte‑lane strobe for write data (byte‑enable). |\n| Input | `s_axi_wvalid` | 1 | Valid signal for write‑data channel. |\n| Output | `s_axi_wready` | 1 | Ready signal for write‑data channel. |\n| Output | `s_axi_bresp` | 2 | Response for write‑address/write data completion. |\n| Output | `s_axi_bvalid` | 1 | Valid signal for write‑response channel. |\n| Input | `s_axi_bready` | 1 | Ready signal for write‑response channel. |\n| Input | `s_axi_araddr` | 32 | Address for AXI read‑address channel. |\n| Input | `s_axi_arvalid` | 1 | Valid signal for read‑address channel. |\n| Output | `s_axi_arready` | 1 | Ready signal for read‑address channel. |\n| Output | `s_axi_rdata` | 32 | Read data returned to the AXI master. |\n", "output": "", "success": false, "strategy": "SystemVerilog Modular (Modern)", "metrics": {}, "coverage": {}, "build_log_excerpt": "[INIT] Starting Build Process for 'axi4_dma_engine_with' using SystemVerilog Modular (Modern)\n[INIT] Logging initialized to /home/vickynishad/OpenLane/designs/axi4_dma_engine_with/axi4_dma_engine_with.log\n[INIT] PDK profile: sky130 (PDK=sky130A, LIB=sky130_fd_sc_hd)\n[INIT] Transitioning: INIT -> SPEC\n[SPEC] Architecture Plan Generated\n[SPEC] Transitioning: SPEC -> RTL_GEN\n[RTL_GEN] No golden template match. Generating from scratch.\n[RTL_GEN] File Write Error: Error: No Verilog 'module' definition found in the provided code. Please ensure you output the full Verilog code inside ```verilog``` fences.", "source": "agentic_web_build"}
web/src/App.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, Suspense } from 'react';
2
  import axios from 'axios';
3
  import { Canvas } from '@react-three/fiber';
4
  import { Chip3D } from './components/Chip3D';
@@ -14,7 +14,8 @@ const App = () => {
14
  const [selectedDesign, setSelectedDesign] = useState<string>('');
15
 
16
  useEffect(() => {
17
- axios.get('http://localhost:8000/designs')
 
18
  .then(res => {
19
  const data = res.data.designs;
20
  setDesigns(data);
 
1
+ import { useState, useEffect, Suspense } from 'react';
2
  import axios from 'axios';
3
  import { Canvas } from '@react-three/fiber';
4
  import { Chip3D } from './components/Chip3D';
 
14
  const [selectedDesign, setSelectedDesign] = useState<string>('');
15
 
16
  useEffect(() => {
17
+ const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000';
18
+ axios.get(`${API_BASE_URL}/designs`)
19
  .then(res => {
20
  const data = res.data.designs;
21
  setDesigns(data);
web/src/components/BuildMonitor.tsx CHANGED
@@ -2,7 +2,7 @@ import React, { useEffect, useRef } from 'react';
2
  import { motion } from 'framer-motion';
3
  import axios from 'axios';
4
 
5
- const API = 'http://localhost:8000';
6
 
7
  const STATES_DISPLAY: Record<string, { label: string; icon: string }> = {
8
  INIT: { label: 'Initializing Workspace', icon: '🔧' },
 
2
  import { motion } from 'framer-motion';
3
  import axios from 'axios';
4
 
5
+ const API = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000';
6
 
7
  const STATES_DISPLAY: Record<string, { label: string; icon: string }> = {
8
  INIT: { label: 'Initializing Workspace', icon: '🔧' },
web/src/components/Chip3D.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import React, { useRef } from 'react';
2
  import { useFrame } from '@react-three/fiber';
3
  import { Float, Box, Edges } from '@react-three/drei';
4
  import * as THREE from 'three';
@@ -29,12 +29,12 @@ export const Chip3D = () => {
29
 
30
  {/* Top Active Matrix - Glowing */}
31
  <Box args={[2.5, 0.2, 2.5]} position={[0, 0, 0]}>
32
- <meshStandardMaterial
33
- color="#00FF88"
34
  emissive="#00FF88"
35
  emissiveIntensity={0.5}
36
- roughness={0.2}
37
- metalness={0.8}
38
  />
39
  <Edges color="#fff" />
40
  </Box>
 
1
+ import { useRef } from 'react';
2
  import { useFrame } from '@react-three/fiber';
3
  import { Float, Box, Edges } from '@react-three/drei';
4
  import * as THREE from 'three';
 
29
 
30
  {/* Top Active Matrix - Glowing */}
31
  <Box args={[2.5, 0.2, 2.5]} position={[0, 0, 0]}>
32
+ <meshStandardMaterial
33
+ color="#00FF88"
34
  emissive="#00FF88"
35
  emissiveIntensity={0.5}
36
+ roughness={0.2}
37
+ metalness={0.8}
38
  />
39
  <Edges color="#fff" />
40
  </Box>
web/src/pages/Dashboard.tsx CHANGED
@@ -17,20 +17,21 @@ export const Dashboard: React.FC<DashboardProps> = ({ selectedDesign }) => {
17
  setLoading(true);
18
 
19
  // Fetch Quick Metrics
20
- axios.get(`http://localhost:8000/metrics/${selectedDesign}`)
 
21
  .then(res => {
22
  if (res.data.metrics) setMetrics(res.data.metrics);
23
  })
24
- .catch(err => {
25
  setMetrics({ wns: 'N/A', power: 'N/A', area: 'N/A', gate_count: 'N/A' });
26
  });
27
 
28
  // Fetch Full LLM Signoff Report
29
- axios.get(`http://localhost:8000/signoff/${selectedDesign}`)
30
  .then(res => {
31
  setSignoffData({ report: res.data.report, pass: res.data.success });
32
  })
33
- .catch(err => {
34
  setSignoffData({ report: 'Failed to retrieve Signoff Report. Has the device been fully hardened via OpenLane yet?', pass: false });
35
  })
36
  .finally(() => setLoading(false));
 
17
  setLoading(true);
18
 
19
  // Fetch Quick Metrics
20
+ const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000';
21
+ axios.get(`${API_BASE_URL}/metrics/${selectedDesign}`)
22
  .then(res => {
23
  if (res.data.metrics) setMetrics(res.data.metrics);
24
  })
25
+ .catch(() => {
26
  setMetrics({ wns: 'N/A', power: 'N/A', area: 'N/A', gate_count: 'N/A' });
27
  });
28
 
29
  // Fetch Full LLM Signoff Report
30
+ axios.get(`${API_BASE_URL}/signoff/${selectedDesign}`)
31
  .then(res => {
32
  setSignoffData({ report: res.data.report, pass: res.data.success });
33
  })
34
+ .catch(() => {
35
  setSignoffData({ report: 'Failed to retrieve Signoff Report. Has the device been fully hardened via OpenLane yet?', pass: false });
36
  })
37
  .finally(() => setLoading(false));
web/src/pages/DesignStudio.tsx CHANGED
@@ -1,10 +1,10 @@
1
- import React, { useState, useEffect, useRef } from 'react';
2
  import { motion, AnimatePresence } from 'framer-motion';
3
  import axios from 'axios';
4
  import { BuildMonitor } from '../components/BuildMonitor';
5
  import { ChipSummary } from '../components/ChipSummary';
6
 
7
- const API = 'http://localhost:8000';
8
 
9
  type Phase = 'prompt' | 'building' | 'done';
10
 
 
1
+ import { useState, useEffect, useRef } from 'react';
2
  import { motion, AnimatePresence } from 'framer-motion';
3
  import axios from 'axios';
4
  import { BuildMonitor } from '../components/BuildMonitor';
5
  import { ChipSummary } from '../components/ChipSummary';
6
 
7
+ const API = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000';
8
 
9
  type Phase = 'prompt' | 'building' | 'done';
10