@@ -20,6 +20,76 @@ source $OFM_PATH/build/Shared.tcl
2020# Procedures and Functions
2121# ---------------------------------------------------------------------
2222
23+ proc VivadoProcessTCLScript {IP_GEN_PATH SIM_GEN_PATH FNAME SCRIPT} {
24+ namespace upvar ::NDKBuild SIM_FLAGS SIM_FLAGS
25+
26+ set IP_NAME [file rootname [file tail $FNAME]]
27+ exec vivado -mode batch -journal ${IP_GEN_PATH}${IP_NAME}_vivado.jou -log ${IP_GEN_PATH}${IP_NAME}_vivado.log -source "$SCRIPT" -tclargs "$SIM_GEN_PATH" "$FNAME" "${SIM_FLAGS(FPGA)}"
28+ }
29+
30+ proc CompileIPCore {IP_GEN_PATH SIM_GEN_PATH FNAME} {
31+ global OFM_PATH
32+ namespace upvar ::NDKBuild SIM_FLAGS SIM_FLAGS
33+ set VIVADO_IP_BUILD [file normalize [file join $OFM_PATH/build Modelsim.ip.tcl]]
34+
35+ #IP core compiling
36+ puts "Generating IP Core file: $FNAME"
37+ if { ![regexp {^.*.xci$} $FNAME] } {
38+ return
39+ }
40+
41+ #Generate files using vivado
42+ VivadoProcessTCLScript $IP_GEN_PATH $SIM_GEN_PATH $FNAME $VIVADO_IP_BUILD
43+ }
44+
45+ # Compile vivado block design using modelsim
46+ proc CompileBlockDesign {IP_GEN_PATH SIM_GEN_PATH FNAME} {
47+ global OFM_PATH
48+ namespace upvar ::NDKBuild SIM_FLAGS SIM_FLAGS
49+ set VIVADO_BD_BUILD [file normalize [file join $OFM_PATH/build Modelsim.bd.tcl]]
50+
51+ #Block Design compiling
52+ puts "Generating Block Design file: $FNAME"
53+ if { ![regexp {^.*.bd$} $FNAME] } {
54+ return
55+ }
56+
57+ #Generate files using vivado
58+ VivadoProcessTCLScript $IP_GEN_PATH $SIM_GEN_PATH $FNAME $VIVADO_IP_BUILD
59+ }
60+
61+ proc ProcessVivadoSimCompile {COMPILE_FILE} {
62+ namespace upvar ::NDKBuild SIM_FLAGS SIM_FLAGS
63+
64+ exec /bin/sed -i {s/ xil_defaultlib/ work/g} "$COMPILE_FILE"
65+ exec /bin/sed -i {/vmap work/d} "$COMPILE_FILE"
66+
67+ source "$COMPILE_FILE"
68+ }
69+
70+ proc ProcessVivadoSimulationExport {SIM_FILE} {
71+ namespace upvar ::NDKBuild SIM_FLAGS SIM_FLAGS
72+ exec /bin/sed -i {s/ xil_defaultlib/ work/g} "$SIM_FILE"
73+ set fp [open [ glob "$SIM_FILE"]]
74+ set compile_content [read $fp]
75+ close $fp
76+
77+ regexp -line {^vsim .*$} "$compile_content" vsim_content
78+ #Regex starting with - must be escaped in tcl ?
79+ regexp {\-(?:[^-\s])+(?:\s(?:[^-\s])+){2}((?:\s[^-\s]+)*)$} "$vsim_content" modules_match modules
80+ set libraries_match [ regexp -all -inline {(?:-L ([^-\s]+))} "$vsim_content" ]
81+ set libraries [ lmap {match group} $libraries_match { set group } ]
82+
83+ if {[info exists libraries]} {
84+ puts "Adding Libs: $libraries"
85+ lappend SIM_FLAGS(SIM_LIB) {*}$libraries
86+ }
87+ if {[info exists modules]} {
88+ puts "Adding Modules: $modules"
89+ lappend SIM_FLAGS(SIM_MODULE) {*}$modules
90+ }
91+ }
92+
2393# Decide which command should be used for particular file
2494proc CompileMod {FNAME OPT} {
2595 namespace upvar ::NDKBuild SIM_FLAGS SIM_FLAGS
@@ -46,32 +116,45 @@ proc CompileMod {FNAME OPT} {
46116 }
47117
48118 # Generate netlists for utilized Vivado IP cores
119+ # TCL Debug trace: trace add execution source enterstep {apply {{cmd op} {puts "+ $cmd"}}}
49120 if {$opt(TYPE) == "VIVADO_IP_XACT"} {
50- set IP_GEN_PATH "$SIM_FLAGS(SIM_MODULE)-${SIM_FLAGS(FPGA)}.vivado_ip_tmp/"
51- file mkdir $IP_GEN_PATH
52-
53- # Initialization
121+ if { ![file exist "modelsim_lib"] } {
122+ file mkdir "modelsim_lib"
123+ }
54124 set IP_NAME [file rootname [file tail $FNAME]]
55- set IP_GEN_SCRIPT ${IP_GEN_PATH}${IP_NAME}_netlist_gen.tcl
56- if {[file exists $IP_GEN_SCRIPT]} {
57- puts "$IP_GEN_SCRIPT exists, assume IP core's netlist has already been generated"
58- return
125+ set SIM_GET_FOLDER "gen_sim"
126+ set IP_GEN_PATH "${SIM_FLAGS(FPGA)}.vivado_ip_tmp/"
127+ set SIM_GEN_PATH [file join "$IP_GEN_PATH" "$IP_NAME" ]
128+ set compile_do [file join "$SIM_GEN_PATH" "*/modelsim/compile.do" ]
129+ set simulate_do [file join "$SIM_GEN_PATH" "*/modelsim/simulate.do" ]
130+ try { glob "$compile_do" } trap {TCL OPERATION GLOB NOMATCH} {} { set generate "" }
131+
132+ if {[info exists generate]} {
133+ CompileIPCore "$IP_GEN_PATH" "$SIM_GEN_PATH" "$FNAME"
59134 }
60- PrintLabel "IP Netlist Generation ($IP_NAME)"
61-
62- # Prepare netlist generation Tcl script for Vivado
63- exec echo "
64- create_project -in_memory -part $SIM_FLAGS(FPGA)
65- set_property target_language VHDL \[current_project\]
66- read_ip $FNAME
67- upgrade_ip \[get_ips $IP_NAME\]
68- set_property GENERATE_SYNTH_CHECKPOINT TRUE \[get_files $FNAME\]
69- synth_ip \[get_ips $IP_NAME\]
70- quit
71- " > $IP_GEN_SCRIPT
72-
73- # Generate netlist using Vivado
74- exec vivado -mode tcl -journal ${IP_GEN_PATH}${IP_NAME}_vivado.jou -log ${IP_GEN_PATH}${IP_NAME}_vivado.log -source $IP_GEN_SCRIPT >&@stdout
135+ set compile_glob_do [ glob "$compile_do" ]
136+ ProcessVivadoSimCompile "$compile_glob_do"
137+ ProcessVivadoSimulationExport "$simulate_do"
138+ return;
139+ } elseif {$opt(TYPE) == "VIVADO_BD"} {
140+ if { ![file exist "modelsim_lib"] } {
141+ file mkdir "modelsim_lib"
142+ }
143+ set BD_NAME [file rootname [file tail $FNAME]]
144+ set SIM_GET_FOLDER "gen_sim"
145+ set BD_GEN_PATH "${SIM_FLAGS(FPGA)}.vivado_ip_tmp/"
146+ set SIM_GEN_PATH [file join "$BD_GEN_PATH" "$BD_NAME" ]
147+ set compile_do [file join "$SIM_GEN_PATH" "*/modelsim/compile.do" ]
148+ set simulate_do [file join "$SIM_GEN_PATH" "*/modelsim/simulate.do" ]
149+ try { glob "$compile_do" } trap {TCL OPERATION GLOB NOMATCH} {} { set generate "" }
150+
151+ if {[info exists generate]} {
152+ CompileBlockDesign "$BD_GEN_PATH" "$SIM_GEN_PATH" "$FNAME"
153+ }
154+ set compile_glob_do [ glob "$compile_do" ]
155+ ProcessVivadoSimCompile "$compile_glob_do"
156+ ProcessVivadoSimulationExport "$simulate_do"
157+ return;
75158 }
76159
77160 # Skip unknown file types
@@ -90,13 +173,21 @@ proc CompileMod {FNAME OPT} {
90173 lappend opt(VLOG_SV_FLAGS)
91174
92175 # Source compiling
93- if {$FEXT in [list .v .vh]} {
176+ if {$FEXT in [list .vh .svh]} {
177+ return
178+ } elseif {$FEXT in [list .v]} {
94179 set CMD [list vlog {*}$COVER_PARAMS -timescale "1ps/1ps" -work $LIB]
95180 } elseif {$FEXT in [list .sv]} {
181+ # Add simulation libarries to .sv files to allow use of modules generated by .ip and .bds
182+ set SV_LIBS ""
183+ foreach i [uniqueList $SIM_FLAGS(SIM_LIB)] {
184+ lappend SV_LIBS -L "$i"
185+ }
186+
96187 regsub "/\[^/\]+\$" $FNAME "/" DIR
97- set CMD [list vlog $VMAKE_OPT {*}$COVER_PARAMS_SV -sv -timescale "1ps/1ps" -work $LIB +incdir+$DIR {*}$SIM_FLAGS(VLOG_SV_FLAGS) {*}$opt(VLOG_SV_FLAGS)]
98- } else {
99- set CMD [list vcom -2008 -explicit {*}$COVER_PARAMS -work $LIB]
188+ set CMD [list vlog $VMAKE_OPT {*}$COVER_PARAMS_SV -sv -timescale "1ps/1ps" -work $LIB +incdir+$DIR $SV_LIBS {*}$SIM_FLAGS(VLOG_SV_FLAGS) {*}$opt(VLOG_SV_FLAGS)]
189+ } elseif {$FEXT in [list .vhd]} {
190+ set CMD [list vcom -mixedsvvh b - 2008 -explicit {*}$COVER_PARAMS -work $LIB]
100191 }
101192
102193 if {$SIM_FLAGS(BATCH_COMPILE)} {
@@ -316,6 +407,7 @@ proc nb_vsim_set_flags {vsim_flags sim_flags} {
316407}
317408
318409proc nb_sim_main {{user_sim_flags SIM_FLAGS}} {
410+
319411 # Let VSIM_FLAGS variable to be accessible in top level stack frame for running vsim by hand
320412 upvar 1 VSIM_FLAGS VSIM_FLAGS
321413
@@ -339,6 +431,7 @@ proc nb_sim_main {{user_sim_flags SIM_FLAGS}} {
339431
340432 # Run simulation
341433 if {!$SIM_FLAGS(VSIM_MANUAL_START)} {
434+ puts "vsim {*}$VSIM_FLAGS"
342435 vsim {*}$VSIM_FLAGS
343436 }
344437}
0 commit comments