blob: 303b5a655fd08dfe5fe1951826460a9fb85abbe7 [file] [log] [blame]
#/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")