Skip to content
Open
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
54 changes: 50 additions & 4 deletions placement.py
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,8 @@ def calculate_normalized_metrics(cell_features, pin_features, edge_list):
- num_cells_with_overlaps: number of unique cells involved in overlaps
- total_cells: total number of cells
- num_nets: number of nets (edges)
- core area: area of the core region
- core utilization: (std cell + macro area) / core area
"""
N = cell_features.shape[0]

Expand All @@ -602,6 +604,22 @@ def calculate_normalized_metrics(cell_features, pin_features, edge_list):
num_cells_with_overlaps = len(cells_with_overlaps)
overlap_ratio = num_cells_with_overlaps / N if N > 0 else 0.0

# Calculate core area: max bounding box containing all cells
positions = cell_features[:, [CellFeatureIdx.X, CellFeatureIdx.Y]]
widths = cell_features[:, CellFeatureIdx.WIDTH]
heights = cell_features[:, CellFeatureIdx.HEIGHT]

min_x = (positions[:, 0] - widths/2).min().item()
max_x = (positions[:, 0] + widths/2).max().item()
min_y = (positions[:, 1] - heights/2).min().item()
max_y = (positions[:, 1] + heights/2).max().item()

core_area = (max_x - min_x) * (max_y - min_y)

# Calculate core utilization: (std cell + macro area) / core area
std_macro_area = cell_features[:, CellFeatureIdx.AREA].sum().item()
core_utilization = (std_macro_area) / core_area if core_area > 0 and overlap_ratio == 0.0 else float('nan')

# Calculate wirelength metric: (wirelength / num nets) / sqrt(total area)
if edge_list.shape[0] == 0:
normalized_wl = 0.0
Expand All @@ -626,6 +644,8 @@ def calculate_normalized_metrics(cell_features, pin_features, edge_list):
"num_cells_with_overlaps": num_cells_with_overlaps,
"total_cells": N,
"num_nets": num_nets,
"core_area": core_area,
"core_utilization": core_utilization,
}


Expand Down Expand Up @@ -690,11 +710,34 @@ def plot_placement(
)

# Set axis limits with margin
all_x = positions[:, 0]
all_y = positions[:, 1]
all_x_max = positions[:, 0] + widths/2
all_y_max = positions[:, 1] + heights/2
all_x_min = positions[:, 0] - widths/2
all_y_min = positions[:, 1] - heights/2
margin = 10
ax.set_xlim(all_x.min() - margin, all_x.max() + margin)
ax.set_ylim(all_y.min() - margin, all_y.max() + margin)
ax.set_xlim(all_x_min.min() - margin, all_x_max.max() + margin)
ax.set_ylim(all_y_min.min() - margin, all_y_max.max() + margin)

# Draw bounding box around all cells
bbox_width = all_x_max.max() - all_x_min.min()
bbox_height = all_y_max.max() - all_y_min.min()
bbox_rect = Rectangle(
(all_x_min.min(), all_y_min.min()),
bbox_width,
bbox_height,
fill=False,
edgecolor='red',
linestyle='--',
linewidth=1
)
ax.add_patch(bbox_rect)

# Add dimensions text
ax.text(all_x_min.min(), all_y_max.max() + 1,
f'({bbox_width:.1f}x{bbox_height:.1f}) = {bbox_width * bbox_height:.1f}',
horizontalalignment='left',
verticalalignment='bottom',
color='red')

plt.tight_layout()
output_path = os.path.join(OUTPUT_DIR, filename)
Expand Down Expand Up @@ -785,6 +828,9 @@ def main():
print(f"Overlap Ratio: {normalized_metrics['overlap_ratio']:.4f} "
f"({normalized_metrics['num_cells_with_overlaps']}/{normalized_metrics['total_cells']} cells)")
print(f"Normalized Wirelength: {normalized_metrics['normalized_wl']:.4f}")
print(f"Core Area: {normalized_metrics['core_area']:.2f}")
core_utilization = normalized_metrics['core_utilization'] if normalized_metrics['core_utilization'] < 1.0 else float('nan')
print(f"Core Utilization: {core_utilization:.2f}")

# Success check
print("\n" + "=" * 70)
Expand Down
6 changes: 6 additions & 0 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ def run_placement_test(
"num_cells_with_overlaps": metrics["num_cells_with_overlaps"],
"overlap_ratio": metrics["overlap_ratio"],
"normalized_wl": metrics["normalized_wl"],
"core_area": metrics["core_area"],
"core_utilization": metrics["core_utilization"],
}


Expand Down Expand Up @@ -157,13 +159,16 @@ def run_all_tests():
status = "✓ PASS" if result["num_cells_with_overlaps"] == 0 else "✗ FAIL"
print(f" Overlap Ratio: {result['overlap_ratio']:.4f} ({result['num_cells_with_overlaps']}/{result['total_cells']} cells)")
print(f" Normalized WL: {result['normalized_wl']:.4f}")
print(f" Core Area: {result['core_area']:.2f}")
print(f" Core Utilization: {result['core_utilization']:.2f}")
print(f" Time: {result['elapsed_time']:.2f}s")
print(f" Status: {status}")
print()

# Compute aggregate statistics
avg_overlap_ratio = sum(r["overlap_ratio"] for r in all_results) / len(all_results)
avg_normalized_wl = sum(r["normalized_wl"] for r in all_results) / len(all_results)
avg_core_utilization = sum(r["core_utilization"] for r in all_results) / len(all_results)
total_time = sum(r["elapsed_time"] for r in all_results)

# Print aggregate results
Expand All @@ -172,6 +177,7 @@ def run_all_tests():
print("=" * 70)
print(f"Average Overlap: {avg_overlap_ratio:.4f}")
print(f"Average Wirelength: {avg_normalized_wl:.4f}")
print(f"Average Core Utilization: {avg_core_utilization:.2f}")
print(f"Total Runtime: {total_time:.2f}s")
print()

Expand Down