How to identify verilog compiler at compile-time?

G

Gammaburst

Guest
How do I put compile-time switches into my Verilog source code so that
it compiles different stuff depending on which compiler I'm using? I
thought this would be easy, like in C where I say "#ifdef __MSVC__" or
"#ifdef __GNUC__", but I can't find any unique pre-defined values in
the Verilog compilers that I'm using (ModelSim, Synplify Pro, and
Xilinx XST). Maybe I just haven't found the right manual page.
 
Gammaburst asked:

How do I put compile-time switches into my Verilog source code so that
it compiles different stuff depending on which compiler I'm using?
As far as I know, you can't, at least not reliably. There is nothing
in the standard that suggests that an implementation specific `define
should be generated by any simulator or synthesis tool, and I'm not
aware of any `define's being defined that serve that purpose.

Now, despite the vendors not generally providing such a feature, many
vendors provide a way of defining "on the command line" (or in some
equivalent fashion, e.g. in a header file found via a search rule) a
way of defining your own "compiler specific" includes.

The next question is why would you want to do that? Are you using
different synthesis tools and you have different specific cell
instantiations that you use to make your model generate the right
gates? Or are you using different simulators and trying to work
around different corner cases (bugs) in the implementation? Or is
there some other reason? Inquiring minds want to know....

-Chris
 
Gammaburst <spambots@eat.this> wrote in message news:<gpp9pvg8akq2otssjtcjrdq81gucgaph01@4ax.com>...
How do I put compile-time switches into my Verilog source code so that
it compiles different stuff depending on which compiler I'm using? I
thought this would be easy, like in C where I say "#ifdef __MSVC__" or
"#ifdef __GNUC__", but I can't find any unique pre-defined values in
the Verilog compilers that I'm using (ModelSim, Synplify Pro, and
Xilinx XST). Maybe I just haven't found the right manual page.
NC-Verilog predefines such a macro, but perhaps the tools you are using
do not.
 
Gammaburst <spambots@eat.this> writes:

How do I put compile-time switches into my Verilog source code so that
it compiles different stuff depending on which compiler I'm using? I
thought this would be easy, like in C where I say "#ifdef __MSVC__" or
"#ifdef __GNUC__", but I can't find any unique pre-defined values in
the Verilog compilers that I'm using (ModelSim, Synplify Pro, and
Xilinx XST). Maybe I just haven't found the right manual page.
You should try to specify what *feature* you want, not what simulator
you are using, e.g. something like:


// most simulators, e.g. icarus have VCD support
if ($test$plusargs("VCD")) begin
$display("%t - %m : starting VCD dump file",$time);
$dumpfile("test.vcd");
$dumpvars(0,top);
end
// signalscan dump files enabled if +TRN given
`ifdef HAS_TRN
if ($test$plusargs("TRN")) begin
$display("%t - %m : starting TRN dump file",$time);
$recordsetup("design=test","version=1","run=1","compress",);
$recordvars;
end
`endif

Then if your driver script is starting a simulator with TRN support
you do +define+HAS_TRN when you compile.

You can even use a tool like autoconf to run a tiny simulation and see
if the simulator will run if you specify $recordsetup and set the
HAS_TRN accordingly.

Petter

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
On 21 Oct 2003 11:28:09 -0400, Chris F Clark
<cfc@shell01.TheWorld.com> wrote:

Gammaburst asked:

How do I put compile-time switches into my Verilog source code so that
it compiles different stuff depending on which compiler I'm using?

As far as I know, you can't, at least not reliably. There is nothing
in the standard that suggests that an implementation specific `define
should be generated by any simulator or synthesis tool, and I'm not
aware of any `define's being defined that serve that purpose.

Now, despite the vendors not generally providing such a feature, many
vendors provide a way of defining "on the command line" (or in some
equivalent fashion, e.g. in a header file found via a search rule) a
way of defining your own "compiler specific" includes.

The next question is why would you want to do that? Are you using
different synthesis tools and you have different specific cell
instantiations that you use to make your model generate the right
gates? Or are you using different simulators and trying to work
around different corner cases (bugs) in the implementation? Or is
there some other reason? Inquiring minds want to know....

-Chris

Mostly, it's attribute syntax. Every compiler does it differently.
For example, initializing a Virtex II Block RAM:

