OpenCores
URL https://opencores.org/ocsvn/radiohdl/radiohdl/trunk

Subversion Repositories radiohdl

[/] [radiohdl/] [trunk/] [doc/] [radiohdl_user_guide.md] - Rev 7

Compare with Previous | Blame | View Log

# RadioHDL User Guide

### *Speed up HDL development*

---
#### Document history:
|Revision|Date|Author|Affiliation|Modification|
|:---|:---|:---|:---|:---|
|0.5|11 dec 2018|R. Overeem |ASTRON|Initial HDL user manual docx.|
|1.0|27 jan 2020|E. Kooistra|ASTRON|Created, based on HDL user manual docx and hdltool_readme.txt.|

---
#### Contents:
1 Introduction  
2 Quick start using simulation in Modelsim  
2.1 Preconditions  
2.2 Setup RadioHDL  
2.3 Create Modelsim Project files  
2.4 Simulate the HDL test bench in Modelsim  
2.5 Utilities  
2.5.1 check_config  
2.5.2 modify_configfiles  
3 Setting up the RadioHDL environment  
3.1 Environment variables  
3.2 Configuration files kinds  
3.2.1 hdl_buildset_<buildset_name>.cfg  
3.2.2 hdl_tool_<tool_name>.cfg  
3.2.3 hdllib.cfg  
4 RadioHDL concepts and features  
4.1 Clean enviroment  
4.2 Copy files  
4.3 Top level design library  
4.4 Design revisions  
5 Adding your own tools  
5.1 New hdl_tool_<tool_name>.cfg file  
5.2 New <tool_name> directory  
5.3 Extend generate_ip_libs  
6 Appendix: RadioHDL configuration file schema basics  

---
#### Terminology:

- FPGA = Field Programmable Gate Array
- GUI = Graphical User Interface
- HDL = Hardware Description Language  
- IP = Intellectual Property  
- MPF = Modelsim Project File  

---
#### References:
[1] radiohdl_hdl_buildset_key_descriptions.md  
[2] radiohdl_hdl_buildset_uniboard1.md  
[3] radiohdl_hdl_tool_modelsim.md  
[4] radiohdl_hdl_tool_quartus.md  
[5] radiohdl_hdl_library_key_descriptions.md  
[6] radiohdl_programmer_guide.md  

---  
## 1 Introduction
The RadioHDL package offers tools for setting up, automating and maintaining the HDL source code, IP code and tools for programming FPGAs. The RadioHDL package consists of a set of scripts that interpret configuration files and that setup or run other tools. Currently RadioHDL supports vendor tools like Modelsim and Quartus, but other vendor tools can be added easily to the package.

The parameters for the HDL source libraries, the vendor IP blocks, the build tools and the target FPGA are kept in configuration files. The configuration files and source files are the inputs for the RadioHDL tools. The output is a build target that depends on which build tool is used. The build target can e.g. be a project file for Modelsim to simulate the HDL, a project file for Quartus to synthesize the HDL, a report log from a regression test that simulated the HDL. Figure 1 shows how RadioHDL fits in the build flow from source to target. The configuration files and source files are kept in one or more source directory trees that can be under version control, while the target files are built in a separate build directory tree. The RadioHDL is configured using three different kinds of configuration files: 

- one central hdl_buildset_<buildset name>.cfg configuration file per set of FPGA technology and tools and tool versions,
- one central hdl_tool_<tool name>.cfg configuration file per vendor tool,
- multiple local hdllib.cfg configuration files, one per HDL library.

After setting up the configuration files for the tools and the source files, RadioHDL can create for the selected buildset all libraries for simulation, create all IP libraries, find out dependencies, generate project files and do a lot more of these labour-intensive tasks automatically.

![Figure 1](./radiohdl_work_flow.jpg "radiohdl_work_flow.jpg")  
Figure 1: RadioHDL flow from source to target

The main benefit of RadioHDL is that it speeds up HDL development by providing a uniform and automated way of using tools and building code. The disadvantage of using RadioHDL is that it requires an initial effort to support a vendor tool and to maintain this support with changes in vendor tool versions. However in practice it has appeared worth the effort to use and maintain RadioHDL.

RadioHDL is open source, see [LICENSE.md](../LICENSE.md). The name RadioHDL reflects that it was first used for HDL development in FPGA projects for radio astronomy, see [NOTICE.md](../NOTICE.md) and [CREDITS.md](../CREDITS.md), but it can be applied for any HDL development project. This user guide focusses on how to use RadioHDL. The internal working of the RadioHDL scripts is described in the RadioHDL gear programmer guide [6].

