2000-07-23 20:06:31 +02:00
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
STANDARDIZATION ISSUES
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
* OBJECTS CAN BE DECLARED ANYWHERE IN THE MODULE
|
|
|
|
|
|
|
|
|
|
Consider this module:
|
|
|
|
|
|
|
|
|
|
module sample1;
|
|
|
|
|
initial foo = 1;
|
|
|
|
|
reg foo;
|
|
|
|
|
wire tmp = bar;
|
|
|
|
|
initial #1 $display("foo = %b, bar = %b", foo, tmp);
|
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
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 x.foo = 1;
|
|
|
|
|
test x;
|
|
|
|
|
initial #1 $display("foo = %b", x.foo);
|
|
|
|
|
endmodule
|
|
|
|
|
|
|
|
|
|
module test;
|
|
|
|
|
reg foo;
|
|
|
|
|
endmodule;
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
2000-11-19 23:03:04 +01:00
|
|
|
|
|
|
|
|
* TASK AND FUNCTION PARAMETERS CANNOT HAVE EXPLICIT TYPES
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
endfunction
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
ports.
|
|
|
|
|
|
|
|
|
|
|
2000-12-15 01:21:46 +01:00
|
|
|
* ROUNDING OF TIME
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
always.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
* VALUE OF X IN PRIMITIVE OUTPUTS
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
|
2001-01-01 20:12:35 +01:00
|
|
|
* REPEAT LOOPS vs. REPEAT EVENT CONTROL
|
|
|
|
|
|
|
|
|
|
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 ::=
|
|
|
|
|
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
|
|
|
|
|
interpretation:
|
|
|
|
|
|
|
|
|
|
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
|
2001-01-02 18:28:08 +01:00
|
|
|
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.
|
2001-01-01 20:12:35 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2001-01-02 18:28:08 +01:00
|
|
|
$Id: ieee1364-notes.txt,v 1.5 2001/01/02 17:28:08 steve Exp $
|
2000-07-23 20:06:31 +02:00
|
|
|
$Log: ieee1364-notes.txt,v $
|
2001-01-02 18:28:08 +01:00
|
|
|
Revision 1.5 2001/01/02 17:28:08 steve
|
|
|
|
|
Resolve repeat ambiguity in favor of loop.
|
|
|
|
|
|
2001-01-01 20:12:35 +01:00
|
|
|
Revision 1.4 2001/01/01 19:12:35 steve
|
|
|
|
|
repeat loops ambiguity.
|
|
|
|
|
|
2000-12-15 01:21:46 +01:00
|
|
|
Revision 1.3 2000/12/15 00:21:46 steve
|
|
|
|
|
rounding of time and x in primitives.
|
|
|
|
|
|
2000-11-19 23:03:04 +01:00
|
|
|
Revision 1.2 2000/11/19 22:03:04 steve
|
|
|
|
|
Integer parameter comments.
|
|
|
|
|
|
2000-07-23 20:06:31 +02:00
|
|
|
Revision 1.1 2000/07/23 18:06:31 steve
|
|
|
|
|
Document ieee1364 issues.
|
|
|
|
|
|