RAMB16_S18 U_RAMB16_S18 (...)
`ifdef synplify
/* synthesis xc_props="INIT_00=00A0FC1B...3378, \
INIT_00=FFFFFFFF...FFFF" */;
`endif
`ifdef xst
;
// synthesis attribute INIT_00 U_RAMB16_S18 "00A0FC1B...3378"
// synthesis attribute INIT_01 U_RAMB16_S18 "FFFFFFFF...FFFF"
`endif
`ifdef modelsim
;
defparam U_RAMB16_S18.INIT_00 = 256'h00A0FC1B...3378;
defparam U_RAMB16_S18.INIT_01 = 256'hFFFFFFFF...FFFF;
`endif


Here's my current clumsy method to identify the compiler. It also
defines 'simulation' if ModelSim, and 'synthesis' if Synplify or XST:

// Try to identify compiler: ModelSim, Synplify, or XST
`ifdef synthesis // if Synplify
`define synplify
`else // if not Synplify
`define xst
// synthesis translate_off // if XST then stop compiling
`undef xst
`define simulation
`define modelsim
// synthesis translate_on // if XST then resume compiling
`ifdef xst
`define synthesis
`endif
`endif
 
Gammaburst <spambots@eat.this> writes:

Mostly, it's attribute syntax. Every compiler does it differently.
For example, initializing a Virtex II Block RAM:

RAMB16_S18 U_RAMB16_S18 (...)
`ifdef synplify
/* synthesis xc_props="INIT_00=00A0FC1B...3378, \
INIT_00=FFFFFFFF...FFFF" */;
`endif
`ifdef xst
;
// synthesis attribute INIT_00 U_RAMB16_S18 "00A0FC1B...3378"
// synthesis attribute INIT_01 U_RAMB16_S18 "FFFFFFFF...FFFF"
`endif
`ifdef modelsim
;
defparam U_RAMB16_S18.INIT_00 = 256'h00A0FC1B...3378;
defparam U_RAMB16_S18.INIT_01 = 256'hFFFFFFFF...FFFF;
`endif

I'm in the favor of testing for functionality instead of products.
This way you don't have to change your source files when you start
using a new tool if it share a feature sub-set (but not all) with some
of your older tools.


What if you did something like:

`ifdef USE_XC_PROPS

/* synthesis xc_props="INIT_00=00A0FC1B...3378, \
INIT_00=FFFFFFFF...FFFF" */;
`endif
`ifdef USE_INIT_ATTRIBUTE
// synthesis attribute INIT_00 U_RAMB16_S18 "00A0FC1B...3378"
// synthesis attribute INIT_01 U_RAMB16_S18 "FFFFFFFF...FFFF"
`endif
`ěfdef USE_DEFPARAM
defparam U_RAMB16_S18.INIT_00 = 256'h00A0FC1B...3378;
defparam U_RAMB16_S18.INIT_01 = 256'hFFFFFFFF...FFFF;
`endif


Then in the respective launching script (or GUI) you define the
respective USE variable. Most verilog simulators would accept
+define+USE_DEFPARAM on the command line. Or, you could have a define
file for each of your tools which defines the supported features above
and then include the define file when you call the respective tool.

My favorite way of detecting features is to use the GNU autoconf tool
to make a configure script which will detect the feature set by trying
to simulate or compile a small snippet containing the feature. If it
succedes to generate an expected output you can enable the fature in
your feature define file.


On the other hand what kind of problems do you get if you do all:

/* synthesis xc_props="INIT_00=00A0FC1B...3378, \
INIT_00=FFFFFFFF...FFFF" */;
// synthesis attribute INIT_00 U_RAMB16_S18 "00A0FC1B...3378"
// synthesis attribute INIT_01 U_RAMB16_S18 "FFFFFFFF...FFFF"
defparam U_RAMB16_S18.INIT_00 = 256'h00A0FC1B...3378;
defparam U_RAMB16_S18.INIT_01 = 256'hFFFFFFFF...FFFF;

All simulators I use (Synopsys, Cadence, and Fintronic) ignore the
pragmas embedded in comments. I would suspect that modelsim does this
too. Hence you could leave the defparam in unconditionally.

Further most synthesis tools I've used seem to ignore pragmas they
don't support (or give a warning only). That way you could leave in
all the above. Is this true for your toolchain?

Petter

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
On 24 Oct 2003 09:42:30 +0200, Petter Gustad
<newsmailcomp5@gustad.com> wrote:
I'm in the favor of testing for functionality instead of products.
This way you don't have to change your source files when you start
using a new tool if it share a feature sub-set (but not all) with some
of your older tools.


What if you did something like:

`ifdef USE_XC_PROPS

