61 m_name->GetTextExtent(
"XXXXXXXXXXXXXXXXXXXXX", &x, &y );
62 m_name->SetMinSize( wxSize( x, -1 ) );
89 std::vector<int> trackColIds;
102 wxGridCellAttr* attr =
new wxGridCellAttr;
105 [
this](
int row,
int col )
107 calculateTrackParametersForCell( row, col );
112 attr =
new wxGridCellAttr;
115 [
this](
int row,
int col )
117 calculateTrackParametersForCell( row, col );
122 attr =
new wxGridCellAttr;
125 [
this](
int row,
int col )
127 calculateTrackParametersForCell( row, col );
142 std::vector<int> viaColIds;
163 m_type->SetSelection(
static_cast<int>( aProfile.
m_Type ) );
187 board->
GetLayerName( entry.GetBottomReferenceLayer() ) );
220 double targetImpedance;
235 m_parentPanel->m_layerNamesToIDs.contains( topReferenceLayerName ) )
244 if( wxString bottomReferenceLayerName =
246 m_parentPanel->m_layerNamesToIDs.contains( bottomReferenceLayerName ) )
277 std::swap( signalLayerIdFrom, signalLayerIdTo );
280 std::swap( viaLayerIdFrom, viaLayerIdTo );
300 wxArrayString layerNames, layerNamesWithNone;
301 layerNamesWithNone.push_back(
"<None>" );
303 [&layerNames, &layerNamesWithNone](
const wxString& aLayerName )
305 layerNames.push_back( aLayerName );
306 layerNamesWithNone.push_back( aLayerName );
311 std::vector<wxString> currentSignalLayer;
312 std::vector<wxString> currentTopReferenceLayer;
313 std::vector<wxString> currentBottomReferenceLayer;
319 currentBottomReferenceLayer.emplace_back(
324 std::vector<wxString> currentSignalLayersFrom;
325 std::vector<wxString> currentSignalLayersTo;
326 std::vector<wxString> currentViaLayersFrom;
327 std::vector<wxString> currentViaLayersTo;
338 wxGridCellAttr* attr =
new wxGridCellAttr;
339 attr->SetEditor(
new wxGridCellChoiceEditor( layerNames,
false ) );
342 attr =
new wxGridCellAttr;
343 attr->SetEditor(
new wxGridCellChoiceEditor( layerNamesWithNone,
false ) );
346 attr =
new wxGridCellAttr;
347 attr->SetEditor(
new wxGridCellChoiceEditor( layerNamesWithNone,
false ) );
350 attr =
new wxGridCellAttr;
351 attr->SetEditor(
new wxGridCellChoiceEditor( layerNames,
false ) );
354 attr =
new wxGridCellAttr;
355 attr->SetEditor(
new wxGridCellChoiceEditor( layerNames,
false ) );
358 attr =
new wxGridCellAttr;
359 attr->SetEditor(
new wxGridCellChoiceEditor( layerNames,
false ) );
362 attr =
new wxGridCellAttr;
363 attr->SetEditor(
new wxGridCellChoiceEditor( layerNames,
false ) );
369 if(
m_parentPanel->m_prevLayerNamesToIDs.contains( currentSignalLayer[row] ) )
373 if(
m_parentPanel->m_copperLayerIdsToIndex.contains( lastSignalId ) )
385 if(
m_parentPanel->m_prevLayerNamesToIDs.contains( currentTopReferenceLayer[row] ) )
389 if(
m_parentPanel->m_copperLayerIdsToIndex.contains( lastTopReferenceId ) )
391 m_parentPanel->m_board->GetLayerName( lastTopReferenceId ) );
400 if(
m_parentPanel->m_prevLayerNamesToIDs.contains( currentBottomReferenceLayer[row] ) )
403 m_parentPanel->m_prevLayerNamesToIDs[currentBottomReferenceLayer[row]];
405 if(
m_parentPanel->m_copperLayerIdsToIndex.contains( lastBottomReferenceId ) )
407 m_parentPanel->m_board->GetLayerName( lastBottomReferenceId ) );
421 if(
m_parentPanel->m_copperLayerIdsToIndex.contains( lastSignalFromId ) )
429 if(
m_parentPanel->m_copperLayerIdsToIndex.contains( lastSignalToId ) )
437 if(
m_parentPanel->m_copperLayerIdsToIndex.contains( lastViaFromId ) )
445 if(
m_parentPanel->m_copperLayerIdsToIndex.contains( lastViaToId ) )
470 const int titleSize = GetTextExtent(
m_viaOverrides->GetColLabelValue( i ) ).x;
472 m_viaOverrides->SetColSize( i, std::max( titleSize, minValueWidth ) );
477 const int impedanceWidth =
m_targetImpedance->GetTextExtent( wxT(
"0000.00" ) ).x;
486 const wxString newName =
event.GetString();
493 if( event.GetSelection() == 0 )
517 auto setFrontRowLayers = [&](
const int row )
534 auto setRowLayers = [&]()
538 setFrontRowLayers( 0 );
542 const wxString lastSignalLayerName =
545 lastSignalLayerName );
552 setFrontRowLayers( numRows );
583 if( selRows.size() == 1 )
605 if( selRows.size() == 1 )
612 return m_name->GetValue();
617 const double aSigma )
626 bool layerFound =
false;
627 int layerStackupId = 0;
629 while( layerStackupId <
static_cast<int>( aLayerList.size() ) && !layerFound )
631 if( aLayerList.at( layerStackupId )->GetBrdLayerId() != aPcbLayerId )
640 return layerStackupId;
649 if( !zStr.ToDouble( &z ) )
657 const std::vector<BOARD_STACKUP_ITEM*>& aStackupLayerList,
const std::vector<int>& dielectricLayerStackupIds,
660 double totalHeight = 0.0;
662 double lossTangent = 0.0;
664 for(
int i : dielectricLayerStackupIds )
668 for(
int subLayerIdx = 0; subLayerIdx < layer->
GetSublayersCount(); ++subLayerIdx )
676 e_r = e_r / totalHeight;
677 lossTangent = lossTangent / totalHeight;
678 totalHeight /= 1000.0;
680 return { totalHeight, e_r, lossTangent };
685 const int aSignalLayerId,
const int aReferenceLayerId,
686 std::vector<int>& aDielectricLayerStackupIds )
688 for(
int i = std::min( aSignalLayerId, aReferenceLayerId ) + 1; i < std::max( aSignalLayerId, aReferenceLayerId );
699 aDielectricLayerStackupIds.push_back( i );
709 if( !
m_parentPanel->m_layerNamesToIDs.contains( signalLayerName ) )
729 int calculatedWidth = 0;
730 int calculatedGap = 0;
731 int calculatedDelay = 0;
746 calculatedWidth =
result.Width;
747 calculatedGap =
result.DiffPairGap;
748 calculatedDelay =
result.Delay;
750 const bool widthOk = calculatedWidth > 0;
751 const bool gapOk = calculatedGap > 0;
752 const bool delayOk = calculatedDelay > 0;
783 int calculatedWidth = 0;
784 int calculatedDelay = 0;
799 calculatedWidth =
result.Width;
800 calculatedDelay =
result.Delay;
802 const bool widthOk = calculatedWidth > 0;
803 const bool delayOk = calculatedDelay > 0;
828 if(
m_name->GetValue() == wxEmptyString )
832 const wxString msg =
_(
"Tuning profile must have a name" );
837 std::set<wxString> layerNames;
843 if( layerNames.contains( layerName ) )
847 const wxString msg =
_(
"Duplicated signal layer configuration in tuning profile" );
853 layerNames.insert( layerName );
870 const std::vector<BOARD_STACKUP_ITEM*>& stackupLayerList = stackup.
GetList();
874 if( !
m_parentPanel->m_layerNamesToIDs.contains( signalLayerName ) )
880 if( signalLayer !=
F_Cu && signalLayer !=
B_Cu )
881 return { {},
CALCULATION_RESULT{
_(
"Internal error: Microstrip can only be on an outer copper layer" ) } };
883 const int signalLayerStackupId =
getStackupLayerId( stackupLayerList, signalLayer );
885 if( signalLayerStackupId == -1 )
888 const double signalLayerThickness =
889 aScale.
IUTomm( stackupLayerList.at( signalLayerStackupId )->GetThickness() ) / 1000.0;
891 if( signalLayerThickness <= 0 )
895 wxString referenceLayerName;
897 if( signalLayer ==
F_Cu )
902 if( !
m_parentPanel->m_layerNamesToIDs.contains( referenceLayerName ) )
906 const int referenceLayerStackupId =
getStackupLayerId( stackupLayerList, referenceLayer );
908 if( signalLayerStackupId == referenceLayerStackupId )
909 return { {},
CALCULATION_RESULT{
_(
"Reference layer must be different to signal layer" ) } };
912 std::vector<int> dielectricLayerStackupIds;
913 getDielectricLayers( stackupLayerList, signalLayerStackupId, referenceLayerStackupId, dielectricLayerStackupIds );
919 if( dielectricInfo.
Height <= 0.0 )
927 return { boardParameters,
result };
937 const std::vector<BOARD_STACKUP_ITEM*>& stackupLayerList = stackup.
GetList();
941 if( !
m_parentPanel->m_layerNamesToIDs.contains( signalLayerName ) )
945 const int signalLayerStackupId =
getStackupLayerId( stackupLayerList, signalLayer );
947 if( signalLayerStackupId == -1 )
950 const double signalLayerThickness =
951 aScale.
IUTomm( stackupLayerList.at( signalLayerStackupId )->GetThickness() ) / 1000.0;
953 if( signalLayerThickness <= 0 )
959 if( !
m_parentPanel->m_layerNamesToIDs.contains( topReferenceLayerName ) )
963 const int topReferenceLayerStackupId =
getStackupLayerId( stackupLayerList, topReferenceLayer );
966 return { {},
CALCULATION_RESULT{
_(
"Top reference layer must be above signal layer in board stackup" ) } };
971 if( !
m_parentPanel->m_layerNamesToIDs.contains( bottomReferenceLayerName ) )
975 const int bottomReferenceLayerStackupId =
getStackupLayerId( stackupLayerList, bottomReferenceLayer );
978 return { {},
CALCULATION_RESULT{
_(
"Bottom reference layer must be below signal layer in board stackup" ) } };
981 std::vector<int> topDielectricLayerStackupIds, bottomDielectricLayerStackupIds;
984 topDielectricLayerStackupIds );
985 getDielectricLayers( stackupLayerList, signalLayerStackupId, bottomReferenceLayerStackupId,
986 bottomDielectricLayerStackupIds );
989 std::vector<int> allDielectricLayerStackupIds( topDielectricLayerStackupIds );
990 allDielectricLayerStackupIds.insert( allDielectricLayerStackupIds.end(), bottomDielectricLayerStackupIds.begin(),
991 bottomDielectricLayerStackupIds.end() );
1000 if( topDielectricInfo.
Height <= 0.0 && bottomDielectricInfo.
Height <= 0.0 )
1004 bottomDielectricInfo.
Height, signalLayerThickness,
1009 return { boardParameters,
result };
1039 const double width = iuScale.
IUTomm( widthInt ) / 1000.0;
1065 std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& results =
1066 [
this, aCalculationType]() ->
decltype(
m_microstripCalc.GetSynthesisResults() )
1115 const double width = iuScale.
IUTomm( widthInt ) / 1000.0;
1125 + boardParameters.SignalLayerThickness
1126 + boardParameters.BottomDielectricLayerThickness );
1140 std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& results =
1141 [
this, aCalculationType]() ->
decltype(
m_striplineCalc.GetSynthesisResults() )
1190 if( !gapOpt || *gapOpt <= 0 )
1191 return CALCULATION_RESULT{
_(
"Diff pair gap must be greater than 0 to calculate width" ) };
1193 gap = iuScale.
IUTomm( gapOpt.value() ) / 1000.0;
1197 if( !widthOpt || *widthOpt <= 0 )
1198 return CALCULATION_RESULT{
_(
"Width must be greater than 0 to calculate diff pair gap" ) };
1200 width = iuScale.
IUTomm( widthOpt.value() ) / 1000.0;
1204 if( !widthOpt || !gapOpt || *widthOpt <= 0 || *gapOpt <= 0 )
1205 return CALCULATION_RESULT{
_(
"Width and diff pair gap must be greater than 0 to calculate delay" ) };
1207 width = iuScale.
IUTomm( widthOpt.value() ) / 1000.0;
1208 gap = iuScale.
IUTomm( gapOpt.value() ) / 1000.0;
1230 switch( aCalculationType )
1237 std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& results =
1238 [
this, aCalculationType]() ->
decltype(
m_microstripCalc.GetSynthesisResults() )
1292 if( !gapOpt || *gapOpt <= 0 )
1293 return CALCULATION_RESULT{
_(
"Diff pair gap must be greater than 0 to calculate width" ) };
1295 gap = iuScale.
IUTomm( gapOpt.value() ) / 1000.0;
1299 if( !widthOpt || *widthOpt <= 0 )
1300 return CALCULATION_RESULT{
_(
"Width must be greater than 0 to calculate diff pair gap" ) };
1302 width = iuScale.
IUTomm( widthOpt.value() ) / 1000.0;
1306 if( !widthOpt || !gapOpt || *widthOpt <= 0 || *gapOpt <= 0 )
1307 return CALCULATION_RESULT{
_(
"Width and diff pair gap must be greater than 0 to calculate delay" ) };
1309 width = iuScale.
IUTomm( widthOpt.value() ) / 1000.0;
1310 gap = iuScale.
IUTomm( gapOpt.value() ) / 1000.0;
1322 + boardParameters.BottomDielectricLayerThickness );
1331 switch( aCalculationType )
1338 std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& results =
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
@ BS_ITEM_TYPE_DIELECTRIC
Manage one layer needed to make a physical board.
int GetSublayersCount() const
double GetEpsilonR(int aDielectricSubLayer=0) const
bool HasEpsilonRValue() const
int GetThickness(int aDielectricSubLayer=0) const
BOARD_STACKUP_ITEM_TYPE GetType() const
double GetLossTangent(int aDielectricSubLayer=0) const
Manage layers needed to make a physical board.
const std::vector< BOARD_STACKUP_ITEM * > & GetList() const
Information pertinent to a Pcbnew printed circuit board.
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Represents a single line in a time domain profile track propagation setup.
void SetWidth(const int aWidth)
void SetEnableTimeDomainTuning(bool aEnable)
void SetDiffPairGap(const int aDiffPairGap)
void SetTopReferenceLayer(const PCB_LAYER_ID aLayer)
void SetSignalLayer(const PCB_LAYER_ID aLayer)
void SetDelay(const int aDelay)
void SetBottomReferenceLayer(const PCB_LAYER_ID aLayer)
PCB_LAYER_ID GetSignalLayer() const
A cell editor which runs a provided function when the grid cell button is clicked.
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
static PAGED_DIALOG * GetDialog(wxWindow *aWindow)
void SetError(const wxString &aMessage, const wxString &aPageName, int aCtrlId, int aRow=-1, int aCol=-1)
WX_GRID * m_trackPropagationGrid
PANEL_SETUP_TUNING_PROFILE_INFO_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(719, 506), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
wxStaticText * m_viaPropSpeedUnits
STD_BITMAP_BUTTON * m_deleteTrackPropogationLayer
wxCheckBox * m_enableDrcGeneration
STD_BITMAP_BUTTON * m_addViaPropagationOverride
STD_BITMAP_BUTTON * m_addTrackPropogationLayer
wxTextCtrl * m_viaPropagationSpeed
wxCheckBox * m_enableDelayTuning
STD_BITMAP_BUTTON * m_removeViaPropagationOverride
wxStaticText * m_viaPropagationSpeedLabel
wxTextCtrl * m_targetImpedance
void OnAddViaOverride(wxCommandEvent &event) override
Adds a via override row.
static constexpr double RHO
MICROSTRIP m_microstripCalc
Calculator for single microstrip parameters.
COUPLED_STRIPLINE m_coupledStriplineCalc
Calculator for coupled (differential) stripline parameters.
void initPanel()
Initialises all controls on the panel.
void calculateTrackParametersForCell(int aRow, int aCol)
Calculates the required track parameters for the given track parameters grid row and col.
@ TRACK_GRID_BOTTOM_REFERENCE
@ TRACK_GRID_TOP_REFERENCE
@ TRACK_GRID_SIGNAL_LAYER
CALCULATION_RESULT calculateSingleStripline(const int aRow, CalculationType aCalculationType)
Calculates the track width or delay for the given propagation grid row.
double getTargetImpedance() const
Gets the target impedance for the profile.
CALCULATION_RESULT calculateSingleMicrostrip(const int aRow, CalculationType aCalculationType)
Calculates the track width or delay for the given propagation grid row.
STRIPLINE m_striplineCalc
Calculator for single stripline parameters.
static double calculateSkinDepth(double aFreq, double aMurc, double aSigma)
Calculate the effective skin depth for the given parameters.
bool ValidateProfile(size_t aPageIndex)
Validate this panel's data.
void UpdateLayerNames()
Updates the displayed layer names in all grids.
static int getStackupLayerId(const std::vector< BOARD_STACKUP_ITEM * > &aLayerList, PCB_LAYER_ID aPcbLayerId)
Gets the index in to the layer list for the given layer.
UNIT_BINDER m_viaPropagationUnits
Units for global via propagation unit delay.
CALCULATION_RESULT calculateDifferentialMicrostrip(int aRow, CalculationType aCalculationType)
Calculates the track width, pair gap, or delay for the given propagation grid row.
std::pair< CALCULATION_BOARD_PARAMETERS, CALCULATION_RESULT > getMicrostripBoardParameters(int aRow, const EDA_IU_SCALE &aScale)
Gets the board parameters for microstrip calculations @parameter aRow The grid row to calculate board...
PANEL_SETUP_TUNING_PROFILE_INFO(wxWindow *aParentWindow, PANEL_SETUP_TUNING_PROFILES *parentPanel)
static DIELECTRIC_INFO calculateAverageDielectricConstants(const std::vector< BOARD_STACKUP_ITEM * > &aStackupLayerList, const std::vector< int > &dielectricLayerStackupIds, const EDA_IU_SCALE &aIuScale)
Calculates the geometric average of the dielectric material properties.
void LoadProfile(const TUNING_PROFILE &aProfile)
Loads the given profile in to the panel.
TUNING_PROFILE GetProfile() const
Saves the panel to the given profile.
~PANEL_SETUP_TUNING_PROFILE_INFO() override
PANEL_SETUP_TUNING_PROFILES * m_parentPanel
The parent setup panel.
void OnChangeProfileType(wxCommandEvent &event) override
Changes between Single and Differential profiles.
std::pair< CALCULATION_BOARD_PARAMETERS, CALCULATION_RESULT > getStriplineBoardParameters(int aRow, const EDA_IU_SCALE &aScale)
Gets the board parameters for stripline calculations @parameter aRow The grid row to calculate board ...
void getDielectricLayers(const std::vector< BOARD_STACKUP_ITEM * > &aStackupLayerList, int aSignalLayerId, int aReferenceLayerId, std::vector< int > &aDielectricLayerStackupIds)
Gets the dielectric layers for dielectrics between the two given copper layer IDs.
void OnRemoveTrackRow(wxCommandEvent &event) override
Removes a row from the track propagation grid.
@ VIA_GRID_SIGNAL_LAYER_TO
@ VIA_GRID_SIGNAL_LAYER_FROM
@ VIA_GRID_VIA_LAYER_FROM
wxString GetProfileName() const
Gets the name of this profile.
COUPLED_MICROSTRIP m_coupledMicrostripCalc
Calculator for coupled (differential) microstrip parameters.
CALCULATION_RESULT calculateDifferentialStripline(int aRow, CalculationType aCalculationType)
Calculates the track width, pair gap, or delay for the given propagation grid row.
void onChangeProfileType(TUNING_PROFILE::PROFILE_TYPE aType) const
Sets the panel display for the given tuning type.
void OnRemoveViaOverride(wxCommandEvent &event) override
Removes a via override row.
void OnAddTrackRow(wxCommandEvent &event) override
Adds a row to the track propagation grid.
void setColumnWidths()
Set up the widths of all grid columns.
void OnProfileNameChanged(wxCommandEvent &event) override
Updates the parent notebook control.
EDA_UNITS GetUnitsFromType(EDA_DATA_TYPE aType) const
Gets the units to use in the conversion based on the underlying user units.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
bool IsCopperLayerLowerThan(PCB_LAYER_ID aLayerA, PCB_LAYER_ID aLayerB)
Return true if copper aLayerA is placed lower than aLayerB, false otherwise.
bool IsFrontLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a front layer.
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
PCB_LAYER_ID
A quick note on layer IDs:
KICOMMON_API double FromUserUnit(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnit, double aValue)
Return in internal units the value aValue given in a real unit such as "in", "mm",...
KICOMMON_API bool IsImperialUnit(EDA_UNITS aUnit)
Represents a single line in the time domain configuration via overrides configuration grid.
constexpr double IUTomm(int iu) const
Represents a single line in the tuning profile configuration grid.
bool m_GenerateNetClassDRCRules
bool m_EnableTimeDomainTuning
std::map< PCB_LAYER_ID, DELAY_PROFILE_TRACK_PROPAGATION_ENTRY > m_TrackPropagationEntriesMap
std::vector< DELAY_PROFILE_VIA_OVERRIDE_ENTRY > m_ViaOverrides
int m_ViaPropagationDelay
std::vector< DELAY_PROFILE_TRACK_PROPAGATION_ENTRY > m_TrackPropagationEntries
wxString result
Test unit parsing edge cases and error handling.