Skip to content

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Sign in
H
Hdlmake
  • Project
    • Project
    • Details
    • Activity
    • Cycle Analytics
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
    • Charts
  • Issues 13
    • Issues 13
    • List
    • Board
    • Labels
    • Milestones
  • Merge Requests 2
    • Merge Requests 2
  • Wiki
    • Wiki
  • image/svg+xml
    Discourse
    • Discourse
  • Members
    • Members
  • Collapse sidebar
  • Activity
  • Graph
  • Charts
  • Create a new issue
  • Commits
  • Issue Boards
  • Projects
  • Hdlmake
  • Wiki
  • Quick start new

Quick start new

Last edited by Theodor-Adrian Stana Aug 16, 2017
Page history

Introduction

This page is meant as a (hopefully) short tutorial to using hdlmake for both synthesis and simulation. For a first-time user, it is recommended to go through the whole tutorial step by step. This will show you (based on a reference project):

  • how to create manifest files to ensure design modularity
  • how to create simulation manifests
  • create manifests for local synthesis
  • how to use IP cores uploaded on a version control system (in our example we use both Git and SVN).

Once you've done this, you can migrate to your own project(s), using this page and the rest of the documentation as a reference. You may skip directly to the Simulation or Synthesis sections, for quick reference on each topic. The summary at the end provides the steps you need to take.

For the moment, this tutorial is written for Linux systems, and for Xilinx FPGAs using Xilinx ISE. While hdlmake does support Altera tools, a tutorial on this is deferred for later.

Before we begin, a few words on the test system. This can be summarized as follows:

  • PC running Ubuntu 12.04 Precise Pangolin;
  • Linux kernel: 3.2.0-31-generic-pae;
  • Xilinx ISE v14.2;
  • Modelsim v10.1d;
  • hdlmake built from the latest (as of 2012-04-10) master repository;
  • SPEC carrier card with an fmc-adc-100m-14b-4cha board;
  • Test scripts from the PTS (Production Test Suite), run under Python 2.7.1+.

Installing hdlmake

There is no need to build hdlmake. It is entirely written in Python and the code gets interpreted on the fly. To get the code you have two choices: you might clone the repository, which contains the most recent changes (more features, more bugs too...) or download a frozen version in a form of a "binary" file.

Downloading the compiled executable

For downloading the compiled executable, click here and choose one of the files without extension. Download to a location of choice, and you're almost ready to use it! You can jump directly to the final steps.

Cloning the repository

If you prefer to get the source code, you need to have the popular Git version control system installed on your machine; if you don't, this page offers details on how you can configure Git to clone our repositories. Assuming you have Git installed, running the following will clone (download all files in the) repository to a folder named hdlmake under your /home/user_name/ folder:

$ git clone git:https://www.ohwr.org/misc/hdl-make.git hdlmake

Now you're almost ready to go. You can run hdlmake by changing directory to a desired location and running

$ python path/to/hdlmake/hdlmake

The sample project

For this tutorial, we have a sample project called play. This is a design which lights some LEDs on the SPEC board's front panel and can be used to play with controlling registers from a PC using the SPEC driver and (optionally) PTS (Production Test Suite). You can see a simplified block diagram of the design below:

It contains a number of design blocks, each defined in a separate VHDL file with the name of the block. The folder hierarchy for the project is as presented below:

  • play/
    • doc/
    • hdl/
      • design/
      • tb/
    • sim/
    • sw/
    • syn/

The relevant folders in our case are:

  • hdl/, where all source files are held; the tb/ folder contains testbenches for the design, and the design/ folder contains the rest of the files relevant to the design;
  • sim/ is the folder where files relevant to the simulation part of the design, such as Makefiles for simulation, simulation scripts, etc., are stored;
  • syn/ is the folder where files relevant to design synthesis are stored. The folder is also where the ISE project file is created.

And that is about as much detail about the sample project as is relevant for the purpose of this tutorial. More details about the sample project can be found in the project description .pdf, under play/doc/.

In order to download the design files for the tutorial, clone the project repository by running the following command in your terminal:

$ git clone --depth=1 -b play git:https://www.ohwr.org/fmc-projects/fmc-adc-100m14b4cha.git

The command creates a new folder in your current folder and downloads all files from the play branch of the fmc-adc-100m14b4cha OHWR repository to this new folder. The output of this command should be something like:

Cloning into 'fmc-adc-100m14b4cha'...
remote: Counting objects: 2518, done.
remote: Compressing objects: 100% (1277/1277), done.
remote: Total 2518 (delta 1518), reused 2010 (delta 1189)
Receiving objects: 100% (2518/2518), 150.71 MiB | 9.51 MiB/s, done.
Resolving deltas: 100% (1518/1518), done.

