2016-07-21 47 views
1

所以我試圖寫一個Makefile以與QuestaSim和systemverilog文件一起使用。如果你不知道那是什麼(而大多數人不會),那麼別擔心,這與我的問題沒有關係。如何編寫一個生成文件,其中編譯後的目標文件位於具有不同名稱的不同目錄中?

我有一個包含項目總監:SRC /工作/ Makefile中

src /目錄中包含幾個目錄,每個包含的源文件。

工作/目錄不存在最初,由生成文件創建。

當我把我的「編譯」這就是所謂的VLOG,在目錄上獲取的工作文件夾具有相同的名稱作爲不帶後綴的.sv文件中創建一個.sv文件。在那個目錄中有三個文件,我將用作我的「對象」文件的文件是_primary.dat。

例如,調用「vlog src/interface/my_interface.sv」創建(如果成功) /my_interface/_primary.dat

我.sv文件還需要按照特定的順序進行編譯,而我只想編譯它們如果源文件或他們的依賴的一個改變。

我可以把使用「$(addsuffix /_primary.dat,$(addprefix $(VLIB_DIR)/,$(basename $(notdir $(SRC)))))將.sv文件的路徑導入到相關_primary.dat文件的路徑中。 「但是相反的情況是不可能的,因爲我們沒有目錄結構。」

所以我想我想要的是某種來自object - > src的映射。因此,在我的$(OBJ)目標中,我可以執行「vlog $(getsrc $ @)」。

之後,我必須處理編譯順序和依賴關係,但我大概可以工作了這一點。

有什麼建議嗎?

+0

1)是否有源名稱衝突的危險?也就是說,如果有'src/interface/foo.sv',那麼是否還會有'src/engine/foo.sv'? 2)'src /'可以超過兩層深嗎?也就是說,有沒有'src/foo/bar/baz.sv'? – Beta

+0

我要求包/接口/模塊具有與文件相同的名稱。所以任何衝突都會導致編譯錯誤。目前這些目錄只有兩層,但我可能會考慮稍後添加更多層。 –

+0

你有沒有看過Questa自帶的'vmake'工具? –

回答

0

我發現了一個可行的解決方案。我不確定它是最好的,但我會在這裏發佈它來幫助有這個問題的其他人。

基本上,我創建了一個宏以兩個參數:.sv源文件路徑和名稱,以及依賴列表。這將源文件路徑轉換爲目標文件路徑並將其創建爲目標。依賴於源文件和任何依賴關係。然後我創建一個包含我所有源的列表的變量。最後我做:$(foreach src,$(SRCS),$(eval $(call create_target_for,$(src)))),它創建了我所有的目標。

此外,我有每個子目錄作爲一個僞目標,與相關的依賴關係,讓我得到目錄正確的編譯順序。

唯一缺少的是,如果我需要確保在一個單一的目錄中的文件有正確的編譯順序。

我的Makefile:

# Makefile for use in building all my UVM components 
# ---------------------------------------------------------------------------------- 
# Requirements: 
# QuestaSim - We use the vlog compiler packaged with QuestaSim. 
#  ModelSim also comes with vlog, but doesn't really support UVM. 
# UVM_INCLUDE_DIR environment var - This should point to the UVM src directory. 
#  For me this is: C:\questasim_10.0b\verilog_src\uvm-1.0p1\src 
# ---------------------------------------------------------------------------------- 
# Notes: 
# The vlog compiler creates an output folder in the VLIB_DIR directors 
# per package/module/interface with the same name as the entity 
# Any capitals are replace with @ followed by the lower case letter 
# IE. FooBar -> @[email protected] 
# This makefile requires that: 
#  All interfaces end in _if 
#  All packages end in _pkg 
#  Each file can only contain a single interface, package or module 
#  No capitals in package/module/interface naems 
#  The package/module/interface has the same name as the file 

# some variabls to use later 
VLIB_DIR = ./work 
VLOG_FLAGS = +incdir+$(UVM_INCLUDE_DIR) 

