oscura 0.5.0__py3-none-any.whl → 0.5.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oscura/__init__.py +1 -1
- oscura/analyzers/digital/__init__.py +0 -48
- oscura/analyzers/digital/extraction.py +0 -195
- oscura/analyzers/protocols/__init__.py +1 -22
- oscura/automotive/__init__.py +1 -1
- oscura/automotive/dtc/data.json +2763 -0
- oscura/export/__init__.py +0 -12
- oscura/export/wireshark/README.md +15 -15
- oscura/exporters/json_export.py +0 -47
- oscura/inference/active_learning/README.md +7 -7
- oscura/pipeline/composition.py +10 -2
- oscura/reporting/__init__.py +0 -7
- oscura/reporting/templates/index.md +13 -13
- oscura/schemas/bus_configuration.json +322 -0
- oscura/schemas/device_mapping.json +182 -0
- oscura/schemas/packet_format.json +418 -0
- oscura/schemas/protocol_definition.json +363 -0
- oscura/utils/autodetect.py +1 -5
- oscura-0.5.1.dist-info/METADATA +583 -0
- {oscura-0.5.0.dist-info → oscura-0.5.1.dist-info}/RECORD +23 -28
- oscura/analyzers/digital/ic_database.py +0 -498
- oscura/analyzers/digital/timing_paths.py +0 -339
- oscura/analyzers/digital/vintage.py +0 -377
- oscura/analyzers/digital/vintage_result.py +0 -148
- oscura/analyzers/protocols/parallel_bus.py +0 -449
- oscura/export/wavedrom.py +0 -430
- oscura/exporters/vintage_logic_csv.py +0 -247
- oscura/reporting/vintage_logic_report.py +0 -523
- oscura/visualization/digital_advanced.py +0 -718
- oscura/visualization/figure_manager.py +0 -156
- oscura-0.5.0.dist-info/METADATA +0 -407
- {oscura-0.5.0.dist-info → oscura-0.5.1.dist-info}/WHEEL +0 -0
- {oscura-0.5.0.dist-info → oscura-0.5.1.dist-info}/entry_points.txt +0 -0
- {oscura-0.5.0.dist-info → oscura-0.5.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,377 +0,0 @@
|
|
|
1
|
-
"""High-level vintage logic analysis API.
|
|
2
|
-
|
|
3
|
-
This module provides a unified interface for complete vintage logic system analysis,
|
|
4
|
-
orchestrating all analysis steps and returning consolidated results.
|
|
5
|
-
|
|
6
|
-
Example:
|
|
7
|
-
>>> from oscura.analyzers.digital.vintage import analyze_vintage_logic
|
|
8
|
-
>>> result = analyze_vintage_logic(
|
|
9
|
-
... traces={"CLK": clk_trace, "DATA": data_trace},
|
|
10
|
-
... target_frequency=2e6
|
|
11
|
-
... )
|
|
12
|
-
>>> print(f"Detected: {result.detected_family}")
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
from __future__ import annotations
|
|
16
|
-
|
|
17
|
-
import time
|
|
18
|
-
from datetime import datetime
|
|
19
|
-
from typing import TYPE_CHECKING, Any, cast
|
|
20
|
-
|
|
21
|
-
import numpy as np
|
|
22
|
-
|
|
23
|
-
from oscura.analyzers.digital.extraction import (
|
|
24
|
-
LOGIC_FAMILIES,
|
|
25
|
-
detect_logic_family,
|
|
26
|
-
detect_open_collector,
|
|
27
|
-
)
|
|
28
|
-
from oscura.analyzers.digital.ic_database import identify_ic, validate_ic_timing
|
|
29
|
-
from oscura.analyzers.digital.timing import hold_time, propagation_delay, setup_time
|
|
30
|
-
from oscura.analyzers.digital.timing_paths import TimingPathResult, analyze_timing_path
|
|
31
|
-
from oscura.analyzers.digital.vintage_result import (
|
|
32
|
-
BOMEntry,
|
|
33
|
-
ICIdentificationResult,
|
|
34
|
-
ModernReplacementIC,
|
|
35
|
-
VintageLogicAnalysisResult,
|
|
36
|
-
)
|
|
37
|
-
from oscura.core.types import WaveformTrace
|
|
38
|
-
|
|
39
|
-
if TYPE_CHECKING:
|
|
40
|
-
from oscura.core.types import DigitalTrace, WaveformTrace
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
# Modern IC replacement recommendations
|
|
44
|
-
REPLACEMENT_DATABASE: dict[str, ModernReplacementIC] = {
|
|
45
|
-
"7400": ModernReplacementIC(
|
|
46
|
-
original_ic="7400",
|
|
47
|
-
replacement_ic="74HCT00",
|
|
48
|
-
family="74HCTxx",
|
|
49
|
-
benefits=["Lower power", "Wider voltage range", "TTL-compatible inputs"],
|
|
50
|
-
notes="HCT family maintains TTL compatibility with CMOS benefits",
|
|
51
|
-
),
|
|
52
|
-
"7474": ModernReplacementIC(
|
|
53
|
-
original_ic="7474",
|
|
54
|
-
replacement_ic="74HCT74",
|
|
55
|
-
family="74HCTxx",
|
|
56
|
-
benefits=["Lower power", "Wider voltage range", "TTL-compatible inputs"],
|
|
57
|
-
notes="HCT family maintains TTL compatibility with CMOS benefits",
|
|
58
|
-
),
|
|
59
|
-
"74LS00": ModernReplacementIC(
|
|
60
|
-
original_ic="74LS00",
|
|
61
|
-
replacement_ic="74HCT00",
|
|
62
|
-
family="74HCTxx",
|
|
63
|
-
benefits=["Lower power", "Similar speed", "Better availability"],
|
|
64
|
-
notes="Direct pin-compatible replacement",
|
|
65
|
-
),
|
|
66
|
-
"74LS74": ModernReplacementIC(
|
|
67
|
-
original_ic="74LS74",
|
|
68
|
-
replacement_ic="74HCT74",
|
|
69
|
-
family="74HCTxx",
|
|
70
|
-
benefits=["Lower power", "Similar speed", "Better availability"],
|
|
71
|
-
notes="Direct pin-compatible replacement",
|
|
72
|
-
),
|
|
73
|
-
"74LS138": ModernReplacementIC(
|
|
74
|
-
original_ic="74LS138",
|
|
75
|
-
replacement_ic="74HCT138",
|
|
76
|
-
family="74HCTxx",
|
|
77
|
-
benefits=["Lower power", "Similar speed", "Better availability"],
|
|
78
|
-
notes="Direct pin-compatible replacement",
|
|
79
|
-
),
|
|
80
|
-
"74LS244": ModernReplacementIC(
|
|
81
|
-
original_ic="74LS244",
|
|
82
|
-
replacement_ic="74HCT244",
|
|
83
|
-
family="74HCTxx",
|
|
84
|
-
benefits=["Lower power", "Similar speed", "Better availability"],
|
|
85
|
-
notes="Direct pin-compatible replacement",
|
|
86
|
-
),
|
|
87
|
-
"74LS245": ModernReplacementIC(
|
|
88
|
-
original_ic="74LS245",
|
|
89
|
-
replacement_ic="74HCT245",
|
|
90
|
-
family="74HCTxx",
|
|
91
|
-
benefits=["Lower power", "Similar speed", "Better availability"],
|
|
92
|
-
notes="Direct pin-compatible replacement",
|
|
93
|
-
),
|
|
94
|
-
"74LS273": ModernReplacementIC(
|
|
95
|
-
original_ic="74LS273",
|
|
96
|
-
replacement_ic="74HCT273",
|
|
97
|
-
family="74HCTxx",
|
|
98
|
-
benefits=["Lower power", "Similar speed", "Better availability"],
|
|
99
|
-
notes="Direct pin-compatible replacement",
|
|
100
|
-
),
|
|
101
|
-
"74LS374": ModernReplacementIC(
|
|
102
|
-
original_ic="74LS374",
|
|
103
|
-
replacement_ic="74HCT374",
|
|
104
|
-
family="74HCTxx",
|
|
105
|
-
benefits=["Lower power", "Similar speed", "Better availability"],
|
|
106
|
-
notes="Direct pin-compatible replacement",
|
|
107
|
-
),
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
def analyze_vintage_logic(
|
|
112
|
-
traces: dict[str, WaveformTrace | DigitalTrace],
|
|
113
|
-
*,
|
|
114
|
-
target_frequency: float | None = None,
|
|
115
|
-
system_description: str | None = None,
|
|
116
|
-
enable_protocol_decode: bool = False,
|
|
117
|
-
timing_paths: list[tuple[str, WaveformTrace, WaveformTrace]] | None = None,
|
|
118
|
-
) -> VintageLogicAnalysisResult:
|
|
119
|
-
"""Complete vintage logic system analysis.
|
|
120
|
-
|
|
121
|
-
High-level API that orchestrates all vintage logic analysis steps and returns
|
|
122
|
-
a comprehensive result object suitable for reporting and export.
|
|
123
|
-
|
|
124
|
-
Args:
|
|
125
|
-
traces: Dictionary mapping channel names to traces.
|
|
126
|
-
target_frequency: Target system clock frequency in Hz.
|
|
127
|
-
system_description: Optional description for documentation.
|
|
128
|
-
enable_protocol_decode: Enable automatic protocol decoding (GPIB, ISA, etc.).
|
|
129
|
-
timing_paths: Optional list of (ic_name, input_trace, output_trace) tuples
|
|
130
|
-
for multi-IC timing path analysis.
|
|
131
|
-
|
|
132
|
-
Returns:
|
|
133
|
-
VintageLogicAnalysisResult object with complete analysis data.
|
|
134
|
-
|
|
135
|
-
Example:
|
|
136
|
-
>>> result = analyze_vintage_logic(
|
|
137
|
-
... traces={"CLK": clk_trace, "DATA": data_trace},
|
|
138
|
-
... target_frequency=2e6,
|
|
139
|
-
... system_description="1976 Microcomputer System"
|
|
140
|
-
... )
|
|
141
|
-
>>> print(f"Detected: {result.detected_family}")
|
|
142
|
-
>>> print(f"ICs: {[ic.ic_name for ic in result.identified_ics]}")
|
|
143
|
-
"""
|
|
144
|
-
start_time = time.time()
|
|
145
|
-
warnings: list[str] = []
|
|
146
|
-
confidence_scores: dict[str, float] = {}
|
|
147
|
-
|
|
148
|
-
# Use first trace for logic family detection
|
|
149
|
-
first_trace_name = next(iter(traces.keys()))
|
|
150
|
-
first_trace = traces[first_trace_name]
|
|
151
|
-
|
|
152
|
-
# Ensure we have a WaveformTrace for voltage-based analysis
|
|
153
|
-
if not hasattr(first_trace.data, "dtype") or first_trace.data.dtype == bool:
|
|
154
|
-
warnings.append(
|
|
155
|
-
f"Digital trace provided for {first_trace_name}, "
|
|
156
|
-
"logic family detection may be inaccurate"
|
|
157
|
-
)
|
|
158
|
-
detected_family = "unknown"
|
|
159
|
-
family_confidence = 0.0
|
|
160
|
-
voltage_levels = {}
|
|
161
|
-
else:
|
|
162
|
-
# Step 1: Detect logic family
|
|
163
|
-
# Type narrowing: we've verified this is a WaveformTrace above
|
|
164
|
-
waveform_trace = cast("WaveformTrace", first_trace)
|
|
165
|
-
detected_family, family_confidence = detect_logic_family(waveform_trace)
|
|
166
|
-
confidence_scores["logic_family"] = family_confidence
|
|
167
|
-
|
|
168
|
-
# Get voltage levels from detected family
|
|
169
|
-
if detected_family in LOGIC_FAMILIES:
|
|
170
|
-
voltage_levels = dict(LOGIC_FAMILIES[detected_family])
|
|
171
|
-
else:
|
|
172
|
-
voltage_levels = {}
|
|
173
|
-
warnings.append(f"Unknown logic family: {detected_family}")
|
|
174
|
-
|
|
175
|
-
# Step 2: Detect open-collector outputs
|
|
176
|
-
open_collector_detected = False
|
|
177
|
-
asymmetry_ratio = 1.0
|
|
178
|
-
if hasattr(first_trace.data, "dtype") and first_trace.data.dtype != bool:
|
|
179
|
-
waveform_trace = cast("WaveformTrace", first_trace)
|
|
180
|
-
open_collector_detected, asymmetry_ratio = detect_open_collector(waveform_trace)
|
|
181
|
-
if open_collector_detected:
|
|
182
|
-
warnings.append(
|
|
183
|
-
"Open-collector output detected - consider 10kΩ pull-up in modern design"
|
|
184
|
-
)
|
|
185
|
-
|
|
186
|
-
# Step 3: Measure timing parameters and identify ICs
|
|
187
|
-
identified_ics: list[ICIdentificationResult] = []
|
|
188
|
-
timing_measurements: dict[str, float] = {}
|
|
189
|
-
|
|
190
|
-
# Analyze each trace pair for timing
|
|
191
|
-
trace_list = list(traces.items())
|
|
192
|
-
for i in range(len(trace_list) - 1):
|
|
193
|
-
name1, trace1 = trace_list[i]
|
|
194
|
-
name2, trace2 = trace_list[i + 1]
|
|
195
|
-
|
|
196
|
-
# Measure propagation delay
|
|
197
|
-
try:
|
|
198
|
-
t_pd_raw = propagation_delay(trace1, trace2)
|
|
199
|
-
t_pd = (
|
|
200
|
-
float(t_pd_raw)
|
|
201
|
-
if isinstance(t_pd_raw, (int, float, np.number))
|
|
202
|
-
else float(t_pd_raw.item())
|
|
203
|
-
)
|
|
204
|
-
if t_pd > 0:
|
|
205
|
-
timing_measurements[f"{name1}→{name2}_t_pd"] = t_pd
|
|
206
|
-
except Exception as e:
|
|
207
|
-
warnings.append(f"Failed to measure propagation delay {name1}→{name2}: {e}")
|
|
208
|
-
|
|
209
|
-
# Measure setup and hold times if clock-like signal
|
|
210
|
-
try:
|
|
211
|
-
t_su_raw = setup_time(trace1, trace2)
|
|
212
|
-
t_su = (
|
|
213
|
-
float(t_su_raw)
|
|
214
|
-
if isinstance(t_su_raw, (int, float, np.number))
|
|
215
|
-
else float(t_su_raw.item())
|
|
216
|
-
)
|
|
217
|
-
if t_su > 0:
|
|
218
|
-
timing_measurements[f"{name2}_t_su"] = t_su
|
|
219
|
-
except Exception:
|
|
220
|
-
pass # Optional measurement
|
|
221
|
-
|
|
222
|
-
try:
|
|
223
|
-
t_h_raw = hold_time(trace1, trace2)
|
|
224
|
-
t_h = (
|
|
225
|
-
float(t_h_raw)
|
|
226
|
-
if isinstance(t_h_raw, (int, float, np.number))
|
|
227
|
-
else float(t_h_raw.item())
|
|
228
|
-
)
|
|
229
|
-
if t_h > 0:
|
|
230
|
-
timing_measurements[f"{name2}_t_h"] = t_h
|
|
231
|
-
except Exception:
|
|
232
|
-
pass # Optional measurement
|
|
233
|
-
|
|
234
|
-
# Attempt IC identification from timing measurements
|
|
235
|
-
if timing_measurements:
|
|
236
|
-
# Extract core timing parameters
|
|
237
|
-
core_params = {}
|
|
238
|
-
for key, value in timing_measurements.items():
|
|
239
|
-
if "_t_pd" in key:
|
|
240
|
-
core_params["t_pd"] = value
|
|
241
|
-
elif "_t_su" in key and "t_su" not in core_params:
|
|
242
|
-
core_params["t_su"] = value
|
|
243
|
-
elif "_t_h" in key and "t_h" not in core_params:
|
|
244
|
-
core_params["t_h"] = value
|
|
245
|
-
|
|
246
|
-
if core_params:
|
|
247
|
-
ic_name, ic_confidence = identify_ic(core_params, tolerance=0.5)
|
|
248
|
-
confidence_scores["ic_identification"] = ic_confidence
|
|
249
|
-
|
|
250
|
-
if ic_name != "unknown":
|
|
251
|
-
# Validate against database
|
|
252
|
-
try:
|
|
253
|
-
validation = validate_ic_timing(ic_name, core_params, tolerance=0.3)
|
|
254
|
-
|
|
255
|
-
identified_ics.append(
|
|
256
|
-
ICIdentificationResult(
|
|
257
|
-
ic_name=ic_name,
|
|
258
|
-
confidence=ic_confidence,
|
|
259
|
-
timing_params=core_params,
|
|
260
|
-
validation=validation,
|
|
261
|
-
family=detected_family,
|
|
262
|
-
)
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
# Check if any parameters fail validation
|
|
266
|
-
failed_params = [k for k, v in validation.items() if v.get("passes") is False]
|
|
267
|
-
if failed_params:
|
|
268
|
-
warnings.append(
|
|
269
|
-
f"IC {ic_name} timing validation failed for: {', '.join(failed_params)}"
|
|
270
|
-
)
|
|
271
|
-
except KeyError:
|
|
272
|
-
warnings.append(f"IC {ic_name} not found in database")
|
|
273
|
-
|
|
274
|
-
# Step 4: Analyze timing paths if provided
|
|
275
|
-
timing_path_results: list[TimingPathResult] | None = None
|
|
276
|
-
if timing_paths:
|
|
277
|
-
try:
|
|
278
|
-
path_result = analyze_timing_path(timing_paths, target_frequency=target_frequency)
|
|
279
|
-
timing_path_results = [path_result]
|
|
280
|
-
|
|
281
|
-
if not path_result.meets_timing:
|
|
282
|
-
warnings.append(
|
|
283
|
-
f"Timing path violation detected at stage {path_result.critical_stage_idx}"
|
|
284
|
-
)
|
|
285
|
-
except Exception as e:
|
|
286
|
-
warnings.append(f"Timing path analysis failed: {e}")
|
|
287
|
-
|
|
288
|
-
# Step 5: Protocol decoding (if enabled)
|
|
289
|
-
decoded_protocols: dict[str, list[Any]] | None = None
|
|
290
|
-
if enable_protocol_decode:
|
|
291
|
-
# Protocol decoding would be implemented here
|
|
292
|
-
# For now, just a placeholder
|
|
293
|
-
decoded_protocols = {}
|
|
294
|
-
|
|
295
|
-
# Step 6: Generate modern replacement recommendations
|
|
296
|
-
modern_replacements: list[ModernReplacementIC] = []
|
|
297
|
-
for ic_result in identified_ics:
|
|
298
|
-
if ic_result.ic_name in REPLACEMENT_DATABASE:
|
|
299
|
-
modern_replacements.append(REPLACEMENT_DATABASE[ic_result.ic_name])
|
|
300
|
-
|
|
301
|
-
# Step 7: Generate BOM
|
|
302
|
-
bom: list[BOMEntry] = []
|
|
303
|
-
|
|
304
|
-
# Add identified ICs
|
|
305
|
-
for ic_result in identified_ics:
|
|
306
|
-
bom.append(
|
|
307
|
-
BOMEntry(
|
|
308
|
-
part_number=ic_result.ic_name,
|
|
309
|
-
description=f"Original IC from {detected_family} family",
|
|
310
|
-
quantity=1,
|
|
311
|
-
category="IC",
|
|
312
|
-
notes=f"Confidence: {ic_result.confidence * 100:.1f}%",
|
|
313
|
-
)
|
|
314
|
-
)
|
|
315
|
-
|
|
316
|
-
# Add modern replacements
|
|
317
|
-
for replacement in modern_replacements:
|
|
318
|
-
bom.append(
|
|
319
|
-
BOMEntry(
|
|
320
|
-
part_number=replacement.replacement_ic,
|
|
321
|
-
description=f"Modern replacement for {replacement.original_ic}",
|
|
322
|
-
quantity=1,
|
|
323
|
-
category="IC",
|
|
324
|
-
notes=f"Benefits: {', '.join(replacement.benefits)}",
|
|
325
|
-
)
|
|
326
|
-
)
|
|
327
|
-
|
|
328
|
-
# Add supporting components
|
|
329
|
-
if open_collector_detected:
|
|
330
|
-
bom.append(
|
|
331
|
-
BOMEntry(
|
|
332
|
-
part_number="Pull-up resistor",
|
|
333
|
-
description="10kΩ resistor for open-collector pull-up",
|
|
334
|
-
quantity=len(list(traces.values())),
|
|
335
|
-
category="Resistor",
|
|
336
|
-
notes="Use for all open-collector outputs",
|
|
337
|
-
)
|
|
338
|
-
)
|
|
339
|
-
|
|
340
|
-
# Add decoupling capacitors (good practice)
|
|
341
|
-
bom.append(
|
|
342
|
-
BOMEntry(
|
|
343
|
-
part_number="0.1µF ceramic capacitor",
|
|
344
|
-
description="Decoupling capacitor",
|
|
345
|
-
quantity=len(identified_ics) * 2,
|
|
346
|
-
category="Capacitor",
|
|
347
|
-
notes="One per IC, place close to VCC/GND pins",
|
|
348
|
-
)
|
|
349
|
-
)
|
|
350
|
-
|
|
351
|
-
# Calculate analysis duration
|
|
352
|
-
analysis_duration = time.time() - start_time
|
|
353
|
-
|
|
354
|
-
return VintageLogicAnalysisResult(
|
|
355
|
-
timestamp=datetime.now(),
|
|
356
|
-
source_file=system_description,
|
|
357
|
-
analysis_duration=analysis_duration,
|
|
358
|
-
detected_family=detected_family,
|
|
359
|
-
family_confidence=family_confidence,
|
|
360
|
-
voltage_levels=voltage_levels,
|
|
361
|
-
identified_ics=identified_ics,
|
|
362
|
-
timing_measurements=timing_measurements,
|
|
363
|
-
timing_paths=timing_path_results,
|
|
364
|
-
decoded_protocols=decoded_protocols,
|
|
365
|
-
open_collector_detected=open_collector_detected,
|
|
366
|
-
asymmetry_ratio=asymmetry_ratio,
|
|
367
|
-
modern_replacements=modern_replacements,
|
|
368
|
-
bom=bom,
|
|
369
|
-
warnings=warnings,
|
|
370
|
-
confidence_scores=confidence_scores,
|
|
371
|
-
)
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
__all__ = [
|
|
375
|
-
"REPLACEMENT_DATABASE",
|
|
376
|
-
"analyze_vintage_logic",
|
|
377
|
-
]
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
"""Vintage logic analysis result data structures.
|
|
2
|
-
|
|
3
|
-
This module defines dataclasses for aggregating vintage logic analysis results,
|
|
4
|
-
enabling comprehensive reporting and export capabilities.
|
|
5
|
-
|
|
6
|
-
Example:
|
|
7
|
-
>>> from oscura.analyzers.digital.vintage_result import VintageLogicAnalysisResult
|
|
8
|
-
>>> result = VintageLogicAnalysisResult(
|
|
9
|
-
... timestamp=datetime.now(),
|
|
10
|
-
... detected_family="TTL",
|
|
11
|
-
... family_confidence=0.95,
|
|
12
|
-
... # ... more fields ...
|
|
13
|
-
... )
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
from __future__ import annotations
|
|
17
|
-
|
|
18
|
-
from dataclasses import dataclass, field
|
|
19
|
-
from datetime import datetime
|
|
20
|
-
from typing import TYPE_CHECKING, Any
|
|
21
|
-
|
|
22
|
-
if TYPE_CHECKING:
|
|
23
|
-
from oscura.analyzers.digital.timing_paths import TimingPathResult
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
@dataclass
|
|
27
|
-
class ICIdentificationResult:
|
|
28
|
-
"""Single IC identification result.
|
|
29
|
-
|
|
30
|
-
Attributes:
|
|
31
|
-
ic_name: Identified IC part number (e.g., "74LS74").
|
|
32
|
-
confidence: Confidence score (0.0-1.0).
|
|
33
|
-
timing_params: Measured timing parameters in seconds.
|
|
34
|
-
validation: Validation results from validate_ic_timing().
|
|
35
|
-
family: Logic family of the IC.
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
ic_name: str
|
|
39
|
-
confidence: float
|
|
40
|
-
timing_params: dict[str, float]
|
|
41
|
-
validation: dict[str, dict[str, Any]]
|
|
42
|
-
family: str
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
@dataclass
|
|
46
|
-
class ModernReplacementIC:
|
|
47
|
-
"""Modern IC recommendation for vintage part.
|
|
48
|
-
|
|
49
|
-
Attributes:
|
|
50
|
-
original_ic: Original vintage IC part number.
|
|
51
|
-
replacement_ic: Recommended modern replacement.
|
|
52
|
-
family: Replacement logic family (e.g., "74HCTxx").
|
|
53
|
-
benefits: List of benefits (speed, power, availability).
|
|
54
|
-
notes: Optional additional notes.
|
|
55
|
-
"""
|
|
56
|
-
|
|
57
|
-
original_ic: str
|
|
58
|
-
replacement_ic: str
|
|
59
|
-
family: str
|
|
60
|
-
benefits: list[str]
|
|
61
|
-
notes: str | None = None
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
@dataclass
|
|
65
|
-
class BOMEntry:
|
|
66
|
-
"""Bill of materials entry.
|
|
67
|
-
|
|
68
|
-
Attributes:
|
|
69
|
-
part_number: Component part number.
|
|
70
|
-
description: Component description.
|
|
71
|
-
quantity: Number of components needed.
|
|
72
|
-
category: Component category ("IC", "Capacitor", "Buffer", etc.).
|
|
73
|
-
notes: Optional notes (pinout, alternatives, etc.).
|
|
74
|
-
"""
|
|
75
|
-
|
|
76
|
-
part_number: str
|
|
77
|
-
description: str
|
|
78
|
-
quantity: int
|
|
79
|
-
category: str
|
|
80
|
-
notes: str | None = None
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
@dataclass
|
|
84
|
-
class VintageLogicAnalysisResult:
|
|
85
|
-
"""Complete vintage logic analysis result.
|
|
86
|
-
|
|
87
|
-
Aggregates all analysis outputs for comprehensive reporting and export.
|
|
88
|
-
|
|
89
|
-
Attributes:
|
|
90
|
-
timestamp: Analysis timestamp.
|
|
91
|
-
source_file: Source file path if loaded from file.
|
|
92
|
-
analysis_duration: Analysis execution time in seconds.
|
|
93
|
-
detected_family: Detected logic family name.
|
|
94
|
-
family_confidence: Logic family detection confidence (0.0-1.0).
|
|
95
|
-
voltage_levels: Measured voltage levels (VCC, VIL, VIH, VOL, VOH).
|
|
96
|
-
identified_ics: List of identified ICs.
|
|
97
|
-
timing_measurements: Dictionary of timing measurements in seconds.
|
|
98
|
-
timing_paths: Multi-IC timing path analysis results.
|
|
99
|
-
decoded_protocols: Protocol decoder results if applicable.
|
|
100
|
-
open_collector_detected: Whether open-collector output detected.
|
|
101
|
-
asymmetry_ratio: Rise/fall time asymmetry ratio.
|
|
102
|
-
modern_replacements: List of modern IC recommendations.
|
|
103
|
-
bom: Bill of materials entries.
|
|
104
|
-
warnings: List of warning messages.
|
|
105
|
-
confidence_scores: Dictionary of confidence scores by analysis type.
|
|
106
|
-
"""
|
|
107
|
-
|
|
108
|
-
# Analysis metadata
|
|
109
|
-
timestamp: datetime
|
|
110
|
-
source_file: str | None
|
|
111
|
-
analysis_duration: float
|
|
112
|
-
|
|
113
|
-
# Logic family detection results
|
|
114
|
-
detected_family: str
|
|
115
|
-
family_confidence: float
|
|
116
|
-
voltage_levels: dict[str, float] # VCC, VIL, VIH, VOL, VOH
|
|
117
|
-
|
|
118
|
-
# IC identification results
|
|
119
|
-
identified_ics: list[ICIdentificationResult] = field(default_factory=list)
|
|
120
|
-
|
|
121
|
-
# Timing measurements
|
|
122
|
-
timing_measurements: dict[str, float] = field(default_factory=dict)
|
|
123
|
-
|
|
124
|
-
# Multi-IC path analysis
|
|
125
|
-
timing_paths: list[TimingPathResult] | None = None
|
|
126
|
-
|
|
127
|
-
# Protocol decoder results (if applicable)
|
|
128
|
-
decoded_protocols: dict[str, list[Any]] | None = None
|
|
129
|
-
|
|
130
|
-
# Open-collector detection
|
|
131
|
-
open_collector_detected: bool = False
|
|
132
|
-
asymmetry_ratio: float = 1.0
|
|
133
|
-
|
|
134
|
-
# Recommendations
|
|
135
|
-
modern_replacements: list[ModernReplacementIC] = field(default_factory=list)
|
|
136
|
-
bom: list[BOMEntry] = field(default_factory=list)
|
|
137
|
-
|
|
138
|
-
# Quality metrics
|
|
139
|
-
warnings: list[str] = field(default_factory=list)
|
|
140
|
-
confidence_scores: dict[str, float] = field(default_factory=dict)
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
__all__ = [
|
|
144
|
-
"BOMEntry",
|
|
145
|
-
"ICIdentificationResult",
|
|
146
|
-
"ModernReplacementIC",
|
|
147
|
-
"VintageLogicAnalysisResult",
|
|
148
|
-
]
|