VHDL - Conditional compilation - compilation

My VHDL testbench uses some features that are specific to VHDL'2008 but, depending on what exactly I'm testing or which software I'm using for the simulation, it cannot always be compiled in VHDL'2008.
To cope with that, I created 2 versions of this testbench :
The full version, compiled in VHDL'2008.
The light one, with all VHDL'2008 lines deleted, compiled in VHDL'93.
However, maintaining two nearly identical versions of this testbench is really an annoying thing to do, so I would like to merge them in some way.
I first thought I could use a generic and an "IF .. GENERATE" statement but this obviously doesn't allow me to '93-compile a file with '2008 features.
Is there a way to merge these 2 files and still compile the result with VHDL'93 ?

Option 1 -- Pragmas
If the code that uses VHDL 2008 doesn't replaces other pieces of the code (i.e., the code using VHDL 2008 does extra stuff), you can use pragmas such as
vhdl_93_component_u : foo_93 port map ( clk => clk, out => out);
-- rtl_synthesis off
vhdl_2008_component_u : foo_2008 port map ( clk => clk, out => out);
-- rtl_synthesis on
Also, check if your tool accepts enabling and disabling interpretation of pragmas and which pragmas it accepts. -- rtl_synthesis on/off is an example here.
Option 2 -- Different files
If you can split your code in 3 (testbench top, VHDL '93 code, VHDL 2008 code), you can compile only the file you need (assuming same package/architecture/entity names).
If you can't refactor your code to use something like this, I suggest you review the way you are implementing your testbench.

Related

Conditional use of libraries when simulating VHDL design with ModelSim in Pre-Synthesis / Post-Synthesis

In my VHDL design there is a 16-bits std_logic_vector. The bit in position 15 is currently not used and the synthesizer (SynplifyPro) throws a warning saying that bit is not used and will be pruned:
#W:CL190 : DATAGEN.vhd(93) | Optimizing register bit MYREG(15) to a constant 0. To keep the instance, apply constraint syn_preserve=1 on the instance.
#W:CL260 : DATAGEN.vhd(93) | Pruning register bit 15 of MYREG(15 downto 0). If this is not the intended behavior, drive the input with valid values, or an input from the top level.
As suggested by the synthesizer, I have added the required attribute and I was able to get rid of these warnings. To add these attributes, I had to include the Synplify library:
library synplify;
at the top of the file, and then define the attribute as follows:
ATTRIBUTE SYN_PRESERVE : BOOLEAN;
ATTRIBUTE SYN_PRESERVE OF MYREG : SIGNAL IS TRUE;
If I try to run ModelSim on Post-Synthesis everything is fine. However, when I try to run ModelSim on Pre-synthesis, it gives me the error:
** Error: .../DATAGEN.vhd(20): (vcom-1598) Library "synplify" not found.
I believe that the problem is because Pre-Synthesis simulation is not supposed to use this library. In fact, if I remove this everything works. The reason for which I would like to keep using the Pre-Synthesis simulation is because it is much faster than Post-Synthesis. However, this issue forces me to keep commenting out this lib for Pre-synthesis and putting it back for Post-synthesis?
Is it possible to use something like conditional include?
Note: I prefer to keep the unused bits, therefore adding the attribute for avoid pruning works fine for me.
Is it possible to use something like conditional include?
The upcoming VHDL-2019 standard supports conditional compilation and some simulators, for example RivieraPro, have started to support that. With such support you can do things like
`if INCLUDE_SYNPLIFY = "true" then
library synplify;
`end if
I don't think ModelSim has that yet but what you can do is to just define a synplify library with vlib and include that when calling vsim. If you are using VUnit you can simply add the following to your run script
prj.add_library("synplify")

Syntax of the full hierarchical names used in Xilinx UCF files

I'm trying to create a TIG constraint in the UCF file of my project.
Problem is, I just can't get the hierarchical name right.
The structure I'm dealing with is the following (pseudo-code showing the hierarchical position of the signal that needs to be addressed):
m1: module1
g1: for i in 0 to m generate
g2: if x /= 0 generate
m2: module2
reset : in std_logic;
Among others I tried NET "m1/m2/reset" TIG; , NET "m1/g1.g2.m2/reset" TIG; and NET "m1/g1*.g2.m2/reset" TIG; (the last one was inspired from one of the intermediate files produced during synthesis *.xdl).
What is the correct way to address the reset net within m2? I looked at the Xilinx Constraint Guide but found no detailed explanation on this.
A recent XST User Guide might have a section on XST Naming Conventions with subsections on *XST Net Naming Conventions, XST Instance Naming Conventions and XST Name Generation Control. The last telling how to control name generation in the netlist (hierarchy separator, bus delimiter, case, duplication suffix, viewable in Synthesis Properties). Your third example above looks promising. You can get closer to the netlist by viewing schematics or the constraint editor. Can you add TIG to the reset in m1? (it's forward referential).

Comprehensive list of RTL pragma directive triggers

In verilog and VHDL RTL commands to tools can be given as pragma directives as pseudo comments. I want to avoid using any of these pragma directives in my real comments, so what I'd like to have is a comprehensive list of pragma directive triggers. Ones I know about are:
-- pragma
// synthesis
-- synopsys
You can find a comprehensive list here:
http://www.sigasi.com/content/list-known-vhdl-metacomment-pragmas
As long as you don't have a comment starting with the trigger, i.e., -- <trigger> ..., you should be safe.
For example, when using Altera Quartus, avoid comments such as
-- altera code below,
while
-- The following is for altera.
would be fine.
You can probably find several lists like this, but I doubt any of them are complete. (The one zennehoy posted is missing -- psl, among others.) Even if there is a complete list somewhere you never know what pragmas vendors will add in the future, thus you can never be sure.
If you want your code to be as portable as possible you should probably avoid starting comments with common vendor/tool names like zennehoy suggests (such as synopsys, altera, xilinx, lattice, modelsim, etc.) Other than that I'd say you just have to take your chances.

Generating Single Port ROM on Spartan 6 using Xilinx ISE Design Suite

I'm having some trouble designing a single port rom onto a spartan 6 board. I use the provided core generator to create block memory and choose single port rom with 32 bit width and 256 depth with a coe file that just counts from 0 to 255. I drop the rom into my vhdl as a component and add the XilinxCoreLib as a library. When I try to generate the programming file I get the translate error:
logical block 'rom1' with type 'rom' could not be
resolved. A pin name misspelling can cause this, a missing edif or ngc file,
case mismatch between the block name and the edif or ngc file name, or the
misspelling of a type name. Symbol 'rom' is not supported in target
'spartan6'.
I'm currently using Xilinx ISE 13.1 if that helps. I feel like this should be really easy to do but I haven't been able to find how to do it.
Edit: Thanks everyone, was a combination of things. Wrong speed grade, and didn't add a copy of the ngc file to my working directory. I'll use arrays in the future.
Easiest way is to forget the vendor tools altogether and simply declare a constant array!
If this is in a package separate from the rest of the design, a few lines of printf's or a simple script can generate the VHDL boilerplate around the contents, which come from your assembler or whatever tool creates the actual data
Since you're adding a Xilinx generated core to your design in ISE, you need to add both the VHD file and the NGC file via "Add Source" via the Project menu.
Even easier, depending on how large your ROM needs to be and what data goes into it, would be to not even bother with a Xilinx core, but to use pure VHDL to declare a constant array and initialization values right in your VHDL file. Here is an example:
type array_ROM is array (0 to NUMBER_OF_ROWS-1) of std_logic_vector (ROM_BITWIDTH-1 downto 0);
signal my_ROM : array_ROM
:=
(
x"12345678",
x"ABCDEF01",
...
x"01010101"
);
Now, you don't put the elipsis (...) in that initialization list, just put rows of constants with bit widths matching ROM_BITWIDTH. The NUMBER_OF_ROWS is the number of address locations you need in the ROM. In this example, ROM_BITWIDTH would have to be set to 32 as I've used 32-bit hexadecimal constants in the initialization list. Being a signal, it's actually modifiable, so if you need it to be constant, just use "constant" instead of signal.
I guess the problem is, as the message says, a misspelling. to get the correct component declaration/instantiation, select your rom.xco in the design-window of ISE. then select "view vhdl instantiation template" from process window. use the component declaration and instantiation described therein.
There are a number of things that can cause this problem, one is that you are using a blocck that was generated for another FPGA family and using it inside the Spartan6. the other is that you may have generated the ROM using an older version of the tool and the wrapper for the ROM has changed since then.
You can either generate a anrray like Brian suggested and forgetting about the tool specific ROM type, or re-generate the IP under your curernt project settings and see how it goes.

Equivalent of #ifdef in VHDL for simulation/synthesis separation?

In order to ease the visual reading of simulation waves, I would like to assign some signals to "XXXX", but only at simulation time, and thus I want the logical synthesis tool (ISE in my case) to skip those instructions.
Two questions from here:
Is there an equivalent technique of a #ifdef SIMULATION_TIME, like in C ?
Would an assignment to "XXXX" have any influence on the logical synthesis (reset to 0 ? warnings ? nothing ?). If it has no impact at all, then my question is answered. If not, I still need to assign to "XXXX"...
Thanks.
(1) You're looking for
--pragma synthesis_off
-- your simulation-only code
--pragma synthesis_on
(2) You might get some warnings from ISE, especially when these signals drive logic. Just make sure, that the signals have a defined value before you use them. This method should work then, as well.
If you find yourself wanting to use ifdef for arbitrary code selection then you can use the VHDL keywords if generate.
label: if SOME_OPTION = SOME_VALUE generate
some VHDL here
end generate;
This is handy if you need to optionally include some code, however the synthesis on/off is more widely used if the selection is between simulation and synthesis.
One other trick to go with George's answer - if you want a boolean for in_synthesis say:
constant in_simulation : boolean := false
--pragma synthesis_off
or true
--pragma synthesis_on
;
constant in_synthesis : boolean := not in_simulation;
As others have mentioned, there is typically a way to turn off synthesis that is tool dependent (check the ISE docs).
When I need something more sophisticated, I perform pre-processing. Typically, I use makefiles and various *nix flavored text processing tools (sed, awk, perl, &c). This can be as simple or as complex as desired. What started as a way to uncomment different blocks of code for simulation vs. synthesis now extracts register documentation and auto-generates C header files for the SW team.
If you don't want to "roll you own", you can apply one of the many pre-existing implementations (C pre-processer, m4 macro language, &c) to your build process.

Resources