---  
## 2 Quick start using simulation in Modelsim

This quick start uses the following RadioHDL tools for Mentor/Modelsim:

* **modelsim_config** : to create Modelsim project files (mpf) for simulation of HDL code
* **run_modelsim** : to start the Modelsim GUI and make and compile HDL code in Modelsim and hierarchically add signals to the Modelsim wave window

See [1] for more detailed information on using RadioHDL with Modelsim.
See [2] for more a more advanced example of using RadioHDL with Modelsim and Quartus, so including synthesis


### 2.1 Preconditions

RadioHDL uses Python3 and bash. Python3 is used to interpret the configuration files nad to create target files, bash is used to setup and invoke tools.

Install a version of Modelsim in $MENTOR_DIR/<version id> (version 6.6c and 10.4 and Questasim have been used) and take care of all vendor specific environment variables in your own .bashrc or local .profile file. For example Altera and Modelsim needs the key LM_LICENSE_FILE to be defined. So the .bashrc file contains the lines:

> export MENTOR_DIR=<path to where Mentor tool versions are installed>
> export LM_LICENSE_FILE=<license1@our_company>:<license2@our_company>

### 2.2 Set up RadioHDL

Create a directory at some location $QS_DIR to store the quick start (QS) example. Copy the example init_qs.sh from the RadioHDL installation directory to $QS_DIR and download the common_pkg, dp_pkg and dp_repack_data HDL libraries from OpenCores and put them in $QS_DIR.

> ls
$QS_DIR/init_qs.sh
$QS_DIR/cores/common/common_pkg
$QS_DIR/cores/dp/dp_pkg
$QS_DIR/cores/dp/dp_repack_data

Source init_qs.sh from within $QS_DIR to set the RadioHDL environment variables RADIOHDL_WORK and RADIOHDL_BUILD_DIR for the quick start (qs) project.

> \> . ./init_qs.sh

The example hdl_buildset_qs.cfg in the RADIOHDL_GEAR/config directory of RadioHDL installation directory defines which Modelsim version should be used. The sim_tool_version key in the hdl_buildset_qs.cfg defines the subdirectory of the installation of the Modelsim simulation tool in $MENTOR_DIR. In the example hdl_buildset_qs.cfg the sim_tool_version = 6.6c, indicating that the Modelsim tool version is installed at $MENTOR_DIR/6.6c/. If necessary change this to your sim_tool_version = <version id> and $MENTOR_DIR/<version id>.

Source init_radiohdl.sh to create $RADIOHDL_GEAR that points to <path to where RadioHDL is installed> and to add search paths within $RADIOHDL_GEAR to $PATH and to $PYTHONPATH

> \> . ./<path to where RadioHDL is installed>/init_radiohdl.sh

Now the environment variables that are important for using RadioHDL and that are also depicted in Figure 1) have been defined.

### 2.3 Create Modelsim project files

Use RadioHDL to build Modelsim simulation project files (*.mpf) for the quick start HDL libraries

> \> modelsim_config qs

The modelsim_config script puts the created files and copied files in the build directory, at:

> $RADIOHDL_BUILD_DIR/qs/modelsim

### 2.4 Simulate the HDL test bench in Modelsim

Start the Modelsim simulation GUI using:

> \> run_modelsim qs &

The run_modelsim also sources a commands.do script in Modelsim that adds the following 
useful Modelsim Transcript command line commands:

* lp = load project
* mk = make project
* as = add signals hierarchically to the wave window
* ds = delete signals from wave window

To compile the HDL code do in the Modelsim Transcript window:

> ModelSim> lp dp_repack_data
> ModelSim> mk all

To simulate the HDL code first double click tb_dp_repack_data icon in the Modelsim Project window to load the test bench (tb) into the simulator and then in the Modelsim Transcript window do.

> ModelSim> as 10
> ModelSim> run -a

The signals in this tb_dp_repack_data.vhd test bench can be observed visually in Modelsim Wave window, see Figure 2.

![Figure 2](./wave_tb_dp_repack_data.jpg "wave_tb_dp_repack_data.jpg")  
Figure 2: Modelsim wave window with hierarchical signals view using 'as' command

### 2.5 Utilities

### 2.5.1 check_config  
The utility **check_config** checks key-value dependencies between the hdl_buildset configuration file and the hdl_tool configuration files.

### 2.5.2 modify_configfiles
The utility **modify_configfiles** implements a tiny menu system that enables you to add, remove or change keys in all hdllib.cfg files of a certain buildset.

