blob: acae41ca0014c5379cf663f3b3c87ddfd5b293bf [file] [log] [blame] [edit]
#!/usr/bin/env python3
'''
Concatenate Verilog source files and process include directives inside them.
Usage: concatenate_v_sources.py [-h] inputfile [inputfile ...] outputfile
'''
import argparse
import sys
import re
from os import path
parser = argparse.ArgumentParser()
parser.add_argument(
"inputfile",
nargs='+',
type=argparse.FileType('r'),
help="Input Verilog file"
)
parser.add_argument(
"outputfile", type=argparse.FileType('w'), help="Output file"
)
include_re = re.compile(r'^`include *"([^"]+)"', flags=re.MULTILINE)
slash_star_re = re.compile(r'\s*/\*.*\*/\s*', flags=re.DOTALL)
slash_slash_re = re.compile(r'\s*//[^\n]*')
v2x_re = re.compile(
r'.*\(\*.*((DELAY)|(CLOCK)|(MODEL)|(SETUP)|(HOLD)|(FASM)).*\*\)\n'
)
def process_includes(file, includes_list):
file_name = path.realpath(file.name)
if file_name in includes_list:
return ''
includes_list.append(file_name)
code = file.read()
code = slash_star_re.sub('', code)
code = slash_slash_re.sub('', code)
code = v2x_re.sub('', code)
def process_match(match):
include_path = path.join(path.dirname(file_name), match[1])
include_file = open(include_path, 'r')
return process_includes(include_file, includes_list)
rel_file_name = path.relpath(file_name)
result = f'// {rel_file_name} {{{{{{\n' + \
include_re.sub(process_match, code) + \
f'// {rel_file_name} }}}}}}\n'
return result
def main(argv):
args = parser.parse_args(argv[1:])
print(args)
includes_list = []
print(
*(process_includes(f, includes_list) for f in args.inputfile),
sep='\n',
end='',
file=args.outputfile
)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))