You should now have the project files, nicely stored following the folder structure we just described, under a new folder called play.

If you don't, you probably don't have git installed correctly. Check here for more information.

Now let's go on and generate a makefile for simulation!

Simulation

This part of the tutorial shows you how to run hdlmake for simulation. Note that hdlmake does not handle creation of simulation scripts, nor does it run the simulation tool for you; it simply creates all settings necessary to run simulation. Therefore, you will need to write your own simulation scripts and run Modelsim to run simulation. hdlmake will try to detect which version of modelsim you're running. Make sure that your modelsim executable is in the PATH before running hdlmake.

In our case, let's say we want to see how the design behaves with only the led_ctrl, addr_dec and irq_controller blocks in the design. Remember that the HDL files for these components are located under (assuming you are in the play/ folder) hdl/design/. We need to create a few very simple Python scripts which tell the tool where to look for files and what action it should perform. Let's see how this is done.

Design file manifests

First, create a file called Manifest.py, containing the following lines of Python code:

files = [
  "led_ctrl.vhd",
  "irq_controller_regs.vhd", # a sub-module of irq_controller
  "irq_controller.vhd",
  "addr_dec.vhd",
]

When hdlmake reads this manifest, it will know that the design files to look for under the current folder are the ones stated in the files variable.

Next, create another Manifest.py, this time under hdl/tb/, with the following contents:

files = [ "testbench.vhd" ]

modules = {
  "local" : [ "../design/" ]
}

As before, the files variable tells hldmake that within this folder, it should look for the file testbench.vhd and that it should for further modules (design files) under ../design/ (which as you might tell, is play/hdl/design/)

Now, cd to the play/sim/ folder and create yet another Manifest.py here, with the following contents:

target = "xilinx"
action = "simulation"
sim_tool = "modelsim"


modules = { "local" : [ "../hdl/tb" ] } 

Again, we see the modules variable, which tells it to look for modules under ../hdl/tb/. Additionally, the manifest tells the tool that the action to be performed is simulation, the target is xilinx and the simulation tool is modelsim.

Okay, now you should be able to run the tool and generate a makefile for simulation.

Running hdlmake

From the play/sim/ folder, run (normal outputs shown under each command):

$ hdlmake
INFO:    Running automatic flow
INFO:    Generating makefile for simulation.
$ make
cp /opt/modelsim_10.0d/modeltech/modelsim.ini .
(vlib work && vmap -modelsimini modelsim.ini work && touch work/.work )|| rm -rf work 
Reading modelsim.ini
"work" maps to directory ./work. (Default mapping)
vcom -quiet -modelsimini modelsim.ini  -work work ../hdl/tb/testbench.vhd 
vcom -quiet -modelsimini modelsim.ini  -work work ../hdl/design/led_ctrl.vhd 
vcom -quiet -modelsimini modelsim.ini  -work work ../hdl/design/irq_controller_regs.vhd 
vcom -quiet -modelsimini modelsim.ini  -work work ../hdl/design/irq_controller.vhd 
vcom -quiet -modelsimini modelsim.ini  -work work ../hdl/design/addr_dec.vhd 

Let's see what happened on the previous command. When you run hdlmake with no arguments, the tool parses the manifest under the current folder. Since the manifest told it to look for modules in ../hdl/tb/, the tool goes and parses the manifest there. Here, it is told to add the file testbench.vhd and to look for additional modules under ../design/. Finally, by parsing the play/hdl/design/Manifest.py file, hdlmake can add the final files needed for simulation. In a nice visual manner, here's how it works:

Assuming you've followed the steps up to here and you've written your simulation script, you should be able to run Modelsim now to simulate this simple design. From play/sim, run:

vsim

and in the Modelsim command line (using the provided scripts):

do run.do

should bring up a window similar to this:

If it does, and all of the signals have definite values (i.e., no 'X'-s, or 'U'-s), then congratulations, you have just performed a working simulation flow!

Synthesis

Okay, so now that you've simulated your design and are sure it works properly, you can proceed to synthesis. Using hdlmake for synthesis is as easy as using it for simulation. All you needed is a synthesis manifest (assuming the manifests for design files are already there), and you are good to go. Synthesis manifests tell the tool how to prepare your project file: what FPGA model to use, what package and speed grade it has, along with some additional information.

Design manifests

Considering our example project, cd to the play/hdl/design/ folder and edit Manifest.py so that it contains the following:

files = [ 
  "clk_div.vhd",
  "leds_sm.vhd",
  "led_ctrl.vhd",
  "irq_controller_regs.vhd",
  "irq_controller.vhd",
  "addr_dec.vhd",
  "led_ctrl_top.vhd"
]