---  
## 3 Setting up RadioHDL environment

### 3.1 Environment variables

The following environment variables are important for RadioHDL:

* RADIOHDL_GEAR : Points to the main directory where your checked out the RadioHDL package. This is the location where this init_radiohdl.sh file is located. Do not change this variable.
* RADIOHDL_BUILD_DIR : Points to the directory where RadioHDL will store all its result files. If this variable is not already set when init_radiohdl.sh is run, then it will be set to point to $RADIOHDL_WORK/build.
* RADIOHDL_CONFIG : Points to the directory where RadioHDL expects the hdl_buildset and hdl_tool configuration files. If this variable is not already set when init_radiohdl.sh is run, then it will be set to point to $RADIOHDL_GEAR/config.
* RADIOHDL_WORK : Points to the root directory of the your project that will use RadioHDL.


### 3.2 Configuration files kinds

The configuration files define key-value pairs, see the appendix for the details of the schema. There are three different kinds of configuration files in RadioHDL. The hdl_buildset configurations file and hdl_tool configuration file are central and define the global keys that hold for the whole HDL project. The hdllib configuration files define keys that apply per HDL library. The key values from the hdl_buildset configuration file can be used in the hdllib configuration files by referring to the hdl_build set key as <key name>. An HDL project in RadioHDL typically targets a certain FPGA board and has an hdl_buildset configuration file for that board. The hdl_buildset configuration file identifies the hdl_tool configuration files for the tools that are needed to build HDL and it points to the directory tree(s) that contain the HDL libraries that are needed for the HDL application(s) that can run on the FPGA board.


#### 3.2.1 hdl_buildset_<buildset_name>.cfg

An hdl_buildset_<buildset_name>.cfg configuration file defines the combination of FPGA type, tools, IP libraries and versions that are needed to build a target. The buildset_name is used as command line option in RadioHDL scripts to identify the buildset. The buildset_name is typically an abbreviation that identifies the target FPGA board hardware and a version, e.g. 'unb1' for a version 1 of an FPGA board called 'UniBoard'. If the same board is used, but with another set of tool versions, then that could be identified by e.g. 'unb1_a' and have a buildset file called hdl_buildset_unb1_a.cfg. The hdl_buildset configuration files are kept centrally at $RADIOHDL_CONFIG. To structure the hdl_buildset configuration file it can be divided into sections that group keys per included tool. The section headers are identified between square brackets [tool_name]
  
#### 3.2.2 hdl_tool_<tool_name>.cfg 

RadioHDL looks for '*_tool_name' keys in the hdl_buildset configuration file to find the tool names that the buildset uses for e.g. simulation and synthesis. In this way RadioHDL knows which hdl_tool_<tool_name> configuration file it needs to use to setup these tools. Typically there is one tool configuration file that covers multiple versions of that tool. The hdl_tool configuration files are kept centrally at $RADIOHDL_CONFIG.

Although most keys in a hdl_tool configuration file are tool specific, there are some keys RadioHDL will always search for in a hdl_tool configuration file. RadioHDL will always search for keys ending in '_paths' and '_environment_variables' for keys that begin with:

- the tool_name of that hdl_tool configuration file (e.g. quartus_paths and quartus_environment_variables)
- the block_design_names you mentioned in your hdl_buildset configuration file (e.g. sopc, qsys)
- the word 'user', so you can always add your own paths and environment variables with the keys user_paths and user_environment_variables.
    
#### 3.2.3 hdllib.cfg

The HDL code is organised in one or more (can be many) HDL libraries. Each HDL Library has a local hdllib.cfg configuration file that defines the sources and supported tools. All HDL files are grouped into libraries. The rule is that each HDL file is compiled in only one HDL library. If a component is used in another library, then it is instantiated in VHDL using <hdl_library_clause_name>.<entity name>, where the hdl_library_clause_name is defined in the hdllib.cfg. Although the creation of these hdllib.cfg files may take some time, you will definitely save time on the long run. An HDL library can define a:

* module library with HDL that is reused in other libraries
* top level library with a top level entity that maps on the IO of the FPGA.

For RadioHDL there is no difference in HDL libraries. A top level library that is used for synthesis has a synth_top_level_entity key. RadioHDL search for all hdllib.cfg files in the directory tree(s) that are specified by the lib_root_dirs key in the hdl_buildset configuration file. Typically the hdllib configuration points to sources that are located in the same directory as where the hdllib.cfg is located or in its sub directories, however relative or absolute paths to sources elsewhere are also allowed. 