# src files - per directory for use with compile orders 
#    ie. transactions have to be compiled before drivers 
INTERFACE_SRCS  = $(wildcard src/interfaces/*.sv) 
CONFIG_SRCS   = $(wildcard src/configs/*.sv) 
TRANSACTION_SRCS = $(wildcard src/transactions/*.sv) 
SEQUENCE_SRCS  = $(wildcard src/sequences/*.sv) 
DRIVER_SRCS   = $(wildcard src/drivers/*.sv) 
MONITOR_SRCS  = $(wildcard src/monitors/*.sv) 
AGENT_SRCS   = $(wildcard src/agents/*.sv) 
SCOREBOARD_SRCS  = $(wildcard src/scoreboards/*.sv) 

# all source files - for use with creating makefile targets 
SRCS    = $(INTERFACE_SRCS) \ 
         $(CONFIG_SRCS) \ 
         $(TRANSACTION_SRCS) \ 
         $(SEQUENCE_SRCS) \ 
         $(DRIVER_SRCS) \ 
         $(MONITOR_SRCS) \ 
         $(AGENT_SRCS) \ 
         $(SCOREBOARD_SRCS) 

# list of all the components 
COMPONENTS = interfaces \ 
       configs \ 
       transactions \ 
       sequences \ 
       drivers \ 
       monitors \ 
       agents \ 
       scoreboards 

# colours for use in echo commands for highlighting 
COLOUR_NONE  = \x1b[0m 
COLOUR_RED  = \x1b[31;01m 
COLOUR_BLUE  = \x1b[34;01m 
COLOUR_GREEN = \x1b[32;01m 

# macros to turn a .sv file into the compiled file in the relevant VLIB_DIR subdirectory 
# src/abc/def.sv -> $(VLIB_DIR)/def/_primary.dat 
src2obj  = $(addsuffix /_primary.dat, $(addprefix $(VLIB_DIR)/, $(basename $(notdir $(1))))) 

# macro to create a target for a given source file 
# it takes two arguments: 
# 1) the path and name of the source file 
# 2) any dependencies 
# It then creates a traget on the relevant _primary.dat (questaSim created object) 
# with a dependency on the source file, and any other passed in dependencies 
define create_target_for 

$$(info $COLOUR_GREEN create_target_for called on $(1)) 
$$(info creating target $(call src2obj, $(1))) 
$$(info with dependencies $(VLIB_DIR) $(1) $(2)) 
$$(info) 
$(call src2obj, $(1)): $(1) $(2) 
    @echo -e "$(COLOUR_BLUE)compiling $(1) because of changes in: $$? $(COLOUR_NONE)\n" 
    vlog $(VLOG_FLAGS) $(1) 

endef 

# default rule is to create the library, compile the UVM pkg and all the components 
all: $(VLIB_DIR) UVM $(COMPONENTS) 

# create the questaSim library if it's not already there 
$(VLIB_DIR): 
    vlib $(VLIB_DIR) 
    @echo -e "$(COLOUR_GREEN)Created the $(VLIB_DIR) library$(COLOUR_NONE)\n" 

# compile the UVM library 
$(VLIB_DIR)/uvm_pkg/_primary.dat: 
    vlog +incdir+$(UVM_INCLUDE_DIR) $(UVM_INCLUDE_DIR)/uvm.sv 
    @echo -e "$(COLOUR_GREEN)Compiled the UVM package$(COLOUR_NONE)\n" 

# simple alias 
UVM: $(VLIB_DIR) $(VLIB_DIR)/uvm_pkg/_primary.dat 

# create targets for all our sources 
# note with this method we can't set dependencies within a single directory 
$(foreach src,$(SRCS),$(eval $(call create_target_for, $(src)))) 

# define a phony target per directory so we can specify compile order 
interfaces: $(VLIB_DIR) UVM \ 
      $(call src2obj, $(INTERFACE_SRCS)) 
    @echo -e "$(COLOUR_GREEN)Compiled all [email protected]$(COLOUR_NONE)\n" 

configs: $(VLIB_DIR) UVM \ 
     $(call src2obj, $(CONFIG_SRCS)) 
    @echo -e "$(COLOUR_GREEN)Compiled all [email protected]$(COLOUR_NONE)\n" 

transactions: $(VLIB_DIR) UVM \ 
       $(call src2obj, $(TRANSACTION_SRCS)) 
    @echo -e "$(COLOUR_GREEN)Compiled all [email protected]$(COLOUR_NONE)\n" 

sequences: $(VLIB_DIR) UVM \ 
      transactions \ 
      $(call src2obj, $(SEQUENCE_SRCS)) 
    @echo -e "$(COLOUR_GREEN)Compiled all [email protected]$(COLOUR_NONE)\n" 

drivers: $(VLIB_DIR) UVM \ 
     transactions interfaces \ 
     $(call src2obj, $(DRIVER_SRCS)) 
    @echo -e "$(COLOUR_GREEN)Compiled all [email protected]$(COLOUR_NONE)\n" 

monitors: $(VLIB_DIR) UVM \ 
      transactions interfaces \ 
      $(call src2obj, $(MONITOR_SRCS)) 
    @echo -e "$(COLOUR_GREEN)Compiled all [email protected]$(COLOUR_NONE)\n" 

agents: $(VLIB_DIR) UVM \ 
     drivers monitors transactions configs interfaces \ 
     $(call src2obj, $(AGENT_SRCS)) 
    @echo -e "$(COLOUR_GREEN)Compiled all [email protected]$(COLOUR_NONE)\n" 

scoreboards: $(call src2obj, $(SCOREBOARD_SRCS)) 
    @echo -e "$(COLOUR_GREEN)Compiled all [email protected]$(COLOUR_NONE)\n" 

# delete the library and all compiled files 
clean: 
    if [ -d $(VLIB_DIR) ]; then vdel -lib $(VLIB_DIR) -all; fi; 

.PHONY: clean UVM $(COMPONENTS) 
相關問題