From ea474301503a8f13f4ace1183e114d0c70de0415 Mon Sep 17 00:00:00 2001 From: Tim Callahan Date: Thu, 6 Jan 2022 23:29:12 -0800 Subject: [PATCH 1/2] Save a placement plot for each parallel job. Untested. Signed-off-by: Tim Callahan --- scripts/parallel-nextpnr-nexus | 5 +++ soc/pre-route.py | 77 ++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 soc/pre-route.py diff --git a/scripts/parallel-nextpnr-nexus b/scripts/parallel-nextpnr-nexus index 5216de972..b0a5f2df6 100755 --- a/scripts/parallel-nextpnr-nexus +++ b/scripts/parallel-nextpnr-nexus @@ -28,6 +28,7 @@ PDC="$2" RESULT_FASM="$3" SEED_COUNT="$4" SEED="$5" +PREROUTE_SCRIPT="" ### check if bash 5.1 for "wait -p"; if not, do plain run @@ -51,6 +52,9 @@ declare -A PID_TO_SEED set -o pipefail # Launch a number of nextpnrs +if [[ -f "../../pre-route.py" ]]; then + PREROUTE_SCRIPT=" --pre-route ../../pre-route.py" +fi echo "$(basename $0): running ${SEED_COUNT} nextpnr-nexus instances." rm -rf runs mkdir runs @@ -67,6 +71,7 @@ for s in $(seq ${SEED_COUNT}); do --device LIFCL-17-8UWG72C \ --report="${DIR}/report.json" \ --detailed-timing-report \ + "${PREROUTE_SCRIPT}" \ --seed "${seed}" 2>&1 | \ (while read line; do echo "$(date +%H:%M:%S) ${line}"; done diff --git a/soc/pre-route.py b/soc/pre-route.py new file mode 100644 index 000000000..23980abbe --- /dev/null +++ b/soc/pre-route.py @@ -0,0 +1,77 @@ +import matplotlib.pyplot as plt +import matplotlib.patches as mpatches +import random + +fig, ax = plt.subplots(dpi=200) + +print("\nGenerating placement image...\n") + +for net, netinfo in ctx.nets: + print(net) + print(netinfo.users) + +for cell, cellinfo in ctx.cells: + if cellinfo.bel: + #print("Cell %s %s" % (cell, cellinfo.type)) + bel = cellinfo.bel + loc = ctx.getBelLocation(bel) + x = int(loc.x) + y = int(loc.y) + + color = 'black' + COLOR_TABLE = [ + ('Vex', 'gray'), + ('Cfu', 'seagreen'), + ('Cfu.core', 'lime'), + ('Cfu.core.sysarray', 'red'), + ('Cfu.core.ppp', 'violet'), + ('Cfu.core.f0', 'yellow'), + ('Cfu.core.f1', 'tan'), + ] + for match, c in COLOR_TABLE: + if match in cell: + color = c + + mul = "MULT" in bel + ebr = "EBR" in bel + + # Set color for LRAMs + lram = "SP512K" in cell + arena = "DPSC512K" in cell + color='tan' if arena else ('bisque' if lram else color) + + if mul: + ax.add_patch(mpatches.Circle( + [x, y+0.5], 0.7, + color=color, + ec='white', + fill=True + )) + elif ebr or lram or arena: + ax.add_patch(mpatches.Rectangle( + [x, y-0.2], 1.6, 1.6, + color=color, + ec='white', + fill=True + )) + else: + rx = random.uniform(0,0.7) + ry = random.uniform(0,0.7) + ax.add_patch(mpatches.Rectangle( + [x+rx, y+ry], 0.1, 0.1, + color=color, + fill=True + )) + +ax.set_aspect('equal') +nl = ',\n' +comma = ', ' +ax.set_title(''.join([f'{match}={c}{nl if i&1 else comma}' for i, (match, c) in enumerate(COLOR_TABLE)]) + + 'Black=LiteX, Circle=DSP, Square=MEM') +ax.autoscale_view() +#plt.show() +plt.savefig("placement.png", format="png") +print("Done\n") + +# Uncommenting this will cause nextpnr to stop without running routing (but still show the placement plot) +# exit() From 01a586b2d176a97833e6ba6f04c9de98ddf27eb4 Mon Sep 17 00:00:00 2001 From: Tim Callahan Date: Sat, 8 Jan 2022 10:12:06 -0800 Subject: [PATCH 2/2] In parallel pnr, dump placement .png for every run. Signed-off-by: Tim Callahan --- scripts/parallel-nextpnr-nexus | 17 +++++++++-------- soc/pre-route.py | 23 ++++++++++++++++++----- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/scripts/parallel-nextpnr-nexus b/scripts/parallel-nextpnr-nexus index b0a5f2df6..887544a97 100755 --- a/scripts/parallel-nextpnr-nexus +++ b/scripts/parallel-nextpnr-nexus @@ -52,8 +52,8 @@ declare -A PID_TO_SEED set -o pipefail # Launch a number of nextpnrs -if [[ -f "../../pre-route.py" ]]; then - PREROUTE_SCRIPT=" --pre-route ../../pre-route.py" +if [[ -e "../../../pre-route.py" ]]; then + PREROUTE_SCRIPT=" --pre-route ../../../../../pre-route.py" fi echo "$(basename $0): running ${SEED_COUNT} nextpnr-nexus instances." rm -rf runs @@ -64,18 +64,19 @@ for s in $(seq ${SEED_COUNT}); do DIR="runs/seed-${seed}" mkdir "${DIR}" ( + cd ${DIR} && nextpnr-nexus \ - --json "${JSON}" \ - --pdc "${PDC}" \ - --fasm "${DIR}/output.fasm" \ + --json "../../${JSON}" \ + --pdc "../../${PDC}" \ + --fasm "./output.fasm" \ --device LIFCL-17-8UWG72C \ - --report="${DIR}/report.json" \ + --report="./report.json" \ --detailed-timing-report \ - "${PREROUTE_SCRIPT}" \ + ${PREROUTE_SCRIPT} \ --seed "${seed}" 2>&1 | \ (while read line; do echo "$(date +%H:%M:%S) ${line}"; done - ) > "${DIR}/nextpnr-nexus.log" + ) > "./nextpnr-nexus.log" ) & PID=$! CHILD_PIDS+=(${PID}) diff --git a/soc/pre-route.py b/soc/pre-route.py index 23980abbe..ebfc223c0 100644 --- a/soc/pre-route.py +++ b/soc/pre-route.py @@ -1,3 +1,20 @@ +#!/usr/bin/env python3 +# Copyright 2021 The CFU-Playground Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""This script is executed by nextpnr-nexus to generate a placement plot.""" + + import matplotlib.pyplot as plt import matplotlib.patches as mpatches import random @@ -6,10 +23,6 @@ print("\nGenerating placement image...\n") -for net, netinfo in ctx.nets: - print(net) - print(netinfo.users) - for cell, cellinfo in ctx.cells: if cellinfo.bel: #print("Cell %s %s" % (cell, cellinfo.type)) @@ -73,5 +86,5 @@ plt.savefig("placement.png", format="png") print("Done\n") -# Uncommenting this will cause nextpnr to stop without running routing (but still show the placement plot) +# Uncommenting this will cause nextpnr to stop without running routing (but still produce the placement plot) # exit()