-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmake_nvc.py
More file actions
145 lines (138 loc) · 5.1 KB
/
make_nvc.py
File metadata and controls
145 lines (138 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
################################################################################
# make_nvc.py
# A part of make-fpga - see https://github.com/amb5l/make-fpga
# This script generates makefiles to simulate FPGA designs with NVC.
################################################################################
import sys,os,argparse
from make_fpga import *
# parse arguments
parser = argparse.ArgumentParser(
prog='make_nvc.py',
description='Create makefiles for simulating FPGA designs with NVC',
epilog=help_run,
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument(
'--lib',
nargs='+',
action='append',
help='precompiled libraries'
)
parser.add_argument(
'--vhdl',
choices=['1993','2000','2002','2008','2019'],
help='VHDL LRM version (defaults to 2008)',
default='2008'
)
parser.add_argument(
'--work',
help='work library (defaults to "work")',
default='work'
)
parser.add_argument(
'--src',
required=True,
nargs='+',
action='append',
help='source(s) in compile order (append =LIB to specify library name)'
)
parser.add_argument(
'--dep',
nargs='+',
action='append',
help='other dependancies e.g. data files'
)
parser.add_argument(
'--run',
required=True,
nargs='+',
action='append',
help='simulation run specification(s) (see below)'
)
parser.add_argument(
'--gen',
nargs='+',
action='append',
help='generics assignment(s) (applied to all runs)'
)
args=parser.parse_args()
c,d=process_src(args.src,args.work)
args.dep=flatten(args.dep)
runs=process_run(flatten(args.run))
args.lib=flatten(args.lib)
args.gen=process_gen(flatten(args.gen))
# output
print('# makefile generated by make_nvc.py (see https://github.com/amb5l/make-fpga)')
print('# for simulation using ModelSim/Questa/etc')
print('')
print('################################################################################')
print('# simulation specific definitions')
print('')
print('# libraries to compile source into')
print('LIB:='+' '.join(d))
print('')
print('# sources in compilation order (source=library)')
print('SRC:='+var_vals([s+'='+l for l,s in c]))
print('')
print('# other simulation prerequisites (e.g. data files)')
print('DEP:='+var_vals(args.dep))
print('')
print('# simulation runs (top plus any run specific generic/SDF assignments)')
print('RUNS:='+' '.join([r[0] for r in runs]))
for r in runs:
s = 'RUN.'+r[0]+':='+r[1]
if r[2]:
s += ' '+' '.join(['-g'+g+'='+v for g,v in r[2]])
if r[3]:
s += ' '+' '.join(['-sdf'+t+' '+p+'='+f for t,p,f in r[3]])
print(s)
print('')
print('# generic assignments (applied to all simulation runs)')
print('GEN:='+var_vals(list(map(lambda e: '-g'+e[0]+'='+e[1],args.gen))))
print('')
print('# global, analysis, elaboration and run options')
print('NVC_GOPTS+=--std='+args.vhdl+' -L.')
print('NVC_AOPTS+=--relaxed')
print('NVC_EOPTS+=')
print('NVC_ROPTS+=--ieee-warnings=off')
print('')
print('################################################################################')
print('')
print('# default goal')
print('all: nvc')
print('')
print('# default name for single run')
print('RUN:=$(if $(word 2,$(RUN)),$(RUN),$(if $(filter :,$(RUN)),$(RUN),sim:$(RUN)))')
print('')
print('# useful definitions')
print('comma:=,')
print('rest=$(wordlist 2,$(words $1),$1)')
print('chop=$(wordlist 1,$(words $(call rest,$1)),$1)')
print('src_dep=$1,$2')
print('pairmap=$(and $(strip $2),$(strip $3),$(call $1,$(firstword $2),$(firstword $3)) $(call pairmap,$1,$(call rest,$2),$(call rest,$3)))')
print('')
print('# compilation dependencies enforce compilation order')
print('dep:=$(firstword $(SRC)), $(if $(word 2,$(SRC)),$(call pairmap,src_dep,$(call rest,$(SRC)),$(call chop,$(SRC))),)')
print('')
print('# generate rule(s) and recipe(s) to compile source(s)')
print('define rr_compile')
print('$1/$(notdir $2).com: $2 $3 $(DEP)')
print('\tnvc $(NVC_GOPTS) --work=$(strip $1) -a $(NVC_AOPTS) $$<')
print('\ttouch $$@')
print('endef')
print('$(foreach d,$(dep),$(eval $(call rr_compile, \\')
print('$(word 2,$(subst =, ,$(word 1,$(subst $(comma), ,$d)))), \\')
print('$(word 1,$(subst =, ,$(word 1,$(subst $(comma), ,$d)))), \\')
print('$(addsuffix .com,$(addprefix $(word 2,$(subst =, ,$(word 2,$(subst $(comma), ,$d))))/,$(notdir $(word 1,$(subst =, ,$(word 2,$(subst $(comma), ,$d))))))) \\')
print(')))')
print('')
print('# generate rule(s) and recipe(s) to run simulation(s)')
print('define rr_run')
print('$1: $(word 2,$(subst =, ,$(lastword $(SRC))))/$(notdir $(word 1,$(subst =, ,$(lastword $(SRC))))).com')
print(' @bash -c \'echo -e "\033[0;32mRUN: $1 ($(word 1,$(RUN.$1))) start at $$$$(date +%T.%2N)\033[0m"\'')
print(' nvc $(NVC_GOPTS) -e $(NVC_EOPTS) $(GEN) $(RUN.$1)')
print(' nvc $(NVC_GOPTS) -r $(NVC_ROPTS) $(word 1,$(RUN.$1))')
print(' @bash -c \'echo -e "\033[0;31mRUN: $1 ($(word 1,$(RUN.$1))) end at $$$$(date +%T.%2N)\033[0m"\'')
print('nvc:: $1')
print('endef')
print('$(foreach r,$(RUNS),$(eval $(call rr_run,$r)))')