Moved SPICE_VALUE to a separate source file
This commit is contained in:
parent
f62a6425a3
commit
4f9a418694
|
@ -182,6 +182,7 @@ set( EESCHEMA_SRCS
|
|||
sim/sim_plot_frame.cpp
|
||||
sim/sim_plot_panel.cpp
|
||||
sim/spice_simulator.cpp
|
||||
sim/spice_value.cpp
|
||||
sim/ngspice.cpp
|
||||
sim/netlist_exporter_pspice_sim.cpp
|
||||
dialogs/dialog_signal_list.cpp
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
*/
|
||||
|
||||
#include "dialog_spice_model.h"
|
||||
|
||||
#include <netlist_exporters/netlist_exporter_pspice.h>
|
||||
#include <sim/spice_value.h>
|
||||
|
||||
#include <wx/tokenzr.h>
|
||||
|
||||
|
|
|
@ -381,91 +381,6 @@ void NETLIST_EXPORTER_PSPICE::writeDirectives( OUTPUTFORMATTER* aFormatter, unsi
|
|||
}
|
||||
|
||||
|
||||
SPICE_VALUE::SPICE_VALUE( const wxString& aString )
|
||||
{
|
||||
char buf[8] = { 0, };
|
||||
|
||||
if( sscanf( (const char*) aString.c_str(), "%lf%7s", &m_base, buf ) == 0 )
|
||||
throw std::invalid_argument( "Invalid Spice value string" );
|
||||
|
||||
if( *buf == 0 )
|
||||
{
|
||||
m_prefix = PFX_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
for( char* bufPtr = buf; *bufPtr; ++bufPtr )
|
||||
*bufPtr = tolower( *bufPtr );
|
||||
|
||||
if( !strcmp( buf, "meg" ) )
|
||||
{
|
||||
m_prefix = PFX_MEGA;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( buf[0] )
|
||||
{
|
||||
case 'f': m_prefix = PFX_FEMTO; break;
|
||||
case 'p': m_prefix = PFX_PICO; break;
|
||||
case 'n': m_prefix = PFX_NANO; break;
|
||||
case 'u': m_prefix = PFX_MICRO; break;
|
||||
case 'm': m_prefix = PFX_MILI; break;
|
||||
case 'k': m_prefix = PFX_KILO; break;
|
||||
case 'g': m_prefix = PFX_GIGA; break;
|
||||
case 't': m_prefix = PFX_TERA; break;
|
||||
|
||||
default:
|
||||
throw std::invalid_argument( "Invalid unit prefix" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SPICE_VALUE::SPICE_VALUE( int aInt, UNIT_PREFIX aPrefix )
|
||||
: m_base( aInt ), m_prefix( aPrefix )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
SPICE_VALUE::SPICE_VALUE( double aDouble, UNIT_PREFIX aPrefix )
|
||||
: m_base( aDouble ), m_prefix( aPrefix )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
double SPICE_VALUE::ToDouble() const
|
||||
{
|
||||
double res = m_base;
|
||||
|
||||
if( m_prefix != PFX_NONE )
|
||||
res *= pow( 10, (int) m_prefix );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
wxString SPICE_VALUE::ToSpiceString() const
|
||||
{
|
||||
wxString res = wxString::Format( "%f", m_base );
|
||||
|
||||
switch( m_prefix )
|
||||
{
|
||||
case PFX_FEMTO: res += "f"; break;
|
||||
case PFX_PICO: res += "p"; break;
|
||||
case PFX_NANO: res += "n"; break;
|
||||
case PFX_MICRO: res += "u"; break;
|
||||
case PFX_MILI: res += "m"; break;
|
||||
case PFX_NONE: break;
|
||||
case PFX_KILO: res += "k"; break;
|
||||
case PFX_MEGA: res += "Meg"; break;
|
||||
case PFX_GIGA: res += "G"; break;
|
||||
case PFX_TERA: res += "T"; break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// Entries in the vector below have to follow the order in SPICE_FIELD enum
|
||||
const std::vector<wxString> NETLIST_EXPORTER_PSPICE::m_spiceFields = {
|
||||
"Spice_Primitive",
|
||||
|
|
|
@ -170,41 +170,4 @@ private:
|
|||
static const std::vector<wxString> m_spiceFields;
|
||||
};
|
||||
|
||||
|
||||
// Helper class to handle Spice way of expressing values (e.g. 10.5m)
|
||||
class SPICE_VALUE
|
||||
{
|
||||
public:
|
||||
enum UNIT_PREFIX
|
||||
{
|
||||
PFX_FEMTO = -15,
|
||||
PFX_PICO = -12,
|
||||
PFX_NANO = -9,
|
||||
PFX_MICRO = -6,
|
||||
PFX_MILI = -3,
|
||||
PFX_NONE = 0,
|
||||
PFX_KILO = 3,
|
||||
PFX_MEGA = 6,
|
||||
PFX_GIGA = 9,
|
||||
PFX_TERA = 12
|
||||
};
|
||||
|
||||
SPICE_VALUE( const wxString& aString );
|
||||
SPICE_VALUE( int aInt, UNIT_PREFIX aPrefix = PFX_NONE );
|
||||
SPICE_VALUE( double aDouble, UNIT_PREFIX aPrefix = PFX_NONE );
|
||||
|
||||
double ToDouble() const;
|
||||
|
||||
wxString ToSpiceString() const;
|
||||
|
||||
wxString ToString() const
|
||||
{
|
||||
return wxString::Format( "%f", ToDouble() );
|
||||
}
|
||||
|
||||
private:
|
||||
double m_base;
|
||||
UNIT_PREFIX m_prefix;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 CERN
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* 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 3
|
||||
* 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:
|
||||
* https://www.gnu.org/licenses/gpl-3.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "spice_value.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <cmath>
|
||||
|
||||
SPICE_VALUE::SPICE_VALUE( const wxString& aString )
|
||||
{
|
||||
char buf[8] = { 0, };
|
||||
|
||||
if( sscanf( (const char*) aString.c_str(), "%lf%7s", &m_base, buf ) == 0 )
|
||||
throw std::invalid_argument( "Invalid Spice value string" );
|
||||
|
||||
if( *buf == 0 )
|
||||
{
|
||||
m_prefix = PFX_NONE;
|
||||
m_spiceStr = false;
|
||||
Normalize();
|
||||
return;
|
||||
}
|
||||
|
||||
m_spiceStr = true;
|
||||
|
||||
for( char* bufPtr = buf; *bufPtr; ++bufPtr )
|
||||
*bufPtr = tolower( *bufPtr );
|
||||
|
||||
if( !strcmp( buf, "meg" ) )
|
||||
{
|
||||
m_prefix = PFX_MEGA;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( buf[0] )
|
||||
{
|
||||
case 'f': m_prefix = PFX_FEMTO; break;
|
||||
case 'p': m_prefix = PFX_PICO; break;
|
||||
case 'n': m_prefix = PFX_NANO; break;
|
||||
case 'u': m_prefix = PFX_MICRO; break;
|
||||
case 'm': m_prefix = PFX_MILI; break;
|
||||
case 'k': m_prefix = PFX_KILO; break;
|
||||
case 'g': m_prefix = PFX_GIGA; break;
|
||||
case 't': m_prefix = PFX_TERA; break;
|
||||
|
||||
default:
|
||||
throw std::invalid_argument( "Invalid unit prefix" );
|
||||
}
|
||||
}
|
||||
|
||||
Normalize();
|
||||
}
|
||||
|
||||
|
||||
void SPICE_VALUE::Normalize()
|
||||
{
|
||||
while( std::fabs( m_base ) >= 1000.0 )
|
||||
{
|
||||
m_base *= 0.001;
|
||||
m_prefix = (UNIT_PREFIX)( m_prefix + 3 );
|
||||
}
|
||||
|
||||
while( m_base != 0.0 && std::fabs( m_base ) <= 0.001 )
|
||||
{
|
||||
m_base *= 1000.0;
|
||||
m_prefix = (UNIT_PREFIX)( m_prefix - 3 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double SPICE_VALUE::ToDouble() const
|
||||
{
|
||||
double res = m_base;
|
||||
|
||||
if( m_prefix != PFX_NONE )
|
||||
res *= std::pow( 10, (int) m_prefix );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
wxString SPICE_VALUE::ToString() const
|
||||
{
|
||||
wxString res( wxString::Format( "%.3f", ToDouble() ) );
|
||||
stripZeros( res );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
wxString SPICE_VALUE::ToSpiceString() const
|
||||
{
|
||||
wxString res = wxString::Format( "%f", m_base );
|
||||
stripZeros( res );
|
||||
|
||||
switch( m_prefix )
|
||||
{
|
||||
case PFX_FEMTO: res += "f"; break;
|
||||
case PFX_PICO: res += "p"; break;
|
||||
case PFX_NANO: res += "n"; break;
|
||||
case PFX_MICRO: res += "u"; break;
|
||||
case PFX_MILI: res += "m"; break;
|
||||
case PFX_NONE: break;
|
||||
case PFX_KILO: res += "k"; break;
|
||||
case PFX_MEGA: res += "Meg"; break;
|
||||
case PFX_GIGA: res += "G"; break;
|
||||
case PFX_TERA: res += "T"; break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
SPICE_VALUE SPICE_VALUE::operator+( const SPICE_VALUE& aOther ) const
|
||||
{
|
||||
int prefixDiff = m_prefix - aOther.m_prefix;
|
||||
SPICE_VALUE res;
|
||||
res.m_spiceStr = m_spiceStr || aOther.m_spiceStr;
|
||||
|
||||
// Convert both numbers to a common prefix
|
||||
if( prefixDiff > 0 )
|
||||
{
|
||||
// Switch to the aOther prefix
|
||||
res.m_base = ( m_base * std::pow( 10, prefixDiff ) ) + aOther.m_base;
|
||||
res.m_prefix = aOther.m_prefix;
|
||||
}
|
||||
else if( prefixDiff < 0 )
|
||||
{
|
||||
// Use the current prefix
|
||||
res.m_base = m_base + ( aOther.m_base * std::pow( 10, -prefixDiff ) );
|
||||
res.m_prefix = m_prefix;
|
||||
}
|
||||
else
|
||||
{
|
||||
res.m_base = m_base + aOther.m_base;
|
||||
res.m_prefix = m_prefix; // == aOther.m_prefix
|
||||
}
|
||||
|
||||
res.Normalize();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
SPICE_VALUE SPICE_VALUE::operator-( const SPICE_VALUE& aOther ) const
|
||||
{
|
||||
int prefixDiff = m_prefix - aOther.m_prefix;
|
||||
SPICE_VALUE res;
|
||||
res.m_spiceStr = m_spiceStr || aOther.m_spiceStr;
|
||||
|
||||
// Convert both numbers to a common prefix
|
||||
if( prefixDiff > 0 )
|
||||
{
|
||||
// Switch to the aOther prefix
|
||||
res.m_base = m_prefix * std::pow( 10, prefixDiff ) - aOther.m_prefix;
|
||||
res.m_prefix = aOther.m_prefix;
|
||||
}
|
||||
else if( prefixDiff < 0 )
|
||||
{
|
||||
// Use the current prefix
|
||||
res.m_base = m_prefix - aOther.m_prefix * std::pow( 10, -prefixDiff );
|
||||
res.m_prefix = m_prefix;
|
||||
}
|
||||
else
|
||||
{
|
||||
res.m_base = m_base - aOther.m_base;
|
||||
res.m_prefix = m_prefix; // == aOther.m_prefix
|
||||
}
|
||||
|
||||
res.Normalize();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
SPICE_VALUE SPICE_VALUE::operator*( const SPICE_VALUE& aOther ) const
|
||||
{
|
||||
SPICE_VALUE res( m_base * aOther.m_base, (UNIT_PREFIX)( m_prefix + aOther.m_prefix ) );
|
||||
res.m_spiceStr = m_spiceStr || aOther.m_spiceStr;
|
||||
res.Normalize();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
SPICE_VALUE SPICE_VALUE::operator/( const SPICE_VALUE& aOther ) const
|
||||
{
|
||||
SPICE_VALUE res( m_base / aOther.m_base, (UNIT_PREFIX)( m_prefix - aOther.m_prefix ) );
|
||||
res.m_spiceStr = m_spiceStr || aOther.m_spiceStr;
|
||||
res.Normalize();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
void SPICE_VALUE::stripZeros( wxString& aString )
|
||||
{
|
||||
while( aString.EndsWith( '0' ) )
|
||||
aString.RemoveLast();
|
||||
|
||||
if( aString.EndsWith( '.' ) )
|
||||
aString.RemoveLast();
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2016 CERN
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* 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 3
|
||||
* 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:
|
||||
* https://www.gnu.org/licenses/gpl-3.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 3 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef SPICE_VALUE_H
|
||||
#define SPICE_VALUE_H
|
||||
|
||||
#include <wx/string.h>
|
||||
|
||||
///> Helper class to handle Spice way of expressing values (e.g. 10.5 Meg)
|
||||
class SPICE_VALUE
|
||||
{
|
||||
public:
|
||||
enum UNIT_PREFIX
|
||||
{
|
||||
PFX_FEMTO = -15,
|
||||
PFX_PICO = -12,
|
||||
PFX_NANO = -9,
|
||||
PFX_MICRO = -6,
|
||||
PFX_MILI = -3,
|
||||
PFX_NONE = 0,
|
||||
PFX_KILO = 3,
|
||||
PFX_MEGA = 6,
|
||||
PFX_GIGA = 9,
|
||||
PFX_TERA = 12
|
||||
};
|
||||
|
||||
SPICE_VALUE()
|
||||
: m_base( 0 ), m_prefix( PFX_NONE )
|
||||
{
|
||||
}
|
||||
|
||||
SPICE_VALUE( const wxString& aString );
|
||||
|
||||
SPICE_VALUE( int aInt, UNIT_PREFIX aPrefix = PFX_NONE )
|
||||
: m_base( aInt ), m_prefix( aPrefix ), m_spiceStr( false )
|
||||
{
|
||||
}
|
||||
|
||||
SPICE_VALUE( double aDouble, UNIT_PREFIX aPrefix = PFX_NONE )
|
||||
: m_base( aDouble ), m_prefix( aPrefix ), m_spiceStr( false )
|
||||
{
|
||||
}
|
||||
|
||||
void Normalize();
|
||||
|
||||
double ToDouble() const;
|
||||
|
||||
wxString ToString() const;
|
||||
|
||||
wxString ToSpiceString() const;
|
||||
|
||||
wxString ToOrigString() const
|
||||
{
|
||||
return m_spiceStr ? ToSpiceString() : ToString();
|
||||
}
|
||||
|
||||
bool IsSpiceString() const
|
||||
{
|
||||
return m_spiceStr;
|
||||
}
|
||||
|
||||
bool operator==( const SPICE_VALUE& aOther ) const
|
||||
{
|
||||
return ( m_prefix == aOther.m_prefix && m_base == aOther.m_base );
|
||||
}
|
||||
|
||||
bool operator>( const SPICE_VALUE& aOther ) const
|
||||
{
|
||||
return this->ToDouble() > aOther.ToDouble();
|
||||
}
|
||||
|
||||
bool operator<( const SPICE_VALUE& aOther ) const
|
||||
{
|
||||
return this->ToDouble() < aOther.ToDouble();
|
||||
}
|
||||
|
||||
bool operator>=( const SPICE_VALUE& aOther ) const
|
||||
{
|
||||
return ( *this == aOther || *this > aOther );
|
||||
}
|
||||
|
||||
bool operator<=( const SPICE_VALUE& aOther ) const
|
||||
{
|
||||
return ( *this == aOther || *this < aOther );
|
||||
}
|
||||
|
||||
SPICE_VALUE operator-( const SPICE_VALUE& aOther ) const;
|
||||
SPICE_VALUE operator+( const SPICE_VALUE& aOther ) const;
|
||||
SPICE_VALUE operator*( const SPICE_VALUE& aOther ) const;
|
||||
SPICE_VALUE operator/( const SPICE_VALUE& aOther ) const;
|
||||
|
||||
private:
|
||||
double m_base;
|
||||
UNIT_PREFIX m_prefix;
|
||||
|
||||
///> Was the value defined using the Spice notation?
|
||||
bool m_spiceStr;
|
||||
|
||||
static void stripZeros( wxString& aString );
|
||||
};
|
||||
|
||||
#endif /* SPICE_VALUE_H */
|
Loading…
Reference in New Issue