Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

218 lines (161 sloc) 8.249 kB
Icarus Verilog vs. IEEE1364
Copyright 2000 Stephen Williams
The IEEE1364 standard is the bible that defines the correctness of the
Icarus Verilog implementation and behavior of the compiled
program. The IEEE1364.1 is also referenced for matters of
synthesis. So the ultimate definition of right and wrong comes from
those documents.
That does not mean that a Verilog implementation is fully
constrained. The standard document allows for implementation specific
behavior that, when properly accounted for, does not effect the
intended semantics of the specified language. It is therefore possible
and common to write programs that produce different results when run
by different Verilog implementations.
These are some issues where the IEEE1364 left unclear, unspecified or
simply wrong. I'll try to be precise as I can, and reference the
standard as needed. I've made implementation decisions for Icarus
Verilog, and I will make clear what those decisions are and how they
affect the language.
Consider this module:
module sample1;
initial foo = 1;
reg foo;
wire tmp = bar;
initial #1 $display("foo = %b, bar = %b", foo, tmp);
Notice that the ``reg foo;'' declaration is placed after the first
initial statement. It turns out that this is a perfectly legal module
according to the -1995 and -2000 versions of the standard. The
statement ``reg foo;'' is a module_item_declaration which is in turn a
module_item. The BNF in the appendix of IEEE1364-1995 treats all
module_item statements equally, so no order is imposed.
Furthermore, there is no text (that I can find) elsewhere in the
standard that imposes any ordering restriction. The sorts of
restrictions I would look for are "module_item_declarations must
appear before all other module_items" or "variables must be declared
textually before they are referenced." Such statements simply do not
exist. (Personally, I think it is fine that they don't.)
The closest is the rules for implicit declarations of variables that
are otherwise undeclared. In the above example, ``bar'' is implicitly
declared and is therefore a wire. However, although ``initial foo = 1;''
is written before foo is declared, foo *is* declared within the
module, and declared legally by the BNF of the standard.
Here is another example:
module sample2;
initial = 1;
test x;
initial #1 $display("foo = %b",;
module test;
reg foo;
From this example one can clearly see that foo is once again declared
after its use in behavioral code. One also sees a forward reference of
an entire module. Once again, the standard places no restriction on
the order of module declarations in a source file, so this program is,
according to the standard, perfectly well formed.
Icarus Verilog interprets both of these examples according to "The
Standard As I Understand It." However, commercial tools in general
break down with these programs. In particular, the first example
may generate different errors depending on the tool. The most common
error is to claim that ``foo'' is declared twice, once (implicitly) as
a wire and once as a reg.
So the question now becomes, "Is the standard broken, or are the tools
limited?" Coverage of the standard seems to vary widely from tool to
tool so it is not clear that the standard really is at fault. It is
clear, however, that somebody goofed somewhere.
My personal opinion is that there is no logical need to require that
all module_item_declarations preceed any other module items. I
personally would oppose such a restriction. It may make sense to
require that declarations of variables within a module be preceded by
their use, although even that is not necessary for the implementation
of efficient compilers.
However, the existence hierarchical naming syntax as demonstrated in
sample2 can have implications that affect any declaration order
rules. When reaching into a module with a hierarchical name, the
module being referenced is already completely declared (or not
declared at all, as in sample2) so module_item order is completely
irrelevent. But a "declare before use" rule would infect module
ordering, by requiring that modules that are used be first defined.
Consider a function negate that wants to take a signed integer value
and return its negative:
function integer negate;
input [15:0] val;
negate = -val;
This is not quite right, because the input is implicitly a reg type,
which is unsigned. The result, then, will always be a negative value,
even if a negative val is passed in.
It is possible to fix up this specific example to work properly with
the bit pattern of a 16bit number, but that is not the point. What's
needed is clarification on whether an input can be declared in the
port declaration as well as in the contained block declaration.
As I understand the situation, this should be allowed:
function integer negate;
input [15:0] val;
reg signed [15:0] val;
negate = -val;
In the -1995 standard, the variable is already implicitly a reg if
declared within a function or task. However, in the -2000 standard
there is now (as in this example) a reason why one might want to
actually declare the type explicitly.
I think that a port *cannot* be declared as an integer or time type
(though the result can) because the range of the port declaration must
match the range of the integer/time declaration, but the range of
integers is unspecified. This, by the way, also applies to module
When the `timescale directive is present, the compiler is supposed to
round fractional times (after scaling) to the nearest integer. The
confusing bit here is that it is apparently conventional that if the
`timescale directive is *not* present, times are rounded towards zero
The IEEE1364-1995 standard clearly states in Table 8-1 that the x
symbols is allowed in input columns, but is not allowed in
outputs. Furthermore, none of the examples have an x in the output of
a primitive. Table 8-1 in the IEEE1364-2000 also says the same thing.
However, the BNF clearly states that 0, 1, x and X are valid
output_symbol characters. The standard is self contradictory. So I
take it that x is allowed, as that is what Verilog-XL does.
There seems to be ambiguity in how code like this should be parsed:
repeat (5) @(posedge clk) <statment>;
There are two valid interpretations of this code, from the
IEEE1364-1995 standard. One looks like this:
procedural_timing_control_statement ::=
delay_or_event_control statement_or_null
delay_or_event_control ::=
| repeat ( expression ) event_control
If this interpretation is used, then the statement <statement> should
be executed after the 5th posedge of clk. However, there is also this
loop_statement ::=
repeat ( expression ) statement
If *this* interpretation is used, then <statement> should be executed
5 times on the posedge of clk. The way the -1995 standard is written,
these are both equally valid interpretations of the example, yet they
produce very different results. The standard offers no guidance on how
to resolve this conflict, and the IEEE1364-2000 DRAFT does not improve
the situation.
Practice suggests that a repeat followed by an event control should be
interpreted as a loop head, and this is what Icarus Verilog does, as
well as all the other major Verilog tools, but the standard does not
say this.
$Id: ieee1364-notes.txt,v 1.5 2001/01/02 17:28:08 steve Exp $
$Log: ieee1364-notes.txt,v $
Revision 1.5 2001/01/02 17:28:08 steve
Resolve repeat ambiguity in favor of loop.
Revision 1.4 2001/01/01 19:12:35 steve
repeat loops ambiguity.
Revision 1.3 2000/12/15 00:21:46 steve
rounding of time and x in primitives.
Revision 1.2 2000/11/19 22:03:04 steve
Integer parameter comments.
Revision 1.1 2000/07/23 18:06:31 steve
Document ieee1364 issues.
Jump to Line
Something went wrong with that request. Please try again.