spice wip

This commit is contained in:
Tomasz Wlostowski 2016-08-11 14:40:57 +02:00 committed by Maciej Suminski
parent 0bf4a6447d
commit 2dd53b6a43
8 changed files with 149 additions and 125 deletions

View File

@ -59,6 +59,7 @@ endif()
option( BUILD_GITHUB_PLUGIN "Build the GITHUB_PLUGIN for pcbnew." ON )
option( KICAD_SPICE "Build Kicad with internal Spice simulator." OFF )
# This can be set to a custom name to brag about a particular branch in the "About" dialog:
set( KICAD_REPO_NAME "product" CACHE STRING "Name of the tree from which this build came." )
@ -98,7 +99,7 @@ endif()
# Add option to add user directories for linker, if any
LINK_DIRECTORIES( ${LINK_DIRECTORIES_PATH} )
LINK_DIRECTORIES( ${LINK_DIRECTORIES_PATH} /usr/local/lib )
if( UNIX )
set( KICAD_USER_CONFIG_DIR $ENV{HOME} CACHE PATH "Location of user specific KiCad config files" )
@ -436,7 +437,9 @@ add_definitions( -DWX_COMPATIBILITY )
# See line 41 of CMakeModules/FindwxWidgets.cmake
set( wxWidgets_CONFIG_OPTIONS ${wxWidgets_CONFIG_OPTIONS} --static=no )
find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml stc REQUIRED )
find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml stc richtext REQUIRED )
# Include wxWidgets macros.
include( ${wxWidgets_USE_FILE} )
@ -517,6 +520,10 @@ set( INC_AFTER
)
#if ( KICAD_SPICE )
# find_package(MathGL2 2.3.4 COMPONENTS wx REQUIRED )
#endif ()
# Find Python and other scripting resources
if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES )
# force a python version < 3.0

View File

@ -7,6 +7,7 @@ include_directories(
./widgets
../common
../common/dialogs
./ngspice
${INC_AFTER}
)
@ -175,6 +176,9 @@ set( EESCHEMA_SRCS
transform.cpp
viewlib_frame.cpp
viewlibs.cpp
sim/simulate.cpp
sim/dialog_simulate_plot.cpp
sim/ngspice.cpp
netlist_exporters/netlist_exporter.cpp
netlist_exporters/netlist_exporter_cadstar.cpp
@ -241,12 +245,19 @@ add_executable( eeschema WIN32 MACOSX_BUNDLE
set_source_files_properties( ../common/single_top.cpp PROPERTIES
COMPILE_DEFINITIONS "TOP_FRAME=FRAME_SCH;PGM_DATA_FILE_EXT=\"sch\";BUILD_KIWAY_DLL"
)
if (KICAD_SPICE)
set ( EESCHEMA_LINK_LIBS ${wxWidgets_LIBRARIES} mgl mgl-wx)
else()
set ( EESCHEMA_LINK_LIBS ${wxWidgets_LIBRARIES} )
endif()
target_link_libraries( eeschema
#singletop # replaces common, giving us restrictive control and link warnings.
# There's way too much crap coming in from common yet.
common
bitmaps
${wxWidgets_LIBRARIES}
${EESCHEMA_LINK_LIBS}
)
# the DSO (KIFACE) housing the main eeschema code:
@ -259,9 +270,9 @@ target_link_libraries( eeschema_kiface
bitmaps
polygon
gal
${wxWidgets_LIBRARIES}
${EESCHEMA_LINK_LIBS}
${GDI_PLUS_LIBRARIES}
)
)
set_target_properties( eeschema_kiface PROPERTIES
# Decorate OUTPUT_NAME with PREFIX and SUFFIX, creating something like
# _eeschema.so, _eeschema.dll, or _eeschema.kiface

View File

@ -254,7 +254,11 @@ enum id_eeschema_frm
ID_END_EESCHEMA_ID_LIST,
ID_UPDATE_PCB_FROM_SCH,
ID_UPDATE_SCH_FROM_PCB
ID_UPDATE_SCH_FROM_PCB,
ID_SIM_RUN,
ID_SIM_STOP,
ID_SIM_ADD_PROBE
};

View File

@ -422,6 +422,25 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
_( "Import and export settings" ),
KiBitmap( save_setup_xpm ) );
wxMenu* simMenu = new wxMenu;
AddMenuItem( simMenu,
ID_SIM_RUN,
_("Run simulation"), _( "Run simulation" ),
KiBitmap( pcbnew_xpm ) );
AddMenuItem( simMenu,
ID_SIM_STOP,
_( "Stop simulation" ), _( "Stop simulation" ),
KiBitmap( pcbnew_xpm ) );
AddMenuItem( simMenu,
ID_SIM_ADD_PROBE,
_( "Add probe" ), _( "Add probe" ),
KiBitmap( pcbnew_xpm ) );
// Menu Tools:
wxMenu* toolsMenu = new wxMenu;
@ -526,6 +545,7 @@ void SCH_EDIT_FRAME::ReCreateMenuBar()
menuBar->Append( viewMenu, _( "&View" ) );
menuBar->Append( placeMenu, _( "&Place" ) );
menuBar->Append( preferencesMenu, _( "P&references" ) );
menuBar->Append( simMenu, _( "&Simulate" ) );
menuBar->Append( toolsMenu, _( "&Tools" ) );
menuBar->Append( helpMenu, _( "&Help" ) );

