Sai Kumar Taraka commited on
Commit
04ea8a9
Β·
1 Parent(s): 9b7377c

feat: Add streamlit_app.py for Streamlit Share deployment

Browse files

- Add full Streamlit UI with protocol selectors (UART, SPI, I2C)
- Add spec editor, options (ML/auto-train configuration
- Add metrics display (completeness, coverage)
- Add file preview and ZIP download
- Built-in logging
- Add streamlit to optional requirements

Deploy to: https://share.streamlit.io/
- Push repo: https://github.com/saikumarstealth-creator/UVM-verification
- Entry point: streamlit_app.py

Files changed (2) hide show
  1. requirements.txt +3 -0
  2. streamlit_app.py +419 -0
requirements.txt CHANGED
@@ -9,6 +9,9 @@ numpy>=1.21.0
9
  scikit-learn>=1.0.0
10
  scipy>=1.7.0
11
 
 
 
 
12
  # Optional: Uncomment for full AI/ML capabilities (requires more resources)
13
  # torch>=2.0.0
14
  # transformers>=4.35.0
 
9
  scikit-learn>=1.0.0
10
  scipy>=1.7.0
11
 
12
+ # Optional: For Streamlit UI (deploy to share.streamlit.io)
13
+ # streamlit>=1.30.0
14
+
15
  # Optional: Uncomment for full AI/ML capabilities (requires more resources)
16
  # torch>=2.0.0
17
  # transformers>=4.35.0
streamlit_app.py ADDED
@@ -0,0 +1,419 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Streamlit UI for UVM Testbench Generator
3
+ Deploy to: https://share.streamlit.io/
4
+ """
5
+
6
+ import streamlit as st
7
+ import logging
8
+ import tempfile
9
+ import os
10
+ import zipfile
11
+ import io
12
+ from pathlib import Path
13
+ from datetime import datetime
14
+
15
+ # Configure logging
16
+ logging.basicConfig(level=logging.INFO)
17
+ logger = logging.getLogger("uvmgen-streamlit")
18
+
19
+ # Page config
20
+ st.set_page_config(
21
+ page_title="UVM Testbench Generator",
22
+ page_icon="πŸ”¬",
23
+ layout="wide",
24
+ initial_sidebar_state="expanded",
25
+ )
26
+
27
+ # Example specifications
28
+ EXAMPLES = {
29
+ "UART": """design_name: uart
30
+ clock_reset:
31
+ clock: clk
32
+ reset: rst_n
33
+
34
+ interfaces:
35
+ - name: wb
36
+ signals:
37
+ - name: wb_cyc
38
+ direction: input
39
+ - name: wb_stb
40
+ direction: input
41
+ - name: wb_we
42
+ direction: input
43
+ - name: wb_addr
44
+ direction: input
45
+ width: 3
46
+ - name: wb_data_o
47
+ direction: output
48
+ width: 8
49
+ - name: wb_data_i
50
+ direction: input
51
+ width: 8
52
+ - name: wb_ack
53
+ direction: output
54
+
55
+ - name: uart
56
+ signals:
57
+ - name: uart_tx
58
+ direction: output
59
+ - name: uart_rx
60
+ direction: input
61
+
62
+ registers:
63
+ - name: RBR_THR
64
+ address: 0x0
65
+ description: Receiver Buffer / Transmitter Holding
66
+ - name: IER
67
+ address: 0x1
68
+ description: Interrupt Enable
69
+ - name: LCR
70
+ address: 0x3
71
+ description: Line Control
72
+ - name: LSR
73
+ address: 0x5
74
+ description: Line Status
75
+
76
+ protocol: uart""",
77
+ "SPI": """design_name: spi_controller
78
+ clock_reset:
79
+ clock: clk
80
+ reset: rst_n
81
+
82
+ interfaces:
83
+ - name: apb
84
+ signals:
85
+ - name: psel
86
+ direction: input
87
+ - name: penable
88
+ direction: input
89
+ - name: pwrite
90
+ direction: input
91
+ - name: paddr
92
+ direction: input
93
+ width: 8
94
+ - name: pwdata
95
+ direction: input
96
+ width: 32
97
+ - name: prdata
98
+ direction: output
99
+ width: 32
100
+ - name: pready
101
+ direction: output
102
+
103
+ - name: spi
104
+ signals:
105
+ - name: sclk
106
+ direction: output
107
+ - name: mosi
108
+ direction: output
109
+ - name: miso
110
+ direction: input
111
+ - name: cs_n
112
+ direction: output
113
+ width: 4
114
+
115
+ registers:
116
+ - name: CTRL
117
+ address: 0x0
118
+ description: Control Register
119
+ - name: TXDATA
120
+ address: 0x4
121
+ description: TX Data
122
+ - name: RXDATA
123
+ address: 0x8
124
+ description: RX Data
125
+ - name: STATUS
126
+ address: 0xC
127
+ description: Status Register
128
+
129
+ protocol: spi""",
130
+ "I2C": """design_name: i2c_master
131
+ clock_reset:
132
+ clock: clk
133
+ reset: rst_n
134
+
135
+ interfaces:
136
+ - name: axi4lite
137
+ signals:
138
+ - name: awvalid
139
+ direction: input
140
+ - name: awready
141
+ direction: output
142
+ - name: awaddr
143
+ direction: input
144
+ width: 16
145
+ - name: wvalid
146
+ direction: input
147
+ - name: wready
148
+ direction: output
149
+ - name: wdata
150
+ direction: input
151
+ width: 32
152
+ - name: rvalid
153
+ direction: output
154
+ - name: rready
155
+ direction: input
156
+ - name: rdata
157
+ direction: output
158
+ width: 32
159
+
160
+ - name: i2c
161
+ signals:
162
+ - name: scl
163
+ direction: inout
164
+ - name: sda
165
+ direction: inout
166
+
167
+ registers:
168
+ - name: PRESCALE
169
+ address: 0x0
170
+ description: Clock Prescale
171
+ - name: CTRL
172
+ address: 0x4
173
+ description: Control
174
+ - name: TX_RX
175
+ address: 0x8
176
+ description: TX/RX Data
177
+ - name: CMD_STATUS
178
+ address: 0xC
179
+ description: Command / Status
180
+
181
+ protocol: i2c"""
182
+ }
183
+
184
+ # Session state
185
+ if 'last_result' not in st.session_state:
186
+ st.session_state.last_result = None
187
+ if 'generated_files' not in st.session_state:
188
+ st.session_state.generated_files = {}
189
+ if 'log_output' not in st.session_state:
190
+ st.session_state.log_output = []
191
+
192
+ # Header
193
+ st.title("πŸ”¬ UVM Testbench Generator")
194
+ st.markdown("""
195
+ **AI-Powered Semiconductor Verification Pipeline**
196
+ Generate industry-grade UVM testbenches from YAML specifications with protocol libraries, coverage-driven auto-training, and CI/CD integration.
197
+ """)
198
+
199
+ # Sidebar
200
+ with st.sidebar:
201
+ st.header("βš™οΈ Configuration")
202
+
203
+ # Protocol selector
204
+ selected_protocol = st.selectbox(
205
+ "Select Protocol Example",
206
+ list(EXAMPLES.keys()),
207
+ index=0
208
+ )
209
+
210
+ # Design name
211
+ default_name = selected_protocol.lower() + "_controller"
212
+ design_name = st.text_input(
213
+ "Design Name",
214
+ value=default_name
215
+ )
216
+
217
+ st.divider()
218
+
219
+ # Options
220
+ st.subheader("Options")
221
+ use_ml = st.checkbox(
222
+ "Enable AI/ML Features",
223
+ value=True,
224
+ help="Use semantic embeddings and learning (when dependencies available)"
225
+ )
226
+
227
+ auto_train = st.checkbox(
228
+ "Enable Auto-Training",
229
+ value=False,
230
+ help="Coverage-driven iterative improvement"
231
+ )
232
+
233
+ max_iterations = st.slider(
234
+ "Max Iterations",
235
+ min_value=1,
236
+ max_value=10,
237
+ value=1
238
+ )
239
+
240
+ st.divider()
241
+
242
+ st.info("πŸ’‘ UVM = Universal Verification Methodology")
243
+ st.caption(f"Developed by **Sai Kumar Taraka**")
244
+
245
+ # Main content
246
+ col1, col2 = st.columns([1, 1])
247
+
248
+ with col1:
249
+ st.subheader("πŸ“ Specification")
250
+
251
+ # Spec editor
252
+ spec_text = st.text_area(
253
+ "YAML Specification",
254
+ value=EXAMPLES[selected_protocol],
255
+ height=400,
256
+ key="spec_editor",
257
+ help="Edit the YAML specification for your design"
258
+ )
259
+
260
+ # Generate button
261
+ generate_btn = st.button(
262
+ "πŸš€ Generate UVM Testbench",
263
+ type="primary",
264
+ use_container_width=True
265
+ )
266
+
267
+ with col2:
268
+ st.subheader("πŸ“Š Results & Output")
269
+
270
+ # Status
271
+ status_placeholder = st.empty()
272
+
273
+ # Metrics
274
+ metrics_placeholder = st.empty()
275
+
276
+ # Logs
277
+ with st.expander("πŸ“‹ Log Output", expanded=True):
278
+ log_placeholder = st.empty()
279
+
280
+ # Files
281
+ files_placeholder = st.empty()
282
+
283
+
284
+ # Generate logic
285
+ if generate_btn:
286
+ st.session_state.log_output = []
287
+ st.session_state.last_result = None
288
+ st.session_state.generated_files = {}
289
+
290
+ status_placeholder.info("πŸ”„ Generating UVM testbench...")
291
+
292
+ try:
293
+ # Import here for lazy loading
294
+ from src.config import ConfigLoader, PipelineConfig
295
+ from src.pipeline import TBPipeline
296
+
297
+ # Save spec to temp file
298
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False, encoding='utf-8') as f:
299
+ f.write(spec_text)
300
+ spec_path = f.name
301
+
302
+ st.session_state.log_output.append(f"[{datetime.now().strftime('%H:%M:%S')}] Starting generation for: {design_name}")
303
+ log_placeholder.code("\n".join(st.session_state.log_output))
304
+
305
+ # Create pipeline
306
+ pipeline = TBPipeline()
307
+ pipeline.cfg.ml.enabled = use_ml
308
+ pipeline.cfg.ml.model_type = "hybrid"
309
+ pipeline.cfg.ml.use_llm = use_ml
310
+ pipeline.cfg.ml.use_semantic_encoder = use_ml
311
+ pipeline.cfg.ml.use_learning = use_ml
312
+ pipeline.cfg.auto_train.enabled = auto_train
313
+ pipeline.cfg.auto_train.max_iterations = max_iterations
314
+
315
+ st.session_state.log_output.append(f"[{datetime.now().strftime('%H:%M:%S')}] ML enabled: {use_ml}")
316
+ st.session_state.log_output.append(f"[{datetime.now().strftime('%H:%M:%S')}] Auto-train: {auto_train} (iterations: {max_iterations})")
317
+ log_placeholder.code("\n".join(st.session_state.log_output))
318
+
319
+ # Run pipeline
320
+ result = pipeline.run(spec_path)
321
+
322
+ # Cleanup
323
+ try:
324
+ os.unlink(spec_path)
325
+ except:
326
+ pass
327
+
328
+ # Store results
329
+ st.session_state.last_result = result
330
+ st.session_state.generated_files = result.get('generated_files', {})
331
+
332
+ st.session_state.log_output.append(f"[{datetime.now().strftime('%H:%M:%S')}] Generation complete!")
333
+ st.session_state.log_output.append(f"[{datetime.now().strftime('%H:%M:%S')}] Files generated: {len(st.session_state.generated_files)}")
334
+ log_placeholder.code("\n".join(st.session_state.log_output))
335
+
336
+ # Update status
337
+ if result.get('passed'):
338
+ status_placeholder.success("βœ… Generation successful!")
339
+ else:
340
+ status_placeholder.warning("⚠️ Generation completed with issues")
341
+
342
+ except Exception as e:
343
+ st.session_state.log_output.append(f"[{datetime.now().strftime('%H:%M:%S')}] ERROR: {str(e)}")
344
+ log_placeholder.code("\n".join(st.session_state.log_output))
345
+ status_placeholder.error(f"❌ Error: {str(e)}")
346
+ import traceback
347
+ st.session_state.log_output.append(traceback.format_exc())
348
+ log_placeholder.code("\n".join(st.session_state.log_output))
349
+
350
+
351
+ # Show results
352
+ if st.session_state.last_result:
353
+ result = st.session_state.last_result
354
+
355
+ # Metrics
356
+ with metrics_placeholder.container():
357
+ eval_metrics = result.get('evaluation', {})
358
+
359
+ m1, m2, m3 = st.columns(3)
360
+ with m1:
361
+ completeness = eval_metrics.get('completeness', 0) * 100
362
+ st.metric("Completeness", f"{completeness:.1f}%")
363
+ with m2:
364
+ signal_cov = eval_metrics.get('interface_signal_coverage', 0) * 100
365
+ st.metric("Signal Coverage", f"{signal_cov:.1f}%")
366
+ with m3:
367
+ reg_cov = eval_metrics.get('register_coverage', 0) * 100
368
+ st.metric("Register Coverage", f"{reg_cov:.1f}%")
369
+
370
+ m4, m5 = st.columns(2)
371
+ with m4:
372
+ st.metric("Files Generated", len(st.session_state.generated_files))
373
+ with m5:
374
+ st.metric("Iterations", result.get('auto_train_iterations', 0))
375
+
376
+ # Files list
377
+ with files_placeholder.expander("πŸ“„ Generated Files", expanded=True):
378
+ if st.session_state.generated_files:
379
+ # File selector
380
+ file_names = sorted(st.session_state.generated_files.keys())
381
+ selected_file = st.selectbox("Select file to preview", file_names)
382
+
383
+ if selected_file:
384
+ file_path = st.session_state.generated_files[selected_file]
385
+ if os.path.exists(file_path):
386
+ try:
387
+ with open(file_path, 'r', encoding='utf-8') as f:
388
+ content = f.read()
389
+ st.code(content, language='systemverilog')
390
+ except Exception as e:
391
+ st.warning(f"Could not read file: {e}")
392
+
393
+ # Download ZIP
394
+ if st.session_state.generated_files:
395
+ zip_buffer = io.BytesIO()
396
+
397
+ with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zipf:
398
+ for name, path in st.session_state.generated_files.items():
399
+ if os.path.exists(path):
400
+ zipf.write(path, arcname=name)
401
+
402
+ zip_buffer.seek(0)
403
+
404
+ st.download_button(
405
+ label="πŸ“₯ Download All Files as ZIP",
406
+ data=zip_buffer,
407
+ file_name=f"{design_name}_uvm_testbench.zip",
408
+ mime="application/zip",
409
+ use_container_width=True,
410
+ type="secondary"
411
+ )
412
+
413
+
414
+ # Footer
415
+ st.divider()
416
+ st.caption("""
417
+ **UVM Testbench Generator** β€’ AI-Powered by Sai Kumar Taraka
418
+ Protocol Libraries: UART, SPI, I2C, AXI4-Lite, APB, Wishbone β€’ Coverage-Driven Auto-Training
419
+ """)