2016-07-21 23 views
1

Also ich versuche, ein Makefile für die Verwendung mit QuestaSim und Systemverilog-Dateien zu schreiben. Wenn Sie nicht wissen, was das ist (und die meisten Leute nicht), dann machen Sie sich keine Sorgen, das ist nicht relevant für mein Problem.Wie schreibe ich ein Makefile, in dem sich die kompilierten Objektdateien in einem anderen Verzeichnis mit einem anderen Namen befinden?

Ich habe ein Projekt Direktor enthält: src/Arbeit/Makefile

das src/Verzeichnis enthält mehrere Verzeichnisse, die jeweils Quelldateien enthalten.

Das Work/Verzeichnis existiert zunächst nicht und wird vom Makefile erstellt.

Wenn ich meinen "Compiler" anrufe, der vlog heißt, wird in einer .sv-Datei ein Verzeichnis im Arbeitsordner mit demselben Namen wie die .sv-Datei ohne das Suffix erstellt. In diesem Verzeichnis sind drei Dateien, die ich als meine "Objekt" Datei verwenden werde _primary.dat.

So zum Beispiel, ruft "vlog src/interface/my_interface.sv" erstellt (wenn es gelingt) arbeiten /my_interface/_primary.dat

Meine .sv Dateien müssen auch in einer bestimmten Reihenfolge erstellt werden, und ich möchte nur, um sie kompilieren, wenn die Quelldatei oder eine ihrer Abhängigkeiten geändert hat.

ich drehen kann der Pfad zur .sv-Datei in den Pfad zur entsprechenden _primary.dat-Datei mit "$ (addsuffix /_primary.dat, $ (addprefix $ (VLIB_DIR) /, $ (Basisname $ (notdir $ (SRC))))) "Aber das Gegenteil ist unmöglich, da wir die Verzeichnisstruktur verlieren.

Also ich denke, was ich will ist eine Art von Karte aus Objekt -> src. Also in meinem $ (OBJ): Ziel kann ich "vlog $ (getsrc $ @)" machen.

Danach muss ich mit der Kompilierreihenfolge und Abhängigkeiten beschäftigen, aber ich kann das wahrscheinlich ausarbeiten.

Irgendwelche Vorschläge?

+0

1) Besteht die Gefahr von Quellennamen Kollisionen? Das heißt, wenn es eine 'src/interface/foo.sv' gibt, kann es auch eine' src/engine/foo.sv' geben? 2) Kann 'src /' mehr als zwei Ebenen tief sein? Das heißt, könnte es eine "src/foo/bar/baz.sv" geben? – Beta

+0

Ich habe die Anforderung, dass das Paket/Schnittstelle/Modul den gleichen Namen wie die Datei hat. Daher würden Kollisionen sowieso Kompilierungsfehler verursachen. Im Moment sind die Verzeichnisse nur zwei Ebenen tief, aber ich könnte später weitere Ebenen hinzufügen. –

+0

Haben Sie sich jemals das Dienstprogramm 'vmake' angesehen, das mit Questa geliefert wird? –

Antwort

0

Ich fand eine Lösung, die funktioniert. Ich bin mir nicht sicher, ob es das Beste ist, aber ich poste es hier, um anderen zu helfen, die dieses Problem haben.

Grundsätzlich erstelle ich ein Makro, das zwei Argumente akzeptiert: den Pfad und den Namen der .sv-Quelldatei und eine Liste der Abhängigkeiten. Dies wandelt den Quelldateipfad in den Pfad der Objektdatei um und erstellt diesen als Ziel. Mit einer Abhängigkeit von der Quelldatei und allen übergebenen Abhängigkeiten. Ich erstelle dann eine Variable, die eine Liste aller meiner Quellen enthält. Schließlich mache ich: $ (foreach src, $ (SRCS), $ (eval $ (Aufruf create_target_for, $ (src))))), die alle meine Ziele erstellt.

Zusätzlich habe ich jedes Unterverzeichnis als ein falsches Ziel, mit den relevanten Abhängigkeiten, die mir erlauben, die richtige Kompilierreihenfolge auf Verzeichnissen zu bekommen.

Das einzige, was fehlt, ist, wenn ich sicherstellen muss, dass Dateien in einem einzigen Verzeichnis die richtige Kompilierreihenfolge haben.

Mein 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)