diff --git a/ivtest/blif_reg.py b/ivtest/blif_reg.py index fcfb73807..78764aed5 100644 --- a/ivtest/blif_reg.py +++ b/ivtest/blif_reg.py @@ -1,86 +1,127 @@ -# -# This is a python script for testing the blif code generator with -# programs specifically set aside for it. The general pattern is that -# the test program comes in two parts: the test bench and the device -# to be tested. The files blif/*_tb.v are the test benches for the -# corresponding files blif/*.v. -# -# This script requires the "abc" command available here: -# -# -# Run this script with the command: python blif_reg.py -# +''' This is a python script for testing the blif code generator with + programs specifically set aside for it. The general pattern is that + the test program comes in two parts: the test bench and the device + to be tested. The files blif/*_tb.v are the test benches for the + corresponding files blif/*.v. + + This script requires the "abc" command available here: + + + Run this script with the command: python3 blif_reg.py ''' import os import subprocess import re -# This is the name of the iverilog command and vvp command. These may +# This is the name of the iverilog, vvp, and abc command. These may # vary in different installations. -iverilog = "iverilog" -vvp = "vvp" +IVERILOG = "iverilog" +VVP = "vvp" +ABC = "berkeley-abc" -list_file = open("blif.list") +def get_tests() -> list: + '''Get the test names''' + # The list file contains a list of test names. The first word in the + # line is the name of the test. + match_prog = re.compile(r"^([a-zA-Z0-9_.]+).*$") -# The list file contains a list of test names. The first word in the -# line is the name of the test. -match_prog = re.compile(r"^([a-zA-Z0-9_.]+).*$") - -tests = [] -for line in list_file: - if line[0] == "#": - continue - match = match_prog.search(line) - if match: - tests.append(match.group(1)) - -list_file.close() - -def run_test(test): - global count_passed, count_failed + tests = [] + with open("blif.list", encoding='ascii') as fd: + for line in fd: + if line[0] == "#": + continue + match = match_prog.search(line) + if match: + tests.append(match.group(1)) + return tests +def run_test(test_name: str) -> bool: + '''Run each test using this routine. + Returns True if the test passes.''' # Assemble the paths for the test-bench and DUT. - dut = "blif/" + test + ".v" - tb = "blif/" + test + "_tb.v" + dut = "blif/" + test_name + ".v" + tb = "blif/" + test_name + "_tb.v" - redirect = "log/" + test + ".log 2>&1" + redirect = "log/" + test_name + ".log 2>&1" # Process the DUT into a .blif file - ivl_blif_cmd = iverilog + " -g2009 -tblif -otmp_blif.blif " + dut + " > " + redirect + ivl_blif_cmd = IVERILOG + " -g2009 -tblif -otmp_blif.blif " + dut + " > " + redirect rc = subprocess.call(ivl_blif_cmd, shell=True) if rc == 0: # Use ABC to convert the .blif file to Verilog - abc_cmd = "berkeley-abc -c 'read_blif tmp_blif.blif ; write_verilog tmp_blif.v' >> " + redirect - rc = subprocess.call(abc_cmd, shell=True); + abc_cmd = ABC +" -c 'read_blif tmp_blif.blif ; write_verilog tmp_blif.v' >> " + redirect + rc = subprocess.call(abc_cmd, shell=True) if rc == 0: # Compile - ivl_blif_tb_cmd = iverilog + " -g2009 -otmp_blif.vvp " + tb + " tmp_blif.v >> " + redirect + ivl_blif_tb_cmd = IVERILOG + " -g2009 -otmp_blif.vvp " + tb + " tmp_blif.v >> " + redirect rc = subprocess.call(ivl_blif_tb_cmd, shell=True) if rc == 0: # Now simulate to make sure the tranlation worked properly. - vvp_cmd = vvp + " tmp_blif.vvp" - output = subprocess.check_output(vvp_cmd, shell=True) - rc = 0 if output == "PASSED\n" else 1 + vvp_cmd = VVP + " tmp_blif.vvp" + output = subprocess.check_output(vvp_cmd, shell=True, text=True) + echo_cmd = "echo " + output.rstrip() + " >> " + redirect + rc = subprocess.call(echo_cmd, shell=True) - if rc == 0: - print(test, "PASSED") - count_passed = count_passed + 1 - else: - print(test, "FAILED") - count_failed = count_failed + 1 - - for tmp in ["tmp_blif.blif", "tmp_blif.v", "tmp_blif.vvp"]: + for tmp in ["tmp_blif.blif", "tmp_blif.v", "tmp_blif.vvp", "abc.history"]: if os.path.exists(tmp): os.remove(tmp) -count_passed = 0 -count_failed = 0 + return not (rc or output != "PASSED\n") -for test in tests: - run_test(test) +def get_ivl_version() -> list: + '''Get the iverilog version''' + text = subprocess.check_output([IVERILOG, "-V"]) + match = re.search(b'Icarus Verilog version ([0-9]+)\\.([0-9]+)', text) + if not match: + return None -print() -print(count_passed, "tests passed,", count_failed, "tests failed.") + items = match.groups() + return [str(items[0], 'ascii'), str(items[1], 'ascii')] + +def get_abc_version() -> list: + '''Get the berkeley-abc version''' + res = subprocess.run([ABC, "-h"], capture_output=True, check=False) + match = re.search(b'UC Berkeley, ABC ([0-9]+)\\.([0-9]+)', res.stdout) + if not match: + return None + + items = match.groups() + return [str(items[0], 'ascii'), str(items[1], 'ascii')] + +def run_tests(tests: list): + '''Run all the tests in the test list''' + ivl_ver = get_ivl_version() + abc_ver = get_abc_version() + # pylint: disable-next=consider-using-f-string + print("Running blif tests for Icarus Verilog version: {ver}.{sver}".format(ver=ivl_ver[0], + sver=ivl_ver[1])) + # pylint: disable-next=consider-using-f-string + print("Using berkely-abc version: {ver}.{sver}".format(ver=abc_ver[0], sver=abc_ver[1])) + print("=" * 50) + + count_passed = 0 + count_failed = 0 + + width = max(len(name) for name in tests) + + for test in tests: + passed = run_test(test) + if passed: + res = "Passed" + count_passed += 1 + else: + res = "Failed" + count_failed += 1 + # pylint: disable-next=consider-using-f-string + print("{name:>{width}}: {res}.".format(name=test, width=width, res=res)) + + print("=" * 50) + # pylint: disable-next=consider-using-f-string + print("Tests results: Passed {passed}, Failed {failed}".format(passed=count_passed, \ + failed=count_failed)) + +if __name__ == "__main__": + run_tests(get_tests()) diff --git a/ivtest/vvp_reg.py b/ivtest/vvp_reg.py index 5f13d1acf..450071121 100755 --- a/ivtest/vvp_reg.py +++ b/ivtest/vvp_reg.py @@ -205,9 +205,7 @@ if __name__ == "__main__": # We need the width of the widest key so that we can figure out # how to align the key:result columns. # pylint: disable-next=invalid-name - width = 0 - for cur in tests_list: - width = max(width, len(cur[0])) + width = max(len(item[0]) for item in tests_list) # pylint: disable-next=invalid-name error_count = 0