kicad-source/common/transline_calculations/transline_calculation_base.h

230 lines
9.2 KiB
C
Raw Normal View History

/*
* Copyright The 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 package; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef TRANSLINE_CALCULATIONS_TRANSLINE_CALCULATION_BASE_H
#define TRANSLINE_CALCULATIONS_TRANSLINE_CALCULATION_BASE_H
#include <cmath>
#include <unordered_map>
/// All possible parameters used (as inputs or outputs) by the transmission line calculations
enum class TRANSLINE_PARAMETERS : int
{
// The following parameters are accessible from the UI
UNKNOWN_ID = -1,
EPSILONR, // Dielectric constant
TAND, // Dielectric Loss Tangent
RHO, // Conductivity of conductor
H, // Height of substrate
H_T, // Height of top surface
T, // Height of top conductor
PHYS_WIDTH, // Width of trace
PHYS_DIAM_IN, // Inner diameter of cable
PHYS_S, // width of gap between line and ground
PHYS_DIAM_OUT, // Outer diameter of cable
PHYS_LEN, // Length of cable
ROUGH, // Surface roughness
MUR, // Magnetic permeability of substrate
MURC, // magnetic permeability of conductor
FREQUENCY, // Frequency of operation
STRIPLINE_A, // Stripline : distance from track to top plane
TWISTEDPAIR_TWIST, // Twists per length
TWISTEDPAIR_EPSILONR_ENV, // Dielectric constant of environment
Z0, // Characteristic impedance
Z0_E, // Even-mode characteristic impedance
Z0_O, // Odd-mode characteristic impedance
ANG_L, // Electrical length in angle
DUMMY_PRM,
// The following parameters are generated by calculations
SIGMA, // Conductivity of the metal
SKIN_DEPTH, // Skin depth
LOSS_DIELECTRIC, // Loss in dielectric (dB)
LOSS_CONDUCTOR, // Loss in conductors (dB)
CUTOFF_FREQUENCY, // Cutoff frequency for higher order modes
EPSILON_EFF, // Effective dielectric constant
EPSILON_EFF_EVEN, // Even mode effective dielectric constant
EPSILON_EFF_ODD, // Odd mode effective dielectric constant
UNIT_PROP_DELAY, // The unit propagation delay (ps/cm)
UNIT_PROP_DELAY_ODD, // The odd mode unit propagation delay (ps/cm)
UNIT_PROP_DELAY_EVEN, // The even mode unit propagation delay (ps/cm)
ATTEN_COND, // The attenuation of the conductor
ATTEN_COND_EVEN, // The even mode attenuation of the conductor
ATTEN_COND_ODD, // The odd mode attenuation of the conductor
ATTEN_DILECTRIC, // The attenuation of the dilectric
ATTEN_DILECTRIC_EVEN, // The even mode attenuation of the dilectric
ATTEN_DILECTRIC_ODD, // The odd mode attenuation of the dilectric
Z_DIFF, // The differential impedance
EXTRAS_COUNT
};
/// Options for specifying synthesis inputs, targets, or strategies
enum class SYNTHESIZE_OPTS
{
DEFAULT, // Use the default synthesis options for the calculation
FIX_WIDTH, // Fixes the width of a differential pair
FIX_SPACING // Fixes the spacing of a differential pair
};
/// Parameter status values
enum class TRANSLINE_STATUS
{
OK,
WARNING,
TS_ERROR // ERROR name is colliding with a define on Windows
};
/**
* The base class for all transmission line calculations.
* This is used by the PCB calculator, and by delay profiles
*/
class TRANSLINE_CALCULATION_BASE
{
public:
/**
* Constructs the transmission line calculation object.
*
* @aParameters all parameters that are used (as inputs or outputs) by the calculation
*/
TRANSLINE_CALCULATION_BASE( std::initializer_list<TRANSLINE_PARAMETERS> aParameters )
{
InitProperties( aParameters );
}
virtual ~TRANSLINE_CALCULATION_BASE() {}
/// Sets the given calculation property
void SetParameter( const TRANSLINE_PARAMETERS aParam, const double aValue ) { m_parameters.at( aParam ) = aValue; }
/// Gets the given calculation property
double GetParameter( const TRANSLINE_PARAMETERS aParam ) const { return m_parameters.at( aParam ); }
/// Adds a constant to the given parameter
double& GetParameterRef( const TRANSLINE_PARAMETERS aParam ) { return m_parameters[aParam]; }
/// Gets the output parameters following analysis
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& GetAnalysisResults();
/// Gets the output parameters following synthesis
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& GetSynthesisResults();
/// Analyses the transmission line using the current parameter set
virtual void Analyse() = 0;
/// Synthesis the transmission line using the current parameter set target
/// @returns true if the synthesis converged, otherwise false
virtual bool Synthesize( SYNTHESIZE_OPTS aOpts ) = 0;
protected:
/// Initialises the properties used (as inputs or outputs) by the calculation
void InitProperties( const std::initializer_list<TRANSLINE_PARAMETERS>& aParams );
/// Sets values in the output analysis results structure
virtual void SetAnalysisResults() = 0;
/// Sets values in the output synthesis results structure
virtual void SetSynthesisResults() = 0;
/// Sets an analysis result
void SetAnalysisResult( TRANSLINE_PARAMETERS aParam, const double aValue,
const TRANSLINE_STATUS aStatus = TRANSLINE_STATUS::OK );
/// Sets a synthesis result
void SetSynthesisResult( TRANSLINE_PARAMETERS aParam, const double aValue,
const TRANSLINE_STATUS aStatus = TRANSLINE_STATUS::OK );
/**
* minimizeZ0Error1D
*
* Tries to find a parameter that minimizes the error on Z0.
* This function only works with a single parameter.
* Calls @ref Analyse several times until the error is acceptable.
*
* This function does not change Z0 / Angl_L
*
* @param aOptimise Parameter to optimise
* @param aMeasure The parameter to measure / optimise against
* @returns true if error < MAX_ERROR, otherwise false
*/
bool MinimiseZ0Error1D( TRANSLINE_PARAMETERS aOptimise, TRANSLINE_PARAMETERS aMeasure );
/**
* minimizeZ0Error2D
*
* Tries to find the parameters that minimizes the error on Z_Diff.
* This function only works with two parameters.
* Calls @ref Analyse several times until the error is acceptable.
* While the error is unacceptable, changes slightly the parameter.
*
* This function does not change Z0 / Angl_L
*
* @param aParam1 First parameter to optimise
* @param aParam2 Secpmd parameter to optimise
* @returns true if error < MAX_ERROR, otherwise false
*/
bool MinimiseZ0Error2D( TRANSLINE_PARAMETERS aParam1, TRANSLINE_PARAMETERS aParam2 );
/**
* Calculate skin depth
*
* \f$ \frac{1}{\sqrt{ \pi \cdot f \cdot \mu \cdot \sigma }} \f$
*/
double SkinDepth() const;
/**
* Calculates the unit propagation delay (ps/cm) for the given effective permittivity
*
* @aEpsilonEff is the effective permittivity of the material
*/
static double UnitPropagationDelay( double aEpsilonEff );
/**
* Computes the complete elliptic integral of first kind K() and the second kind E() using the
* arithmetic-geometric mean algorithm (AGM) by Abramowitz and Stegun.
*
* @returns std::pair<K, E> where K = first kind integral, E = second kind integral
*/
static std::pair<double, double> EllipticIntegral( double arg );
/// Calculates cosh of the given argument
static double coth( const double x ) { return ( std::exp( 2.0 * x ) + 1.0 ) / ( std::exp( 2.0 * x ) - 1.0 ); }
/// Calculates sech of the given argument
static double sech( const double x ) { return 2.0 / ( std::exp( x ) + std::exp( -x ) ); }
/// All input and output properties used by the calculation
std::unordered_map<TRANSLINE_PARAMETERS, double> m_parameters;
/// Analysis results
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>> m_analysisStatus;
/// Synthesis results
std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>> m_synthesisStatus;
/// The maximum error for Z0 optimisations
static constexpr double m_maxError{ 0.000001 };
};
#endif //TRANSLINE_CALCULATIONS_TRANSLINE_CALCULATION_BASE_H