library support in hdlmake

Is there a way to define libraries in the Manifest files to organise bigger projects?
I couldn’t manage to use other libraries then ‘work’

You can specify the library with library="xxx", but several synthesizers don’t really support libraries.


Many thanks for your reply. That’s what i did, but it didn’t work for questasim/quartus using hdlmake 3.0. I’ll prepare a minimal example and post it here.

In fact, libraries seem to be correctly supported for Modelsim. Yet, when using GHDL, everything is put into the library work. The situation might be similar for synthesis as well.
As many larger projects use libraries, this is IMHO a serious flaw. It should be fixable by changing makefile_sim_compilation/makefile_sim_dep_files similar to the Modelsim version.

So you need library support when generating a Makefile for ghdl, don’t you ?

Exactly. In the current version of Hdlmake the files are compiled into the correct folder by the makefile, yet the option -work=mylibrary is missing, so ghdl cannot correctly link the files.

Hi Tristan,
I still have problems using libraries with latest hdlmake 3.3.
The Makefile which is generated reads the following, even I defined a library:

      @$(foreach sourcefile, $(SOURCES_VHDLFile), echo "set_global_assignment -name VHDL_FILE $(sourcefile) -library       work" >> $@ &)

So all files will be in the work library. That’s not correct.
In the test example with additional simple_pkg.vhd file the files.tcl shows

set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:../../../top/cyclone3_sk/pinout.tcl"
set_global_assignment -name POST_MODULE_SCRIPT_FILE "quartus_sh:../../../top/cyclone3_sk/module.tcl"
set_global_assignment -name VHDL_FILE ../../../modules/counter/vhdl/counter.vhd -library work
set_global_assignment -name VHDL_FILE ../../../modules/package/vhdl/simple_pkg.vhd -library work
set_global_assignment -name VHDL_FILE ../../../top/cyclone3_sk/vhdl/cyclone3_top.vhd -library work

obviously this causes errors during synthesis. It should read:

set_global_assignment -name PRE_FLOW_SCRIPT_FILE "quartus_sh:../../../top/cyclone3_sk/pinout.tcl"
set_global_assignment -name POST_MODULE_SCRIPT_FILE "quartus_sh:../../../top/cyclone3_sk/module.tcl"
set_global_assignment -name VHDL_FILE ../../../modules/counter/vhdl/counter.vhd -library work
set_global_assignment -name VHDL_FILE ../../../modules/package/vhdl/simple_pkg.vhd -library <name of library>
set_global_assignment -name VHDL_FILE ../../../top/cyclone3_sk/vhdl/cyclone3_top.vhd -library work

Could you please fix that. I really like to use hdlmake for future projects, but this is a blocker for me, I need library support.
Note, for some unknown reason, the current hdlmake version with all files in the work library works with Quartus II 13.1, but newer versions of Quartus fail. Modern Intel FPGAs need new Quartus II versions. I can confirm, that with the above modification, they’ll work.

So if I understand correctly, new versions of Quartus support libraries but not the older ones. I will have a look.


Well, old Quartus II versions e.g. 13.1 should also support libraries (see page 16-12 in
But even though all files are in the work library, synthesis doesn’t fail, but it fails for newer versions.
Whereas, also with correct file - library association (done be editing files.tcl), the old Quartus II 13.1 runs without error.
If it helps, I could run tests with different Quartus versions, just let me know the git commit.

Now implemented.


Many thanks!
But I can’t see any changes at Did you push?

I found your changes on develop branch.

If it works for you, I could push them on the master branch.

Thanks for fixing this issue. It would be nice to have the library in the list-json output as well.

For Vivado I had to add a line to use that propagated library value.

diff --git a/hdlmake/tools/ b/hdlmake/tools/
index f586cc2..c987d55 100644
--- a/hdlmake/tools/
+++ b/hdlmake/tools/
@@ -36,7 +36,8 @@ class ToolXilinx(MakefileSyn):

         "add_files -norecurse {srcfile}; "
-        "set_property IS_GLOBAL_INCLUDE 1 [get_files {srcfile}]")
+        "set_property IS_GLOBAL_INCLUDE 1 [get_files {srcfile}]; "
+        "set_property LIBRARY {library} [get_files {srcfile}]")

    HDL_FILES = {

Then I want XCI files to follow the library directive as well and not have them in a library called work.

diff --git a/hdlmake/sourcefiles/ b/hdlmake/sourcefiles/
index ca77789..913dc74 100644
--- a/hdlmake/sourcefiles/
+++ b/hdlmake/sourcefiles/
@@ -197,8 +197,7 @@ XILINX_FILE_DICT = {
     'ram': RAMFile,
     'vho': VHOFile,
     'veo': VEOFile,
-    'bmm': BMMFile,
-    'xci': XCIFile}
+    'bmm': BMMFile}

