Skip to content

Commit ca7d44f

Browse files
3D Viewer in the GUI
Signed-off-by: Jorge Ferreira <jorge.ferreira@precisioninno.com>
1 parent e52456e commit ca7d44f

9 files changed

Lines changed: 128 additions & 85 deletions

File tree

src/OpenRoad.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,15 +139,15 @@ OpenRoad::~OpenRoad()
139139
delete finale_;
140140
delete ram_gen_;
141141
delete antenna_checker_;
142+
delete web_server_;
143+
odb::dbDatabase::destroy(db_);
142144
delete partitionMgr_;
143145
delete pdngen_;
144146
delete icewall_;
145147
delete distributer_;
146148
delete stt_builder_;
147149
delete dft_;
148150
delete estimate_parasitics_;
149-
delete web_server_;
150-
odb::dbDatabase::destroy(db_);
151151
delete logger_;
152152
delete verilog_reader_;
153153
delete callback_handler_;

src/web/BUILD

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ cc_library(
1919
srcs = [
2020
"src/clock_tree_report.cpp",
2121
"src/clock_tree_report.h",
22-
"src/drc_report.cpp",
23-
"src/drc_report.h",
2422
"src/color.cpp",
2523
"src/color.h",
24+
"src/drc_report.cpp",
25+
"src/drc_report.h",
2626
"src/hierarchy_report.cpp",
2727
"src/hierarchy_report.h",
2828
"src/json_builder.h",

src/web/src/drc_report.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "drc_report.h"
55

66
#include <string>
7+
#include <utility>
78
#include <variant>
89
#include <vector>
910

@@ -47,7 +48,8 @@ void DRCReport::collectViolations(odb::dbMarkerCategory* category,
4748
}
4849

4950
// Ensure at least one shape for rendering
50-
if (v.rects.empty() && v.polys.empty() && v.cuboids.empty() && !v.bbox.isInverted()) {
51+
if (v.rects.empty() && v.polys.empty() && v.cuboids.empty()
52+
&& !v.bbox.isInverted()) {
5153
v.rects.push_back(v.bbox);
5254
}
5355

src/web/src/drc_report.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ class TileGenerator;
1818

1919
struct DRCViolation
2020
{
21-
int index = 0; // flat global index (for highlight lookup)
22-
std::string rule; // sub-category / marker rule name
23-
std::string layer; // tech layer name (empty if none)
24-
odb::Rect bbox; // bounding box in DBU (for zoom)
21+
int index = 0; // flat global index (for highlight lookup)
22+
std::string rule; // sub-category / marker rule name
23+
std::string layer; // tech layer name (empty if none)
24+
odb::Rect bbox; // bounding box in DBU (for zoom)
2525
std::string comment;
2626
bool is_visited = false;
27-
std::vector<odb::Rect> rects; // shape rects for highlight rendering
28-
std::vector<odb::Polygon> polys; // shape polys for highlight rendering
29-
std::vector<odb::Cuboid> cuboids; // shape cuboids for 3D highlight rendering
27+
std::vector<odb::Rect> rects; // shape rects for highlight rendering
28+
std::vector<odb::Polygon> polys; // shape polys for highlight rendering
29+
std::vector<odb::Cuboid> cuboids; // shape cuboids for 3D highlight rendering
3030
};
3131

3232
struct DRCCategoryResult

src/web/src/request_handler.cpp

Lines changed: 60 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <cstdint>
1111
#include <exception>
1212
#include <filesystem>
13+
#include <functional>
1314
#include <map>
1415
#include <memory>
1516
#include <mutex>
@@ -26,12 +27,12 @@
2627
#include "clock_tree_report.h"
2728
#include "color.h"
2829
#include "drc_report.h"
29-
#include "odb/3dblox.h"
3030
#include "gui/descriptor_registry.h"
3131
#include "gui/gui.h"
3232
#include "gui/heatMap.h"
3333
#include "hierarchy_report.h"
3434
#include "json_builder.h"
35+
#include "odb/3dblox.h"
3536
#include "odb/db.h"
3637
#include "odb/dbTransform.h"
3738
#include "odb/dbTypes.h"
@@ -192,7 +193,8 @@ int extract_int(const std::string& json, const std::string& key)
192193
pos++;
193194
}
194195
int result = 0;
195-
auto [p, ec] = std::from_chars(json.data() + pos, json.data() + json.size(), result);
196+
auto [p, ec]
197+
= std::from_chars(json.data() + pos, json.data() + json.size(), result);
196198
if (ec == std::errc()) {
197199
return result;
198200
}
@@ -228,8 +230,8 @@ float extract_float_or(const std::string& json,
228230
pos++;
229231
}
230232
float result = default_val;
231-
auto [p, ec] = std::from_chars(
232-
json.data() + pos, json.data() + json.size(), result);
233+
auto [p, ec]
234+
= std::from_chars(json.data() + pos, json.data() + json.size(), result);
233235
if (ec == std::errc()) {
234236
return result;
235237
}
@@ -396,8 +398,8 @@ static double extract_double_value(const std::string& json)
396398
pos++;
397399
}
398400
double result = 0.0;
399-
auto [p, ec] = std::from_chars(
400-
json.data() + pos, json.data() + json.size(), result);
401+
auto [p, ec]
402+
= std::from_chars(json.data() + pos, json.data() + json.size(), result);
401403
if (ec == std::errc()) {
402404
return result;
403405
}
@@ -586,7 +588,8 @@ WebSocketResponse dispatch_request(
586588
}
587589
case WebSocketRequest::TECH: {
588590
bool has_block = gen.getBlock() != nullptr;
589-
bool has_chip_insts = gen.getChip() != nullptr && !gen.getChip()->getChipInsts().empty();
591+
bool has_chip_insts
592+
= gen.getChip() != nullptr && !gen.getChip()->getChipInsts().empty();
590593
if (!has_block && !has_chip_insts) {
591594
resp.type = 2;
592595
const std::string err = "No block or chip with instances is loaded.";
@@ -599,14 +602,14 @@ WebSocketResponse dispatch_request(
599602
builder.beginArray("layers");
600603
{
601604
static const int palette[][3] = {
602-
{ 70, 130, 210}, // moderate blue
603-
{200, 50, 50}, // red
604-
{ 50, 180, 80}, // green
605-
{200, 160, 40}, // amber
606-
{160, 60, 200}, // purple
607-
{ 40, 190, 190}, // teal
608-
{220, 120, 50}, // orange
609-
{180, 70, 150}, // magenta
605+
{70, 130, 210}, // moderate blue
606+
{200, 50, 50}, // red
607+
{50, 180, 80}, // green
608+
{200, 160, 40}, // amber
609+
{160, 60, 200}, // purple
610+
{40, 190, 190}, // teal
611+
{220, 120, 50}, // orange
612+
{180, 70, 150}, // magenta
610613
};
611614
static constexpr int palette_size = 8;
612615
int idx = 0;
@@ -1288,12 +1291,22 @@ WebSocketResponse SelectHandler::handleGet3DData(const WebSocketRequest& req)
12881291
builder.beginObject();
12891292
builder.beginArray("chiplets");
12901293

1291-
auto processInst = [&](auto& self, odb::dbChipInst* inst, int offset_x, int offset_y, int offset_z, const std::string& parent_name) -> void {
1294+
auto processInst = [&](auto& self,
1295+
odb::dbChipInst* inst,
1296+
int offset_x,
1297+
int offset_y,
1298+
int offset_z,
1299+
const std::string& parent_name) -> void {
12921300
odb::dbChip* master_chip = inst->getMasterChip();
12931301
if (master_chip && !master_chip->getChipInsts().empty()) {
12941302
for (odb::dbChipInst* child : master_chip->getChipInsts()) {
12951303
odb::Point3D loc = inst->getLoc();
1296-
self(self, child, offset_x + loc.x(), offset_y + loc.y(), offset_z + loc.z(), parent_name + std::string(inst->getName()) + "/");
1304+
self(self,
1305+
child,
1306+
offset_x + loc.x(),
1307+
offset_y + loc.y(),
1308+
offset_z + loc.z(),
1309+
parent_name + std::string(inst->getName()) + "/");
12971310
}
12981311
} else {
12991312
builder.beginObject();
@@ -2468,7 +2481,7 @@ WebSocketResponse DRCHandler::handleDRCHighlight(const WebSocketRequest& req,
24682481
}
24692482
}
24702483
if (found) {
2471-
const Color red{255, 50, 50, 200};
2484+
const Color red{.r = 255, .g = 50, .b = 50, .a = 200};
24722485
for (const auto& rect : found->rects) {
24732486
state.drc_rects.push_back({rect, red, found->layer});
24742487
}
@@ -2506,13 +2519,17 @@ WebSocketResponse DRCHandler::handleDRCSetVisible(const WebSocketRequest& req,
25062519

25072520
if (!req.drc_visible_indexes.empty()) {
25082521
const DRCReportResult result = drc_report_->getReport();
2509-
const Color red{255, 50, 50, 200};
2510-
2522+
const Color red{.r = 255, .g = 50, .b = 50, .a = 200};
2523+
25112524
for (const auto& cat : result.categories) {
25122525
for (const auto& v : cat.violations) {
2513-
if (req.drc_visible_indexes.count(v.index) > 0) {
2526+
if (req.drc_visible_indexes.contains(v.index)) {
25142527
for (const auto& rect : v.rects) {
2515-
state.drc_rects.push_back({rect, red, v.layer, true}); // true for is_drc if we need to differentiate later
2528+
state.drc_rects.push_back(
2529+
{rect,
2530+
red,
2531+
v.layer,
2532+
true}); // true for is_drc if we need to differentiate later
25162533
}
25172534
for (const auto& poly : v.polys) {
25182535
state.drc_rects.push_back(
@@ -2546,24 +2563,29 @@ WebSocketResponse DRCHandler::handleDRCMarkVisited(const WebSocketRequest& req)
25462563
int index = 0;
25472564
odb::dbMarker* found_marker = nullptr;
25482565
// Find marker by flat index (this matches drc_report.cpp logic)
2549-
std::function<void(odb::dbMarkerCategory*)> search = [&](odb::dbMarkerCategory* cat) {
2550-
for (odb::dbMarker* marker : cat->getMarkers()) {
2551-
if (index == req.drc_violation_index) {
2552-
found_marker = marker;
2553-
return;
2554-
}
2555-
index++;
2556-
}
2557-
for (odb::dbMarkerCategory* sub : cat->getMarkerCategories()) {
2558-
if (found_marker) return;
2559-
search(sub);
2560-
}
2561-
};
2566+
std::function<void(odb::dbMarkerCategory*)> search
2567+
= [&](odb::dbMarkerCategory* cat) {
2568+
for (odb::dbMarker* marker : cat->getMarkers()) {
2569+
if (index == req.drc_violation_index) {
2570+
found_marker = marker;
2571+
return;
2572+
}
2573+
index++;
2574+
}
2575+
for (odb::dbMarkerCategory* sub : cat->getMarkerCategories()) {
2576+
if (found_marker) {
2577+
return;
2578+
}
2579+
search(sub);
2580+
}
2581+
};
25622582
for (odb::dbMarkerCategory* cat : chip->getMarkerCategories()) {
2563-
if (found_marker) break;
2583+
if (found_marker) {
2584+
break;
2585+
}
25642586
search(cat);
25652587
}
2566-
2588+
25672589
if (found_marker) {
25682590
found_marker->setVisited(true);
25692591
}
@@ -2596,13 +2618,9 @@ WebSocketResponse DRCHandler::handleDRCLoad(const WebSocketRequest& req)
25962618
}
25972619

25982620
odb::dbMarkerCategory* cat = nullptr;
2599-
const std::string ext = path.size() >= 5
2600-
? path.substr(path.size() - std::min(path.size(), size_t(5)))
2601-
: path;
26022621

26032622
// Determine format by extension (.json → JSON, else TritonRoute report)
2604-
if (path.size() >= 5
2605-
&& path.compare(path.size() - 5, 5, ".json") == 0) {
2623+
if (path.size() >= 5 && path.compare(path.size() - 5, 5, ".json") == 0) {
26062624
auto cats = odb::dbMarkerCategory::fromJSON(chip, path);
26072625
if (!cats.empty()) {
26082626
cat = *cats.begin();

src/web/src/request_handler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ struct WebSocketRequest
169169
// DRC fields
170170
int drc_violation_index = -1; // -1 = clear highlight
171171
std::set<int> drc_visible_indexes;
172-
std::string drc_file_path; // for DRC_LOAD
172+
std::string drc_file_path; // for DRC_LOAD
173173

174174
// Heat map fields
175175
std::string heatmap_name;

src/web/src/search.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ class Search : public odb::dbBlockCallBackObj
150150
// Returns true once shape R-trees are built.
151151
bool shapesReady() const { return top_block_data_.shapes_init.load(); }
152152

153-
void setTopBlockReady() {
153+
void setTopBlockReady()
154+
{
154155
top_block_data_.shapes_init = true;
155156
top_block_data_.fills_init = true;
156157
top_block_data_.insts_init = true;

src/web/src/tile_generator.cpp

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ std::vector<std::string> TileGenerator::getLayers() const
576576
odb::dbTech* tech = db_->getTech();
577577
if (!tech) {
578578
if (getChip() && !getChip()->getChipInsts().empty()) {
579-
layers.push_back("Chiplets");
579+
layers.emplace_back("Chiplets");
580580
}
581581
return layers;
582582
}
@@ -589,7 +589,7 @@ std::vector<std::string> TileGenerator::getLayers() const
589589
}
590590
}
591591
if (getChip() && !getChip()->getChipInsts().empty()) {
592-
layers.push_back("Chiplets");
592+
layers.emplace_back("Chiplets");
593593
}
594594
return layers;
595595
}
@@ -840,8 +840,10 @@ std::vector<unsigned char> TileGenerator::renderTileBuffer(
840840
const double tile_dbu_size = full_bounds.maxDXDY() / num_tiles_at_zoom;
841841
const int dbu_x_min = full_bounds.xMin() + x * tile_dbu_size;
842842
const int dbu_y_min = full_bounds.yMin() + flipped_y * tile_dbu_size;
843-
const int dbu_x_max = full_bounds.xMin() + std::ceil((x + 1) * tile_dbu_size);
844-
const int dbu_y_max = full_bounds.yMin() + std::ceil((flipped_y + 1) * tile_dbu_size);
843+
const int dbu_x_max
844+
= full_bounds.xMin() + std::ceil((x + 1) * tile_dbu_size);
845+
const int dbu_y_max
846+
= full_bounds.yMin() + std::ceil((flipped_y + 1) * tile_dbu_size);
845847
const odb::Rect dbu_tile(dbu_x_min, dbu_y_min, dbu_x_max, dbu_y_max);
846848
const double scale = kTileSizeInPixel / tile_dbu_size;
847849

@@ -864,16 +866,32 @@ std::vector<unsigned char> TileGenerator::renderTileBuffer(
864866
Color chiplet_color{.r = 100, .g = 150, .b = 200, .a = 150};
865867
drawFilledRect(image_buffer, draw, chiplet_color);
866868
if (draw.xMin() >= 0 && draw.xMin() < kTileSizeInPixel) {
867-
drawFilledRect(image_buffer, odb::Rect(draw.xMin(), draw.yMin(), draw.xMin() + 1, draw.yMax()), Color{.r = 50, .g = 100, .b = 150, .a = 255});
869+
drawFilledRect(
870+
image_buffer,
871+
odb::Rect(
872+
draw.xMin(), draw.yMin(), draw.xMin() + 1, draw.yMax()),
873+
Color{.r = 50, .g = 100, .b = 150, .a = 255});
868874
}
869875
if (draw.xMax() >= 0 && draw.xMax() < kTileSizeInPixel) {
870-
drawFilledRect(image_buffer, odb::Rect(draw.xMax() - 1, draw.yMin(), draw.xMax(), draw.yMax()), Color{.r = 50, .g = 100, .b = 150, .a = 255});
876+
drawFilledRect(
877+
image_buffer,
878+
odb::Rect(
879+
draw.xMax() - 1, draw.yMin(), draw.xMax(), draw.yMax()),
880+
Color{.r = 50, .g = 100, .b = 150, .a = 255});
871881
}
872882
if (draw.yMin() >= 0 && draw.yMin() < kTileSizeInPixel) {
873-
drawFilledRect(image_buffer, odb::Rect(draw.xMin(), draw.yMin(), draw.xMax(), draw.yMin() + 1), Color{.r = 50, .g = 100, .b = 150, .a = 255});
883+
drawFilledRect(
884+
image_buffer,
885+
odb::Rect(
886+
draw.xMin(), draw.yMin(), draw.xMax(), draw.yMin() + 1),
887+
Color{.r = 50, .g = 100, .b = 150, .a = 255});
874888
}
875889
if (draw.yMax() >= 0 && draw.yMax() < kTileSizeInPixel) {
876-
drawFilledRect(image_buffer, odb::Rect(draw.xMin(), draw.yMax() - 1, draw.xMax(), draw.yMax()), Color{.r = 50, .g = 100, .b = 150, .a = 255});
890+
drawFilledRect(
891+
image_buffer,
892+
odb::Rect(
893+
draw.xMin(), draw.yMax() - 1, draw.xMax(), draw.yMax()),
894+
Color{.r = 50, .g = 100, .b = 150, .a = 255});
877895
}
878896
}
879897
}
@@ -2239,10 +2257,12 @@ void TileGenerator::drawColoredHighlight(std::vector<unsigned char>& image,
22392257

22402258
if (draw.dx() >= draw.dy()) {
22412259
// Horizontal shape: draw horizontal centerline
2242-
drawLine(image, draw.xMin(), 255 - cy, draw.xMax(), 255 - cy, line_color);
2260+
drawLine(
2261+
image, draw.xMin(), 255 - cy, draw.xMax(), 255 - cy, line_color);
22432262
} else {
22442263
// Vertical shape: draw vertical centerline
2245-
drawLine(image, cx, 255 - draw.yMin(), cx, 255 - draw.yMax(), line_color);
2264+
drawLine(
2265+
image, cx, 255 - draw.yMin(), cx, 255 - draw.yMax(), line_color);
22462266
}
22472267
}
22482268
}

0 commit comments

Comments
 (0)