vxkyyy commited on
Commit
c9be45d
·
1 Parent(s): e4ce6eb

fix: strict_gates defaults to false, remove dead code

Browse files

- Set strict_gates=False in orchestrator constructor and both frontend pages
- Move docker/eqy from required_bins to optional_bins in startup_self_check
- Remove dead files: debug_llm.py (broken import), .streamlit/ (superseded),
golden_lib/verilator_coverage.py (never imported, superseded by vlsi_tools)
- Fix stale Nemotron/GLM5 references in api.py comments

.streamlit/config.toml DELETED
@@ -1,14 +0,0 @@
1
- [theme]
2
- primaryColor = "#00FF88"
3
- backgroundColor = "#000000"
4
- secondaryBackgroundColor = "#0E1117"
5
- textColor = "#E0E0E0"
6
- font = "sans serif"
7
-
8
- [server]
9
- headless = true
10
- enableCORS = false
11
- enableXsrfProtection = false
12
-
13
- [deprecation]
14
- showPyplotGlobalUse = false
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
debug_llm.py DELETED
@@ -1,52 +0,0 @@
1
- import os
2
- import sys
3
-
4
- # Add src to path to import config
5
- sys.path.append(os.path.join(os.path.dirname(__file__), 'src'))
6
- from agentic.config import NVIDIA_CONFIG, GLM5_CONFIG, LOCAL_CONFIG
7
- from crewai import LLM
8
-
9
- print(f"--- Debugging LLM Flow ---")
10
-
11
- def try_model(name, config):
12
- print(f"\nTesting {name}...")
13
- print(f"Model: {config['model']}")
14
- print(f"Base URL: {config['base_url']}")
15
- masked_key = '*' * 5 + config['api_key'][-4:] if config['api_key'] and len(config['api_key']) > 4 else 'None'
16
- print(f"API Key: {masked_key}")
17
-
18
- if not config['api_key'] or config['api_key'] == "NA":
19
- print(f"⏭ Skipping {name}: No API Key found.")
20
- return False
21
-
22
- try:
23
- llm = LLM(
24
- model=config['model'],
25
- base_url=config['base_url'],
26
- api_key=config['api_key']
27
- )
28
- resp = llm.call(
29
- messages=[{"role": "user", "content": "Return the word 'CONNECTED' if you hear me."}]
30
- )
31
- print(f"✅ {name} Success! Response:\n{resp}")
32
- return True
33
- except Exception as e:
34
- print(f"❌ {name} Failed: {e}")
35
- return False
36
-
37
- # 1. Try NVIDIA
38
- if try_model("NVIDIA (Primary)", NVIDIA_CONFIG):
39
- print("\n🎉 Verification Complete: Using NVIDIA.")
40
- sys.exit(0)
41
-
42
- # 2. Try GLM5
43
- if try_model("GLM5 (Backup)", GLM5_CONFIG):
44
- print("\n🎉 Verification Complete: Using GLM5.")
45
- sys.exit(0)
46
-
47
- # 3. Try Local
48
- if try_model("Local (Default)", LOCAL_CONFIG):
49
- print("\n🎉 Verification Complete: Using Local LLM.")
50
- sys.exit(0)
51
-
52
- print("\n🔥 All LLM connections failed.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
server/api.py CHANGED
@@ -93,7 +93,7 @@ STAGE_META: Dict[str, Dict[str, str]] = {
93
 
94
  def _get_llm(byok_api_key: str = None):
95
  """Tries cloud backends first, then local Ollama.
96
- Priority: NVIDIA Nemotron → Groq LLaMA-3.3 → VeriReason Local
97
 
98
  If byok_api_key is provided (BYOK plan), it overrides the cloud config key.
99
  """
@@ -344,7 +344,7 @@ def _run_agentic_build(job_id: str, req: BuildRequest):
344
  thought_type = _infer_thought_type(message)
345
  _emit_agent_thought(job_id, agent_name, thought_type, message, state)
346
 
347
- # Use smart LLM selection: Cloud first (NemotronGLM5) → Local fallback
348
  byok_key = JOB_STORE[job_id].get("byok_key")
349
  llm, llm_name = _get_llm(byok_api_key=byok_key)
350
  _emit_event(job_id, "checkpoint", "INIT", f"🤖 Compute engine ready", step=1)
 
93
 
94
  def _get_llm(byok_api_key: str = None):
95
  """Tries cloud backends first, then local Ollama.
96
+ Priority: NVIDIA Cloud → Groq LLaMA-3.3 → Local Ollama
97
 
98
  If byok_api_key is provided (BYOK plan), it overrides the cloud config key.
99
  """
 
344
  thought_type = _infer_thought_type(message)
345
  _emit_agent_thought(job_id, agent_name, thought_type, message, state)
346
 
347
+ # Use smart LLM selection: Cloud first (NVIDIAGroq) → Local fallback
348
  byok_key = JOB_STORE[job_id].get("byok_key")
349
  llm, llm_name = _get_llm(byok_api_key=byok_key)
350
  _emit_event(job_id, "checkpoint", "INIT", f"🤖 Compute engine ready", step=1)
src/agentic/golden_lib/verilator_coverage.py DELETED
@@ -1,213 +0,0 @@
1
- """Verilator Real Coverage Integration.
2
-
3
- Provides actual code coverage using Verilator's --coverage flag,
4
- replacing the heuristic-based coverage estimate in vlsi_tools.py.
5
- """
6
-
7
- import os
8
- import re
9
- import subprocess
10
- from ..config import OPENLANE_ROOT
11
-
12
-
13
- def run_verilator_coverage(design_name: str) -> tuple:
14
- """Compiles and runs simulation with Verilator's real coverage instrumentation.
15
-
16
- Uses Verilator to compile the design with --coverage flag, runs the
17
- simulation binary, then parses the coverage output.
18
-
19
- Returns:
20
- tuple: (success: bool, report: str, coverage_data: dict)
21
- coverage_data = {'line': float, 'branch': float, 'toggle': float, 'overall': float}
22
- """
23
- src_dir = f"{OPENLANE_ROOT}/designs/{design_name}/src"
24
- rtl_file = f"{src_dir}/{design_name}.v"
25
- tb_file = f"{src_dir}/{design_name}_tb.v"
26
- obj_dir = f"{src_dir}/verilator_cov_obj"
27
- cov_dat = f"{src_dir}/coverage.dat"
28
-
29
- if not os.path.exists(rtl_file):
30
- return False, f"RTL file not found: {rtl_file}", {}
31
- if not os.path.exists(tb_file):
32
- return False, f"Testbench file not found: {tb_file}", {}
33
-
34
- # Step 1: Compile with Verilator --coverage
35
- compile_cmd = [
36
- "verilator", "--binary", "--coverage",
37
- "--coverage-line", "--coverage-toggle",
38
- "-Wno-fatal",
39
- "--timing",
40
- f"--Mdir", obj_dir,
41
- "-o", f"V{design_name}",
42
- "--top-module", f"{design_name}_tb",
43
- rtl_file, tb_file
44
- ]
45
-
46
- try:
47
- result = subprocess.run(
48
- compile_cmd,
49
- capture_output=True, text=True,
50
- timeout=180
51
- )
52
- if result.returncode != 0:
53
- # Fallback: Verilator couldn't compile (common with iverilog-style TBs)
54
- return False, f"Verilator compilation failed (this is normal for iverilog-style testbenches):\n{result.stderr[:500]}", {}
55
- except FileNotFoundError:
56
- return False, "Verilator not installed. Falling back to heuristic coverage.", {}
57
- except subprocess.TimeoutExpired:
58
- return False, "Verilator compilation timed out.", {}
59
-
60
- # Step 2: Run the simulation
61
- sim_binary = f"{obj_dir}/V{design_name}"
62
- if not os.path.exists(sim_binary):
63
- return False, f"Simulation binary not found: {sim_binary}", {}
64
-
65
- try:
66
- sim_result = subprocess.run(
67
- [sim_binary, f"+verilator+coverage+file+{cov_dat}"],
68
- capture_output=True, text=True,
69
- timeout=300,
70
- cwd=src_dir
71
- )
72
- except subprocess.TimeoutExpired:
73
- return False, "Simulation timed out.", {}
74
-
75
- sim_output = (sim_result.stdout or "") + ("\n" + sim_result.stderr if sim_result.stderr else "")
76
- sim_passed = "TEST PASSED" in sim_output
77
-
78
- # Step 3: Parse coverage data
79
- coverage_data = parse_verilator_coverage(cov_dat, src_dir)
80
-
81
- report = f"Simulation: {'PASSED' if sim_passed else 'FAILED'}\n"
82
- report += f"Coverage: line={coverage_data.get('line', 0):.1f}% "
83
- report += f"toggle={coverage_data.get('toggle', 0):.1f}% "
84
- report += f"overall={coverage_data.get('overall', 0):.1f}%"
85
-
86
- return sim_passed, report, coverage_data
87
-
88
-
89
- def parse_verilator_coverage(cov_dat_path: str, output_dir: str) -> dict:
90
- """Parse Verilator coverage.dat file into coverage percentages.
91
-
92
- Args:
93
- cov_dat_path: Path to coverage.dat file
94
- output_dir: Directory for annotated output
95
-
96
- Returns:
97
- dict with 'line', 'toggle', 'branch', 'overall' percentages
98
- """
99
- result = {
100
- 'line': 0.0,
101
- 'toggle': 0.0,
102
- 'branch': 0.0,
103
- 'overall': 0.0,
104
- 'total_points': 0,
105
- 'hit_points': 0
106
- }
107
-
108
- if not os.path.exists(cov_dat_path):
109
- result['error'] = 'coverage.dat not found'
110
- return result
111
-
112
- # Use verilator_coverage tool to get summary
113
- annotate_dir = f"{output_dir}/cov_annotate"
114
-
115
- try:
116
- # Get annotated output
117
- subprocess.run(
118
- ["verilator_coverage", "--annotate", annotate_dir, cov_dat_path],
119
- capture_output=True, text=True, timeout=30
120
- )
121
-
122
- # Parse annotated files for line coverage
123
- line_total = 0
124
- line_hit = 0
125
- toggle_total = 0
126
- toggle_hit = 0
127
-
128
- if os.path.exists(annotate_dir):
129
- for root, dirs, files in os.walk(annotate_dir):
130
- for fname in files:
131
- if fname.endswith('.v') or fname.endswith('.sv'):
132
- fpath = os.path.join(root, fname)
133
- with open(fpath, 'r') as f:
134
- for line in f:
135
- line = line.strip()
136
- # Verilator annotates with coverage counts
137
- cov_match = re.match(r'^(\d+)\s+(.+)', line)
138
- if cov_match:
139
- count = int(cov_match.group(1))
140
- line_total += 1
141
- if count > 0:
142
- line_hit += 1
143
- elif line.startswith('%'):
144
- # Toggle coverage annotations
145
- toggle_total += 1
146
- pct_match = re.match(r'%0*(\d+)', line)
147
- if pct_match and int(pct_match.group(1)) > 0:
148
- toggle_hit += 1
149
-
150
- if line_total > 0:
151
- result['line'] = round((line_hit / line_total) * 100, 1)
152
- if toggle_total > 0:
153
- result['toggle'] = round((toggle_hit / toggle_total) * 100, 1)
154
-
155
- result['total_points'] = line_total + toggle_total
156
- result['hit_points'] = line_hit + toggle_hit
157
-
158
- # Branch coverage estimate (Verilator doesn't separate this well)
159
- result['branch'] = round(result['line'] * 0.85, 1) if result['line'] > 0 else 0.0
160
-
161
- # Overall
162
- if result['total_points'] > 0:
163
- result['overall'] = round((result['hit_points'] / result['total_points']) * 100, 1)
164
-
165
- except FileNotFoundError:
166
- result['error'] = 'verilator_coverage tool not found'
167
- except Exception as e:
168
- result['error'] = str(e)
169
-
170
- # Also try to get summary directly from coverage.dat
171
- try:
172
- with open(cov_dat_path, 'r') as f:
173
- cov_text = f.read()
174
-
175
- # Count coverage points
176
- point_matches = re.findall(r"'(\d+)'", cov_text)
177
- if point_matches:
178
- total = len(point_matches)
179
- hit = sum(1 for p in point_matches if int(p) > 0)
180
- if total > 0 and result['overall'] == 0:
181
- result['line'] = round((hit / total) * 100, 1)
182
- result['overall'] = result['line']
183
- result['total_points'] = total
184
- result['hit_points'] = hit
185
- except Exception:
186
- pass
187
-
188
- return result
189
-
190
-
191
- def get_coverage_summary(design_name: str) -> str:
192
- """Get a human-readable coverage summary for a design.
193
-
194
- Returns:
195
- str: Formatted coverage summary
196
- """
197
- src_dir = f"{OPENLANE_ROOT}/designs/{design_name}/src"
198
- cov_dat = f"{src_dir}/coverage.dat"
199
-
200
- data = parse_verilator_coverage(cov_dat, src_dir)
201
-
202
- if data.get('error'):
203
- return f"Coverage data unavailable: {data['error']}"
204
-
205
- return (
206
- f"📊 Coverage Report for {design_name}\n"
207
- f"{'='*40}\n"
208
- f" Line Coverage: {data['line']:.1f}%\n"
209
- f" Toggle Coverage: {data['toggle']:.1f}%\n"
210
- f" Branch Coverage: {data['branch']:.1f}% (estimated)\n"
211
- f" Overall: {data['overall']:.1f}%\n"
212
- f" Points: {data['hit_points']}/{data['total_points']} hit\n"
213
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/agentic/orchestrator.py CHANGED
@@ -172,7 +172,7 @@ class BuildOrchestrator:
172
  skip_coverage: bool = False,
173
  full_signoff: bool = False,
174
  min_coverage: float = 80.0,
175
- strict_gates: bool = True,
176
  pdk_profile: str = "sky130",
177
  max_pivots: int = 2,
178
  congestion_threshold: float = 10.0,
 
172
  skip_coverage: bool = False,
173
  full_signoff: bool = False,
174
  min_coverage: float = 80.0,
175
+ strict_gates: bool = False,
176
  pdk_profile: str = "sky130",
177
  max_pivots: int = 2,
178
  congestion_threshold: float = 10.0,
src/agentic/tools/vlsi_tools.py CHANGED
@@ -220,12 +220,12 @@ def startup_self_check() -> Dict[str, Any]:
220
  "verilator": "verilator",
221
  "iverilog": "iverilog",
222
  "vvp": "vvp",
223
- "docker": "docker",
224
  "yosys": YOSYS_BIN,
225
  "sby": SBY_BIN,
226
- "eqy": EQY_BIN,
227
  }
228
  optional_bins = {
 
 
229
  "verilator_coverage": "verilator_coverage",
230
  }
231
  all_pass = True
 
220
  "verilator": "verilator",
221
  "iverilog": "iverilog",
222
  "vvp": "vvp",
 
223
  "yosys": YOSYS_BIN,
224
  "sby": SBY_BIN,
 
225
  }
226
  optional_bins = {
227
+ "docker": "docker",
228
+ "eqy": EQY_BIN,
229
  "verilator_coverage": "verilator_coverage",
230
  }
231
  all_pass = True
web/src/pages/DesignStudio.tsx CHANGED
@@ -52,7 +52,7 @@ export const DesignStudio = () => {
52
  const [maxRetries, setMaxRetries] = useState(5);
53
  const [showThinking, setShowThinking] = useState(false);
54
  const [minCoverage, setMinCoverage] = useState(80.0);
55
- const [strictGates, setStrictGates] = useState(true);
56
  const [pdkProfile, setPdkProfile] = useState("sky130");
57
  const [maxPivots, setMaxPivots] = useState(2);
58
  const [congestionThreshold, setCongestionThreshold] = useState(10.0);
 
52
  const [maxRetries, setMaxRetries] = useState(5);
53
  const [showThinking, setShowThinking] = useState(false);
54
  const [minCoverage, setMinCoverage] = useState(80.0);
55
+ const [strictGates, setStrictGates] = useState(false);
56
  const [pdkProfile, setPdkProfile] = useState("sky130");
57
  const [maxPivots, setMaxPivots] = useState(2);
58
  const [congestionThreshold, setCongestionThreshold] = useState(10.0);
web/src/pages/HumanInLoopBuild.tsx CHANGED
@@ -125,7 +125,7 @@ export const HumanInLoopBuild = () => {
125
  const [maxRetries, setMaxRetries] = useState(5);
126
  const [showThinking, setShowThinking] = useState(false);
127
  const [minCoverage, setMinCoverage] = useState(80.0);
128
- const [strictGates, setStrictGates] = useState(true);
129
  const [pdkProfile, setPdkProfile] = useState("sky130");
130
 
131
  // Build mode & stage skipping (Improvement 2)
 
125
  const [maxRetries, setMaxRetries] = useState(5);
126
  const [showThinking, setShowThinking] = useState(false);
127
  const [minCoverage, setMinCoverage] = useState(80.0);
128
+ const [strictGates, setStrictGates] = useState(false);
129
  const [pdkProfile, setPdkProfile] = useState("sky130");
130
 
131
  // Build mode & stage skipping (Improvement 2)