@@ -340,6 +339,8 @@ def create_source_file(path, module, library=None, include_dirs=None):
+    elif extension == 'xci':
+        new_file = XCIFile(path=path, module=module, library=library)
     elif extension == 'wb':
         new_file = WBGenFile(path=path, module=module)
     elif extension == 'tcl':
diff --git a/hdlmake/sourcefiles/ b/hdlmake/sourcefiles/
index 5af26e2..4f86fdd 100644
--- a/hdlmake/sourcefiles/
+++ b/hdlmake/sourcefiles/
@@ -39,7 +39,7 @@ class XCIParser(DepParser):
     def parse(self, dep_file):
         """Parse a Xilinx XCI IP description file to determine the provided module(s)"""
         assert not dep_file.is_parsed
-        logging.debug("Parsing %s", dep_file.path)
+        logging.debug("Parsing %s in library %s", dep_file.path, dep_file.library)

         with open(dep_file.path) as f:

If these patches are applied, an undocumented feature becomes important: the vhdl parser will recognize a component instantiation only if the component keyword is used. Otherwise it is parsed as an entity and assigned to the current library.

Patch for the parser:

index 93a1cf1..40235c1 100644
--- a/hdlmake/sourcefiles/
+++ b/hdlmake/sourcefiles/
@@ -150,6 +150,24 @@ class VHDLParser(DepParser):
         buf = re.sub(component_pattern, do_component, buf)
+        # component instantiation
+        instance_component_pattern = re.compile(
+            r"^\s*(?P<LABEL>\w+)\s*:"
+            r"\s*(?:component\s+)?(?P<COMPONENT>\w+)\s*"
+            r"(?:port\s+map.*?|generic\s+map.*?)",
+            re.DOTALL | re.MULTILINE | re.IGNORECASE)
+        def do_instance_component(text):
+            """Function to be applied by re.sub to every match of the
+            component_pattern in the VHDL code -- group() returns positive
+            matches as indexed plain strings. It doesn't add any relation
+            to the file"""
+            logging.debug("found component instantiation %s %s",,
+            comp_name ="COMPONENT")
+            return "<hdlmake component instance %s as %s>" % (comp_name,"LABEL"))
+        buf = re.sub(instance_component_pattern, do_instance_component, buf)
         # Signal declaration
         signal_pattern = re.compile(
@@ -219,7 +237,7 @@ class VHDLParser(DepParser):
         libraries = set([dep_file.library])
         instance_pattern = re.compile(
-            r"\s*(?:entity\s+(?P<LIB>\w+)\.)?(?P<ENTITY>\w+)"
+            r"\s*(?:entity\s+)((?P<LIB>\w+)\.)?(?P<ENTITY>\w+)"
         re.DOTALL | re.MULTILINE | re.IGNORECASE)

Sorry for the number of patches. It is a rabbit hole. I may fork.

Hi Tristan,
your fix works for me, many thanks.
Now I have problems including Intel IP core files. I’ll oben a new ticket for that.

I see that context declarations are not parsed correctly. I ended up using hdlmake -a.

The patched allows:

clk_wiz_sysclk_inst : entity xil_defaultlib.clk_wiz_sysclk
port map(…

I have added the patch for library on xilinx source files.

I have also added your changes for XCI.
I am investigating the use of ‘component’ in instantiation. With your change, I have some regressions.

Do you have an example of context declarations ?


Ok, Christos has just added support for contexts, so I think you don’t need anymore to use ‘-a’.