From 25f9ee741708a4a7cdf92c639917f9e781c218fc Mon Sep 17 00:00:00 2001 From: David Mapstone <david@mapstone.me> Date: Thu, 23 Mar 2023 15:28:07 +0000 Subject: [PATCH] SOC1-156: Changed Syntax of Vgen to work with python3 and added set_env script to CHIPKIT --- set_env.sh | 50 ++++++++++++++++++++++ tools/vgen/bin/vgen.py | 50 ++++++++++++---------- tools/vgen/examples/pads/vgen_pads.py | 2 +- tools/vgen/examples/registers/vgen_regs.py | 36 ++++++++-------- 4 files changed, 97 insertions(+), 41 deletions(-) create mode 100755 set_env.sh diff --git a/set_env.sh b/set_env.sh new file mode 100755 index 0000000..57af45c --- /dev/null +++ b/set_env.sh @@ -0,0 +1,50 @@ +#----------------------------------------------------------------------------- +# SoC Labs Environment Setup Script +# A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license. +# +# Contributors +# +# David Mapstone (d.a.mapstone@soton.ac.uk) +# +# Copyright 2023, SoC Labs (www.soclabs.org) +#----------------------------------------------------------------------------- +#!/bin/bash + +# Get Root Location of Design Structure +if [ -z $DESIGN_ROOT ]; then + # If $DESIGN_ROOT hasn't been set yet + DESIGN_ROOT=`git rev-parse --show-superproject-working-tree` + + if [ -z $DESIGN_ROOT ]; then + # If not in a submodule - at root + DESIGN_ROOT=`git rev-parse --show-toplevel` + fi + + # Source Top-Level Sourceme + source $DESIGN_ROOT/set_env.sh +else + # Set Environment Variable for this Repository + export CHIPKIT_DIR="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 ; pwd -P )" + + # If this Repo is root of workspace + if [ $CHIPKIT_DIR = $DESIGN_ROOT ]; then + echo "Design Workspace: $DESIGN_ROOT" + export DESIGN_ROOT + # Set Default Simulator + export SIMULATOR="ivlog" + fi + + # Source environment variables for all submodules + for d in $CHIPKIT_DIR/* ; do + if [ -f "$d/.git" ]; then + if [ -f "$d/set_env.sh" ]; then + # If .git file exists - submodule + source $d/set_env.sh + fi + fi + done + + # Add Scripts to Path + export PATH="$PATH:/$CHIPKIT_DIR" + export PYTHONPATH="$PYTHONPATH:$CHIPKIT_DIR/tools/vgen/bin" +fi \ No newline at end of file diff --git a/tools/vgen/bin/vgen.py b/tools/vgen/bin/vgen.py index db0300c..dea5342 100755 --- a/tools/vgen/bin/vgen.py +++ b/tools/vgen/bin/vgen.py @@ -60,7 +60,7 @@ def get_verilog_signals(module_file,signal_prefix): Read a (system)verilog file and return all signals with a matching prefix, along with some related details """ fi = open(module_file,"r") - print "** Reading file \""+module_file+"\" to get signals with prefix \""+signal_prefix+"\"." + print("** Reading file \""+module_file+"\" to get signals with prefix \""+signal_prefix+"\".") # define some regexs re_nb = '(\\b'+re.escape(signal_prefix)+'\w+)\[(\d+)\:(\d+)\]' # this regex matches multibit signals: e.g. "mysig[7:0]" @@ -161,17 +161,17 @@ def get_verilog_module_signals(module_file,debug=False): if ')' in line: break elif re.search(re_nb,line): - if d: print 'Found nb signal in module declaration.' + if d: print('Found nb signal in module declaration.') nbits = int(re.search(re_nb,line).group(2)) - int(re.search(re_nb,line).group(3)) +1 start = int(re.search(re_nb,line).group(3)) assert start == 0, 'start bit index in slice is not zero: %s' % start signal_match = [re.search(re_nb,line).group(4).strip(),re.search(re_nb,line).group(1).strip(),nbits,0] elif re.search(re_1b,line): - if d: print 'Found 1b signal in module declaration.' + if d: print('Found 1b signal in module declaration.') nbits = 1 signal_match = [re.search(re_1b,line).group(2).strip(),re.search(re_1b,line).group(1).strip(),nbits,0] new = dict((key,val) for key,val in zip(keys,signal_match)) - if d: print new + if d: print(new) vglist.append(new) return vglist @@ -196,42 +196,44 @@ def read_csv(csv_file, debug=False): try: fi = open(csv_file,"r") except IOError: - print "** Error: File not found: "+vglist_file + print("** Error: File not found: "+vglist_file) sys.exit() # create an empty list to add dictionaries to vglist = [] # use csv module to iterate over input file - reader = csv.reader(fi) + reader = csv.reader(fi, delimiter="\t") # get keys from header on first line row = next(reader) + print(row) header = [x.strip(' ') for x in row] # clean up any whitespace + print(header) header = [header[0].replace('*','').strip()] + header[1:] - if d: print "line contains key list: " + str(header) + if d: print("line contains key list: " + str(header)) # get the rows for row in reader: - if d: print row + if d: print(row) if not row: - if d: print "line is empty" + if d: print("line is empty") elif not row[0].strip(): - if d: print "line is whitespace" + if d: print("line is whitespace") #elif row[0].strip().startswith('*'): # header starts with * (store this to generate keys) # header = [x.strip(' ') for x in row] # clean up any whitespace # header = [header[0].replace('*','').strip()] + header[1:] # if d: print "line contains key list: " + str(header) elif row[0].lstrip().startswith("#"): # comments or whitespace (ignore) pass - if d: print "line is comment: "+"-".join(row) + if d: print("line is comment: "+"-".join(row)) else: # Add legit entry to list assert len(header) > 0 # should have already seen the header entry = [x.strip(' ') for x in row[:]] # clean up any whitespace assert len(header) == len(entry) # check equal number of key/val pairs - if d: print "line is CSV row: "+str(entry) + if d: print("line is CSV row: "+str(entry)) new = dict((key,val) for key,val in zip(header,entry)) - if d: print "new dict is: "+str(new) + if d: print("new dict is: "+str(new)) vglist.append(new) #print vglist @@ -251,7 +253,7 @@ def append_csv(csv_file,vglist,keys,unused_str='?',debug=False): d = debug assert vglist != [], 'empty vglist supplied: %s' %str(vglist) - print "** Appending new signals to csv file \""+csv_file+"\"" + print("** Appending new signals to csv file \""+csv_file+"\"") if os.path.isfile(csv_file): shutil.copy2(csv_file,csv_file+".bak") # copy2 preserves mod/access info @@ -263,7 +265,7 @@ def append_csv(csv_file,vglist,keys,unused_str='?',debug=False): header = [header[0].strip()] + header[1:] assert len(header) > 0, 'Header is missing in CSV file: %s' % csv_file assert all(x in header for x in keys), 'Header does not contain all keys. Header: %s, Keys: %s' % (header,keys) - if d: print "Header line contains key list: " + str(header) + if d: print("Header line contains key list: " + str(header)) fi.close() # Now append new rows to CSV, obeying order specified in header. @@ -278,7 +280,7 @@ def append_csv(csv_file,vglist,keys,unused_str='?',debug=False): else: line.append(unused_str) #line = [row[x] for x in keys] - if d: print line + if d: print(line) writer.writerow(line) fo.close() @@ -333,7 +335,7 @@ def remove_duplicates(vglist,key): val = row[key] if val in values: # duplicate! - print "**Found duplicate: "+row + print("**Found duplicate: "+row) else: new_list.append(row) values.append(row[key]) @@ -358,7 +360,7 @@ def check_complete(vglist): l = row.values() for field in l: if (field == ""): - print "** Warning: Signals list contains incomplete fields!" + print("** Warning: Signals list contains incomplete fields!") return False return True @@ -370,6 +372,10 @@ def check_keys_exist(vglist,my_keys): """ for d in vglist: if not all(key in d for key in my_keys): + print("Key ERROR") + for key in d: + print(key) + print(vglist) return False return True @@ -389,7 +395,7 @@ def test(): """ # TODO test of the verilog module reading function - print get_verilog_module_signals('../TOP.sv',debug=True) + print(get_verilog_module_signals('../TOP.sv',debug=True)) # Test reading in a list from a CSV file myvglist = read_csv('test.csv') @@ -403,9 +409,9 @@ def test(): # print x["that"] # Test check keys - print check_keys(myvglist,['this']) - print check_keys(myvglist,['this','that']) - print check_keys(myvglist,['this','that','other']) + print(check_keys(myvglist,['this'])) + print(check_keys(myvglist,['this','that'])) + print(check_keys(myvglist,['this','that','other'])) # Test appending to CSV file append_csv('test.csv',[{'this':'blah','that':'blaf'}],['this','that']) diff --git a/tools/vgen/examples/pads/vgen_pads.py b/tools/vgen/examples/pads/vgen_pads.py index 39b73f8..ed85677 100755 --- a/tools/vgen/examples/pads/vgen_pads.py +++ b/tools/vgen/examples/pads/vgen_pads.py @@ -17,7 +17,7 @@ import os; import sys; import argparse; -from vgen import *; +from CHIPKIT.tools.vgen.bin.vgen import *; # This is the minimum set of keys required for generating Verilog diff --git a/tools/vgen/examples/registers/vgen_regs.py b/tools/vgen/examples/registers/vgen_regs.py index fd4e237..3dbb65a 100755 --- a/tools/vgen/examples/registers/vgen_regs.py +++ b/tools/vgen/examples/registers/vgen_regs.py @@ -12,7 +12,7 @@ import os; import sys; import argparse; -from vgen import *; +from CHIPKIT.tools.vgen.bin.vgen import *; # This is the minimum set of keys required for generation. @@ -49,7 +49,7 @@ def update_regs_csv_from_verilog(csv_file,verilog_file,match_prefix=''): Return True if any new signals were added to csv. """ # Read in list of io signals from CSV file - print '** Reading csv_file: %s, and Verilog file: %s' % (csv_file,verilog_file) + print('** Reading csv_file: %s, and Verilog file: %s' % (csv_file,verilog_file)) csv_vglist = read_csv(csv_file) check_keys_exist(csv_vglist,regs_keys) @@ -62,18 +62,18 @@ def update_regs_csv_from_verilog(csv_file,verilog_file,match_prefix=''): # debug if (True): - print 'csv_vglist: '+str([d['name'] for d in csv_vglist]) - print 'verilog_vglist: '+str([d['name'] for d in verilog_vglist]) + print('csv_vglist: '+str([d['name'] for d in csv_vglist])) + print('verilog_vglist: '+str([d['name'] for d in verilog_vglist])) # Compare the two lists, keep signals that are in CSV and not in Verilog missing_in_verilog = find_new(verilog_vglist,csv_vglist,'name') if len(missing_in_verilog) > 0: - print 'WARNING: Found signals in CSV (%s) not in Verilog (%s): \n%s' % (csv_file,verilog_file,str([d['name'] for d in missing_in_verilog])) + print('WARNING: Found signals in CSV (%s) not in Verilog (%s): \n%s' % (csv_file,verilog_file,str([d['name'] for d in missing_in_verilog]))) # Write any new signals from Verilog back to the CSV. if new_in_verilog != []: - print 'Found new signals in Verilog file (not listed in CSV):\n %s' % str([d['name'] for d in new_in_verilog]) - print 'Updating CSV file: %s' % csv_file + print('Found new signals in Verilog file (not listed in CSV):\n %s' % str([d['name'] for d in new_in_verilog])) + print('Updating CSV file: %s' % csv_file) append_csv(csv_file,new_in_verilog,regs_keys,unused_str='') # Return true if new signals were added to FE csv @@ -110,8 +110,8 @@ def gen_regs_module(module_name,module_file,template_file,regs): # Open output file if (os.path.isfile(module_file)): # if verilog already exists, backup first shutil.copy2(module_file,module_file+".bak") # copy2 preserves mod/access info - fo = open(module_file,"wb") - print "**Writing module \""+module_name+"\" to file \""+fo.name+"\"" + fo = open(module_file,"w") + print("**Writing module \""+module_name+"\" to file \""+fo.name+"\"") fo.write(banner_start()) # Print some header info into the generated file @@ -198,7 +198,7 @@ def gen_regs_instance(module_name,instance_file,regs,clock='?clk',reset='?rstn') """ Generate an instantiation template for the register module """ fo = open(instance_file,"w") - print "**Writing module instantiation template to file \""+fo.name+"\"" + print("**Writing module instantiation template to file \""+fo.name+"\"") fo.write(banner_start()) # list of signals @@ -246,7 +246,7 @@ def gen_regs_docs(module_name,md_file,regs): """ Generate markdown documentation for the register module """ fo = open(md_file,"w") - print "**Writing module documentation to markdown file \""+fo.name+"\"" + print("**Writing module documentation to markdown file \""+fo.name+"\"") fo.write(banner_start()) # Title for the documentation @@ -296,7 +296,7 @@ def gen_regs_cheader(module_name,cheader_file,regs): """ Generate C header with definitions for the register module """ fo = open(cheader_file,"w") - print "**Writing register map to C header file \""+fo.name+"\"" + print("**Writing register map to C header file \""+fo.name+"\"") # comment line and header guards fo.write(banner_start()) @@ -356,7 +356,7 @@ def gen_regs_python(module_name,output_file,regs): """ Generate Python module with dictionary containing definitions for the register module """ fo = open(output_file,"w") - print "**Writing register map dictionary to python module \""+fo.name+"\"" + print("**Writing register map dictionary to python module \""+fo.name+"\"") # comment line and header guards fo.write("# "+banner_start()) @@ -404,7 +404,7 @@ def gen_regs_ctest(module_name,output_file,regs): # Write a header for the test fo = open(output_file[0],"w") - print "**Writing C test header (.h) file \""+fo.name+"\"" + print("**Writing C test header (.h) file \""+fo.name+"\"") # comment line and header guards fo.write(banner_start()) @@ -439,7 +439,7 @@ def gen_regs_ctest(module_name,output_file,regs): # Write out the c code for the test fo = open(output_file[1],"w") - print "**Writing C test (.c) file \""+fo.name+"\"" + print("**Writing C test (.c) file \""+fo.name+"\"") fo.write(banner_end()) # include the header @@ -528,7 +528,7 @@ def main(): args = parser.parse_args() if not (args.generate or args.update): parser.error('No action specified. Please specify an action: --update or --generate') - print 'Command line arguments: %s' + str(args) + print('Command line arguments: %s' + str(args)) # Run scripts @@ -538,14 +538,14 @@ def main(): if (args.generate): # Module name is derived from the CSV filename module = args.generate.split('.')[0] - print module + print(module) outdir = args.output # Read in the register list regs = read_csv(args.generate,debug=True) # generate verilog - gen_regs_module(module,outdir+'/'+module+'.sv','regs_template.sv',regs) + gen_regs_module(module,outdir+'/'+module+'.sv',os.path.dirname(__file__)+'/regs_template.sv',regs) gen_regs_instance(module,outdir+'/'+module+'.inst.sv',regs,clock=args.clock,reset=args.reset) gen_regs_docs(module,outdir+'/'+module+'.md',regs) gen_regs_python(module,outdir+'/'+module+'.py',regs) -- GitLab