Add new spice regression test for windows path separators.

This commit is contained in:
Jeff Young 2023-01-21 14:27:33 +00:00
parent 542719c753
commit 6053b86a24
8 changed files with 1161 additions and 252 deletions

View File

@ -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": {}
}

View File

@ -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 "")
)
)
)

View File

@ -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

View File

@ -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)

View File

@ -96,6 +96,7 @@ if( KICAD_SPICE )
sim/test_library_spice.cpp sim/test_library_spice.cpp
sim/test_sim_model_inference.cpp sim/test_sim_model_inference.cpp
sim/test_sim_model_ngspice.cpp sim/test_sim_model_ngspice.cpp
sim/test_sim_regressions.cpp
sim/test_ngspice_helpers.cpp sim/test_ngspice_helpers.cpp
) )
endif() endif()

View File

@ -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 <qa_utils/wx_utils/unit_test_utils.h>
#include <boost/test/results_collector.hpp> // To check if the current test failed (to be moved?).
#include <eeschema_test_utils.h>
#include <test_netlist_exporter_spice.h>
#include <wx/ffile.h>
#include <mock_pgm_base.h>
#include <locale_io.h>
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

View File

@ -25,263 +25,12 @@
#include <qa_utils/wx_utils/unit_test_utils.h> #include <qa_utils/wx_utils/unit_test_utils.h>
#include <boost/test/results_collector.hpp> // To check if the current test failed (to be moved?). #include <boost/test/results_collector.hpp> // To check if the current test failed (to be moved?).
#include <eeschema_test_utils.h> #include <test_netlist_exporter_spice.h>
#include <netlist_exporter_spice.h>
#include <sim/ngspice.h>
#include <sim/spice_reporter.h> #include <sim/spice_reporter.h>
#include <wx/ffile.h>
#include <mock_pgm_base.h> #include <mock_pgm_base.h>
#include <locale_io.h> #include <locale_io.h>
class TEST_NETLIST_EXPORTER_SPICE_FIXTURE : public TEST_NETLIST_EXPORTER_FIXTURE<NETLIST_EXPORTER_SPICE>
{
public:
class SPICE_TEST_REPORTER : public SPICE_REPORTER
{
public:
SPICE_TEST_REPORTER( std::shared_ptr<wxString> 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<wxString> m_log;
};
TEST_NETLIST_EXPORTER_SPICE_FIXTURE() :
TEST_NETLIST_EXPORTER_FIXTURE<NETLIST_EXPORTER_SPICE>(),
m_simulator( SPICE_SIMULATOR::CreateInstance( "ngspice" ) ),
m_log( std::make_shared<wxString>() ),
m_reporter( std::make_unique<SPICE_TEST_REPORTER>( 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<NGSPICE*>( 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<NETLIST_EXPORTER_SPICE>::TestNetlist( aBaseName );
}
void TestOpPoint( double aRefValue, const std::string& aVectorName, double aMaxRelError = 1e-2 )
{
BOOST_TEST_CONTEXT( "Vector name: " << aVectorName )
{
NGSPICE* ngspice = static_cast<NGSPICE*>( m_simulator.get() );
std::vector<double> 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<const std::string, double> 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<NGSPICE*>( m_simulator.get() );
std::vector<double> xVector = ngspice->GetRealPlot( aXVectorName );
std::size_t i = 0;
for(; i < xVector.size(); ++i )
{
double inf = std::numeric_limits<double>::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<double> 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<const std::string, double> aTestVectorsAndValues,
double aMaxRelError = 1e-2 )
{
TestPoint( "time", aTime, aTestVectorsAndValues, aMaxRelError );
}
void TestACPoint( double aFrequency,
const std::map<const std::string, double> 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<SPICE_SIMULATOR> m_simulator;
std::shared_ptr<wxString> m_log;
std::unique_ptr<SPICE_TEST_REPORTER> m_reporter;
bool m_abort; // set to true to force abort durint a test
};
BOOST_FIXTURE_TEST_SUITE( NetlistExporterSpice, TEST_NETLIST_EXPORTER_SPICE_FIXTURE ) BOOST_FIXTURE_TEST_SUITE( NetlistExporterSpice, TEST_NETLIST_EXPORTER_SPICE_FIXTURE )

View File

@ -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 <qa_utils/wx_utils/unit_test_utils.h>
#include <boost/test/results_collector.hpp> // To check if the current test failed (to be moved?).
#include <eeschema_test_utils.h>
#include <netlist_exporter_spice.h>
#include <sim/ngspice.h>
#include <sim/spice_reporter.h>
#include <wx/ffile.h>
#include <mock_pgm_base.h>
#include <locale_io.h>
class TEST_NETLIST_EXPORTER_SPICE_FIXTURE : public TEST_NETLIST_EXPORTER_FIXTURE<NETLIST_EXPORTER_SPICE>
{
public:
class SPICE_TEST_REPORTER : public SPICE_REPORTER
{
public:
SPICE_TEST_REPORTER( std::shared_ptr<wxString> 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<wxString> m_log;
};
TEST_NETLIST_EXPORTER_SPICE_FIXTURE() :
TEST_NETLIST_EXPORTER_FIXTURE<NETLIST_EXPORTER_SPICE>(),
m_simulator( SPICE_SIMULATOR::CreateInstance( "ngspice" ) ),
m_log( std::make_shared<wxString>() ),
m_reporter( std::make_unique<SPICE_TEST_REPORTER>( 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<NGSPICE*>( 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<NGSPICE*>( m_simulator.get() );
std::vector<double> 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<const std::string, double> 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<NGSPICE*>( m_simulator.get() );
std::vector<double> xVector = ngspice->GetRealPlot( aXVectorName );
std::size_t i = 0;
for(; i < xVector.size(); ++i )
{
double inf = std::numeric_limits<double>::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<double> 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<const std::string, double> aTestVectorsAndValues,
double aMaxRelError = 1e-2 )
{
TestPoint( "time", aTime, aTestVectorsAndValues, aMaxRelError );
}
void TestACPoint( double aFrequency,
const std::map<const std::string, double> 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<SPICE_SIMULATOR> m_simulator;
std::shared_ptr<wxString> m_log;
std::unique_ptr<SPICE_TEST_REPORTER> m_reporter;
bool m_abort; // set to true to force abort durint a test
};
#endif // KICAD_SPICE