Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/gui/src/displayControls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2124,8 +2124,10 @@ void DisplayControls::techInit(odb::dbTech* tech)
std::mt19937 gen_color(1);

auto generate_next_color = [&gen_color]() -> QColor {
return QColor(
50 + gen_color() % 200, 50 + gen_color() % 200, 50 + gen_color() % 200);
const int blue = 50 + gen_color() % 200;
const int green = 50 + gen_color() % 200;
const int red = 50 + gen_color() % 200;
return QColor(red, green, blue);
};

// Iterate through the layers and set default colors
Expand Down
9 changes: 6 additions & 3 deletions src/web/src/tile_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -939,9 +939,12 @@ static odb::PtrMap<odb::dbTechLayer, Color> buildLayerColorMap(

std::mt19937 rng(1);
auto random_color = [&rng]() {
return Color{.r = static_cast<unsigned char>(50 + rng() % 200),
.g = static_cast<unsigned char>(50 + rng() % 200),
.b = static_cast<unsigned char>(50 + rng() % 200),
const int blue = 50 + rng() % 200;
const int green = 50 + rng() % 200;
const int red = 50 + rng() % 200;
return Color{.r = static_cast<unsigned char>(red),
.g = static_cast<unsigned char>(green),
.b = static_cast<unsigned char>(blue),
.a = 180};
};

Expand Down
144 changes: 100 additions & 44 deletions src/web/test/cpp/TestTileGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,55 +183,111 @@ TEST_F(TileGeneratorTest, GetLayers)
}

// Layer colors must mirror gui::DisplayControls::techInit so the GUI and the
// web frontend show the same color for the same layer. Spot-check the first
// few entries of each palette and exercise the type-based assignment rules.
// web frontend show the same color for the same layer. Nangate45 only has 10
// routing + 9 cut layers, all within the 14-entry built-in palettes, so we
// extend the tech to 20 routing + 19 cut layers to also exercise the overflow
// path: layers past the palette get deterministic mt19937(1)-seeded random
// colors. The expected RGB values below were computed by replaying the exact
// blue/green/red draw order (matching gui::DisplayControls::techInit) over the
// full getLayers() iteration, including the MASTERSLICE/OVERLAP layers that
// also consume random draws.
TEST_F(TileGeneratorTest, GetLayerColorMapMatchesGuiPalette)
{
makeTileGen();
const auto& colors = tile_gen_->getLayerColorMap();

odb::dbTech* tech = getDb()->getTech();
ASSERT_NE(tech, nullptr);

odb::dbTechLayer* metal1 = tech->findLayer("metal1");
odb::dbTechLayer* metal2 = tech->findLayer("metal2");
odb::dbTechLayer* metal3 = tech->findLayer("metal3");
odb::dbTechLayer* via1 = tech->findLayer("via1");
odb::dbTechLayer* via2 = tech->findLayer("via2");
ASSERT_NE(metal1, nullptr);
ASSERT_NE(metal2, nullptr);
ASSERT_NE(metal3, nullptr);
ASSERT_NE(via1, nullptr);
ASSERT_NE(via2, nullptr);

// First three metals match the GUI's seeded #00F, #F00, #0D0 entries.
const Color m1 = colors.at(metal1);
EXPECT_EQ(m1.r, 0);
EXPECT_EQ(m1.g, 0);
EXPECT_EQ(m1.b, 254);
EXPECT_EQ(m1.a, 180);

const Color m2 = colors.at(metal2);
EXPECT_EQ(m2.r, 254);
EXPECT_EQ(m2.g, 0);
EXPECT_EQ(m2.b, 0);

const Color m3 = colors.at(metal3);
EXPECT_EQ(m3.r, 9);
EXPECT_EQ(m3.g, 221);
EXPECT_EQ(m3.b, 0);

// First two cuts match the GUI's cut palette (light blue, light red).
const Color v1 = colors.at(via1);
EXPECT_EQ(v1.r, 126);
EXPECT_EQ(v1.g, 126);
EXPECT_EQ(v1.b, 255);
EXPECT_EQ(v1.a, 180);

const Color v2 = colors.at(via2);
EXPECT_EQ(v2.r, 255);
EXPECT_EQ(v2.g, 126);
EXPECT_EQ(v2.b, 126);
// Grow the stack to 20 routing + 19 cut layers (metal11..metal20 +
// via10..via19), created interleaved (metalN, via(N-1)) just like a real
// LEF, so getLayers() yields them in that order.
for (int i = 11; i <= 20; ++i) {
odb::dbTechLayer::create(tech,
("metal" + std::to_string(i)).c_str(),
odb::dbTechLayerType::ROUTING);
odb::dbTechLayer::create(tech,
("via" + std::to_string(i - 1)).c_str(),
odb::dbTechLayerType::CUT);
}

makeTileGen();
const auto& colors = tile_gen_->getLayerColorMap();

// Helper: assert a layer's color matches an expected RGB (alpha is always
// 180 in both the GUI and the web palette).
auto expectColor = [&](const char* name, int r, int g, int b) {
odb::dbTechLayer* layer = tech->findLayer(name);
ASSERT_NE(layer, nullptr) << "missing layer " << name;
const Color c = colors.at(layer);
EXPECT_EQ(c.r, r) << name << " red";
EXPECT_EQ(c.g, g) << name << " green";
EXPECT_EQ(c.b, b) << name << " blue";
EXPECT_EQ(c.a, 180) << name << " alpha";
};

struct LayerColor
{
const char* name;
int r;
int g;
int b;
};

// All 20 routing layers: metal1..metal14 are the seeded kMetalColors palette
// (#00F, #F00, #0D0, ...), metal15..metal20 are the mt19937(1) overflow.
const LayerColor kRouting[] = {
{"metal1", 0, 0, 254},
{"metal2", 254, 0, 0},
{"metal3", 9, 221, 0},
{"metal4", 190, 244, 81},
{"metal5", 222, 33, 96},
{"metal6", 32, 216, 253},
{"metal7", 253, 108, 160},
{"metal8", 117, 63, 194},
{"metal9", 128, 155, 49},
{"metal10", 234, 63, 252},
{"metal11", 9, 96, 19},
{"metal12", 214, 120, 239},
{"metal13", 192, 222, 164},
{"metal14", 110, 68, 107},
// Overflow (random_color past the 14-entry palette).
{"metal15", 99, 98, 82},
{"metal16", 63, 193, 166},
{"metal17", 200, 166, 92},
{"metal18", 124, 126, 173},
{"metal19", 137, 246, 68},
{"metal20", 242, 216, 153},
};

// All 19 cut layers: via1..via14 are the seeded kCutColors palette,
// via15..via19 are the mt19937(1) overflow.
const LayerColor kCut[] = {
{"via1", 126, 126, 255},
{"via2", 255, 126, 126},
{"via3", 4, 110, 0},
{"via4", 95, 122, 40},
{"via5", 111, 17, 48},
{"via6", 16, 108, 126},
{"via7", 126, 54, 80},
{"via8", 58, 32, 97},
{"via9", 225, 255, 136},
{"via10", 117, 32, 126},
{"via11", 18, 192, 38},
{"via12", 107, 60, 119},
{"via13", 96, 111, 82},
{"via14", 220, 136, 214},
// Overflow (random_color past the 14-entry palette).
{"via15", 171, 152, 190},
{"via16", 54, 196, 143},
{"via17", 104, 79, 102},
{"via18", 123, 187, 153},
{"via19", 179, 175, 160},
};

for (const LayerColor& lc : kRouting) {
expectColor(lc.name, lc.r, lc.g, lc.b);
}
for (const LayerColor& lc : kCut) {
expectColor(lc.name, lc.r, lc.g, lc.b);
}
}

TEST_F(TileGeneratorTest, GetLayerColorMapIsCached)
Expand Down
Loading