2022-06-09 18:30:51 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2022 Fabien Corona f.corona<at>laposte.net
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
|
|
* are permitted provided that the following conditions are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
*
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
|
|
* and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
|
|
|
* to endorse or promote products derived from this software without specific
|
|
|
|
* prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
|
|
|
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
|
|
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
|
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef IBIS_PARSER_H
|
|
|
|
#define IBIS_PARSER_H
|
|
|
|
|
|
|
|
#define _( x ) x
|
|
|
|
|
|
|
|
#define NAN_NA "1"
|
|
|
|
#define NAN_INVALID "0"
|
|
|
|
|
|
|
|
#define IBIS_MAX_VERSION 7.0 // Up to v7.0, IBIS is fully backward compatible
|
|
|
|
#define IBIS_MAX_LINE_LENGTH 2048 // official limit is 1024
|
|
|
|
|
|
|
|
#include <wx/string.h>
|
|
|
|
#include <reporter.h>
|
|
|
|
//#include "common.h"
|
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
|
|
|
#include <vector>
|
|
|
|
#include <math.h>
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
|
|
|
|
class IBIS_REPORTER
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/** @brief Print a message
|
|
|
|
*
|
|
|
|
* In the future, this function could do more than just printing a message.
|
|
|
|
* All KIBIS messages are concentrated at a single point in the code.
|
|
|
|
*
|
|
|
|
* @param aMsg Message
|
|
|
|
* @param aSeverity Message sevirity
|
|
|
|
*/
|
|
|
|
void Report( std::string aMsg, SEVERITY aSeverity ) { std::cout << aMsg << std::endl; };
|
|
|
|
};
|
|
|
|
|
|
|
|
class IBIS_ANY
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IBIS_ANY( IBIS_REPORTER* aReporter ) { m_reporter = aReporter; };
|
|
|
|
IBIS_REPORTER* m_reporter;
|
|
|
|
|
|
|
|
/** @brief Print a message
|
|
|
|
*
|
|
|
|
* Call m_reporter->Report if m_reporter exists.
|
|
|
|
*
|
|
|
|
* @param aMsg Message
|
|
|
|
* @param aSeverity Message sevirity
|
|
|
|
*/
|
|
|
|
void Report( std::string aMsg, SEVERITY aSeverity = RPT_SEVERITY_INFO )
|
|
|
|
{
|
|
|
|
if( m_reporter )
|
|
|
|
{
|
|
|
|
m_reporter->Report( aMsg, aSeverity );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
protected:
|
|
|
|
/** @brief Convert a double to string using scientific notation
|
|
|
|
*
|
|
|
|
* @param aNumber Number
|
|
|
|
* @return Output string
|
|
|
|
*/
|
|
|
|
std::string doubleToString( double aNumber );
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IBIS_INPUT : public IBIS_ANY
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IBIS_INPUT( IBIS_REPORTER* aReporter ) : IBIS_ANY( aReporter ){};
|
|
|
|
/** @brief Check if the data held by the object is valid.
|
|
|
|
*
|
|
|
|
* @return true in case of success
|
|
|
|
*/
|
|
|
|
bool virtual Check() { return false; };
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
enum IBIS_CORNER
|
|
|
|
{
|
|
|
|
TYP = 0,
|
|
|
|
MIN,
|
|
|
|
MAX
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
enum class IBIS_MATRIX_TYPE
|
|
|
|
{
|
|
|
|
// All matrices are supposed to be symmetrical, only upper right triangle is given
|
|
|
|
UNDEFINED,
|
Fix typos in pcbnew sub-directory
Found via `codespell -q 3 -S *.po,./thirdparty,./Documentation/changelogs -L aactual,acount,aline,alocation,alog,anormal,anumber,aother,apoints,aparent,aray,ba,busses,dout,einstance,leaded,modul,ontext,ot,overide,serie,te,,tesselate,tesselator,tht`
2022-06-29 20:21:10 +00:00
|
|
|
BANDED, // Give the main diagonal + [bandwidth] elements on the right
|
2022-06-09 18:30:51 +00:00
|
|
|
SPARSE, // Only give non-zero values.
|
|
|
|
FULL, // Give the whole upper triangle.
|
|
|
|
};
|
|
|
|
|
|
|
|
class IBIS_MATRIX : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IBIS_MATRIX( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
2022-06-14 19:32:12 +00:00
|
|
|
virtual ~IBIS_MATRIX(){};
|
|
|
|
|
2022-06-09 18:30:51 +00:00
|
|
|
IBIS_MATRIX_TYPE m_type = IBIS_MATRIX_TYPE::UNDEFINED;
|
|
|
|
int m_dim = -5;
|
|
|
|
std::vector<double> m_data;
|
|
|
|
};
|
|
|
|
|
|
|
|
class IBIS_MATRIX_BANDED : public IBIS_MATRIX
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IBIS_MATRIX_BANDED( IBIS_REPORTER* aReporter ) : IBIS_MATRIX( aReporter ){};
|
|
|
|
IBIS_MATRIX_TYPE m_type = IBIS_MATRIX_TYPE::BANDED;
|
|
|
|
int m_dim = -2;
|
|
|
|
int m_bandwidth = 0;
|
|
|
|
std::vector<double> m_data;
|
|
|
|
|
|
|
|
bool Check() override;
|
|
|
|
};
|
|
|
|
|
|
|
|
class IBIS_MATRIX_SPARSE : public IBIS_MATRIX
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IBIS_MATRIX_SPARSE( IBIS_REPORTER* aReporter ) : IBIS_MATRIX( aReporter ){};
|
|
|
|
IBIS_MATRIX_TYPE m_type = IBIS_MATRIX_TYPE::BANDED;
|
|
|
|
int m_dim = -3;
|
|
|
|
std::vector<double> m_data;
|
|
|
|
|
|
|
|
bool Check() override;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IBIS_MATRIX_FULL : public IBIS_MATRIX
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IBIS_MATRIX_FULL( IBIS_REPORTER* aReporter ) : IBIS_MATRIX( aReporter ){};
|
|
|
|
IBIS_MATRIX_TYPE m_type = IBIS_MATRIX_TYPE::FULL;
|
|
|
|
int m_dim = -4;
|
|
|
|
std::vector<double> m_data;
|
|
|
|
|
|
|
|
bool Check() override;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IBIS_SECTION : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IBIS_SECTION( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IbisHeader : IBIS_SECTION
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IbisHeader( IBIS_REPORTER* aReporter ) : IBIS_SECTION( aReporter ){};
|
|
|
|
double m_ibisVersion = -1;
|
|
|
|
double m_fileRevision = -1;
|
|
|
|
std::string m_fileName;
|
|
|
|
std::string m_source;
|
|
|
|
std::string m_date;
|
|
|
|
std::string m_notes;
|
|
|
|
std::string m_disclaimer;
|
|
|
|
std::string m_copyright;
|
|
|
|
|
|
|
|
bool Check() override;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class TypMinMaxValue : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
TypMinMaxValue( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
2022-06-14 19:32:12 +00:00
|
|
|
double value[3] = { -1, -1, -1 };
|
2022-06-09 18:30:51 +00:00
|
|
|
|
|
|
|
bool Check() override;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IbisComponentPackage : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
2022-06-13 19:31:57 +00:00
|
|
|
IbisComponentPackage( IBIS_REPORTER* aReporter ) :
|
|
|
|
IBIS_INPUT( aReporter ),
|
|
|
|
m_Rpkg( aReporter ),
|
|
|
|
m_Lpkg( aReporter ),
|
|
|
|
m_Cpkg( aReporter )
|
|
|
|
{};
|
|
|
|
|
|
|
|
TypMinMaxValue m_Rpkg;
|
|
|
|
TypMinMaxValue m_Lpkg;
|
|
|
|
TypMinMaxValue m_Cpkg;
|
2022-06-09 18:30:51 +00:00
|
|
|
|
|
|
|
bool Check() override;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IbisComponentPin : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IbisComponentPin( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
|
|
|
|
|
|
|
std::string m_pinName;
|
|
|
|
std::string m_signalName;
|
|
|
|
std::string m_modelName;
|
2022-06-11 20:10:07 +00:00
|
|
|
double m_Rpin = nan( NAN_NA );
|
|
|
|
double m_Lpin = nan( NAN_NA );
|
|
|
|
double m_Cpin = nan( NAN_NA );
|
2022-06-09 18:30:51 +00:00
|
|
|
|
|
|
|
int m_Rcol = 0;
|
|
|
|
int m_Lcol = 0;
|
|
|
|
int m_Ccol = 0;
|
|
|
|
|
|
|
|
bool Check() override;
|
|
|
|
|
|
|
|
bool m_dummy = false;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IbisComponentPinMapping : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IbisComponentPinMapping( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
|
|
|
std::string m_pinName;
|
|
|
|
std::string m_PDref;
|
|
|
|
std::string m_PUref;
|
|
|
|
std::string m_GNDClampRef;
|
|
|
|
std::string m_POWERClampRef;
|
|
|
|
std::string m_extRef;
|
|
|
|
|
2022-06-13 19:31:57 +00:00
|
|
|
bool m_virtual = false;
|
2022-06-09 18:30:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IbisDiffPinEntry : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
2022-06-13 19:31:57 +00:00
|
|
|
IbisDiffPinEntry( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), tdelay( aReporter ){};
|
2022-06-09 18:30:51 +00:00
|
|
|
|
|
|
|
std::string pinA;
|
|
|
|
std::string pinB;
|
|
|
|
double Vdiff = 0.2; // ignored for input
|
2022-06-14 19:32:12 +00:00
|
|
|
TypMinMaxValue tdelay = 0; // ignored for outputs
|
2022-06-09 18:30:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IbisDiffPin : IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IbisDiffPin( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
|
|
|
std::vector<IbisDiffPinEntry> m_entries;
|
|
|
|
};
|
|
|
|
|
|
|
|
class IbisComponent : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
2022-06-13 19:31:57 +00:00
|
|
|
IbisComponent( IBIS_REPORTER* aReporter ) :
|
|
|
|
IBIS_INPUT( aReporter ),
|
|
|
|
m_package( aReporter ),
|
|
|
|
m_diffPin( aReporter )
|
|
|
|
{};
|
2022-06-09 18:30:51 +00:00
|
|
|
|
|
|
|
std::string m_name = "";
|
|
|
|
std::string m_manufacturer = "";
|
|
|
|
IbisComponentPackage m_package;
|
|
|
|
std::vector<IbisComponentPin> m_pins;
|
|
|
|
std::vector<IbisComponentPinMapping> m_pinMappings;
|
|
|
|
std::string m_packageModel;
|
|
|
|
std::string m_busLabel;
|
|
|
|
std::string m_dieSupplyPads;
|
2022-06-13 19:31:57 +00:00
|
|
|
IbisDiffPin m_diffPin;
|
2022-06-09 18:30:51 +00:00
|
|
|
|
|
|
|
bool Check() override;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IbisModelSelectorEntry
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
std::string m_modelName;
|
|
|
|
std::string m_modelDescription;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IbisModelSelector : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IbisModelSelector( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
|
|
|
std::string m_name;
|
|
|
|
std::vector<IbisModelSelectorEntry> m_models;
|
|
|
|
|
|
|
|
bool Check() override;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IVtableEntry : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
2022-06-13 19:31:57 +00:00
|
|
|
IVtableEntry( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), I( aReporter ){};
|
|
|
|
double V = 0;
|
|
|
|
TypMinMaxValue I;
|
2022-06-09 18:30:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IVtable : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IVtable( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
|
|
|
std::vector<IVtableEntry> m_entries;
|
|
|
|
|
|
|
|
bool Check() override;
|
|
|
|
|
|
|
|
/** @brief Interpolate the IV table
|
|
|
|
*
|
|
|
|
* Linear interpolation to find the current for voltage aV
|
|
|
|
*
|
|
|
|
* @param aV voltage
|
|
|
|
* @param aCorner Power supply corner
|
|
|
|
* @return current
|
|
|
|
*/
|
|
|
|
double InterpolatedI( double aV, IBIS_CORNER aCorner );
|
|
|
|
|
|
|
|
/** @brief Interpolate the IV table
|
|
|
|
*
|
|
|
|
* Generate the spice directive needed to define a model defined by its IV table.
|
|
|
|
* The order of aPort1 and aPort2 is important. ( Inverting them will reverse the component )
|
|
|
|
*
|
|
|
|
* @param aN Index of the 'a' device
|
|
|
|
* @param aPort1 Spice node
|
|
|
|
* @param aPort2 Spice node
|
|
|
|
* @param aPort2 Name of the generated model
|
|
|
|
* @param aCorner Power supply corner
|
|
|
|
* @return Multline spice directives
|
|
|
|
*/
|
|
|
|
std::string Spice( int aN, std::string aPort1, std::string aPort2, std::string aModelName,
|
|
|
|
IBIS_CORNER aCorner );
|
|
|
|
|
|
|
|
private:
|
|
|
|
};
|
|
|
|
|
|
|
|
class VTtableEntry : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
2022-06-13 19:31:57 +00:00
|
|
|
VTtableEntry( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), V( aReporter ){};
|
|
|
|
double t = 0;
|
2022-06-14 19:32:12 +00:00
|
|
|
TypMinMaxValue V = 0;
|
2022-06-09 18:30:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class VTtable : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
VTtable( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
|
|
|
std::vector<VTtableEntry> m_entries;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
Model_type must be one of the following:
|
|
|
|
Input, Output, I/O, 3-state, Open_drain, I/O_open_drain, Open_sink, I/O_open_sink,
|
|
|
|
Open_source, I/O_open_source, Input_ECL, Output_ECL, I/O_ECL, 3-state_ECL, Terminator,
|
|
|
|
Series, and Series_switch.
|
|
|
|
*/
|
|
|
|
|
|
|
|
enum class IBIS_MODEL_TYPE
|
|
|
|
{
|
|
|
|
UNDEFINED,
|
|
|
|
INPUT,
|
|
|
|
OUTPUT,
|
|
|
|
IO,
|
|
|
|
THREE_STATE,
|
|
|
|
OPEN_DRAIN,
|
|
|
|
IO_OPEN_DRAIN,
|
|
|
|
OPEN_SINK,
|
|
|
|
IO_OPEN_SINK,
|
|
|
|
OPEN_SOURCE,
|
|
|
|
IO_OPEN_SOURCE,
|
|
|
|
INPUT_ECL,
|
|
|
|
OUTPUT_ECL,
|
|
|
|
IO_ECL,
|
|
|
|
THREE_STATE_ECL,
|
|
|
|
TERMINATOR,
|
|
|
|
SERIES,
|
|
|
|
SERIES_SWITCH
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class IBIS_MODEL_ENABLE
|
|
|
|
{
|
|
|
|
UNDEFINED,
|
|
|
|
ACTIVE_HIGH,
|
|
|
|
ACTIVE_LOW
|
|
|
|
};
|
|
|
|
|
|
|
|
class dvdt
|
|
|
|
{
|
|
|
|
public:
|
2022-06-13 19:31:57 +00:00
|
|
|
double m_dv = 1;
|
|
|
|
double m_dt = 1;
|
2022-06-09 18:30:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class dvdtTypMinMax : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
dvdtTypMinMax( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
|
|
|
dvdt value[3];
|
|
|
|
|
|
|
|
bool Check() override;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IbisRamp : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
2022-06-13 19:31:57 +00:00
|
|
|
IbisRamp( IBIS_REPORTER* aReporter ) :
|
|
|
|
IBIS_INPUT( aReporter ),
|
|
|
|
m_falling( aReporter ),
|
|
|
|
m_rising( aReporter )
|
|
|
|
{};
|
|
|
|
|
|
|
|
dvdtTypMinMax m_falling;
|
|
|
|
dvdtTypMinMax m_rising;
|
2022-06-09 18:30:51 +00:00
|
|
|
double m_Rload = 50; // The R_load subparameter is optional if the default 50 ohm load is used
|
|
|
|
|
|
|
|
bool Check() override;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class IBIS_WAVEFORM_TYPE
|
|
|
|
{
|
|
|
|
RISING,
|
|
|
|
FALLING
|
|
|
|
};
|
|
|
|
|
|
|
|
class IbisWaveform : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
2022-06-13 19:31:57 +00:00
|
|
|
IbisWaveform( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), m_table( aReporter ){};
|
|
|
|
|
|
|
|
VTtable m_table;
|
|
|
|
IBIS_WAVEFORM_TYPE m_type = IBIS_WAVEFORM_TYPE::RISING;
|
|
|
|
double m_R_dut = 0;
|
|
|
|
double m_C_dut = 0;
|
|
|
|
double m_L_dut = 0;
|
2022-06-09 18:30:51 +00:00
|
|
|
double m_R_fixture = 0;
|
|
|
|
double m_C_fixture = 0;
|
|
|
|
double m_L_fixture = 0;
|
|
|
|
double m_V_fixture = 0;
|
|
|
|
double m_V_fixture_min = 0;
|
|
|
|
double m_V_fixture_max = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class IBIS_MODEL_POLARITY
|
|
|
|
{
|
|
|
|
UNDEFINED,
|
|
|
|
INVERTING,
|
|
|
|
NON_INVERTING
|
|
|
|
};
|
|
|
|
|
|
|
|
class IbisModel : IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
2022-06-13 19:31:57 +00:00
|
|
|
IbisModel( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ),
|
|
|
|
m_C_comp( aReporter ),
|
|
|
|
m_voltageRange( aReporter ),
|
|
|
|
m_temperatureRange( aReporter ),
|
|
|
|
m_pullupReference( aReporter ),
|
|
|
|
m_pulldownReference( aReporter ),
|
|
|
|
m_GNDClampReference( aReporter ),
|
|
|
|
m_POWERClampReference( aReporter ),
|
|
|
|
m_Rgnd( aReporter ),
|
|
|
|
m_Rpower( aReporter ),
|
|
|
|
m_Rac( aReporter ),
|
|
|
|
m_Cac( aReporter ),
|
|
|
|
m_GNDClamp( aReporter ),
|
|
|
|
m_POWERClamp( aReporter ),
|
|
|
|
m_pullup( aReporter ),
|
|
|
|
m_pulldown( aReporter ),
|
|
|
|
m_ramp( aReporter )
|
|
|
|
{};
|
2022-06-09 18:30:51 +00:00
|
|
|
|
|
|
|
std::string m_name;
|
|
|
|
IBIS_MODEL_TYPE m_type = IBIS_MODEL_TYPE::UNDEFINED;
|
|
|
|
/* The Polarity, Enable, Vinl, Vinh, Vmeas, Cref, Rref, and Vref subparameters are optional. */
|
|
|
|
/* the default values of Vinl = 0.8 V and Vinh = 2.0 V are assumed. */
|
|
|
|
double m_vinl = 0.8;
|
|
|
|
double m_vinh = 2;
|
|
|
|
double m_vref = 0;
|
|
|
|
double m_rref = 0;
|
|
|
|
double m_cref = 0;
|
|
|
|
double m_vmeas = 0;
|
|
|
|
IBIS_MODEL_ENABLE m_enable = IBIS_MODEL_ENABLE::UNDEFINED;
|
|
|
|
IBIS_MODEL_POLARITY m_polarity = IBIS_MODEL_POLARITY::UNDEFINED;
|
|
|
|
// End of optional subparameters
|
|
|
|
|
2022-06-13 19:31:57 +00:00
|
|
|
TypMinMaxValue m_C_comp;
|
|
|
|
TypMinMaxValue m_voltageRange;
|
|
|
|
TypMinMaxValue m_temperatureRange;
|
|
|
|
TypMinMaxValue m_pullupReference;
|
|
|
|
TypMinMaxValue m_pulldownReference;
|
|
|
|
TypMinMaxValue m_GNDClampReference;
|
|
|
|
TypMinMaxValue m_POWERClampReference;
|
|
|
|
TypMinMaxValue m_Rgnd;
|
|
|
|
TypMinMaxValue m_Rpower;
|
|
|
|
TypMinMaxValue m_Rac;
|
|
|
|
TypMinMaxValue m_Cac;
|
|
|
|
IVtable m_GNDClamp;
|
|
|
|
IVtable m_POWERClamp;
|
|
|
|
IVtable m_pullup;
|
|
|
|
IVtable m_pulldown;
|
2022-06-09 18:30:51 +00:00
|
|
|
std::vector<IbisWaveform*> m_risingWaveforms;
|
|
|
|
std::vector<IbisWaveform*> m_fallingWaveforms;
|
2022-06-13 19:31:57 +00:00
|
|
|
IbisRamp m_ramp;
|
2022-06-09 18:30:51 +00:00
|
|
|
|
|
|
|
bool Check() override;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class IbisPackageModel : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IbisPackageModel( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ){};
|
|
|
|
|
|
|
|
std::string m_name;
|
|
|
|
std::string m_manufacturer;
|
|
|
|
std::string m_OEM;
|
|
|
|
std::string m_description;
|
2022-06-13 19:31:57 +00:00
|
|
|
int m_numberOfPins = 0;
|
2022-06-09 18:30:51 +00:00
|
|
|
std::vector<std::string> m_pins;
|
|
|
|
|
|
|
|
std::shared_ptr<IBIS_MATRIX> m_resistanceMatrix;
|
|
|
|
std::shared_ptr<IBIS_MATRIX> m_capacitanceMatrix;
|
|
|
|
std::shared_ptr<IBIS_MATRIX> m_inductanceMatrix;
|
|
|
|
|
|
|
|
bool Check() override;
|
|
|
|
};
|
|
|
|
|
|
|
|
class IbisFile : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
2022-06-13 19:31:57 +00:00
|
|
|
IbisFile( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), m_header( aReporter ){};
|
2022-06-09 18:30:51 +00:00
|
|
|
|
2022-06-13 19:31:57 +00:00
|
|
|
IbisHeader m_header;
|
2022-06-09 18:30:51 +00:00
|
|
|
std::vector<IbisComponent> m_components;
|
|
|
|
std::vector<IbisModelSelector> m_modelSelectors;
|
|
|
|
std::vector<IbisModel> m_models;
|
|
|
|
std::vector<IbisPackageModel> m_packageModels;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
enum class IBIS_PARSER_CONTINUE
|
|
|
|
{
|
|
|
|
NONE,
|
|
|
|
STRING,
|
|
|
|
COMPONENT_PACKAGE,
|
|
|
|
COMPONENT_PINMAPPING,
|
|
|
|
COMPONENT_DIFFPIN,
|
|
|
|
COMPONENT_DIESUPPLYPADS,
|
|
|
|
COMPONENT_PIN,
|
|
|
|
MATRIX,
|
|
|
|
MODELSELECTOR,
|
|
|
|
MODEL,
|
|
|
|
IV_TABLE,
|
|
|
|
VT_TABLE,
|
|
|
|
RAMP,
|
|
|
|
WAVEFORM,
|
|
|
|
PACKAGEMODEL_PINS
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class IBIS_PARSER_CONTEXT
|
|
|
|
{
|
|
|
|
HEADER,
|
|
|
|
COMPONENT,
|
|
|
|
MODELSELECTOR,
|
|
|
|
MODEL,
|
|
|
|
PACKAGEMODEL,
|
|
|
|
PACKAGEMODEL_MODELDATA,
|
|
|
|
END
|
|
|
|
};
|
|
|
|
|
|
|
|
class IbisParser : public IBIS_INPUT
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
IbisParser( IBIS_REPORTER* aReporter ) : IBIS_INPUT( aReporter ), m_ibisFile( aReporter ){};
|
|
|
|
|
|
|
|
bool m_parrot = true; // Write back all lines.
|
|
|
|
|
2022-06-13 19:31:57 +00:00
|
|
|
long m_lineCounter = 0;
|
2022-06-09 18:30:51 +00:00
|
|
|
char m_commentChar = '|';
|
|
|
|
std::vector<char> m_buffer;
|
2022-06-13 19:31:57 +00:00
|
|
|
int m_bufferIndex = 0;
|
|
|
|
int m_lineOffset = 0;
|
|
|
|
int m_lineIndex = 0;
|
|
|
|
int m_lineLength = 0;
|
2022-06-09 18:30:51 +00:00
|
|
|
|
|
|
|
IbisFile m_ibisFile;
|
2022-06-13 19:31:57 +00:00
|
|
|
IbisComponent* m_currentComponent = nullptr;
|
|
|
|
IbisModelSelector* m_currentModelSelector = nullptr;
|
|
|
|
IbisModel* m_currentModel = nullptr;
|
|
|
|
IbisPackageModel* m_currentPackageModel = nullptr;
|
2022-06-14 19:32:12 +00:00
|
|
|
std::shared_ptr<IBIS_MATRIX> m_currentMatrix = nullptr;
|
|
|
|
int m_currentMatrixRow = 0;
|
|
|
|
int m_currentMatrixRowIndex = 0;
|
2022-06-13 19:31:57 +00:00
|
|
|
IVtable* m_currentIVtable = nullptr;
|
|
|
|
VTtable* m_currentVTtable = nullptr;
|
|
|
|
IbisWaveform* m_currentWaveform = nullptr;
|
2022-06-09 18:30:51 +00:00
|
|
|
|
|
|
|
/** @brief Parse a file
|
|
|
|
*
|
|
|
|
* This is the entry point to parse a file
|
|
|
|
*
|
|
|
|
* @param aFileName input file name
|
|
|
|
* @return True in case of success
|
|
|
|
*/
|
|
|
|
bool ParseFile( std::string& aFileName );
|
|
|
|
|
|
|
|
private:
|
2022-06-14 19:32:12 +00:00
|
|
|
std::string* m_continuingString = nullptr;
|
2022-06-09 18:30:51 +00:00
|
|
|
|
|
|
|
/** @brief compare two strings without being case sensitive
|
|
|
|
*
|
|
|
|
* Ibis: "The content of the files is case sensitive, except for reserved words and keywords."
|
|
|
|
*
|
|
|
|
* @param a string to compare
|
|
|
|
* @param b string to compare
|
|
|
|
* @return true if the string are equal
|
|
|
|
*/
|
|
|
|
bool compareIbisWord( const std::string& a, const std::string& b );
|
|
|
|
|
|
|
|
/** @brief Parse a single keyword in the header context
|
|
|
|
*
|
|
|
|
* @param aKeyword Keyword
|
|
|
|
* @return True in case of success
|
|
|
|
*/
|
|
|
|
bool parseHeader( std::string& aKeyword );
|
|
|
|
/** @brief Parse a single keyword in the component context
|
|
|
|
*
|
|
|
|
* @param aKeyword Keyword
|
|
|
|
* @return True in case of success
|
|
|
|
*/
|
|
|
|
bool parseComponent( std::string& aKeyword );
|
|
|
|
/** @brief Parse a single keyword in the component context
|
|
|
|
*
|
|
|
|
* @param aKeyword Keyword
|
|
|
|
* @return True in case of success
|
|
|
|
*/
|
|
|
|
bool parseModelSelector( std::string& aKeyword );
|
|
|
|
/** @brief Parse a single keyword in the model selector context
|
|
|
|
*
|
|
|
|
* @param aKeyword Keyword
|
|
|
|
* @return True in case of success
|
|
|
|
*/
|
|
|
|
bool parseModel( std::string& aKeyword );
|
|
|
|
/** @brief Parse a single keyword in the model context
|
|
|
|
*
|
|
|
|
* @param aKeyword Keyword
|
|
|
|
* @return True in case of success
|
|
|
|
*/
|
|
|
|
bool parsePackageModel( std::string& aKeyword );
|
|
|
|
/** @brief Parse a single keyword in the package model context
|
|
|
|
*
|
|
|
|
* @param aKeyword Keyword
|
|
|
|
* @return True in case of success
|
|
|
|
*/
|
|
|
|
bool parsePackageModelModelData( std::string& );
|
|
|
|
/** @brief Parse a double according to the ibis standard
|
|
|
|
*
|
|
|
|
* @param aDest Where the double should be stored
|
|
|
|
* @param aStr The string to parse
|
|
|
|
* @param aAllowModifiers Allows modifiers ( p for pico, f for femto, k for kilo, ... )
|
|
|
|
* @return True in case of success
|
|
|
|
*/
|
|
|
|
bool parseDouble( double& aDest, std::string& aStr, bool aAllowModifiers = false );
|
|
|
|
|
|
|
|
/** @brief Parse the current line
|
|
|
|
*
|
|
|
|
* @return True in case of success
|
|
|
|
*/
|
|
|
|
bool onNewLine(); // Gets rid of comments ( except on a comment character change command...)
|
|
|
|
/** @brief Load the next line
|
|
|
|
*
|
|
|
|
* @return True in case of success
|
|
|
|
*/
|
|
|
|
bool getNextLine();
|
|
|
|
/** @brief Print the current line */
|
|
|
|
void printLine();
|
|
|
|
|
|
|
|
void skipWhitespaces();
|
|
|
|
bool checkEndofLine(); // To be used when there cannot be any character left on the line
|
|
|
|
bool isLineEmptyFromCursor();
|
|
|
|
std::string getKeyword();
|
|
|
|
|
|
|
|
bool readInt( int& aDest );
|
|
|
|
bool readDouble( double& aDest );
|
|
|
|
bool readWord( std::string& aDest );
|
|
|
|
bool readDvdt( std::string& aString, dvdt& aDest );
|
|
|
|
bool readMatrix( std::shared_ptr<IBIS_MATRIX> aDest );
|
|
|
|
bool readMatrixBanded( std::string, IBIS_MATRIX_BANDED& aDest );
|
|
|
|
bool readMatrixFull( std::string, IBIS_MATRIX_FULL& aDest );
|
|
|
|
bool readMatrixSparse( std::string, IBIS_MATRIX_SPARSE& aDest );
|
|
|
|
bool readRampdvdt( dvdtTypMinMax& aDest );
|
|
|
|
bool readRamp();
|
|
|
|
bool readWaveform( IbisWaveform* aDest, IBIS_WAVEFORM_TYPE aType );
|
|
|
|
bool readString( std::string& aDest );
|
|
|
|
bool storeString( std::string& aDest, bool aMultiline );
|
|
|
|
bool readTableLine( std::vector<std::string>& aDest );
|
|
|
|
|
|
|
|
bool readNumericSubparam( std::string aSubparam, double& aDest );
|
|
|
|
bool readIVtableEntry( IVtable& aTable );
|
|
|
|
bool readVTtableEntry( VTtable& aTable );
|
|
|
|
bool readTypMinMaxValue( TypMinMaxValue& aDest );
|
|
|
|
bool readTypMinMaxValueSubparam( std::string aSubparam, TypMinMaxValue& aDest );
|
|
|
|
//bool ReadDieSupplyPads();
|
|
|
|
|
|
|
|
bool readPackage();
|
|
|
|
bool readPin();
|
|
|
|
bool readPinMapping();
|
|
|
|
bool readDiffPin();
|
|
|
|
bool readModelSelector();
|
|
|
|
bool readModel();
|
|
|
|
bool readPackageModelPins();
|
|
|
|
|
|
|
|
/** @brief Ibis can change the character used for comments */
|
|
|
|
bool changeCommentChar();
|
|
|
|
bool changeContext( std::string& aKeyword );
|
|
|
|
|
|
|
|
IBIS_PARSER_CONTINUE m_continue = IBIS_PARSER_CONTINUE::NONE;
|
|
|
|
IBIS_PARSER_CONTEXT m_context = IBIS_PARSER_CONTEXT::HEADER;
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|