diff options
author | Andrew Moch <Andrew.Moch@ni.com> | 2020-03-11 19:39:06 +0100 |
---|---|---|
committer | Wade Fife <wade.fife@ettus.com> | 2020-03-20 10:34:59 -0500 |
commit | b296b26053d4437b8ae97e3df415a3d041b7b51e (patch) | |
tree | fa34231aec17809dff523d81aa513a7f990069a5 | |
parent | 07b85b6dcc6e84f42da3579b65692a3d4ba04e38 (diff) | |
download | uhd-b296b26053d4437b8ae97e3df415a3d041b7b51e.tar.gz uhd-b296b26053d4437b8ae97e3df415a3d041b7b51e.tar.bz2 uhd-b296b26053d4437b8ae97e3df415a3d041b7b51e.zip |
fpga: tools: Add modelsim to make sim targets
This adds a simulation make target that allows you to run ModelSim
natively rather than through Vivado.
Adds or modifies the following simulation make targets:
make vlint - Brake up compilation to Verilog/SystemVerilog/VHDL
make modelsim - Depends on make vlint and invokes modelsim
Adds the following variables:
MODELSIM_ARGS - Added to invocation of ModelSim
SVLOG_ARGS - Added to SystemVerilog invocation of vlog
VLOG_ARGS - Added to Verilog invocation of vlog
VHDL_ARGS - Added to VHDL invocation of vcom
-rw-r--r-- | fpga/docs/usrp3/sim/running_testbenches.md | 5 | ||||
-rw-r--r-- | fpga/usrp3/tools/make/viv_sim_preamble.mak | 26 | ||||
-rw-r--r-- | fpga/usrp3/tools/make/viv_simulator.mak | 99 | ||||
-rw-r--r-- | fpga/usrp3/tools/scripts/viv_sim_project.tcl | 32 |
4 files changed, 127 insertions, 35 deletions
diff --git a/fpga/docs/usrp3/sim/running_testbenches.md b/fpga/docs/usrp3/sim/running_testbenches.md index 2e2068e5e..4afd66fe0 100644 --- a/fpga/docs/usrp3/sim/running_testbenches.md +++ b/fpga/docs/usrp3/sim/running_testbenches.md @@ -17,8 +17,9 @@ all supported simulator targets. Currently, the following targets will work: cleanall: Cleanup everything! xsim: Run the simulation using the Xilinx Vivado Simulator xclean: Cleanup Xilinx Vivado Simulator intermediate files - vsim: Run the simulation using Modelsim - vclean: Cleanup Modelsim intermediate files + vsim: Run the simulation using ModelSim simulator via Vivado + modelsim: Runs the simulation using ModelSim without Vivado + vclean: Cleanup ModelSim intermediate files ## Using Xilinx Vivado XSim diff --git a/fpga/usrp3/tools/make/viv_sim_preamble.mak b/fpga/usrp3/tools/make/viv_sim_preamble.mak index 47ad153f4..afeca0b3c 100644 --- a/fpga/usrp3/tools/make/viv_sim_preamble.mak +++ b/fpga/usrp3/tools/make/viv_sim_preamble.mak @@ -9,11 +9,16 @@ SIM_RUNTIME_US = 1000000000 # ------------------------------------------------------------------- # Setup simulation # ------------------------------------------------------------------- + # Define part using PART_ID (<device>/<package>/<speedgrade>) # and architecture (zynq, kintex7, or artix7) -# User can override these if needed -ARCH = kintex7 -PART_ID = xc7k410t/ffg900/-2 +# +# Most simulations are part agnostic, but the user can override +# these if needed in the makefile in the simulation directory +# +# TODO : Update to set from setupenv.sh +ARCH ?= kintex7 +PART_ID ?= xc7k410t/ffg900/-2 # Include makefiles and sources for the DUT and its dependencies include $(BASE_DIR)/../lib/sim/Makefile.srcs @@ -36,14 +41,18 @@ $(SIM_RFNOC_SRCS) \ # Predeclare RFNOC_OOT_SRCS to make sure it's not recursively expanded RFNOC_OOT_SRCS := +# Debug target +vars:: + env + @echo "ARCH=$(ARCH)" + @echo "PART_ID=$(PART_ID)" + all: $(error "all" or "<empty>" is not a valid target. Run make help for a list of supported targets.) ipclean: @rm -rf $(abspath ./build-ip) -cleanall: ipclean clean - help:: @echo "-----------------" @echo "Supported Targets" @@ -51,10 +60,7 @@ help:: @echo "ipclean: Cleanup all IP intermediate files" @echo "clean: Cleanup all simulator intermediate files" @echo "cleanall: Cleanup everything!" - @echo "vsim: Simulate with Modelsim" - @echo "vlint: Lint simulation files with Modelsim's Verilog compiler" - @echo "vclean: Cleanup Modelsim's intermediates files" - @echo "xsim: Simulate with Vivado's XSIM simulator" - @echo "xclean: Cleanup Vivado's XSIM intermediate files" + +cleanall: ipclean clean .PHONY: ipclean cleanall help diff --git a/fpga/usrp3/tools/make/viv_simulator.mak b/fpga/usrp3/tools/make/viv_simulator.mak index add3e651d..3ee4a727c 100644 --- a/fpga/usrp3/tools/make/viv_simulator.mak +++ b/fpga/usrp3/tools/make/viv_simulator.mak @@ -28,12 +28,62 @@ PART_NAME=$(subst /,,$(PART_ID)) # Usage: SETUP_AND_LAUNCH_SIMULATION # Args: $1 = Simulator Name # ------------------------------------------------------------------- + +# Resolve path +EXP_DESIGN_SRCS = $(call RESOLVE_PATHS,$(DESIGN_SRCS)) +EXP_SIM_SRCS = $(call RESOLVE_PATHS,$(SIM_SRCS)) +EXP_INC_SRCS = $(call RESOLVE_PATHS,$(INC_SRCS)) + +# (NOQ) No quotes! +NOQ_DESIGN_SRCS := $(subst $\",,$(EXP_DESIGN_SRCS)) +NOQ_SIM_SRCS := $(subst $\",,$(EXP_SIM_SRCS)) +NOQ_INC_SRCS := $(subst $\",,$(EXP_INC_SRCS)) + +# Separate out VHDL +NOQ_DESIGN_VHDL := $(filter %.vhd,$(NOQ_DESIGN_SRCS)) +NOQ_SIM_VHDL := $(filter %.vhd,$(NOQ_SIM_SRCS)) +NOQ_VHDL := $(NOQ_DESIGN_VHDL) $(NOQ_SIM_VHDL) + +# Separate out System Verilog +NOQ_DESIGN_SV := $(filter %.sv,$(NOQ_DESIGN_SRCS)) +NOQ_SIM_SV := $(filter %.sv,$(NOQ_SIM_SRCS)) +NOQ_SV := $(NOQ_DESIGN_SV) $(NOQ_SIM_SV) +# Fetch packages from include list to compile +NOQ_PKG_SV := $(filter %.sv,$(NOQ_INC_SRCS)) + +# Seperate out Verilog +NOQ_INC_DIRS := $(sort $(dir $(NOQ_INC_SRCS))) +NOQ_DESIGN_VERILOG := $(filter %.v,$(NOQ_DESIGN_SRCS)) +NOQ_SIM_VERILOG := $(filter %.v,$(NOQ_SIM_SRCS)) +NOQ_VERILOG := $(NOQ_DESIGN_VERILOG) $(NOQ_SIM_VERILOG) + +# Modelsim Load libraries +MODELSIM_LIBS += unisims_ver + +# Arguments for various simulators +MODELSIM_ARGS += -quiet +SVLOG_ARGS += -quiet +SVLOG_ARGS += +define+WORKING_DIR="\"${CURDIR}\"" +VLOG_ARGS += -quiet +VLOG_ARGS += +define+WORKING_DIR="\"${CURDIR}\"" +VHDL_ARGS += -quiet + +# Working directory for standalone ModelSim execution +MODELSIM_PROJ_DIR ?= modelsim_proj + +# Check if we want to load the ModelSim GUI +ifeq ($(GUI), 1) + MODELSIM_ARGS += -do "run -all" +else + MODELSIM_ARGS += -c -do "run -all; quit -f" +endif + SETUP_AND_LAUNCH_SIMULATION = \ @ \ export VIV_SIMULATOR=$1; \ - export VIV_DESIGN_SRCS=$(call RESOLVE_PATHS,$(DESIGN_SRCS)); \ - export VIV_SIM_SRCS=$(call RESOLVE_PATHS,$(SIM_SRCS)); \ - export VIV_INC_SRCS=$(call RESOLVE_PATHS,$(INC_SRCS)); \ + export VIV_DESIGN_SRCS=$(EXP_DESIGN_SRCS); \ + export VIV_SIM_SRCS=$(EXP_SIM_SRCS); \ + export VIV_INC_SRCS=$(EXP_INC_SRCS); \ export VIV_SIM_TOP=$(SIM_TOP); \ export VIV_SYNTH_TOP="$(SYNTH_DUT)"; \ export VIV_PART_NAME=$(PART_NAME); \ @@ -61,20 +111,51 @@ xclean: @rm -f xvlog.pb @rm -f vivado_pid*.str -##vsim: Run the simulation using Modelsim +##vsim: Run the simulation using ModelSim (via vivado) vsim: .check_tool $(COMPLIBDIR) $(DESIGN_SRCS) $(SIM_SRCS) $(INC_SRCS) $(call SETUP_AND_LAUNCH_SIMULATION,Modelsim) -##vlint: Run verilog compiler to lint files. -vlint: .check_tool - @vlog $(SIM_SRCS) +incdir+$(BASE_DIR)/../sim/axi +incdir+$(BASE_DIR)/../sim/general +incdir+$(BASE_DIR)/../sim/control +incdir+$(BASE_DIR)/../sim/rfnoc +incdir+$(BASE_DIR)/../lib/rfnoc +##modelsim: Run the simulation using Modelsim (natively) +modelsim: .check_tool vlint + cd $(MODELSIM_PROJ_DIR) && vsim $(MODELSIM_ARGS) $(foreach lib,$(MODELSIM_LIBS),-L $(lib)) $(SIM_TOP) -##vclean: Cleanup Modelsim intermediate files + +# NOTE: VHDL files require a correct compile order. This script compiles files +# in the order they are defined in $(DESIGN_SRC), then $SIM_SRC) + +##vlint: Run ModelSim compiler to lint files. +vlint: .check_tool $(COMPLIBDIR) $(DESIGN_SRCS) $(SIM_SRCS) $(INC_SRCS) + $(shell mkdir -p ./modelsim_proj) + $(file >modelsim_proj/svlogarglist.txt,/* Auto generated argument file for vlog -sv */) + $(file >>modelsim_proj/svlogarglist.txt,-sv) + $(foreach dir,$(NOQ_INC_DIRS), $(file >>modelsim_proj/svlogarglist.txt,+incdir+$(dir))) + $(foreach src,$(NOQ_PKG_SV), $(file >>modelsim_proj/svlogarglist.txt,$(src))) + $(foreach src,$(NOQ_SV), $(file >>modelsim_proj/svlogarglist.txt,$(src))) + $(file >modelsim_proj/vlogarglist.txt,/* Auto generated argument file for vlog */) + $(file >>modelsim_proj/vlogarglist.txt,-vlog01compat) + $(foreach dir,$(NOQ_INC_DIRS), $(file >>modelsim_proj/vlogarglist.txt,+incdir+$(dir))) + $(foreach src,$(NOQ_VERILOG), $(file >>modelsim_proj/vlogarglist.txt,$(src))) + $(file >modelsim_proj/vcomarglist.txt,/* Auto generated argument file for vcom */) + $(file >>modelsim_proj/vcomarglist.txt,-2008) + $(foreach src,$(NOQ_VHDL),$(file >>modelsim_proj/vcomarglist.txt,$(src))) +ifneq ($(strip $(NOQ_SV)),) + @echo "*** COMPILING SYSTEM VERILOG ***" + cd $(MODELSIM_PROJ_DIR) && vlog $(SVLOG_ARGS) -f svlogarglist.txt +endif +ifneq ($(strip $(NOQ_VERILOG)),) + @echo "*** COMPILING VERILOG ***" + cd $(MODELSIM_PROJ_DIR) && vlog $(VLOG_ARGS) -f vlogarglist.txt +endif +ifneq ($(strip $(NOQ_VHDL)),) + @echo "*** COMPILING VHDL ***" + cd $(MODELSIM_PROJ_DIR) && vcom $(VHDL_ARGS) -f vcomarglist.txt +endif + +##vclean: Cleanup ModelSim intermediate files vclean: @rm -f modelsim*.log @rm -rf modelsim_proj @rm -f vivado_pid*.str - @rm -rf work # Use clean with :: to support allow "make clean" to work with multiple makefiles clean:: xclean vclean diff --git a/fpga/usrp3/tools/scripts/viv_sim_project.tcl b/fpga/usrp3/tools/scripts/viv_sim_project.tcl index f2d071f10..b524e332c 100644 --- a/fpga/usrp3/tools/scripts/viv_sim_project.tcl +++ b/fpga/usrp3/tools/scripts/viv_sim_project.tcl @@ -125,21 +125,25 @@ if [expr [string equal $simulator "Modelsim"] == 1] { # Launch simulation launch_simulation -# Synthesize requested modules -foreach synth_top "$::env(VIV_SYNTH_TOP)" { - set_property top $synth_top [current_fileset] - synth_design -mode out_of_context - # Perform a simple regex-based search for all clock signals and constrain - # them to 500 MHz for the timing report. - set clk_regexp "(?i)^(?!.*en.*).*(clk|clock).*" - foreach clk_inst [get_ports -regexp $clk_regexp] { - create_clock -name $clk_inst -period 2.0 [get_ports $clk_inst] - } - report_utilization -no_primitives -file ${working_dir}/${synth_top}_synth.rpt - report_timing_summary -setup -max_paths 3 -unique_pins -no_header -append -file ${working_dir}/${synth_top}_synth.rpt - write_checkpoint -force ${working_dir}/${synth_top}_synth.dcp +if { [info exists ::env(VIV_SYNTH_TOP)] } { + puts "BUILDER: Synthesizing" + # Synthesize requested modules + foreach synth_top "$::env(VIV_SYNTH_TOP)" { + set_property top $synth_top [current_fileset] + synth_design -mode out_of_context + # Perform a simple regex-based search for all clock signals and constrain + # them to 500 MHz for the timing report. + set clk_regexp "(?i)^(?!.*en.*).*(clk|clock).*" + foreach clk_inst [get_ports -regexp $clk_regexp] { + create_clock -name $clk_inst -period 2.0 [get_ports $clk_inst] + } + report_utilization -no_primitives -file ${working_dir}/${synth_top}_synth.rpt + report_timing_summary -setup -max_paths 3 -unique_pins -no_header -append -file ${working_dir}/${synth_top}_synth.rpt + write_checkpoint -force ${working_dir}/${synth_top}_synth.dcp + } +} else { + puts "BUILDER: Skipping resource report because VIV_SYNTH_TOP is not set" } - # Close project if [string equal $vivado_mode "batch"] { puts "BUILDER: Closing project" |