Foundation Express recognizes the following Verilog statements and constructs when they are used in a Verilog module.
Data declarations and assignments are described in this section. Module and gate instantiations are described later in this chapter. Function definitions, task statements, and always blocks are described in the Functional Descriptions chapter.
Verilog structural data types include wire, wand, wor, tri, supply0, and supply1. Although parameter does not fall into the category of structural data types, it is presented here because it is used with structural data types.
You can define an optional range for all the data types presented in this section. The range provides a means for creating a bit vector. The syntax for a range specification follows.
[msb : lsb]
Expressions for msb (most significant bit) and lsb (least significant bit) must be non-negative constant-valued expressions. Constant-valued expressions are composed only of constants, Verilog parameters, and operators.
You can customize each instantiation of a module by using Verilog parameters. By setting different values for the parameter when you instantiate the module, you can construct different logic. For more information, see the Parameterized Designs section of this chapter.
A parameter definition symbolically represents constant values. The definition for a parameter consists of the parameter name and the value assigned to it. The value can be any constant-valued expression of integer or Boolean type, but not of real type. If you do not set the size of the parameter with a range definition or a sized constant, the parameter is unsized and defaults to a 32-bit quantity. Refer to the Expressions chapter for information about the format of constants.
You can use a parameter wherever a number is allowed, and you can define a parameter anywhere within a module definition. However, the Verilog language requires that you define the parameter before you use it.
The following example shows two parameter declarations. Parameters TRUE and FALSE are unsized and have values of 1 and 0, respectively. Parameters S0, S1, S2, and S3 have values of 3, 1, 0, and 2, respectively, and are stored as 2-bit quantities.
parameter TRUE=1, FALSE=0;
parameter [1:0]S0=3,S1=1,S2=0,S3=2;
A wire data type in a Verilog description represents the physical wires in a circuit. A wire connects gate-level instantiations and module instantiations. With the Verilog language, you can read a wire value from within a function or a begin...end block, but you cannot delete a wire value from within a function or a begin...end block. (An always block is a specific type of begin...end block).
A wire does not store its value. It must be driven in one of two ways.
In the Verilog language, an undriven wire defaults to a value of Z (high impedance). However, Foundation Express either leaves undriven wires unconnected or connects some undriven wires to a constraint value, depending on the requirements of the vendor place and route tool. When an undriven wire is connected to a constant value, Foundation Express issues a warning for the corresponding implementation. Multiple connections or assignments to a wire short the wires together.
In the following example, two wire data types are declared, a is a single-bit wire, while b is a 3-bit vector of wires. Its most significant bit (msb) has an index of 2 and its least significant bit (lsb) has an index of 0.
wire a;
wire [2:0] b;
You can assign a delay value in a wire declaration, and you can use the Verilog keywords scalared and vectored for simulation. Foundation Express accepts the syntax of these constructs, but they are ignored when the circuit is synthesized.
You can use delay information for modeling, but Foundation Express ignores this delay information. If the functionality of your circuit depends on the delay information, Foundation Express might create logic with behavior that does not agree with the behavior of the simulated circuit.
The wand (wired AND) data type is a specific type of wire data type.
In the following example, two variables drive the variable c. The value of c is determined by the logical AND of a and b.
module wand_test(a,b,c);
input a,b;
output c;
wand c;
assign c = a;
assign c = b;
endmodule
You can assign a delay value in a wand declaration, and you can use the Verilog keywords scalared and vectored for simulation. Foundation Express accepts the syntax of these constructs, but they are ignored when the circuit is synthesized.
The wor (wired OR) data type is a specific type of wire data type.
In the following example, two variables drive the variable c. The value of c is determined by the logical OR of a and b.
module wor_test(a, b, c);
input a, b;
output c;
wor c;
assign c = a;
assign c = b;
endmodule
The tri (three-state) data type is a specific type of wire data type. Only one of the variables that drive the tri data type can have a non-Z (high impedance) value. This single variable determines the value of the tri data type.
You must ensure that no more than one variable driving a tri data type has a value other than Z, because Foundation Express does not enforce this condition.
In the following example, three variables drive the variable out.
module tri_test (out,condition);
input [1:0] condition;
output out;
reg a,b,c;
tri out;
always @ (condition) begin
a = 1'bz;//set all variables to Z
b = 1'bz;
c = 1'bz;
case (condition) //set only one variable to non-Z
2'b00 : a = 1'b1;
2'b01 : b = 1'b0;
2'b10 : c = 1'b1;
endcase
end
assign out = a; // make the tri connection
assign out = b;
assign out = c;
endmodule
The supply0 and supply1 data types define wires tied to logic 0 (ground) and logic 1 (power). Using supply0 and supply1 is the same as declaring a wire and assigning a 0 or a 1 to it. In the following example, power is tied to logic 1 and gnd is tied to logic 0.
supply0 gnd;
supply1 power;
A reg represents a variable in Verilog. A reg can be a 1-bit quantity or a vector of bits. For a vector of bits, the range indicates the most significant bit (msb) and least significant bit (lsb) of the vector. Both bits must be non-negative constants, parameters, or constant-valued expressions. The following example shows reg declarations.
reg x;// single bit
reg a,b,c;// 3 1-bit quantities
reg [7:0] q;// an 8-bit vector
You must explicitly declare the direction (input, output, or bidirectional) of each port that appears in the port list of a port definition. Use the input, output, and inout statements, as described in the following sections.
All input ports of a module are declared with an input statement. An input is a type of wire and is governed by the syntax of wire. You can use a range specification to declare an input that is a vector of signals, as for input b in the following example. The input statements can appear in any order in the description but must be declared before they are used. The following is an example.
input a;
input [2:0] b;
All output ports of a module are declared with an output statement. Unless otherwise defined by a reg, wand, wor, or tri declaration, an output is a type of wire and is governed by the syntax of wire. An output statement can appear in any order in the description, but you must declare the output before you use it.
You can use a range specification to declare an output value that is a vector of signals. If you use a reg declaration for an output, the reg must have the same range as the vector of signals. The following declaration is an example.
output a;
output [2:0]b;
reg [2:0] b;
You can declare bidirectional ports with the inout statement. An inout is a type of wire and is governed by the syntax of wire. With Foundation Express, you can connect only inout ports to module or gate instantiations. You must declare an inout before you use it. The following declaration is an example.
inout a;
inout [2:0]b;
If you want to drive a value onto a wire, wand, wor, or tri, use a continuous assignment to specify an expression for the wire value. You can specify a continuous assignment in two ways.
The following example shows two equivalent continuous assignments for wire a.
wire a; // declare
assign a = b & c; // assign
wire a = b & c; // declare and assign
The left side of a continuous assignment can be any of the following.
The right side of the continuous assignment statement can be any supported Verilog operator or any arbitrary expression that uses previously declared variables and functions. You cannot assign a value to a reg in a continuous assignment.
With Verilog, you can assign drive strength for each continuous assignment statement. Foundation Express accepts drive strength, but it does not affect the synthesis of the circuit. Keep this in mind when you use drive strength in your Verilog source.
Assignments are performed bit-wise, with the low bit on the right side assigned to the low bit on the left side.