The hdllib can distinguish between source HDL that can be synthesized (at synth_files key),  HDL code that is used only in test benches for simulation (at test_bench_files key) and test benches that are selected to be part of a simulation regression test (at regression_test_vhdl key)..

The hdllib.cfg files are used by many utilities from the RadioHDL package. To structure the hdllib.cfg file, it can be divided into sections that group keys that are used for a specific target. The section headers are identified between square brackets [target_name]. The first part of an hdllib.cfg file has no section header as these keys are available for all target scripts. The keys within a section are applicable to the corresponding tool script. For example:

- section [modelsim_project_file]       contains key-value pairs for modelsim_config
- section [quartus_project_file] contains key-value pairs for quartus_config
- section [generate_ip_libs] contains key-value pairs for generate_ip_libs

Future target scripts can have their own [target_name] header in the hdllib.cfg to keep the files more organised.

---
## 4 RadioHDL concepts and features

### 4.1 Clean environment

The RadioHDL settings are only active in the terminal where RadioHDL was started. Therefore it is possible to run different buildsets in different terminals on the same machine. When the terminal is closed, then also all RadioHDL settings vanish as well.

### 4.2 Copy files

RadioHDL has <tool_name>_copy_files keys that can be used to copy files from the source directory tree to anywhere in the build directory tree. The file may also be copied to multiple locations in the build tree. This can be useful if different tools need the same source file, but at different locations.

A file may also be copied to another file. This can be useful to keep several variants of a file in the source tree, but only use one variant with a fixed filename in the build tree. The hdllib.cfg configuration can then refer to the file in the build tree.

### 4.3 Top level design library

A synth_top_level_entity key in the hdllib.cfg of an HDL library indicates that the HDL library is a design library that can be synthesized to yield an FPGA image. A design library should not depend on another design library, because then there may occur conflicting or double design constraints for Quartus. Therefore it is not advised to directly use VHDL from a design library in other libraries. A proper solution is to put these VHDL files in a separate library and then use them from that library. Another solution (i.e. work around) is to break the rule that an HDL file should only be compiled once in one library and then also compile it in the design library that needs to reuse it.

### 4.4 Design revisions

A design in this context is a top level entity in a HDL library that can be synthesized to create a FPGA image that can run on an FPGA. Within a design, several design revisions can be made that all use the same HDL source code from the base design, but with different generic settings at the top level entity. To keep these design revisions separate, add a directory 'revisions/' in the base design directory, which contains a list of subdirectories. Each subdirectory is a revision. The base design 'unb1_minimal' can be uses as an example: 

> designs/unb1_minimal/hdllib.cfg
> designs/unb1_minimal/revisions/unb1_minimal_sopc/hdllib.cfg
> designs/unb1_minimal/revisions/unb1_minimal_qsys/hdllib.cfg

The base design library unb1_minimal/hdllib.cfg contains the source code. Each design revision library also has a hdllib.cfg  file and a top level VHDL file that wraps the top level VHDL file from unb1_minimal. The wrapper file makes the generic settings for the specific revision. In addition it is useful to specify a 'g_design_name' generic that can be used to store a string in the FPGA that can be read out to know which design revision runs on the FPGA. In this example for UniBoard1 the 'g_design_name' for the revisions is 'unb1_minimal_qsys' or 'unb1_minimal_qsys'.

When a design library has revisions, then the base library should not include keys for synthesis. Instead the synthesis is only done for the revisions. The base library contains all the VHDL source files. The revision hdllib.cfg should not refer to these base library VHDL files (i.e. using a relative path via ../../), but instead it should instantiate the top level base entity using the base design library name. This to follow the rule that a HDL file is only compiled in one HDL library.

---  
## 5 Adding your own tools

The RadioHDL package as described in this user guide is based on the tools Modelsim and Quartus. If you are using the same tools, then everything should work in your environment after you checked/modified the configuration files in $RADIOHDL_CONFIG. But what if you are using others tool like e.g. Xilinx Vivado? In that case you have to create some new configuration files, some directories and (unfortunately) extend one script. This chapter guides you through this process.

### 5.1 New hdl_tool_<tool_name>.cfg file

Assume you want to add Vivado to RadioHDL, then create in $RADIOHDL_CONFIG a file named hdl_tool_vivado.cfg and put in that file Vivado specific paths and environment variables. There are no required keys in configuration files of the type hdl_tool, so you are free to choose your own key names. Note: the script you create in the following section uses the definitions you create in the hdl_tool file.

### 5.2 New <tool_name> directory

