Ibis differential and PRBS models
This commit is contained in:
parent
8ae48bb093
commit
7e486327d9
|
@ -524,7 +524,26 @@ void DIALOG_SIM_MODEL<T>::loadLibrary( const wxString& aFilePath )
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_library->ReadFile( std::string( absolutePath.ToUTF8() ) );
|
if( IsIbisLoaded() )
|
||||||
|
{
|
||||||
|
wxString ibisTypeString = SIM_MODEL::GetFieldValue( &m_fields, SIM_MODEL::TYPE_FIELD );
|
||||||
|
|
||||||
|
SIM_MODEL::TYPE ibisType = SIM_MODEL::TYPE::KIBIS_DEVICE;
|
||||||
|
|
||||||
|
if( ibisTypeString == "IBISDRIVER" )
|
||||||
|
ibisType = SIM_MODEL::TYPE::KIBIS_DRIVER;
|
||||||
|
else if( ibisTypeString == "IBISDIFFDRIVER" )
|
||||||
|
ibisType = SIM_MODEL::TYPE::KIBIS_DIFFDRIVER;
|
||||||
|
else if( ibisTypeString == "IBISDIFFDEVICE" )
|
||||||
|
ibisType = SIM_MODEL::TYPE::KIBIS_DIFFDEVICE;
|
||||||
|
|
||||||
|
std::dynamic_pointer_cast<SIM_LIBRARY_KIBIS>( m_library )
|
||||||
|
->ReadFile( std::string( absolutePath.ToUTF8() ), ibisType );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_library->ReadFile( std::string( absolutePath.ToUTF8() ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch( const IO_ERROR& e )
|
catch( const IO_ERROR& e )
|
||||||
{
|
{
|
||||||
|
@ -1010,8 +1029,9 @@ void DIALOG_SIM_MODEL<T>::onTypeChoice( wxCommandEvent& aEvent )
|
||||||
&& typeDescription == SIM_MODEL::TypeInfo( type ).description )
|
&& typeDescription == SIM_MODEL::TypeInfo( type ).description )
|
||||||
{
|
{
|
||||||
if( IsIbisLoaded()
|
if( IsIbisLoaded()
|
||||||
&& ( type == SIM_MODEL::TYPE::KIBIS_DEVICE
|
&& ( type == SIM_MODEL::TYPE::KIBIS_DEVICE || type == SIM_MODEL::TYPE::KIBIS_DRIVER
|
||||||
|| type == SIM_MODEL::TYPE::KIBIS_DRIVER ) )
|
|| type == SIM_MODEL::TYPE::KIBIS_DIFFDRIVER
|
||||||
|
|| type == SIM_MODEL::TYPE::KIBIS_DIFFDEVICE ) )
|
||||||
{
|
{
|
||||||
std::shared_ptr<SIM_MODEL_KIBIS> kibismodel =
|
std::shared_ptr<SIM_MODEL_KIBIS> kibismodel =
|
||||||
std::dynamic_pointer_cast<SIM_MODEL_KIBIS>(
|
std::dynamic_pointer_cast<SIM_MODEL_KIBIS>(
|
||||||
|
|
|
@ -273,6 +273,8 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
||||||
|
|
||||||
switch( type )
|
switch( type )
|
||||||
{
|
{
|
||||||
|
case SIM_MODEL::TYPE::KIBIS_DIFFDEVICE:
|
||||||
|
case SIM_MODEL::TYPE::KIBIS_DIFFDRIVER:
|
||||||
case SIM_MODEL::TYPE::KIBIS_DEVICE:
|
case SIM_MODEL::TYPE::KIBIS_DEVICE:
|
||||||
case SIM_MODEL::TYPE::KIBIS_DRIVER: break;
|
case SIM_MODEL::TYPE::KIBIS_DRIVER: break;
|
||||||
default:
|
default:
|
||||||
|
@ -329,6 +331,10 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
||||||
case SIM_MODEL::TYPE::KIBIS_DEVICE:
|
case SIM_MODEL::TYPE::KIBIS_DEVICE:
|
||||||
kpin->writeSpiceDevice( &modelData, modelName, *kmodel, kparams );
|
kpin->writeSpiceDevice( &modelData, modelName, *kmodel, kparams );
|
||||||
break;
|
break;
|
||||||
|
case SIM_MODEL::TYPE::KIBIS_DIFFDEVICE:
|
||||||
|
kpin->writeSpiceDiffDevice( &modelData, modelName, *kmodel, kparams );
|
||||||
|
break;
|
||||||
|
case SIM_MODEL::TYPE::KIBIS_DIFFDRIVER:
|
||||||
case SIM_MODEL::TYPE::KIBIS_DRIVER:
|
case SIM_MODEL::TYPE::KIBIS_DRIVER:
|
||||||
{
|
{
|
||||||
mparam = spiceItem.model->FindParam( "wftype" );
|
mparam = spiceItem.model->FindParam( "wftype" );
|
||||||
|
@ -369,6 +375,39 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
||||||
->Get()
|
->Get()
|
||||||
.value_or( 0 ) );
|
.value_or( 0 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( paramValue == "prbs" )
|
||||||
|
{
|
||||||
|
kparams.m_waveform = static_cast<KIBIS_WAVEFORM*>(
|
||||||
|
new KIBIS_WAVEFORM_PRBS() );
|
||||||
|
|
||||||
|
mparam = spiceItem.model->FindParam( "bitrate" );
|
||||||
|
|
||||||
|
if( mparam )
|
||||||
|
static_cast<KIBIS_WAVEFORM_PRBS*>( kparams.m_waveform )
|
||||||
|
->m_bitrate = static_cast<double>(
|
||||||
|
std::dynamic_pointer_cast<SIM_VALUE_FLOAT>( mparam->value )
|
||||||
|
->Get()
|
||||||
|
.value_or( 1 ) );
|
||||||
|
|
||||||
|
mparam = spiceItem.model->FindParam( "nbits" );
|
||||||
|
|
||||||
|
if( mparam )
|
||||||
|
static_cast<KIBIS_WAVEFORM_PRBS*>( kparams.m_waveform )
|
||||||
|
->m_bits = static_cast<double>(
|
||||||
|
std::dynamic_pointer_cast<SIM_VALUE_FLOAT>( mparam->value )
|
||||||
|
->Get()
|
||||||
|
.value_or( 1 ) );
|
||||||
|
|
||||||
|
mparam = spiceItem.model->FindParam( "delay" );
|
||||||
|
|
||||||
|
if( mparam )
|
||||||
|
static_cast<KIBIS_WAVEFORM_PRBS*>( kparams.m_waveform )
|
||||||
|
->m_delay = static_cast<double>(
|
||||||
|
std::dynamic_pointer_cast<SIM_VALUE_FLOAT>( mparam->value )
|
||||||
|
->Get()
|
||||||
|
.value_or( 0 ) );
|
||||||
|
}
|
||||||
else if( paramValue == "stuck high" )
|
else if( paramValue == "stuck high" )
|
||||||
{
|
{
|
||||||
kparams.m_waveform =
|
kparams.m_waveform =
|
||||||
|
@ -385,7 +424,11 @@ bool NETLIST_EXPORTER_SPICE::ReadSchematicAndLibraries( unsigned aNetlistOptions
|
||||||
static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_HIGH_Z() );
|
static_cast<KIBIS_WAVEFORM*>( new KIBIS_WAVEFORM_HIGH_Z() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kpin->writeSpiceDriver( &modelData, modelName, *kmodel, kparams );
|
|
||||||
|
if( type == SIM_MODEL::TYPE::KIBIS_DIFFDRIVER )
|
||||||
|
kpin->writeSpiceDiffDriver( &modelData, modelName, *kmodel, kparams );
|
||||||
|
else
|
||||||
|
kpin->writeSpiceDriver( &modelData, modelName, *kmodel, kparams );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: continue;
|
default: continue;
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
#include <pegtl/contrib/parse_tree.hpp>
|
#include <pegtl/contrib/parse_tree.hpp>
|
||||||
|
|
||||||
|
|
||||||
void SIM_LIBRARY_KIBIS::ReadFile( const std::string& aFilePath )
|
void SIM_LIBRARY_KIBIS::ReadFile( const std::string& aFilePath, SIM_MODEL::TYPE aType )
|
||||||
{
|
{
|
||||||
SIM_LIBRARY::ReadFile( aFilePath );
|
SIM_LIBRARY::ReadFile( aFilePath );
|
||||||
m_kibis = KIBIS( std::string( aFilePath.c_str() ) );
|
m_kibis = KIBIS( std::string( aFilePath.c_str() ) );
|
||||||
|
@ -41,13 +41,20 @@ void SIM_LIBRARY_KIBIS::ReadFile( const std::string& aFilePath )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned pinNumber = 2;
|
||||||
|
|
||||||
|
if( aType == SIM_MODEL::TYPE::KIBIS_DIFFDEVICE || aType == SIM_MODEL::TYPE::KIBIS_DIFFDEVICE )
|
||||||
|
pinNumber = 3;
|
||||||
|
|
||||||
for( KIBIS_COMPONENT& kcomp : m_kibis.m_components )
|
for( KIBIS_COMPONENT& kcomp : m_kibis.m_components )
|
||||||
{
|
{
|
||||||
m_models.push_back( SIM_MODEL::Create( SIM_MODEL::TYPE::KIBIS_DEVICE, 2 ) );
|
m_models.push_back( SIM_MODEL::Create( aType, pinNumber ) );
|
||||||
m_modelNames.emplace_back( kcomp.m_name );
|
m_modelNames.emplace_back( kcomp.m_name );
|
||||||
|
|
||||||
SIM_MODEL_KIBIS* libcomp = dynamic_cast<SIM_MODEL_KIBIS*>( m_models.back().get() );
|
SIM_MODEL_KIBIS* libcomp = dynamic_cast<SIM_MODEL_KIBIS*>( m_models.back().get() );
|
||||||
InitModel( *libcomp, kcomp.m_name );
|
|
||||||
|
if ( libcomp )
|
||||||
|
InitModel( *libcomp, kcomp.m_name );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,11 @@ public:
|
||||||
static constexpr auto MODEL_FIELD = "Ibis_Model";
|
static constexpr auto MODEL_FIELD = "Ibis_Model";
|
||||||
|
|
||||||
// @copydoc SIM_LIBRARY::ReadFile()
|
// @copydoc SIM_LIBRARY::ReadFile()
|
||||||
void ReadFile( const std::string& aFilePath ) override;
|
void ReadFile( const std::string& aFilePath, SIM_MODEL::TYPE aType );
|
||||||
|
void ReadFile( const std::string& aFilePath ) override
|
||||||
|
{
|
||||||
|
ReadFile( aFilePath, SIM_MODEL::TYPE::KIBIS_DEVICE );
|
||||||
|
}
|
||||||
|
|
||||||
// @copydoc SIM_LIBRARY::WriteFile()
|
// @copydoc SIM_LIBRARY::WriteFile()
|
||||||
void WriteFile( const std::string& aFilePath ) override{};
|
void WriteFile( const std::string& aFilePath ) override{};
|
||||||
|
|
|
@ -229,8 +229,10 @@ SIM_MODEL::INFO SIM_MODEL::TypeInfo( TYPE aType )
|
||||||
//case TYPE::I_RANDPOISSON: return { DEVICE_TYPE::I, "RANDPOISSON", "Random Poisson" };
|
//case TYPE::I_RANDPOISSON: return { DEVICE_TYPE::I, "RANDPOISSON", "Random Poisson" };
|
||||||
case TYPE::I_BEHAVIORAL: return { DEVICE_TYPE_::I, "=", "Behavioral" };
|
case TYPE::I_BEHAVIORAL: return { DEVICE_TYPE_::I, "=", "Behavioral" };
|
||||||
|
|
||||||
case TYPE::KIBIS_DRIVER: return { DEVICE_TYPE_::KIBIS, "IBISDRIVER", "Driver" };
|
case TYPE::KIBIS_DRIVER: return { DEVICE_TYPE_::KIBIS, "IBISDRIVER", "Driver" };
|
||||||
case TYPE::KIBIS_DEVICE: return { DEVICE_TYPE_::KIBIS, "IBISDEVICE", "Device" };
|
case TYPE::KIBIS_DEVICE: return { DEVICE_TYPE_::KIBIS, "IBISDEVICE", "Device" };
|
||||||
|
case TYPE::KIBIS_DIFFDRIVER: return { DEVICE_TYPE_::KIBIS, "IBISDIFFDRIVER", "Differential driver" };
|
||||||
|
case TYPE::KIBIS_DIFFDEVICE: return { DEVICE_TYPE_::KIBIS, "IBISDIFFDEVICE", "Differential device" };
|
||||||
case TYPE::SUBCKT: return { DEVICE_TYPE_::SUBCKT, "", "" };
|
case TYPE::SUBCKT: return { DEVICE_TYPE_::SUBCKT, "", "" };
|
||||||
case TYPE::XSPICE: return { DEVICE_TYPE_::XSPICE, "", "" };
|
case TYPE::XSPICE: return { DEVICE_TYPE_::XSPICE, "", "" };
|
||||||
case TYPE::RAWSPICE: return { DEVICE_TYPE_::SPICE, "", "" };
|
case TYPE::RAWSPICE: return { DEVICE_TYPE_::SPICE, "", "" };
|
||||||
|
@ -365,6 +367,9 @@ SIM_MODEL::SPICE_INFO SIM_MODEL::SpiceInfo( TYPE aType )
|
||||||
|
|
||||||
case TYPE::KIBIS_DEVICE: return { "X" };
|
case TYPE::KIBIS_DEVICE: return { "X" };
|
||||||
case TYPE::KIBIS_DRIVER: return { "X" };
|
case TYPE::KIBIS_DRIVER: return { "X" };
|
||||||
|
case TYPE::KIBIS_DIFFDEVICE: return { "X" };
|
||||||
|
case TYPE::KIBIS_DIFFDRIVER: return { "X" };
|
||||||
|
|
||||||
case TYPE::NONE:
|
case TYPE::NONE:
|
||||||
case TYPE::RAWSPICE:
|
case TYPE::RAWSPICE:
|
||||||
return {};
|
return {};
|
||||||
|
@ -949,6 +954,8 @@ std::unique_ptr<SIM_MODEL> SIM_MODEL::Create( TYPE aType )
|
||||||
|
|
||||||
case TYPE::KIBIS_DRIVER:
|
case TYPE::KIBIS_DRIVER:
|
||||||
case TYPE::KIBIS_DEVICE:
|
case TYPE::KIBIS_DEVICE:
|
||||||
|
case TYPE::KIBIS_DIFFDEVICE:
|
||||||
|
case TYPE::KIBIS_DIFFDRIVER:
|
||||||
return std::make_unique<SIM_MODEL_KIBIS>( aType );
|
return std::make_unique<SIM_MODEL_KIBIS>( aType );
|
||||||
|
|
||||||
case TYPE::RAWSPICE:
|
case TYPE::RAWSPICE:
|
||||||
|
|
|
@ -298,6 +298,8 @@ public:
|
||||||
|
|
||||||
KIBIS_DRIVER,
|
KIBIS_DRIVER,
|
||||||
KIBIS_DEVICE,
|
KIBIS_DEVICE,
|
||||||
|
KIBIS_DIFFDEVICE,
|
||||||
|
KIBIS_DIFFDRIVER,
|
||||||
|
|
||||||
SUBCKT,
|
SUBCKT,
|
||||||
XSPICE,
|
XSPICE,
|
||||||
|
@ -502,7 +504,7 @@ public:
|
||||||
DEVICE_TYPE_ GetDeviceType() const { return GetTypeInfo().deviceType; }
|
DEVICE_TYPE_ GetDeviceType() const { return GetTypeInfo().deviceType; }
|
||||||
TYPE GetType() const { return m_type; }
|
TYPE GetType() const { return m_type; }
|
||||||
|
|
||||||
const SIM_MODEL* GetBaseModel() const { return m_baseModel; }
|
virtual const SIM_MODEL* GetBaseModel() const { return m_baseModel; }
|
||||||
virtual void SetBaseModel( const SIM_MODEL& aBaseModel ) { m_baseModel = &aBaseModel; }
|
virtual void SetBaseModel( const SIM_MODEL& aBaseModel ) { m_baseModel = &aBaseModel; }
|
||||||
|
|
||||||
int GetPinCount() const { return static_cast<int>( m_pins.size() ); }
|
int GetPinCount() const { return static_cast<int>( m_pins.size() ); }
|
||||||
|
@ -517,7 +519,7 @@ public:
|
||||||
|
|
||||||
|
|
||||||
int GetParamCount() const { return static_cast<int>( m_params.size() ); }
|
int GetParamCount() const { return static_cast<int>( m_params.size() ); }
|
||||||
const PARAM& GetParam( unsigned aParamIndex ) const; // Return base parameter unless it's overridden.
|
virtual const PARAM& GetParam( unsigned aParamIndex ) const; // Return base parameter unless it's overridden.
|
||||||
|
|
||||||
const PARAM* FindParam( const std::string& aParamName ) const;
|
const PARAM* FindParam( const std::string& aParamName ) const;
|
||||||
|
|
||||||
|
@ -571,6 +573,7 @@ protected:
|
||||||
bool aAllowParamValuePairs = true );
|
bool aAllowParamValuePairs = true );
|
||||||
std::vector<PARAM> m_params;
|
std::vector<PARAM> m_params;
|
||||||
bool m_requiresUIUpdate = false;
|
bool m_requiresUIUpdate = false;
|
||||||
|
const SIM_MODEL* m_baseModel;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static TYPE readTypeFromSpiceStrings( const std::string& aTypeString,
|
static TYPE readTypeFromSpiceStrings( const std::string& aTypeString,
|
||||||
|
@ -599,7 +602,6 @@ private:
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<SPICE_GENERATOR> m_spiceGenerator;
|
std::unique_ptr<SPICE_GENERATOR> m_spiceGenerator;
|
||||||
const SIM_MODEL* m_baseModel;
|
|
||||||
|
|
||||||
const TYPE m_type;
|
const TYPE m_type;
|
||||||
std::vector<PIN> m_pins;
|
std::vector<PIN> m_pins;
|
||||||
|
|
|
@ -59,16 +59,25 @@ SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, std::string aWfType ) :
|
||||||
{
|
{
|
||||||
SetParameters( aType, aWfType );
|
SetParameters( aType, aWfType );
|
||||||
|
|
||||||
AddPin( { "GND", "1" } );
|
if( aType == SIM_MODEL::TYPE::KIBIS_DIFFDEVICE || aType == SIM_MODEL::TYPE::KIBIS_DIFFDRIVER )
|
||||||
AddPin( { "IN/OUT", "2" } );
|
{
|
||||||
|
AddPin( { "GND", "1" } );
|
||||||
|
AddPin( { "+", "2" } );
|
||||||
|
AddPin( { "-", "3" } );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddPin( { "GND", "1" } );
|
||||||
|
AddPin( { "IN/OUT", "2" } );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource ) : SIM_MODEL_KIBIS( aType )
|
SIM_MODEL_KIBIS::SIM_MODEL_KIBIS( TYPE aType, const SIM_MODEL_KIBIS& aSource ) : SIM_MODEL_KIBIS( aType )
|
||||||
{
|
{
|
||||||
for( PARAM& param1 : m_params )
|
for( PARAM& param1 : m_params )
|
||||||
{
|
{
|
||||||
for( auto param2refwrap : aSource.GetParams() )
|
for( auto& param2refwrap : aSource.GetParams() )
|
||||||
{
|
{
|
||||||
const PARAM& param2 = param2refwrap.get();
|
const PARAM& param2 = param2refwrap.get();
|
||||||
|
|
||||||
|
@ -109,8 +118,10 @@ void SIM_MODEL_KIBIS::SetParameters( TYPE aType, std::string aWfType )
|
||||||
makeKibisParamInfos( SIM_MODEL::TYPE::KIBIS_DRIVER, SIM_MODEL_KIBIS::DRIVER_STUCKL );
|
makeKibisParamInfos( SIM_MODEL::TYPE::KIBIS_DRIVER, SIM_MODEL_KIBIS::DRIVER_STUCKL );
|
||||||
static std::vector<PARAM::INFO> kibisparam_driver_highz =
|
static std::vector<PARAM::INFO> kibisparam_driver_highz =
|
||||||
makeKibisParamInfos( SIM_MODEL::TYPE::KIBIS_DRIVER, SIM_MODEL_KIBIS::DRIVER_HIGHZ );
|
makeKibisParamInfos( SIM_MODEL::TYPE::KIBIS_DRIVER, SIM_MODEL_KIBIS::DRIVER_HIGHZ );
|
||||||
|
static std::vector<PARAM::INFO> kibisparam_driver_prbs =
|
||||||
|
makeKibisParamInfos( SIM_MODEL::TYPE::KIBIS_DRIVER, SIM_MODEL_KIBIS::DRIVER_PRBS );
|
||||||
static std::vector<PARAM::INFO> kibisparam_driver_allParams =
|
static std::vector<PARAM::INFO> kibisparam_driver_allParams =
|
||||||
makeKibisParamInfos( SIM_MODEL::TYPE::KIBIS_DRIVER, "NoInit" );
|
makeKibisParamInfos( SIM_MODEL::TYPE::KIBIS_DRIVER, SIM_MODEL_KIBIS::JOCKER );
|
||||||
|
|
||||||
m_requiresUIUpdate = true;
|
m_requiresUIUpdate = true;
|
||||||
|
|
||||||
|
@ -118,7 +129,9 @@ void SIM_MODEL_KIBIS::SetParameters( TYPE aType, std::string aWfType )
|
||||||
|
|
||||||
switch( aType )
|
switch( aType )
|
||||||
{
|
{
|
||||||
case SIM_MODEL::TYPE::KIBIS_DEVICE: params = &kibisparam_device; break;
|
case SIM_MODEL::TYPE::KIBIS_DEVICE:
|
||||||
|
case SIM_MODEL::TYPE::KIBIS_DIFFDEVICE: params = &kibisparam_device; break;
|
||||||
|
case SIM_MODEL::TYPE::KIBIS_DIFFDRIVER:
|
||||||
case SIM_MODEL::TYPE::KIBIS_DRIVER:
|
case SIM_MODEL::TYPE::KIBIS_DRIVER:
|
||||||
|
|
||||||
if( aWfType == SIM_MODEL_KIBIS::DRIVER_RECT )
|
if( aWfType == SIM_MODEL_KIBIS::DRIVER_RECT )
|
||||||
|
@ -129,6 +142,8 @@ void SIM_MODEL_KIBIS::SetParameters( TYPE aType, std::string aWfType )
|
||||||
params = &kibisparam_driver_stuckl;
|
params = &kibisparam_driver_stuckl;
|
||||||
else if( aWfType == SIM_MODEL_KIBIS::DRIVER_HIGHZ )
|
else if( aWfType == SIM_MODEL_KIBIS::DRIVER_HIGHZ )
|
||||||
params = &kibisparam_driver_highz;
|
params = &kibisparam_driver_highz;
|
||||||
|
else if( aWfType == SIM_MODEL_KIBIS::DRIVER_PRBS )
|
||||||
|
params = &kibisparam_driver_prbs;
|
||||||
else
|
else
|
||||||
params = &kibisparam_driver_allParams;
|
params = &kibisparam_driver_allParams;
|
||||||
// All params allow for a newly created model to read any parameter
|
// All params allow for a newly created model to read any parameter
|
||||||
|
@ -137,6 +152,9 @@ void SIM_MODEL_KIBIS::SetParameters( TYPE aType, std::string aWfType )
|
||||||
default: wxFAIL; return;
|
default: wxFAIL; return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_params.clear();
|
||||||
|
|
||||||
|
/*
|
||||||
if( m_params.empty() )
|
if( m_params.empty() )
|
||||||
{
|
{
|
||||||
for( const PARAM::INFO& paramInfo : *params )
|
for( const PARAM::INFO& paramInfo : *params )
|
||||||
|
@ -151,14 +169,10 @@ void SIM_MODEL_KIBIS::SetParameters( TYPE aType, std::string aWfType )
|
||||||
m_params.pop_back(); // waveform parameters are at the end of the vector
|
m_params.pop_back(); // waveform parameters are at the end of the vector
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
for( const PARAM::INFO& paramInfo : *params )
|
for( const PARAM::INFO& paramInfo : *params )
|
||||||
{
|
AddParam( paramInfo );
|
||||||
if( paramInfo.category == PARAM::CATEGORY::WAVEFORM )
|
|
||||||
{
|
|
||||||
AddParam( paramInfo );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SIM_MODEL_KIBIS::SetParameters( std::string aWfType )
|
void SIM_MODEL_KIBIS::SetParameters( std::string aWfType )
|
||||||
|
@ -204,7 +218,7 @@ SIM_MODEL_KIBIS::makeKibisParamInfos( TYPE aType, std::string aWfType )
|
||||||
paramInfos.push_back( paramInfo );
|
paramInfos.push_back( paramInfo );
|
||||||
|
|
||||||
paramInfo.name = "lpin";
|
paramInfo.name = "lpin";
|
||||||
paramInfo.type = SIM_VALUE::TYPE_STRING;
|
paramInfo.type = SIM_VALUE::TYPE_STRING;
|
||||||
paramInfo.unit = "";
|
paramInfo.unit = "";
|
||||||
paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
|
paramInfo.category = PARAM::CATEGORY::PRINCIPAL;
|
||||||
paramInfo.defaultValue = "TYP";
|
paramInfo.defaultValue = "TYP";
|
||||||
|
@ -223,9 +237,26 @@ SIM_MODEL_KIBIS::makeKibisParamInfos( TYPE aType, std::string aWfType )
|
||||||
paramInfo.enumValues = { "TYP", "MIN", "MAX" };
|
paramInfo.enumValues = { "TYP", "MIN", "MAX" };
|
||||||
paramInfos.push_back( paramInfo );
|
paramInfos.push_back( paramInfo );
|
||||||
|
|
||||||
if ( aType == SIM_MODEL::TYPE::KIBIS_DEVICE )
|
if( aType == SIM_MODEL::TYPE::KIBIS_DEVICE || aType == SIM_MODEL::TYPE::KIBIS_DIFFDEVICE )
|
||||||
return paramInfos; // Devices have no waveform parameters
|
return paramInfos; // Devices have no waveform parameters
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
paramInfo.name = "wftype";
|
||||||
|
paramInfo.type = SIM_VALUE::TYPE_STRING;
|
||||||
|
paramInfo.unit = "";
|
||||||
|
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
|
||||||
|
paramInfo.defaultValue = DRIVER_HIGHZ;
|
||||||
|
paramInfo.description = _( "Waveform" );
|
||||||
|
paramInfo.spiceModelName = "";
|
||||||
|
paramInfo.enumValues = { DRIVER_RECT, DRIVER_STUCKH, DRIVER_STUCKL, DRIVER_HIGHZ, DRIVER_PRBS };
|
||||||
|
paramInfos.push_back( paramInfo );
|
||||||
|
|
||||||
|
if( aWfType == DRIVER_STUCKH || aWfType == DRIVER_STUCKL || aWfType == DRIVER_HIGHZ )
|
||||||
|
{
|
||||||
|
return paramInfos;
|
||||||
|
}
|
||||||
|
|
||||||
paramInfo.name = "ac";
|
paramInfo.name = "ac";
|
||||||
paramInfo.type = SIM_VALUE::TYPE_STRING;
|
paramInfo.type = SIM_VALUE::TYPE_STRING;
|
||||||
paramInfo.unit = "";
|
paramInfo.unit = "";
|
||||||
|
@ -236,47 +267,58 @@ SIM_MODEL_KIBIS::makeKibisParamInfos( TYPE aType, std::string aWfType )
|
||||||
paramInfo.enumValues = { "low", "normal", "high" };
|
paramInfo.enumValues = { "low", "normal", "high" };
|
||||||
paramInfos.push_back( paramInfo );
|
paramInfos.push_back( paramInfo );
|
||||||
|
|
||||||
paramInfo.name = "wftype";
|
if ( aWfType == DRIVER_RECT || aWfType == JOCKER )
|
||||||
paramInfo.type = SIM_VALUE::TYPE_STRING;
|
|
||||||
paramInfo.unit = "";
|
|
||||||
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
|
|
||||||
paramInfo.defaultValue = DRIVER_HIGHZ;
|
|
||||||
paramInfo.description = _( "Waveform" );
|
|
||||||
paramInfo.spiceModelName = "";
|
|
||||||
paramInfo.enumValues = { DRIVER_RECT, DRIVER_STUCKH, DRIVER_STUCKL, DRIVER_HIGHZ };
|
|
||||||
paramInfos.push_back( paramInfo );
|
|
||||||
|
|
||||||
if( aWfType == DRIVER_STUCKH || aWfType == DRIVER_STUCKL || aWfType == DRIVER_HIGHZ )
|
|
||||||
{
|
{
|
||||||
return paramInfos;
|
paramInfo.name = "ton";
|
||||||
|
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
|
||||||
|
paramInfo.unit = "s";
|
||||||
|
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
|
||||||
|
paramInfo.defaultValue = "";
|
||||||
|
paramInfo.description = _( "ON time" );
|
||||||
|
paramInfo.spiceModelName = "";
|
||||||
|
paramInfos.push_back( paramInfo );
|
||||||
|
|
||||||
|
paramInfo.name = "toff";
|
||||||
|
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
|
||||||
|
paramInfo.unit = "s";
|
||||||
|
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
|
||||||
|
paramInfo.defaultValue = "";
|
||||||
|
paramInfo.description = _( "OFF time" );
|
||||||
|
paramInfo.spiceModelName = "";
|
||||||
|
paramInfos.push_back( paramInfo );
|
||||||
|
|
||||||
|
paramInfo.name = "delay";
|
||||||
|
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
|
||||||
|
paramInfo.unit = "s";
|
||||||
|
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
|
||||||
|
paramInfo.defaultValue = "0";
|
||||||
|
paramInfo.description = _( "Delay" );
|
||||||
|
paramInfo.spiceModelName = "";
|
||||||
|
paramInfos.push_back( paramInfo );
|
||||||
}
|
}
|
||||||
|
|
||||||
paramInfo.name = "ton";
|
if ( ( aWfType == DRIVER_PRBS ) || ( aWfType == JOCKER ) )
|
||||||
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
|
|
||||||
paramInfo.unit = "s";
|
|
||||||
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
|
|
||||||
paramInfo.defaultValue = "";
|
|
||||||
paramInfo.description = _( "ON time" );
|
|
||||||
paramInfo.spiceModelName = "";
|
|
||||||
paramInfos.push_back( paramInfo );
|
|
||||||
|
|
||||||
paramInfo.name = "toff";
|
{
|
||||||
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
|
paramInfo.name = "f0";
|
||||||
paramInfo.unit = "s";
|
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
|
||||||
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
|
paramInfo.unit = "Hz";
|
||||||
paramInfo.defaultValue = "";
|
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
|
||||||
paramInfo.description = _( "OFF time" );
|
paramInfo.defaultValue = "";
|
||||||
paramInfo.spiceModelName = "";
|
paramInfo.description = _( "Bitrate" );
|
||||||
paramInfos.push_back( paramInfo );
|
paramInfo.spiceModelName = "";
|
||||||
|
paramInfos.push_back( paramInfo );
|
||||||
|
|
||||||
paramInfo.name = "delay";
|
paramInfo.name = "bits";
|
||||||
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
|
paramInfo.type = SIM_VALUE::TYPE_FLOAT;
|
||||||
paramInfo.unit = "s";
|
paramInfo.unit = "Hz";
|
||||||
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
|
paramInfo.category = PARAM::CATEGORY::WAVEFORM;
|
||||||
paramInfo.defaultValue = "0";
|
paramInfo.defaultValue = "";
|
||||||
paramInfo.description = _( "Delay" );
|
paramInfo.description = _( "Number of bits" );
|
||||||
paramInfo.spiceModelName = "";
|
paramInfo.spiceModelName = "";
|
||||||
paramInfos.push_back( paramInfo );
|
paramInfos.push_back( paramInfo );
|
||||||
|
}
|
||||||
|
|
||||||
return paramInfos;
|
return paramInfos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,13 +50,15 @@ class SIM_MODEL_KIBIS : public SIM_MODEL
|
||||||
static constexpr auto DRIVER_STUCKH = "stuck high";
|
static constexpr auto DRIVER_STUCKH = "stuck high";
|
||||||
static constexpr auto DRIVER_STUCKL = "stuck low";
|
static constexpr auto DRIVER_STUCKL = "stuck low";
|
||||||
static constexpr auto DRIVER_HIGHZ = "high Z";
|
static constexpr auto DRIVER_HIGHZ = "high Z";
|
||||||
|
static constexpr auto DRIVER_PRBS = "prbs";
|
||||||
|
static constexpr auto JOCKER = "kicadjocker"; // Gets all parameters
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SIM_MODEL_KIBIS( TYPE aType, std::string aWfType = "NoInit" );
|
SIM_MODEL_KIBIS( TYPE aType, std::string aWfType = "NoInit" );
|
||||||
|
|
||||||
// @brief Special copy constructor
|
// @brief Special copy constructor
|
||||||
// creates a a model with aType, but tries to match parameters from aSource.
|
// creates a a model with aType, but tries to match parameters from aSource.
|
||||||
SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource );
|
SIM_MODEL_KIBIS( TYPE aType, const SIM_MODEL_KIBIS& aSource );
|
||||||
|
|
||||||
SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource, const std::vector<LIB_FIELD>& aFields );
|
SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource, const std::vector<LIB_FIELD>& aFields );
|
||||||
SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource, const std::vector<SCH_FIELD>& aFields );
|
SIM_MODEL_KIBIS( TYPE aType, SIM_MODEL_KIBIS& aSource, const std::vector<SCH_FIELD>& aFields );
|
||||||
|
@ -80,6 +82,9 @@ public:
|
||||||
: m_componentName;
|
: m_componentName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const PARAM& GetParam( unsigned aParamIndex ) const override { return m_params.at( aParamIndex ); };
|
||||||
|
|
||||||
/** @brief update the list of available models based on the pin number.
|
/** @brief update the list of available models based on the pin number.
|
||||||
* */
|
* */
|
||||||
bool ChangePin( SIM_LIBRARY_KIBIS& aLib, std::string aPinNumber );
|
bool ChangePin( SIM_LIBRARY_KIBIS& aLib, std::string aPinNumber );
|
||||||
|
|
|
@ -481,6 +481,7 @@ std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNo
|
||||||
{
|
{
|
||||||
IBIS_CORNER supply = aParam.m_supply;
|
IBIS_CORNER supply = aParam.m_supply;
|
||||||
std::string simul;
|
std::string simul;
|
||||||
|
std::vector<int>stimuliIndex;
|
||||||
|
|
||||||
IbisWaveform risingWF = TrimWaveform( *( aPair.first ) );
|
IbisWaveform risingWF = TrimWaveform( *( aPair.first ) );
|
||||||
IbisWaveform fallingWF = TrimWaveform( *( aPair.second ) );
|
IbisWaveform fallingWF = TrimWaveform( *( aPair.second ) );
|
||||||
|
@ -495,16 +496,24 @@ std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNo
|
||||||
double delta = deltaR + deltaF;
|
double delta = deltaR + deltaF;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
|
int prevBit = 2;
|
||||||
|
|
||||||
for( std::pair<int, double> bit : aBits )
|
for( std::pair<int, double> bit : aBits )
|
||||||
{
|
{
|
||||||
IbisWaveform* WF;
|
IbisWaveform* WF;
|
||||||
double timing = bit.second;
|
double timing = bit.second;
|
||||||
|
|
||||||
|
|
||||||
|
if ( bit.first != prevBit )
|
||||||
|
{
|
||||||
if( bit.first == 1 )
|
if( bit.first == 1 )
|
||||||
WF = &risingWF;
|
WF = &risingWF;
|
||||||
else
|
else
|
||||||
WF = &fallingWF;
|
WF = &fallingWF;
|
||||||
|
|
||||||
|
stimuliIndex.push_back( i );
|
||||||
|
|
||||||
simul += "Vstimuli";
|
simul += "Vstimuli";
|
||||||
simul += std::to_string( i );
|
simul += std::to_string( i );
|
||||||
simul += " stimuli";
|
simul += " stimuli";
|
||||||
|
@ -534,8 +543,10 @@ std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNo
|
||||||
simul += " ";
|
simul += " ";
|
||||||
}
|
}
|
||||||
simul += ")\n";
|
simul += ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
prevBit = bit.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
simul += "bin ";
|
simul += "bin ";
|
||||||
|
@ -544,7 +555,7 @@ std::string KIBIS_MODEL::generateSquareWave( std::string aNode1, std::string aNo
|
||||||
simul += aNode2;
|
simul += aNode2;
|
||||||
simul += " v=(";
|
simul += " v=(";
|
||||||
|
|
||||||
for( size_t ii = 0; ii < aBits.size(); ii++ )
|
for( int ii: stimuliIndex )
|
||||||
{
|
{
|
||||||
simul += " v( stimuli";
|
simul += " v( stimuli";
|
||||||
simul += std::to_string( ii );
|
simul += std::to_string( ii );
|
||||||
|
@ -797,6 +808,13 @@ std::string KIBIS_PIN::KuKdDriver( KIBIS_MODEL& aMode
|
||||||
simul += aModel.generateSquareWave( "DIE0", "GND", bits, aPair, aParam );
|
simul += aModel.generateSquareWave( "DIE0", "GND", bits, aPair, aParam );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case KIBIS_WAVEFORM_TYPE::PRBS:
|
||||||
|
{
|
||||||
|
KIBIS_WAVEFORM_PRBS* prbsWave = dynamic_cast<KIBIS_WAVEFORM_PRBS*>( wave );
|
||||||
|
std::vector<std::pair<int, double>> bits = prbsWave->GenerateBitSequence();
|
||||||
|
simul += aModel.generateSquareWave( "DIE0", "GND", bits, aPair, aParam );
|
||||||
|
break;
|
||||||
|
}
|
||||||
case KIBIS_WAVEFORM_TYPE::STUCK_HIGH:
|
case KIBIS_WAVEFORM_TYPE::STUCK_HIGH:
|
||||||
{
|
{
|
||||||
IbisWaveform* waveform = wave->inverted ? risingWF : fallingWF;
|
IbisWaveform* waveform = wave->inverted ? risingWF : fallingWF;
|
||||||
|
@ -901,8 +919,15 @@ void KIBIS_PIN::getKuKdOneWaveform( KIBIS_MODEL& aMod
|
||||||
|
|
||||||
switch( wave->GetType() )
|
switch( wave->GetType() )
|
||||||
{
|
{
|
||||||
case KIBIS_WAVEFORM_TYPE::RECTANGULAR: simul += ".tran 0.1n 1000n \n"; break;
|
case KIBIS_WAVEFORM_TYPE::PRBS:
|
||||||
|
case KIBIS_WAVEFORM_TYPE::RECTANGULAR:
|
||||||
|
{
|
||||||
|
double duration = wave->GetDuration();
|
||||||
|
simul += ".tran 0.1n ";
|
||||||
|
simul += doubleToString( duration );
|
||||||
|
simul += "\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
case KIBIS_WAVEFORM_TYPE::HIGH_Z:
|
case KIBIS_WAVEFORM_TYPE::HIGH_Z:
|
||||||
case KIBIS_WAVEFORM_TYPE::STUCK_LOW:
|
case KIBIS_WAVEFORM_TYPE::STUCK_LOW:
|
||||||
case KIBIS_WAVEFORM_TYPE::STUCK_HIGH:
|
case KIBIS_WAVEFORM_TYPE::STUCK_HIGH:
|
||||||
|
@ -1097,15 +1122,30 @@ void KIBIS_PIN::getKuKdTwoWaveforms( KIBIS_MODEL& aMo
|
||||||
Report( _( "Driver needs at least a pullup or a pulldown" ), RPT_SEVERITY_ERROR );
|
Report( _( "Driver needs at least a pullup or a pulldown" ), RPT_SEVERITY_ERROR );
|
||||||
}
|
}
|
||||||
|
|
||||||
simul += ".tran 0.1n 1000n \n";
|
switch( wave->GetType() )
|
||||||
|
{
|
||||||
|
case KIBIS_WAVEFORM_TYPE::RECTANGULAR:
|
||||||
|
case KIBIS_WAVEFORM_TYPE::PRBS:
|
||||||
|
{
|
||||||
|
double duration = wave->GetDuration();
|
||||||
|
simul += ".tran 0.1n ";
|
||||||
|
simul += doubleToString( duration );
|
||||||
|
simul += "\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case KIBIS_WAVEFORM_TYPE::HIGH_Z:
|
||||||
|
case KIBIS_WAVEFORM_TYPE::STUCK_LOW:
|
||||||
|
case KIBIS_WAVEFORM_TYPE::STUCK_HIGH:
|
||||||
|
default: simul += ".tran 0.5 1 \n"; //
|
||||||
|
}
|
||||||
//simul += ".dc Vpin -5 5 0.1\n";
|
//simul += ".dc Vpin -5 5 0.1\n";
|
||||||
simul += ".control run \n";
|
simul += ".control run \n";
|
||||||
simul += "set filetype=ascii\n";
|
simul += "set filetype=ascii\n";
|
||||||
simul += "run \n";
|
simul += "run \n";
|
||||||
simul += "plot v(KU) v(KD)\n";
|
simul += "plot v(KU) v(KD)\n";
|
||||||
simul += "plot v(x1.DIE0) \n";
|
//simul += "plot v(x1.DIE0) \n";
|
||||||
simul += "write temp_output.spice v(KU) v(KD)\n"; // @TODO we might want to remove this...
|
simul += "write temp_output.spice v(KU) v(KD)\n"; // @TODO we might want to remove this...
|
||||||
//simul += "quit\n";
|
simul += "quit\n";
|
||||||
simul += ".endc \n";
|
simul += ".endc \n";
|
||||||
simul += ".end \n";
|
simul += ".end \n";
|
||||||
|
|
||||||
|
@ -1142,13 +1182,13 @@ bool KIBIS_PIN::writeSpiceDriver( std::string* aDest, std::string aName, KIBIS_M
|
||||||
|
|
||||||
if( m_parent )
|
if( m_parent )
|
||||||
{
|
{
|
||||||
result += m_parent->m_name;
|
//result += m_parent->m_name;
|
||||||
}
|
}
|
||||||
result += "\n*Manufacturer: ";
|
result += "\n*Manufacturer: ";
|
||||||
|
|
||||||
if( m_parent )
|
if( m_parent )
|
||||||
{
|
{
|
||||||
result += m_parent->m_manufacturer;
|
//result += m_parent->m_manufacturer;
|
||||||
}
|
}
|
||||||
result += "\n*Pin number: ";
|
result += "\n*Pin number: ";
|
||||||
result += m_pinNumber;
|
result += m_pinNumber;
|
||||||
|
@ -1303,13 +1343,13 @@ bool KIBIS_PIN::writeSpiceDiffDriver( std::string* aDest, std::string aName, KIB
|
||||||
|
|
||||||
if( m_parent )
|
if( m_parent )
|
||||||
{
|
{
|
||||||
result += m_parent->m_name;
|
//result += m_parent->m_name;
|
||||||
}
|
}
|
||||||
result += "\n*Manufacturer: ";
|
result += "\n*Manufacturer: ";
|
||||||
|
|
||||||
if( m_parent )
|
if( m_parent )
|
||||||
{
|
{
|
||||||
result += m_parent->m_manufacturer;
|
//result += m_parent->m_manufacturer;
|
||||||
}
|
}
|
||||||
|
|
||||||
result += "\n.SUBCKT ";
|
result += "\n.SUBCKT ";
|
||||||
|
@ -1350,13 +1390,13 @@ bool KIBIS_PIN::writeSpiceDiffDevice( std::string* aDest, std::string aName, KIB
|
||||||
|
|
||||||
if( m_parent )
|
if( m_parent )
|
||||||
{
|
{
|
||||||
result += m_parent->m_name;
|
//result += m_parent->m_name;
|
||||||
}
|
}
|
||||||
result += "\n*Manufacturer: ";
|
result += "\n*Manufacturer: ";
|
||||||
|
|
||||||
if( m_parent )
|
if( m_parent )
|
||||||
{
|
{
|
||||||
result += m_parent->m_manufacturer;
|
//result += m_parent->m_manufacturer;
|
||||||
}
|
}
|
||||||
|
|
||||||
result += "\n.SUBCKT ";
|
result += "\n.SUBCKT ";
|
||||||
|
@ -1414,3 +1454,38 @@ void KIBIS_PARAMETER::SetCornerFromString( IBIS_CORNER& aCorner, std::string aSt
|
||||||
else
|
else
|
||||||
aCorner = IBIS_CORNER::TYP;
|
aCorner = IBIS_CORNER::TYP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::pair<int, double>> KIBIS_WAVEFORM_PRBS::GenerateBitSequence()
|
||||||
|
{
|
||||||
|
std::vector<std::pair<int, double>> bitSequence;
|
||||||
|
uint8_t polynomial = 0b1100000;
|
||||||
|
//1100000 = x^7+x^6+1
|
||||||
|
//10100 = x^5+x^3+1
|
||||||
|
//110 = x^3+x^2+1
|
||||||
|
uint8_t seed = 0x12; // Any non zero state
|
||||||
|
uint8_t lfsr = seed;
|
||||||
|
|
||||||
|
if ( m_bitrate == 0 )
|
||||||
|
return bitSequence;
|
||||||
|
|
||||||
|
double period = 1/m_bitrate;
|
||||||
|
double t = 0;
|
||||||
|
m_bits = abs( m_bits ); // Just to be sure.
|
||||||
|
|
||||||
|
int bits = 0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
uint8_t lsb = lfsr & 0x01;
|
||||||
|
bitSequence.emplace_back( ( inverted ^ lsb ? 1 : 0 ), t );
|
||||||
|
lfsr = lfsr >> 1;
|
||||||
|
|
||||||
|
if ( lsb )
|
||||||
|
lfsr ^= polynomial;
|
||||||
|
|
||||||
|
t += period;
|
||||||
|
|
||||||
|
} while ( ++bits < m_bits );
|
||||||
|
|
||||||
|
return bitSequence;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ public:
|
||||||
enum KIBIS_WAVEFORM_TYPE
|
enum KIBIS_WAVEFORM_TYPE
|
||||||
{
|
{
|
||||||
NONE = 0, // Used for three state
|
NONE = 0, // Used for three state
|
||||||
|
PRBS,
|
||||||
RECTANGULAR,
|
RECTANGULAR,
|
||||||
STUCK_HIGH,
|
STUCK_HIGH,
|
||||||
STUCK_LOW,
|
STUCK_LOW,
|
||||||
|
@ -63,6 +64,7 @@ class KIBIS_WAVEFORM
|
||||||
public:
|
public:
|
||||||
KIBIS_WAVEFORM(){};
|
KIBIS_WAVEFORM(){};
|
||||||
KIBIS_WAVEFORM_TYPE GetType() { return m_type; };
|
KIBIS_WAVEFORM_TYPE GetType() { return m_type; };
|
||||||
|
virtual double GetDuration() { return 1; };
|
||||||
bool inverted = false; // Used for differential drivers
|
bool inverted = false; // Used for differential drivers
|
||||||
virtual ~KIBIS_WAVEFORM(){};
|
virtual ~KIBIS_WAVEFORM(){};
|
||||||
|
|
||||||
|
@ -76,8 +78,23 @@ public:
|
||||||
KIBIS_WAVEFORM_RECTANGULAR() : KIBIS_WAVEFORM() { m_type = KIBIS_WAVEFORM_TYPE::RECTANGULAR; };
|
KIBIS_WAVEFORM_RECTANGULAR() : KIBIS_WAVEFORM() { m_type = KIBIS_WAVEFORM_TYPE::RECTANGULAR; };
|
||||||
double m_ton = 100e-9;
|
double m_ton = 100e-9;
|
||||||
double m_toff = 100e-9;
|
double m_toff = 100e-9;
|
||||||
int m_cycles = 10;
|
int m_cycles = 1;
|
||||||
double m_delay = 0;
|
double m_delay = 0;
|
||||||
|
|
||||||
|
double GetDuration() override { return ( m_ton + m_toff ) * m_cycles; };
|
||||||
|
};
|
||||||
|
|
||||||
|
// For now, we only support PRBS7
|
||||||
|
class KIBIS_WAVEFORM_PRBS : public KIBIS_WAVEFORM
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
KIBIS_WAVEFORM_PRBS() : KIBIS_WAVEFORM() { m_type = KIBIS_WAVEFORM_TYPE::PRBS; };
|
||||||
|
double m_bitrate = 10e6;
|
||||||
|
double m_delay = 0;
|
||||||
|
double m_bits = 10;
|
||||||
|
|
||||||
|
std::vector<std::pair<int, double>> GenerateBitSequence();
|
||||||
|
double GetDuration() override { return m_bits / m_bitrate ; };
|
||||||
};
|
};
|
||||||
|
|
||||||
class KIBIS_WAVEFORM_STUCK_HIGH : public KIBIS_WAVEFORM
|
class KIBIS_WAVEFORM_STUCK_HIGH : public KIBIS_WAVEFORM
|
||||||
|
|
|
@ -43,6 +43,8 @@ int main( void )
|
||||||
|
|
||||||
KIBIS_PARAMETER params;
|
KIBIS_PARAMETER params;
|
||||||
|
|
||||||
|
params.m_waveform = new KIBIS_WAVEFORM_RECTANGULAR();
|
||||||
|
|
||||||
pin2->writeSpiceDevice( tmp4, "device_typ", *( pin2->m_models.at( 0 ) ), params );
|
pin2->writeSpiceDevice( tmp4, "device_typ", *( pin2->m_models.at( 0 ) ), params );
|
||||||
|
|
||||||
KIBIS_MODEL* model1 = pin1->m_models.at( 0 );
|
KIBIS_MODEL* model1 = pin1->m_models.at( 0 );
|
||||||
|
|
Loading…
Reference in New Issue