oscura 0.5.0__py3-none-any.whl → 0.6.0__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.
Files changed (513) hide show
  1. oscura/__init__.py +169 -167
  2. oscura/analyzers/__init__.py +3 -0
  3. oscura/analyzers/classification.py +659 -0
  4. oscura/analyzers/digital/__init__.py +0 -48
  5. oscura/analyzers/digital/edges.py +325 -65
  6. oscura/analyzers/digital/extraction.py +0 -195
  7. oscura/analyzers/digital/quality.py +293 -166
  8. oscura/analyzers/digital/timing.py +260 -115
  9. oscura/analyzers/digital/timing_numba.py +334 -0
  10. oscura/analyzers/entropy.py +605 -0
  11. oscura/analyzers/eye/diagram.py +176 -109
  12. oscura/analyzers/eye/metrics.py +5 -5
  13. oscura/analyzers/jitter/__init__.py +6 -4
  14. oscura/analyzers/jitter/ber.py +52 -52
  15. oscura/analyzers/jitter/classification.py +156 -0
  16. oscura/analyzers/jitter/decomposition.py +163 -113
  17. oscura/analyzers/jitter/spectrum.py +80 -64
  18. oscura/analyzers/ml/__init__.py +39 -0
  19. oscura/analyzers/ml/features.py +600 -0
  20. oscura/analyzers/ml/signal_classifier.py +604 -0
  21. oscura/analyzers/packet/daq.py +246 -158
  22. oscura/analyzers/packet/parser.py +12 -1
  23. oscura/analyzers/packet/payload.py +50 -2110
  24. oscura/analyzers/packet/payload_analysis.py +361 -181
  25. oscura/analyzers/packet/payload_patterns.py +133 -70
  26. oscura/analyzers/packet/stream.py +84 -23
  27. oscura/analyzers/patterns/__init__.py +26 -5
  28. oscura/analyzers/patterns/anomaly_detection.py +908 -0
  29. oscura/analyzers/patterns/clustering.py +169 -108
  30. oscura/analyzers/patterns/clustering_optimized.py +227 -0
  31. oscura/analyzers/patterns/discovery.py +1 -1
  32. oscura/analyzers/patterns/matching.py +581 -197
  33. oscura/analyzers/patterns/pattern_mining.py +778 -0
  34. oscura/analyzers/patterns/periodic.py +121 -38
  35. oscura/analyzers/patterns/sequences.py +175 -78
  36. oscura/analyzers/power/conduction.py +1 -1
  37. oscura/analyzers/power/soa.py +6 -6
  38. oscura/analyzers/power/switching.py +250 -110
  39. oscura/analyzers/protocol/__init__.py +17 -1
  40. oscura/analyzers/protocols/__init__.py +1 -22
  41. oscura/analyzers/protocols/base.py +6 -6
  42. oscura/analyzers/protocols/ble/__init__.py +38 -0
  43. oscura/analyzers/protocols/ble/analyzer.py +809 -0
  44. oscura/analyzers/protocols/ble/uuids.py +288 -0
  45. oscura/analyzers/protocols/can.py +257 -127
  46. oscura/analyzers/protocols/can_fd.py +107 -80
  47. oscura/analyzers/protocols/flexray.py +139 -80
  48. oscura/analyzers/protocols/hdlc.py +93 -58
  49. oscura/analyzers/protocols/i2c.py +247 -106
  50. oscura/analyzers/protocols/i2s.py +138 -86
  51. oscura/analyzers/protocols/industrial/__init__.py +40 -0
  52. oscura/analyzers/protocols/industrial/bacnet/__init__.py +33 -0
  53. oscura/analyzers/protocols/industrial/bacnet/analyzer.py +708 -0
  54. oscura/analyzers/protocols/industrial/bacnet/encoding.py +412 -0
  55. oscura/analyzers/protocols/industrial/bacnet/services.py +622 -0
  56. oscura/analyzers/protocols/industrial/ethercat/__init__.py +30 -0
  57. oscura/analyzers/protocols/industrial/ethercat/analyzer.py +474 -0
  58. oscura/analyzers/protocols/industrial/ethercat/mailbox.py +339 -0
  59. oscura/analyzers/protocols/industrial/ethercat/topology.py +166 -0
  60. oscura/analyzers/protocols/industrial/modbus/__init__.py +31 -0
  61. oscura/analyzers/protocols/industrial/modbus/analyzer.py +525 -0
  62. oscura/analyzers/protocols/industrial/modbus/crc.py +79 -0
  63. oscura/analyzers/protocols/industrial/modbus/functions.py +436 -0
  64. oscura/analyzers/protocols/industrial/opcua/__init__.py +21 -0
  65. oscura/analyzers/protocols/industrial/opcua/analyzer.py +552 -0
  66. oscura/analyzers/protocols/industrial/opcua/datatypes.py +446 -0
  67. oscura/analyzers/protocols/industrial/opcua/services.py +264 -0
  68. oscura/analyzers/protocols/industrial/profinet/__init__.py +23 -0
  69. oscura/analyzers/protocols/industrial/profinet/analyzer.py +441 -0
  70. oscura/analyzers/protocols/industrial/profinet/dcp.py +263 -0
  71. oscura/analyzers/protocols/industrial/profinet/ptcp.py +200 -0
  72. oscura/analyzers/protocols/jtag.py +180 -98
  73. oscura/analyzers/protocols/lin.py +219 -114
  74. oscura/analyzers/protocols/manchester.py +4 -4
  75. oscura/analyzers/protocols/onewire.py +253 -149
  76. oscura/analyzers/protocols/parallel_bus/__init__.py +20 -0
  77. oscura/analyzers/protocols/parallel_bus/centronics.py +92 -0
  78. oscura/analyzers/protocols/parallel_bus/gpib.py +137 -0
  79. oscura/analyzers/protocols/spi.py +192 -95
  80. oscura/analyzers/protocols/swd.py +321 -167
  81. oscura/analyzers/protocols/uart.py +267 -125
  82. oscura/analyzers/protocols/usb.py +235 -131
  83. oscura/analyzers/side_channel/power.py +17 -12
  84. oscura/analyzers/signal/__init__.py +15 -0
  85. oscura/analyzers/signal/timing_analysis.py +1086 -0
  86. oscura/analyzers/signal_integrity/__init__.py +4 -1
  87. oscura/analyzers/signal_integrity/sparams.py +2 -19
  88. oscura/analyzers/spectral/chunked.py +129 -60
  89. oscura/analyzers/spectral/chunked_fft.py +300 -94
  90. oscura/analyzers/spectral/chunked_wavelet.py +100 -80
  91. oscura/analyzers/statistical/checksum.py +376 -217
  92. oscura/analyzers/statistical/classification.py +229 -107
  93. oscura/analyzers/statistical/entropy.py +78 -53
  94. oscura/analyzers/statistics/correlation.py +407 -211
  95. oscura/analyzers/statistics/outliers.py +2 -2
  96. oscura/analyzers/statistics/streaming.py +30 -5
  97. oscura/analyzers/validation.py +216 -101
  98. oscura/analyzers/waveform/measurements.py +9 -0
  99. oscura/analyzers/waveform/measurements_with_uncertainty.py +31 -15
  100. oscura/analyzers/waveform/spectral.py +500 -228
  101. oscura/api/__init__.py +31 -5
  102. oscura/api/dsl/__init__.py +582 -0
  103. oscura/{dsl → api/dsl}/commands.py +43 -76
  104. oscura/{dsl → api/dsl}/interpreter.py +26 -51
  105. oscura/{dsl → api/dsl}/parser.py +107 -77
  106. oscura/{dsl → api/dsl}/repl.py +2 -2
  107. oscura/api/dsl.py +1 -1
  108. oscura/{integrations → api/integrations}/__init__.py +1 -1
  109. oscura/{integrations → api/integrations}/llm.py +201 -102
  110. oscura/api/operators.py +3 -3
  111. oscura/api/optimization.py +144 -30
  112. oscura/api/rest_server.py +921 -0
  113. oscura/api/server/__init__.py +17 -0
  114. oscura/api/server/dashboard.py +850 -0
  115. oscura/api/server/static/README.md +34 -0
  116. oscura/api/server/templates/base.html +181 -0
  117. oscura/api/server/templates/export.html +120 -0
  118. oscura/api/server/templates/home.html +284 -0
  119. oscura/api/server/templates/protocols.html +58 -0
  120. oscura/api/server/templates/reports.html +43 -0
  121. oscura/api/server/templates/session_detail.html +89 -0
  122. oscura/api/server/templates/sessions.html +83 -0
  123. oscura/api/server/templates/waveforms.html +73 -0
  124. oscura/automotive/__init__.py +8 -1
  125. oscura/automotive/can/__init__.py +10 -0
  126. oscura/automotive/can/checksum.py +3 -1
  127. oscura/automotive/can/dbc_generator.py +590 -0
  128. oscura/automotive/can/message_wrapper.py +121 -74
  129. oscura/automotive/can/patterns.py +98 -21
  130. oscura/automotive/can/session.py +292 -56
  131. oscura/automotive/can/state_machine.py +6 -3
  132. oscura/automotive/can/stimulus_response.py +97 -75
  133. oscura/automotive/dbc/__init__.py +10 -2
  134. oscura/automotive/dbc/generator.py +84 -56
  135. oscura/automotive/dbc/parser.py +6 -6
  136. oscura/automotive/dtc/data.json +2763 -0
  137. oscura/automotive/dtc/database.py +2 -2
  138. oscura/automotive/flexray/__init__.py +31 -0
  139. oscura/automotive/flexray/analyzer.py +504 -0
  140. oscura/automotive/flexray/crc.py +185 -0
  141. oscura/automotive/flexray/fibex.py +449 -0
  142. oscura/automotive/j1939/__init__.py +45 -8
  143. oscura/automotive/j1939/analyzer.py +605 -0
  144. oscura/automotive/j1939/spns.py +326 -0
  145. oscura/automotive/j1939/transport.py +306 -0
  146. oscura/automotive/lin/__init__.py +47 -0
  147. oscura/automotive/lin/analyzer.py +612 -0
  148. oscura/automotive/loaders/blf.py +13 -2
  149. oscura/automotive/loaders/csv_can.py +143 -72
  150. oscura/automotive/loaders/dispatcher.py +50 -2
  151. oscura/automotive/loaders/mdf.py +86 -45
  152. oscura/automotive/loaders/pcap.py +111 -61
  153. oscura/automotive/uds/__init__.py +4 -0
  154. oscura/automotive/uds/analyzer.py +725 -0
  155. oscura/automotive/uds/decoder.py +140 -58
  156. oscura/automotive/uds/models.py +7 -1
  157. oscura/automotive/visualization.py +1 -1
  158. oscura/cli/analyze.py +348 -0
  159. oscura/cli/batch.py +142 -122
  160. oscura/cli/benchmark.py +275 -0
  161. oscura/cli/characterize.py +137 -82
  162. oscura/cli/compare.py +224 -131
  163. oscura/cli/completion.py +250 -0
  164. oscura/cli/config_cmd.py +361 -0
  165. oscura/cli/decode.py +164 -87
  166. oscura/cli/export.py +286 -0
  167. oscura/cli/main.py +115 -31
  168. oscura/{onboarding → cli/onboarding}/__init__.py +3 -3
  169. oscura/{onboarding → cli/onboarding}/help.py +80 -58
  170. oscura/{onboarding → cli/onboarding}/tutorials.py +97 -72
  171. oscura/{onboarding → cli/onboarding}/wizard.py +55 -36
  172. oscura/cli/progress.py +147 -0
  173. oscura/cli/shell.py +157 -135
  174. oscura/cli/validate_cmd.py +204 -0
  175. oscura/cli/visualize.py +158 -0
  176. oscura/convenience.py +125 -79
  177. oscura/core/__init__.py +4 -2
  178. oscura/core/backend_selector.py +3 -3
  179. oscura/core/cache.py +126 -15
  180. oscura/core/cancellation.py +1 -1
  181. oscura/{config → core/config}/__init__.py +20 -11
  182. oscura/{config → core/config}/defaults.py +1 -1
  183. oscura/{config → core/config}/loader.py +7 -5
  184. oscura/{config → core/config}/memory.py +5 -5
  185. oscura/{config → core/config}/migration.py +1 -1
  186. oscura/{config → core/config}/pipeline.py +99 -23
  187. oscura/{config → core/config}/preferences.py +1 -1
  188. oscura/{config → core/config}/protocol.py +3 -3
  189. oscura/{config → core/config}/schema.py +426 -272
  190. oscura/{config → core/config}/settings.py +1 -1
  191. oscura/{config → core/config}/thresholds.py +195 -153
  192. oscura/core/correlation.py +5 -6
  193. oscura/core/cross_domain.py +0 -2
  194. oscura/core/debug.py +9 -5
  195. oscura/{extensibility → core/extensibility}/docs.py +158 -70
  196. oscura/{extensibility → core/extensibility}/extensions.py +160 -76
  197. oscura/{extensibility → core/extensibility}/logging.py +1 -1
  198. oscura/{extensibility → core/extensibility}/measurements.py +1 -1
  199. oscura/{extensibility → core/extensibility}/plugins.py +1 -1
  200. oscura/{extensibility → core/extensibility}/templates.py +73 -3
  201. oscura/{extensibility → core/extensibility}/validation.py +1 -1
  202. oscura/core/gpu_backend.py +11 -7
  203. oscura/core/log_query.py +101 -11
  204. oscura/core/logging.py +126 -54
  205. oscura/core/logging_advanced.py +5 -5
  206. oscura/core/memory_limits.py +108 -70
  207. oscura/core/memory_monitor.py +2 -2
  208. oscura/core/memory_progress.py +7 -7
  209. oscura/core/memory_warnings.py +1 -1
  210. oscura/core/numba_backend.py +13 -13
  211. oscura/{plugins → core/plugins}/__init__.py +9 -9
  212. oscura/{plugins → core/plugins}/base.py +7 -7
  213. oscura/{plugins → core/plugins}/cli.py +3 -3
  214. oscura/{plugins → core/plugins}/discovery.py +186 -106
  215. oscura/{plugins → core/plugins}/lifecycle.py +1 -1
  216. oscura/{plugins → core/plugins}/manager.py +7 -7
  217. oscura/{plugins → core/plugins}/registry.py +3 -3
  218. oscura/{plugins → core/plugins}/versioning.py +1 -1
  219. oscura/core/progress.py +16 -1
  220. oscura/core/provenance.py +8 -2
  221. oscura/{schemas → core/schemas}/__init__.py +2 -2
  222. oscura/core/schemas/bus_configuration.json +322 -0
  223. oscura/core/schemas/device_mapping.json +182 -0
  224. oscura/core/schemas/packet_format.json +418 -0
  225. oscura/core/schemas/protocol_definition.json +363 -0
  226. oscura/core/types.py +4 -0
  227. oscura/core/uncertainty.py +3 -3
  228. oscura/correlation/__init__.py +52 -0
  229. oscura/correlation/multi_protocol.py +811 -0
  230. oscura/discovery/auto_decoder.py +117 -35
  231. oscura/discovery/comparison.py +191 -86
  232. oscura/discovery/quality_validator.py +155 -68
  233. oscura/discovery/signal_detector.py +196 -79
  234. oscura/export/__init__.py +18 -20
  235. oscura/export/kaitai_struct.py +513 -0
  236. oscura/export/scapy_layer.py +801 -0
  237. oscura/export/wireshark/README.md +15 -15
  238. oscura/export/wireshark/generator.py +1 -1
  239. oscura/export/wireshark/templates/dissector.lua.j2 +2 -2
  240. oscura/export/wireshark_dissector.py +746 -0
  241. oscura/guidance/wizard.py +207 -111
  242. oscura/hardware/__init__.py +19 -0
  243. oscura/{acquisition → hardware/acquisition}/__init__.py +4 -4
  244. oscura/{acquisition → hardware/acquisition}/file.py +2 -2
  245. oscura/{acquisition → hardware/acquisition}/hardware.py +7 -7
  246. oscura/{acquisition → hardware/acquisition}/saleae.py +15 -12
  247. oscura/{acquisition → hardware/acquisition}/socketcan.py +1 -1
  248. oscura/{acquisition → hardware/acquisition}/streaming.py +2 -2
  249. oscura/{acquisition → hardware/acquisition}/synthetic.py +3 -3
  250. oscura/{acquisition → hardware/acquisition}/visa.py +33 -11
  251. oscura/hardware/firmware/__init__.py +29 -0
  252. oscura/hardware/firmware/pattern_recognition.py +874 -0
  253. oscura/hardware/hal_detector.py +736 -0
  254. oscura/hardware/security/__init__.py +37 -0
  255. oscura/hardware/security/side_channel_detector.py +1126 -0
  256. oscura/inference/__init__.py +4 -0
  257. oscura/inference/active_learning/README.md +7 -7
  258. oscura/inference/active_learning/observation_table.py +4 -1
  259. oscura/inference/alignment.py +216 -123
  260. oscura/inference/bayesian.py +113 -33
  261. oscura/inference/crc_reverse.py +101 -55
  262. oscura/inference/logic.py +6 -2
  263. oscura/inference/message_format.py +342 -183
  264. oscura/inference/protocol.py +95 -44
  265. oscura/inference/protocol_dsl.py +180 -82
  266. oscura/inference/signal_intelligence.py +1439 -706
  267. oscura/inference/spectral.py +99 -57
  268. oscura/inference/state_machine.py +810 -158
  269. oscura/inference/stream.py +270 -110
  270. oscura/iot/__init__.py +34 -0
  271. oscura/iot/coap/__init__.py +32 -0
  272. oscura/iot/coap/analyzer.py +668 -0
  273. oscura/iot/coap/options.py +212 -0
  274. oscura/iot/lorawan/__init__.py +21 -0
  275. oscura/iot/lorawan/crypto.py +206 -0
  276. oscura/iot/lorawan/decoder.py +801 -0
  277. oscura/iot/lorawan/mac_commands.py +341 -0
  278. oscura/iot/mqtt/__init__.py +27 -0
  279. oscura/iot/mqtt/analyzer.py +999 -0
  280. oscura/iot/mqtt/properties.py +315 -0
  281. oscura/iot/zigbee/__init__.py +31 -0
  282. oscura/iot/zigbee/analyzer.py +615 -0
  283. oscura/iot/zigbee/security.py +153 -0
  284. oscura/iot/zigbee/zcl.py +349 -0
  285. oscura/jupyter/display.py +125 -45
  286. oscura/{exploratory → jupyter/exploratory}/__init__.py +8 -8
  287. oscura/{exploratory → jupyter/exploratory}/error_recovery.py +298 -141
  288. oscura/jupyter/exploratory/fuzzy.py +746 -0
  289. oscura/{exploratory → jupyter/exploratory}/fuzzy_advanced.py +258 -100
  290. oscura/{exploratory → jupyter/exploratory}/legacy.py +464 -242
  291. oscura/{exploratory → jupyter/exploratory}/parse.py +167 -145
  292. oscura/{exploratory → jupyter/exploratory}/recovery.py +119 -87
  293. oscura/jupyter/exploratory/sync.py +612 -0
  294. oscura/{exploratory → jupyter/exploratory}/unknown.py +299 -176
  295. oscura/jupyter/magic.py +4 -4
  296. oscura/{ui → jupyter/ui}/__init__.py +2 -2
  297. oscura/{ui → jupyter/ui}/formatters.py +3 -3
  298. oscura/{ui → jupyter/ui}/progressive_display.py +153 -82
  299. oscura/loaders/__init__.py +171 -63
  300. oscura/loaders/binary.py +88 -1
  301. oscura/loaders/chipwhisperer.py +153 -137
  302. oscura/loaders/configurable.py +208 -86
  303. oscura/loaders/csv_loader.py +458 -215
  304. oscura/loaders/hdf5_loader.py +278 -119
  305. oscura/loaders/lazy.py +87 -54
  306. oscura/loaders/mmap_loader.py +1 -1
  307. oscura/loaders/numpy_loader.py +253 -116
  308. oscura/loaders/pcap.py +226 -151
  309. oscura/loaders/rigol.py +110 -49
  310. oscura/loaders/sigrok.py +201 -78
  311. oscura/loaders/tdms.py +81 -58
  312. oscura/loaders/tektronix.py +291 -174
  313. oscura/loaders/touchstone.py +182 -87
  314. oscura/loaders/vcd.py +215 -117
  315. oscura/loaders/wav.py +155 -68
  316. oscura/reporting/__init__.py +9 -7
  317. oscura/reporting/analyze.py +352 -146
  318. oscura/reporting/argument_preparer.py +69 -14
  319. oscura/reporting/auto_report.py +97 -61
  320. oscura/reporting/batch.py +131 -58
  321. oscura/reporting/chart_selection.py +57 -45
  322. oscura/reporting/comparison.py +63 -17
  323. oscura/reporting/content/executive.py +76 -24
  324. oscura/reporting/core_formats/multi_format.py +11 -8
  325. oscura/reporting/engine.py +312 -158
  326. oscura/reporting/enhanced_reports.py +949 -0
  327. oscura/reporting/export.py +86 -43
  328. oscura/reporting/formatting/numbers.py +69 -42
  329. oscura/reporting/html.py +139 -58
  330. oscura/reporting/index.py +137 -65
  331. oscura/reporting/output.py +158 -67
  332. oscura/reporting/pdf.py +67 -102
  333. oscura/reporting/plots.py +191 -112
  334. oscura/reporting/sections.py +88 -47
  335. oscura/reporting/standards.py +104 -61
  336. oscura/reporting/summary_generator.py +75 -55
  337. oscura/reporting/tables.py +138 -54
  338. oscura/reporting/templates/enhanced/protocol_re.html +525 -0
  339. oscura/reporting/templates/index.md +13 -13
  340. oscura/sessions/__init__.py +14 -23
  341. oscura/sessions/base.py +3 -3
  342. oscura/sessions/blackbox.py +106 -10
  343. oscura/sessions/generic.py +2 -2
  344. oscura/sessions/legacy.py +783 -0
  345. oscura/side_channel/__init__.py +63 -0
  346. oscura/side_channel/dpa.py +1025 -0
  347. oscura/utils/__init__.py +15 -1
  348. oscura/utils/autodetect.py +1 -5
  349. oscura/utils/bitwise.py +118 -0
  350. oscura/{builders → utils/builders}/__init__.py +1 -1
  351. oscura/{comparison → utils/comparison}/__init__.py +6 -6
  352. oscura/{comparison → utils/comparison}/compare.py +202 -101
  353. oscura/{comparison → utils/comparison}/golden.py +83 -63
  354. oscura/{comparison → utils/comparison}/limits.py +313 -89
  355. oscura/{comparison → utils/comparison}/mask.py +151 -45
  356. oscura/{comparison → utils/comparison}/trace_diff.py +1 -1
  357. oscura/{comparison → utils/comparison}/visualization.py +147 -89
  358. oscura/{component → utils/component}/__init__.py +3 -3
  359. oscura/{component → utils/component}/impedance.py +122 -58
  360. oscura/{component → utils/component}/reactive.py +165 -168
  361. oscura/{component → utils/component}/transmission_line.py +3 -3
  362. oscura/{filtering → utils/filtering}/__init__.py +6 -6
  363. oscura/{filtering → utils/filtering}/base.py +1 -1
  364. oscura/{filtering → utils/filtering}/convenience.py +2 -2
  365. oscura/{filtering → utils/filtering}/design.py +169 -93
  366. oscura/{filtering → utils/filtering}/filters.py +2 -2
  367. oscura/{filtering → utils/filtering}/introspection.py +2 -2
  368. oscura/utils/geometry.py +31 -0
  369. oscura/utils/imports.py +184 -0
  370. oscura/utils/lazy.py +1 -1
  371. oscura/{math → utils/math}/__init__.py +2 -2
  372. oscura/{math → utils/math}/arithmetic.py +114 -48
  373. oscura/{math → utils/math}/interpolation.py +139 -106
  374. oscura/utils/memory.py +129 -66
  375. oscura/utils/memory_advanced.py +92 -9
  376. oscura/utils/memory_extensions.py +10 -8
  377. oscura/{optimization → utils/optimization}/__init__.py +1 -1
  378. oscura/{optimization → utils/optimization}/search.py +2 -2
  379. oscura/utils/performance/__init__.py +58 -0
  380. oscura/utils/performance/caching.py +889 -0
  381. oscura/utils/performance/lsh_clustering.py +333 -0
  382. oscura/utils/performance/memory_optimizer.py +699 -0
  383. oscura/utils/performance/optimizations.py +675 -0
  384. oscura/utils/performance/parallel.py +654 -0
  385. oscura/utils/performance/profiling.py +661 -0
  386. oscura/{pipeline → utils/pipeline}/base.py +1 -1
  387. oscura/{pipeline → utils/pipeline}/composition.py +11 -3
  388. oscura/{pipeline → utils/pipeline}/parallel.py +3 -2
  389. oscura/{pipeline → utils/pipeline}/pipeline.py +1 -1
  390. oscura/{pipeline → utils/pipeline}/reverse_engineering.py +412 -221
  391. oscura/{search → utils/search}/__init__.py +3 -3
  392. oscura/{search → utils/search}/anomaly.py +188 -58
  393. oscura/utils/search/context.py +294 -0
  394. oscura/{search → utils/search}/pattern.py +138 -10
  395. oscura/utils/serial.py +51 -0
  396. oscura/utils/storage/__init__.py +61 -0
  397. oscura/utils/storage/database.py +1166 -0
  398. oscura/{streaming → utils/streaming}/chunked.py +302 -143
  399. oscura/{streaming → utils/streaming}/progressive.py +1 -1
  400. oscura/{streaming → utils/streaming}/realtime.py +3 -2
  401. oscura/{triggering → utils/triggering}/__init__.py +6 -6
  402. oscura/{triggering → utils/triggering}/base.py +6 -6
  403. oscura/{triggering → utils/triggering}/edge.py +2 -2
  404. oscura/{triggering → utils/triggering}/pattern.py +2 -2
  405. oscura/{triggering → utils/triggering}/pulse.py +115 -74
  406. oscura/{triggering → utils/triggering}/window.py +2 -2
  407. oscura/utils/validation.py +32 -0
  408. oscura/validation/__init__.py +121 -0
  409. oscura/{compliance → validation/compliance}/__init__.py +5 -5
  410. oscura/{compliance → validation/compliance}/advanced.py +5 -5
  411. oscura/{compliance → validation/compliance}/masks.py +1 -1
  412. oscura/{compliance → validation/compliance}/reporting.py +127 -53
  413. oscura/{compliance → validation/compliance}/testing.py +114 -52
  414. oscura/validation/compliance_tests.py +915 -0
  415. oscura/validation/fuzzer.py +990 -0
  416. oscura/validation/grammar_tests.py +596 -0
  417. oscura/validation/grammar_validator.py +904 -0
  418. oscura/validation/hil_testing.py +977 -0
  419. oscura/{quality → validation/quality}/__init__.py +4 -4
  420. oscura/{quality → validation/quality}/ensemble.py +251 -171
  421. oscura/{quality → validation/quality}/explainer.py +3 -3
  422. oscura/{quality → validation/quality}/scoring.py +1 -1
  423. oscura/{quality → validation/quality}/warnings.py +4 -4
  424. oscura/validation/regression_suite.py +808 -0
  425. oscura/validation/replay.py +788 -0
  426. oscura/{testing → validation/testing}/__init__.py +2 -2
  427. oscura/{testing → validation/testing}/synthetic.py +5 -5
  428. oscura/visualization/__init__.py +9 -0
  429. oscura/visualization/accessibility.py +1 -1
  430. oscura/visualization/annotations.py +64 -67
  431. oscura/visualization/colors.py +7 -7
  432. oscura/visualization/digital.py +180 -81
  433. oscura/visualization/eye.py +236 -85
  434. oscura/visualization/interactive.py +320 -143
  435. oscura/visualization/jitter.py +587 -247
  436. oscura/visualization/layout.py +169 -134
  437. oscura/visualization/optimization.py +103 -52
  438. oscura/visualization/palettes.py +1 -1
  439. oscura/visualization/power.py +427 -211
  440. oscura/visualization/power_extended.py +626 -297
  441. oscura/visualization/presets.py +2 -0
  442. oscura/visualization/protocols.py +495 -181
  443. oscura/visualization/render.py +79 -63
  444. oscura/visualization/reverse_engineering.py +171 -124
  445. oscura/visualization/signal_integrity.py +460 -279
  446. oscura/visualization/specialized.py +190 -100
  447. oscura/visualization/spectral.py +670 -255
  448. oscura/visualization/thumbnails.py +166 -137
  449. oscura/visualization/waveform.py +150 -63
  450. oscura/workflows/__init__.py +3 -0
  451. oscura/{batch → workflows/batch}/__init__.py +5 -5
  452. oscura/{batch → workflows/batch}/advanced.py +150 -75
  453. oscura/workflows/batch/aggregate.py +531 -0
  454. oscura/workflows/batch/analyze.py +236 -0
  455. oscura/{batch → workflows/batch}/logging.py +2 -2
  456. oscura/{batch → workflows/batch}/metrics.py +1 -1
  457. oscura/workflows/complete_re.py +1144 -0
  458. oscura/workflows/compliance.py +44 -54
  459. oscura/workflows/digital.py +197 -51
  460. oscura/workflows/legacy/__init__.py +12 -0
  461. oscura/{workflow → workflows/legacy}/dag.py +4 -1
  462. oscura/workflows/multi_trace.py +9 -9
  463. oscura/workflows/power.py +42 -62
  464. oscura/workflows/protocol.py +82 -49
  465. oscura/workflows/reverse_engineering.py +351 -150
  466. oscura/workflows/signal_integrity.py +157 -82
  467. oscura-0.6.0.dist-info/METADATA +643 -0
  468. oscura-0.6.0.dist-info/RECORD +590 -0
  469. oscura/analyzers/digital/ic_database.py +0 -498
  470. oscura/analyzers/digital/timing_paths.py +0 -339
  471. oscura/analyzers/digital/vintage.py +0 -377
  472. oscura/analyzers/digital/vintage_result.py +0 -148
  473. oscura/analyzers/protocols/parallel_bus.py +0 -449
  474. oscura/batch/aggregate.py +0 -300
  475. oscura/batch/analyze.py +0 -139
  476. oscura/dsl/__init__.py +0 -73
  477. oscura/exceptions.py +0 -59
  478. oscura/exploratory/fuzzy.py +0 -513
  479. oscura/exploratory/sync.py +0 -384
  480. oscura/export/wavedrom.py +0 -430
  481. oscura/exporters/__init__.py +0 -94
  482. oscura/exporters/csv.py +0 -303
  483. oscura/exporters/exporters.py +0 -44
  484. oscura/exporters/hdf5.py +0 -217
  485. oscura/exporters/html_export.py +0 -701
  486. oscura/exporters/json_export.py +0 -338
  487. oscura/exporters/markdown_export.py +0 -367
  488. oscura/exporters/matlab_export.py +0 -354
  489. oscura/exporters/npz_export.py +0 -219
  490. oscura/exporters/spice_export.py +0 -210
  491. oscura/exporters/vintage_logic_csv.py +0 -247
  492. oscura/reporting/vintage_logic_report.py +0 -523
  493. oscura/search/context.py +0 -149
  494. oscura/session/__init__.py +0 -34
  495. oscura/session/annotations.py +0 -289
  496. oscura/session/history.py +0 -313
  497. oscura/session/session.py +0 -520
  498. oscura/visualization/digital_advanced.py +0 -718
  499. oscura/visualization/figure_manager.py +0 -156
  500. oscura/workflow/__init__.py +0 -13
  501. oscura-0.5.0.dist-info/METADATA +0 -407
  502. oscura-0.5.0.dist-info/RECORD +0 -486
  503. /oscura/core/{config.py → config/legacy.py} +0 -0
  504. /oscura/{extensibility → core/extensibility}/__init__.py +0 -0
  505. /oscura/{extensibility → core/extensibility}/registry.py +0 -0
  506. /oscura/{plugins → core/plugins}/isolation.py +0 -0
  507. /oscura/{builders → utils/builders}/signal_builder.py +0 -0
  508. /oscura/{optimization → utils/optimization}/parallel.py +0 -0
  509. /oscura/{pipeline → utils/pipeline}/__init__.py +0 -0
  510. /oscura/{streaming → utils/streaming}/__init__.py +0 -0
  511. {oscura-0.5.0.dist-info → oscura-0.6.0.dist-info}/WHEEL +0 -0
  512. {oscura-0.5.0.dist-info → oscura-0.6.0.dist-info}/entry_points.txt +0 -0
  513. {oscura-0.5.0.dist-info → oscura-0.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,498 +0,0 @@
1
- """IC timing database for vintage and modern logic ICs.
2
-
3
- This module provides timing specifications for common ICs to enable automatic
4
- validation and identification.
5
-
6
- Example:
7
- >>> from oscura.analyzers.digital.ic_database import IC_DATABASE, identify_ic
8
- >>> spec = IC_DATABASE["74LS74"]
9
- >>> print(f"Setup time: {spec.timing['t_su']*1e9:.1f}ns")
10
- >>>
11
- >>> # Auto-identify IC from measurements
12
- >>> ic_name, conf = identify_ic(measured_timings)
13
- """
14
-
15
- from __future__ import annotations
16
-
17
- from dataclasses import dataclass, field
18
-
19
-
20
- @dataclass
21
- class ICTiming:
22
- """Timing specification for an IC.
23
-
24
- Attributes:
25
- part_number: IC part number (e.g., "74LS74").
26
- description: Brief description of function.
27
- family: Logic family (e.g., "TTL", "LS-TTL", "HC-CMOS").
28
- vcc_nom: Nominal supply voltage.
29
- vcc_range: Supply voltage range (min, max).
30
- timing: Dictionary of timing parameters in seconds.
31
- voltage_levels: Dictionary of voltage thresholds.
32
- """
33
-
34
- part_number: str
35
- description: str
36
- family: str
37
- vcc_nom: float
38
- vcc_range: tuple[float, float]
39
- timing: dict[str, float] = field(default_factory=dict)
40
- voltage_levels: dict[str, float] = field(default_factory=dict)
41
-
42
-
43
- # Timing parameter definitions:
44
- # t_pd: Propagation delay
45
- # t_su: Setup time
46
- # t_h: Hold time
47
- # t_w: Pulse width (minimum)
48
- # t_r: Rise time
49
- # t_f: Fall time
50
- # t_co: Clock-to-output delay
51
-
52
- # 74xx TTL Series (Standard TTL - 1970s era)
53
- IC_7400_STD = ICTiming(
54
- part_number="7400",
55
- description="Quad 2-input NAND gate",
56
- family="TTL",
57
- vcc_nom=5.0,
58
- vcc_range=(4.75, 5.25),
59
- timing={
60
- "t_pd": 22e-9, # Typ 22ns, max 33ns
61
- "t_r": 12e-9,
62
- "t_f": 8e-9,
63
- },
64
- voltage_levels={
65
- "VIL_max": 0.8,
66
- "VIH_min": 2.0,
67
- "VOL_max": 0.4,
68
- "VOH_min": 2.4,
69
- },
70
- )
71
-
72
- IC_7474_STD = ICTiming(
73
- part_number="7474",
74
- description="Dual D-type flip-flop",
75
- family="TTL",
76
- vcc_nom=5.0,
77
- vcc_range=(4.75, 5.25),
78
- timing={
79
- "t_pd": 25e-9, # Clock-to-output
80
- "t_su": 20e-9, # Setup time
81
- "t_h": 5e-9, # Hold time
82
- "t_w": 25e-9, # Minimum clock pulse width
83
- "t_r": 12e-9,
84
- "t_f": 8e-9,
85
- },
86
- voltage_levels={
87
- "VIL_max": 0.8,
88
- "VIH_min": 2.0,
89
- "VOL_max": 0.4,
90
- "VOH_min": 2.4,
91
- },
92
- )
93
-
94
- # 74LSxx Low-Power Schottky TTL Series (1970s-1980s)
95
- IC_74LS00 = ICTiming(
96
- part_number="74LS00",
97
- description="Quad 2-input NAND gate",
98
- family="LS-TTL",
99
- vcc_nom=5.0,
100
- vcc_range=(4.75, 5.25),
101
- timing={
102
- "t_pd": 10e-9, # Typ 10ns, max 15ns
103
- "t_r": 10e-9,
104
- "t_f": 7e-9,
105
- },
106
- voltage_levels={
107
- "VIL_max": 0.8,
108
- "VIH_min": 2.0,
109
- "VOL_max": 0.5,
110
- "VOH_min": 2.7,
111
- },
112
- )
113
-
114
- IC_74LS74 = ICTiming(
115
- part_number="74LS74",
116
- description="Dual D-type flip-flop",
117
- family="LS-TTL",
118
- vcc_nom=5.0,
119
- vcc_range=(4.75, 5.25),
120
- timing={
121
- "t_pd": 25e-9, # Clock-to-output (typ), max 40ns
122
- "t_su": 20e-9, # Setup time
123
- "t_h": 5e-9, # Hold time
124
- "t_w": 25e-9, # Min clock pulse width
125
- "t_r": 10e-9,
126
- "t_f": 7e-9,
127
- },
128
- voltage_levels={
129
- "VIL_max": 0.8,
130
- "VIH_min": 2.0,
131
- "VOL_max": 0.5,
132
- "VOH_min": 2.7,
133
- },
134
- )
135
-
136
- IC_74LS244 = ICTiming(
137
- part_number="74LS244",
138
- description="Octal buffer/line driver",
139
- family="LS-TTL",
140
- vcc_nom=5.0,
141
- vcc_range=(4.75, 5.25),
142
- timing={
143
- "t_pd": 12e-9, # Typ 12ns, max 18ns
144
- "t_r": 7e-9,
145
- "t_f": 5e-9,
146
- },
147
- voltage_levels={
148
- "VIL_max": 0.8,
149
- "VIH_min": 2.0,
150
- "VOL_max": 0.5,
151
- "VOH_min": 2.7,
152
- },
153
- )
154
-
155
- IC_74LS245 = ICTiming(
156
- part_number="74LS245",
157
- description="Octal bus transceiver",
158
- family="LS-TTL",
159
- vcc_nom=5.0,
160
- vcc_range=(4.75, 5.25),
161
- timing={
162
- "t_pd": 12e-9, # Typ 12ns, max 18ns
163
- "t_r": 7e-9,
164
- "t_f": 5e-9,
165
- },
166
- voltage_levels={
167
- "VIL_max": 0.8,
168
- "VIH_min": 2.0,
169
- "VOL_max": 0.5,
170
- "VOH_min": 2.7,
171
- },
172
- )
173
-
174
- IC_74LS138 = ICTiming(
175
- part_number="74LS138",
176
- description="3-to-8 line decoder/demultiplexer",
177
- family="LS-TTL",
178
- vcc_nom=5.0,
179
- vcc_range=(4.75, 5.25),
180
- timing={
181
- "t_pd": 21e-9, # Typ 21ns, max 41ns
182
- "t_r": 10e-9,
183
- "t_f": 7e-9,
184
- },
185
- voltage_levels={
186
- "VIL_max": 0.8,
187
- "VIH_min": 2.0,
188
- "VOL_max": 0.5,
189
- "VOH_min": 2.7,
190
- },
191
- )
192
-
193
- IC_74LS273 = ICTiming(
194
- part_number="74LS273",
195
- description="Octal D-type flip-flop with clear",
196
- family="LS-TTL",
197
- vcc_nom=5.0,
198
- vcc_range=(4.75, 5.25),
199
- timing={
200
- "t_pd": 20e-9, # Clock-to-output
201
- "t_su": 20e-9, # Setup time
202
- "t_h": 5e-9, # Hold time
203
- "t_w": 20e-9, # Min clock pulse width
204
- "t_r": 10e-9,
205
- "t_f": 7e-9,
206
- },
207
- voltage_levels={
208
- "VIL_max": 0.8,
209
- "VIH_min": 2.0,
210
- "VOL_max": 0.5,
211
- "VOH_min": 2.7,
212
- },
213
- )
214
-
215
- IC_74LS374 = ICTiming(
216
- part_number="74LS374",
217
- description="Octal D-type flip-flop with 3-state outputs",
218
- family="LS-TTL",
219
- vcc_nom=5.0,
220
- vcc_range=(4.75, 5.25),
221
- timing={
222
- "t_pd": 20e-9, # Clock-to-output
223
- "t_su": 20e-9, # Setup time
224
- "t_h": 5e-9, # Hold time
225
- "t_w": 20e-9, # Min clock pulse width
226
- "t_pz": 18e-9, # Output enable to output
227
- "t_pzh": 30e-9, # Output disable to high-Z
228
- "t_r": 10e-9,
229
- "t_f": 7e-9,
230
- },
231
- voltage_levels={
232
- "VIL_max": 0.8,
233
- "VIH_min": 2.0,
234
- "VOL_max": 0.5,
235
- "VOH_min": 2.7,
236
- },
237
- )
238
-
239
- # 74HCxx High-Speed CMOS Series (1980s-present)
240
- IC_74HC00 = ICTiming(
241
- part_number="74HC00",
242
- description="Quad 2-input NAND gate",
243
- family="HC-CMOS",
244
- vcc_nom=5.0,
245
- vcc_range=(2.0, 6.0),
246
- timing={
247
- "t_pd": 8e-9, # At 5V, typ 8ns
248
- "t_r": 6e-9,
249
- "t_f": 6e-9,
250
- },
251
- voltage_levels={
252
- "VIL_max": 1.35,
253
- "VIH_min": 3.15,
254
- "VOL_max": 0.33,
255
- "VOH_min": 3.84,
256
- },
257
- )
258
-
259
- IC_74HC74 = ICTiming(
260
- part_number="74HC74",
261
- description="Dual D-type flip-flop",
262
- family="HC-CMOS",
263
- vcc_nom=5.0,
264
- vcc_range=(2.0, 6.0),
265
- timing={
266
- "t_pd": 16e-9, # Clock-to-output at 5V
267
- "t_su": 14e-9, # Setup time
268
- "t_h": 3e-9, # Hold time
269
- "t_w": 14e-9, # Min clock pulse width
270
- "t_r": 6e-9,
271
- "t_f": 6e-9,
272
- },
273
- voltage_levels={
274
- "VIL_max": 1.35,
275
- "VIH_min": 3.15,
276
- "VOL_max": 0.33,
277
- "VOH_min": 3.84,
278
- },
279
- )
280
-
281
- IC_74HC595 = ICTiming(
282
- part_number="74HC595",
283
- description="8-bit shift register with output latches",
284
- family="HC-CMOS",
285
- vcc_nom=5.0,
286
- vcc_range=(2.0, 6.0),
287
- timing={
288
- "t_pd": 16e-9, # Clock-to-output
289
- "t_su": 14e-9, # Setup time
290
- "t_h": 3e-9, # Hold time
291
- "t_w": 14e-9, # Min clock pulse width
292
- "t_r": 6e-9,
293
- "t_f": 6e-9,
294
- },
295
- voltage_levels={
296
- "VIL_max": 1.35,
297
- "VIH_min": 3.15,
298
- "VOL_max": 0.33,
299
- "VOH_min": 3.84,
300
- },
301
- )
302
-
303
- # 4000 Series CMOS (1970s-1980s)
304
- IC_4011 = ICTiming(
305
- part_number="4011",
306
- description="Quad 2-input NAND gate",
307
- family="CMOS_5V",
308
- vcc_nom=5.0,
309
- vcc_range=(3.0, 18.0),
310
- timing={
311
- "t_pd": 90e-9, # At 5V, typ 90ns
312
- "t_r": 60e-9,
313
- "t_f": 60e-9,
314
- },
315
- voltage_levels={
316
- "VIL_max": 1.5,
317
- "VIH_min": 3.5,
318
- "VOL_max": 0.05,
319
- "VOH_min": 4.95,
320
- },
321
- )
322
-
323
- IC_4013 = ICTiming(
324
- part_number="4013",
325
- description="Dual D-type flip-flop",
326
- family="CMOS_5V",
327
- vcc_nom=5.0,
328
- vcc_range=(3.0, 18.0),
329
- timing={
330
- "t_pd": 140e-9, # Clock-to-output at 5V
331
- "t_su": 60e-9, # Setup time
332
- "t_h": 40e-9, # Hold time
333
- "t_w": 100e-9, # Min clock pulse width
334
- "t_r": 60e-9,
335
- "t_f": 60e-9,
336
- },
337
- voltage_levels={
338
- "VIL_max": 1.5,
339
- "VIH_min": 3.5,
340
- "VOL_max": 0.05,
341
- "VOH_min": 4.95,
342
- },
343
- )
344
-
345
- # Comprehensive IC database
346
- IC_DATABASE: dict[str, ICTiming] = {
347
- # Standard TTL
348
- "7400": IC_7400_STD,
349
- # LS-TTL (74LS series preferred over 74 for specificity)
350
- "74LS00": IC_74LS00,
351
- "74LS74": IC_74LS74,
352
- "74LS138": IC_74LS138,
353
- "74LS244": IC_74LS244,
354
- "74LS245": IC_74LS245,
355
- "74LS273": IC_74LS273,
356
- "74LS374": IC_74LS374,
357
- # HC-CMOS
358
- "74HC00": IC_74HC00,
359
- "74HC74": IC_74HC74,
360
- "74HC595": IC_74HC595,
361
- # 4000 series CMOS
362
- "4011": IC_4011,
363
- "4013": IC_4013,
364
- }
365
-
366
-
367
- def identify_ic(
368
- measured_timings: dict[str, float],
369
- *,
370
- tolerance: float = 0.5,
371
- min_confidence: float = 0.6,
372
- ) -> tuple[str, float]:
373
- """Identify IC from measured timing parameters.
374
-
375
- Args:
376
- measured_timings: Dictionary of measured timing values (e.g., {'t_pd': 25e-9}).
377
- tolerance: Allowable deviation (0.0-1.0, 0.5 = 50% tolerance).
378
- min_confidence: Minimum confidence score (0.0-1.0).
379
-
380
- Returns:
381
- Tuple of (ic_name, confidence_score).
382
- Returns ("unknown", 0.0) if no match above min_confidence.
383
-
384
- Example:
385
- >>> timings = {'t_pd': 25e-9, 't_su': 20e-9, 't_h': 5e-9}
386
- >>> ic, conf = identify_ic(timings)
387
- >>> print(f"Identified: {ic} ({conf*100:.1f}% confidence)")
388
- """
389
- scores: dict[str, float] = {}
390
-
391
- for ic_name, ic_spec in IC_DATABASE.items():
392
- # Calculate match score for this IC
393
- param_scores = []
394
-
395
- for param, measured_value in measured_timings.items():
396
- if param not in ic_spec.timing:
397
- continue
398
-
399
- spec_value = ic_spec.timing[param]
400
-
401
- # Calculate relative error
402
- if spec_value == 0:
403
- continue
404
-
405
- error = abs(measured_value - spec_value) / spec_value
406
-
407
- # Score based on error (within tolerance gets high score)
408
- if error <= tolerance:
409
- param_score = 1.0 - (error / tolerance)
410
- else:
411
- param_score = 0.0
412
-
413
- param_scores.append(param_score)
414
-
415
- # Overall score is average of parameter scores
416
- if param_scores:
417
- scores[ic_name] = sum(param_scores) / len(param_scores)
418
-
419
- # Find best match
420
- if not scores:
421
- return ("unknown", 0.0)
422
-
423
- best_ic = max(scores.items(), key=lambda x: x[1])
424
-
425
- if best_ic[1] < min_confidence:
426
- return ("unknown", best_ic[1])
427
-
428
- return best_ic
429
-
430
-
431
- def validate_ic_timing(
432
- ic_name: str,
433
- measured_timings: dict[str, float],
434
- *,
435
- tolerance: float = 0.3,
436
- ) -> dict[str, dict[str, float | bool | None]]:
437
- """Validate measured timings against IC specification.
438
-
439
- Args:
440
- ic_name: IC part number (e.g., "74LS74").
441
- measured_timings: Dictionary of measured timing values.
442
- tolerance: Allowable deviation (0.0-1.0).
443
-
444
- Returns:
445
- Dictionary mapping parameter names to validation results:
446
- {'t_pd': {'measured': 25e-9, 'spec': 25e-9, 'passes': True, 'error': 0.0}}
447
-
448
- Raises:
449
- KeyError: If IC not found in database.
450
-
451
- Example:
452
- >>> results = validate_ic_timing("74LS74", {'t_pd': 30e-9})
453
- >>> if not results['t_pd']['passes']:
454
- ... print(f"Propagation delay out of spec!")
455
- """
456
- if ic_name not in IC_DATABASE:
457
- raise KeyError(f"IC '{ic_name}' not found in database")
458
-
459
- ic_spec = IC_DATABASE[ic_name]
460
- results: dict[str, dict[str, float | bool | None]] = {}
461
-
462
- for param, measured_value in measured_timings.items():
463
- if param not in ic_spec.timing:
464
- results[param] = {
465
- "measured": measured_value,
466
- "spec": None,
467
- "passes": None,
468
- "error": None,
469
- }
470
- continue
471
-
472
- spec_value = ic_spec.timing[param]
473
-
474
- # Calculate relative error
475
- if spec_value == 0:
476
- error = 0.0
477
- else:
478
- error = abs(measured_value - spec_value) / spec_value
479
-
480
- # Check if within tolerance
481
- passes = error <= tolerance
482
-
483
- results[param] = {
484
- "measured": measured_value,
485
- "spec": spec_value,
486
- "passes": passes,
487
- "error": error,
488
- }
489
-
490
- return results
491
-
492
-
493
- __all__ = [
494
- "IC_DATABASE",
495
- "ICTiming",
496
- "identify_ic",
497
- "validate_ic_timing",
498
- ]