@@ -630,6 +630,78 @@ TEST_P(Lef58AreaFixture, lef58_area)
630630
631631INSTANTIATE_TEST_SUITE_P (Lef58AreaSuite, Lef58AreaFixture, testing::Bool());
632632
633+ // Check the LEF58 area EXCEPTRECTANGLE option: the rule is ignored for a
634+ // single-rectangle shape but still applies to a non-rectangular one. The
635+ // required area is set high so both shapes are below it; only the shape
636+ // decides whether a marker is produced.
637+ using Lef58AreaExceptRectFixture = FixtureWithParam<bool >;
638+
639+ TEST_P (Lef58AreaExceptRectFixture, lef58_area_except_rectangle)
640+ {
641+ const bool rectangular = GetParam ();
642+ makeLef58AreaConstraint (
643+ 2 , /* area */ 100000 , /* rect_width */ -1 , /* except_rectangle */ true );
644+
645+ frNet* n1 = makeNet (" n1" );
646+
647+ makePathseg (n1, 2 , {0 , 100 }, {200 , 100 });
648+ if (!rectangular) {
649+ // Add a stem to turn the wire into a (non-rectangular) T-shape.
650+ makePathseg (n1, 2 , {100 , 50 }, {100 , 300 });
651+ }
652+
653+ runGC ();
654+
655+ // Test the results
656+ auto & markers = worker.getMarkers ();
657+ if (rectangular) {
658+ EXPECT_EQ (markers.size (), 0 );
659+ } else {
660+ EXPECT_EQ (markers.size (), 1 );
661+ testMarker (markers[0 ].get (),
662+ 2 ,
663+ frConstraintTypeEnum::frcLef58AreaConstraint,
664+ odb::Rect (0 , 50 , 200 , 300 ));
665+ }
666+ }
667+
668+ INSTANTIATE_TEST_SUITE_P (Lef58AreaExceptRectSuite,
669+ Lef58AreaExceptRectFixture,
670+ testing::Bool ());
671+
672+ // Same rectangle below the required area, varying only EXCEPTRECTANGLE: with
673+ // it set the rectangle is excepted (no marker); without it the rule applies.
674+ using Lef58AreaExceptRectRectFixture = FixtureWithParam<bool >;
675+
676+ TEST_P (Lef58AreaExceptRectRectFixture, lef58_area_except_rectangle_rect)
677+ {
678+ const bool except_rectangle = GetParam ();
679+ makeLef58AreaConstraint (
680+ 2 , /* area */ 30000 , /* rect_width */ -1 , except_rectangle);
681+
682+ frNet* n1 = makeNet (" n1" );
683+
684+ makePathseg (n1, 2 , {0 , 100 }, {200 , 100 }); // rectangle, area 20000
685+
686+ runGC ();
687+
688+ // Test the results
689+ auto & markers = worker.getMarkers ();
690+ if (except_rectangle) {
691+ EXPECT_EQ (markers.size (), 0 );
692+ } else {
693+ EXPECT_EQ (markers.size (), 1 );
694+ testMarker (markers[0 ].get (),
695+ 2 ,
696+ frConstraintTypeEnum::frcLef58AreaConstraint,
697+ odb::Rect (0 , 50 , 200 , 150 ));
698+ }
699+ }
700+
701+ INSTANTIATE_TEST_SUITE_P (Lef58AreaExceptRectRectSuite,
702+ Lef58AreaExceptRectRectFixture,
703+ testing::Bool ());
704+
633705// Check for a spacing table influence violation.
634706TEST_F (GCFixture, spacing_table_infl_vertical)
635707{
0 commit comments