modules = {
  "git" : "git:https://www.ohwr.org/hdl-core-lib/general-cores.git",
  "svn" : [ "http://svn.ohwr.org/ddr3-sp6-core/trunk/hdl",
            "http://svn.ohwr.org/gn4124-core/trunk/hdl/gn4124core/rtl",
            "http://svn.ohwr.org/gn4124-core/trunk/hdl/common/rtl"
  ]
}

fetchto = "../../../ip_cores"

You can see a number of extra things as opposed to the simulation case. First, we have more design files in the current folder (you might have noticed it when you cloned the design repository). Next, this manifest also contains a modules variable. This variable tells hdlmake that we are using some IP cores (in our case, the GN4124 interface core, and some other cores it depends on) which are stored on version control systems using both Git and SVN servers. Last, there is a fetchto variable; this tells hdlmake where to store the files retrieved from the repository, in case the files are not present.

Synthesis manifest

Now, you should create a manifest in the synthesis folder, telling hdlmake where to look for modules and what it should do. In our case, we cd to the synthesis folder (play/syn/) and create the following manifest file:

target = "xilinx"
action = "synthesis"

syn_device = "xc6slx45t"
syn_grade = "-3"
syn_package = "fgg484"
syn_top = "led_ctrl_top"
syn_project = "led_ctrl.xise"

files = "led_ctrl.ucf"

modules = {
  "local" : "../hdl/design"
}

The following extra variables appear in the manifest:

  • target: informs the tool that the target architecture is from Xilinx;
  • action: synthesis is to be performed;
  • syn_device: the FPGA device to perform synthesis for;
  • syn_grade: the speed grade of the FPGA;
  • syn_top: the top-level entity for the design;
  • syn_project: the target ISE project file.

Running hdlmake

Assuming everything is right up to now, running hdlmake without any arguments should download the missing files from the repository (note: this might take quite some time, so get ready for a coffee break), create a project file and a makefile for synthesis:

$ hdlmake
INFO:    Running automatic flow
INFO:    Fetching needed modules.
------------------
INFO:    Fetching module: git:https://www.ohwr.org/hdl-core-lib/general-cores.git [parent: /home/tstana/Projects/play/hdl/design]
INFO:    [git] Fetching to /home/tstana/Projects/ip_cores
Cloning into 'general-cores'...
remote: Counting objects: 2144, done.
remote: Compressing objects: 100% (1262/1262), done.
remote: Total 2144 (delta 1242), reused 1485 (delta 813)
Receiving objects: 100% (2144/2144), 6.79 MiB | 7.96 MiB/s, done.
Resolving deltas: 100% (1242/1242), done.
INFO:    The manifest inside /home/tstana/Projects/ip_cores/general-cores/modules/genrams/Manifest.py tried to print something:
> [genrams] creating workdir /home/tstana/Projects/ip_cores/general-cores/modules/genrams/coregen_ip
> [genrams] copying ISE files...
> 
------------------
INFO:    Fetching module: http://svn.ohwr.org/gn4124-core/trunk/hdl/common/rtl [parent: /home/tstana/Projects/play/hdl/design]
INFO:    [svn] Fetching to /home/tstana/Projects/ip_cores
A    gn4124-core/trunk/hdl/common/rtl/dummy_ctrl_regs.vhd
A    gn4124-core/trunk/hdl/common/rtl/dummy_stat_regs.vhd
A    gn4124-core/trunk/hdl/common/rtl/wb_addr_decoder.vhd
A    gn4124-core/trunk/hdl/common/rtl/Manifest.py
Checked out revision 195.
------------------
INFO:    Fetching module: http://svn.ohwr.org/gn4124-core/trunk/hdl/gn4124core/rtl [parent: /home/tstana/Projects/play/hdl/design]
INFO:    [svn] Fetching to /home/tstana/Projects/ip_cores
A    gn4124-core/trunk/hdl/gn4124core/rtl/dma_controller.vhd
A    gn4124-core/trunk/hdl/gn4124core/rtl/l2p_arbiter.vhd
A    gn4124-core/trunk/hdl/gn4124core/rtl/p2l_decode32.vhd
A    gn4124-core/trunk/hdl/gn4124core/rtl/dma_controller_wb_slave.vhd
A    gn4124-core/trunk/hdl/gn4124core/rtl/l2p_dma_master.vhd
A    gn4124-core/trunk/hdl/gn4124core/rtl/p2l_dma_master.vhd
A    gn4124-core/trunk/hdl/gn4124core/rtl/wbmaster32.vhd
A    gn4124-core/trunk/hdl/gn4124core/rtl/spartan3
[...]
Checked out revision 108.
INFO:    Generating/updating ISE project
INFO:    Generating makefile for local synthesis.
WARNING: Connection data is not given. Accessing environmental variables in the makefile
INFO:    Generating makefile for remote synthesis.

