#!/usr/bin/env python3 """Suffix every module in rtl_ip/ with _IP so original and IP-based RTL can coexist in one xsim `work` library for the dual-DUT cycle-true comparison. - renames `module X` -> `module X_IP` for every module DECLARED in rtl_ip/*.v - rewrites instantiations of those modules accordingly (word-boundary match) - IP core instances (dist_mem_gen/blk_mem_gen/... names from ip_manifest) are left untouched -- they are not declared here. Run LAST, after rom_to_ip.py / ram_to_ip.py / any hand edits (CORDIC, FIFO). Idempotent: modules already ending in _IP are skipped. """ import argparse, os, re def main(): ap = argparse.ArgumentParser() ap.add_argument('rtl_ip_dir') a = ap.parse_args() d = os.path.abspath(a.rtl_ip_dir) files = [os.path.join(d, f) for f in os.listdir(d) if f.endswith('.v')] mods = [] for p in files: for m in re.finditer(r'^\s*module\s+(\w+)', open(p, encoding='utf-8', errors='replace').read(), re.M): if not m.group(1).endswith('_IP'): mods.append(m.group(1)) mods = sorted(set(mods), key=len, reverse=True) print('modules:', mods) for p in files: txt = open(p, encoding='utf-8', errors='replace').read() for mod in mods: txt = re.sub(r'\b%s\b(?!_IP)' % re.escape(mod), mod + '_IP', txt) open(p, 'w', encoding='utf-8').write(txt) print(f'suffixed {len(mods)} modules across {len(files)} files') if __name__ == '__main__': main()