wire a wire b trireg_la trireg_sm 0 strong 1
4.8 Integers, reals, times, and realtimes
In addition to modeling hardware, there are other uses for variables in an HDL model. Although reg variables can be used for general purposes such as counting the number of times a particular net changes value, the integer and time variable data types are provided for convenience and to make the description more self-documenting.
The syntax for declaring integer, time, real, and realtime variables is given in Syntax 4-3 (from Syntax 4-2).
Syntax 4-3—Syntax for integer, time, real, and realtime declarations
The syntax for a list of reg variables is defined in 4.2.2.
An integer is a general-purpose variable used for manipulating quantities that are not regarded as hardware registers.
integer_declaration ::= (From A.2.1.3) integer list_of_variable_identifiers ; real_declaration ::=
real list_of_real_identifiers ; realtime_declaration ::=
realtime list_of_real_identifiers ; time_declaration ::=
time list_of_variable_identifiers ; real_type ::= (From A.2.2.1)
real_identifier { dimension }
| real_identifier = constant_expression variable_type ::=
variable_identifier { dimension }
| variable_identifier = constant_expression list_of_real_identifiers ::= (From A.2.3)
real_type { , real_type } list_of_variable_identifiers ::=
variable_type { , variable_type } dimension ::= (From A.2.5)
[ dimension_constant_expression : dimension_constant_expression ]
A time variable is used for storing and manipulating simulation time quantities in situations where timing checks are required and for diagnostics and debugging purposes. This data type is typically used in conjunction with the $time system function (see 17.7.1).
The integer and time variables shall be assigned values in the same manner as reg. Procedural assignments shall be used to trigger their value changes.
The time variables shall behave the same as a reg of at least 64 bits, with the least significant bit being bit 0.
They shall be unsigned quantities, and unsigned arithmetic shall be performed on them. In contrast, integer variables shall be treated as signed regs with the least significant bit being zero. Arithmetic operations performed on integer variables shall produce twos-complement results.
Bit-selects and part-selects of vector regs, integer variables, and time variables shall be allowed (see 5.2).
Implementations may limit the maximum size of integer variables, but it shall be at least 32 bits.
The Verilog HDL supports real number constants and real variable data types in addition to integer and time variable data types. Except for the following restrictions, variables declared as real can be used in the same places that integer and time variables are used:
— Not all Verilog HDL operators can be used with real number values. See Table 5-2 and Table 5-3 for lists of valid and invalid operators for real numbers and real variables.
— Real variables shall not use range in the declaration.
— Real variables shall default to an initial value of zero.
The realtime declarations shall be treated synonymously with real declarations and can be used interchangeably.
For example:
integer a; // integer value time last_chng; // time value
real float ; // a variable to store a real value
realtime rtime ; // a variable to store time as a real value 4.8.1 Operators and real numbers
The result of using logical or relational operators on real numbers and real variables is a single-bit scalar value. Not all Verilog HDL operators can be used with expressions involving real numbers and real variables. Table 5-2 lists the valid operators for use with real numbers and real variables. Real number constants and real variables are also prohibited in the following cases:
— Edge descriptors (posedge, negedge) applied to real variables
— Bit-select or part-select references of variables declared as real
— Real number index expressions of bit-select or part-select references of vectors 4.8.2 Conversion
Real numbers shall be converted to integers by rounding the real number to the nearest integer, rather than by truncating it. Implicit conversion shall take place when a real number is assigned to an integer. If the fractional part of the real number is exactly 0.5, it shall be rounded away from zero.
Implicit conversion shall take place when an expression is assigned to a real. Individual bits that are x or z in the net or the variable shall be treated as zero upon conversion.
See 17.8 for a discussion of system tasks that perform explicit conversion.
4.9 Arrays
An array declaration for a net or a variable declares an element type that is either scalar or vector (see 4.3).
For example:
NOTE—Array size does not affect the element size.
Arrays can be used to group elements of the declared element type into multidimensional objects. Arrays shall be declared by specifying the element address range(s) after the declared identifier. Each dimension shall be represented by an address range. See 4.2.1 and 4.2.2 for net and variable declarations. The expressions that specify the indices of the array shall be constant integer expressions. The value of the constant expression can be a positive integer, a negative integer, or zero.
One declaration statement can be used for declaring both arrays and elements of the declared data type. This ability makes it convenient to declare both arrays and elements that match the element vector width in the same declaration statement.
An element can be assigned a value in a single assignment, but complete or partial array dimensions cannot.
Nor can complete or partial array dimensions be used to provide a value to an expression. To assign a value to an element of an array, an index for every dimension shall be specified. The index can be an expression.
This option provides a mechanism to reference different array elements depending on the value of other variables and nets in the circuit. For example, a program counter reg can be used to index into a random access memory (RAM).
Implementations may limit the maximum size of an array, but they shall allow at least 16 777 216 (224) elements.
4.9.1 Net arrays
Elements of net arrays can be used in the same fashion as a scalar or vector net. They are useful for connecting to ports of module instances inside loop generate constructs (see 12.4.1).
4.9.2 reg and variable arrays
Arrays for all variables types (reg, integer, time, real, realtime) shall be possible.
Declaration Element type
reg x[11:0]; scalar reg
wire [0:7] y[5:0]; 8-bit-wide vector wire indexed from 0 to 7 reg [31:0] x [127:0]; 32-bit-wide reg
4.9.3 Memories
A one-dimensional array with elements of type reg is also called a memory. These memories can be used to model read-only memories (ROMs), random access memories (RAMs), and reg files. Each reg in the array is known as an element or word and is addressed by a single array index.
An n-bit reg can be assigned a value in a single assignment, but a complete memory cannot. To assign a value to a memory word, an index shall be specified. The index can be an expression. This option provides a mechanism to reference different memory words, depending on the value of other variables and nets in the circuit. For example, a program counter reg could be used to index into a RAM.
4.9.3.1 Array examples 4.9.3.1.1 Array declarations
reg [7:0] mema[0:255]; // declares a memory mema of 256 8-bit // registers. The indices are 0 to 255 reg arrayb[7:0][0:255]; // declare a two-dimensional array of
// one bit registers wire w_array[7:0][5:0]; // declare array of wires
integer inta[1:64]; // an array of 64 integer values time chng_hist[1:1000] // an array of 1000 time values integer t_index;
4.9.3.1.2 Assignment to array elements
The assignment statements in this subclause assume the presence of the declarations in 4.9.3.1.1.
mema = 0; // Illegal syntax- Attempt to write to entire array arrayb[1] = 0; // Illegal Syntax - Attempt to write to elements // [1][0]..[1][255]
arrayb[1][12:31] = 0; // Illegal Syntax - Attempt to write to // elements [1][12]..[1][31]
mema[1] = 0; // Assigns 0 to the second element of mema arrayb[1][0] = 0; // Assigns 0 to the bit referenced by indices // [1][0]
inta[4] = 33559; // Assign decimal number to integer in array chng_hist[t_index] = $time; // Assign current simulation time to // element addressed by integer index 4.9.3.1.3 Memory differences
A memory of n 1-bit regs is different from an n-bit vector reg.
reg [1:n] rega; // An n-bit register is not the same reg mema [1:n]; // as a memory of n 1-bit registers
4.10 Parameters
Verilog HDL parameters do not belong to either the variable or the net group. Parameters are not variables;
they are constants. There are two types of parameters: module parameters and specify parameters. It is illegal to redeclare a name already declared by a net, parameter, or variable declaration.
Both types of parameters accept a range specification. By default, parameters and specparams shall be as wide as necessary to contain the value of the constant, except when a range specification is present.
4.10.1 Module parameters
The syntax for module parameter declarations is given in Syntax 4-4.
Syntax 4-4—Syntax for module parameter declaration
The list_of_param_assignments shall be a comma-separated list of assignments, where the right-hand side of the assignment shall be a constant expression, that is, an expression containing only constant numbers and previously defined parameters (see Clause 5).
The list_of_param_assignments can appear in a module as a set of module_items or in the module declaration in the module_parameter_port_list (see 12.1). If any param_assignments appear in a module_parameter_port_list, then any param_assignments that appear in the module become local parameters and shall not be overridden by any method.
Parameters represent constants; hence, it is illegal to modify their value at run time. However, module parameters can be modified at compilation time to have values that are different from those specified in the declaration assignment. This allows customization of module instances. A parameter can be modified with the defparam statement or in the module instance statement. Typical uses of parameters are to specify delays and width of variables. See 12.2 for details on parameter value assignment.
A module parameter can have a type specification and a range specification. The type and range of module parameters shall be in accordance with the following rules:
— A parameter declaration with no type or range specification shall default to the type and range of the final value assigned to the parameter, after any value overrides have been applied.
— A parameter with a range specification, but with no type specification, shall be the range of the parameter declaration and shall be unsigned. The sign and range shall not be affected by value overrides.
— A parameter with a type specification, but with no range specification, shall be of the type specified.
A signed parameter shall default to the range of the final value assigned to the parameter, after any value overrides have been applied.
— A parameter with a signed type specification and with a range specification shall be signed and shall be the range of its declaration. The sign and range shall not be affected by value overrides.
local_parameter_declaration ::= (From A.2.1.1)
localparam [ signed ] [ range ] list_of_param_assignments
| localparam parameter_type list_of_param_assignments parameter_declaration ::=
parameter [ signed ] [ range ] list_of_param_assignments
| parameter parameter_type list_of_param_assignments parameter_type ::=
integer | real | realtime | time
list_of_param_assignments ::= (From A.2.3) param_assignment { , param_assignment } param_assignment ::= (From A.2.4)
parameter_identifier = constant_mintypmax_expression range ::= (From A.2.5)
[ msb_constant_expression : lsb_constant_expression ]
— A parameter with no range specification and with either a signed type specification or no type specification shall have an implied range with an lsb equal to 0 and an msb equal to one less than the size of the final value assigned to the parameter.
— A parameter with no range specification, with either a signed type specification or no type specification, and for which the final value assigned to it is unsized shall have an implied range with an lsb equal to 0 and an msb equal to an implementation-dependent value of at least 31.
The conversion rules between real and integer values described in 4.8.2 apply to parameters as well.
Bit-selects and part-selects of parameters that are not of type real shall be allowed (see 5.2).
For example:
parameter msb = 7; // defines msb as a constant value 7 parameter e = 25, f = 9; // defines two constant numbers parameter r = 5.7; // declares r as a real parameter parameter byte_size = 8,
byte_mask = byte_size - 1;
parameter average_delay = (r + f) / 2;
parameter signed [3:0] mux_selector = 0;
parameter real r1 = 3.5e17;
parameter p1 = 13'h7e;
parameter [31:0] dec_const = 1'b1; // value converted to 32 bits parameter newconst = 3'h4; // implied range of [2:0]
parameter newconst = 4; // implied range of at least [31:0]
4.10.2 Local parameters (localparam)
Verilog HDL local parameters are identical to parameters except that they cannot directly be modified by defparam statements (see 12.2.1) or module instance parameter value assignments (see 12.2.2). Local parameters can be assigned constant expressions containing parameters, which can be modified with defparam statements or module instance parameter value assignments.
Bit-selects and part-selects of local parameters that are not of type real shall be allowed (see 5.2).
The syntax for local parameter declarations is given in Syntax 4-4.
4.10.3 Specify parameters
The syntax for declaring specify parameters is shown in Syntax 4-5.
Syntax 4-5—Syntax for specparam declaration
The keyword specparam declares a special type of parameter that is intended only for providing timing and delay values, but can appear in any expression that is not assigned to a parameter and is not part of the range specification of a declaration. Specify parameters (also called specparams) are permitted both within the specify block (see Clause 14) and in the main module body.
A specify parameter declared outside a specify block shall be declared before it is referenced. The value assigned to a specify parameter can be any constant expression. A specify parameter can be used as part of a constant expression for a subsequent specify parameter declaration. Unlike a module parameter, a specify parameter cannot be modified from within the language, but it can be modified through SDF annotation (see Clause 16).
Specify parameters and module parameters are not interchangeable. In addition, module parameters shall not be assigned a constant expression that includes any specify parameters. Table 4-7 summarizes the differences between the two types of parameter declarations.
specparam_declaration ::= (From A.2.1.1)
specparam [ range ] list_of_specparam_assignments ; list_of_specparam_assignments ::= (From A.2.3)
specparam_assignment { , specparam_assignment } specparam_assignment ::= (From A.2.4)
specparam_identifier = constant_mintypmax_expression
| pulse_control_specparam pulse_control_specparam ::=
PATHPULSE$ = ( reject_limit_value [ , error_limit_value ] )
| PATHPULSE$specify_input_terminal_descriptor$specify_output_terminal_descriptor
= ( reject_limit_value [ , error_limit_value ] ) error_limit_value ::=
limit_value reject_limit_value ::=
limit_value limit_value ::=
constant_mintypmax_expression range ::= (From A.2.5)
[ msb_constant_expression : lsb_constant_expression ]
Table 4-7—Differences between specparams and parameters
Specparams (specify parameter) Parameters (module parameter) Use keyword specparam Use keyword parameter
Shall be declared inside a module or specify block Shall be declared outside specify blocks May only be used inside a module or specify block May not be used inside specify blocks May be assigned specparams and parameters May not be assigned specparams
Use SDF annotation to override values Use defparam or instance declaration parame-ter value passing to override values
A specify parameter can have a range specification. The range of specify parameters shall be in accordance with the following rules:
— A specparam declaration with no range specification shall default to the range of the final value assigned to the parameter, after any value overrides have been applied.
— A specparam with a range specification shall be the range of the parameter declaration. The range shall not be affected by value overrides.
Bit-selects and part-selects of specify parameters that are not of type real shall be allowed (see 5.2).
For example:
specify
specparam tRise_clk_q = 150, tFall_clk_q = 200;
specparam tRise_control = 40, tFall_control = 50;
endspecify
The lines between the keywords specify and endspecify declare four specify parameters. The first line declares specify parameters called tRise_clk_q and tFall_clk_q with values 150 and 200, respectively; the second line declares tRise_control and tFall_control specify parameters with values 40 and 50, respectively.
For example:
module RAM16GEN (output [7:0] DOUT, input [7:0] DIN, input [5:0] ADR, input WE, CE);
specparam dhold = 1.0;
specparam ddly = 1.0;
parameter width = 1;
parameter regsize = dhold + 1.0; // Illegal - cannot assign // specparams to parameters endmodule