Every tool has its own directory in $RADIOHDL_GEAR. In this directory we expect a script named set_<tool_name> to be present, that accepts the buildset_name as an argument. That script sets up the whole environment, so that the tool can be used, e.g. extend paths, setup environment variables, etc. Look in e.g. set_modelsim and set_quartus how to get access to the information that is stored in your configuration files in the $RADIOHDL_CONFIG. So to add e.g. to add Vivado:

- create a directory $RADIOHDL_GEAR/vivado
- inside this directory make a script set_vivado that sets up the Vivado environment using the information that is configured in the hdl_buildset and hdl_tool files.

### 5.3 Extend generate_ip_libs

Currently generate_ip_libs supports three IP generation tools from Altera: qmegawiz, qsys-generate and quartus_sh. These IP tools are configured in the hdl_tool_quartus.cfg file (key ip_tools) and implemented as special functions in generate_ip_libs. If you need different IP generation tools you should add them to the ip_tools key and add an extra function in generate_ip_libs. This generate_ip_libs script is the one place (left) where tool specific code is part of a RadioHDL script. In a future release of RadioHDL this should be solved in a more generic way, but for now you have to add a function to generate_ip_libs, when you are using a tool other than qmegawiz, qsys-generate or quartus_sh for creating your IP libraries.

The main flow of generate_ip_libs is:

- read the hdl_buildset file of the buildset you started the program with.
- search for hdllib.cfg files in all directories mentioned in the key lib_root_dirs
- read the hdl_tool_<tool_name>.cfg file where tool_name is the value of the key synth_tool_name in your buildset file.
- read the value of the key ip_tools in this hdl_tool file which is a list of tools you use for creating the IP libraries. Each of these ip_tools have their own <ip_tool>_default_options key to configure the default options of that command.
- finally it loops over all buildset.technology_names, all tool.ip_tools and all hdllibs that where read in, to see if there is a match in technology and ip_tool with the information in the hdllibs.
- for each match found in these nested loops it calls a function called run_<ip_tool_name> that is part of the generate_ip_libs program.

So if you are using other ip_tools then the three mentioned above you have to add a run_<your_ip_tool> function to generate_ip_libs and extend the if-then-else construction in the main loop with a call to that function. And you have to setup your configuration files in the right way of course. Take a look at the other run_ functions in generate_ip_libs for what to implement. Basically it constructs a shell script that runs the IP tool and analyses the exit-code of the execution. No rocket science.

---  
## 6 Appendix: RadioHDL configuration file schema basics

A RadioHDL configuration file is a collection of key-value pairs. Key and value are separated with the assignment char '='. Everything after (and including) a '#' char till the end of the line is treated as comment and is skipped in the interpretation of the files.
```
    this_is_a_key = and this is the value    # except for this comment.
```
The files can be divided into sections. A section marker is a line that starts with '[', contains a string and ends with ']'. Sections can be used to group keys that are only used by certain tool scripts and may be ignored by other tool scripts. Key names in different sections must still be unique in the entire configuration file.
```
    [start of a new section]  
    key = value
```
To make the files easier to read and maintain for humans each value can be defined in more than one line where spacing is trivial. This makes is easy to define values that consist of more than one item. Actually, the concept of 'value' is implemented as 'being everything between the assignment char and the start of the next key or the start of a section. Newline characters are translated into a single space.
```
    invitationlist = John & Marry,  
                     Robert,  
                     Sandra and Naomi,  
```
This is equivalent with:
```
    invitationlist = John & Marry, Robert, Sandra and Naomi,
```
You can use environment variables in values:
```
    lib_root_dirs = ${RADIOHDL_WORK}
```
Keys are always in lowercase even when the name of the key will be used as environment variable. RadioHDL takes care that the key names are converted to uppercase in these cases.

You can refer to a value of another key by placing the name of that key between '<' and '>'. Key word substitution can happen local within a file or global between files:

- Local: A key name can be used for key value substitution in other key values within the same cfg file at <key name>.
- Global: A key name in the hdl_buildset cfg file can be used to substitute in key values in hdllib cfg files: e.g. <buildset_name>

For example:
```
    tool_name     = quartus  
    tool_version  = 12.3  
    tool_location = /home/software/\<tool_name\>/\<tool_version\>/bin  
```

Key values can be e.g.:

* Single value : e.g 'hdl_lib_name' key
* List of values : e.g. 'synth_files' key
* List of value pairs : e.g '*_copy_files' key

The pairs in '*_copy_files' are separated by a space and therfore the values can not contain a space.

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2021 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.