View File

@ -27,6 +27,8 @@
#include <build_version.h>
#include <confirm.h>
#include <map>
#include <schframe.h>
#include <netlist.h>
#include <sch_reference_list.h>
@ -36,9 +38,13 @@
bool NETLIST_EXPORTER_PSPICE::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
{
FILE* f = NULL;
bool aUsePrefix = aNetlistOptions & NET_USE_X_PREFIX;
bool aUseNetcodeAsNetName = aNetlistOptions & NET_USE_NETCODES_AS_NETNAMES;
return false;
}
bool NETLIST_EXPORTER_PSPICE::Format( OUTPUTFORMATTER* formatter, int aCtl )
{
bool aUsePrefix = aCtl & NET_USE_X_PREFIX;
int ret = 0;
int nbitems;
@ -55,31 +61,23 @@ bool NETLIST_EXPORTER_PSPICE::WriteNetlist( const wxString& aOutFileName, unsign
wxString delimeters = wxT( "{:,; }" );
wxString disableStr = wxT( "N" );
if( ( f = wxFopen( aOutFileName, wxT( "wt" ) ) ) == NULL )
{
msg.Printf( _( "Failed to create file '%s'" ),
GetChars( aOutFileName ) );
DisplayError( NULL, msg );
return false;
}
ret |= fprintf( f, "* %s\n\n", TO_UTF8( aOutFileName ) );
ret |= fprintf( f, "* %s (Spice format) creation date: %s\n\n",
NETLIST_HEAD_STRING, TO_UTF8( DateAndTime() ) );
std::map<wxString, int> netIndices;
// Prepare list of nets generation (not used here, but...
for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
m_masterList->GetItem( ii )->m_Flag = 0;
ret |= fprintf( f, "* To exclude a component from the Spice Netlist add [Spice_Netlist_Enabled] user FIELD set to: N\n" );
ret |= fprintf( f, "* To reorder the component spice node sequence add [Spice_Node_Sequence] user FIELD and define sequence: 2,1,0\n" );
// Create text list starting by [.-]pspice , or [.-]gnucap (simulator
// commands) and create text list starting by [+]pspice , or [+]gnucap
// (simulator commands)
bufnum[BUFYPOS_LEN] = 0;
SCH_SHEET_LIST sheetList( g_RootSheet );
std::vector<wxString> directives;
std::vector<wxString> probeNets;
netIndices["GND"] = 0;
for( unsigned i = 0; i < sheetList.size(); i++ )
{
for( EDA_ITEM* item = sheetList[i].LastDrawList(); item; item = item->Next() )
@ -99,72 +97,24 @@ bool NETLIST_EXPORTER_PSPICE::WriteNetlist( const wxString& aOutFileName, unsign
ident = text.GetChar( 0 );
if( ident != '.' && ident != '-' && ident != '+' )
continue;
text.Remove( 0, 1 ); // Remove the first char.
text.Remove( 6 ); // text contains 6 char.
text.MakeLower();
if( text != wxT( "pspice" ) && text != wxT( "gnucap" ) )
continue;
text = drawText->GetText().Mid( 7 );
l1 = text.Length();
text.Trim( false );
l2 = text.Length();
if( l1 == l2 )
continue; // no whitespace after ident text
if( ident == '.' )
{
// Put the Y position as an ascii string, for sort by vertical
// position, using usual sort string by alphabetic value
int ypos = drawText->GetPosition().y;
for( int ii = 0; ii < BUFYPOS_LEN; ii++ )
{
bufnum[BUFYPOS_LEN - 1 - ii] = (ypos & 63) + ' ';
ypos >>= 6;
}
// First BUFYPOS_LEN char are the Y position.
msg.Printf( wxT( "%s %s" ), bufnum, text.GetData() );
if( ident == '+' )
spiceCommandAtEndFile.Add( msg );
else
spiceCommandAtBeginFile.Add( msg );
printf("Directive found: '%s'\n", (const char *) text.c_str());
directives.push_back(text);
}
}
}
// Print texts starting by [.-]pspice , ou [.-]gnucap (of course, without
// the Y position string)
nbitems = spiceCommandAtBeginFile.GetCount();
if( nbitems )
{
spiceCommandAtBeginFile.Sort();
for( int ii = 0; ii < nbitems; ii++ )
{
spiceCommandAtBeginFile[ii].Remove( 0, BUFYPOS_LEN );
spiceCommandAtBeginFile[ii].Trim( true );
spiceCommandAtBeginFile[ii].Trim( false );
ret |= fprintf( f, "%s\n", TO_UTF8( spiceCommandAtBeginFile[ii] ) );
}
}
ret |= fprintf( f, "\n" );
// Create component list
m_ReferencesAlreadyFound.Clear();
int curNetIndex = 1;
for( unsigned sheet_idx = 0; sheet_idx < sheetList.size(); sheet_idx++ )
{
ret |= fprintf( f, "* Sheet Name: %s\n",
TO_UTF8( sheetList[sheet_idx].PathHumanReadable() ) );
//printf( "* Sheet Name: %s\n",
// TO_UTF8( sheetList[sheet_idx].PathHumanReadable() ) );
for( EDA_ITEM* item = sheetList[sheet_idx].LastDrawList(); item; item = item->Next() )
{
@ -178,6 +128,33 @@ bool NETLIST_EXPORTER_PSPICE::WriteNetlist( const wxString& aOutFileName, unsign
// Reset NodeSeqIndex Count:
pinSequence.clear();
SCH_FIELD* spicePrimitiveType = comp->FindField( wxT( "Spice_Primitive" ) );
SCH_FIELD* spiceModel = comp->FindField( wxT( "Spice_Model" ) );
wxString RefName = comp->GetRef( &sheetList[sheet_idx] );
wxString CompValue = comp->GetField( VALUE )->GetText();
wxString model("");
wxString primType ("X");
if(spicePrimitiveType)
primType = spicePrimitiveType->GetText();
else {
if (RefName.StartsWith(wxT("IC")) || RefName.StartsWith("U") )
primType = wxT("X"); // subckt
else
primType = RefName.GetChar(0);
}
if(spiceModel)
{
// printf("model specified\n");
model = spiceModel->GetText();
} else {
// printf("no model\n");
model = CompValue;
}
// Check to see if component should be removed from Spice Netlist:
SCH_FIELD* netlistEnabledField = comp->FindField( wxT( "Spice_Netlist_Enabled" ) );
@ -234,21 +211,30 @@ bool NETLIST_EXPORTER_PSPICE::WriteNetlist( const wxString& aOutFileName, unsign
}
}
//Get Standard Reference Designator:
wxString RefName = comp->GetRef( &sheetList[sheet_idx] );
if(CompValue == wxT("SPICE_PROBE"))
{
NETLIST_OBJECT* pin = m_SortedComponentPinList[0];
printf("Probe net: %s\n", (const char*) pin->GetNetName().c_str() );
probeNets.push_back(pin->GetNetName());
continue;
}
//Conditionally add Prefix only for devices that begin with U or IC:
if( aUsePrefix )
{
if( RefName.StartsWith( wxT( "U" ) ) || RefName.StartsWith( wxT( "IC" ) ) )
RefName = wxT( "X" ) + RefName;
//if( RefName.StartsWith( wxT( "U" ) ) || RefName.StartsWith( wxT( "IC" ) ) )
// RefName = wxT( "X" ) + RefName;
}
ret |= fprintf( f, "%s ", TO_UTF8( RefName ) );
printf( "Ref %s primType %s model/value '%s'\n", TO_UTF8( RefName ), (const char*)primType.c_str(), (const char *)model.c_str() );
// Write pin list:
int activePinIndex = 0;
formatter->Print(0, "%s%s ", (const char *)primType.c_str(), (const char *)RefName.c_str());
for( unsigned ii = 0; ii < m_SortedComponentPinList.size(); ii++ )
{
// Case of Alt Sequence definition with Unused/Invalid Node index:
@ -282,56 +268,41 @@ bool NETLIST_EXPORTER_PSPICE::WriteNetlist( const wxString& aOutFileName, unsign
if( !pin )
continue;
sprintPinNetName( netName , wxT( "N-%.6d" ), pin, aUseNetcodeAsNetName );
wxString netName = pin->GetNetName();
int netIdx;
if (netIndices.find(netName) == netIndices.end())
{
netIdx = curNetIndex++;
netIndices[netName] = netIdx;
} else {
netIdx = netIndices[netName];
}
//printf("net %s index %d\n", (const char*)netName.c_str(), netIdx);
// sprintPinNetName( netName , wxT( "N-%.6d" ), pin, aUseNetcodeAsNetName );
//Replace parenthesis with underscore to prevent parse issues with Simulators:
netName.Replace( wxT( "(" ), wxT( "_" ) );
netName.Replace( wxT( ")" ), wxT( "_" ) );
// netName.Replace( wxT( "(" ), wxT( "_" ) );
// netName.Replace( wxT( ")" ), wxT( "_" ) );
if( netName.IsEmpty() )
netName = wxT( "?" );
// if( netName.IsEmpty() )
// netName = wxT( "?" );
ret |= fprintf( f, " %s", TO_UTF8( netName ) );
// ret |= fprintf( f, " %s", TO_UTF8( netName ) );
formatter->Print(0, "%d ", netIdx );
}
// Get Component Value Name:
wxString CompValue = comp->GetField( VALUE )->GetText();
formatter->Print(0, "%s\n",(const char *) model.c_str());
// Check if Override Model Name is Provided:
SCH_FIELD* spiceModelField = comp->FindField( wxT( "spice_model" ) );
if( spiceModelField )
{
// Get Model Name String:
wxString ModelNameStr = spiceModelField->GetText();
// Verify Field Exists and is not empty:
if( !ModelNameStr.IsEmpty() )
CompValue = ModelNameStr;
}
// Print Component Value:
ret |= fprintf( f, " %s\t\t",TO_UTF8( CompValue ) );
// Show Seq Spec on same line as component using line-comment ";":
for( unsigned ii = 0; ii < pinSequence.size(); ++ii )
{
if( ii == 0 )
ret |= fprintf( f, ";Node Sequence Spec.<" );
ret |= fprintf( f, "%s", TO_UTF8( stdPinNameArray.Item( pinSequence[ii] ) ) );
if( ii < pinSequence.size()-1 )
ret |= fprintf( f, "," );
else
ret |= fprintf( f, ">" );
}
// Next Netlist line record:
ret |= fprintf( f, "\n" );
}
}
#if 0
m_SortedComponentPinList.clear();
// Print texts starting with [+]pspice or [+]gnucap
@ -354,5 +325,8 @@ bool NETLIST_EXPORTER_PSPICE::WriteNetlist( const wxString& aOutFileName, unsign
ret |= fprintf( f, "\n.end\n" );
fclose( f );
#endif
return ret >= 0;
}

View File

@ -45,6 +45,9 @@ public:
* writes to specified output file
*/
bool WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions );
bool Format( OUTPUTFORMATTER* aOutputFormatter, int aCtl );
};
#endif

View File

@ -264,6 +264,9 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME )
EVT_TOOL( ID_GET_ERC, SCH_EDIT_FRAME::OnErc )
EVT_TOOL( ID_GET_NETLIST, SCH_EDIT_FRAME::OnCreateNetlist )
EVT_TOOL( ID_UPDATE_PCB_FROM_SCH, SCH_EDIT_FRAME::OnUpdatePCB )
EVT_TOOL( ID_SIM_RUN, SCH_EDIT_FRAME::OnSimulationRun )
EVT_TOOL( ID_SIM_STOP, SCH_EDIT_FRAME::OnSimulationStop )
EVT_TOOL( ID_SIM_ADD_PROBE, SCH_EDIT_FRAME::OnSimulationAddProbe )
EVT_TOOL( ID_GET_TOOLS, SCH_EDIT_FRAME::OnCreateBillOfMaterials )
EVT_TOOL( ID_FIND_ITEMS, SCH_EDIT_FRAME::OnFindItems )
EVT_TOOL( wxID_REPLACE, SCH_EDIT_FRAME::OnFindItems )
@ -1371,4 +1374,3 @@ void SCH_EDIT_FRAME::UpdateTitle()
SetTitle( title );
}

View File

@ -813,6 +813,9 @@ private:
void OnErc( wxCommandEvent& event );
void OnCreateNetlist( wxCommandEvent& event );
void OnUpdatePCB( wxCommandEvent& event );
void OnSimulationRun( wxCommandEvent& event );
void OnSimulationStop( wxCommandEvent& event );
void OnSimulationAddProbe( wxCommandEvent& event );
void OnCreateBillOfMaterials( wxCommandEvent& event );
void OnFindItems( wxCommandEvent& event );
void OnFindDialogClose( wxFindDialogEvent& event );