/* synthesis xc_props="INIT_00=00A0FC1B...3378, \
INIT_00=FFFFFFFF...FFFF" */;
`endif
`ifdef USE_INIT_ATTRIBUTE
// synthesis attribute INIT_00 U_RAMB16_S18 "00A0FC1B...3378"
// synthesis attribute INIT_01 U_RAMB16_S18 "FFFFFFFF...FFFF"
`endif
`ěfdef USE_DEFPARAM
defparam U_RAMB16_S18.INIT_00 = 256'h00A0FC1B...3378;
defparam U_RAMB16_S18.INIT_01 = 256'hFFFFFFFF...FFFF;
`endif


Then in the respective launching script (or GUI) you define the
respective USE variable. Most verilog simulators would accept
+define+USE_DEFPARAM on the command line. Or, you could have a define
file for each of your tools which defines the supported features above
and then include the define file when you call the respective tool.

My favorite way of detecting features is to use the GNU autoconf tool
to make a configure script which will detect the feature set by trying
to simulate or compile a small snippet containing the feature. If it
succedes to generate an expected output you can enable the fature in
your feature define file.


On the other hand what kind of problems do you get if you do all:

/* synthesis xc_props="INIT_00=00A0FC1B...3378, \
INIT_00=FFFFFFFF...FFFF" */;
// synthesis attribute INIT_00 U_RAMB16_S18 "00A0FC1B...3378"
// synthesis attribute INIT_01 U_RAMB16_S18 "FFFFFFFF...FFFF"
defparam U_RAMB16_S18.INIT_00 = 256'h00A0FC1B...3378;
defparam U_RAMB16_S18.INIT_01 = 256'hFFFFFFFF...FFFF;

All simulators I use (Synopsys, Cadence, and Fintronic) ignore the
pragmas embedded in comments. I would suspect that modelsim does this
too. Hence you could leave the defparam in unconditionally.

Further most synthesis tools I've used seem to ignore pragmas they
don't support (or give a warning only). That way you could leave in
all the above. Is this true for your toolchain?

Petter

Thanks for the suggestions. Yes it would be better to switch on
features rather than products. Unfortunately, Synplify complains if it
sees XST's "// synthesis attribute". XST complains if it sees
ModelSim's defparam. Synplify's "synthesis xc_props=" is the only safe
one.

I don't see any way to define a macro on the command line in any of
these tools. Even ModelSim ignores +define.

Yes I could use little define files. That's my fallback approach.
 
On Tue, 21 Oct 2003 01:01:07 -0700, Gammaburst <spambots@eat.this>
wrote:

How do I put compile-time switches into my Verilog source code so that
it compiles different stuff depending on which compiler I'm using? I
thought this would be easy, like in C where I say "#ifdef __MSVC__" or
"#ifdef __GNUC__", but I can't find any unique pre-defined values in
the Verilog compilers that I'm using (ModelSim, Synplify Pro, and
Xilinx XST). Maybe I just haven't found the right manual page.
Not quite on-topic for this thread, but here's how I have identified
the compiler from within a Tcl compile script. This can be used to
generate compiler dependent command line args, etc. and allows a
single compile script to be used in multiple tools.

Most compilers allow some sort of Tcl scripting. Notable exceptions
(at the low cost end of the market) are XST and Icarus iverilog.

if {![info exists interpreter]} {
if {[info exists env(MODEL_TECH)] && [llength [info commands
vsimVersion]] == 1} {
# Modelsim
} elseif {[llength [info commands add_file]] == 1} {
# Synplify
} elseif { [info exists ::Symphony::Version] } {
# Simili (VHDL only)
} elseif {[info exists registry_product_name] && [string compare
$registry_product_name "LeonardoSpectrum"] == 0} {
# Leonardo
} elseif {[info exists aldec] && [llength [info commands acom]] ==
1} {
# Aldec (& Riviera)
} else {
# put tests for other tools here

puts "unknown TCL interpreter";
}
}

Regards,
Allan.
 

Welcome to EDABoard.com

Sponsor

Back
Top