ADDED: PCB Tuning Profiles

Tuning profiles build on the previous delay tuning work to allow
the definition of track geometries per-layer for a given tuning
profile. These can be calculated from a target impedance (with
all relevant geometry taken from the board stackup), or entered
manually.

Tuning profiles can be configured to enable time-domain tuning,
and to automatically generate track geometry DRC rules for net
classes which have an assigned tuning profile.

Adds a DRC check for net classes with a tuning profile assigned
which is not itself defined.
This commit is contained in:
JamesJCode
2025-10-10 11:08:59 +01:00
parent 513a58a438
commit b7ce289e4e
68 changed files with 6349 additions and 2520 deletions
@@ -49,6 +49,9 @@ message NetClassBoardSettings
optional kiapi.board.types.PadStack microvia_stack = 7;
optional kiapi.common.types.Color color = 8;
// Since 10.0.0
optional string tuning_profile = 9;
}
message NetClassSchematicSettings
+2 -2
View File
@@ -153,7 +153,7 @@ set( KICOMMON_SRCS
project/project_archiver.cpp
project/project_file.cpp
project/project_local_settings.cpp
project/time_domain_parameters.cpp
project/tuning_profiles.cpp
text_eval/text_eval_wrapper.cpp
text_eval/text_eval_parser.cpp
@@ -959,7 +959,7 @@ set( PCB_COMMON_SRCS
${CMAKE_SOURCE_DIR}/pcbnew/length_delay_calculation/length_delay_calculation.cpp
${CMAKE_SOURCE_DIR}/pcbnew/length_delay_calculation/length_delay_calculation_item.cpp
${CMAKE_SOURCE_DIR}/pcbnew/length_delay_calculation/time_domain_parameters_user_defined.cpp
${CMAKE_SOURCE_DIR}/pcbnew/length_delay_calculation/tuning_profile_parameters_user_defined.cpp
widgets/net_selector.cpp
)
+2 -2
View File
@@ -287,7 +287,7 @@ void PANEL_SETUP_NETCLASSES::loadNetclasses()
[&]( int aRow, const NETCLASS* nc )
{
m_netclassGrid->SetCellValue( aRow, GRID_NAME, nc->GetName() );
m_netclassGrid->SetCellValue( aRow, GRID_DELAY_PROFILE, nc->GetDelayProfile() );
m_netclassGrid->SetCellValue( aRow, GRID_DELAY_PROFILE, nc->GetTuningProfile() );
m_netclassGrid->SetOptionalUnitValue( aRow, GRID_WIREWIDTH, nc->GetWireWidthOpt() );
m_netclassGrid->SetOptionalUnitValue( aRow, GRID_BUSWIDTH, nc->GetBusWidthOpt() );
@@ -486,7 +486,7 @@ bool PANEL_SETUP_NETCLASSES::TransferDataFromWindow()
nc->SetPriority( aRow );
nc->SetName( m_netclassGrid->GetCellValue( aRow, GRID_NAME ) );
nc->SetDelayProfile( m_netclassGrid->GetCellValue( aRow, GRID_DELAY_PROFILE ) );
nc->SetTuningProfile( m_netclassGrid->GetCellValue( aRow, GRID_DELAY_PROFILE ) );
nc->SetWireWidth( m_netclassGrid->GetOptionalUnitValue( aRow, GRID_WIREWIDTH ) );
nc->SetBusWidth( m_netclassGrid->GetOptionalUnitValue( aRow, GRID_BUSWIDTH ) );
@@ -57,7 +57,7 @@ PANEL_SETUP_NETCLASSES_BASE::PANEL_SETUP_NETCLASSES_BASE( wxWindow* parent, wxWi
m_netclassGrid->SetColLabelValue( 6, _("uVia Hole") );
m_netclassGrid->SetColLabelValue( 7, _("DP Width") );
m_netclassGrid->SetColLabelValue( 8, _("DP Gap") );
m_netclassGrid->SetColLabelValue( 9, _("Delay Profile") );
m_netclassGrid->SetColLabelValue( 9, _("Tuning Profile") );
m_netclassGrid->SetColLabelValue( 10, _("PCB Color") );
m_netclassGrid->SetColLabelValue( 11, _("Wire Thickness") );
m_netclassGrid->SetColLabelValue( 12, _("Bus Thickness") );
@@ -290,7 +290,7 @@
<property name="close_button">1</property>
<property name="col_label_horiz_alignment">wxALIGN_CENTER</property>
<property name="col_label_size">wxGRID_AUTOSIZE</property>
<property name="col_label_values">&quot;Name&quot; &quot;Clearance&quot; &quot;Track Width&quot; &quot;Via Size&quot; &quot;Via Hole&quot; &quot;uVia Size&quot; &quot;uVia Hole&quot; &quot;DP Width&quot; &quot;DP Gap&quot; &quot;Delay Profile&quot; &quot;PCB Color&quot; &quot;Wire Thickness&quot; &quot;Bus Thickness&quot; &quot;Color&quot; &quot;Line Style&quot;</property>
<property name="col_label_values">&quot;Name&quot; &quot;Clearance&quot; &quot;Track Width&quot; &quot;Via Size&quot; &quot;Via Hole&quot; &quot;uVia Size&quot; &quot;uVia Hole&quot; &quot;DP Width&quot; &quot;DP Gap&quot; &quot;Tuning Profile&quot; &quot;PCB Color&quot; &quot;Wire Thickness&quot; &quot;Bus Thickness&quot; &quot;Color&quot; &quot;Line Style&quot;</property>
<property name="col_label_vert_alignment">wxALIGN_CENTER</property>
<property name="cols">15</property>
<property name="column_sizes"></property>
+8 -2
View File
@@ -59,7 +59,7 @@ NETCLASS::NETCLASS( const wxString& aName, bool aInitWithDefaults ) : m_isDefaul
SetName( aName );
SetPriority( -1 );
SetDelayProfile( wxEmptyString );
SetTuningProfile( wxEmptyString );
// Colors are a special optional case - always set, but UNSPECIFIED used in place of optional
SetPcbColor( COLOR4D::UNSPECIFIED );
@@ -102,7 +102,7 @@ void NETCLASS::ResetParents()
SetBusWidthParent( this );
SetSchematicColorParent( this );
SetLineStyleParent( this );
SetDelayProfileParent( this );
SetTuningProfileParent( this );
}
@@ -180,6 +180,9 @@ void NETCLASS::Serialize( google::protobuf::Any &aContainer ) const
if( m_pcbColor != COLOR4D::UNSPECIFIED )
PackColor( *board->mutable_color(), m_pcbColor );
if( m_tuningProfile != wxEmptyString )
board->set_tuning_profile( m_tuningProfile.ToUTF8() );
project::NetClassSchematicSettings* schematic = nc.mutable_schematic();
if( m_wireWidth )
@@ -246,6 +249,9 @@ bool NETCLASS::Deserialize( const google::protobuf::Any &aContainer )
if( nc.board().has_color() )
m_pcbColor = UnpackColor( nc.board().color() );
if( nc.board().has_tuning_profile() )
m_tuningProfile = wxString::FromUTF8( nc.board().tuning_profile() );
if( nc.schematic().has_wire_width() )
m_wireWidth = nc.schematic().wire_width().value_nm();
+8 -8
View File
@@ -76,7 +76,7 @@ NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
{ "priority", nc->GetPriority() },
{ "schematic_color", nc->GetSchematicColor( true ) },
{ "pcb_color", nc->GetPcbColor( true ) },
{ "tuning_profile", nc->GetDelayProfile() } };
{ "tuning_profile", nc->GetTuningProfile() } };
auto saveInPcbUnits =
[]( nlohmann::json& json, const std::string& aKey, int aValue )
@@ -134,7 +134,7 @@ NET_SETTINGS::NET_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
int priority = entry["priority"];
nc->SetPriority( priority );
nc->SetDelayProfile( entry["tuning_profile"] );
nc->SetTuningProfile( entry["tuning_profile"] );
if( auto value = getInPcbUnits( entry, "clearance" ) )
nc->SetClearance( *value );
@@ -925,10 +925,10 @@ void NET_SETTINGS::makeEffectiveNetclass( std::shared_ptr<NETCLASS>& effectiveNe
effectiveNetclass->SetSchematicColorParent( nc );
}
if( nc->HasDelayProfile() )
if( nc->HasTuningProfile() )
{
effectiveNetclass->SetDelayProfile( nc->GetDelayProfile() );
effectiveNetclass->SetDelayProfileParent( nc );
effectiveNetclass->SetTuningProfile( nc->GetTuningProfile() );
effectiveNetclass->SetTuningProfileParent( nc );
}
}
@@ -1021,11 +1021,11 @@ bool NET_SETTINGS::addMissingDefaults( NETCLASS* nc ) const
}
// The tuning profile can be empty - only fill if a default tuning profile is set
if( !nc->HasDelayProfile() && m_defaultNetClass->HasDelayProfile() )
if( !nc->HasTuningProfile() && m_defaultNetClass->HasTuningProfile() )
{
addedDefault = true;
nc->SetDelayProfile( m_defaultNetClass->GetDelayProfile() );
nc->SetDelayProfileParent( m_defaultNetClass.get() );
nc->SetTuningProfile( m_defaultNetClass->GetTuningProfile() );
nc->SetTuningProfileParent( m_defaultNetClass.get() );
}
return addedDefault;
+2 -3
View File
@@ -22,7 +22,7 @@
#include <project.h>
#include <project/component_class_settings.h>
#include <project/net_settings.h>
#include <project/time_domain_parameters.h>
#include <project/tuning_profiles.h>
#include <settings/json_settings_internals.h>
#include <project/project_file.h>
#include <settings/common_settings.h>
@@ -160,8 +160,7 @@ PROJECT_FILE::PROJECT_FILE( const wxString& aFullPath ) :
m_ComponentClassSettings =
std::make_shared<COMPONENT_CLASS_SETTINGS>( this, "component_class_settings" );
m_timeDomainParameters =
std::make_shared<TIME_DOMAIN_PARAMETERS>( this, "time_domain_parameters" );
m_tuningProfileParameters = std::make_shared<TUNING_PROFILES>( this, "tuning_profiles" );
m_params.emplace_back( new PARAM_LAYER_PRESET( "board.layer_presets", &m_LayerPresets ) );
@@ -21,18 +21,15 @@
#include <lset.h>
#include <netclass.h>
#include <io/cadstar/cadstar_archive_parser.h>
#include <project/time_domain_parameters.h>
#include <project/tuning_profiles.h>
#include <nlohmann/json.hpp>
#include <settings/parameters.h>
constexpr int timeDomainParametersSchemaVersion = 0;
constexpr int tuningParametersSchemaVersion = 0;
TIME_DOMAIN_PARAMETERS::TIME_DOMAIN_PARAMETERS( JSON_SETTINGS* aParent, const std::string& aPath ) :
NESTED_SETTINGS( "time_domain_parameters", timeDomainParametersSchemaVersion, aParent,
aPath, false )
TUNING_PROFILES::TUNING_PROFILES( JSON_SETTINGS* aParent, const std::string& aPath ) :
NESTED_SETTINGS( "tuning_profiles", tuningParametersSchemaVersion, aParent, aPath, false )
{
auto saveViaOverrideConfigurationLine =
[]( nlohmann::json& json_array, const DELAY_PROFILE_VIA_OVERRIDE_ENTRY& item )
@@ -71,14 +68,22 @@ TIME_DOMAIN_PARAMETERS::TIME_DOMAIN_PARAMETERS( JSON_SETTINGS* aParent, const st
};
auto saveUserDefinedProfileConfigurationLine =
[&saveViaOverrideConfigurationLine]( nlohmann::json& json_array, const DELAY_PROFILE& item )
[&saveViaOverrideConfigurationLine]( nlohmann::json& json_array, const TUNING_PROFILE& item )
{
nlohmann::json layer_velocities = nlohmann::json::array();
nlohmann::json layer_entries = nlohmann::json::array();
for( const auto& [layerId, velocity] : item.m_LayerPropagationDelays )
for( const DELAY_PROFILE_TRACK_PROPAGATION_ENTRY& trackEntry : item.m_TrackPropagationEntries )
{
nlohmann::json layer_json = { { "layer", LSET::Name( layerId ) }, { "delay", velocity } };
layer_velocities.push_back( layer_json );
nlohmann::json layer_json;
layer_json["signal_layer"] = LSET::Name( trackEntry.m_signalLayer );
layer_json["top_reference_layer"] = LSET::Name( trackEntry.m_topReferenceLayer );
layer_json["bottom_reference_layer"] = LSET::Name( trackEntry.m_bottomReferenceLayer );
layer_json["width"] = trackEntry.m_width;
layer_json["diff_pair_gap"] = trackEntry.m_diffPairGap;
layer_json["delay"] = trackEntry.m_delay;
layer_entries.push_back( layer_json );
}
nlohmann::json via_overrides = nlohmann::json::array();
@@ -89,8 +94,12 @@ TIME_DOMAIN_PARAMETERS::TIME_DOMAIN_PARAMETERS( JSON_SETTINGS* aParent, const st
}
const nlohmann::json item_json = { { "profile_name", item.m_ProfileName.ToUTF8() },
{ "type", static_cast<int>( item.m_Type ) },
{ "target_impedance", item.m_TargetImpedance },
{ "generate_drc_rules", item.m_GenerateNetClassDRCRules },
{ "enable_time_domain_tuning", item.m_EnableTimeDomainTuning },
{ "layer_entries", layer_entries },
{ "via_prop_delay", item.m_ViaPropagationDelay },
{ "layer_delays", layer_velocities },
{ "via_overrides", via_overrides } };
json_array.push_back( item_json );
@@ -98,19 +107,38 @@ TIME_DOMAIN_PARAMETERS::TIME_DOMAIN_PARAMETERS( JSON_SETTINGS* aParent, const st
auto readUserDefinedProfileConfigurationLine = [&readViaOverrideConfigurationLine]( const nlohmann::json& entry )
{
const wxString profileName = entry["profile_name"];
const int viaPropDelay = entry["via_prop_delay"];
std::map<PCB_LAYER_ID, int> traceDelays;
const wxString profileName = entry["profile_name"];
const TUNING_PROFILE::PROFILE_TYPE profileType = static_cast<TUNING_PROFILE::PROFILE_TYPE>( entry["type"] );
const double targetImpedance = entry["target_impedance"];
const bool generateDrcRules = entry["generate_drc_rules"];
const bool enableTimeDomainTuning = entry["enable_time_domain_tuning"];
const int viaPropDelay = entry["via_prop_delay"];
std::vector<DELAY_PROFILE_TRACK_PROPAGATION_ENTRY> trackEntries;
std::map<PCB_LAYER_ID, DELAY_PROFILE_TRACK_PROPAGATION_ENTRY> trackEntriesMap;
for( const nlohmann::json& layerEntry : entry["layer_delays"] )
for( const nlohmann::json& layerEntry : entry["layer_entries"] )
{
if( !layerEntry.is_object() || !layerEntry.contains( "layer" ) )
if( !layerEntry.is_object() )
continue;
wxString layerName = layerEntry["layer"];
int layerId = LSET::NameToLayer( layerName );
const int velocity = layerEntry["delay"];
traceDelays[static_cast<PCB_LAYER_ID>( layerId )] = velocity;
wxString signalLayer = layerEntry["signal_layer"];
wxString topRefLayer = layerEntry["top_reference_layer"];
wxString bottomRefLayer = layerEntry["bottom_reference_layer"];
int signalLayerId = LSET::NameToLayer( signalLayer );
int topRefLayerId = LSET::NameToLayer( topRefLayer );
int bottomRefLayerId = LSET::NameToLayer( bottomRefLayer );
DELAY_PROFILE_TRACK_PROPAGATION_ENTRY trackEntry;
trackEntry.m_signalLayer = static_cast<PCB_LAYER_ID>( signalLayerId );
trackEntry.m_topReferenceLayer = static_cast<PCB_LAYER_ID>( topRefLayerId );
trackEntry.m_bottomReferenceLayer = static_cast<PCB_LAYER_ID>( bottomRefLayerId );
trackEntry.m_width = layerEntry["width"];
trackEntry.m_diffPairGap = layerEntry["diff_pair_gap"];
trackEntry.m_delay = layerEntry["delay"];
trackEntry.m_enableTimeDomainTuning = enableTimeDomainTuning;
trackEntries.push_back( trackEntry );
trackEntriesMap[static_cast<PCB_LAYER_ID>( signalLayerId )] = trackEntry;
}
std::vector<DELAY_PROFILE_VIA_OVERRIDE_ENTRY> viaOverrides;
@@ -123,18 +151,26 @@ TIME_DOMAIN_PARAMETERS::TIME_DOMAIN_PARAMETERS( JSON_SETTINGS* aParent, const st
viaOverrides.push_back( readViaOverrideConfigurationLine( viaEntry ) );
}
DELAY_PROFILE item{ profileName, viaPropDelay, std::move( traceDelays ), std::move( viaOverrides ) };
TUNING_PROFILE item{ profileName,
profileType,
targetImpedance,
generateDrcRules,
enableTimeDomainTuning,
std::move( trackEntries ),
viaPropDelay,
std::move( viaOverrides ),
std::move( trackEntriesMap ) };
return item;
};
m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>(
"delay_profiles_user_defined",
"tuning_profiles_impedance_geometric",
[&]() -> nlohmann::json
{
nlohmann::json ret = nlohmann::json::array();
for( const auto& entry : m_delayProfiles )
for( const auto& entry : m_tuningProfiles )
saveUserDefinedProfileConfigurationLine( ret, entry );
return ret;
@@ -144,21 +180,21 @@ TIME_DOMAIN_PARAMETERS::TIME_DOMAIN_PARAMETERS( JSON_SETTINGS* aParent, const st
if( !aJson.is_array() )
return;
ClearDelayProfiles();
ClearTuningProfiles();
for( const nlohmann::json& entry : aJson )
{
if( !entry.is_object() || !entry.contains( "profile_name" ) )
continue;
m_delayProfiles.emplace_back( readUserDefinedProfileConfigurationLine( entry ) );
m_tuningProfiles.emplace_back( readUserDefinedProfileConfigurationLine( entry ) );
}
},
{} ) );
}
TIME_DOMAIN_PARAMETERS::~TIME_DOMAIN_PARAMETERS()
TUNING_PROFILES::~TUNING_PROFILES()
{
// Release early before destroying members
if( m_parent )
@@ -169,28 +205,22 @@ TIME_DOMAIN_PARAMETERS::~TIME_DOMAIN_PARAMETERS()
}
bool TIME_DOMAIN_PARAMETERS::operator==( const TIME_DOMAIN_PARAMETERS& aOther ) const
TUNING_PROFILE& TUNING_PROFILES::GetTuningProfile( wxString aProfileName )
{
/*
if( !std::equal( std::begin( m_netClasses ), std::end( m_netClasses ),
std::begin( aOther.m_netClasses ) ) )
return false;
auto itr = std::find_if( m_tuningProfiles.begin(), m_tuningProfiles.end(),
[&aProfileName]( const TUNING_PROFILE& aProfile )
{
return aProfile.m_ProfileName == aProfileName;
} );
if( !std::equal( std::begin( m_netClassPatternAssignments ),
std::end( m_netClassPatternAssignments ),
std::begin( aOther.m_netClassPatternAssignments ) ) )
return false;
if( itr == m_tuningProfiles.end() )
return m_nullDelayProfile;
if( !std::equal( std::begin( m_netClassLabelAssignments ),
std::end( m_netClassLabelAssignments ),
std::begin( aOther.m_netClassLabelAssignments ) ) )
return false;
if( !std::equal( std::begin( m_netColorAssignments ), std::end( m_netColorAssignments ),
std::begin( aOther.m_netColorAssignments ) ) )
return false;
*/
return true;
return *itr;
}
bool TUNING_PROFILES::operator==( const TUNING_PROFILES& aOther ) const
{
return m_tuningProfiles == aOther.m_tuningProfiles;
}
@@ -60,10 +60,10 @@ void COUPLED_MICROSTRIP::Analyse()
bool COUPLED_MICROSTRIP::Synthesize( const SYNTHESIZE_OPTS aOpts )
{
if( aOpts == SYNTHESIZE_OPTS::FIX_WIDTH )
return MinimiseZ0Error1D( TCP::PHYS_S, TCP::Z0_O );
return MinimiseZ0Error1D( TCP::PHYS_S, TCP::Z0_O, false );
if( aOpts == SYNTHESIZE_OPTS::FIX_SPACING )
return MinimiseZ0Error1D( TCP::PHYS_WIDTH, TCP::Z0_O );
return MinimiseZ0Error1D( TCP::PHYS_WIDTH, TCP::Z0_O, false );
double Z0_e, Z0_o, ang_l_dest;
double f1, f2, ft1, ft2, j11, j12, j21, j22, d_s_h, d_w_h, err;
@@ -173,16 +173,16 @@ void COUPLED_MICROSTRIP::SetAnalysisResults()
void COUPLED_MICROSTRIP::SetSynthesisResults()
{
SetAnalysisResult( TCP::EPSILON_EFF_EVEN, er_eff_e );
SetAnalysisResult( TCP::EPSILON_EFF_ODD, er_eff_o );
SetAnalysisResult( TCP::UNIT_PROP_DELAY_EVEN, prop_delay_e );
SetAnalysisResult( TCP::UNIT_PROP_DELAY_ODD, prop_delay_o );
SetAnalysisResult( TCP::ATTEN_COND_EVEN, atten_cond_e );
SetAnalysisResult( TCP::ATTEN_COND_ODD, atten_cond_o );
SetAnalysisResult( TCP::ATTEN_DILECTRIC_EVEN, atten_dielectric_e );
SetAnalysisResult( TCP::ATTEN_DILECTRIC_ODD, atten_dielectric_o );
SetAnalysisResult( TCP::SKIN_DEPTH, GetParameter( TCP::SKIN_DEPTH ) );
SetAnalysisResult( TCP::Z_DIFF, Zdiff );
SetSynthesisResult( TCP::EPSILON_EFF_EVEN, er_eff_e );
SetSynthesisResult( TCP::EPSILON_EFF_ODD, er_eff_o );
SetSynthesisResult( TCP::UNIT_PROP_DELAY_EVEN, prop_delay_e );
SetSynthesisResult( TCP::UNIT_PROP_DELAY_ODD, prop_delay_o );
SetSynthesisResult( TCP::ATTEN_COND_EVEN, atten_cond_e );
SetSynthesisResult( TCP::ATTEN_COND_ODD, atten_cond_o );
SetSynthesisResult( TCP::ATTEN_DILECTRIC_EVEN, atten_dielectric_e );
SetSynthesisResult( TCP::ATTEN_DILECTRIC_ODD, atten_dielectric_o );
SetSynthesisResult( TCP::SKIN_DEPTH, GetParameter( TCP::SKIN_DEPTH ) );
SetSynthesisResult( TCP::Z_DIFF, Zdiff );
const double Z0_E = GetParameter( TCP::Z0_E );
const double Z0_O = GetParameter( TCP::Z0_O );
@@ -198,12 +198,12 @@ void COUPLED_MICROSTRIP::SetSynthesisResults()
const bool L_invalid = !std::isfinite( L ) || L < 0;
const bool S_invalid = !std::isfinite( S ) || S <= 0;
SetAnalysisResult( TCP::Z0_E, Z0_E, Z0_E_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
SetAnalysisResult( TCP::Z0_O, Z0_O, Z0_O_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
SetAnalysisResult( TCP::ANG_L, ANG_L, ANG_L_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
SetAnalysisResult( TCP::PHYS_WIDTH, W, W_invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
SetAnalysisResult( TCP::PHYS_LEN, L, L_invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
SetAnalysisResult( TCP::PHYS_S, S, S_invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
SetSynthesisResult( TCP::Z0_E, Z0_E, Z0_E_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
SetSynthesisResult( TCP::Z0_O, Z0_O, Z0_O_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
SetSynthesisResult( TCP::ANG_L, ANG_L, ANG_L_invalid ? TRANSLINE_STATUS::WARNING : TRANSLINE_STATUS::OK );
SetSynthesisResult( TCP::PHYS_WIDTH, W, W_invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
SetSynthesisResult( TCP::PHYS_LEN, L, L_invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
SetSynthesisResult( TCP::PHYS_S, S, S_invalid ? TRANSLINE_STATUS::TS_ERROR : TRANSLINE_STATUS::OK );
}
@@ -71,10 +71,10 @@ void COUPLED_STRIPLINE::Analyse()
bool COUPLED_STRIPLINE::Synthesize( const SYNTHESIZE_OPTS aOpts )
{
if( aOpts == SYNTHESIZE_OPTS::FIX_WIDTH )
return MinimiseZ0Error1D( TCP::PHYS_S, TCP::Z0_O );
return MinimiseZ0Error1D( TCP::PHYS_S, TCP::Z0_O, false );
if( aOpts == SYNTHESIZE_OPTS::FIX_SPACING )
return MinimiseZ0Error1D( TCP::PHYS_WIDTH, TCP::Z0_O );
return MinimiseZ0Error1D( TCP::PHYS_WIDTH, TCP::Z0_O, false );
// This synthesis approach is modified from wcalc, which is released under GPL version 2
// Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2006 Dan McMahill
@@ -63,7 +63,7 @@ void TRANSLINE_CALCULATION_BASE::SetSynthesisResult( const TRANSLINE_PARAMETERS
bool TRANSLINE_CALCULATION_BASE::MinimiseZ0Error1D( const TRANSLINE_PARAMETERS aOptimise,
const TRANSLINE_PARAMETERS aMeasure )
const TRANSLINE_PARAMETERS aMeasure, bool aRecalculateLength )
{
double& var = GetParameterRef( aOptimise );
double& Z0_param = GetParameterRef( aMeasure );
@@ -125,17 +125,20 @@ bool TRANSLINE_CALCULATION_BASE::MinimiseZ0Error1D( const TRANSLINE_PARAMETERS a
}
/* Compute one last time, but with correct length */
Z0_param = Z0_dest;
ANG_L_param = angl_l_dest;
SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( GetParameter( TCP::EPSILON_EFF ) )
* ANG_L_param / 2.0 / M_PI ); /* in m */
Analyse();
if( aRecalculateLength )
{
Z0_param = Z0_dest;
ANG_L_param = angl_l_dest;
SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( GetParameter( TCP::EPSILON_EFF ) )
* ANG_L_param / 2.0 / M_PI ); /* in m */
Analyse();
/* Restore parameters */
Z0_param = Z0_dest;
ANG_L_param = angl_l_dest;
SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( GetParameter( TCP::EPSILON_EFF ) )
* ANG_L_param / 2.0 / M_PI ); /* in m */
/* Restore parameters */
Z0_param = Z0_dest;
ANG_L_param = angl_l_dest;
SetParameter( TCP::PHYS_LEN, TC::C0 / GetParameter( TCP::FREQUENCY ) / sqrt( GetParameter( TCP::EPSILON_EFF ) )
* ANG_L_param / 2.0 / M_PI ); /* in m */
}
return error <= m_maxError;
}
@@ -165,9 +165,11 @@ protected:
*
* @param aOptimise Parameter to optimise
* @param aMeasure The parameter to measure / optimise against
* @param aRecalculateLength True if the angular length should be recalculated (not for differential pair usage)
* @returns true if error < MAX_ERROR, otherwise false
*/
bool MinimiseZ0Error1D( TRANSLINE_PARAMETERS aOptimise, TRANSLINE_PARAMETERS aMeasure );
bool MinimiseZ0Error1D( TRANSLINE_PARAMETERS aOptimise, TRANSLINE_PARAMETERS aMeasure,
bool aRecalculateLength = false );
/**
* minimizeZ0Error2D
@@ -621,3 +621,58 @@ void GRID_CELL_PATH_EDITOR::Create( wxWindow* aParent, wxWindowID aId,
wxGridCellEditor::Create( aParent, aId, aEventHandler );
}
class TEXT_BUTTON_RUN_FUNCTION final : public wxComboCtrl
{
public:
TEXT_BUTTON_RUN_FUNCTION( wxWindow* aParent, DIALOG_SHIM* aParentDlg, std::function<void( int, int )>& aFunction,
int& aRow, int& aCol ) :
wxComboCtrl( aParent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize( 0, 0 ),
wxTE_PROCESS_ENTER | wxBORDER_NONE ),
m_dlg( aParentDlg ),
m_function( aFunction ),
m_row( aRow ),
m_col( aCol )
{
SetButtonBitmaps( KiBitmapBundle( BITMAPS::small_refresh ) );
// win32 fix, avoids drawing the "native dropdown caret"
Customize( wxCC_IFLAG_HAS_NONSTANDARD_BUTTON );
}
protected:
void DoSetPopupControl( wxComboPopup* popup ) override { m_popup = nullptr; }
void OnButtonClick() override { m_function( m_row, m_col ); }
DIALOG_SHIM* m_dlg;
std::function<void( int, int )>& m_function;
int& m_row;
int& m_col;
};
void GRID_CELL_RUN_FUNCTION_EDITOR::Create( wxWindow* aParent, wxWindowID aId, wxEvtHandler* aEventHandler )
{
m_control = new TEXT_BUTTON_RUN_FUNCTION( aParent, m_dlg, m_function, m_row, m_col );
WX_GRID::CellEditorSetMargins( Combo() );
#if wxUSE_VALIDATORS
// validate text in textctrl, if validator is set
if( m_validator )
{
Combo()->SetValidator( *m_validator );
}
#endif
wxGridCellEditor::Create( aParent, aId, aEventHandler );
}
void GRID_CELL_RUN_FUNCTION_EDITOR::BeginEdit( int aRow, int aCol, wxGrid* aGrid )
{
m_row = aRow;
m_col = aCol;
GRID_CELL_TEXT_BUTTON::BeginEdit( aRow, aCol, aGrid );
}
+10 -2
View File
@@ -386,7 +386,8 @@ void WX_GRID::onCellEditorHidden( wxGridEvent& aEvent )
if( cellEditor )
{
if( GRID_CELL_MARK_AS_NULLABLE* nullable = dynamic_cast<GRID_CELL_MARK_AS_NULLABLE*>( cellEditor ) )
if( const GRID_CELL_NULLABLE_INTERFACE* nullable =
dynamic_cast<GRID_CELL_NULLABLE_INTERFACE*>( cellEditor ) )
isNullable = nullable->IsNullable();
cellEditor->DecRef();
@@ -897,7 +898,14 @@ void WX_GRID::SetUnitValue( int aRow, int aCol, int aValue )
void WX_GRID::SetOptionalUnitValue( int aRow, int aCol, std::optional<int> aValue )
{
SetCellValue( aRow, aCol, getUnitsProvider( aCol )->StringFromOptionalValue( aValue, true ) );
EDA_DATA_TYPE cellDataType;
if( m_autoEvalColsUnits.contains( aCol ) )
cellDataType = m_autoEvalColsUnits[aCol].second;
else
cellDataType = EDA_DATA_TYPE::DISTANCE;
SetCellValue( aRow, aCol, getUnitsProvider( aCol )->StringFromOptionalValue( aValue, true, cellDataType ) );
}
+7 -7
View File
@@ -241,11 +241,11 @@ public:
void SetPriority( int aPriority ) { m_Priority = aPriority; }
int GetPriority() const { return m_Priority; }
bool HasDelayProfile() const { return !m_DelayProfile.empty(); }
void SetDelayProfile( const wxString& aDelayProfile ) { m_DelayProfile = aDelayProfile; }
wxString GetDelayProfile() const { return m_DelayProfile; }
void SetDelayProfileParent( NETCLASS* aParent ) { m_delayProfileParent = aParent; }
NETCLASS* GetDelayProfileParent() const { return m_delayProfileParent; }
bool HasTuningProfile() const { return !m_tuningProfile.empty(); }
void SetTuningProfile( const wxString& aTuningProfile ) { m_tuningProfile = aTuningProfile; }
wxString GetTuningProfile() const { return m_tuningProfile; }
void SetTuningProfileParent( NETCLASS* aParent ) { m_tuningProfileParent = aParent; }
NETCLASS* GetTuningProfileParent() const { return m_tuningProfileParent; }
protected:
bool m_isDefault; ///< Mark if this instance is the default netclass
@@ -276,7 +276,7 @@ protected:
COLOR4D m_pcbColor; ///< Optional PCB color override for this netclass
wxString m_DelayProfile; ///< The tuning profile name being used by this netclass
wxString m_tuningProfile; ///< The tuning profile name being used by this netclass
// The NETCLASS providing each parameter
NETCLASS* m_clearanceParent;
@@ -293,7 +293,7 @@ protected:
NETCLASS* m_busWidthParent;
NETCLASS* m_schematicColorParent;
NETCLASS* m_lineStyleParent;
NETCLASS* m_delayProfileParent;
NETCLASS* m_tuningProfileParent;
};
#endif // CLASS_NETCLASS_H
+4 -7
View File
@@ -32,7 +32,7 @@ class BOARD_DESIGN_SETTINGS;
class ERC_SETTINGS;
class NET_SETTINGS;
class COMPONENT_CLASS_SETTINGS;
class TIME_DOMAIN_PARAMETERS;
class TUNING_PROFILES;
class LAYER_PAIR_SETTINGS;
class SCHEMATIC_SETTINGS;
class TEMPLATES;
@@ -144,10 +144,7 @@ public:
return m_ComponentClassSettings;
}
std::shared_ptr<TIME_DOMAIN_PARAMETERS>& TimeDomainParameters()
{
return m_timeDomainParameters;
}
std::shared_ptr<TUNING_PROFILES>& TuningProfileParameters() { return m_tuningProfileParameters; }
/**
* @return true if it should be safe to auto-save this file without user action
@@ -237,9 +234,9 @@ public:
std::shared_ptr<COMPONENT_CLASS_SETTINGS> m_ComponentClassSettings;
/**
* Time domain parameters for this project
* Tuning profile parameters for this project
*/
std::shared_ptr<TIME_DOMAIN_PARAMETERS> m_timeDomainParameters;
std::shared_ptr<TUNING_PROFILES> m_tuningProfileParameters;
std::vector<LAYER_PRESET> m_LayerPresets; /// List of stored layer presets
std::vector<VIEWPORT> m_Viewports; /// List of stored viewports (pos + zoom)
-94
View File
@@ -1,94 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 CERN
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
* @author Jon Evans <jon@craftyjon.com>
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef KICAD_TIME_DOMAIN_PARAMETERS_H
#define KICAD_TIME_DOMAIN_PARAMETERS_H
#include <settings/nested_settings.h>
#include <layer_ids.h>
/**
* Represents a single line in the time domain configuration via overrides configuration grid
*/
struct DELAY_PROFILE_VIA_OVERRIDE_ENTRY
{
PCB_LAYER_ID m_SignalLayerFrom;
PCB_LAYER_ID m_SignalLayerTo;
PCB_LAYER_ID m_ViaLayerFrom;
PCB_LAYER_ID m_ViaLayerTo;
int m_Delay;
bool operator<( const DELAY_PROFILE_VIA_OVERRIDE_ENTRY& other ) const
{
if( m_SignalLayerFrom != other.m_SignalLayerFrom )
return IsCopperLayerLowerThan( m_SignalLayerFrom, other.m_SignalLayerFrom );
if( m_SignalLayerTo != other.m_SignalLayerTo )
return IsCopperLayerLowerThan( m_SignalLayerTo, other.m_SignalLayerTo );
if( m_ViaLayerFrom != other.m_ViaLayerFrom )
return IsCopperLayerLowerThan( m_ViaLayerFrom, other.m_ViaLayerFrom );
if( m_ViaLayerTo != other.m_ViaLayerTo )
return IsCopperLayerLowerThan( m_ViaLayerTo, other.m_ViaLayerTo );
return m_Delay < other.m_Delay;
}
};
/**
* Represents a single line in the time domain configuration net class configuration grid
*/
struct DELAY_PROFILE
{
wxString m_ProfileName;
int m_ViaPropagationDelay;
std::map<PCB_LAYER_ID, int> m_LayerPropagationDelays;
std::vector<DELAY_PROFILE_VIA_OVERRIDE_ENTRY> m_ViaOverrides;
};
/**
* TIME_DOMAIN_PARAMETERS stores the configuration for time-domain tuning
*/
class KICOMMON_API TIME_DOMAIN_PARAMETERS final : public NESTED_SETTINGS
{
public:
TIME_DOMAIN_PARAMETERS( JSON_SETTINGS* aParent, const std::string& aPath );
virtual ~TIME_DOMAIN_PARAMETERS();
bool operator==( const TIME_DOMAIN_PARAMETERS& aOther ) const;
bool operator!=( const TIME_DOMAIN_PARAMETERS& aOther ) const { return !operator==( aOther ); }
void ClearDelayProfiles() { m_delayProfiles.clear(); }
void AddDelayProfile( DELAY_PROFILE&& aTraceEntry ) { m_delayProfiles.emplace_back( std::move( aTraceEntry ) ); }
const std::vector<DELAY_PROFILE>& GetDelayProfiles() const { return m_delayProfiles; }
private:
std::vector<DELAY_PROFILE> m_delayProfiles;
};
#endif // KICAD_NET_SETTINGS_H
+225
View File
@@ -0,0 +1,225 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 CERN
* Copyright The KiCad Developers, see AUTHORS.txt for contributors.
* @author Jon Evans <jon@craftyjon.com>
*
* 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, see <http://www.gnu.org/licenses/>.
*/
#ifndef KICAD_TUNING_PROFILES_H
#define KICAD_TUNING_PROFILES_H
#include <settings/nested_settings.h>
#include <layer_ids.h>
/**
* Represents a single line in the time domain configuration via overrides configuration grid
*/
struct DELAY_PROFILE_VIA_OVERRIDE_ENTRY
{
PCB_LAYER_ID m_SignalLayerFrom;
PCB_LAYER_ID m_SignalLayerTo;
PCB_LAYER_ID m_ViaLayerFrom;
PCB_LAYER_ID m_ViaLayerTo;
int m_Delay;
bool operator<( const DELAY_PROFILE_VIA_OVERRIDE_ENTRY& other ) const
{
if( m_SignalLayerFrom != other.m_SignalLayerFrom )
return IsCopperLayerLowerThan( m_SignalLayerFrom, other.m_SignalLayerFrom );
if( m_SignalLayerTo != other.m_SignalLayerTo )
return IsCopperLayerLowerThan( m_SignalLayerTo, other.m_SignalLayerTo );
if( m_ViaLayerFrom != other.m_ViaLayerFrom )
return IsCopperLayerLowerThan( m_ViaLayerFrom, other.m_ViaLayerFrom );
if( m_ViaLayerTo != other.m_ViaLayerTo )
return IsCopperLayerLowerThan( m_ViaLayerTo, other.m_ViaLayerTo );
return m_Delay < other.m_Delay;
}
bool operator==( const DELAY_PROFILE_VIA_OVERRIDE_ENTRY& other ) const
{
if( m_SignalLayerFrom != other.m_SignalLayerFrom )
return false;
if( m_SignalLayerTo != other.m_SignalLayerTo )
return false;
if( m_ViaLayerFrom != other.m_ViaLayerFrom )
return false;
if( m_ViaLayerTo != other.m_ViaLayerTo )
return false;
if( m_Delay != other.m_Delay )
return false;
return true;
}
};
class TUNING_PROFILES;
/**
* Represents a single line in a time domain profile track propagation setup
*/
class DELAY_PROFILE_TRACK_PROPAGATION_ENTRY
{
public:
friend class TUNING_PROFILES;
void SetSignalLayer( const PCB_LAYER_ID aLayer ) { m_signalLayer = aLayer; }
void SetTopReferenceLayer( const PCB_LAYER_ID aLayer ) { m_topReferenceLayer = aLayer; }
void SetBottomReferenceLayer( const PCB_LAYER_ID aLayer ) { m_bottomReferenceLayer = aLayer; }
void SetWidth( const int aWidth ) { m_width = aWidth; }
void SetDiffPairGap( const int aDiffPairGap ) { m_diffPairGap = aDiffPairGap; }
void SetDelay( const int aDelay ) { m_delay = aDelay; }
void SetEnableTimeDomainTuning( bool aEnable ) { m_enableTimeDomainTuning = aEnable; }
PCB_LAYER_ID GetSignalLayer() const { return m_signalLayer; }
PCB_LAYER_ID GetTopReferenceLayer() const { return m_topReferenceLayer; }
PCB_LAYER_ID GetBottomReferenceLayer() const { return m_bottomReferenceLayer; }
int GetWidth() const { return m_width; }
int GetDiffPairGap() const { return m_diffPairGap; }
int GetDelay() const { return m_enableTimeDomainTuning ? m_delay : 0; }
bool operator==( const DELAY_PROFILE_TRACK_PROPAGATION_ENTRY& other ) const
{
if( m_signalLayer != other.m_signalLayer )
return false;
if( m_topReferenceLayer != other.m_topReferenceLayer )
return false;
if( m_bottomReferenceLayer != other.m_bottomReferenceLayer )
return false;
if( m_width != other.m_width )
return false;
if( m_diffPairGap != other.m_diffPairGap )
return false;
if( m_delay != other.m_delay )
return false;
if( m_enableTimeDomainTuning != other.m_enableTimeDomainTuning )
return false;
return true;
}
private:
PCB_LAYER_ID m_signalLayer{ UNDEFINED_LAYER };
PCB_LAYER_ID m_topReferenceLayer{ UNDEFINED_LAYER };
PCB_LAYER_ID m_bottomReferenceLayer{ UNDEFINED_LAYER };
int m_width{ 0 };
int m_diffPairGap{ 0 };
int m_delay{ 0 };
bool m_enableTimeDomainTuning{ false };
};
/**
* Represents a single line in the tuning profile configuration grid
*/
struct TUNING_PROFILE
{
enum class PROFILE_TYPE
{
SINGLE,
DIFFERENTIAL
};
wxString m_ProfileName;
PROFILE_TYPE m_Type;
double m_TargetImpedance;
bool m_GenerateNetClassDRCRules;
bool m_EnableTimeDomainTuning;
std::vector<DELAY_PROFILE_TRACK_PROPAGATION_ENTRY> m_TrackPropagationEntries;
int m_ViaPropagationDelay;
std::vector<DELAY_PROFILE_VIA_OVERRIDE_ENTRY> m_ViaOverrides;
// This is not persisted - but is used for quick lookup for track statistics calculations
std::map<PCB_LAYER_ID, DELAY_PROFILE_TRACK_PROPAGATION_ENTRY> m_TrackPropagationEntriesMap;
bool operator==( const TUNING_PROFILE& aOther ) const
{
if( m_ProfileName != aOther.m_ProfileName )
return false;
if( m_Type != aOther.m_Type )
return false;
if( m_TargetImpedance != aOther.m_TargetImpedance )
return false;
if( m_GenerateNetClassDRCRules != aOther.m_GenerateNetClassDRCRules )
return false;
if( m_EnableTimeDomainTuning != aOther.m_EnableTimeDomainTuning )
return false;
if( m_TrackPropagationEntries != aOther.m_TrackPropagationEntries )
return false;
if( m_ViaPropagationDelay != aOther.m_ViaPropagationDelay )
return false;
if( m_ViaOverrides != aOther.m_ViaOverrides )
return false;
return true;
}
};
/**
* TUNING_PROFILES stores the configuration for impedance / delay tuning profiles
*/
class KICOMMON_API TUNING_PROFILES final : public NESTED_SETTINGS
{
public:
TUNING_PROFILES( JSON_SETTINGS* aParent, const std::string& aPath );
virtual ~TUNING_PROFILES();
bool operator==( const TUNING_PROFILES& aOther ) const;
bool operator!=( const TUNING_PROFILES& aOther ) const { return !operator==( aOther ); }
void ClearTuningProfiles() { m_tuningProfiles.clear(); }
void AddTuningProfile( TUNING_PROFILE&& aTraceEntry ) { m_tuningProfiles.emplace_back( std::move( aTraceEntry ) ); }
const std::vector<TUNING_PROFILE>& GetTuningProfiles() const { return m_tuningProfiles; }
TUNING_PROFILE& GetTuningProfile( wxString aProfileName );
private:
std::vector<TUNING_PROFILE> m_tuningProfiles;
TUNING_PROFILE m_nullDelayProfile;
};
#endif // KICAD_TUNING_PROFILES_H
+29 -10
View File
@@ -140,26 +140,45 @@ protected:
};
class GRID_CELL_NULLABLE_INTERFACE
{
public:
GRID_CELL_NULLABLE_INTERFACE() :
m_isNullable( true )
{
}
GRID_CELL_NULLABLE_INTERFACE( bool aIsNullable ) :
m_isNullable( aIsNullable )
{
}
virtual ~GRID_CELL_NULLABLE_INTERFACE() = default;
virtual bool IsNullable() const { return m_isNullable; }
protected:
bool m_isNullable{ false };
};
//---- Grid helpers: custom wxGridCellTextEditor ------------------------------------------
//
// Note: This is used to mark WX_GRID cell as nullable
class GRID_CELL_MARK_AS_NULLABLE : public wxGridCellTextEditor
class GRID_CELL_MARK_AS_NULLABLE : public wxGridCellTextEditor, public GRID_CELL_NULLABLE_INTERFACE
{
public:
GRID_CELL_MARK_AS_NULLABLE() : m_isNullable( true ) {}
GRID_CELL_MARK_AS_NULLABLE( bool aIsNullable ) : m_isNullable( aIsNullable ) {}
wxGridCellEditor* Clone() const override
GRID_CELL_MARK_AS_NULLABLE() :
GRID_CELL_NULLABLE_INTERFACE( true )
{
return new GRID_CELL_MARK_AS_NULLABLE( m_isNullable );
}
GRID_CELL_MARK_AS_NULLABLE( const bool aIsNullable ) :
GRID_CELL_NULLABLE_INTERFACE( aIsNullable )
{
}
wxGridCellEditor* Clone() const override { return new GRID_CELL_MARK_AS_NULLABLE( IsNullable() ); }
void Reset() override {}
bool IsNullable() { return m_isNullable; }
protected:
bool m_isNullable;
wxDECLARE_NO_COPY_CLASS( GRID_CELL_MARK_AS_NULLABLE );
};
@@ -25,6 +25,8 @@
#ifndef GRID_TEXT_BUTTON_HELPERS_H
#define GRID_TEXT_BUTTON_HELPERS_H
#include <widgets/grid_icon_text_helpers.h>
#include <memory>
#include <wx/combo.h>
@@ -222,4 +224,39 @@ protected:
};
/**
* A cell editor which runs a provided function when the grid cell button is clicked.
*
* The function has the signature (int, int) -> void. The passed parameters are the (row, col) of the
* clicked grid cell
*/
class GRID_CELL_RUN_FUNCTION_EDITOR : public GRID_CELL_TEXT_BUTTON, public GRID_CELL_NULLABLE_INTERFACE
{
public:
GRID_CELL_RUN_FUNCTION_EDITOR( DIALOG_SHIM* aParent, const std::function<void( int, int )> aFunction,
const bool aIsNullable = false ) :
GRID_CELL_NULLABLE_INTERFACE( aIsNullable ),
m_dlg( aParent ),
m_row( -1 ),
m_col( -1 ),
m_function( aFunction )
{
}
wxGridCellEditor* Clone() const override
{
return new GRID_CELL_RUN_FUNCTION_EDITOR( m_dlg, m_function, IsNullable() );
}
void Create( wxWindow* aParent, wxWindowID aId, wxEvtHandler* aEventHandler ) override;
void BeginEdit( int aRow, int aCol, wxGrid* aGrid ) override;
protected:
DIALOG_SHIM* m_dlg;
int m_row;
int m_col;
std::function<void( int, int )> m_function;
};
#endif // GRID_TEXT_BUTTON_HELPERS_H
+4 -2
View File
@@ -206,8 +206,10 @@ set( PCBNEW_DIALOGS
dialogs/panel_setup_tracks_and_vias_base.cpp
dialogs/panel_setup_tuning_patterns.cpp
dialogs/panel_setup_tuning_patterns_base.cpp
dialogs/panel_setup_time_domain_parameters.cpp
dialogs/panel_setup_time_domain_parameters_base.cpp
dialogs/panel_setup_tuning_profiles_base.cpp
dialogs/panel_setup_tuning_profiles.cpp
dialogs/panel_setup_tuning_profile_info_base.cpp
dialogs/panel_setup_tuning_profile_info.cpp
footprint_wizard.cpp
footprint_wizard_frame.cpp
footprint_wizard_frame_functions.cpp
+2 -2
View File
@@ -2408,9 +2408,9 @@ void BOARD::SynchronizeProperties()
}
void BOARD::SynchronizeTimeDomainProperties()
void BOARD::SynchronizeTuningProfileProperties()
{
m_lengthDelayCalc->SynchronizeTimeDomainProperties();
m_lengthDelayCalc->SynchronizeTuningProfileProperties();
}
+1 -1
View File
@@ -1084,7 +1084,7 @@ public:
/**
* Ensure that all time domain properties providers are in sync with current settings
*/
void SynchronizeTimeDomainProperties();
void SynchronizeTuningProfileProperties();
/**
* Return the Similarity. Because we compare board to board, we just return 1.0 here
+2
View File
@@ -204,6 +204,8 @@ BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std:
m_DRCSeverities[DRCE_MIRRORED_TEXT_ON_FRONT_LAYER] = RPT_SEVERITY_WARNING;
m_DRCSeverities[DRCE_NONMIRRORED_TEXT_ON_BACK_LAYER] = RPT_SEVERITY_WARNING;
m_DRCSeverities[DRCE_MISSING_TUNING_PROFILE] = RPT_SEVERITY_WARNING;
m_MaxError = ARC_HIGH_DEF;
m_ZoneKeepExternalFillets = false;
m_UseHeightForLengthCalcs = true;
+60 -60
View File
@@ -38,7 +38,7 @@
#include <dialogs/panel_setup_tuning_patterns.h>
#include <dialogs/panel_setup_netclasses.h>
#include <dialogs/panel_assign_component_classes.h>
#include <dialogs/panel_setup_time_domain_parameters.h>
#include <dialogs/panel_setup_tuning_profiles.h>
#include <panel_text_variables.h>
#include <project.h>
#include <project/project_file.h>
@@ -50,6 +50,7 @@
#include "dialog_board_setup.h"
#include <advanced_config.h>
#include <dialog_board_setup.h>
#include <footprint.h>
@@ -62,7 +63,7 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame, wxWindow* aParen
m_layers( nullptr ),
m_boardFinish( nullptr ),
m_physicalStackup( nullptr ),
m_timeDomainParameters( nullptr ),
m_tuningProfiles( nullptr ),
m_netClasses( nullptr ),
m_currentPage( 0 ),
m_layersPage( 0 ),
@@ -78,7 +79,7 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame, wxWindow* aParen
m_netclassesPage( 0 ),
m_customRulesPage( 0 ),
m_severitiesPage( 0 ),
m_timeDomainParametersPage( 0 )
m_tuningProfilesPage( 0 )
{
SetEvtHandlerEnabled( false );
@@ -181,6 +182,16 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame, wxWindow* aParen
bds.m_SkewMeanderSettings );
}, _( "Length-tuning Patterns" ) );
m_tuningProfilesPage = m_treebook->GetPageCount();
m_treebook->AddLazySubPage(
[this]( wxWindow* aParent ) -> wxWindow*
{
BOARD* board = m_frame->GetBoard();
return new PANEL_SETUP_TUNING_PROFILES( aParent, m_frame, board,
m_frame->Prj().GetProjectFile().TuningProfileParameters() );
},
_( "Tuning Profiles" ) );
m_netclassesPage = m_treebook->GetPageCount();
m_treebook->AddLazySubPage(
[this]( wxWindow* aParent ) -> wxWindow*
@@ -203,56 +214,46 @@ DIALOG_BOARD_SETUP::DIALOG_BOARD_SETUP( PCB_EDIT_FRAME* aFrame, wxWindow* aParen
},
_( "Component Classes" ) );
m_timeDomainParametersPage = m_treebook->GetPageCount();
m_treebook->AddLazySubPage(
[this]( wxWindow* aParent ) -> wxWindow*
{
BOARD* board = m_frame->GetBoard();
return new PANEL_SETUP_TIME_DOMAIN_PARAMETERS(
aParent, m_frame, board, m_frame->Prj().GetProjectFile().TimeDomainParameters() );
},
_( "Time Domain Parameters" ) );
m_customRulesPage = m_treebook->GetPageCount();
m_treebook->AddLazySubPage(
[this]( wxWindow* aParent ) -> wxWindow*
{
return new PANEL_SETUP_RULES( aParent, m_frame );
},
_( "Custom Rules" ) );
m_customRulesPage = m_treebook->GetPageCount();
m_treebook->AddLazySubPage(
[this]( wxWindow* aParent ) -> wxWindow*
{
return new PANEL_SETUP_RULES( aParent, m_frame );
},
_( "Custom Rules" ) );
m_severitiesPage = m_treebook->GetPageCount();
m_treebook->AddLazySubPage(
[this]( wxWindow* aParent ) -> wxWindow*
{
BOARD* board = m_frame->GetBoard();
return new PANEL_SETUP_SEVERITIES( aParent, DRC_ITEM::GetItemsWithSeverities(),
board->GetDesignSettings().m_DRCSeverities );
},
_( "Violation Severity" ) );
m_severitiesPage = m_treebook->GetPageCount();
m_treebook->AddLazySubPage(
[this]( wxWindow* aParent ) -> wxWindow*
{
BOARD* board = m_frame->GetBoard();
return new PANEL_SETUP_SEVERITIES( aParent, DRC_ITEM::GetItemsWithSeverities(),
board->GetDesignSettings().m_DRCSeverities );
},
_( "Violation Severity" ) );
m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Board Data" ) );
m_embeddedFilesPage = m_treebook->GetPageCount();
m_treebook->AddLazySubPage(
[this]( wxWindow* aParent ) -> wxWindow*
{
return new PANEL_EMBEDDED_FILES( aParent, m_frame->GetBoard(), NO_MARGINS );
},
_( "Embedded Files" ) );
m_treebook->AddPage( new wxPanel( GetTreebook() ), _( "Board Data" ) );
m_embeddedFilesPage = m_treebook->GetPageCount();
m_treebook->AddLazySubPage(
[this]( wxWindow* aParent ) -> wxWindow*
{
return new PANEL_EMBEDDED_FILES( aParent, m_frame->GetBoard(), NO_MARGINS );
},
_( "Embedded Files" ) );
for( size_t i = 0; i < m_treebook->GetPageCount(); ++i )
m_treebook->ExpandNode( i );
for( size_t i = 0; i < m_treebook->GetPageCount(); ++i )
m_treebook->ExpandNode( i );
SetEvtHandlerEnabled( true );
SetEvtHandlerEnabled( true );
finishDialogSettings();
finishDialogSettings();
if( Prj().IsReadOnly() )
{
m_infoBar->ShowMessage( _( "Project is missing or read-only. Some settings will not "
"be editable." ),
wxICON_WARNING );
}
if( Prj().IsReadOnly() )
{
m_infoBar->ShowMessage( _( "Project is missing or read-only. Some settings will not "
"be editable." ),
wxICON_WARNING );
}
wxBookCtrlEvent evt( wxEVT_TREEBOOK_PAGE_CHANGED, wxID_ANY, 0 );
@@ -273,12 +274,12 @@ void DIALOG_BOARD_SETUP::onPageChanged( wxBookCtrlEvent& aEvent )
if( m_physicalStackupPage > 0 ) // Don't run this during initialization
{
if( m_currentPage == m_physicalStackupPage || m_currentPage == m_timeDomainParametersPage
|| page == m_physicalStackupPage || page == m_timeDomainParametersPage || page == m_netclassesPage )
if( m_currentPage == m_physicalStackupPage || page == m_physicalStackupPage || page == m_netclassesPage
|| page == m_tuningProfilesPage )
{
m_layers = RESOLVE_PAGE( PANEL_SETUP_LAYERS, m_layersPage );
m_physicalStackup = RESOLVE_PAGE( PANEL_SETUP_BOARD_STACKUP, m_physicalStackupPage );
m_timeDomainParameters = RESOLVE_PAGE( PANEL_SETUP_TIME_DOMAIN_PARAMETERS, m_timeDomainParametersPage );
m_tuningProfiles = RESOLVE_PAGE( PANEL_SETUP_TUNING_PROFILES, m_tuningProfilesPage );
m_netClasses = RESOLVE_PAGE( PANEL_SETUP_NETCLASSES, m_netclassesPage );
}
@@ -287,21 +288,21 @@ void DIALOG_BOARD_SETUP::onPageChanged( wxBookCtrlEvent& aEvent )
{
m_layers->SyncCopperLayers( m_physicalStackup->GetCopperLayerCount() );
// Avoid calling SyncCopperLayers twice if moving from stackup to time domain directly
m_timeDomainParameters->SyncCopperLayers( m_physicalStackup->GetCopperLayerCount() );
// Avoid calling SyncCopperLayers twice if moving from stackup to tuning profiles directly
m_tuningProfiles->SyncCopperLayers( m_physicalStackup->GetCopperLayerCount() );
}
if( page == m_physicalStackupPage )
{
m_physicalStackup->OnLayersOptionsChanged( m_layers->GetUILayerMask() );
}
else if( page == m_netclassesPage || m_currentPage == m_timeDomainParametersPage )
else if( page == m_netclassesPage || m_currentPage == m_tuningProfilesPage )
{
m_netClasses->UpdateDelayProfileNames( m_timeDomainParameters->GetDelayProfileNames() );
m_netClasses->UpdateDelayProfileNames( m_tuningProfiles->GetDelayProfileNames() );
}
else if( page == m_timeDomainParametersPage )
else if( page == m_tuningProfilesPage )
{
m_timeDomainParameters->SyncCopperLayers( m_physicalStackup->GetCopperLayerCount() );
m_tuningProfiles->SyncCopperLayers( m_physicalStackup->GetCopperLayerCount() );
}
if( Prj().IsReadOnly() )
@@ -475,13 +476,12 @@ void DIALOG_BOARD_SETUP::onAuxiliaryAction( wxCommandEvent& aEvent )
RESOLVE_PAGE( PANEL_SETUP_SEVERITIES,
m_severitiesPage )->ImportSettingsFrom( otherSettings.m_DRCSeverities );
}
if( importDlg.m_TimeDomainParametersOpt->GetValue() )
if( importDlg.m_TuningProfilesOpt->GetValue() )
{
PROJECT_FILE& otherProjectFile = otherPrj->GetProjectFile();
RESOLVE_PAGE( PANEL_SETUP_TIME_DOMAIN_PARAMETERS, m_timeDomainParametersPage )
->ImportSettingsFrom( otherProjectFile.TimeDomainParameters() );
RESOLVE_PAGE( PANEL_SETUP_TUNING_PROFILES, m_tuningProfilesPage )
->ImportSettingsFrom( otherProjectFile.TuningProfileParameters() );
}
if( otherPrj != &m_frame->Prj() )
+3 -3
View File
@@ -29,7 +29,6 @@ class PANEL_SETUP_CONSTRAINTS;
class PANEL_SETUP_LAYERS;
class PANEL_SETUP_TEXT_AND_GRAPHICS;
class PANEL_SETUP_NETCLASSES;
class PANEL_SETUP_TIME_DOMAIN_PARAMETERS;
class PANEL_SETUP_RULES;
class PANEL_SETUP_TRACKS_AND_VIAS;
class PANEL_SETUP_MASK_AND_PASTE;
@@ -37,6 +36,7 @@ class PANEL_SETUP_BOARD_STACKUP;
class PANEL_SETUP_BOARD_FINISH;
class PANEL_SETUP_SEVERITIES;
class PANEL_TEXT_VARIABLES;
class PANEL_SETUP_TUNING_PROFILES;
class DIALOG_BOARD_SETUP : public PAGED_DIALOG
@@ -54,7 +54,7 @@ protected:
PANEL_SETUP_LAYERS* m_layers;
PANEL_SETUP_BOARD_FINISH* m_boardFinish;
PANEL_SETUP_BOARD_STACKUP* m_physicalStackup;
PANEL_SETUP_TIME_DOMAIN_PARAMETERS* m_timeDomainParameters;
PANEL_SETUP_TUNING_PROFILES* m_tuningProfiles;
PANEL_SETUP_NETCLASSES* m_netClasses;
private:
@@ -74,7 +74,7 @@ private:
size_t m_customRulesPage;
size_t m_severitiesPage;
size_t m_embeddedFilesPage;
size_t m_timeDomainParametersPage;
size_t m_tuningProfilesPage;
};
+3 -3
View File
@@ -83,8 +83,8 @@ bool DIALOG_IMPORT_SETTINGS::UpdateImportSettingsButton()
( m_LayersOpt->IsChecked() || m_MaskAndPasteOpt->IsChecked() || m_ConstraintsOpt->IsChecked()
|| m_NetclassesOpt->IsChecked() || m_SeveritiesOpt->IsChecked() || m_TextAndGraphicsOpt->IsChecked()
|| m_FormattingOpt->IsChecked() || m_TracksAndViasOpt->IsChecked() || m_TuningPatternsOpt->IsChecked()
|| m_CustomRulesOpt->IsChecked() || m_ComponentClassesOpt->IsChecked()
|| m_TimeDomainParametersOpt->IsChecked() || m_TeardropsOpt->IsChecked() );
|| m_CustomRulesOpt->IsChecked() || m_ComponentClassesOpt->IsChecked() || m_TuningProfilesOpt->IsChecked()
|| m_TeardropsOpt->IsChecked() );
m_sdbSizer1OK->Enable( buttonEnableState );
@@ -150,7 +150,7 @@ void DIALOG_IMPORT_SETTINGS::OnSelectAll( wxCommandEvent& event )
m_TeardropsOpt->SetValue( m_showSelectAllOnBtn );
m_TuningPatternsOpt->SetValue( m_showSelectAllOnBtn );
m_CustomRulesOpt->SetValue( m_showSelectAllOnBtn );
m_TimeDomainParametersOpt->SetValue( m_showSelectAllOnBtn );
m_TuningProfilesOpt->SetValue( m_showSelectAllOnBtn );
m_ComponentClassesOpt->SetValue( m_showSelectAllOnBtn );
// Ensure "Import Settings" button state is enabled as appropriate
@@ -78,8 +78,8 @@ DIALOG_IMPORT_SETTINGS_BASE::DIALOG_IMPORT_SETTINGS_BASE( wxWindow* parent, wxWi
m_ComponentClassesOpt = new wxCheckBox( this, wxID_ANY, _("Component classes"), wxDefaultPosition, wxDefaultSize, 0 );
bLeftCol->Add( m_ComponentClassesOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 );
m_TimeDomainParametersOpt = new wxCheckBox( this, wxID_ANY, _("Time domain parameters"), wxDefaultPosition, wxDefaultSize, 0 );
bLeftCol->Add( m_TimeDomainParametersOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 );
m_TuningProfilesOpt = new wxCheckBox( this, wxID_ANY, _("Tuning Profiles"), wxDefaultPosition, wxDefaultSize, 0 );
bLeftCol->Add( m_TuningProfilesOpt, 0, wxBOTTOM|wxLEFT|wxRIGHT, 5 );
m_CustomRulesOpt = new wxCheckBox( this, wxID_ANY, _("Custom rules"), wxDefaultPosition, wxDefaultSize, 0 );
bLeftCol->Add( m_CustomRulesOpt, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
@@ -128,7 +128,7 @@ DIALOG_IMPORT_SETTINGS_BASE::DIALOG_IMPORT_SETTINGS_BASE( wxWindow* parent, wxWi
m_TuningPatternsOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_NetclassesOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_ComponentClassesOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_TimeDomainParametersOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_TuningProfilesOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_CustomRulesOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_SeveritiesOpt->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_selectAllButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnSelectAll ), NULL, this );
@@ -147,7 +147,7 @@ DIALOG_IMPORT_SETTINGS_BASE::~DIALOG_IMPORT_SETTINGS_BASE()
m_TuningPatternsOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_NetclassesOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_ComponentClassesOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_TimeDomainParametersOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_TuningProfilesOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_CustomRulesOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_SeveritiesOpt->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnCheckboxClicked ), NULL, this );
m_selectAllButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_IMPORT_SETTINGS_BASE::OnSelectAll ), NULL, this );
@@ -1050,7 +1050,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Time domain parameters</property>
<property name="label">Tuning Profiles</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@@ -1058,7 +1058,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_TimeDomainParametersOpt</property>
<property name="name">m_TuningProfilesOpt</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
+1 -1
View File
@@ -65,7 +65,7 @@ class DIALOG_IMPORT_SETTINGS_BASE : public DIALOG_SHIM
wxCheckBox* m_TuningPatternsOpt;
wxCheckBox* m_NetclassesOpt;
wxCheckBox* m_ComponentClassesOpt;
wxCheckBox* m_TimeDomainParametersOpt;
wxCheckBox* m_TuningProfilesOpt;
wxCheckBox* m_CustomRulesOpt;
wxCheckBox* m_SeveritiesOpt;
@@ -1,661 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* 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 program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <widgets/wx_panel.h>
#include <widgets/std_bitmap_button.h>
#include <bitmaps.h>
#include <dialogs/panel_setup_time_domain_parameters.h>
#include <pcb_edit_frame.h>
#include <grid_tricks.h>
#include <layer_ids.h>
#include <pgm_base.h>
#include <widgets/grid_icon_text_helpers.h>
#include <widgets/paged_dialog.h>
#include <wx/wupdlock.h>
PANEL_SETUP_TIME_DOMAIN_PARAMETERS::PANEL_SETUP_TIME_DOMAIN_PARAMETERS(
wxWindow* aParentWindow, PCB_EDIT_FRAME* aFrame, BOARD* aBoard,
std::shared_ptr<TIME_DOMAIN_PARAMETERS> aTimeDomainParameters ) :
PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE( aParentWindow ),
m_timeDomainParameters( std::move( aTimeDomainParameters ) ),
m_frame( aFrame ),
m_board( aFrame->GetBoard() )
{
m_timeDomainParametersPane->SetBorders( true, false, false, false );
m_viaDelayOverridesPane->SetBorders( true, false, false, false );
// Set up units
m_unitsProvider = std::make_unique<UNITS_PROVIDER>( pcbIUScale, m_frame->GetUserUnits() );
m_tracePropagationGrid->SetUnitsProvider( m_unitsProvider.get() );
m_viaPropagationGrid->SetUnitsProvider( m_unitsProvider.get() );
Freeze();
m_splitter->SetMinimumPaneSize( FromDIP( m_splitter->GetMinimumPaneSize() ) );
// Set up the tuning profiles grid
m_tracePropagationGrid->BeginBatch();
m_tracePropagationGrid->SetUseNativeColLabels();
m_tracePropagationGrid->EnsureColLabelsVisible();
m_tracePropagationGrid->PushEventHandler( new GRID_TRICKS( m_tracePropagationGrid ) );
m_tracePropagationGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
m_addDelayProfileButton->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
m_removeDelayProfileButton->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
m_tracePropagationGrid->EndBatch();
m_tracePropagationGrid->Connect(
wxEVT_GRID_CELL_CHANGING,
wxGridEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS::OnDelayProfileGridCellChanging ), nullptr, this );
// Set up the via override grid
m_viaPropagationGrid->BeginBatch();
m_viaPropagationGrid->SetUseNativeColLabels();
m_viaPropagationGrid->EnsureColLabelsVisible();
m_viaPropagationGrid->PushEventHandler( new GRID_TRICKS( m_viaPropagationGrid ) );
m_viaPropagationGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
std::vector<int> viaColIds;
m_viaPropagationGrid->SetAutoEvalColUnits( VIA_GRID_DELAY,
m_unitsProvider->GetUnitsFromType( EDA_DATA_TYPE::TIME ) );
viaColIds.push_back( VIA_GRID_DELAY );
m_viaPropagationGrid->SetAutoEvalCols( viaColIds );
m_viaPropagationGrid->EndBatch();
m_addViaOverrideButton->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
m_removeViaOverrideButton->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
setColumnWidths();
Thaw();
}
PANEL_SETUP_TIME_DOMAIN_PARAMETERS::~PANEL_SETUP_TIME_DOMAIN_PARAMETERS()
{
// Delete the GRID_TRICKS
m_tracePropagationGrid->PopEventHandler( true );
m_viaPropagationGrid->PopEventHandler( true );
m_tracePropagationGrid->Disconnect(
wxEVT_GRID_CELL_CHANGING,
wxGridEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS::OnDelayProfileGridCellChanging ), nullptr, this );
}
bool PANEL_SETUP_TIME_DOMAIN_PARAMETERS::TransferDataToWindow()
{
m_tracePropagationGrid->ClearRows();
m_viaPropagationGrid->ClearRows();
const std::vector<DELAY_PROFILE>& delayProfiles = m_timeDomainParameters->GetDelayProfiles();
SyncCopperLayers( m_board->GetCopperLayerCount() );
for( const DELAY_PROFILE& profile : delayProfiles )
{
addProfileRow( profile );
for( const DELAY_PROFILE_VIA_OVERRIDE_ENTRY& viaOverride : profile.m_ViaOverrides )
addViaRow( profile.m_ProfileName, viaOverride );
}
updateViaProfileNamesEditor();
return true;
}
bool PANEL_SETUP_TIME_DOMAIN_PARAMETERS::TransferDataFromWindow()
{
if( !Validate() )
return false;
m_timeDomainParameters->ClearDelayProfiles();
for( int i = 0; i < m_tracePropagationGrid->GetNumberRows(); ++i )
{
DELAY_PROFILE profile = getProfileRow( i );
wxString profileName = profile.m_ProfileName;
for( int j = 0; j < m_viaPropagationGrid->GetNumberRows(); ++j )
{
if( m_viaPropagationGrid->GetCellValue( j, VIA_GRID_PROFILE_NAME ) == profileName )
profile.m_ViaOverrides.emplace_back( getViaRow( j ) );
}
m_timeDomainParameters->AddDelayProfile( std::move( profile ) );
}
return true;
}
void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::addProfileRow( const DELAY_PROFILE& aDelayProfile )
{
const int rowId = m_tracePropagationGrid->GetNumberRows();
m_tracePropagationGrid->AppendRows();
m_tracePropagationGrid->SetCellValue( rowId, PROFILE_GRID_PROFILE_NAME, aDelayProfile.m_ProfileName );
m_tracePropagationGrid->SetUnitValue( rowId, PROFILE_GRID_VIA_PROP_DELAY, aDelayProfile.m_ViaPropagationDelay );
for( const auto& [layerId, velocity] : aDelayProfile.m_LayerPropagationDelays )
{
if( !m_copperLayerIdsToColumns.contains( layerId ) )
continue;
int col = m_copperLayerIdsToColumns[layerId];
if( col < m_tracePropagationGrid->GetNumberCols() )
m_tracePropagationGrid->SetUnitValue( rowId, col, velocity );
}
}
DELAY_PROFILE PANEL_SETUP_TIME_DOMAIN_PARAMETERS::getProfileRow( const int aRow )
{
DELAY_PROFILE entry;
entry.m_ProfileName = getProfileNameForProfileGridRow( aRow );
entry.m_ViaPropagationDelay = m_tracePropagationGrid->GetUnitValue( aRow, PROFILE_GRID_VIA_PROP_DELAY );
std::map<PCB_LAYER_ID, int> propDelays;
for( const auto& [layer, col] : m_copperLayerIdsToColumns )
propDelays[layer] = m_tracePropagationGrid->GetUnitValue( aRow, col );
entry.m_LayerPropagationDelays = std::move( propDelays );
return entry;
}
void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::addViaRow( const wxString& aProfileName,
const DELAY_PROFILE_VIA_OVERRIDE_ENTRY& aViaOverrideEntry ) const
{
const int rowId = m_viaPropagationGrid->GetNumberRows();
m_viaPropagationGrid->AppendRows();
m_viaPropagationGrid->SetCellValue( rowId, VIA_GRID_PROFILE_NAME, aProfileName );
m_viaPropagationGrid->SetCellValue( rowId, VIA_GRID_SIGNAL_LAYER_FROM,
m_board->GetLayerName( aViaOverrideEntry.m_SignalLayerFrom ) );
m_viaPropagationGrid->SetCellValue( rowId, VIA_GRID_SIGNAL_LAYER_TO,
m_board->GetLayerName( aViaOverrideEntry.m_SignalLayerTo ) );
m_viaPropagationGrid->SetCellValue( rowId, VIA_GRID_VIA_LAYER_FROM,
m_board->GetLayerName( aViaOverrideEntry.m_ViaLayerFrom ) );
m_viaPropagationGrid->SetCellValue( rowId, VIA_GRID_VIA_LAYER_TO,
m_board->GetLayerName( aViaOverrideEntry.m_ViaLayerTo ) );
m_viaPropagationGrid->SetUnitValue( rowId, VIA_GRID_DELAY, aViaOverrideEntry.m_Delay );
}
DELAY_PROFILE_VIA_OVERRIDE_ENTRY PANEL_SETUP_TIME_DOMAIN_PARAMETERS::getViaRow( const int aRow )
{
// Get layer info
const wxString signalLayerFrom = m_viaPropagationGrid->GetCellValue( aRow, VIA_GRID_SIGNAL_LAYER_FROM );
const wxString signalLayerTo = m_viaPropagationGrid->GetCellValue( aRow, VIA_GRID_SIGNAL_LAYER_TO );
const wxString viaLayerFrom = m_viaPropagationGrid->GetCellValue( aRow, VIA_GRID_VIA_LAYER_FROM );
const wxString viaLayerTo = m_viaPropagationGrid->GetCellValue( aRow, VIA_GRID_VIA_LAYER_TO );
PCB_LAYER_ID signalLayerIdFrom = m_layerNamesToIDs[signalLayerFrom];
PCB_LAYER_ID signalLayerIdTo = m_layerNamesToIDs[signalLayerTo];
PCB_LAYER_ID viaLayerIdFrom = m_layerNamesToIDs[viaLayerFrom];
PCB_LAYER_ID viaLayerIdTo = m_layerNamesToIDs[viaLayerTo];
// Order layers in stackup order (from F_Cu first)
if( IsCopperLayerLowerThan( signalLayerIdFrom, signalLayerIdTo ) )
std::swap( signalLayerIdFrom, signalLayerIdTo );
if( IsCopperLayerLowerThan( viaLayerIdFrom, viaLayerIdTo ) )
std::swap( viaLayerIdFrom, viaLayerIdTo );
const DELAY_PROFILE_VIA_OVERRIDE_ENTRY entry{ signalLayerIdFrom, signalLayerIdTo, viaLayerIdFrom, viaLayerIdTo,
m_viaPropagationGrid->GetUnitValue( aRow, VIA_GRID_DELAY ) };
return entry;
}
void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::SyncCopperLayers( int aNumCopperLayers )
{
m_prevLayerNamesToIDs = m_layerNamesToIDs;
m_copperLayerIdsToColumns.clear();
m_copperColumnsToLayerId.clear();
m_layerNames.clear();
m_layerNamesToIDs.clear();
int colIdx = PROFILE_GRID_NUM_REQUIRED_COLS;
for( const auto& layer : LSET::AllCuMask( aNumCopperLayers ).CuStack() )
{
wxString layerName = m_board->GetLayerName( layer );
m_layerNames.emplace_back( layerName );
m_layerNamesToIDs[layerName] = layer;
m_copperLayerIdsToColumns[layer] = colIdx;
m_copperColumnsToLayerId[colIdx] = layer;
++colIdx;
}
updateProfileGridColumns();
updateViaGridColumns();
setColumnWidths();
}
void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::setColumnWidths()
{
const int minValueWidth = m_tracePropagationGrid->GetTextExtent( wxT( "000.00 ps/mm" ) ).x;
const int minNameWidth = m_tracePropagationGrid->GetTextExtent( wxT( "MMMMMMMMMMMM" ) ).x;
for( int i = 0; i < m_tracePropagationGrid->GetNumberCols(); ++i )
{
const int titleSize = m_tracePropagationGrid->GetTextExtent( m_tracePropagationGrid->GetColLabelValue( i ) ).x;
if( i == PROFILE_GRID_PROFILE_NAME )
m_tracePropagationGrid->SetColSize( i, std::max( titleSize, minNameWidth ) );
else
m_tracePropagationGrid->SetColSize( i, std::max( titleSize, minValueWidth ) );
}
for( int i = 0; i < m_viaPropagationGrid->GetNumberCols(); ++i )
{
const int titleSize = GetTextExtent( m_viaPropagationGrid->GetColLabelValue( i ) ).x;
if( i == VIA_GRID_PROFILE_NAME )
m_viaPropagationGrid->SetColSize( i, std::max( titleSize, minNameWidth ) );
else
m_viaPropagationGrid->SetColSize( i, titleSize + 30 );
}
}
void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::updateProfileGridColumns()
{
const int newCopperLayers = static_cast<int>( m_copperLayerIdsToColumns.size() );
const int curCopperLayers = m_tracePropagationGrid->GetNumberCols() - PROFILE_GRID_NUM_REQUIRED_COLS;
if( newCopperLayers < curCopperLayers )
{
// TODO: WARN OF DELETING DATA?
m_tracePropagationGrid->DeleteCols( curCopperLayers - newCopperLayers + PROFILE_GRID_NUM_REQUIRED_COLS,
curCopperLayers - newCopperLayers );
}
else if( newCopperLayers > curCopperLayers )
{
m_tracePropagationGrid->AppendCols( newCopperLayers - curCopperLayers );
}
std::vector<int> copperColIds;
m_tracePropagationGrid->SetAutoEvalColUnits( PROFILE_GRID_VIA_PROP_DELAY,
m_unitsProvider->GetUnitsFromType( EDA_DATA_TYPE::LENGTH_DELAY ) );
copperColIds.push_back( PROFILE_GRID_VIA_PROP_DELAY );
for( const auto& [colIdx, layerId] : m_copperColumnsToLayerId )
{
m_tracePropagationGrid->SetColLabelValue( colIdx, m_board->GetLayerName( layerId ) );
m_tracePropagationGrid->SetAutoEvalColUnits( colIdx,
m_unitsProvider->GetUnitsFromType( EDA_DATA_TYPE::LENGTH_DELAY ) );
copperColIds.push_back( colIdx );
}
m_tracePropagationGrid->SetAutoEvalCols( copperColIds );
m_tracePropagationGrid->EnsureColLabelsVisible();
m_tracePropagationGrid->Refresh();
}
void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::updateViaGridColumns()
{
wxArrayString layerNames;
std::ranges::for_each( m_layerNames,
[&layerNames]( const wxString& aLayerName )
{
layerNames.push_back( aLayerName );
} );
// Save the current data
std::vector<wxString> currentSignalLayersFrom;
std::vector<wxString> currentSignalLayersTo;
std::vector<wxString> currentViaLayersFrom;
std::vector<wxString> currentViaLayersTo;
for( int row = 0; row < m_viaPropagationGrid->GetNumberRows(); ++row )
{
currentSignalLayersFrom.emplace_back( m_viaPropagationGrid->GetCellValue( row, VIA_GRID_SIGNAL_LAYER_FROM ) );
currentSignalLayersTo.emplace_back( m_viaPropagationGrid->GetCellValue( row, VIA_GRID_SIGNAL_LAYER_TO ) );
currentViaLayersFrom.emplace_back( m_viaPropagationGrid->GetCellValue( row, VIA_GRID_VIA_LAYER_FROM ) );
currentViaLayersTo.emplace_back( m_viaPropagationGrid->GetCellValue( row, VIA_GRID_VIA_LAYER_TO ) );
}
// Reset the via layers lists
wxGridCellAttr* attr = new wxGridCellAttr;
attr->SetEditor( new wxGridCellChoiceEditor( layerNames, false ) );
m_viaPropagationGrid->SetColAttr( VIA_GRID_SIGNAL_LAYER_FROM, attr );
attr = new wxGridCellAttr;
attr->SetEditor( new wxGridCellChoiceEditor( layerNames, false ) );
m_viaPropagationGrid->SetColAttr( VIA_GRID_SIGNAL_LAYER_TO, attr );
attr = new wxGridCellAttr;
attr->SetEditor( new wxGridCellChoiceEditor( layerNames, false ) );
m_viaPropagationGrid->SetColAttr( VIA_GRID_VIA_LAYER_FROM, attr );
attr = new wxGridCellAttr;
attr->SetEditor( new wxGridCellChoiceEditor( layerNames, false ) );
m_viaPropagationGrid->SetColAttr( VIA_GRID_VIA_LAYER_TO, attr );
// Restore the data, changing or resetting layer names if required
for( int row = 0; row < m_viaPropagationGrid->GetNumberRows(); ++row )
{
const PCB_LAYER_ID lastSignalFromId = m_prevLayerNamesToIDs[currentSignalLayersFrom[row]];
if( m_copperLayerIdsToColumns.contains( lastSignalFromId ) )
m_viaPropagationGrid->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_FROM,
m_board->GetLayerName( lastSignalFromId ) );
else
m_viaPropagationGrid->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_FROM, m_layerNames.front() );
const PCB_LAYER_ID lastSignalToId = m_prevLayerNamesToIDs[currentSignalLayersTo[row]];
if( m_copperLayerIdsToColumns.contains( lastSignalToId ) )
m_viaPropagationGrid->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_TO,
m_board->GetLayerName( lastSignalToId ) );
else
m_viaPropagationGrid->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_TO, m_layerNames.back() );
const PCB_LAYER_ID lastViaFromId = m_prevLayerNamesToIDs[currentViaLayersFrom[row]];
if( m_copperLayerIdsToColumns.contains( lastViaFromId ) )
m_viaPropagationGrid->SetCellValue( row, VIA_GRID_VIA_LAYER_FROM, m_board->GetLayerName( lastViaFromId ) );
else
m_viaPropagationGrid->SetCellValue( row, VIA_GRID_VIA_LAYER_FROM, m_layerNames.front() );
const PCB_LAYER_ID lastViaToId = m_prevLayerNamesToIDs[currentViaLayersTo[row]];
if( m_copperLayerIdsToColumns.contains( lastViaToId ) )
m_viaPropagationGrid->SetCellValue( row, VIA_GRID_VIA_LAYER_TO, m_board->GetLayerName( lastViaToId ) );
else
m_viaPropagationGrid->SetCellValue( row, VIA_GRID_VIA_LAYER_TO, m_layerNames.back() );
}
}
void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::OnAddDelayProfileClick( wxCommandEvent& event )
{
m_tracePropagationGrid->OnAddRow(
[&]() -> std::pair<int, int>
{
const int row = m_tracePropagationGrid->GetNumberRows();
m_tracePropagationGrid->AppendRows();
m_tracePropagationGrid->SetCellValue( row, PROFILE_GRID_PROFILE_NAME, "" );
for( int i = PROFILE_GRID_VIA_PROP_DELAY; i < m_tracePropagationGrid->GetNumberCols(); ++i )
m_tracePropagationGrid->SetUnitValue( row, i, 0 );
return { row, PROFILE_GRID_PROFILE_NAME };
} );
}
void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::OnRemoveDelayProfileClick( wxCommandEvent& event )
{
m_tracePropagationGrid->OnDeleteRows(
[&]( int row )
{
wxString profileName = getProfileNameForProfileGridRow( row );
// Delete associated via overrides
for( int viaRow = m_viaPropagationGrid->GetNumberRows() - 1; viaRow >= 0; --viaRow )
{
if( m_viaPropagationGrid->GetCellValue( viaRow, VIA_GRID_PROFILE_NAME ) == profileName )
m_viaPropagationGrid->DeleteRows( viaRow, 1 );
}
// Delete tuning profile
m_tracePropagationGrid->DeleteRows( row, 1 );
updateViaProfileNamesEditor();
} );
}
void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::OnAddViaOverrideClick( wxCommandEvent& event )
{
m_viaPropagationGrid->OnAddRow(
[&]() -> std::pair<int, int>
{
const int row = m_viaPropagationGrid->GetNumberRows();
// Check we have delay profiles to override
if( m_tracePropagationGrid->GetNumberRows() == 0 )
{
PAGED_DIALOG::GetDialog( this )->SetError( _( "No delay profiles to override" ), this, nullptr );
return { row, -1 };
}
m_viaPropagationGrid->AppendRows();
m_viaPropagationGrid->SetCellValue( row, VIA_GRID_PROFILE_NAME, getProfileNameForProfileGridRow( 0 ) );
m_viaPropagationGrid->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_FROM, m_layerNames.front() );
m_viaPropagationGrid->SetCellValue( row, VIA_GRID_SIGNAL_LAYER_TO, m_layerNames.back() );
m_viaPropagationGrid->SetCellValue( row, VIA_GRID_VIA_LAYER_FROM, m_layerNames.front() );
m_viaPropagationGrid->SetCellValue( row, VIA_GRID_VIA_LAYER_TO, m_layerNames.back() );
m_viaPropagationGrid->SetUnitValue( row, VIA_GRID_DELAY, 0 );
return { row, VIA_GRID_DELAY };
} );
}
void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::OnRemoveViaOverrideClick( wxCommandEvent& event )
{
m_viaPropagationGrid->OnDeleteRows(
[&]( int row )
{
m_viaPropagationGrid->DeleteRows( row, 1 );
} );
}
void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::OnDelayProfileGridCellChanging( wxGridEvent& event )
{
if( event.GetCol() == PROFILE_GRID_PROFILE_NAME )
{
if( validateDelayProfileName( event.GetRow(), event.GetString() ) )
{
const wxString oldName = getProfileNameForProfileGridRow( event.GetRow() );
wxString newName = event.GetString();
newName.Trim( true ).Trim( false );
if( !oldName.IsEmpty() )
{
wxWindowUpdateLocker updateLocker( m_viaPropagationGrid );
updateViaProfileNamesEditor( oldName, newName );
// Update changed profile names
for( int row = 0; row < m_viaPropagationGrid->GetNumberRows(); ++row )
{
if( m_viaPropagationGrid->GetCellValue( row, VIA_GRID_PROFILE_NAME ) == oldName )
m_viaPropagationGrid->SetCellValue( row, VIA_GRID_PROFILE_NAME, newName );
}
}
else
{
updateViaProfileNamesEditor( oldName, newName );
}
}
else
{
event.Veto();
}
}
}
void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::updateViaProfileNamesEditor( const wxString& aOldName,
const wxString& aNewName ) const
{
wxArrayString profileNames;
for( int i = 0; i < m_tracePropagationGrid->GetNumberRows(); ++i )
{
wxString profileName = getProfileNameForProfileGridRow( i );
if( profileName == aOldName )
profileName = aNewName;
profileNames.push_back( profileName );
}
std::ranges::sort( profileNames,
[]( const wxString& a, const wxString& b )
{
return a.CmpNoCase( b ) < 0;
} );
wxGridCellAttr* attr = new wxGridCellAttr;
attr->SetEditor( new wxGridCellChoiceEditor( profileNames, false ) );
m_viaPropagationGrid->SetColAttr( VIA_GRID_PROFILE_NAME, attr );
}
bool PANEL_SETUP_TIME_DOMAIN_PARAMETERS::validateDelayProfileName( int aRow, const wxString& aName, bool focusFirst )
{
wxString tmp = aName;
tmp.Trim( true );
tmp.Trim( false );
if( tmp.IsEmpty() )
{
const wxString msg = _( "Tuning profile must have a name" );
PAGED_DIALOG::GetDialog( this )->SetError( msg, this, m_tracePropagationGrid, aRow, PROFILE_GRID_PROFILE_NAME );
return false;
}
for( int ii = 0; ii < m_tracePropagationGrid->GetNumberRows(); ii++ )
{
if( ii != aRow && getProfileNameForProfileGridRow( ii ).CmpNoCase( tmp ) == 0 )
{
const wxString msg = _( "Tuning profile name already in use" );
PAGED_DIALOG::GetDialog( this )->SetError( msg, this, m_tracePropagationGrid, focusFirst ? aRow : ii,
PROFILE_GRID_PROFILE_NAME );
return false;
}
}
return true;
}
bool PANEL_SETUP_TIME_DOMAIN_PARAMETERS::Validate()
{
if( !m_tracePropagationGrid->CommitPendingChanges() || !m_viaPropagationGrid->CommitPendingChanges() )
return false;
// Test delay profile parameters
for( int row = 0; row < m_tracePropagationGrid->GetNumberRows(); row++ )
{
const wxString profileName = getProfileNameForProfileGridRow( row );
if( !validateDelayProfileName( row, profileName, false ) )
return false;
}
// Test via override parameters
if( !validateViaRows() )
return false;
return true;
}
bool PANEL_SETUP_TIME_DOMAIN_PARAMETERS::validateViaRows()
{
std::map<wxString, std::set<DELAY_PROFILE_VIA_OVERRIDE_ENTRY>> rowCache;
for( int row = 0; row < m_viaPropagationGrid->GetNumberRows(); row++ )
{
DELAY_PROFILE_VIA_OVERRIDE_ENTRY entry = getViaRow( row );
const wxString profileName = m_viaPropagationGrid->GetCellValue( row, VIA_GRID_PROFILE_NAME );
std::set<DELAY_PROFILE_VIA_OVERRIDE_ENTRY>& viaOverrides = rowCache[profileName];
if( viaOverrides.contains( entry ) )
{
const wxString msg = _( "Via override configuration is duplicated" );
PAGED_DIALOG::GetDialog( this )->SetError( msg, this, m_viaPropagationGrid, row, VIA_GRID_PROFILE_NAME );
return false;
}
else
{
viaOverrides.insert( entry );
}
}
return true;
}
std::vector<wxString> PANEL_SETUP_TIME_DOMAIN_PARAMETERS::GetDelayProfileNames() const
{
std::vector<wxString> profileNames;
for( int i = 0; i < m_tracePropagationGrid->GetNumberRows(); i++ )
{
const wxString profileName = getProfileNameForProfileGridRow( i );
profileNames.emplace_back( profileName );
}
std::ranges::sort( profileNames,
[]( const wxString& a, const wxString& b )
{
return a.CmpNoCase( b ) < 0;
} );
return profileNames;
}
void PANEL_SETUP_TIME_DOMAIN_PARAMETERS::ImportSettingsFrom(
const std::shared_ptr<TIME_DOMAIN_PARAMETERS>& aOtherParameters )
{
std::shared_ptr<TIME_DOMAIN_PARAMETERS> savedParameters = m_timeDomainParameters;
m_timeDomainParameters = aOtherParameters;
TransferDataToWindow();
updateViaProfileNamesEditor();
m_viaPropagationGrid->ForceRefresh();
m_timeDomainParameters = std::move( savedParameters );
}
wxString PANEL_SETUP_TIME_DOMAIN_PARAMETERS::getProfileNameForProfileGridRow( const int aRow ) const
{
wxString profileName = m_tracePropagationGrid->GetCellValue( aRow, PROFILE_GRID_PROFILE_NAME );
profileName.Trim( true ).Trim( false );
return profileName;
}
@@ -1,156 +0,0 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* 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 program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef PANEL_SETUP_TIME_DOMAIN_PARAMETERS_H
#define PANEL_SETUP_TIME_DOMAIN_PARAMETERS_H
#include <utility>
#include <board.h>
#include <dialogs/panel_setup_time_domain_parameters_base.h>
#include <project/time_domain_parameters.h>
class NET_SETTINGS;
class PANEL_SETUP_TIME_DOMAIN_PARAMETERS : public PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE
{
public:
PANEL_SETUP_TIME_DOMAIN_PARAMETERS(
wxWindow* aParentWindow, PCB_EDIT_FRAME* aFrame, BOARD* aBoard,
std::shared_ptr<TIME_DOMAIN_PARAMETERS> aTimeDomainParameters );
~PANEL_SETUP_TIME_DOMAIN_PARAMETERS() override;
/**
* Called when switching to this tab to make sure that any changes to the copper layer count
* made on the physical stackup page are reflected here
* @param aNumCopperLayers is the number of copper layers in the board
*/
void SyncCopperLayers( int aNumCopperLayers );
/// Load parameter data from the settings object
bool TransferDataToWindow() override;
/// Save parameter data to the settings object
bool TransferDataFromWindow() override;
/// Returns all configured tuning profile names. Used by the netclass setup panel
std::vector<wxString> GetDelayProfileNames() const;
/// Load configuration from the given settings object
void ImportSettingsFrom( const std::shared_ptr<TIME_DOMAIN_PARAMETERS>& aOtherParameters );
private:
enum PROFILE_GRID_REQUIRED_COLS
{
PROFILE_GRID_PROFILE_NAME = 0,
PROFILE_GRID_VIA_PROP_DELAY,
PROFILE_GRID_NUM_REQUIRED_COLS
};
enum VIA_GRID_REQUIRED_COLS
{
VIA_GRID_PROFILE_NAME = 0,
VIA_GRID_SIGNAL_LAYER_FROM,
VIA_GRID_SIGNAL_LAYER_TO,
VIA_GRID_VIA_LAYER_FROM,
VIA_GRID_VIA_LAYER_TO,
VIA_GRID_DELAY
};
/// Optimise grid columns to fit titles and content
void setColumnWidths();
/// Updates the via override tuning profile name dropdown lists
/// Updates entries if aOldName and aNewName are passed
void updateViaProfileNamesEditor( const wxString& aOldName = wxEmptyString,
const wxString& aNewName = wxEmptyString ) const;
/// Update the dynamic (per-layer) columns in the tuning profiles grid
void updateProfileGridColumns();
/// Update the dynamic (per-layer) columns in the via overrides grid
void updateViaGridColumns();
/// Adds a new tuning profile entry to the tuning profile grid
void OnAddDelayProfileClick( wxCommandEvent& event ) override;
/// Removes a tuning profile entry from the tuning profile grid
void OnRemoveDelayProfileClick( wxCommandEvent& event ) override;
/// Adds a new via override profile entry to the via overrides grid
void OnAddViaOverrideClick( wxCommandEvent& event ) override;
/// Removes a via override profile entry from the via overrides grid
void OnRemoveViaOverrideClick( wxCommandEvent& event ) override;
/// Validates a tuning profile row data
void OnDelayProfileGridCellChanging( wxGridEvent& event );
/// Validates a tuning profile name (checks for not empty and not duplicated)
bool validateDelayProfileName( int aRow, const wxString& aName, bool focusFirst = true );
/// Validates all data
bool Validate() override;
/// Validates all via override rows
bool validateViaRows();
/// Adds a tuning profile row with the given persisted parameters
void addProfileRow( const DELAY_PROFILE& aDelayProfile );
/// Gets a tuning profile row as a set of persistable parameters
DELAY_PROFILE getProfileRow( int aRow );
/// Adds a via override row with the given persisted parameters
void addViaRow( const wxString& aProfileName, const DELAY_PROFILE_VIA_OVERRIDE_ENTRY& aViaOverrideEntry ) const;
/// Gets a via override row as a set of persistable parameters
DELAY_PROFILE_VIA_OVERRIDE_ENTRY getViaRow( int aRow );
/// Gets the profile name for the given profile grid row
wxString getProfileNameForProfileGridRow( int aRow ) const;
/// The parameters object to load / save data from / to
std::shared_ptr<TIME_DOMAIN_PARAMETERS> m_timeDomainParameters;
/// The active edit frame
PCB_EDIT_FRAME* m_frame;
/// The current board
BOARD* m_board;
std::unique_ptr<UNITS_PROVIDER> m_unitsProvider;
// Layer / column lookups
std::map<PCB_LAYER_ID, int> m_copperLayerIdsToColumns;
std::map<int, PCB_LAYER_ID> m_copperColumnsToLayerId;
std::vector<wxString> m_layerNames;
// We cache these in case the names change on the layers panel
std::map<wxString, PCB_LAYER_ID> m_layerNamesToIDs;
std::map<wxString, PCB_LAYER_ID> m_prevLayerNamesToIDs;
};
#endif // PANEL_SETUP_TIME_DOMAIN_PARAMETERS_H
@@ -1,185 +0,0 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "widgets/std_bitmap_button.h"
#include "widgets/wx_grid.h"
#include "widgets/wx_panel.h"
#include "panel_setup_time_domain_parameters_base.h"
///////////////////////////////////////////////////////////////////////////
PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name )
{
wxBoxSizer* bpanelTomeDomainSizer;
bpanelTomeDomainSizer = new wxBoxSizer( wxVERTICAL );
wxBoxSizer* bMargins;
bMargins = new wxBoxSizer( wxVERTICAL );
m_splitter = new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH|wxSP_LIVE_UPDATE|wxSP_NO_XP_THEME );
m_splitter->SetMinimumPaneSize( 160 );
m_timeDomainParametersPane = new WX_PANEL( m_splitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bUpperSizer;
bUpperSizer = new wxBoxSizer( wxVERTICAL );
m_staticText3 = new wxStaticText( m_timeDomainParametersPane, wxID_ANY, _("Delay Profiles"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText3->Wrap( -1 );
bUpperSizer->Add( m_staticText3, 0, wxTOP|wxLEFT|wxEXPAND, 8 );
bUpperSizer->Add( 0, 3, 0, wxEXPAND, 5 );
m_tracePropagationGrid = new WX_GRID( m_timeDomainParametersPane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL );
// Grid
m_tracePropagationGrid->CreateGrid( 0, 2 );
m_tracePropagationGrid->EnableEditing( true );
m_tracePropagationGrid->EnableGridLines( true );
m_tracePropagationGrid->EnableDragGridSize( false );
m_tracePropagationGrid->SetMargins( 0, 0 );
// Columns
m_tracePropagationGrid->EnableDragColMove( false );
m_tracePropagationGrid->EnableDragColSize( true );
m_tracePropagationGrid->SetColLabelValue( 0, _("Profile Name") );
m_tracePropagationGrid->SetColLabelValue( 1, _("Vias") );
m_tracePropagationGrid->SetColLabelSize( wxGRID_AUTOSIZE );
m_tracePropagationGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Rows
m_tracePropagationGrid->EnableDragRowSize( true );
m_tracePropagationGrid->SetRowLabelSize( 0 );
m_tracePropagationGrid->SetRowLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTER );
// Label Appearance
// Cell Defaults
m_tracePropagationGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_CENTER );
bUpperSizer->Add( m_tracePropagationGrid, 1, wxEXPAND|wxFIXED_MINSIZE|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* buttonBoxSizer;
buttonBoxSizer = new wxBoxSizer( wxHORIZONTAL );
m_addDelayProfileButton = new STD_BITMAP_BUTTON( m_timeDomainParametersPane, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 );
buttonBoxSizer->Add( m_addDelayProfileButton, 0, wxBOTTOM|wxLEFT, 5 );
buttonBoxSizer->Add( 20, 0, 0, wxEXPAND, 5 );
m_removeDelayProfileButton = new STD_BITMAP_BUTTON( m_timeDomainParametersPane, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 );
buttonBoxSizer->Add( m_removeDelayProfileButton, 0, wxBOTTOM|wxLEFT, 5 );
buttonBoxSizer->Add( 20, 0, 0, wxEXPAND, 5 );
bUpperSizer->Add( buttonBoxSizer, 0, wxEXPAND|wxTOP, 3 );
m_timeDomainParametersPane->SetSizer( bUpperSizer );
m_timeDomainParametersPane->Layout();
bUpperSizer->Fit( m_timeDomainParametersPane );
m_viaDelayOverridesPane = new WX_PANEL( m_splitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bUpperSizer1;
bUpperSizer1 = new wxBoxSizer( wxVERTICAL );
m_staticText31 = new wxStaticText( m_viaDelayOverridesPane, wxID_ANY, _("Via Delay Overrides"), wxDefaultPosition, wxDefaultSize, 0 );
m_staticText31->Wrap( -1 );
bUpperSizer1->Add( m_staticText31, 0, wxTOP|wxLEFT|wxEXPAND, 8 );
bUpperSizer1->Add( 0, 3, 0, wxEXPAND, 5 );
m_viaPropagationGrid = new WX_GRID( m_viaDelayOverridesPane, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL );
// Grid
m_viaPropagationGrid->CreateGrid( 0, 6 );
m_viaPropagationGrid->EnableEditing( true );
m_viaPropagationGrid->EnableGridLines( true );
m_viaPropagationGrid->EnableDragGridSize( false );
m_viaPropagationGrid->SetMargins( 0, 0 );
// Columns
m_viaPropagationGrid->EnableDragColMove( false );
m_viaPropagationGrid->EnableDragColSize( true );
m_viaPropagationGrid->SetColLabelValue( 0, _("Profile Name") );
m_viaPropagationGrid->SetColLabelValue( 1, _("Signal Layer From") );
m_viaPropagationGrid->SetColLabelValue( 2, _("Signal Layer To") );
m_viaPropagationGrid->SetColLabelValue( 3, _("Via Layer From") );
m_viaPropagationGrid->SetColLabelValue( 4, _("Via Layer To") );
m_viaPropagationGrid->SetColLabelValue( 5, _("Delay") );
m_viaPropagationGrid->SetColLabelSize( wxGRID_AUTOSIZE );
m_viaPropagationGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Rows
m_viaPropagationGrid->EnableDragRowSize( true );
m_viaPropagationGrid->SetRowLabelSize( 0 );
m_viaPropagationGrid->SetRowLabelAlignment( wxALIGN_LEFT, wxALIGN_CENTER );
// Label Appearance
// Cell Defaults
m_viaPropagationGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_CENTER );
bUpperSizer1->Add( m_viaPropagationGrid, 1, wxEXPAND|wxFIXED_MINSIZE|wxRIGHT|wxLEFT, 5 );
wxBoxSizer* buttonBoxSizer1;
buttonBoxSizer1 = new wxBoxSizer( wxHORIZONTAL );
m_addViaOverrideButton = new STD_BITMAP_BUTTON( m_viaDelayOverridesPane, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 );
buttonBoxSizer1->Add( m_addViaOverrideButton, 0, wxBOTTOM|wxLEFT, 5 );
buttonBoxSizer1->Add( 20, 0, 0, wxEXPAND, 5 );
m_removeViaOverrideButton = new STD_BITMAP_BUTTON( m_viaDelayOverridesPane, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize( -1,-1 ), wxBU_AUTODRAW|0 );
buttonBoxSizer1->Add( m_removeViaOverrideButton, 0, wxBOTTOM|wxLEFT, 5 );
buttonBoxSizer1->Add( 20, 0, 0, wxEXPAND, 5 );
bUpperSizer1->Add( buttonBoxSizer1, 0, wxEXPAND|wxTOP, 3 );
m_viaDelayOverridesPane->SetSizer( bUpperSizer1 );
m_viaDelayOverridesPane->Layout();
bUpperSizer1->Fit( m_viaDelayOverridesPane );
m_splitter->SplitHorizontally( m_timeDomainParametersPane, m_viaDelayOverridesPane, -1 );
bMargins->Add( m_splitter, 1, wxEXPAND, 10 );
bpanelTomeDomainSizer->Add( bMargins, 1, wxEXPAND|wxTOP, 2 );
this->SetSizer( bpanelTomeDomainSizer );
this->Layout();
bpanelTomeDomainSizer->Fit( this );
// Connect Events
this->Connect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnUpdateUI ) );
m_tracePropagationGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnSizeTraceParametersGrid ), NULL, this );
m_addDelayProfileButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnAddDelayProfileClick ), NULL, this );
m_removeDelayProfileButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnRemoveDelayProfileClick ), NULL, this );
m_viaPropagationGrid->Connect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnSizeTraceParametersGrid ), NULL, this );
m_addViaOverrideButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnAddViaOverrideClick ), NULL, this );
m_removeViaOverrideButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnRemoveViaOverrideClick ), NULL, this );
}
PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::~PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE()
{
// Disconnect Events
this->Disconnect( wxEVT_UPDATE_UI, wxUpdateUIEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnUpdateUI ) );
m_tracePropagationGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnSizeTraceParametersGrid ), NULL, this );
m_addDelayProfileButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnAddDelayProfileClick ), NULL, this );
m_removeDelayProfileButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnRemoveDelayProfileClick ), NULL, this );
m_viaPropagationGrid->Disconnect( wxEVT_SIZE, wxSizeEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnSizeTraceParametersGrid ), NULL, this );
m_addViaOverrideButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnAddViaOverrideClick ), NULL, this );
m_removeViaOverrideButton->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE::OnRemoveViaOverrideClick ), NULL, this );
}
@@ -1,950 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="18"/>
<object class="Project" expanded="true">
<property name="code_generation">C++</property>
<property name="cpp_class_decoration"></property>
<property name="cpp_disconnect_events">1</property>
<property name="cpp_event_generation">connect</property>
<property name="cpp_help_provider">none</property>
<property name="cpp_namespace"></property>
<property name="cpp_precompiled_header"></property>
<property name="cpp_use_array_enum">0</property>
<property name="cpp_use_enum">1</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="file">panel_setup_time_domain_parameters_base</property>
<property name="first_id">1000</property>
<property name="internationalize">1</property>
<property name="lua_skip_events">1</property>
<property name="lua_ui_table">UI</property>
<property name="name">panel_setup_time_domain_parameters_base</property>
<property name="path">.</property>
<property name="php_disconnect_events">0</property>
<property name="php_disconnect_mode">source_name</property>
<property name="php_skip_events">1</property>
<property name="python_disconnect_events">0</property>
<property name="python_disconnect_mode">source_name</property>
<property name="python_image_path_wrapper_function_name"></property>
<property name="python_indent_with_spaces"></property>
<property name="python_skip_events">1</property>
<property name="relative_path">1</property>
<property name="use_microsoft_bom">0</property>
<property name="use_native_eol">0</property>
<object class="Panel" expanded="true">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size">-1,-1</property>
<property name="name">PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE</property>
<property name="pos"></property>
<property name="size">-1,-1</property>
<property name="subclass">; forward_declare</property>
<property name="tooltip"></property>
<property name="two_step_creation">0</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxTAB_TRAVERSAL</property>
<event name="OnUpdateUI">OnUpdateUI</event>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bpanelTomeDomainSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">2</property>
<property name="flag">wxEXPAND|wxTOP</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bMargins</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">10</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxSplitterWindow" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_pane_size">160</property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_splitter</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="sashgravity">0.0</property>
<property name="sashpos">-1</property>
<property name="sashsize">-1</property>
<property name="show">1</property>
<property name="size"></property>
<property name="splitmode">wxSPLIT_HORIZONTAL</property>
<property name="style">wxSP_3DSASH|wxSP_LIVE_UPDATE|wxSP_NO_XP_THEME</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<object class="splitteritem" expanded="true">
<object class="wxPanel" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_timeDomainParametersPane</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="subclass">WX_PANEL; widgets/wx_panel.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxTAB_TRAVERSAL</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bUpperSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="false">
<property name="border">8</property>
<property name="flag">wxTOP|wxLEFT|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Delay Profiles</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticText3</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="spacer" expanded="false">
<property name="height">3</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxFIXED_MINSIZE|wxRIGHT|wxLEFT</property>
<property name="proportion">1</property>
<object class="wxGrid" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="autosize_cols">0</property>
<property name="autosize_rows">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="cell_bg"></property>
<property name="cell_font"></property>
<property name="cell_horiz_alignment">wxALIGN_LEFT</property>
<property name="cell_text"></property>
<property name="cell_vert_alignment">wxALIGN_CENTER</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="col_label_horiz_alignment">wxALIGN_CENTER</property>
<property name="col_label_size">wxGRID_AUTOSIZE</property>
<property name="col_label_values">&quot;Profile Name&quot; &quot;Vias&quot;</property>
<property name="col_label_vert_alignment">wxALIGN_CENTER</property>
<property name="cols">2</property>
<property name="column_sizes"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="drag_col_move">0</property>
<property name="drag_col_size">1</property>
<property name="drag_grid_size">0</property>
<property name="drag_row_size">1</property>
<property name="editing">1</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="grid_line_color"></property>
<property name="grid_lines">1</property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label_bg"></property>
<property name="label_font"></property>
<property name="label_text"></property>
<property name="margin_height">0</property>
<property name="margin_width">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">-1,-1</property>
<property name="moveable">1</property>
<property name="name">m_tracePropagationGrid</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="row_label_horiz_alignment">wxALIGN_LEFT</property>
<property name="row_label_size">0</property>
<property name="row_label_values"></property>
<property name="row_label_vert_alignment">wxALIGN_CENTER</property>
<property name="row_sizes"></property>
<property name="rows">0</property>
<property name="show">1</property>
<property name="size"></property>
<property name="subclass">WX_GRID; widgets/wx_grid.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL</property>
<event name="OnSize">OnSizeTraceParametersGrid</event>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">3</property>
<property name="flag">wxEXPAND|wxTOP</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">buttonBoxSizer</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Add Parameter</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">-1,-1</property>
<property name="moveable">1</property>
<property name="name">m_addDelayProfileButton</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size">-1,-1</property>
<property name="style"></property>
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnAddDelayProfileClick</event>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="spacer" expanded="false">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">20</property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Delete Parameter</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">-1,-1</property>
<property name="moveable">1</property>
<property name="name">m_removeDelayProfileButton</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size">-1,-1</property>
<property name="style"></property>
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnRemoveDelayProfileClick</event>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="spacer" expanded="false">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">20</property>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
<object class="splitteritem" expanded="true">
<object class="wxPanel" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_viaDelayOverridesPane</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="subclass">WX_PANEL; widgets/wx_panel.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxTAB_TRAVERSAL</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bUpperSizer1</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">8</property>
<property name="flag">wxTOP|wxLEFT|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxStaticText" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Via Delay Overrides</property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticText31</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<property name="wrap">-1</property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="spacer" expanded="true">
<property name="height">3</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxFIXED_MINSIZE|wxRIGHT|wxLEFT</property>
<property name="proportion">1</property>
<object class="wxGrid" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="autosize_cols">0</property>
<property name="autosize_rows">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="cell_bg"></property>
<property name="cell_font"></property>
<property name="cell_horiz_alignment">wxALIGN_LEFT</property>
<property name="cell_text"></property>
<property name="cell_vert_alignment">wxALIGN_CENTER</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="col_label_horiz_alignment">wxALIGN_CENTER</property>
<property name="col_label_size">wxGRID_AUTOSIZE</property>
<property name="col_label_values">&quot;Profile Name&quot; &quot;Signal Layer From&quot; &quot;Signal Layer To&quot; &quot;Via Layer From&quot; &quot;Via Layer To&quot; &quot;Delay&quot;</property>
<property name="col_label_vert_alignment">wxALIGN_CENTER</property>
<property name="cols">6</property>
<property name="column_sizes"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="drag_col_move">0</property>
<property name="drag_col_size">1</property>
<property name="drag_grid_size">0</property>
<property name="drag_row_size">1</property>
<property name="editing">1</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="grid_line_color"></property>
<property name="grid_lines">1</property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label_bg"></property>
<property name="label_font"></property>
<property name="label_text"></property>
<property name="margin_height">0</property>
<property name="margin_width">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">-1,-1</property>
<property name="moveable">1</property>
<property name="name">m_viaPropagationGrid</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="row_label_horiz_alignment">wxALIGN_LEFT</property>
<property name="row_label_size">0</property>
<property name="row_label_values"></property>
<property name="row_label_vert_alignment">wxALIGN_CENTER</property>
<property name="row_sizes"></property>
<property name="rows">0</property>
<property name="show">1</property>
<property name="size"></property>
<property name="subclass">WX_GRID; widgets/wx_grid.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxHSCROLL|wxTAB_TRAVERSAL|wxVSCROLL</property>
<event name="OnSize">OnSizeTraceParametersGrid</event>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">3</property>
<property name="flag">wxEXPAND|wxTOP</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">buttonBoxSizer1</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Add Parameter</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">-1,-1</property>
<property name="moveable">1</property>
<property name="name">m_addViaOverrideButton</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size">-1,-1</property>
<property name="style"></property>
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnAddViaOverrideClick</event>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="spacer" expanded="true">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">20</property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Delete Parameter</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size">-1,-1</property>
<property name="moveable">1</property>
<property name="name">m_removeViaOverrideButton</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size">-1,-1</property>
<property name="style"></property>
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnRemoveViaOverrideClick</event>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="spacer" expanded="true">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">20</property>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>
@@ -1,71 +0,0 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class STD_BITMAP_BUTTON;
class WX_GRID;
class WX_PANEL;
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/grid.h>
#include <wx/bmpbuttn.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/sizer.h>
#include <wx/panel.h>
#include <wx/splitter.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE
///////////////////////////////////////////////////////////////////////////////
class PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE : public wxPanel
{
private:
protected:
wxSplitterWindow* m_splitter;
WX_PANEL* m_timeDomainParametersPane;
wxStaticText* m_staticText3;
WX_GRID* m_tracePropagationGrid;
STD_BITMAP_BUTTON* m_addDelayProfileButton;
STD_BITMAP_BUTTON* m_removeDelayProfileButton;
WX_PANEL* m_viaDelayOverridesPane;
wxStaticText* m_staticText31;
WX_GRID* m_viaPropagationGrid;
STD_BITMAP_BUTTON* m_addViaOverrideButton;
STD_BITMAP_BUTTON* m_removeViaOverrideButton;
// Virtual event handlers, override them in your derived class
virtual void OnUpdateUI( wxUpdateUIEvent& event ) { event.Skip(); }
virtual void OnSizeTraceParametersGrid( wxSizeEvent& event ) { event.Skip(); }
virtual void OnAddDelayProfileClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRemoveDelayProfileClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnAddViaOverrideClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRemoveViaOverrideClick( wxCommandEvent& event ) { event.Skip(); }
public:
PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
~PANEL_SETUP_TIME_DOMAIN_PARAMETERS_BASE();
};
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,184 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* 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 program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef PANEL_SETUP_TUNING_PROFILE_INFO_H
#define PANEL_SETUP_TUNING_PROFILE_INFO_H
#include <dialogs/panel_setup_tuning_profile_info_base.h>
#include <project/tuning_profiles.h>
#include <transline_calculations/coupled_microstrip.h>
#include <transline_calculations/coupled_stripline.h>
#include <transline_calculations/microstrip.h>
#include <transline_calculations/stripline.h>
#include <widgets/unit_binder.h>
#include <board_stackup_manager/board_stackup.h>
#include <layer_ids.h>
class PANEL_SETUP_TUNING_PROFILES;
class PANEL_SETUP_TUNING_PROFILE_INFO : public PANEL_SETUP_TUNING_PROFILE_INFO_BASE
{
public:
PANEL_SETUP_TUNING_PROFILE_INFO( wxWindow* aParentWindow, PANEL_SETUP_TUNING_PROFILES* parentPanel );
~PANEL_SETUP_TUNING_PROFILE_INFO() override;
/// Updates the displayed layer names in all grids
void UpdateLayerNames();
/// Loads the given profile in to the panel
void LoadProfile( const TUNING_PROFILE& aProfile );
/// Saves the panel to the given profile
TUNING_PROFILE GetProfile() const;
/// Updates the parent notebook control
void OnProfileNameChanged( wxCommandEvent& event ) override;
/// Changes between Single and Differential profiles
void OnChangeProfileType( wxCommandEvent& event ) override;
/// Adds a row to the track propagation grid
void OnAddTrackRow( wxCommandEvent& event ) override;
/// Removes a row from the track propagation grid
void OnRemoveTrackRow( wxCommandEvent& event ) override;
/// Adds a via override row
void OnAddViaOverride( wxCommandEvent& event ) override;
/// Removes a via override row
void OnRemoveViaOverride( wxCommandEvent& event ) override;
/// Gets the name of this profile
wxString GetProfileName() const;
/// Validate this panel's data
bool ValidateProfile( size_t aPageIndex );
private:
enum TRACK_GRID_COLS
{
TRACK_GRID_SIGNAL_LAYER = 0,
TRACK_GRID_TOP_REFERENCE,
TRACK_GRID_BOTTOM_REFERENCE,
TRACK_GRID_TRACK_WIDTH,
TRACK_GRID_TRACK_GAP,
TRACK_GRID_DELAY
};
enum VIA_GRID_COLS
{
VIA_GRID_SIGNAL_LAYER_FROM = 0,
VIA_GRID_SIGNAL_LAYER_TO,
VIA_GRID_VIA_LAYER_FROM,
VIA_GRID_VIA_LAYER_TO,
VIA_GRID_DELAY
};
enum class CalculationType
{
WIDTH,
GAP,
DELAY
};
/// Initialises all controls on the panel
void initPanel();
/// Set up the widths of all grid columns
void setColumnWidths();
/// Calculates the track width or delay for the given propagation grid row
/// @returns pair of (width, unit propagation delay) in IU
std::pair<int, int> calculateSingleMicrostrip( const int aRow, CalculationType aCalculationType );
/// Calculates the track width or delay for the given propagation grid row
/// @returns pair of (width, unit propagation delay) in IU
std::pair<int, int> calculateSingleStripline( const int aRow, CalculationType aCalculationType );
/// Calculates the track width, pair gap, or delay for the given propagation grid row
/// @returns tuple of (width, diff pair gap, unit propagation delay) in IU
std::tuple<int, int, int> calculateDifferentialMicrostrip( int aRow, CalculationType aCalculationType );
/// Calculates the track width, pair gap, or delay for the given propagation grid row
/// @returns tuple of (width, diff pair gap, unit propagation delay) in IU
std::tuple<int, int, int> calculateDifferentialStripline( int aRow, CalculationType aCalculationType );
/// Calculate the effective skin depth for the given parameters
static double calculateSkinDepth( double aFreq, double aMurc, double aSigma );
/// Gets the index in to the layer list for the given layer.
/// @returns -1 if not found
static int getStackupLayerId( const std::vector<BOARD_STACKUP_ITEM*>& aLayerList, PCB_LAYER_ID aPcbLayerId );
/**
* Calculates the geometric average of the dielectric material properties. Note: This is a poor approximation as the
* electric field distribution is not equal across the dielectrics. However, it will do as an approximation before
* we have a field solver integrated.
*
* @returns (E_r, LossTangent) pair
*/
static std::pair<double, double>
calculateAverageDielectricConstants( const std::vector<BOARD_STACKUP_ITEM*>& aStackupLayerList,
const std::vector<int>& dielectricLayerStackupIds,
const EDA_IU_SCALE& aIuScale );
/// Gets the dielectric layers and heights for dielectrics between the two given copper layer IDs
void getDielectricDetails( const std::vector<BOARD_STACKUP_ITEM*>& aStackupLayerList, int aSignalLayerId,
int aReferenceLayerId, std::vector<int>& aDielectricLayerStackupIds,
double& aDielectricLayerHeight );
/// Gets the target impedance for the profile
double getTargetImpedance() const;
/// Calculates the required track parameters for the given track parameters grid row and col
void calculateTrackParametersForCell( int aRow, int aCol );
/// Sets the panel display for the given tuning type
void onChangeProfileType( TUNING_PROFILE::PROFILE_TYPE aType ) const;
/// The parent setup panel
PANEL_SETUP_TUNING_PROFILES* m_parentPanel;
/// Units for global via propagation unit delay
UNIT_BINDER m_viaPropagationUnits;
/// Calculator for single microstrip parameters
MICROSTRIP m_microstripCalc;
/// Calculator for single stripline parameters
STRIPLINE m_striplineCalc;
/// Calculator for coupled (differential) microstrip parameters
COUPLED_MICROSTRIP m_coupledMicrostripCalc;
/// Calculator for coupled (differential) stripline parameters
COUPLED_STRIPLINE m_coupledStriplineCalc;
// Electrical resistivity or specific electrical resistance of copper (ohm*meter)
static constexpr double RHO = 1.72e-8;
};
#endif //PANEL_SETUP_TUNING_PROFILE_INFO_H
@@ -0,0 +1,270 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "widgets/std_bitmap_button.h"
#include "widgets/wx_grid.h"
#include "panel_setup_tuning_profile_info_base.h"
///////////////////////////////////////////////////////////////////////////
PANEL_SETUP_TUNING_PROFILE_INFO_BASE::PANEL_SETUP_TUNING_PROFILE_INFO_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name )
{
wxFlexGridSizer* fgSizer1;
fgSizer1 = new wxFlexGridSizer( 3, 1, 0, 0 );
fgSizer1->AddGrowableCol( 0 );
fgSizer1->AddGrowableRow( 2 );
fgSizer1->SetFlexibleDirection( wxBOTH );
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL );
wxFlexGridSizer* fgSizer2;
fgSizer2 = new wxFlexGridSizer( 1, 9, 0, 0 );
fgSizer2->AddGrowableCol( 2 );
fgSizer2->AddGrowableCol( 5 );
fgSizer2->SetFlexibleDirection( wxHORIZONTAL );
fgSizer2->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL );
m_nameLabel = new wxStaticText( this, wxID_ANY, _("Name:"), wxDefaultPosition, wxDefaultSize, 0 );
m_nameLabel->Wrap( -1 );
fgSizer2->Add( m_nameLabel, 0, wxALL, 5 );
m_name = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer2->Add( m_name, 0, wxALL|wxEXPAND, 5 );
fgSizer2->Add( 0, 0, 1, wxEXPAND, 5 );
m_typeLabel = new wxStaticText( this, wxID_ANY, _("Type:"), wxDefaultPosition, wxDefaultSize, 0 );
m_typeLabel->Wrap( -1 );
fgSizer2->Add( m_typeLabel, 0, wxALL, 5 );
wxString m_typeChoices[] = { _("Single"), _("Differential") };
int m_typeNChoices = sizeof( m_typeChoices ) / sizeof( wxString );
m_type = new wxChoice( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_typeNChoices, m_typeChoices, 0 );
m_type->SetSelection( 0 );
fgSizer2->Add( m_type, 0, wxALL, 5 );
fgSizer2->Add( 0, 0, 1, wxEXPAND, 5 );
m_targetImpedanceLabel = new wxStaticText( this, wxID_ANY, _("Target Impedance:"), wxDefaultPosition, wxDefaultSize, 0 );
m_targetImpedanceLabel->Wrap( -1 );
fgSizer2->Add( m_targetImpedanceLabel, 0, wxALL, 5 );
m_targetImpedance = new wxTextCtrl( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
#ifdef __WXGTK__
if ( !m_targetImpedance->HasFlag( wxTE_MULTILINE ) )
{
m_targetImpedance->SetMaxLength( 15 );
}
#else
m_targetImpedance->SetMaxLength( 15 );
#endif
fgSizer2->Add( m_targetImpedance, 0, wxALL|wxEXPAND, 5 );
m_ohmsLabel = new wxStaticText( this, wxID_ANY, _("ohms"), wxDefaultPosition, wxDefaultSize, 0 );
m_ohmsLabel->Wrap( -1 );
fgSizer2->Add( m_ohmsLabel, 0, wxALL|wxRIGHT, 5 );
fgSizer1->Add( fgSizer2, 1, wxEXPAND, 5 );
wxGridBagSizer* gbSizer1;
gbSizer1 = new wxGridBagSizer( 0, 0 );
gbSizer1->SetFlexibleDirection( wxBOTH );
gbSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_enableDrcGeneration = new wxCheckBox( this, wxID_ANY, _("Generate Net Class DRC Rules"), wxDefaultPosition, wxDefaultSize, 0 );
m_enableDrcGeneration->SetValue(true);
gbSizer1->Add( m_enableDrcGeneration, wxGBPosition( 0, 0 ), wxGBSpan( 1, 1 ), wxALL, 5 );
m_enableDelayTuning = new wxCheckBox( this, wxID_ANY, _("Enable Time Domain Tuning"), wxDefaultPosition, wxDefaultSize, 0 );
gbSizer1->Add( m_enableDelayTuning, wxGBPosition( 0, 1 ), wxGBSpan( 1, 1 ), wxALL, 5 );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
gbSizer1->Add( m_staticline1, wxGBPosition( 1, 0 ), wxGBSpan( 1, 2 ), wxEXPAND | wxALL, 5 );
gbSizer1->AddGrowableCol( 0 );
fgSizer1->Add( gbSizer1, 1, wxEXPAND, 5 );
m_splitter1 = new wxSplitterWindow( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3DSASH );
m_splitter1->Connect( wxEVT_IDLE, wxIdleEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::m_splitter1OnIdle ), NULL, this );
m_panel3 = new wxPanel( m_splitter1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxStaticBoxSizer* sbSizer2;
sbSizer2 = new wxStaticBoxSizer( new wxStaticBox( m_panel3, wxID_ANY, _("Track Propagation") ), wxVERTICAL );
wxFlexGridSizer* fgSizer4;
fgSizer4 = new wxFlexGridSizer( 0, 1, 0, 0 );
fgSizer4->AddGrowableCol( 0 );
fgSizer4->AddGrowableRow( 0 );
fgSizer4->SetFlexibleDirection( wxBOTH );
fgSizer4->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
m_trackPropagationGrid = new WX_GRID( sbSizer2->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
// Grid
m_trackPropagationGrid->CreateGrid( 0, 6 );
m_trackPropagationGrid->EnableEditing( true );
m_trackPropagationGrid->EnableGridLines( true );
m_trackPropagationGrid->EnableDragGridSize( false );
m_trackPropagationGrid->SetMargins( 0, 0 );
// Columns
m_trackPropagationGrid->AutoSizeColumns();
m_trackPropagationGrid->EnableDragColMove( false );
m_trackPropagationGrid->EnableDragColSize( true );
m_trackPropagationGrid->SetColLabelValue( 0, _("Signal Layer") );
m_trackPropagationGrid->SetColLabelValue( 1, _("Top Reference") );
m_trackPropagationGrid->SetColLabelValue( 2, _("Bottom Reference") );
m_trackPropagationGrid->SetColLabelValue( 3, _("Track Width") );
m_trackPropagationGrid->SetColLabelValue( 4, _("Diff Pair Gap") );
m_trackPropagationGrid->SetColLabelValue( 5, _("Unit Delay") );
m_trackPropagationGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Rows
m_trackPropagationGrid->EnableDragRowSize( true );
m_trackPropagationGrid->SetRowLabelSize( 0 );
m_trackPropagationGrid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Label Appearance
// Cell Defaults
m_trackPropagationGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
fgSizer4->Add( m_trackPropagationGrid, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* bSizer9;
bSizer9 = new wxBoxSizer( wxHORIZONTAL );
m_addTrackPropogationLayer = new STD_BITMAP_BUTTON( sbSizer2->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
bSizer9->Add( m_addTrackPropogationLayer, 0, wxBOTTOM|wxLEFT|wxTOP, 5 );
bSizer9->Add( 20, 0, 1, 0, 5 );
m_deleteTrackPropogationLayer = new STD_BITMAP_BUTTON( sbSizer2->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
bSizer9->Add( m_deleteTrackPropogationLayer, 0, wxBOTTOM|wxLEFT|wxTOP, 5 );
fgSizer4->Add( bSizer9, 1, 0, 5 );
sbSizer2->Add( fgSizer4, 1, wxEXPAND, 5 );
m_panel3->SetSizer( sbSizer2 );
m_panel3->Layout();
sbSizer2->Fit( m_panel3 );
m_panel4 = new wxPanel( m_splitter1, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxStaticBoxSizer* sbSizer3;
sbSizer3 = new wxStaticBoxSizer( new wxStaticBox( m_panel4, wxID_ANY, _("Via Propagation") ), wxVERTICAL );
wxFlexGridSizer* fgSizer3;
fgSizer3 = new wxFlexGridSizer( 3, 1, 0, 0 );
fgSizer3->AddGrowableCol( 0 );
fgSizer3->AddGrowableRow( 1 );
fgSizer3->SetFlexibleDirection( wxBOTH );
fgSizer3->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
wxBoxSizer* bSizer8;
bSizer8 = new wxBoxSizer( wxHORIZONTAL );
m_viaPropagationSpeedLabel = new wxStaticText( sbSizer3->GetStaticBox(), wxID_ANY, _("Via Propagation Speed:"), wxDefaultPosition, wxDefaultSize, 0 );
m_viaPropagationSpeedLabel->Wrap( -1 );
bSizer8->Add( m_viaPropagationSpeedLabel, 0, wxALL, 5 );
m_viaPropagationSpeed = new wxTextCtrl( sbSizer3->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
bSizer8->Add( m_viaPropagationSpeed, 0, wxALL, 5 );
m_viaPropSpeedUnits = new wxStaticText( sbSizer3->GetStaticBox(), wxID_ANY, _("ps/cm"), wxDefaultPosition, wxDefaultSize, 0 );
m_viaPropSpeedUnits->Wrap( -1 );
bSizer8->Add( m_viaPropSpeedUnits, 0, wxALL, 5 );
bSizer8->Add( 50, 0, 1, wxEXPAND, 5 );
m_viaDelayOverridesLabel = new wxStaticText( sbSizer3->GetStaticBox(), wxID_ANY, _("Via Delay Overrides:"), wxDefaultPosition, wxDefaultSize, 0 );
m_viaDelayOverridesLabel->Wrap( -1 );
bSizer8->Add( m_viaDelayOverridesLabel, 0, wxALL, 5 );
fgSizer3->Add( bSizer8, 1, 0, 5 );
m_viaOverrides = new WX_GRID( sbSizer3->GetStaticBox(), wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
// Grid
m_viaOverrides->CreateGrid( 0, 5 );
m_viaOverrides->EnableEditing( true );
m_viaOverrides->EnableGridLines( true );
m_viaOverrides->EnableDragGridSize( false );
m_viaOverrides->SetMargins( 0, 0 );
// Columns
m_viaOverrides->AutoSizeColumns();
m_viaOverrides->EnableDragColMove( false );
m_viaOverrides->EnableDragColSize( true );
m_viaOverrides->SetColLabelValue( 0, _("Signal Layer From") );
m_viaOverrides->SetColLabelValue( 1, _("Signal Layer To") );
m_viaOverrides->SetColLabelValue( 2, _("Via Layer From") );
m_viaOverrides->SetColLabelValue( 3, _("Via Layer To") );
m_viaOverrides->SetColLabelValue( 4, _("Delay") );
m_viaOverrides->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Rows
m_viaOverrides->EnableDragRowSize( true );
m_viaOverrides->SetRowLabelSize( 0 );
m_viaOverrides->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
// Label Appearance
// Cell Defaults
m_viaOverrides->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP );
fgSizer3->Add( m_viaOverrides, 0, wxALL|wxEXPAND, 5 );
wxBoxSizer* bSizer91;
bSizer91 = new wxBoxSizer( wxHORIZONTAL );
m_addViaPropagationOverride = new STD_BITMAP_BUTTON( sbSizer3->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
bSizer91->Add( m_addViaPropagationOverride, 0, wxBOTTOM|wxLEFT, 5 );
bSizer91->Add( 20, 0, 1, wxEXPAND, 5 );
m_removeViaPropagationOverride = new STD_BITMAP_BUTTON( sbSizer3->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
bSizer91->Add( m_removeViaPropagationOverride, 0, wxBOTTOM|wxLEFT, 5 );
fgSizer3->Add( bSizer91, 1, 0, 5 );
sbSizer3->Add( fgSizer3, 1, wxEXPAND, 5 );
m_panel4->SetSizer( sbSizer3 );
m_panel4->Layout();
sbSizer3->Fit( m_panel4 );
m_splitter1->SplitHorizontally( m_panel3, m_panel4, 0 );
fgSizer1->Add( m_splitter1, 1, wxEXPAND, 5 );
this->SetSizer( fgSizer1 );
this->Layout();
// Connect Events
m_name->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::OnProfileNameChanged ), NULL, this );
m_type->Connect( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::OnChangeProfileType ), NULL, this );
m_addTrackPropogationLayer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::OnAddTrackRow ), NULL, this );
m_deleteTrackPropogationLayer->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::OnRemoveTrackRow ), NULL, this );
m_addViaPropagationOverride->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::OnAddViaOverride ), NULL, this );
m_removeViaPropagationOverride->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::OnRemoveViaOverride ), NULL, this );
}
PANEL_SETUP_TUNING_PROFILE_INFO_BASE::~PANEL_SETUP_TUNING_PROFILE_INFO_BASE()
{
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,94 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class STD_BITMAP_BUTTON;
class WX_GRID;
#include <wx/string.h>
#include <wx/stattext.h>
#include <wx/gdicmn.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/textctrl.h>
#include <wx/choice.h>
#include <wx/sizer.h>
#include <wx/checkbox.h>
#include <wx/statline.h>
#include <wx/gbsizer.h>
#include <wx/grid.h>
#include <wx/bmpbuttn.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/statbox.h>
#include <wx/panel.h>
#include <wx/splitter.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class PANEL_SETUP_TUNING_PROFILE_INFO_BASE
///////////////////////////////////////////////////////////////////////////////
class PANEL_SETUP_TUNING_PROFILE_INFO_BASE : public wxPanel
{
private:
protected:
wxStaticText* m_nameLabel;
wxTextCtrl* m_name;
wxStaticText* m_typeLabel;
wxChoice* m_type;
wxStaticText* m_targetImpedanceLabel;
wxTextCtrl* m_targetImpedance;
wxStaticText* m_ohmsLabel;
wxCheckBox* m_enableDrcGeneration;
wxCheckBox* m_enableDelayTuning;
wxStaticLine* m_staticline1;
wxSplitterWindow* m_splitter1;
wxPanel* m_panel3;
WX_GRID* m_trackPropagationGrid;
STD_BITMAP_BUTTON* m_addTrackPropogationLayer;
STD_BITMAP_BUTTON* m_deleteTrackPropogationLayer;
wxPanel* m_panel4;
wxStaticText* m_viaPropagationSpeedLabel;
wxTextCtrl* m_viaPropagationSpeed;
wxStaticText* m_viaPropSpeedUnits;
wxStaticText* m_viaDelayOverridesLabel;
WX_GRID* m_viaOverrides;
STD_BITMAP_BUTTON* m_addViaPropagationOverride;
STD_BITMAP_BUTTON* m_removeViaPropagationOverride;
// Virtual event handlers, override them in your derived class
virtual void OnProfileNameChanged( wxCommandEvent& event ) { event.Skip(); }
virtual void OnChangeProfileType( wxCommandEvent& event ) { event.Skip(); }
virtual void OnAddTrackRow( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRemoveTrackRow( wxCommandEvent& event ) { event.Skip(); }
virtual void OnAddViaOverride( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRemoveViaOverride( wxCommandEvent& event ) { event.Skip(); }
public:
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 );
~PANEL_SETUP_TUNING_PROFILE_INFO_BASE();
void m_splitter1OnIdle( wxIdleEvent& )
{
m_splitter1->SetSashPosition( 0 );
m_splitter1->Disconnect( wxEVT_IDLE, wxIdleEventHandler( PANEL_SETUP_TUNING_PROFILE_INFO_BASE::m_splitter1OnIdle ), NULL, this );
}
};
@@ -0,0 +1,200 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* 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 program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <dialogs/panel_setup_tuning_profiles.h>
#include <dialogs/panel_setup_tuning_profile_info.h>
#include <widgets/wx_panel.h>
#include <widgets/std_bitmap_button.h>
#include <bitmaps.h>
#include <pcb_edit_frame.h>
#include <grid_tricks.h>
#include <layer_ids.h>
#include <magic_enum.hpp>
#include <pgm_base.h>
#include <widgets/grid_icon_text_helpers.h>
#include <widgets/paged_dialog.h>
PANEL_SETUP_TUNING_PROFILES::PANEL_SETUP_TUNING_PROFILES( wxWindow* aParentWindow, PCB_EDIT_FRAME* aFrame,
BOARD* aBoard,
std::shared_ptr<TUNING_PROFILES> aTimeDomainParameters ) :
PANEL_SETUP_TUNING_PROFILES_BASE( aParentWindow ),
m_tuningProfileParameters( std::move( aTimeDomainParameters ) ),
m_dlg( dynamic_cast<DIALOG_SHIM*>( aParentWindow ) ),
m_frame( aFrame ),
m_board( aFrame->GetBoard() ),
m_unitsProvider( std::make_unique<UNITS_PROVIDER>( pcbIUScale, m_frame->GetUserUnits() ) )
{
Freeze();
m_addTuningProfileButton->SetBitmap( KiBitmapBundle( BITMAPS::small_plus ) );
m_removeTuningProfileButton->SetBitmap( KiBitmapBundle( BITMAPS::small_trash ) );
Thaw();
}
PANEL_SETUP_TUNING_PROFILES::~PANEL_SETUP_TUNING_PROFILES()
{
}
bool PANEL_SETUP_TUNING_PROFILES::TransferDataToWindow()
{
m_tuningProfiles->DeleteAllPages();
SyncCopperLayers( m_board->GetCopperLayerCount() );
const std::vector<TUNING_PROFILE>& tuningProfiles = m_tuningProfileParameters->GetTuningProfiles();
for( const TUNING_PROFILE& profile : tuningProfiles )
{
PANEL_SETUP_TUNING_PROFILE_INFO* panel = new PANEL_SETUP_TUNING_PROFILE_INFO( m_tuningProfiles, this );
m_tuningProfiles->AddPage( panel, profile.m_ProfileName, true );
panel->LoadProfile( profile );
}
return true;
}
bool PANEL_SETUP_TUNING_PROFILES::TransferDataFromWindow()
{
if( !Validate() )
return false;
m_tuningProfileParameters->ClearTuningProfiles();
for( size_t i = 0; i < m_tuningProfiles->GetPageCount(); ++i )
{
PANEL_SETUP_TUNING_PROFILE_INFO* panel =
dynamic_cast<PANEL_SETUP_TUNING_PROFILE_INFO*>( m_tuningProfiles->GetPage( i ) );
TUNING_PROFILE profile = panel->GetProfile();
m_tuningProfileParameters->AddTuningProfile( std::move( profile ) );
}
return true;
}
void PANEL_SETUP_TUNING_PROFILES::SyncCopperLayers( const int aNumCopperLayers )
{
m_prevLayerNamesToIDs = m_layerNamesToIDs;
m_copperLayerIdsToIndex.clear();
m_copperIndexToLayerId.clear();
m_layerNames.clear();
m_layerNamesToIDs.clear();
int layerIdx = 0;
for( const auto& layer : LSET::AllCuMask( aNumCopperLayers ).CuStack() )
{
wxString layerName = m_board->GetLayerName( layer );
m_layerNames.emplace_back( layerName );
m_layerNamesToIDs[layerName] = layer;
m_copperLayerIdsToIndex[layer] = layerIdx;
m_copperIndexToLayerId[layerIdx] = layer;
++layerIdx;
}
if( m_prevLayerNamesToIDs.empty() )
m_prevLayerNamesToIDs = m_layerNamesToIDs;
for( size_t i = 0; i < m_tuningProfiles->GetPageCount(); ++i )
{
PANEL_SETUP_TUNING_PROFILE_INFO* panel =
static_cast<PANEL_SETUP_TUNING_PROFILE_INFO*>( m_tuningProfiles->GetPage( i ) );
panel->UpdateLayerNames();
}
}
void PANEL_SETUP_TUNING_PROFILES::OnAddTuningProfileClick( wxCommandEvent& event )
{
PANEL_SETUP_TUNING_PROFILE_INFO* panel = new PANEL_SETUP_TUNING_PROFILE_INFO( m_tuningProfiles, this );
m_tuningProfiles->AddPage( panel, "Profile ", true );
}
void PANEL_SETUP_TUNING_PROFILES::OnRemoveTuningProfileClick( wxCommandEvent& event )
{
if( const wxWindow* page = m_tuningProfiles->GetCurrentPage() )
{
const size_t pageIdx = m_tuningProfiles->FindPage( page );
m_tuningProfiles->RemovePage( pageIdx );
}
}
bool PANEL_SETUP_TUNING_PROFILES::Validate()
{
for( size_t i = 0; i < m_tuningProfiles->GetPageCount(); ++i )
{
PANEL_SETUP_TUNING_PROFILE_INFO* panel =
static_cast<PANEL_SETUP_TUNING_PROFILE_INFO*>( m_tuningProfiles->GetPage( i ) );
if( !panel->ValidateProfile( i ) )
return false;
}
return true;
}
void PANEL_SETUP_TUNING_PROFILES::UpdateProfileName( PANEL_SETUP_TUNING_PROFILE_INFO* panel, wxString newName ) const
{
const int pageId = m_tuningProfiles->FindPage( panel );
if( pageId == wxNOT_FOUND )
return;
m_tuningProfiles->SetPageText( pageId, newName );
}
void PANEL_SETUP_TUNING_PROFILES::ImportSettingsFrom( const std::shared_ptr<TUNING_PROFILES>& aOtherParameters )
{
std::shared_ptr<TUNING_PROFILES> savedSettings = m_tuningProfileParameters;
m_tuningProfileParameters = aOtherParameters;
TransferDataToWindow();
m_tuningProfileParameters = std::move( savedSettings );
}
std::vector<wxString> PANEL_SETUP_TUNING_PROFILES::GetDelayProfileNames() const
{
std::vector<wxString> names;
size_t profileCount = m_tuningProfiles->GetPageCount();
for( size_t i = 0; i < profileCount; ++i )
{
const PANEL_SETUP_TUNING_PROFILE_INFO* profilePage =
dynamic_cast<PANEL_SETUP_TUNING_PROFILE_INFO*>( m_tuningProfiles->GetPage( i ) );
if( wxString name = profilePage->GetProfileName(); name != wxEmptyString )
names.push_back( name );
}
return names;
}
@@ -0,0 +1,102 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* 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 program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef PANEL_SETUP_TUNING_PROFILES_H
#define PANEL_SETUP_TUNING_PROFILES_H
#include <memory>
#include <board.h>
#include <dialog_shim.h>
#include <dialogs/panel_setup_tuning_profiles_base.h>
#include <project/tuning_profiles.h>
class PANEL_SETUP_TUNING_PROFILE_INFO;
class PANEL_SETUP_TUNING_PROFILES final : public PANEL_SETUP_TUNING_PROFILES_BASE
{
public:
friend class PANEL_SETUP_TUNING_PROFILE_INFO;
PANEL_SETUP_TUNING_PROFILES( wxWindow* aParentWindow, PCB_EDIT_FRAME* aFrame, BOARD* aBoard,
std::shared_ptr<TUNING_PROFILES> aTimeDomainParameters );
~PANEL_SETUP_TUNING_PROFILES() override;
/**
* Called when switching to this tab to make sure that any changes to the copper layer count
* made on the physical stackup page are reflected here
* @param aNumCopperLayers is the number of copper layers in the board
*/
void SyncCopperLayers( int aNumCopperLayers );
/// Load parameter data from the settings object
bool TransferDataToWindow() override;
/// Save parameter data to the settings object
bool TransferDataFromWindow() override;
/// Returns all configured tuning profile names. Used by the netclass setup panel
std::vector<wxString> GetDelayProfileNames() const;
/// Load configuration from the given settings object
void ImportSettingsFrom( const std::shared_ptr<TUNING_PROFILES>& aOtherParameters );
/// Adds a new tuning profile entry to the tuning profile grid
void OnAddTuningProfileClick( wxCommandEvent& event ) override;
/// Removes a tuning profile entry from the tuning profile grid
void OnRemoveTuningProfileClick( wxCommandEvent& event ) override;
/// Validates all data
bool Validate() override;
/// Update the notebook display of the name for a given panel
void UpdateProfileName( PANEL_SETUP_TUNING_PROFILE_INFO* panel, wxString newName ) const;
private:
/// The parameters object to load / save data from / to
std::shared_ptr<TUNING_PROFILES> m_tuningProfileParameters;
/// The parent dialog
DIALOG_SHIM* m_dlg;
/// The active edit frame
PCB_EDIT_FRAME* m_frame;
/// The current board
BOARD* m_board;
std::unique_ptr<UNITS_PROVIDER> m_unitsProvider;
// Layer / index lookups
std::map<PCB_LAYER_ID, int> m_copperLayerIdsToIndex;
std::map<int, PCB_LAYER_ID> m_copperIndexToLayerId;
std::vector<wxString> m_layerNames;
// We cache these in case the names change on the layers panel
std::map<wxString, PCB_LAYER_ID> m_layerNamesToIDs;
std::map<wxString, PCB_LAYER_ID> m_prevLayerNamesToIDs;
};
#endif //PANEL_SETUP_TUNING_PROFILES_H
@@ -0,0 +1,53 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#include "widgets/std_bitmap_button.h"
#include "panel_setup_tuning_profiles_base.h"
///////////////////////////////////////////////////////////////////////////
PANEL_SETUP_TUNING_PROFILES_BASE::PANEL_SETUP_TUNING_PROFILES_BASE( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name ) : wxPanel( parent, id, pos, size, style, name )
{
wxFlexGridSizer* fgSizer1;
fgSizer1 = new wxFlexGridSizer( 2, 1, 0, 0 );
fgSizer1->AddGrowableCol( 0 );
fgSizer1->AddGrowableRow( 0 );
fgSizer1->SetFlexibleDirection( wxBOTH );
fgSizer1->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_ALL );
m_tuningProfiles = new wxNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_tuningProfiles, 1, wxEXPAND | wxALL, 5 );
wxBoxSizer* bSizer91;
bSizer91 = new wxBoxSizer( wxHORIZONTAL );
m_addTuningProfileButton = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
bSizer91->Add( m_addTuningProfileButton, 0, wxBOTTOM|wxLEFT, 5 );
bSizer91->Add( 20, 0, 1, wxEXPAND, 5 );
m_removeTuningProfileButton = new STD_BITMAP_BUTTON( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
bSizer91->Add( m_removeTuningProfileButton, 0, wxBOTTOM|wxLEFT, 5 );
fgSizer1->Add( bSizer91, 1, wxTOP, 5 );
this->SetSizer( fgSizer1 );
this->Layout();
// Connect Events
m_addTuningProfileButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TUNING_PROFILES_BASE::OnAddTuningProfileClick ), NULL, this );
m_removeTuningProfileButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( PANEL_SETUP_TUNING_PROFILES_BASE::OnRemoveTuningProfileClick ), NULL, this );
}
PANEL_SETUP_TUNING_PROFILES_BASE::~PANEL_SETUP_TUNING_PROFILES_BASE()
{
}
@@ -0,0 +1,304 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="18"/>
<object class="Project" expanded="true">
<property name="code_generation">C++</property>
<property name="cpp_class_decoration">; </property>
<property name="cpp_disconnect_events">0</property>
<property name="cpp_event_generation">connect</property>
<property name="cpp_help_provider">none</property>
<property name="cpp_namespace"></property>
<property name="cpp_precompiled_header"></property>
<property name="cpp_use_array_enum">0</property>
<property name="cpp_use_enum">1</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="file">panel_setup_tuning_profiles_base</property>
<property name="first_id">6000</property>
<property name="internationalize">1</property>
<property name="lua_skip_events">1</property>
<property name="lua_ui_table">UI</property>
<property name="name">PANEL_SETUP_TUNING_PROFILE_INFO_BASE</property>
<property name="path">.</property>
<property name="php_disconnect_events">0</property>
<property name="php_disconnect_mode">source_name</property>
<property name="php_skip_events">1</property>
<property name="python_disconnect_events">0</property>
<property name="python_disconnect_mode">source_name</property>
<property name="python_image_path_wrapper_function_name"></property>
<property name="python_indent_with_spaces">1</property>
<property name="python_skip_events">1</property>
<property name="relative_path">1</property>
<property name="use_microsoft_bom">0</property>
<property name="use_native_eol">0</property>
<object class="Panel" expanded="true">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
<property name="bg"></property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="event_handler">impl_virtual</property>
<property name="fg"></property>
<property name="font"></property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="maximum_size"></property>
<property name="minimum_size"></property>
<property name="name">PANEL_SETUP_TUNING_PROFILES_BASE</property>
<property name="pos"></property>
<property name="size">719,506</property>
<property name="subclass">; ; forward_declare</property>
<property name="tooltip"></property>
<property name="two_step_creation">0</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxTAB_TRAVERSAL</property>
<object class="wxFlexGridSizer" expanded="true">
<property name="cols">1</property>
<property name="flexible_direction">wxBOTH</property>
<property name="growablecols">0</property>
<property name="growablerows">0</property>
<property name="hgap">0</property>
<property name="minimum_size"></property>
<property name="name">fgSizer1</property>
<property name="non_flexible_grow_mode">wxFLEX_GROWMODE_ALL</property>
<property name="permission">none</property>
<property name="rows">2</property>
<property name="vgap">0</property>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND | wxALL</property>
<property name="proportion">1</property>
<object class="wxNotebook" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmapsize"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_tuningProfiles</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxTOP</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="true">
<property name="minimum_size"></property>
<property name="name">bSizer91</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">MyButton</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_addTuningProfileButton</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnAddTuningProfileClick</event>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="spacer" expanded="true">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">20</property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="false">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="auth_needed">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">MyButton</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_removeTuningProfileButton</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">STD_BITMAP_BUTTON; widgets/std_bitmap_button.h; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">OnRemoveTuningProfileClick</event>
</object>
</object>
</object>
</object>
</object>
</object>
</object>
</wxFormBuilder_Project>
@@ -0,0 +1,55 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
///////////////////////////////////////////////////////////////////////////
#pragma once
#include <wx/artprov.h>
#include <wx/xrc/xmlres.h>
#include <wx/intl.h>
class STD_BITMAP_BUTTON;
#include <wx/gdicmn.h>
#include <wx/notebook.h>
#include <wx/font.h>
#include <wx/colour.h>
#include <wx/settings.h>
#include <wx/string.h>
#include <wx/bmpbuttn.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/sizer.h>
#include <wx/panel.h>
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class PANEL_SETUP_TUNING_PROFILES_BASE
///////////////////////////////////////////////////////////////////////////////
class PANEL_SETUP_TUNING_PROFILES_BASE : public wxPanel
{
private:
protected:
wxNotebook* m_tuningProfiles;
STD_BITMAP_BUTTON* m_addTuningProfileButton;
STD_BITMAP_BUTTON* m_removeTuningProfileButton;
// Virtual event handlers, override them in your derived class
virtual void OnAddTuningProfileClick( wxCommandEvent& event ) { event.Skip(); }
virtual void OnRemoveTuningProfileClick( wxCommandEvent& event ) { event.Skip(); }
public:
PANEL_SETUP_TUNING_PROFILES_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 );
~PANEL_SETUP_TUNING_PROFILES_BASE();
};
+116 -1
View File
@@ -44,6 +44,8 @@
#include <core/profile.h>
#include <thread_pool.h>
#include <zone.h>
#include <project/project_file.h>
#include <project/tuning_profiles.h>
// wxListBox's performance degrades horrifically with very large datasets. It's not clear
@@ -436,8 +438,121 @@ void DRC_ENGINE::loadImplicitRules()
for( std::shared_ptr<DRC_RULE>& ncRule : netclassItemSpecificRules )
addRule( ncRule );
// 3) keepout area rules
// 4) tuning profile rules
auto addTuningSingleRule = [this, &bds]( const DELAY_PROFILE_TRACK_PROPAGATION_ENTRY& aLayerEntry,
const wxString& aProfileName, const wxString& aNetclassName )
{
if( aLayerEntry.GetWidth() <= 0 )
return;
std::shared_ptr<DRC_RULE> tuningRule = std::make_shared<DRC_RULE>();
tuningRule->m_Name = wxString::Format( _( "tuning profile '%s'" ), aProfileName );
tuningRule->m_Implicit = true;
wxString expr = wxString::Format( wxT( "A.hasExactNetclass('%s') && A.Layer == '%s'" ), aNetclassName,
LSET::Name( aLayerEntry.GetSignalLayer() ) );
tuningRule->m_Condition = new DRC_RULE_CONDITION( expr );
DRC_CONSTRAINT constraint( TRACK_WIDTH_CONSTRAINT );
constraint.Value().SetMin( bds.m_TrackMinWidth );
constraint.Value().SetOpt( aLayerEntry.GetWidth() );
tuningRule->AddConstraint( constraint );
addRule( tuningRule );
};
auto addTuningDifferentialRules = [this, &bds]( const DELAY_PROFILE_TRACK_PROPAGATION_ENTRY& aLayerEntry,
const wxString& aProfileName, const NETCLASS* aNetclass )
{
if( aLayerEntry.GetWidth() <= 0 || aLayerEntry.GetDiffPairGap() <= 0 )
return;
std::shared_ptr<DRC_RULE> tuningRule = std::make_shared<DRC_RULE>();
tuningRule->m_Name = wxString::Format( _( "tuning profile '%s'" ), aProfileName );
tuningRule->m_Implicit = true;
wxString expr = wxString::Format( wxT( "A.hasExactNetclass('%s') && A.Layer == '%s' && A.inDiffPair('*')" ),
aNetclass->GetName(), LSET::Name( aLayerEntry.GetSignalLayer() ) );
tuningRule->m_Condition = new DRC_RULE_CONDITION( expr );
DRC_CONSTRAINT constraint( TRACK_WIDTH_CONSTRAINT );
constraint.Value().SetMin( bds.m_TrackMinWidth );
constraint.Value().SetOpt( aLayerEntry.GetWidth() );
tuningRule->AddConstraint( constraint );
addRule( tuningRule );
std::shared_ptr<DRC_RULE> tuningRule2 = std::make_shared<DRC_RULE>();
tuningRule2->m_Name = wxString::Format( _( "tuning profile '%s'" ), aProfileName );
tuningRule2->m_Implicit = true;
const wxString expr2 =
wxString::Format( wxT( "A.hasExactNetclass('%s') && A.Layer == '%s' && A.inDiffPair('*')" ),
aNetclass->GetName(), LSET::Name( aLayerEntry.GetSignalLayer() ) );
tuningRule2->m_Condition = new DRC_RULE_CONDITION( expr2 );
DRC_CONSTRAINT constraint2( DIFF_PAIR_GAP_CONSTRAINT );
constraint2.Value().SetMin( bds.m_TrackMinWidth );
constraint2.Value().SetOpt( aLayerEntry.GetDiffPairGap() );
tuningRule2->AddConstraint( constraint2 );
addRule( tuningRule2 );
// A narrower diffpair gap overrides the netclass min clearance
if( aLayerEntry.GetDiffPairGap() < aNetclass->GetClearance() )
{
std::shared_ptr<DRC_RULE> diffPairClearanceRule = std::make_shared<DRC_RULE>();
diffPairClearanceRule->m_Name = wxString::Format( _( "tuning profile '%s'" ), aProfileName );
diffPairClearanceRule->m_Implicit = true;
expr = wxString::Format( wxT( "A.hasExactNetclass('%s') && A.Layer == '%s' && A.inDiffPair('*')" ),
aNetclass->GetName(), LSET::Name( aLayerEntry.GetSignalLayer() ) );
diffPairClearanceRule->m_Condition = new DRC_RULE_CONDITION( expr );
DRC_CONSTRAINT min_clearanceConstraint( CLEARANCE_CONSTRAINT );
min_clearanceConstraint.Value().SetMin( aLayerEntry.GetDiffPairGap() );
diffPairClearanceRule->AddConstraint( min_clearanceConstraint );
addRule( diffPairClearanceRule );
}
};
if( PROJECT* project = m_board->GetProject() )
{
std::shared_ptr<TUNING_PROFILES> tuningParams = project->GetProjectFile().TuningProfileParameters();
auto addNetclassTuningProfileRules =
[&tuningParams, &addTuningSingleRule, &addTuningDifferentialRules]( NETCLASS* aNetclass )
{
if( aNetclass->HasTuningProfile() )
{
const wxString delayProfileName = aNetclass->GetTuningProfile();
const TUNING_PROFILE& profile = tuningParams->GetTuningProfile( delayProfileName );
if( !profile.m_GenerateNetClassDRCRules )
return;
for( const DELAY_PROFILE_TRACK_PROPAGATION_ENTRY& layerEntry : profile.m_TrackPropagationEntries )
{
if( layerEntry.GetWidth() <= 0 )
continue;
if( profile.m_Type == TUNING_PROFILE::PROFILE_TYPE::SINGLE )
addTuningSingleRule( layerEntry, delayProfileName, aNetclass->GetName() );
else
addTuningDifferentialRules( layerEntry, delayProfileName, aNetclass );
}
}
};
for( const auto& [netclassName, netclass] : bds.m_NetSettings->GetNetclasses() )
addNetclassTuningProfileRules( netclass.get() );
for( const auto& [netclassName, netclass] : bds.m_NetSettings->GetCompositeNetclasses() )
addNetclassTuningProfileRules( netclass.get() );
}
// 5) keepout area rules
std::vector<ZONE*> keepoutZones;
for( ZONE* zone : m_board->Zones() )
+76 -72
View File
@@ -298,84 +298,87 @@ DRC_ITEM DRC_ITEM::nonMirroredTextOnBackLayer( DRCE_NONMIRRORED_TEXT_ON_BACK_LAY
_HKI( "Non-Mirrored text on back layer" ),
wxT( "nonmirrored_text_on_back_layer" ) );
std::vector<std::reference_wrapper<RC_ITEM>> DRC_ITEM::allItemTypes(
{
DRC_ITEM::heading_electrical,
DRC_ITEM::shortingItems,
DRC_ITEM::tracksCrossing,
DRC_ITEM::clearance,
DRC_ITEM::creepage,
DRC_ITEM::viaDangling,
DRC_ITEM::trackDangling,
DRC_ITEM::starvedThermal,
DRC_ITEM DRC_ITEM::missingTuningProfile( DRCE_MISSING_TUNING_PROFILE, _HKI( "Missing tuning profile" ),
wxT( "missing_tuning_profile" ) );
DRC_ITEM::heading_DFM,
DRC_ITEM::edgeClearance,
DRC_ITEM::holeClearance,
DRC_ITEM::holeNearHole,
DRC_ITEM::holesCoLocated,
DRC_ITEM::trackWidth,
DRC_ITEM::trackAngle,
DRC_ITEM::trackSegmentLength,
DRC_ITEM::annularWidth,
DRC_ITEM::drillTooSmall,
DRC_ITEM::microviaDrillTooSmall,
DRC_ITEM::courtyardsOverlap,
DRC_ITEM::missingCourtyard,
DRC_ITEM::malformedCourtyard,
DRC_ITEM::invalidOutline,
DRC_ITEM::copperSliver,
DRC_ITEM::solderMaskBridge,
DRC_ITEM::connectionWidth,
std::vector<std::reference_wrapper<RC_ITEM>> DRC_ITEM::allItemTypes( {
DRC_ITEM::heading_electrical,
DRC_ITEM::shortingItems,
DRC_ITEM::tracksCrossing,
DRC_ITEM::clearance,
DRC_ITEM::creepage,
DRC_ITEM::viaDangling,
DRC_ITEM::trackDangling,
DRC_ITEM::starvedThermal,
DRC_ITEM::heading_schematic_parity,
DRC_ITEM::duplicateFootprints,
DRC_ITEM::missingFootprint,
DRC_ITEM::extraFootprint,
DRC_ITEM::schematicParity,
DRC_ITEM::footprintFilters,
DRC_ITEM::netConflict,
DRC_ITEM::unconnectedItems,
DRC_ITEM::heading_DFM,
DRC_ITEM::edgeClearance,
DRC_ITEM::holeClearance,
DRC_ITEM::holeNearHole,
DRC_ITEM::holesCoLocated,
DRC_ITEM::trackWidth,
DRC_ITEM::trackAngle,
DRC_ITEM::trackSegmentLength,
DRC_ITEM::annularWidth,
DRC_ITEM::drillTooSmall,
DRC_ITEM::microviaDrillTooSmall,
DRC_ITEM::courtyardsOverlap,
DRC_ITEM::missingCourtyard,
DRC_ITEM::malformedCourtyard,
DRC_ITEM::invalidOutline,
DRC_ITEM::copperSliver,
DRC_ITEM::solderMaskBridge,
DRC_ITEM::connectionWidth,
DRC_ITEM::heading_signal_integrity,
DRC_ITEM::lengthOutOfRange,
DRC_ITEM::skewOutOfRange,
DRC_ITEM::viaCountOutOfRange,
DRC_ITEM::diffPairGapOutOfRange,
DRC_ITEM::diffPairUncoupledLengthTooLong,
DRC_ITEM::heading_schematic_parity,
DRC_ITEM::duplicateFootprints,
DRC_ITEM::missingFootprint,
DRC_ITEM::extraFootprint,
DRC_ITEM::schematicParity,
DRC_ITEM::footprintFilters,
DRC_ITEM::netConflict,
DRC_ITEM::unconnectedItems,
DRC_ITEM::heading_readability,
DRC_ITEM::silkOverlaps,
DRC_ITEM::silkMaskClearance,
DRC_ITEM::silkEdgeClearance,
DRC_ITEM::textHeightOutOfRange,
DRC_ITEM::textThicknessOutOfRange,
DRC_ITEM::mirroredTextOnFrontLayer,
DRC_ITEM::nonMirroredTextOnBackLayer,
DRC_ITEM::heading_signal_integrity,
DRC_ITEM::lengthOutOfRange,
DRC_ITEM::skewOutOfRange,
DRC_ITEM::viaCountOutOfRange,
DRC_ITEM::diffPairGapOutOfRange,
DRC_ITEM::diffPairUncoupledLengthTooLong,
DRC_ITEM::heading_misc,
DRC_ITEM::itemsNotAllowed,
DRC_ITEM::textOnEdgeCuts,
DRC_ITEM::zonesIntersect,
DRC_ITEM::isolatedCopper,
DRC_ITEM::footprint,
DRC_ITEM::padstack,
DRC_ITEM::pthInsideCourtyard,
DRC_ITEM::npthInsideCourtyard,
DRC_ITEM::itemOnDisabledLayer,
DRC_ITEM::unresolvedVariable,
DRC_ITEM::footprintTypeMismatch,
DRC_ITEM::libFootprintIssues,
DRC_ITEM::libFootprintMismatch,
DRC_ITEM::footprintTHPadhasNoHole,
DRC_ITEM::heading_readability,
DRC_ITEM::silkOverlaps,
DRC_ITEM::silkMaskClearance,
DRC_ITEM::silkEdgeClearance,
DRC_ITEM::textHeightOutOfRange,
DRC_ITEM::textThicknessOutOfRange,
DRC_ITEM::mirroredTextOnFrontLayer,
DRC_ITEM::nonMirroredTextOnBackLayer,
// DRC_ITEM types with no user-editable severities
// NOTE: this MUST be the last grouping in the list!
DRC_ITEM::heading_internal,
DRC_ITEM::padstackInvalid,
DRC_ITEM::genericError,
DRC_ITEM::genericWarning,
} );
DRC_ITEM::heading_misc,
DRC_ITEM::itemsNotAllowed,
DRC_ITEM::textOnEdgeCuts,
DRC_ITEM::zonesIntersect,
DRC_ITEM::isolatedCopper,
DRC_ITEM::footprint,
DRC_ITEM::padstack,
DRC_ITEM::pthInsideCourtyard,
DRC_ITEM::npthInsideCourtyard,
DRC_ITEM::itemOnDisabledLayer,
DRC_ITEM::unresolvedVariable,
DRC_ITEM::footprintTypeMismatch,
DRC_ITEM::libFootprintIssues,
DRC_ITEM::libFootprintMismatch,
DRC_ITEM::footprintTHPadhasNoHole,
DRC_ITEM::missingTuningProfile,
// DRC_ITEM types with no user-editable severities
// NOTE: this MUST be the last grouping in the list!
DRC_ITEM::heading_internal,
DRC_ITEM::padstackInvalid,
DRC_ITEM::genericError,
DRC_ITEM::genericWarning,
} );
std::shared_ptr<DRC_ITEM> DRC_ITEM::Create( int aErrorCode )
@@ -444,6 +447,7 @@ std::shared_ptr<DRC_ITEM> DRC_ITEM::Create( int aErrorCode )
case DRCE_PAD_TH_WITH_NO_HOLE: return std::make_shared<DRC_ITEM>( footprintTHPadhasNoHole );
case DRCE_MIRRORED_TEXT_ON_FRONT_LAYER: return std::make_shared<DRC_ITEM>( mirroredTextOnFrontLayer );
case DRCE_NONMIRRORED_TEXT_ON_BACK_LAYER: return std::make_shared<DRC_ITEM>( nonMirroredTextOnBackLayer );
case DRCE_MISSING_TUNING_PROFILE: return std::make_shared<DRC_ITEM>( missingTuningProfile );
default:
wxFAIL_MSG( wxT( "Unknown DRC error code" ) );
return nullptr;
+27 -23
View File
@@ -34,7 +34,8 @@ class DRC_TEST_PROVIDER;
class PCB_MARKER;
class BOARD;
enum PCB_DRC_CODE {
enum PCB_DRC_CODE
{
DRCE_FIRST = 1,
DRCE_UNCONNECTED_ITEMS = DRCE_FIRST, // items are unconnected
DRCE_SHORTING_ITEMS, // items short two nets but are not a net-tie
@@ -68,37 +69,37 @@ enum PCB_DRC_CODE {
// (not convertible to a closed polygon with holes)
DRCE_PTH_IN_COURTYARD,
DRCE_NPTH_IN_COURTYARD,
DRCE_DISABLED_LAYER_ITEM, // item on a disabled layer
DRCE_INVALID_OUTLINE, // invalid board outline
DRCE_DISABLED_LAYER_ITEM, // item on a disabled layer
DRCE_INVALID_OUTLINE, // invalid board outline
DRCE_MISSING_FOOTPRINT, // footprint not found for netlist item
DRCE_DUPLICATE_FOOTPRINT, // more than one footprints found for netlist item
DRCE_EXTRA_FOOTPRINT, // netlist item not found for footprint
DRCE_NET_CONFLICT, // pad net doesn't match netlist
DRCE_SCHEMATIC_PARITY, // footprint attributes don't match symbol attributes
DRCE_FOOTPRINT_FILTERS, // footprint doesn't match symbol's footprint filters
DRCE_MISSING_FOOTPRINT, // footprint not found for netlist item
DRCE_DUPLICATE_FOOTPRINT, // more than one footprints found for netlist item
DRCE_EXTRA_FOOTPRINT, // netlist item not found for footprint
DRCE_NET_CONFLICT, // pad net doesn't match netlist
DRCE_SCHEMATIC_PARITY, // footprint attributes don't match symbol attributes
DRCE_FOOTPRINT_FILTERS, // footprint doesn't match symbol's footprint filters
DRCE_FOOTPRINT_TYPE_MISMATCH, // footprint attribute does not match actual pads
DRCE_LIB_FOOTPRINT_ISSUES, // footprint not found in active libraries
DRCE_LIB_FOOTPRINT_MISMATCH, // footprint does not match the current library
DRCE_PAD_TH_WITH_NO_HOLE, // footprint has Plated Through-Hole with no hole
DRCE_FOOTPRINT, // error in footprint definition
DRCE_FOOTPRINT_TYPE_MISMATCH, // footprint attribute does not match actual pads
DRCE_LIB_FOOTPRINT_ISSUES, // footprint not found in active libraries
DRCE_LIB_FOOTPRINT_MISMATCH, // footprint does not match the current library
DRCE_PAD_TH_WITH_NO_HOLE, // footprint has Plated Through-Hole with no hole
DRCE_FOOTPRINT, // error in footprint definition
DRCE_UNRESOLVED_VARIABLE,
DRCE_ASSERTION_FAILURE, // user-defined (custom rule) assertion
DRCE_GENERIC_WARNING, // generic warning
DRCE_GENERIC_ERROR, // generic error
DRCE_ASSERTION_FAILURE, // user-defined (custom rule) assertion
DRCE_GENERIC_WARNING, // generic warning
DRCE_GENERIC_ERROR, // generic error
DRCE_COPPER_SLIVER,
DRCE_SOLDERMASK_BRIDGE, // failure to maintain min soldermask web thickness
// between copper items with different nets
DRCE_SOLDERMASK_BRIDGE, // failure to maintain min soldermask web thickness
// between copper items with different nets
DRCE_SILK_MASK_CLEARANCE, // silkscreen clipped by mask (potentially leaving it
// over pads, exposed copper, etc.)
DRCE_SILK_MASK_CLEARANCE, // silkscreen clipped by mask (potentially leaving it
// over pads, exposed copper, etc.)
DRCE_SILK_EDGE_CLEARANCE,
DRCE_TEXT_HEIGHT,
DRCE_TEXT_THICKNESS,
DRCE_OVERLAPPING_SILK, // silk-to-silk or silk-to-other clearance error
DRCE_OVERLAPPING_SILK, // silk-to-silk or silk-to-other clearance error
DRCE_LENGTH_OUT_OF_RANGE,
DRCE_SKEW_OUT_OF_RANGE,
@@ -109,7 +110,9 @@ enum PCB_DRC_CODE {
DRCE_MIRRORED_TEXT_ON_FRONT_LAYER,
DRCE_NONMIRRORED_TEXT_ON_BACK_LAYER,
DRCE_LAST = DRCE_NONMIRRORED_TEXT_ON_BACK_LAYER
DRCE_MISSING_TUNING_PROFILE, // Tuning profile used in net class is not defined
DRCE_LAST = DRCE_MISSING_TUNING_PROFILE
};
@@ -242,6 +245,7 @@ private:
static DRC_ITEM footprintTHPadhasNoHole;
static DRC_ITEM mirroredTextOnFrontLayer;
static DRC_ITEM nonMirroredTextOnBackLayer;
static DRC_ITEM missingTuningProfile;
private:
DRC_RULE* m_violatingRule = nullptr;
+49
View File
@@ -36,6 +36,8 @@
#include <drawing_sheet/ds_proxy_view_item.h>
#include <limits>
#include <project/project_file.h>
#include <project/tuning_profiles.h>
/*
Miscellaneous tests:
@@ -46,6 +48,7 @@
- DRCE_ASSERTION_FAILURE, ///< user-defined assertions
- DRCE_GENERIC_WARNING ///< user-defined warnings
- DRCE_GENERIC_ERROR ///< user-defined errors
- DRCE_MISSING_TUNING_PROFILES ///< tuning profile for netc lass not defined
*/
static void findClosestOutlineGap( BOARD* aBoard, PCB_SHAPE*& aItemA, PCB_SHAPE*& aItemB,
@@ -126,6 +129,7 @@ private:
void testDisabledLayers();
void testTextVars();
void testAssertions();
void testMissingTuningProfiles();
BOARD* m_board;
};
@@ -518,6 +522,43 @@ void DRC_TEST_PROVIDER_MISC::testTextVars()
}
void DRC_TEST_PROVIDER_MISC::testMissingTuningProfiles()
{
if( !m_board->GetProject() )
return;
std::shared_ptr<NET_SETTINGS> netSettings = m_board->GetProject()->GetProjectFile().NetSettings();
const std::shared_ptr<TUNING_PROFILES> tuningProfiles =
m_board->GetProject()->GetProjectFile().TuningProfileParameters();
std::set<wxString> profileNames;
std::ranges::for_each( tuningProfiles->GetTuningProfiles(),
[&profileNames]( const TUNING_PROFILE& tuningProfile )
{
if( const wxString name = tuningProfile.m_ProfileName; name != wxEmptyString )
profileNames.insert( name );
} );
for( const auto& [name, netclass] : netSettings->GetNetclasses() )
{
if( m_drcEngine->IsErrorLimitExceeded( DRCE_MISSING_TUNING_PROFILE ) )
return;
const wxString profileName = netclass->GetTuningProfile();
if( netclass->HasTuningProfile() && !profileNames.contains( profileName ) )
{
auto drcItem = DRC_ITEM::Create( DRCE_MISSING_TUNING_PROFILE );
wxString errMsg = wxString::Format( "%s (Net Class: %s, Tuning Profile: %s)", drcItem->GetErrorText(), name,
profileName );
drcItem->SetErrorMessage( errMsg );
reportViolation( drcItem, VECTOR2I(), UNDEFINED_LAYER );
}
}
}
bool DRC_TEST_PROVIDER_MISC::Run()
{
m_board = m_drcEngine->GetBoard();
@@ -556,6 +597,14 @@ bool DRC_TEST_PROVIDER_MISC::Run()
testAssertions();
}
if( !m_drcEngine->IsErrorLimitExceeded( DRCE_MISSING_TUNING_PROFILE ) )
{
if( !reportPhase( _( "Checking for missing tuning profiles..." ) ) )
return false; // DRC cancelled
testMissingTuningProfiles();
}
return !m_drcEngine->IsCancelled();
}
+1 -1
View File
@@ -952,7 +952,7 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
GetBoard()->GetComponentClassManager().RebuildRequiredCaches();
// Initialise time domain tuning caches
GetBoard()->GetLengthCalculation()->SynchronizeTimeDomainProperties();
GetBoard()->GetLengthCalculation()->SynchronizeTuningProfileProperties();
// Syncs the UI (appearance panel, etc) with the loaded board and project
OnBoardLoaded();
@@ -249,10 +249,10 @@ LENGTH_DELAY_STATS LENGTH_DELAY_CALCULATION::CalculateLengthDetails( std::vector
wxLogTrace( wxT( "PNS_TUNE" ), wxT( "CalculateLengthDetails: calculating time domain statistics" ) );
// TODO(JJ): Populate this
TIME_DOMAIN_GEOMETRY_CONTEXT ctx;
TUNING_PROFILE_GEOMETRY_CONTEXT ctx;
ctx.NetClass = aItems.front().GetEffectiveNetClass(); // We don't care if this is merged for net class lookup
const std::vector<int64_t> itemDelays = m_timeDomainParameters->GetPropagationDelays( aItems, ctx );
const std::vector<int64_t> itemDelays = m_tuningProfileParameters->GetPropagationDelays( aItems, ctx );
wxASSERT( itemDelays.size() == aItems.size() );
@@ -660,29 +660,28 @@ LENGTH_DELAY_CALCULATION::GetLengthCalculationItem( const BOARD_CONNECTED_ITEM*
}
void LENGTH_DELAY_CALCULATION::SetTimeDomainParametersProvider(
std::unique_ptr<TIME_DOMAIN_PARAMETERS_IFACE>&& aProvider )
void LENGTH_DELAY_CALCULATION::SetTuningProfileParametersProvider(
std::unique_ptr<TUNING_PROFILE_PARAMETERS_IFACE>&& aProvider )
{
m_timeDomainParameters = std::move( aProvider );
m_tuningProfileParameters = std::move( aProvider );
}
void LENGTH_DELAY_CALCULATION::SynchronizeTimeDomainProperties() const
void LENGTH_DELAY_CALCULATION::SynchronizeTuningProfileProperties() const
{
m_timeDomainParameters->OnSettingsChanged();
m_tuningProfileParameters->OnSettingsChanged();
}
int64_t LENGTH_DELAY_CALCULATION::CalculateLengthForDelay( const int64_t aDesiredDelay,
const TIME_DOMAIN_GEOMETRY_CONTEXT& aCtx ) const
int64_t LENGTH_DELAY_CALCULATION::CalculateLengthForDelay( const int64_t aDesiredDelay,
const TUNING_PROFILE_GEOMETRY_CONTEXT& aCtx ) const
{
return m_timeDomainParameters->GetTrackLengthForPropagationDelay( aDesiredDelay, aCtx );
return m_tuningProfileParameters->GetTrackLengthForPropagationDelay( aDesiredDelay, aCtx );
}
int64_t
LENGTH_DELAY_CALCULATION::CalculatePropagationDelayForShapeLineChain( const SHAPE_LINE_CHAIN& aShape,
const TIME_DOMAIN_GEOMETRY_CONTEXT& aCtx ) const
int64_t LENGTH_DELAY_CALCULATION::CalculatePropagationDelayForShapeLineChain(
const SHAPE_LINE_CHAIN& aShape, const TUNING_PROFILE_GEOMETRY_CONTEXT& aCtx ) const
{
return m_timeDomainParameters->CalculatePropagationDelayForShapeLineChain( aShape, aCtx );
return m_tuningProfileParameters->CalculatePropagationDelayForShapeLineChain( aShape, aCtx );
}
@@ -24,8 +24,8 @@
#ifndef PCBNEW_LENGTH_DELAY_CALCULATION_H
#define PCBNEW_LENGTH_DELAY_CALCULATION_H
#include "time_domain_parameters_iface.h"
#include "time_domain_parameters_user_defined.h"
#include "tuning_profile_parameters_iface.h"
#include "tuning_profile_parameters_user_defined.h"
#include <board_design_settings.h>
#include <connectivity/connectivity_data.h>
@@ -128,7 +128,7 @@ public:
*/
explicit LENGTH_DELAY_CALCULATION( BOARD* aBoard ) :
m_board( aBoard ),
m_timeDomainParameters( std::make_unique<TIME_DOMAIN_PARAMETERS_USER_DEFINED>( aBoard, this ) )
m_tuningProfileParameters( std::make_unique<TUNING_PROFILE_PARAMETERS_USER_DEFINED>( aBoard, this ) )
{
}
@@ -176,8 +176,8 @@ public:
* @param aShape is the shape to calculate delay for
* @param aCtx is the geometry context for which to query to propagation delay
*/
int64_t CalculatePropagationDelayForShapeLineChain( const SHAPE_LINE_CHAIN& aShape,
const TIME_DOMAIN_GEOMETRY_CONTEXT& aCtx ) const;
int64_t CalculatePropagationDelayForShapeLineChain( const SHAPE_LINE_CHAIN& aShape,
const TUNING_PROFILE_GEOMETRY_CONTEXT& aCtx ) const;
/**
* @brief Calculates the length of track required for the given delay in a specific geometry context
@@ -185,7 +185,7 @@ public:
* @param aDesiredDelay is the desired track delay (in IU)
* @param aCtx is the track geometry context to calculate propagation velocitiy against
*/
int64_t CalculateLengthForDelay( int64_t aDesiredDelay, const TIME_DOMAIN_GEOMETRY_CONTEXT& aCtx ) const;
int64_t CalculateLengthForDelay( int64_t aDesiredDelay, const TUNING_PROFILE_GEOMETRY_CONTEXT& aCtx ) const;
/// Optimises the given trace / line to minimise the electrical path length within the given pad
static void OptimiseTraceInPad( SHAPE_LINE_CHAIN& aLine, const PAD* aPad, PCB_LAYER_ID aPcbLayer );
@@ -193,11 +193,11 @@ public:
/// Return a LENGTH_CALCULATION_ITEM constructed from the given BOARD_CONNECTED_ITEM
LENGTH_DELAY_CALCULATION_ITEM GetLengthCalculationItem( const BOARD_CONNECTED_ITEM* aBoardItem ) const;
/// Sets the provider for time domain parameter resolution
void SetTimeDomainParametersProvider( std::unique_ptr<TIME_DOMAIN_PARAMETERS_IFACE>&& aProvider );
/// Sets the provider for tuning profile parameter resolution
void SetTuningProfileParametersProvider( std::unique_ptr<TUNING_PROFILE_PARAMETERS_IFACE>&& aProvider );
/// Ensure time domain properties provider is synced with board / project settings if required
void SynchronizeTimeDomainProperties() const;
void SynchronizeTuningProfileProperties() const;
/**
* Returns the stackup distance between the two given layers.
@@ -210,8 +210,8 @@ protected:
/// The parent board for all items
BOARD* m_board;
/// The active provider of time domain parameters
std::unique_ptr<TIME_DOMAIN_PARAMETERS_IFACE> m_timeDomainParameters;
/// The active provider of tuning profile parameters
std::unique_ptr<TUNING_PROFILE_PARAMETERS_IFACE> m_tuningProfileParameters;
/// Enum to describe whether track merging is attempted from the start or end of a track segment
enum class MERGE_POINT
@@ -21,8 +21,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef PCBNEW_TIME_DOMAIN_PARAMETERS_INTERFACE_H
#define PCBNEW_TIME_DOMAIN_PARAMETERS_INTERFACE_H
#ifndef PCBNEW_TUNING_PROFILE_PARAMETERS_IFACE_H
#define PCBNEW_TUNING_PROFILE_PARAMETERS_IFACE_H
#include <length_delay_calculation/length_delay_calculation_item.h>
#include <netclass.h>
@@ -32,7 +32,7 @@ class LENGTH_DELAY_CALCULATION;
/**
* A data structure to contain basic geometry data which can affect signal propagation calculations.
*/
struct TIME_DOMAIN_GEOMETRY_CONTEXT
struct TUNING_PROFILE_GEOMETRY_CONTEXT
{
/// The net class this track belongs to
const NETCLASS* NetClass;
@@ -52,19 +52,20 @@ struct TIME_DOMAIN_GEOMETRY_CONTEXT
/**
* Interface for providers of time domain parameter information. This interface is consumed by the
* LENGTH_TIME_CALCULATOR object to convert space-domain physical layout informaton (e.g. track lengths) in to
* Interface for providers of tuning profile parameter information. This interface is consumed by the
* LENGTH_TIME_CALCULATOR object to convert space-domain physical layout information (e.g. track lengths) in to
* time-domain propagation information.
*/
class TIME_DOMAIN_PARAMETERS_IFACE
class TUNING_PROFILE_PARAMETERS_IFACE
{
public:
explicit TIME_DOMAIN_PARAMETERS_IFACE( BOARD* aBoard, LENGTH_DELAY_CALCULATION* aCalculation ) :
m_board{ aBoard }, m_lengthCalculation{ aCalculation }
explicit TUNING_PROFILE_PARAMETERS_IFACE( BOARD* aBoard, LENGTH_DELAY_CALCULATION* aCalculation ) :
m_board{ aBoard },
m_lengthCalculation{ aCalculation }
{
}
virtual ~TIME_DOMAIN_PARAMETERS_IFACE() = default;
virtual ~TUNING_PROFILE_PARAMETERS_IFACE() = default;
/**
* Event called by the length and time calculation architecture if the board stackup has changed. This can be used
@@ -85,7 +86,7 @@ public:
* @param aContext the geometry context in which to query to propagation delay
*/
virtual std::vector<int64_t> GetPropagationDelays( const std::vector<LENGTH_DELAY_CALCULATION_ITEM>& aItems,
const TIME_DOMAIN_GEOMETRY_CONTEXT& aContext ) = 0;
const TUNING_PROFILE_GEOMETRY_CONTEXT& aContext ) = 0;
/**
* Gets the propagation delay (in internal units) for the given item in the given geometry context
@@ -93,8 +94,8 @@ public:
* @param aItem the board item to query propagation delay for
* @param aContext is the geometry context in which to query to propagation delay
*/
virtual int64_t GetPropagationDelay( const LENGTH_DELAY_CALCULATION_ITEM& aItem,
const TIME_DOMAIN_GEOMETRY_CONTEXT& aContext ) = 0;
virtual int64_t GetPropagationDelay( const LENGTH_DELAY_CALCULATION_ITEM& aItem,
const TUNING_PROFILE_GEOMETRY_CONTEXT& aContext ) = 0;
/**
* Gets the track length (in internal distance units) required for the given propagation delay (in internal time
@@ -103,8 +104,8 @@ public:
* @param aContext the geometry context in which to query to propagation delay
* @param aDelay the propagation delay for which a length should be calculated
*/
virtual int64_t GetTrackLengthForPropagationDelay( int64_t aDelay,
const TIME_DOMAIN_GEOMETRY_CONTEXT& aContext ) = 0;
virtual int64_t GetTrackLengthForPropagationDelay( int64_t aDelay,
const TUNING_PROFILE_GEOMETRY_CONTEXT& aContext ) = 0;
/**
* Gets the propagation delay for the given shape line chain
@@ -112,8 +113,8 @@ public:
* @param aShape is the shape to calculate delay for
* @param aContext is the geometry context for which to query to propagation delay
*/
virtual int64_t CalculatePropagationDelayForShapeLineChain( const SHAPE_LINE_CHAIN& aShape,
const TIME_DOMAIN_GEOMETRY_CONTEXT& aContext ) = 0;
virtual int64_t CalculatePropagationDelayForShapeLineChain( const SHAPE_LINE_CHAIN& aShape,
const TUNING_PROFILE_GEOMETRY_CONTEXT& aContext ) = 0;
protected:
/// The board all calculations are for
@@ -123,4 +124,4 @@ protected:
LENGTH_DELAY_CALCULATION* m_lengthCalculation;
};
#endif //PCBNEW_TIME_DOMAIN_PARAMETERS_INTERFACE_H
#endif //PCBNEW_TUNING_PROFILE_PARAMETERS_IFACE_H
@@ -23,25 +23,25 @@
#include <board.h>
#include <length_delay_calculation/length_delay_calculation.h>
#include <length_delay_calculation/time_domain_parameters_user_defined.h>
#include <length_delay_calculation/tuning_profile_parameters_user_defined.h>
#include <project/project_file.h>
void TIME_DOMAIN_PARAMETERS_USER_DEFINED::OnSettingsChanged()
void TUNING_PROFILE_PARAMETERS_USER_DEFINED::OnSettingsChanged()
{
rebuildCaches();
}
std::vector<int64_t>
TIME_DOMAIN_PARAMETERS_USER_DEFINED::GetPropagationDelays( const std::vector<LENGTH_DELAY_CALCULATION_ITEM>& aItems,
const TIME_DOMAIN_GEOMETRY_CONTEXT& aContext )
TUNING_PROFILE_PARAMETERS_USER_DEFINED::GetPropagationDelays( const std::vector<LENGTH_DELAY_CALCULATION_ITEM>& aItems,
const TUNING_PROFILE_GEOMETRY_CONTEXT& aContext )
{
if( aItems.empty() )
return {};
const wxString delayProfileName = aItems.front().GetEffectiveNetClass()->GetDelayProfile();
const DELAY_PROFILE* delayProfile = GetDelayProfile( delayProfileName );
const wxString delayProfileName = aItems.front().GetEffectiveNetClass()->GetTuningProfile();
const TUNING_PROFILE* delayProfile = GetTuningProfile( delayProfileName );
if( !delayProfile )
return std::vector<int64_t>( aItems.size(), 0 );
@@ -56,14 +56,14 @@ TIME_DOMAIN_PARAMETERS_USER_DEFINED::GetPropagationDelays( const std::vector<LEN
}
int64_t TIME_DOMAIN_PARAMETERS_USER_DEFINED::GetPropagationDelay( const LENGTH_DELAY_CALCULATION_ITEM& aItem,
const TIME_DOMAIN_GEOMETRY_CONTEXT& aContext )
int64_t TUNING_PROFILE_PARAMETERS_USER_DEFINED::GetPropagationDelay( const LENGTH_DELAY_CALCULATION_ITEM& aItem,
const TUNING_PROFILE_GEOMETRY_CONTEXT& aContext )
{
if( aItem.GetMergeStatus() == LENGTH_DELAY_CALCULATION_ITEM::MERGE_STATUS::MERGED_RETIRED )
return 0;
const wxString delayProfileName = aItem.GetEffectiveNetClass()->GetDelayProfile();
const DELAY_PROFILE* delayProfile = GetDelayProfile( delayProfileName );
const wxString delayProfileName = aItem.GetEffectiveNetClass()->GetTuningProfile();
const TUNING_PROFILE* delayProfile = GetTuningProfile( delayProfileName );
if( !delayProfile )
return 0;
@@ -72,9 +72,9 @@ int64_t TIME_DOMAIN_PARAMETERS_USER_DEFINED::GetPropagationDelay( const LENGTH_D
}
int64_t TIME_DOMAIN_PARAMETERS_USER_DEFINED::getPropagationDelay( const LENGTH_DELAY_CALCULATION_ITEM& aItem,
const TIME_DOMAIN_GEOMETRY_CONTEXT& aContext,
const DELAY_PROFILE* aDelayProfile ) const
int64_t TUNING_PROFILE_PARAMETERS_USER_DEFINED::getPropagationDelay( const LENGTH_DELAY_CALCULATION_ITEM& aItem,
const TUNING_PROFILE_GEOMETRY_CONTEXT& aContext,
const TUNING_PROFILE* aDelayProfile ) const
{
if( aItem.GetMergeStatus() == LENGTH_DELAY_CALCULATION_ITEM::MERGE_STATUS::MERGED_RETIRED )
return 0;
@@ -83,12 +83,23 @@ int64_t TIME_DOMAIN_PARAMETERS_USER_DEFINED::getPropagationDelay( const LENGTH_D
if( itemType == LENGTH_DELAY_CALCULATION_ITEM::TYPE::LINE )
{
const double delayUnit = aDelayProfile->m_LayerPropagationDelays.at( aItem.GetStartLayer() );
double delayUnit = 0.0;
if( aDelayProfile->m_TrackPropagationEntriesMap.contains( aItem.GetStartLayer() ) )
{
const DELAY_PROFILE_TRACK_PROPAGATION_ENTRY& entry =
aDelayProfile->m_TrackPropagationEntriesMap.at( aItem.GetStartLayer() );
delayUnit = entry.GetDelay();
}
return static_cast<int64_t>( delayUnit * ( static_cast<double>( aItem.GetLine().Length() ) / PCB_IU_PER_MM ) );
}
if( itemType == LENGTH_DELAY_CALCULATION_ITEM::TYPE::VIA )
{
if( !aDelayProfile->m_EnableTimeDomainTuning )
return 0;
const PCB_LAYER_ID signalStartLayer = aItem.GetStartLayer();
const PCB_LAYER_ID signalEndLayer = aItem.GetEndLayer();
const PCB_LAYER_ID viaStartLayer = aItem.GetVia()->Padstack().StartLayer();
@@ -117,7 +128,7 @@ int64_t TIME_DOMAIN_PARAMETERS_USER_DEFINED::getPropagationDelay( const LENGTH_D
}
const DELAY_PROFILE* TIME_DOMAIN_PARAMETERS_USER_DEFINED::GetDelayProfile( const wxString& aDelayProfileName )
const TUNING_PROFILE* TUNING_PROFILE_PARAMETERS_USER_DEFINED::GetTuningProfile( const wxString& aDelayProfileName )
{
auto itr = m_delayProfilesCache.find( aDelayProfileName );
@@ -128,49 +139,61 @@ const DELAY_PROFILE* TIME_DOMAIN_PARAMETERS_USER_DEFINED::GetDelayProfile( const
}
int64_t
TIME_DOMAIN_PARAMETERS_USER_DEFINED::GetTrackLengthForPropagationDelay( int64_t aDelay,
const TIME_DOMAIN_GEOMETRY_CONTEXT& aContext )
int64_t TUNING_PROFILE_PARAMETERS_USER_DEFINED::GetTrackLengthForPropagationDelay(
int64_t aDelay, const TUNING_PROFILE_GEOMETRY_CONTEXT& aContext )
{
const wxString delayProfileName = aContext.NetClass->GetDelayProfile();
const DELAY_PROFILE* profile = GetDelayProfile( delayProfileName );
const wxString delayProfileName = aContext.NetClass->GetTuningProfile();
const TUNING_PROFILE* profile = GetTuningProfile( delayProfileName );
if( !profile )
return 0;
const double delayUnit = profile->m_LayerPropagationDelays.at( aContext.Layer ); // Time IU / MM
const double lengthInMM = static_cast<double>( aDelay ) / delayUnit; // MM
return static_cast<int64_t>( lengthInMM * PCB_IU_PER_MM ); // Length IU
double delayUnit = 0.0;
if( profile->m_TrackPropagationEntriesMap.contains( aContext.Layer ) )
{
const DELAY_PROFILE_TRACK_PROPAGATION_ENTRY& entry = profile->m_TrackPropagationEntriesMap.at( aContext.Layer );
delayUnit = entry.GetDelay();
}
const double lengthInMM = static_cast<double>( aDelay ) / delayUnit; // MM
return static_cast<int64_t>( lengthInMM * PCB_IU_PER_MM ); // Length IU
}
int64_t TIME_DOMAIN_PARAMETERS_USER_DEFINED::CalculatePropagationDelayForShapeLineChain(
const SHAPE_LINE_CHAIN& aShape, const TIME_DOMAIN_GEOMETRY_CONTEXT& aContext )
int64_t TUNING_PROFILE_PARAMETERS_USER_DEFINED::CalculatePropagationDelayForShapeLineChain(
const SHAPE_LINE_CHAIN& aShape, const TUNING_PROFILE_GEOMETRY_CONTEXT& aContext )
{
const wxString delayProfileName = aContext.NetClass->GetDelayProfile();
const DELAY_PROFILE* profile = GetDelayProfile( delayProfileName );
const wxString delayProfileName = aContext.NetClass->GetTuningProfile();
const TUNING_PROFILE* profile = GetTuningProfile( delayProfileName );
if( !profile )
return 0;
const double delayUnit = profile->m_LayerPropagationDelays.at( aContext.Layer );
double delayUnit = 0.0;
if( profile->m_TrackPropagationEntriesMap.contains( aContext.Layer ) )
{
const DELAY_PROFILE_TRACK_PROPAGATION_ENTRY& entry = profile->m_TrackPropagationEntriesMap.at( aContext.Layer );
delayUnit = entry.GetDelay();
}
return static_cast<int64_t>( delayUnit * ( static_cast<double>( aShape.Length() ) / PCB_IU_PER_MM ) );
}
void TIME_DOMAIN_PARAMETERS_USER_DEFINED::rebuildCaches()
void TUNING_PROFILE_PARAMETERS_USER_DEFINED::rebuildCaches()
{
m_delayProfilesCache.clear();
m_viaOverridesCache.clear();
if( const PROJECT* project = m_board->GetProject() )
{
TIME_DOMAIN_PARAMETERS* params = project->GetProjectFile().TimeDomainParameters().get();
TUNING_PROFILES* params = project->GetProjectFile().TuningProfileParameters().get();
for( const DELAY_PROFILE& profile : params->GetDelayProfiles() )
for( const TUNING_PROFILE& profile : params->GetTuningProfiles() )
{
m_delayProfilesCache[profile.m_ProfileName] = &profile;
std::map<VIA_OVERRIDE_CACHE_KEY, int64_t>& viaOverrides = m_viaOverridesCache[profile.m_ProfileName];
for( const DELAY_PROFILE_VIA_OVERRIDE_ENTRY& viaOverride : profile.m_ViaOverrides )
@@ -21,18 +21,18 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef PCB_NEW_TIME_DOMAIN_PARAMETERS_USER_DEFINED_H
#define PCB_NEW_TIME_DOMAIN_PARAMETERS_USER_DEFINED_H
#ifndef PCB_NEW_TUNING_PROFILE_PARAMETERS_USER_DEFINED_H
#define PCB_NEW_TUNING_PROFILE_PARAMETERS_USER_DEFINED_H
#include <length_delay_calculation/time_domain_parameters_iface.h>
#include <project/time_domain_parameters.h>
#include <length_delay_calculation/tuning_profile_parameters_iface.h>
#include <project/tuning_profiles.h>
class TIME_DOMAIN_PARAMETERS_USER_DEFINED final : public TIME_DOMAIN_PARAMETERS_IFACE
class TUNING_PROFILE_PARAMETERS_USER_DEFINED final : public TUNING_PROFILE_PARAMETERS_IFACE
{
public:
explicit TIME_DOMAIN_PARAMETERS_USER_DEFINED( BOARD* aBoard, LENGTH_DELAY_CALCULATION* aCalculation ) :
TIME_DOMAIN_PARAMETERS_IFACE( aBoard, aCalculation )
explicit TUNING_PROFILE_PARAMETERS_USER_DEFINED( BOARD* aBoard, LENGTH_DELAY_CALCULATION* aCalculation ) :
TUNING_PROFILE_PARAMETERS_IFACE( aBoard, aCalculation )
{
}
@@ -50,7 +50,7 @@ public:
* @param aContext the geometry context in which to query to propagation delay
*/
std::vector<int64_t> GetPropagationDelays( const std::vector<LENGTH_DELAY_CALCULATION_ITEM>& aItems,
const TIME_DOMAIN_GEOMETRY_CONTEXT& aContext ) override;
const TUNING_PROFILE_GEOMETRY_CONTEXT& aContext ) override;
/**
* Gets the propagation delay (in internal units) for the given item in the given geometry context
@@ -58,8 +58,8 @@ public:
* @param aItem the board item to query propagation delay for
* @param aContext the geometry context in which to query to propagation delay
*/
int64_t GetPropagationDelay( const LENGTH_DELAY_CALCULATION_ITEM& aItem,
const TIME_DOMAIN_GEOMETRY_CONTEXT& aContext ) override;
int64_t GetPropagationDelay( const LENGTH_DELAY_CALCULATION_ITEM& aItem,
const TUNING_PROFILE_GEOMETRY_CONTEXT& aContext ) override;
/**
* Gets the track length (in internal distance units) required for the given propagation delay (in internal time
@@ -68,7 +68,8 @@ public:
* @param aContext the geometry context in which to query to propagation delay
* @param aDelay the propagation delay for which a length should be calculated
*/
int64_t GetTrackLengthForPropagationDelay( int64_t aDelay, const TIME_DOMAIN_GEOMETRY_CONTEXT& aContext ) override;
int64_t GetTrackLengthForPropagationDelay( int64_t aDelay,
const TUNING_PROFILE_GEOMETRY_CONTEXT& aContext ) override;
/**
* Gets the propagation delay for the given shape line chain
@@ -76,8 +77,8 @@ public:
* @param aShape is the shape to calculate delay for
* @param aContext is the geometry context for which to query to propagation delay
*/
int64_t CalculatePropagationDelayForShapeLineChain( const SHAPE_LINE_CHAIN& aShape,
const TIME_DOMAIN_GEOMETRY_CONTEXT& aContext ) override;
int64_t CalculatePropagationDelayForShapeLineChain( const SHAPE_LINE_CHAIN& aShape,
const TUNING_PROFILE_GEOMETRY_CONTEXT& aContext ) override;
private:
void rebuildCaches();
@@ -120,9 +121,9 @@ private:
* @param aContext the geometry context in which to query to propagation delay
* @param aDelayProfile the time domain tuning profile for the given item
*/
int64_t getPropagationDelay( const LENGTH_DELAY_CALCULATION_ITEM& aItem,
const TIME_DOMAIN_GEOMETRY_CONTEXT& aContext,
const DELAY_PROFILE* aDelayProfile ) const;
int64_t getPropagationDelay( const LENGTH_DELAY_CALCULATION_ITEM& aItem,
const TUNING_PROFILE_GEOMETRY_CONTEXT& aContext,
const TUNING_PROFILE* aDelayProfile ) const;
/**
* Gets the tuning profile pointer for the given tuning profile name
@@ -130,13 +131,13 @@ private:
* @param aDelayProfileName the tuning profile name to return
* @returns Valid pointer to a tuning profile, or nullptr if no profile found
*/
const DELAY_PROFILE* GetDelayProfile( const wxString& aDelayProfileName );
const TUNING_PROFILE* GetTuningProfile( const wxString& aDelayProfileName );
/// Cached map of tuning profile names to per-layer time domain parameters
std::map<wxString, const DELAY_PROFILE*> m_delayProfilesCache;
std::map<wxString, const TUNING_PROFILE*> m_delayProfilesCache;
/// Cached per-tuning profile via overrides
std::map<wxString, std::map<VIA_OVERRIDE_CACHE_KEY, int64_t>> m_viaOverridesCache;
};
#endif //PCB_NEW_TIME_DOMAIN_PARAMETERS_USER_DEFINED_H
#endif //PCB_NEW_TUNING_PROFILE_PARAMETERS_USER_DEFINED_H
+1 -1
View File
@@ -1497,7 +1497,7 @@ void PCB_EDIT_FRAME::ShowBoardSetupDialog( const wxString& aInitialPage, wxWindo
{
// Note: We must synchronise time domain properties before nets and classes, otherwise the updates
// called by the board listener events are using stale data
GetBoard()->SynchronizeTimeDomainProperties();
GetBoard()->SynchronizeTuningProfileProperties();
GetBoard()->SynchronizeNetsAndNetClasses( true );
if( !GetBoard()->SynchronizeComponentClasses( std::unordered_set<wxString>() ) )
+2 -2
View File
@@ -2508,7 +2508,7 @@ int64_t PNS_KICAD_IFACE_BASE::CalculateLengthForDelay( int64_t aDesiredDelay, co
const bool aIsDiffPairCoupled, const int aDiffPairCouplingGap,
const int aPNSLayer, const NETCLASS* aNetClass )
{
TIME_DOMAIN_GEOMETRY_CONTEXT ctx;
TUNING_PROFILE_GEOMETRY_CONTEXT ctx;
ctx.NetClass = aNetClass;
ctx.Width = aWidth;
ctx.IsDiffPairCoupled = aIsDiffPairCoupled;
@@ -2524,7 +2524,7 @@ int64_t PNS_KICAD_IFACE_BASE::CalculateDelayForShapeLineChain( const SHAPE_LINE_
bool aIsDiffPairCoupled, int aDiffPairCouplingGap,
int aPNSLayer, const NETCLASS* aNetClass )
{
TIME_DOMAIN_GEOMETRY_CONTEXT ctx;
TUNING_PROFILE_GEOMETRY_CONTEXT ctx;
ctx.NetClass = aNetClass;
ctx.Width = aWidth;
ctx.IsDiffPairCoupled = aIsDiffPairCoupled;
+1 -1
View File
@@ -27,7 +27,7 @@
#include "pns_solid.h"
#include "pns_topology.h"
#include <length_delay_calculation/time_domain_parameters_iface.h>
#include <length_delay_calculation/tuning_profile_parameters_iface.h>
namespace PNS {
@@ -0,0 +1,131 @@
(kicad_pcb
(version 20250926)
(generator "pcbnew")
(generator_version "9.99")
(general
(thickness 1.6)
(legacy_teardrops no)
)
(paper "A4")
(layers
(0 "F.Cu" signal)
(2 "B.Cu" signal)
(9 "F.Adhes" user "F.Adhesive")
(11 "B.Adhes" user "B.Adhesive")
(13 "F.Paste" user)
(15 "B.Paste" user)
(5 "F.SilkS" user "F.Silkscreen")
(7 "B.SilkS" user "B.Silkscreen")
(1 "F.Mask" user)
(3 "B.Mask" user)
(17 "Dwgs.User" user "User.Drawings")
(19 "Cmts.User" user "User.Comments")
(21 "Eco1.User" user "User.Eco1")
(23 "Eco2.User" user "User.Eco2")
(25 "Edge.Cuts" user)
(27 "Margin" user)
(31 "F.CrtYd" user "F.Courtyard")
(29 "B.CrtYd" user "B.Courtyard")
(35 "F.Fab" user)
(33 "B.Fab" user)
(39 "User.1" user)
(41 "User.2" user)
(43 "User.3" user)
(45 "User.4" user)
)
(setup
(stackup
(layer "F.SilkS"
(type "Top Silk Screen")
)
(layer "F.Paste"
(type "Top Solder Paste")
)
(layer "F.Mask"
(type "Top Solder Mask")
(thickness 0.01)
)
(layer "F.Cu"
(type "copper")
(thickness 0.035)
)
(layer "dielectric 1"
(type "core")
(thickness 1.51)
(material "FR4")
(epsilon_r 4.5)
(loss_tangent 0.02)
)
(layer "B.Cu"
(type "copper")
(thickness 0.035)
)
(layer "B.Mask"
(type "Bottom Solder Mask")
(thickness 0.01)
)
(layer "B.Paste"
(type "Bottom Solder Paste")
)
(layer "B.SilkS"
(type "Bottom Silk Screen")
)
(copper_finish "None")
(dielectric_constraints no)
)
(pad_to_mask_clearance 0)
(allow_soldermask_bridges_in_footprints no)
(tenting
(front yes)
(back yes)
)
(covering
(front no)
(back no)
)
(plugging
(front no)
(back no)
)
(capping no)
(filling no)
(pcbplotparams
(layerselection 0x00000000_00000000_55555555_5755f5ff)
(plot_on_all_layers_selection 0x00000000_00000000_00000000_00000000)
(disableapertmacros no)
(usegerberextensions no)
(usegerberattributes yes)
(usegerberadvancedattributes yes)
(creategerberjobfile yes)
(dashed_line_dash_ratio 12)
(dashed_line_gap_ratio 3)
(svgprecision 4)
(plotframeref no)
(mode 1)
(useauxorigin no)
(pdf_front_fp_property_popups yes)
(pdf_back_fp_property_popups yes)
(pdf_metadata yes)
(pdf_single_document no)
(dxfpolygonmode yes)
(dxfimperialunits yes)
(dxfusepcbnewfont yes)
(psnegative no)
(psa4output no)
(plot_black_and_white yes)
(sketchpadsonfab no)
(plotpadnumbers no)
(hidednponfab no)
(sketchdnponfab yes)
(crossoutdnponfab yes)
(subtractmaskfromsilk no)
(outputformat 1)
(mirror no)
(drillshape 1)
(scaleselection 1)
(outputdirectory "")
)
)
(net 0 "")
(embedded_fonts no)
)
@@ -0,0 +1,335 @@
{
"board": {
"3dviewports": [],
"design_settings": {
"defaults": {
"apply_defaults_to_fp_barcodes": false,
"apply_defaults_to_fp_dimensions": false,
"apply_defaults_to_fp_fields": false,
"apply_defaults_to_fp_shapes": false,
"apply_defaults_to_fp_text": false,
"board_outline_line_width": 0.05,
"copper_line_width": 0.2,
"copper_text_italic": false,
"copper_text_size_h": 1.5,
"copper_text_size_v": 1.5,
"copper_text_thickness": 0.3,
"copper_text_upright": false,
"courtyard_line_width": 0.05,
"dimension_precision": 4,
"dimension_units": 3,
"dimensions": {
"arrow_length": 1270000,
"extension_offset": 500000,
"keep_text_aligned": true,
"suppress_zeroes": true,
"text_position": 0,
"units_format": 0
},
"fab_line_width": 0.1,
"fab_text_italic": false,
"fab_text_size_h": 1.0,
"fab_text_size_v": 1.0,
"fab_text_thickness": 0.15,
"fab_text_upright": false,
"other_line_width": 0.1,
"other_text_italic": false,
"other_text_size_h": 1.0,
"other_text_size_v": 1.0,
"other_text_thickness": 0.15,
"other_text_upright": false,
"pads": {
"drill": 0.8,
"height": 1.27,
"width": 2.54
},
"silk_line_width": 0.1,
"silk_text_italic": false,
"silk_text_size_h": 1.0,
"silk_text_size_v": 1.0,
"silk_text_thickness": 0.1,
"silk_text_upright": false,
"zones": {
"min_clearance": 0.5
}
},
"diff_pair_dimensions": [],
"drc_exclusions": [],
"meta": {
"version": 2
},
"rule_severities": {
"annular_width": "error",
"clearance": "error",
"connection_width": "warning",
"copper_edge_clearance": "error",
"copper_sliver": "warning",
"courtyards_overlap": "error",
"creepage": "error",
"diff_pair_gap_out_of_range": "error",
"diff_pair_uncoupled_length_too_long": "error",
"drill_out_of_range": "error",
"duplicate_footprints": "warning",
"extra_footprint": "warning",
"footprint": "error",
"footprint_filters_mismatch": "ignore",
"footprint_symbol_mismatch": "warning",
"footprint_type_mismatch": "ignore",
"hole_clearance": "error",
"hole_to_hole": "warning",
"holes_co_located": "warning",
"invalid_outline": "error",
"isolated_copper": "warning",
"item_on_disabled_layer": "error",
"items_not_allowed": "error",
"length_out_of_range": "error",
"lib_footprint_issues": "warning",
"lib_footprint_mismatch": "warning",
"malformed_courtyard": "error",
"microvia_drill_out_of_range": "error",
"mirrored_text_on_front_layer": "warning",
"missing_courtyard": "ignore",
"missing_footprint": "warning",
"missing_tuning_profile": "warning",
"net_conflict": "warning",
"nonmirrored_text_on_back_layer": "warning",
"npth_inside_courtyard": "ignore",
"padstack": "warning",
"pth_inside_courtyard": "ignore",
"shorting_items": "error",
"silk_edge_clearance": "warning",
"silk_over_copper": "warning",
"silk_overlap": "warning",
"skew_out_of_range": "error",
"solder_mask_bridge": "error",
"starved_thermal": "error",
"text_height": "warning",
"text_on_edge_cuts": "error",
"text_thickness": "warning",
"through_hole_pad_without_hole": "error",
"too_many_vias": "error",
"track_angle": "error",
"track_dangling": "warning",
"track_segment_length": "error",
"track_width": "error",
"tracks_crossing": "error",
"unconnected_items": "error",
"unresolved_variable": "error",
"via_dangling": "warning",
"zones_intersect": "error"
},
"rules": {
"max_error": 0.005,
"min_clearance": 0.0,
"min_connection": 0.0,
"min_copper_edge_clearance": 0.5,
"min_groove_width": 0.0,
"min_hole_clearance": 0.25,
"min_hole_to_hole": 0.25,
"min_microvia_diameter": 0.2,
"min_microvia_drill": 0.1,
"min_resolved_spokes": 2,
"min_silk_clearance": 0.0,
"min_text_height": 0.8,
"min_text_thickness": 0.08,
"min_through_hole_diameter": 0.3,
"min_track_width": 0.0,
"min_via_annular_width": 0.1,
"min_via_diameter": 0.5,
"solder_mask_to_copper_clearance": 0.0,
"use_height_for_length_calcs": true
},
"teardrop_options": [
{
"td_onpthpad": true,
"td_onroundshapesonly": false,
"td_onsmdpad": true,
"td_ontrackend": false,
"td_onvia": true
}
],
"teardrop_parameters": [
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_round_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_rect_shape",
"td_width_to_size_filter_ratio": 0.9
},
{
"td_allow_use_two_tracks": true,
"td_curve_segcount": 0,
"td_height_ratio": 1.0,
"td_length_ratio": 0.5,
"td_maxheight": 2.0,
"td_maxlen": 1.0,
"td_on_pad_in_zone": false,
"td_target_name": "td_track_end",
"td_width_to_size_filter_ratio": 0.9
}
],
"track_widths": [],
"tuning_pattern_settings": {
"diff_pair_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 1.0
},
"diff_pair_skew_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
},
"single_track_defaults": {
"corner_radius_percentage": 80,
"corner_style": 1,
"max_amplitude": 1.0,
"min_amplitude": 0.2,
"single_sided": false,
"spacing": 0.6
}
},
"via_dimensions": [],
"zones_allow_external_fillets": false
},
"ipc2581": {
"dist": "",
"distpn": "",
"internal_id": "",
"mfg": "",
"mpn": ""
},
"layer_pairs": [],
"layer_presets": [],
"viewports": []
},
"boards": [],
"component_class_settings": {
"assignments": [],
"meta": {
"version": 0
},
"sheet_component_classes": {
"enabled": false
}
},
"cvpcb": {
"equivalence_files": []
},
"libraries": {
"pinned_footprint_libs": [],
"pinned_symbol_libs": []
},
"meta": {
"filename": "drc_missing_tuning_profile.kicad_pro",
"version": 3
},
"net_settings": {
"classes": [
{
"bus_width": 12,
"clearance": 0.2,
"diff_pair_gap": 0.25,
"diff_pair_via_gap": 0.25,
"diff_pair_width": 0.2,
"line_style": 0,
"microvia_diameter": 0.3,
"microvia_drill": 0.1,
"name": "Default",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"priority": 2147483647,
"schematic_color": "rgba(0, 0, 0, 0.000)",
"track_width": 0.2,
"tuning_profile": "",
"via_diameter": 0.6,
"via_drill": 0.3,
"wire_width": 6
},
{
"name": "CLASS1",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"priority": 1,
"schematic_color": "rgba(0, 0, 0, 0.000)",
"tuning_profile": "PROFILE1"
},
{
"name": "CLASS2",
"pcb_color": "rgba(0, 0, 0, 0.000)",
"priority": 0,
"schematic_color": "rgba(0, 0, 0, 0.000)",
"tuning_profile": "PROFILE2"
}
],
"meta": {
"version": 5
},
"net_colors": null,
"netclass_assignments": null,
"netclass_patterns": []
},
"pcbnew": {
"last_paths": {
"idf": "",
"netlist": "",
"plot": "",
"specctra_dsn": "",
"vrml": ""
},
"page_layout_descr_file": ""
},
"schematic": {
"bus_aliases": {},
"legacy_lib_dir": "",
"legacy_lib_list": []
},
"sheets": [],
"text_variables": {},
"tuning_profiles": {
"meta": {
"version": 0
},
"tuning_profiles_impedance_geometric": [
{
"enable_time_domain_tuning": false,
"generate_drc_rules": true,
"layer_entries": [],
"profile_name": "PROFILE1",
"target_impedance": 0.0,
"type": 0,
"via_overrides": [],
"via_prop_delay": 0
},
{
"enable_time_domain_tuning": false,
"generate_drc_rules": true,
"layer_entries": [],
"profile_name": "PROFILE2_RENAME",
"target_impedance": 0.0,
"type": 0,
"via_overrides": [],
"via_prop_delay": 0
}
]
}
}
@@ -0,0 +1,14 @@
(kicad_sch
(version 20250922)
(generator "eeschema")
(generator_version "9.99")
(uuid 834b6ea0-3699-46bc-922e-4fa7e8a4a2a9)
(paper "A4")
(lib_symbols)
(sheet_instances
(path "/"
(page "1")
)
)
(embedded_fonts no)
)
+1 -1
View File
@@ -1,5 +1,5 @@
(kicad_pcb
(version 20250801)
(version 20250926)
(generator "pcbnew")
(generator_version "9.99")
(general
+334
View File
@@ -3,6 +3,8 @@
"3dviewports": [],
"design_settings": {
"defaults": {
"apply_defaults_to_fp_barcodes": false,
"apply_defaults_to_fp_dimensions": false,
"apply_defaults_to_fp_fields": false,
"apply_defaults_to_fp_shapes": false,
"apply_defaults_to_fp_text": false,
@@ -664,6 +666,7 @@
"sort_asc": true,
"sort_field": "Reference"
},
"bus_aliases": {},
"connection_grid_size": 50.0,
"drawing": {
"dashed_lines_dash_length_ratio": 12.0,
@@ -927,5 +930,336 @@
"via_layer_to": "In2.Cu"
}
]
},
"tuning_profiles": {
"meta": {
"version": 0
},
"tuning_profiles_impedance_geometric": [
{
"enable_time_domain_tuning": true,
"generate_drc_rules": false,
"layer_entries": [
{
"bottom_reference_layer": "UNDEFINED",
"delay": 1000000,
"diff_pair_gap": 0,
"signal_layer": "F.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 0,
"diff_pair_gap": 0,
"signal_layer": "In1.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 0,
"diff_pair_gap": 0,
"signal_layer": "In2.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 0,
"diff_pair_gap": 0,
"signal_layer": "B.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
}
],
"profile_name": "CLASS1",
"target_impedance": 0.0,
"type": 0,
"via_overrides": [],
"via_prop_delay": 0
},
{
"enable_time_domain_tuning": true,
"generate_drc_rules": false,
"layer_entries": [
{
"bottom_reference_layer": "UNDEFINED",
"delay": 1000000,
"diff_pair_gap": 0,
"signal_layer": "F.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 0,
"diff_pair_gap": 0,
"signal_layer": "In1.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 0,
"diff_pair_gap": 0,
"signal_layer": "In2.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 0,
"diff_pair_gap": 0,
"signal_layer": "B.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
}
],
"profile_name": "CLASS2",
"target_impedance": 0.0,
"type": 0,
"via_overrides": [],
"via_prop_delay": 0
},
{
"enable_time_domain_tuning": true,
"generate_drc_rules": false,
"layer_entries": [
{
"bottom_reference_layer": "UNDEFINED",
"delay": 1000000,
"diff_pair_gap": 0,
"signal_layer": "F.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 1000000,
"diff_pair_gap": 0,
"signal_layer": "In1.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 1000000,
"diff_pair_gap": 0,
"signal_layer": "In2.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 2000000,
"diff_pair_gap": 0,
"signal_layer": "B.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
}
],
"profile_name": "CLASS3",
"target_impedance": 0.0,
"type": 0,
"via_overrides": [],
"via_prop_delay": 0
},
{
"enable_time_domain_tuning": true,
"generate_drc_rules": false,
"layer_entries": [
{
"bottom_reference_layer": "UNDEFINED",
"delay": 1000000,
"diff_pair_gap": 0,
"signal_layer": "F.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 0,
"diff_pair_gap": 0,
"signal_layer": "In1.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 0,
"diff_pair_gap": 0,
"signal_layer": "In2.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 1000000,
"diff_pair_gap": 0,
"signal_layer": "B.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
}
],
"profile_name": "CLASS4",
"target_impedance": 0.0,
"type": 0,
"via_overrides": [],
"via_prop_delay": 1000000
},
{
"enable_time_domain_tuning": true,
"generate_drc_rules": false,
"layer_entries": [
{
"bottom_reference_layer": "UNDEFINED",
"delay": 1000000,
"diff_pair_gap": 0,
"signal_layer": "F.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 0,
"diff_pair_gap": 0,
"signal_layer": "In1.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 0,
"diff_pair_gap": 0,
"signal_layer": "In2.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 1000000,
"diff_pair_gap": 0,
"signal_layer": "B.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
}
],
"profile_name": "CLASS5",
"target_impedance": 0.0,
"type": 0,
"via_overrides": [
{
"delay": 20000000,
"signal_layer_from": "F.Cu",
"signal_layer_to": "B.Cu",
"via_layer_from": "F.Cu",
"via_layer_to": "B.Cu"
}
],
"via_prop_delay": 0
},
{
"enable_time_domain_tuning": true,
"generate_drc_rules": false,
"layer_entries": [
{
"bottom_reference_layer": "UNDEFINED",
"delay": 1000000,
"diff_pair_gap": 0,
"signal_layer": "F.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 2000000,
"diff_pair_gap": 0,
"signal_layer": "In1.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 0,
"diff_pair_gap": 0,
"signal_layer": "In2.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 0,
"diff_pair_gap": 0,
"signal_layer": "B.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
}
],
"profile_name": "CLASS6",
"target_impedance": 0.0,
"type": 0,
"via_overrides": [
{
"delay": 10000000,
"signal_layer_from": "F.Cu",
"signal_layer_to": "In1.Cu",
"via_layer_from": "F.Cu",
"via_layer_to": "In1.Cu"
},
{
"delay": 20000000,
"signal_layer_from": "F.Cu",
"signal_layer_to": "In1.Cu",
"via_layer_from": "F.Cu",
"via_layer_to": "In2.Cu"
}
],
"via_prop_delay": 0
},
{
"enable_time_domain_tuning": true,
"generate_drc_rules": false,
"layer_entries": [
{
"bottom_reference_layer": "UNDEFINED",
"delay": 1000000,
"diff_pair_gap": 0,
"signal_layer": "F.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 0,
"diff_pair_gap": 0,
"signal_layer": "In1.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 0,
"diff_pair_gap": 0,
"signal_layer": "In2.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
},
{
"bottom_reference_layer": "UNDEFINED",
"delay": 0,
"diff_pair_gap": 0,
"signal_layer": "B.Cu",
"top_reference_layer": "UNDEFINED",
"width": 0
}
],
"profile_name": "CLASS7",
"target_impedance": 0.0,
"type": 0,
"via_overrides": [],
"via_prop_delay": 0
}
]
}
}
+2 -2
View File
@@ -147,10 +147,10 @@ void LoadBoard( SETTINGS_MANAGER& aSettingsManager, const wxString& aRelPath,
return;
}
BOOST_TEST_CHECKPOINT( "Synchronize Time Domain Properties" );
BOOST_TEST_CHECKPOINT( "Synchronize Tuning Profile Properties" );
try
{
aBoard->GetLengthCalculation()->SynchronizeTimeDomainProperties();
aBoard->GetLengthCalculation()->SynchronizeTuningProfileProperties();
}
catch( const std::exception& e )
{
+1
View File
@@ -77,6 +77,7 @@ set( QA_PCBNEW_SRCS
drc/test_drc_lengths.cpp
drc/test_drc_unconnected_items_exclusion_loss.cpp
drc/test_drc_via_dangling.cpp
drc/test_drc_tuning_profiles.cpp
pcb_io/altium/test_altium_rule_transformer.cpp
pcb_io/altium/test_altium_pcblib_import.cpp
@@ -0,0 +1,96 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* 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 program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <qa_utils/wx_utils/unit_test_utils.h>
#include <pcbnew_utils/board_test_utils.h>
#include <board.h>
#include <board_design_settings.h>
#include <drc/drc_item.h>
#include <settings/settings_manager.h>
struct DRC_REGRESSION_TEST_FIXTURE
{
DRC_REGRESSION_TEST_FIXTURE() :
m_settingsManager( true /* headless */ )
{
}
SETTINGS_MANAGER m_settingsManager;
std::unique_ptr<BOARD> m_board;
};
BOOST_FIXTURE_TEST_CASE( DRCTuningProfiles, DRC_REGRESSION_TEST_FIXTURE )
{
std::vector<std::pair<wxString, int>> tests = { { "drc_missing_tuning_profile", 2 } };
for( const std::pair<wxString, int>& test : tests )
{
KI_TEST::LoadBoard( m_settingsManager, test.first, m_board );
KI_TEST::FillZones( m_board.get() );
std::vector<DRC_ITEM> violations;
BOARD_DESIGN_SETTINGS& bds = m_board->GetDesignSettings();
// These DRC tests are not useful and do not work because they need a footprint library
// associated to the board
bds.m_DRCSeverities[DRCE_LIB_FOOTPRINT_ISSUES] = SEVERITY::RPT_SEVERITY_IGNORE;
bds.m_DRCSeverities[DRCE_LIB_FOOTPRINT_MISMATCH] = SEVERITY::RPT_SEVERITY_IGNORE;
bds.m_DRCSeverities[DRCE_DANGLING_VIA] = SEVERITY::RPT_SEVERITY_IGNORE;
// Ensure that our desired error is fired
bds.m_DRCSeverities[DRCE_MISSING_TUNING_PROFILE] = SEVERITY::RPT_SEVERITY_ERROR;
bds.m_DRCEngine->SetViolationHandler(
[&]( const std::shared_ptr<DRC_ITEM>& aItem, const VECTOR2I& aPos, int aLayer,
const std::function<void( PCB_MARKER* )>& aPathGenerator )
{
if( bds.GetSeverity( aItem->GetErrorCode() ) == SEVERITY::RPT_SEVERITY_ERROR )
violations.push_back( *aItem );
} );
bds.m_DRCEngine->RunTests( EDA_UNITS::MM, true, false );
if( violations.size() == test.second )
{
BOOST_CHECK_EQUAL( 1, 1 ); // quiet "did not check any assertions" warning
BOOST_TEST_MESSAGE( wxString::Format( "DRC missing tuning profile: %s, passed", test.first ) );
}
else
{
UNITS_PROVIDER unitsProvider( pcbIUScale, EDA_UNITS::INCH );
std::map<KIID, EDA_ITEM*> itemMap;
m_board->FillItemMap( itemMap );
for( const DRC_ITEM& item : violations )
{
BOOST_TEST_MESSAGE( item.ShowReport( &unitsProvider, RPT_SEVERITY_ERROR, itemMap ) );
}
BOOST_ERROR( wxString::Format( "DRC missing tuning profile: %s, failed (violations found %d expected %d)",
test.first, (int) violations.size(), test.second ) );
}
}
}
+2 -2
View File
@@ -194,7 +194,7 @@ public:
const int aDiffPairCouplingGap, const int aPNSLayer,
const NETCLASS* aNetClass ) override
{
TIME_DOMAIN_GEOMETRY_CONTEXT ctx;
TUNING_PROFILE_GEOMETRY_CONTEXT ctx;
ctx.NetClass = aNetClass;
ctx.Width = aWidth;
ctx.IsDiffPairCoupled = aIsDiffPairCoupled;
@@ -208,7 +208,7 @@ public:
int aDiffPairCouplingGap, int aPNSLayer,
const NETCLASS* aNetClass ) override
{
TIME_DOMAIN_GEOMETRY_CONTEXT ctx;
TUNING_PROFILE_GEOMETRY_CONTEXT ctx;
ctx.NetClass = aNetClass;
ctx.Width = aWidth;
ctx.IsDiffPairCoupled = aIsDiffPairCoupled;