| #/usr/bin/python |
| |
| import re |
| import os |
| import argparse |
| from pathlib import Path |
| from common import convert_libname, lib_extract_from_path, files |
| from verilog2simple import print_cont |
| |
| debug = False |
| |
| debug_print = lambda x: print(x) if debug else 0 |
| |
| def main(in_file, out_file = None): |
| |
| with open(in_file, 'r') as in_f: |
| contents = in_f.read() |
| |
| lib = lib_extract_from_path(in_file) |
| |
| # user defined primitives to modules |
| contents = re.sub(r"primitive ", "module ", contents) |
| contents = re.sub(r"endprimitive", "endmodule", contents) |
| # remove alias modules |
| contents = re.sub(r"(?s)module\s*\w*alias\(.*[\n]endmodule", "", contents) |
| # contents = re.sub(r"(?<!^)\s*\\.*?[\n]", "", contents) |
| |
| re_mod_def_libname = re.compile(fr"\s*module\s*{lib}_") |
| |
| lines = contents.split("\n") |
| in_module = False |
| in_module_header = False |
| in_port_def = False |
| module_header = [] |
| module_sep = re.compile(r"[\t ]*,[\t\n ]*") |
| module_regexp = re.compile(r"^\W*module.*?") |
| port_def_regexp = re.compile(r"^\s*(inout|input|output)\s+.*(;|,)") |
| output = "" |
| for line in lines: |
| if in_port_def: |
| if line.find(";") != -1: |
| in_port_def = False |
| output += line + "\n" |
| if in_module_header: |
| line = line.replace("(", "") |
| if line.find("`") != -1 or line == "": |
| continue |
| if line.find(");") != -1: |
| in_module_header = False |
| module_header += module_sep.split(line[:line.find(")")]) |
| output += "\t" + create_mod_header(module_header) + ");\n" |
| module_header = [] |
| else: |
| module_header += module_sep.split(line) |
| else: |
| module_def = module_regexp.search(line) |
| module_end = line.find("endmodule") != -1 |
| port_def = port_def_regexp.search(line) |
| if module_def: |
| output+="\n(* blackbox *)\n" |
| in_module = True |
| libname_str= re_mod_def_libname.search(line) |
| paren_begin = line.find("(") |
| if not line.find(";") != -1 : |
| bracket_start = line.rfind("(") |
| if bracket_start != -1: |
| module_header += module_sep.split(line[bracket_start+1:]) |
| line = line[:bracket_start+1] |
| else: |
| line += "(" |
| in_module_header = True |
| else: |
| bracket_start = line.rfind("(") |
| bracket_end = line.rfind(")") |
| end = ");" |
| module_header = module_sep.split(line[bracket_start + 1:bracket_end]) |
| line = line[:bracket_start + 1] + "\n\t" + create_mod_header(module_header) + end |
| module_header = [] |
| if port_def and line.find(";") == -1: |
| in_port_def = True |
| if module_end: |
| in_module = False |
| if any([module_end, |
| port_def, |
| module_def]): |
| output += line + "\n" |
| # hack- remove 'addr' input definition from s8fmlt files |
| # this input is not defined in module header |
| output = re.sub(r"[\n].* addr;", "", output) |
| # output = re.sub(r"\^\\n", "", output) |
| # strip empty ifdef/else/endif |
| output = re.sub(r"[`]ifdef.*[\n]([`]else\W*(//.*)?[\n])?[`]endif\W*(//.*)?[\n]", "", output) |
| # move commas from begining of line to end of previous |
| output = re.sub(r"(?s)[\n],", r",\n", output) |
| #move closing bracket to end of line |
| output = re.sub(r"\s*[\n]\s*\);", ");\n", output) |
| # remove empty modules definition |
| output = re.sub(r"(?s)\(\* blackbox \*\)\s*[\n]module\s*[a-z0-9_]*\s\(\s*\);\s*[\n]\s*endmodule\s*[\n]", "", output) |
| |
| if out_file is not None: |
| with open(out_file, 'w') as out_f: |
| out_f.write(output) |
| else: |
| print(">>> Output:") |
| print_cont(output) |
| |
| def create_mod_header(module_header): |
| module_header = [x.replace("\t", "") for x in module_header if x.strip() != ""] |
| return ",\n\t".join(module_header) |
| |
| |
| if __name__ == "__main__": |
| |
| import doctest |
| fails, _ = doctest.testmod() |
| if fails>0: |
| exit() |
| else: |
| print("Tests Passed") |
| parser = argparse.ArgumentParser() |
| parser.add_argument( |
| "input", |
| help="The path to the source directory/file. If file is passed it will run in debug mode with no output file" + |
| "If dir is passed it will find '.full.v' files generate '.simple.v' in the same directory", |
| type=Path) |
| args = parser.parse_args() |
| if not os.path.isdir(args.input): |
| debug = True |
| main(str(args.input)) |
| else: |
| files = args.input.rglob('*.full.v') |
| for f in files: |
| f = str(f) |
| print(f) |
| main(f, f[:-7] + ".blackbox.v") |
| |
| |