74 virtual bool Run()
override;
76 virtual const wxString
GetName()
const override {
return wxT(
"microvia_stack" ); };
80 void checkColumn(
const std::vector<PCB_VIA*>& aColumn );
88 std::vector<PCB_VIA*> vias;
97 vias.push_back(
via );
112 drcItem->SetItems( aStack );
117 std::map<int, int> layerToIndex;
121 layerToIndex[layer] = spanLen++;
123 std::set<int> covered;
128 auto top = layerToIndex.find(
via->TopLayer() );
129 auto bot = layerToIndex.find(
via->BottomLayer() );
131 if(
top == layerToIndex.end() || bot == layerToIndex.end() ||
std::abs(
top->second - bot->second ) != 1 )
137 covered.insert( std::min(
top->second, bot->second ) );
140 if( broken || (
int) covered.size() != spanLen - 1 )
143 drcItem->SetItems( aStack );
163 drcItem->SetErrorMessage( wxString::Format(
_(
"Stack is %d hops deep, limit is %d" ), (
int) aColumn.size(),
165 drcItem->SetItems(
top );
166 drcItem->SetViolatingRule( depthConstraint.
GetParentRule() );
176 bool boardFillsVias =
m_drcEngine->GetBoard()->GetDesignSettings().m_FillVias;
180 if( !
via->Padstack().Drill().is_filled.value_or( boardFillsVias ) )
183 drcItem->SetItems(
via );
194 const int progressDelta = 250;
197 for(
const std::vector<PCB_VIA*>& column : columns )
216 if( !checkRatio && !checkCore )
221 const int progressDelta = 500;
241 for(
int i = 0; i < (int) stack.size(); ++i )
248 if( layer ==
via->TopLayer() || layer ==
via->BottomLayer() )
257 if( first < 0 || last < 0 )
262 bool crossesCore =
false;
264 for(
int i = first + 1; i < last; ++i )
270 for(
int sub = 0; sub < stack[i]->GetSublayersCount(); ++sub )
271 thickness += stack[i]->GetThickness( sub );
273 if( stack[i]->GetTypeName() ==
KEY_CORE )
276 if( dielectric.IsEmpty() )
277 dielectric = stack[i]->GetTypeName();
282 if( crossesCore && checkCore )
286 drcItem->SetErrorMessage(
287 wxString::Format(
_(
"The stackup gives the dielectric between %s and %s as core" ),
289 drcItem->SetItems(
via );
293 if( !checkRatio || thickness <= 0 )
303 double limit = ratioConstraint.
GetValue().
Max() / 1000.0;
313 thickness += stack[fromBack ? last : first]->GetThickness();
315 double ratio = (double) thickness / (
double)
via->GetDrillValue();
331 drcItem->SetErrorMessage(
332 wxString::Format(
_(
"Crosses %s dielectric: aspect ratio %.2f exceeds the %.2f limit" ),
333 dielectric.IsEmpty() ?
_(
"an unnamed" ) : dielectric, ratio, limit ) );
335 drcItem->SetItems(
via );
336 drcItem->SetViolatingRule( ratioConstraint.
GetParentRule() );
353 if( !
reportPhase(
_(
"Checking microvia stacks..." ) ) )
@ BS_ITEM_TYPE_DIELECTRIC
Container for design settings for a BOARD object.
BOARD_STACKUP & GetStackupDescriptor()
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
const std::vector< BOARD_STACKUP_ITEM * > & GetList() const
Information pertinent to a Pcbnew printed circuit board.
const GENERATORS & Generators() const
int GetCopperLayerCount() const
const TRACKS & Tracks() const
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
const MINOPTMAX< int > & GetValue() const
DRC_RULE * GetParentRule() const
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
DRC_TEST_PROVIDER_VIA_STACK()
virtual const wxString GetName() const override
virtual ~DRC_TEST_PROVIDER_VIA_STACK()=default
void checkAspectRatio(BOARD *aBoard)
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
void checkColumn(const std::vector< PCB_VIA * > &aColumn)
void checkSpan(PCB_VIA_STACK *aStack, int aCopperLayers)
void checkLooseMicrovias(BOARD *aBoard)
virtual bool reportPhase(const wxString &aStageName)
void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer, const std::function< void(PCB_MARKER *)> &aPathGenerator=[](PCB_MARKER *){})
virtual bool reportProgress(size_t aCount, size_t aSize, size_t aDelta=1)
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
VECTOR2I GetPosition() const override
std::unordered_set< BOARD_ITEM * > GetBoardItems() const
A microvia stack: several single hop microvias, plus connecting traces for staggered stacks,...
PCB_LAYER_ID GetStartLayer() const
PCB_LAYER_ID GetEndLayer() const
static bool IsSpanValid(BOARD *aBoard, PCB_LAYER_ID aStart, PCB_LAYER_ID aEnd)
True when both span ends are copper layers within the board's copper layer count.
static std::vector< std::vector< PCB_VIA * > > CollectMicroviaColumns(BOARD *aBoard)
Runs of microvias that land on one another, each ordered from its outermost hop down.
@ DRCE_MICROVIA_STACK_DEPTH
@ DRCE_MICROVIA_CROSSES_CORE
@ DRCE_MALFORMED_MICROVIA_STACK_SPAN
@ DRCE_MICROVIA_ASPECT_RATIO
@ DRCE_MICROVIA_STACK_NOT_FILLED
@ MICROVIA_ASPECT_RATIO_CONSTRAINT
@ MICROVIA_STACK_DEPTH_CONSTRAINT
bool IsExternalCopperLayer(int aLayerId)
Test whether a layer is an external (F_Cu or B_Cu) copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
static DRC_REGISTER_TEST_PROVIDER< DRC_TEST_PROVIDER_ANNULAR_WIDTH > dummy
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
KIBIS top(path, &reporter)
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)