#!/usr/bin/env python3 # coding=utf-8 from __future__ import print_function import os import os.path as path import re import argparse from datetime import datetime script_dir = path.dirname(path.realpath(__file__)) defines = {} for k, v in os.environ.items(): if k.upper().startswith('V_'): defines[k[2:]] = v print('Custom params:', ', '.join(['='.join(x) for x in defines.items()])) parser = argparse.ArgumentParser() parser.add_argument('--outc', default='none', help='Output C header') parser.add_argument('--outv', default='none', help='Output Verilog header') args = parser.parse_args() if args.outc == 'none' and args.outv == 'none': print('Warning: not emitting any files. Specify arguments') if args.outv != 'none': with open(args.outv, 'w') as f: print(''' // auto-generated by gen_config.py. DO NOT EDIT // Generated at {date} `ifndef VX_USER_CONFIG `define VX_USER_CONFIG '''[1:].format(date=datetime.now()), file=f) for k, v in defines.items(): print('`define {} {}'.format(k, v), file=f) print('\n`endif', file=f) if args.outc != 'none': with open(args.outc, 'w') as f: print(''' // auto-generated by gen_config.py. DO NOT EDIT // Generated at {date} #ifndef VX_USER_CONFIG #define VX_USER_CONFIG '''[1:].format(date=datetime.now()), file=f) for k, v in defines.items(): print('#define {} {}'.format(k, v), file=f) print('\n#endif', file=f) translation_rules = [ (re.compile(r'^$'), r''), (re.compile(r'^( *)`ifndef ([^ ]+)$'), r'\1#ifndef \2'), (re.compile(r'^( *)`define ([^ ]+)$'), r'\1#define \2'), # (re.compile(r'^( *)`include "\./VX_define_synth\.v"$'), r'\1#include "VX_define_synth.h"'), (re.compile(r'^( *)`include "VX_user_config\.vh"$'), r''), (re.compile(r'^( *)`define ([^ ]+) (.+)$'), r'\1#define \2 \3'), (re.compile(r'^( *)`endif$'), r'\1#endif'), (re.compile(r'^( *)// (.*)$'), r'\1// \2'), ] post_rules = [ (re.compile(r"\d+'d(\d+)"), r'\1'), # non-standard C but supported by GCC and Clang (re.compile(r"\d+'b([01]+)"), r'0b\1'), (re.compile(r"\d+'h([\da-fA-F]+)"), r'0x\1'), # fix macro references (does not support escaped identifiers ยง5.6.1) (re.compile(r"`([A-Za-z_][$_0-9A-Za-z]*)"), r'\1'), ] def post_process_line(line): for pat, repl in post_rules: line = pat.sub(repl, line) return line in_expansion = False if args.outc != 'none': with open(args.outc, 'a') as f: print(''' // auto-generated by gen_config.py. DO NOT EDIT // Generated at {date} // Translated from VX_config.vh: '''[1:].format(date=datetime.now()), file=f) with open(path.join(script_dir, '../rtl/VX_config.vh'), 'r') as r: for line in r: if in_expansion: f.write(post_process_line(line)) if not line.strip().endswith('\\'): in_expansion = False else: for pat, repl in translation_rules: if pat.match(line): if line.strip().endswith('\\'): in_expansion = True f.write(post_process_line(pat.sub(repl, line))) break else: raise ValueError('failed to find rule for: ' + line) print(''' // Misc #define THREADS_PER_WARP NUM_THREADS #define WARPS_PER_CORE NUM_WARPS #define NUMBER_WI (NUM_WARPS * NUM_THREADS * NUMBER_CORES_PER_CLUSTER * NUMBER_CLUSTERS) // legacy #define TOTAL_THREADS NUMBER_WI #define TOTAL_WARPS (NUM_WARPS * NUMBER_CORES_PER_CLUSTER * NUMBER_CLUSTERS) // COLORS #define GREEN "\\033[32m" #define RED "\\033[31m" #define DEFAULT "\\033[39m" '''[1:], file=f)