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, and create manifests for local synthesis. Additionally, it will show you how to use IP cores uploaded on a version control system (in our example we use git).
Once you've done this, you can migrate to your own project(S), using this page as a reference. You may skip directly to the Simulation or Synthesis sections, for quick reference on each topic.
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 continue, 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
In order to run hdlmake on your computer, you have two choices. The first (and the easiest) is downloading the binary file to a location of choice on the computer. The second choice is cloning the hdlmake repository and building hdlmake on your own. While the first choice might seem the more elegant solution, it is never 100% certain that the uploaded binary is conclusive with the sources, so building the tool on your own might be a wiser decision. Up to you.
Downloading the compiled binary
For downloading the compiled binary, click here. Download to a location of choice, and you're almost ready to use it! You can jump directly to the #Final-steps.
Compile hdlmake yourself
If you prefer building it yourself (highly recommended), 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 and you are in your /home/
folder,
running the following will clone the repository (download all files in
the repository) in a folder named .hdlmake
under your
/home/user_name/
folder:
$ git clone git:https://www.ohwr.org/misc/hdl-make.git .hdlmake
Now, cd to the newly created folder, then to the source folder, clean
already built files and build again. This will generate a new executable
in the file .hdlmake/hdlmake
:
$ cd .hdlmake/src/
$ make clean
$ make
Final steps
To be able to run the hdlmake
command from anywhere on your file
system, create a link to the binary from your /usr/bin/
folder (or any
folder that is on your system's $PATH). Assuming your hdlmake
binary
is under /home/user_name/.hdlmake/
:
$ cd /usr/bin
$ sudo ln -s /home/user_name/.hdlmake/hdlmake
There, now you should be able to run the command from anywhere on your file system!
The sample project
For this tutorial, we have a sample project called play. We will start
by describing this sample project, and then download it from a git
repository, in order to actually run simulation and synthesis using
hdlmake
.
The play project 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:
design-bd.jpg
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. In order to download the design files for the tutorial, clone the project repository by running the following command in your terminal (note: you need git for this part as well; check here if you don't have it):
(red) !! UPLOAD AND CLONE GIT REPOs !!
Okay, 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 for simulation assumes you are running some version of Modelsim and will create a Makefile for simulation using this software.
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",
"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"
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, and that the target is
Modelsim for Xilinx.
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.
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 (considering the manifests for design files are already there), and you are good to go. So let's see how this is done!
As in the simulation section, we need a few Python scripts called manifests, which will give the tool information about where to look for design files and, in the case of synthesis, what FPGA model, package and speed grade we are using, along with some additional information. But first, let us talk about the design manifests.
Design manifests
Considering our example project, from the play/
folder, cd
to the
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 (in this case, git and svn). 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.
(red) Running make
now, the Generate Programming File flow from
the Xilinx ISE tool is run. Before that, one could 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. 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; themodule
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. - 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.
Closing remarks
If you find any inaccuracies with the current tutorial, don't hesitate to contact the developers of this project.