blob: 8ee1f0637cea6aebe112a4272f1a60e2ce9f264c [file] [log] [blame] [edit]
#!/usr/bin/env python3
"""
This utility script allows to visualize VPR placement. It reads a VPR .place
file and generates a bitmap with the visualization.
"""
import argparse
import re
import itertools
from PIL import Image, ImageDraw
# =============================================================================
def load_placement(placement_file):
"""
Loads VPR placement file. Returns a tuple with the grid size and a dict
indexed by locations that contains top-level block names.
"""
RE_PLACEMENT = re.compile(
r"^\s*(?P<net>\S+)\s+(?P<x>[0-9]+)\s+(?P<y>[0-9]+)\s+(?P<z>[0-9]+)"
)
RE_GRID_SIZE = re.compile(
r"Array size:\s+(?P<x>[0-9]+)\s+x\s+(?P<y>[0-9]+)\s+logic blocks"
)
# Load the file
with open(placement_file, "r") as fp:
lines = fp.readlines()
# Parse
grid_size = None
placement = {}
for line in lines:
line = line.strip()
if line.startswith("#"):
continue
# Placement
match = RE_PLACEMENT.match(line)
if match is not None:
loc = (int(match.group("x")), int(match.group("y")))
placement[loc] = match.group("net")
# Grid size
match = RE_GRID_SIZE.match(line)
if match is not None:
grid_size = (int(match.group("x")), int(match.group("y")))
return grid_size, placement
def generate_image(grid_size, placement, block_size=8, colormap=None):
"""
Generates a visualization of the placement.
"""
block_size = max(block_size, 3)
gap_size = 1
cell_size = block_size + 2 * gap_size
# Create new image
dx = grid_size[0] * cell_size + 1
dy = grid_size[1] * cell_size + 1
image = Image.new("RGB", (dx, dy), color="#FFFFFF")
# Draw stuff
draw = ImageDraw.Draw(image)
for cx, cy in itertools.product(range(grid_size[0]), range(grid_size[1])):
x0 = cx * cell_size + gap_size
y0 = cy * cell_size + gap_size
x1 = x0 + block_size
y1 = y0 + block_size
if (cx, cy) in placement:
name = placement[(cx, cy)]
if colormap is not None and name in colormap:
color = colormap[name]
else:
color = "#2080C0"
else:
color = "#FFFFFF"
draw.rectangle((x0, y0, x1, y1), color, "#000000")
return image
# =============================================================================
def main():
# Parse arguments
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument("place", type=str, help="A VPR .place file")
parser.add_argument(
"-o", type=str, default="placement.png", help="Output image file"
)
parser.add_argument(
"--block-size", type=int, default=4, help="Block size (def. 4)"
)
args = parser.parse_args()
# Load placement
grid_size, placement = load_placement(args.place)
# Colormap
colormap = {
"$true": "#C02020",
"$false": "#000000",
}
# Generate the image
image = generate_image(grid_size, placement, args.block_size, colormap)
image.save(args.o)
# =============================================================================
if __name__ == "__main__":
main()