From 6053b86a24c11e5f8fc133c8b4e947c520c93c85 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sat, 21 Jan 2023 14:27:33 +0000 Subject: [PATCH] Add new spice regression test for windows path separators. --- qa/data/eeschema/issue13591.kicad_pro | 334 ++++++++++++++ qa/data/eeschema/issue13591.kicad_sch | 429 ++++++++++++++++++ qa/data/eeschema/issue13591.spice | 10 + qa/data/eeschema/issue13591_models/diode.lib | 22 + qa/unittests/eeschema/CMakeLists.txt | 1 + .../eeschema/sim/test_sim_regressions.cpp | 84 ++++ .../eeschema/test_netlist_exporter_spice.cpp | 253 +---------- .../eeschema/test_netlist_exporter_spice.h | 280 ++++++++++++ 8 files changed, 1161 insertions(+), 252 deletions(-) create mode 100644 qa/data/eeschema/issue13591.kicad_pro create mode 100644 qa/data/eeschema/issue13591.kicad_sch create mode 100644 qa/data/eeschema/issue13591.spice create mode 100644 qa/data/eeschema/issue13591_models/diode.lib create mode 100644 qa/unittests/eeschema/sim/test_sim_regressions.cpp create mode 100644 qa/unittests/eeschema/test_netlist_exporter_spice.h diff --git a/qa/data/eeschema/issue13591.kicad_pro b/qa/data/eeschema/issue13591.kicad_pro new file mode 100644 index 0000000000..202b3dfb72 --- /dev/null +++ b/qa/data/eeschema/issue13591.kicad_pro @@ -0,0 +1,334 @@ +{ + "board": { + "3dviewports": [], + "design_settings": { + "defaults": { + "board_outline_line_width": 0.1, + "copper_line_width": 0.2, + "copper_text_size_h": 1.5, + "copper_text_size_v": 1.5, + "copper_text_thickness": 0.3, + "other_line_width": 0.15, + "silk_line_width": 0.15, + "silk_text_size_h": 1.0, + "silk_text_size_v": 1.0, + "silk_text_thickness": 0.15 + }, + "diff_pair_dimensions": [], + "drc_exclusions": [], + "rules": { + "min_copper_edge_clearance": 0.0, + "solder_mask_clearance": 0.0, + "solder_mask_min_width": 0.0 + }, + "track_widths": [], + "via_dimensions": [] + }, + "layer_presets": [], + "viewports": [] + }, + "boards": [], + "cvpcb": { + "equivalence_files": [] + }, + "erc": { + "erc_exclusions": [], + "meta": { + "version": 0 + }, + "pin_map": [ + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0, + 1, + 2 + ], + [ + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2 + ], + [ + 1, + 1, + 1, + 1, + 1, + 0, + 1, + 1, + 1, + 1, + 1, + 2 + ], + [ + 0, + 0, + 0, + 1, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 2, + 0, + 0, + 1, + 0, + 2, + 2, + 2, + 2 + ], + [ + 0, + 2, + 0, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 0, + 2, + 1, + 1, + 0, + 0, + 1, + 0, + 2, + 0, + 0, + 2 + ], + [ + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2, + 2 + ] + ], + "rule_severities": { + "bus_definition_conflict": "error", + "bus_entry_needed": "error", + "bus_label_syntax": "error", + "bus_to_bus_conflict": "error", + "bus_to_net_conflict": "error", + "different_unit_footprint": "error", + "different_unit_net": "error", + "duplicate_reference": "error", + "duplicate_sheet_names": "error", + "extra_units": "error", + "global_label_dangling": "warning", + "hier_label_mismatch": "error", + "label_dangling": "error", + "lib_symbol_issues": "warning", + "multiple_net_names": "warning", + "net_not_bus_member": "warning", + "no_connect_connected": "warning", + "no_connect_dangling": "warning", + "pin_not_connected": "error", + "pin_not_driven": "error", + "pin_to_pin": "warning", + "power_pin_not_driven": "error", + "similar_labels": "warning", + "unannotated": "error", + "unit_value_mismatch": "error", + "unresolved_variable": "error", + "wire_dangling": "error" + } + }, + "libraries": { + "pinned_footprint_libs": [], + "pinned_symbol_libs": [] + }, + "meta": { + "filename": "sim2_V6.kicad_pro", + "version": 1 + }, + "net_settings": { + "classes": [ + { + "bus_width": 12.0, + "clearance": 0.2, + "diff_pair_gap": 0.25, + "diff_pair_via_gap": 0.25, + "diff_pair_width": 0.2, + "line_style": 0, + "microvia_diameter": 0.3, + "microvia_drill": 0.1, + "name": "Default", + "pcb_color": "rgba(0, 0, 0, 0.000)", + "schematic_color": "rgba(0, 0, 0, 0.000)", + "track_width": 0.25, + "via_diameter": 0.8, + "via_drill": 0.4, + "wire_width": 6.0 + } + ], + "meta": { + "version": 2 + }, + "net_colors": null, + "netclass_assignments": null, + "netclass_patterns": [] + }, + "pcbnew": { + "last_paths": { + "gencad": "", + "idf": "", + "netlist": "", + "specctra_dsn": "", + "step": "", + "vrml": "" + }, + "page_layout_descr_file": "" + }, + "schematic": { + "annotate_start_num": 0, + "drawing": { + "dashed_lines_dash_length_ratio": 12.0, + "dashed_lines_gap_length_ratio": 3.0, + "default_line_thickness": 6.0, + "default_text_size": 50.0, + "field_names": [], + "intersheets_ref_own_page": false, + "intersheets_ref_prefix": "", + "intersheets_ref_short": false, + "intersheets_ref_show": false, + "intersheets_ref_suffix": "", + "junction_size_choice": 3, + "label_size_ratio": 0.375, + "pin_symbol_size": 25.0, + "text_offset_ratio": 0.15 + }, + "legacy_lib_dir": "", + "legacy_lib_list": [], + "meta": { + "version": 1 + }, + "net_format_name": "", + "ngspice": { + "fix_include_paths": true, + "fix_passive_vals": true, + "meta": { + "version": 0 + }, + "model_mode": 2, + "workbook_filename": "sim2_V6.wbk" + }, + "page_layout_descr_file": "", + "plot_directory": "", + "spice_adjust_passive_values": false, + "spice_external_command": "spice \"%I\"", + "spice_save_all_currents": false, + "spice_save_all_voltages": false, + "subpart_first_id": 65, + "subpart_id_separator": 0 + }, + "sheets": [ + [ + "c320d65b-dd35-489c-9c1b-364c21869ec2", + "" + ] + ], + "text_variables": {} +} diff --git a/qa/data/eeschema/issue13591.kicad_sch b/qa/data/eeschema/issue13591.kicad_sch new file mode 100644 index 0000000000..a046a20b4d --- /dev/null +++ b/qa/data/eeschema/issue13591.kicad_sch @@ -0,0 +1,429 @@ +(kicad_sch (version 20211123) (generator eeschema) + + (uuid c320d65b-dd35-489c-9c1b-364c21869ec2) + + (paper "A4") + + (lib_symbols + (symbol "Device:D" (pin_numbers hide) (pin_names (offset 1.016) hide) (in_bom yes) (on_board yes) + (property "Reference" "D" (id 0) (at 0 2.54 0) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "D" (id 1) (at 0 -2.54 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (id 2) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "diode" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Diode" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "TO-???* *_Diode_* *SingleDiode* D_*" (id 6) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "D_0_1" + (polyline + (pts + (xy -1.27 1.27) + (xy -1.27 -1.27) + ) + (stroke (width 0.254) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 0) + (xy -1.27 0) + ) + (stroke (width 0) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (polyline + (pts + (xy 1.27 1.27) + (xy 1.27 -1.27) + (xy -1.27 0) + (xy 1.27 1.27) + ) + (stroke (width 0.254) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + ) + (symbol "D_1_1" + (pin passive line (at -3.81 0 0) (length 2.54) + (name "K" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 3.81 0 180) (length 2.54) + (name "A" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "Device:R" (pin_numbers hide) (pin_names (offset 0)) (in_bom yes) (on_board yes) + (property "Reference" "R" (id 0) (at 2.032 0 90) + (effects (font (size 1.27 1.27))) + ) + (property "Value" "R" (id 1) (at 0 0 90) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (id 2) (at -1.778 0 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "R res resistor" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Resistor" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_fp_filters" "R_*" (id 6) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "R_0_1" + (rectangle (start -1.016 -2.54) (end 1.016 2.54) + (stroke (width 0.254) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + ) + (symbol "R_1_1" + (pin passive line (at 0 3.81 270) (length 1.27) + (name "~" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 0 -3.81 90) (length 1.27) + (name "~" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "Simulation_SPICE:VPULSE" (pin_numbers hide) (pin_names (offset 0.0254)) (in_bom yes) (on_board yes) + (property "Reference" "V" (id 0) (at 2.54 2.54 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "VPULSE" (id 1) (at 2.54 0 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (id 2) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Spice_Netlist_Enabled" "Y" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "Spice_Primitive" "V" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "Spice_Model" "pulse(0 1 2n 2n 2n 50n 100n)" (id 6) (at 2.54 -2.54 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "ki_keywords" "simulation" (id 7) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "Voltage source, pulse" (id 8) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "VPULSE_0_0" + (polyline + (pts + (xy -2.032 -0.762) + (xy -1.397 -0.762) + (xy -1.143 0.762) + (xy -0.127 0.762) + (xy 0.127 -0.762) + (xy 1.143 -0.762) + (xy 1.397 0.762) + (xy 2.032 0.762) + ) + (stroke (width 0) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + (text "+" (at 0 1.905 0) + (effects (font (size 1.27 1.27))) + ) + ) + (symbol "VPULSE_0_1" + (circle (center 0 0) (radius 2.54) + (stroke (width 0.254) (type default) (color 0 0 0 0)) + (fill (type background)) + ) + ) + (symbol "VPULSE_1_1" + (pin passive line (at 0 5.08 270) (length 2.54) + (name "~" (effects (font (size 1.27 1.27)))) + (number "1" (effects (font (size 1.27 1.27)))) + ) + (pin passive line (at 0 -5.08 90) (length 2.54) + (name "~" (effects (font (size 1.27 1.27)))) + (number "2" (effects (font (size 1.27 1.27)))) + ) + ) + ) + (symbol "pspice:0" (power) (pin_names (offset 0)) (in_bom yes) (on_board yes) + (property "Reference" "#GND" (id 0) (at 0 -2.54 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "0" (id 1) (at 0 -1.778 0) + (effects (font (size 1.27 1.27))) + ) + (property "Footprint" "" (id 2) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_keywords" "simulation" (id 4) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "ki_description" "0V reference potential for simulation" (id 5) (at 0 0 0) + (effects (font (size 1.27 1.27)) hide) + ) + (symbol "0_0_1" + (polyline + (pts + (xy -1.27 0) + (xy 0 -1.27) + (xy 1.27 0) + (xy -1.27 0) + ) + (stroke (width 0) (type default) (color 0 0 0 0)) + (fill (type none)) + ) + ) + (symbol "0_1_1" + (pin power_in line (at 0 0 0) (length 0) hide + (name "0" (effects (font (size 1.016 1.016)))) + (number "1" (effects (font (size 1.016 1.016)))) + ) + ) + ) + ) + + (text ".tran 1us 1ms" (at 142.24 63.5 0) + (effects (font (size 1.27 1.27)) (justify left bottom)) + (uuid 14103cc0-6e61-4ce0-83d2-854b9063d98e) + ) + + (junction (at 96.52 63.5) (diameter 0) (color 0 0 0 0) + (uuid cd3bc7f1-e10c-4d40-aa30-03430340cec2) + ) + + (wire (pts (xy 76.2 63.5) (xy 96.52 63.5)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 02ecd695-b1f0-43ff-8105-c2eee8a924e0) + ) + (wire (pts (xy 68.58 63.5) (xy 49.53 63.5)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 199035fe-3d65-490e-9880-3fcdb007162e) + ) + (wire (pts (xy 110.49 73.66) (xy 110.49 63.5)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 215ac09b-1d70-4686-a946-5aba79aff49c) + ) + (wire (pts (xy 96.52 91.44) (xy 96.52 81.28)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 43b501d1-3d64-4f8e-ba9c-39ed115faf74) + ) + (wire (pts (xy 110.49 63.5) (xy 96.52 63.5)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 6839711f-d909-4163-b101-e6e468058419) + ) + (wire (pts (xy 110.49 91.44) (xy 110.49 81.28)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid 84e89c8f-a4c5-417c-a59f-c74d16e4650a) + ) + (wire (pts (xy 49.53 91.44) (xy 49.53 81.28)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid ba6e88b9-4c9b-4399-aae0-1b99322816ce) + ) + (wire (pts (xy 49.53 63.5) (xy 49.53 71.12)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid df55dc38-4eea-45b7-a8f8-143ff8efc8db) + ) + (wire (pts (xy 96.52 63.5) (xy 96.52 73.66)) + (stroke (width 0) (type default) (color 0 0 0 0)) + (uuid f6b28b27-dfbc-4a27-bd69-3846a4360743) + ) + + (symbol (lib_id "pspice:0") (at 110.49 91.44 0) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid 1a5be67d-9866-401d-b629-c1e5f0845d67) + (property "Reference" "#GND?" (id 0) (at 110.49 93.98 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "0" (id 1) (at 110.49 88.9 0)) + (property "Footprint" "" (id 2) (at 110.49 91.44 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 110.49 91.44 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid af973b92-8147-4b47-8721-90b66e63bbe1)) + ) + + (symbol (lib_id "Device:R") (at 110.49 77.47 180) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid 32a7603d-e2c3-4e8d-ac2e-a18bb24f71aa) + (property "Reference" "R2" (id 0) (at 113.03 76.1999 0) + (effects (font (size 1.27 1.27)) (justify right)) + ) + (property "Value" "10k" (id 1) (at 113.03 78.7399 0) + (effects (font (size 1.27 1.27)) (justify right)) + ) + (property "Footprint" "" (id 2) (at 112.268 77.47 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 110.49 77.47 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid c720522c-2ba3-466b-b6fd-5f98646ffa63)) + (pin "2" (uuid 232c161c-09f2-4e91-85fb-1f5d5b2879e9)) + ) + + (symbol (lib_id "Simulation_SPICE:VPULSE") (at 49.53 76.2 0) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid 374e384d-7485-4232-8741-607d5a41e745) + (property "Reference" "V1" (id 0) (at 53.34 73.4701 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Value" "VPULSE" (id 1) (at 53.34 76.0101 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (property "Footprint" "" (id 2) (at 49.53 76.2 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 49.53 76.2 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Spice_Netlist_Enabled" "Y" (id 4) (at 49.53 76.2 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "Spice_Primitive" "V" (id 5) (at 49.53 76.2 0) + (effects (font (size 1.27 1.27)) (justify left) hide) + ) + (property "Spice_Model" "dc 0 pulse(0 2 1m 50n 50n 1m 2m)" (id 6) (at 53.34 78.5501 0) + (effects (font (size 1.27 1.27)) (justify left)) + ) + (pin "1" (uuid a7947fd2-165d-493f-b8e6-e78b75dfae94)) + (pin "2" (uuid 5a395677-a9eb-4147-bea3-fd3e5d82083c)) + ) + + (symbol (lib_id "Device:R") (at 72.39 63.5 90) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid 7a95e03e-5b98-4b61-ab70-bbeb1cb67ed1) + (property "Reference" "R1" (id 0) (at 72.39 57.15 90)) + (property "Value" "1k" (id 1) (at 72.39 59.69 90)) + (property "Footprint" "" (id 2) (at 72.39 65.278 90) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 72.39 63.5 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 2eab2dfb-1a4b-401a-ac8e-8b70039fa135)) + (pin "2" (uuid e4424596-4abb-4814-957e-e352746501fa)) + ) + + (symbol (lib_id "Device:D") (at 96.52 77.47 90) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid 828fa253-b44e-4f6e-a95a-66db5e9fea1d) + (property "Reference" "D1" (id 0) (at 99.06 76.1999 90) + (effects (font (size 1.27 1.27)) (justify right)) + ) + (property "Value" "D" (id 1) (at 99.06 78.7399 90) + (effects (font (size 1.27 1.27)) (justify right)) + ) + (property "Footprint" "" (id 2) (at 96.52 77.47 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 96.52 77.47 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Spice_Primitive" "D" (id 4) (at 96.52 77.47 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Spice_Model" "1N456" (id 5) (at 96.52 77.47 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Spice_Netlist_Enabled" "Y" (id 6) (at 96.52 77.47 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Spice_Lib_File" "issue13591_models\\diode.lib" (id 7) (at 96.52 77.47 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Spice_Node_Sequence" "2 1" (id 8) (at 96.52 77.47 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid aee777e6-7ff9-4ad6-b577-bdc81dc1193f)) + (pin "2" (uuid bd555bb7-3705-46ea-83aa-fec188339f87)) + ) + + (symbol (lib_id "pspice:0") (at 49.53 91.44 0) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid 953baf45-76c0-417d-b68a-33fecdb25a10) + (property "Reference" "#GND01" (id 0) (at 49.53 93.98 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "0" (id 1) (at 49.53 88.9 0)) + (property "Footprint" "" (id 2) (at 49.53 91.44 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 49.53 91.44 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 77e096c3-94c7-4388-beca-f23c80794d4d)) + ) + + (symbol (lib_id "pspice:0") (at 96.52 91.44 0) (unit 1) + (in_bom yes) (on_board yes) (fields_autoplaced) + (uuid e743f90c-f4b3-4e96-b93e-fa4a32eee11e) + (property "Reference" "#GND02" (id 0) (at 96.52 93.98 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Value" "0" (id 1) (at 96.52 88.9 0)) + (property "Footprint" "" (id 2) (at 96.52 91.44 0) + (effects (font (size 1.27 1.27)) hide) + ) + (property "Datasheet" "~" (id 3) (at 96.52 91.44 0) + (effects (font (size 1.27 1.27)) hide) + ) + (pin "1" (uuid 8e93e08f-211b-4f8d-bccf-f7d4fc979e9a)) + ) + + (sheet_instances + (path "/" (page "1")) + ) + + (symbol_instances + (path "/953baf45-76c0-417d-b68a-33fecdb25a10" + (reference "#GND01") (unit 1) (value "0") (footprint "") + ) + (path "/e743f90c-f4b3-4e96-b93e-fa4a32eee11e" + (reference "#GND02") (unit 1) (value "0") (footprint "") + ) + (path "/1a5be67d-9866-401d-b629-c1e5f0845d67" + (reference "#GND?") (unit 1) (value "0") (footprint "") + ) + (path "/828fa253-b44e-4f6e-a95a-66db5e9fea1d" + (reference "D1") (unit 1) (value "D") (footprint "") + ) + (path "/7a95e03e-5b98-4b61-ab70-bbeb1cb67ed1" + (reference "R1") (unit 1) (value "1k") (footprint "") + ) + (path "/32a7603d-e2c3-4e8d-ac2e-a18bb24f71aa" + (reference "R2") (unit 1) (value "10k") (footprint "") + ) + (path "/374e384d-7485-4232-8741-607d5a41e745" + (reference "V1") (unit 1) (value "VPULSE") (footprint "") + ) + ) +) diff --git a/qa/data/eeschema/issue13591.spice b/qa/data/eeschema/issue13591.spice new file mode 100644 index 0000000000..d664d532fa --- /dev/null +++ b/qa/data/eeschema/issue13591.spice @@ -0,0 +1,10 @@ +KiCad schematic +.include "/Users/jeff/kicad_arm/kicad/qa/data/eeschema/issue13591_models/diode.lib" +.save all +.probe alli +.tran 1us 1ms +R2 0 Net-_D1-A_ 10k +D1 Net-_D1-A_ 0 1N456 +R1 Net-_R1-Pad1_ Net-_D1-A_ 1k +V1 Net-_R1-Pad1_ 0 dc 0 pulse(0 2 1m 50n 50n 1m 2m) +.end diff --git a/qa/data/eeschema/issue13591_models/diode.lib b/qa/data/eeschema/issue13591_models/diode.lib new file mode 100644 index 0000000000..44e9424d29 --- /dev/null +++ b/qa/data/eeschema/issue13591_models/diode.lib @@ -0,0 +1,22 @@ +***** +* DIODE.LIB +* spectrum +* andy +* Generated by the Micro-Cap Model program Version 11.0.1.7. +***** + +*** Low Leakage Diode +.MODEL 1N456 D (BV=30 CJO=4.505p IBV=100p IS=29.054p M=385.099m N=1.425 ++ RL=125.018MEG RS=910.713m TT=5u VJ=700m) + +*** Low Leakage Diode +.MODEL 1N456A D (BV=30 CJO=4.505E-12 IBV=100E-12 IS=29.054E-12 M=385.099E-3 N=1.425 ++ RS=910.713E-3 TT=5E-6 VJ=700E-3) + +*** Low Leakage Diode +.MODEL 1N457 D (BV=70 CJO=4.505p IBV=100p IS=19.191p M=385.099m N=1.388 ++ RL=125.012MEG RS=980.164m TT=5u VJ=700m) + +*** Low Leakage Diode +.MODEL 1N457A D (BV=70 CJO=4.505p IBV=100p IS=19.191p M=385.099m N=1.388 ++ RL=125.018MEG RS=980.164m TT=5u VJ=700m) diff --git a/qa/unittests/eeschema/CMakeLists.txt b/qa/unittests/eeschema/CMakeLists.txt index 55e8a6710e..97a19c094c 100644 --- a/qa/unittests/eeschema/CMakeLists.txt +++ b/qa/unittests/eeschema/CMakeLists.txt @@ -96,6 +96,7 @@ if( KICAD_SPICE ) sim/test_library_spice.cpp sim/test_sim_model_inference.cpp sim/test_sim_model_ngspice.cpp + sim/test_sim_regressions.cpp sim/test_ngspice_helpers.cpp ) endif() diff --git a/qa/unittests/eeschema/sim/test_sim_regressions.cpp b/qa/unittests/eeschema/sim/test_sim_regressions.cpp new file mode 100644 index 0000000000..0f54cc2fa4 --- /dev/null +++ b/qa/unittests/eeschema/sim/test_sim_regressions.cpp @@ -0,0 +1,84 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2023 KiCad Developers, see AUTHORS.TXT for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef KICAD_SPICE + +#include +#include // To check if the current test failed (to be moved?). +#include +#include +#include +#include +#include + + +class TEST_SIM_REGRESSIONS_FIXTURE : public TEST_NETLIST_EXPORTER_SPICE_FIXTURE +{ +public: + TEST_SIM_REGRESSIONS_FIXTURE() : + TEST_NETLIST_EXPORTER_SPICE_FIXTURE() + { + } + + ~TEST_SIM_REGRESSIONS_FIXTURE() + { + } + + wxFileName GetSchematicPath( const wxString& aBaseName ) override + { + wxFileName fn = KI_TEST::GetEeschemaTestDataDir(); + fn.SetName( aBaseName ); + fn.SetExt( KiCadSchematicFileExtension ); + + return fn; + } + + wxString GetNetlistPath( bool aTest = false ) override + { + wxFileName netFile = m_schematic.Prj().GetProjectFullName(); + + if( aTest ) + netFile.SetName( netFile.GetName() + "_test" ); + + netFile.SetExt( "spice" ); + return netFile.GetFullPath(); + } +}; + + +BOOST_FIXTURE_TEST_SUITE( SimRegressions, TEST_SIM_REGRESSIONS_FIXTURE ) + + +BOOST_AUTO_TEST_CASE( WindowsPaths ) +{ + LOCALE_IO dummy; + + TestNetlist( "issue13591" ); + TestTranPoint( 100e-6, { { "I(R1)", 0 }, { "I(R2)", 0 } } ); + TestTranPoint( 500e-6, { { "I(R1)", 0 }, { "I(R2)", 0 } } ); +} + + +BOOST_AUTO_TEST_SUITE_END() + +#endif // KICAD_SPICE diff --git a/qa/unittests/eeschema/test_netlist_exporter_spice.cpp b/qa/unittests/eeschema/test_netlist_exporter_spice.cpp index 59d3c7fcf2..99fb4d49bb 100644 --- a/qa/unittests/eeschema/test_netlist_exporter_spice.cpp +++ b/qa/unittests/eeschema/test_netlist_exporter_spice.cpp @@ -25,263 +25,12 @@ #include #include // To check if the current test failed (to be moved?). -#include -#include -#include +#include #include -#include #include #include -class TEST_NETLIST_EXPORTER_SPICE_FIXTURE : public TEST_NETLIST_EXPORTER_FIXTURE -{ -public: - class SPICE_TEST_REPORTER : public SPICE_REPORTER - { - public: - SPICE_TEST_REPORTER( std::shared_ptr aLog ) : m_log( std::move( aLog ) ) {} - - REPORTER& Report( const wxString& aText, - SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override - { - *m_log << aText << "\n"; - - // You can add a debug trace here. - return *this; - } - - bool HasMessage() const override { return false; } - - void OnSimStateChange( SPICE_SIMULATOR* aObject, SIM_STATE aNewState ) override - { - } - - private: - std::shared_ptr m_log; - }; - - TEST_NETLIST_EXPORTER_SPICE_FIXTURE() : - TEST_NETLIST_EXPORTER_FIXTURE(), - m_simulator( SPICE_SIMULATOR::CreateInstance( "ngspice" ) ), - m_log( std::make_shared() ), - m_reporter( std::make_unique( m_log ) ), - m_abort( false ) - { - } - - ~TEST_NETLIST_EXPORTER_SPICE_FIXTURE() - { - using namespace boost::unit_test; - - test_case::id_t id = framework::current_test_case().p_id; - test_results results = results_collector.results( id ); - - // Output a log if the test has failed. - BOOST_CHECK_MESSAGE( results.passed(), "\nNGSPICE LOG\n===========\n" << *m_log ); - } - - wxFileName GetSchematicPath( const wxString& aBaseName ) override - { - wxFileName fn = KI_TEST::GetEeschemaTestDataDir(); - fn.AppendDir( "spice_netlists" ); - fn.AppendDir( aBaseName ); - fn.SetName( aBaseName ); - fn.SetExt( KiCadSchematicFileExtension ); - - return fn; - } - - wxString GetNetlistPath( bool aTest = false ) override - { - wxFileName netFile = m_schematic.Prj().GetProjectFullName(); - - if( aTest ) - netFile.SetName( netFile.GetName() + "_test" ); - - netFile.SetExt( "spice" ); - return netFile.GetFullPath(); - } - - void CompareNetlists() override - { - m_abort = false; - - // Our simulator is actually Ngspice. - NGSPICE* ngspice = dynamic_cast( m_simulator.get() ); - BOOST_REQUIRE( ngspice ); - - ngspice->SetReporter( m_reporter.get() ); - - wxFFile file( GetNetlistPath( true ), "rt" ); - wxString netlist; - - file.ReadAll( &netlist ); - - //ngspice->Init(); - ngspice->Command( "set ngbehavior=ps" ); - ngspice->Command( "setseed 1" ); - BOOST_REQUIRE( ngspice->LoadNetlist( std::string( netlist.ToUTF8() ) ) ); - BOOST_REQUIRE( ngspice->Run() ); - - // Test if ngspice cannot run a simulation (missing code models). - // in this case the log contains "MIF-ERROR" and/or "Error: circuit not parsed" - // when the simulation is not run the spice command "linearize" crashes. - bool err_found = m_log->Find( wxT( "Error: circuit not parsed" ) ) != wxNOT_FOUND - || m_log->Find( wxT( "MIF-ERROR" ) ) != wxNOT_FOUND; - - if( err_found ) - { - if( m_log->Find( wxT( "MIF-ERROR" ) ) != wxNOT_FOUND ) - wxLogWarning( wxT( "Cannot run ngspice. test skipped. Missing code model files?" ) ); - else - wxLogWarning( wxT( "Cannot run ngspice. test skipped. Install error?" ) ); - - m_abort = true; - - // Still display the original netlist in this case. - *m_log << "Original Netlist\n"; - *m_log << "----------------\n"; - *m_log << netlist << "\n"; - - return; - } - - // We need to make sure that the number of points always the same. - ngspice->Command( "linearize" ); - - - // Debug info. - - // Display all vectors. - ngspice->Command( "echo Available Vectors" ); - ngspice->Command( "echo -----------------" ); - ngspice->Command( "display" ); - - // Display the original netlist. - *m_log << "Original Netlist\n"; - *m_log << "----------------\n"; - *m_log << netlist << "\n"; - - // Display the expanded netlist. - ngspice->Command( "echo Expanded Netlist" ); - ngspice->Command( "echo ----------------" ); - ngspice->Command( "listing runnable" ); - } - - void TestNetlist( const wxString& aBaseName ) - { - // We actually ended up only generating the netlist here. - TEST_NETLIST_EXPORTER_FIXTURE::TestNetlist( aBaseName ); - } - - void TestOpPoint( double aRefValue, const std::string& aVectorName, double aMaxRelError = 1e-2 ) - { - BOOST_TEST_CONTEXT( "Vector name: " << aVectorName ) - { - NGSPICE* ngspice = static_cast( m_simulator.get() ); - - std::vector vector = ngspice->GetRealPlot( aVectorName ); - - BOOST_REQUIRE_EQUAL( vector.size(), 1 ); - - double maxError = abs( aRefValue * aMaxRelError ); - BOOST_CHECK_LE( abs( vector[0] - aRefValue ), aMaxRelError ); - } - } - - void TestPoint( const std::string& aXVectorName, double aXValue, - const std::map aTestVectorsAndValues, - double aMaxRelError = 1e-2 ) - { - // The default aMaxRelError is fairly large because we have some problems with determinism - // in QA pipeline. We don't need to fix this for now because, if this has to be fixed in - // the first place, this has to be done from Ngspice's side. - - BOOST_TEST_CONTEXT( "X vector name: " << aXVectorName << ", X value: " << aXValue ) - { - NGSPICE* ngspice = static_cast( m_simulator.get() ); - - std::vector xVector = ngspice->GetRealPlot( aXVectorName ); - std::size_t i = 0; - - for(; i < xVector.size(); ++i ) - { - double inf = std::numeric_limits::infinity(); - - double leftDelta = ( aXValue - ( i >= 1 ? xVector[i - 1] : -inf ) ); - double middleDelta = ( aXValue - xVector[i] ); - double rightDelta = ( aXValue - ( i < xVector.size() - 1 ? xVector[i + 1] : inf ) ); - - // Check if this point is the closest one. - if( abs( middleDelta ) <= abs( leftDelta ) - && abs( middleDelta ) <= abs( rightDelta ) ) - { - break; - } - } - - BOOST_REQUIRE_LT( i, xVector.size() ); - - for( auto& [vectorName, refValue] : aTestVectorsAndValues ) - { - std::vector yVector = ngspice->GetMagPlot( vectorName ); - - BOOST_REQUIRE_GE( yVector.size(), i + 1 ); - - BOOST_TEST_CONTEXT( "Y vector name: " << vectorName - << ", Ref value: " << refValue - << ", Actual value: " << yVector[i] ) - { - double maxError = abs( refValue * aMaxRelError ); - if( maxError == 0 ) - { - // If refValue is 0, we need a obtain the max. error differently. - maxError = aMaxRelError; - } - - BOOST_CHECK_LE( abs( yVector[i] - refValue ), maxError ); - } - } - } - } - - void TestTranPoint( double aTime, - const std::map aTestVectorsAndValues, - double aMaxRelError = 1e-2 ) - { - TestPoint( "time", aTime, aTestVectorsAndValues, aMaxRelError ); - } - - void TestACPoint( double aFrequency, - const std::map aTestVectorsAndValues, - double aMaxRelError = 1e-2 ) - { - TestPoint( "frequency", aFrequency, aTestVectorsAndValues, aMaxRelError ); - } - - wxString GetResultsPath( bool aTest = false ) - { - wxFileName netlistPath( GetNetlistPath( aTest ) ); - netlistPath.SetExt( "csv" ); - - return netlistPath.GetFullPath(); - } - - unsigned GetNetlistOptions() override - { - return NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES - | NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS - | NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS - | NETLIST_EXPORTER_SPICE::OPTION_SIM_COMMAND; - } - - std::shared_ptr m_simulator; - std::shared_ptr m_log; - std::unique_ptr m_reporter; - bool m_abort; // set to true to force abort durint a test -}; - BOOST_FIXTURE_TEST_SUITE( NetlistExporterSpice, TEST_NETLIST_EXPORTER_SPICE_FIXTURE ) diff --git a/qa/unittests/eeschema/test_netlist_exporter_spice.h b/qa/unittests/eeschema/test_netlist_exporter_spice.h new file mode 100644 index 0000000000..05f61e4162 --- /dev/null +++ b/qa/unittests/eeschema/test_netlist_exporter_spice.h @@ -0,0 +1,280 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2022 KiCad Developers, see AUTHORS.TXT for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef KICAD_SPICE + +#include +#include // To check if the current test failed (to be moved?). +#include +#include +#include +#include +#include +#include +#include + + +class TEST_NETLIST_EXPORTER_SPICE_FIXTURE : public TEST_NETLIST_EXPORTER_FIXTURE +{ +public: + class SPICE_TEST_REPORTER : public SPICE_REPORTER + { + public: + SPICE_TEST_REPORTER( std::shared_ptr aLog ) : + m_log( std::move( aLog ) ) + {} + + REPORTER& Report( const wxString& aText, + SEVERITY aSeverity = RPT_SEVERITY_UNDEFINED ) override + { + *m_log << aText << "\n"; + + // You can add a debug trace here. + return *this; + } + + bool HasMessage() const override { return false; } + + void OnSimStateChange( SPICE_SIMULATOR* aObject, SIM_STATE aNewState ) override { } + + private: + std::shared_ptr m_log; + }; + + TEST_NETLIST_EXPORTER_SPICE_FIXTURE() : + TEST_NETLIST_EXPORTER_FIXTURE(), + m_simulator( SPICE_SIMULATOR::CreateInstance( "ngspice" ) ), + m_log( std::make_shared() ), + m_reporter( std::make_unique( m_log ) ), + m_abort( false ) + { + } + + ~TEST_NETLIST_EXPORTER_SPICE_FIXTURE() + { + using namespace boost::unit_test; + + test_case::id_t id = framework::current_test_case().p_id; + test_results results = results_collector.results( id ); + + // Output a log if the test has failed. + BOOST_CHECK_MESSAGE( results.passed(), "\nNGSPICE LOG\n===========\n" << *m_log ); + } + + wxFileName GetSchematicPath( const wxString& aBaseName ) override + { + wxFileName fn = KI_TEST::GetEeschemaTestDataDir(); + fn.AppendDir( "spice_netlists" ); + fn.AppendDir( aBaseName ); + fn.SetName( aBaseName ); + fn.SetExt( KiCadSchematicFileExtension ); + + return fn; + } + + wxString GetNetlistPath( bool aTest = false ) override + { + wxFileName netFile = m_schematic.Prj().GetProjectFullName(); + + if( aTest ) + netFile.SetName( netFile.GetName() + "_test" ); + + netFile.SetExt( "spice" ); + return netFile.GetFullPath(); + } + + void CompareNetlists() override + { + m_abort = false; + + // Our simulator is actually Ngspice. + NGSPICE* ngspice = dynamic_cast( m_simulator.get() ); + BOOST_REQUIRE( ngspice ); + + ngspice->SetReporter( m_reporter.get() ); + + wxFFile file( GetNetlistPath( true ), "rt" ); + wxString netlist; + + file.ReadAll( &netlist ); + + //ngspice->Init(); + ngspice->Command( "set ngbehavior=ps" ); + ngspice->Command( "setseed 1" ); + BOOST_REQUIRE( ngspice->LoadNetlist( std::string( netlist.ToUTF8() ) ) ); + BOOST_REQUIRE( ngspice->Run() ); + + // Test if ngspice cannot run a simulation (missing code models). + // in this case the log contains "MIF-ERROR" and/or "Error: circuit not parsed" + // when the simulation is not run the spice command "linearize" crashes. + bool err_found = m_log->Find( wxT( "Error: circuit not parsed" ) ) != wxNOT_FOUND + || m_log->Find( wxT( "MIF-ERROR" ) ) != wxNOT_FOUND; + + if( err_found ) + { + if( m_log->Find( wxT( "MIF-ERROR" ) ) != wxNOT_FOUND ) + wxLogWarning( wxT( "Cannot run ngspice. test skipped. Missing code model files?" ) ); + else + wxLogWarning( wxT( "Cannot run ngspice. test skipped. Install error?" ) ); + + m_abort = true; + + // Still display the original netlist in this case. + *m_log << "Original Netlist\n"; + *m_log << "----------------\n"; + *m_log << netlist << "\n"; + + return; + } + + // We need to make sure that the number of points always the same. + ngspice->Command( "linearize" ); + + + // Debug info. + + // Display all vectors. + ngspice->Command( "echo Available Vectors" ); + ngspice->Command( "echo -----------------" ); + ngspice->Command( "display" ); + + // Display the original netlist. + *m_log << "Original Netlist\n"; + *m_log << "----------------\n"; + *m_log << netlist << "\n"; + + // Display the expanded netlist. + ngspice->Command( "echo Expanded Netlist" ); + ngspice->Command( "echo ----------------" ); + ngspice->Command( "listing runnable" ); + } + + void TestOpPoint( double aRefValue, const std::string& aVectorName, double aMaxRelError = 1e-2 ) + { + BOOST_TEST_CONTEXT( "Vector name: " << aVectorName ) + { + NGSPICE* ngspice = static_cast( m_simulator.get() ); + + std::vector vector = ngspice->GetRealPlot( aVectorName ); + + BOOST_REQUIRE_EQUAL( vector.size(), 1 ); + + double maxError = abs( aRefValue * aMaxRelError ); + BOOST_CHECK_LE( abs( vector[0] - aRefValue ), aMaxRelError ); + } + } + + void TestPoint( const std::string& aXVectorName, double aXValue, + const std::map aTestVectorsAndValues, + double aMaxRelError = 1e-2 ) + { + // The default aMaxRelError is fairly large because we have some problems with determinism + // in QA pipeline. We don't need to fix this for now because, if this has to be fixed in + // the first place, this has to be done from Ngspice's side. + + BOOST_TEST_CONTEXT( "X vector name: " << aXVectorName << ", X value: " << aXValue ) + { + NGSPICE* ngspice = static_cast( m_simulator.get() ); + + std::vector xVector = ngspice->GetRealPlot( aXVectorName ); + std::size_t i = 0; + + for(; i < xVector.size(); ++i ) + { + double inf = std::numeric_limits::infinity(); + + double leftDelta = ( aXValue - ( i >= 1 ? xVector[i - 1] : -inf ) ); + double middleDelta = ( aXValue - xVector[i] ); + double rightDelta = ( aXValue - ( i < xVector.size() - 1 ? xVector[i + 1] : inf ) ); + + // Check if this point is the closest one. + if( abs( middleDelta ) <= abs( leftDelta ) + && abs( middleDelta ) <= abs( rightDelta ) ) + { + break; + } + } + + BOOST_REQUIRE_LT( i, xVector.size() ); + + for( auto& [vectorName, refValue] : aTestVectorsAndValues ) + { + std::vector yVector = ngspice->GetMagPlot( vectorName ); + + BOOST_REQUIRE_GE( yVector.size(), i + 1 ); + + BOOST_TEST_CONTEXT( "Y vector name: " << vectorName + << ", Ref value: " << refValue + << ", Actual value: " << yVector[i] ) + { + double maxError = abs( refValue * aMaxRelError ); + if( maxError == 0 ) + { + // If refValue is 0, we need a obtain the max. error differently. + maxError = aMaxRelError; + } + + BOOST_CHECK_LE( abs( yVector[i] - refValue ), maxError ); + } + } + } + } + + void TestTranPoint( double aTime, + const std::map aTestVectorsAndValues, + double aMaxRelError = 1e-2 ) + { + TestPoint( "time", aTime, aTestVectorsAndValues, aMaxRelError ); + } + + void TestACPoint( double aFrequency, + const std::map aTestVectorsAndValues, + double aMaxRelError = 1e-2 ) + { + TestPoint( "frequency", aFrequency, aTestVectorsAndValues, aMaxRelError ); + } + + wxString GetResultsPath( bool aTest = false ) + { + wxFileName netlistPath( GetNetlistPath( aTest ) ); + netlistPath.SetExt( "csv" ); + + return netlistPath.GetFullPath(); + } + + unsigned GetNetlistOptions() override + { + return NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_VOLTAGES + | NETLIST_EXPORTER_SPICE::OPTION_SAVE_ALL_CURRENTS + | NETLIST_EXPORTER_SPICE::OPTION_ADJUST_INCLUDE_PATHS + | NETLIST_EXPORTER_SPICE::OPTION_SIM_COMMAND; + } + + std::shared_ptr m_simulator; + std::shared_ptr m_log; + std::unique_ptr m_reporter; + bool m_abort; // set to true to force abort durint a test +}; + + +#endif // KICAD_SPICE