As in the simulation case, the tool parses through each manifest that it is pointed to (via modules variables) and recursively adds files to the project. When parsing the manifest under play/hdl/design/ and it encounters the "git" and "svn" keys, hdlmake searches for design manifests in the folder the fetchto variable points to. If it can find manifests there, it will continue adding files in a manner similar to before. Otherwise, hdlmake will try to fetch the repositories listed in the manifest. In a nutshell:

Additionally, hdlmake will create an ISE project file and a makefile. Running make now, the Generate Programming File flow from the Xilinx ISE tool is run. Before that, one can edit the flow in Xilinx ISE to adjust for custom settings or steps. The final result of the flow would be a programming file one can download to the FPGA RAM. (Btw, you should get ready for another coffee break, since this flow might take some time as well).

Summary

And that's it! That is how you use hdlmake for keeping track of your project files. A summary of what needs to be done is listed below:

  • Create one manifest file for each folder where you have design files. A manifest is a Python script (therefore, following Python language conventions) defining variables relevant to hdlmake when it generates your design project. When you run hdlmake, the manifests get read by the Python interpreter, so if need be, you can write more advanced Python code in the manifest. A simple manifest such as those we've shown here will however suffice in most cases.
  • Splitting design files into folders in a logical manner keeps your design modular and maintanable. One such design folder is called a module (in hdlmake parlance), and is indicated via the modules variable in the manifest; the module variable is a Python dictionary and the keys can have three different values:
    • "local": the modules are located on the current machine
    • "git": the modules are located on a git version control server
    • "svn": the modules are located on a svn version control server
  • Edit the manifest files if you add, remove, or modify any of your designs. In this case, you should run hdlmake to update your ISE project file and/or your simulation makefile.
  • For simulation, create a manifest file in the simulation folder, where you specify simulation as the action variable of the script.
  • For synthesis, create a manifest file in the synthesis folder, where you specify synthesis as the action variable, along with the rest of the relevant variables.
  • Run make in your simulation or synthesis folder to prepare the design for simulation, or respectively to run the Generate Programming File flow. This step is not needed; if you are more comfortable with double-clicking Generate Programming File in the Project Navigator's flow pane, you are free to do so. Just make sure you do not switch to automatic compile order in Project Navigator. If you do, you will lose the settings made by hdlmake.

Closing remarks

Running hdlmake with the --list option is a pretty useful way of checking if your design manifests have been written correctly. The option runs hdlmake without creating makefiles or fetching anything, instead it shows you all design files you defined in your manifests. For example, the following is a sample of a correct output:

$ hdlmake --list
../../ip_cores/gn4124-core/trunk/hdl/gn4124core/rtl
#http://svn.ohwr.org/gn4124-core/trunk/hdl/gn4124core/rtl
   dma_controller.vhd
   dma_controller_wb_slave.vhd
   l2p_arbiter.vhd
   l2p_dma_master.vhd
   p2l_decode32.vhd
   p2l_dma_master.vhd
   wbmaster32.vhd

../../ip_cores/gn4124-core/trunk/hdl/common/rtl
#http://svn.ohwr.org/gn4124-core/trunk/hdl/common/rtl
   dummy_ctrl_regs.vhd
   dummy_stat_regs.vhd
   wb_addr_decoder.vhd

../../ip_cores/general-cores
#git:https://www.ohwr.org/hdl-core-lib/general-cores.git
   # no files

If hdlmake had to download some files from the repository, an #unfetched message would appear under each of the repository links. If something is however wrong with your manifest(s), hdlmake will exit with an error and usually tell you where the problem is. You can use this output to debug your manifests. Running hdlmake --verbose can also help in debugging what you did wrong in your manifests.

For more details about the tool, feel free to check the introduction page as well as details about run parameters and manifest variables.

Finally, if you find any inaccuracies with the current tutorial, don't hesitate to contact the developers of this project.

Files

  • sim-flow.png
  • design-bd.png
  • syn-flow.png
  • sim-ex-1.png
Clone repository
  • 2014 release
  • Building wrpc with hdlmake
  • Documents
  • Fusesoc
  • Home
  • Ideas
  • News
  • Quick start
  • Sample project
  • Faq
  • Full documentation
  • Manifest
  • Manifest variables description
  • Masterforisypusers
  • Documents
    • Project attachments
More Pages

New Wiki Page

Tip: You can specify the full path for the new file. We will automatically create any missing directories.