blob: b421d844a546099aa2a76056ebad92d8c070aec1 [file] [log] [blame] [edit]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2020-2022 F4PGA 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
#
# https://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.
#
# SPDX-License-Identifier: Apache-2.0
"""
This script parses and then compares contents of two PCF files. If the
constraints are identical exits with code 0. Otherwise prints parsed content
of both files and exits with -1. It is used to verify whether
design constraints were correctly applied during the toolchain flow.
fasm2bels for QuickLogic PP3 architecture can write PCF with actual
IO locations as encoded in the bitstream. This is verified against
the original PCF from the design.
"""
import argparse
from f4pga.utils.pcf import parse_simple_pcf
def main():
parser = argparse.ArgumentParser(
description="Compares IO constraints across two PCF files"
)
parser.add_argument("pcf", nargs=2, type=str, help="PCF files")
args = parser.parse_args()
# Read constraints, convert them to tuples for easy comparison
pcf = []
for i in [0, 1]:
with open(args.pcf[i], "r") as fp:
constrs = set()
for constr in parse_simple_pcf(fp):
key = tuple(
[
type(constr).__name__, constr.net,
None if not hasattr(constr, "pad") else constr.pad
]
)
constrs.add(key)
pcf.append(constrs)
# We have a match
if pcf[0] == pcf[1]:
exit(0)
# Print difference
print("PCF constraints mismatch!")
for i in [0, 1]:
print("'{}'".format(args.pcf[i]))
for key in sorted(pcf[i]):
print("", key)
exit(-1)
if __name__ == "__main__":
main()