Action Item 46

            Change to use static by default, reference class members, provide example of automatic usage.

Action Item 73

            Resolve Editor’s Note: No syntax or examples of these new attributes was provided by the SV-EC.

Section 10.4

Change as shown in red:

 

In Verilog-2001, the default lifetime for tasks and functions is static. Automatic tasks and functions must be explicitly declared, using the automatic keyword.

 

SystemVerilog adds an optional qualifier to specify the default lifetime of all tasks and functions declared within a module, interface, or program (see Section 15). The lifetime qualifier is automatic or static. The default lifetime is static for modules, and automatic for the program block (see section 15).

 

program automatic test ;

 

       task foo( int a ); ... endtask    // arguments and variables in foo are automatic

 

endmodule

 

Class methods are by default automatic, regardless of the lifetime attribute of the scope in which they are declared. Classes are discussed in section 11.

 

Annex A

Editors Note: This qualifier alters the BNF rules as follows:

module_declaration ::=

{ attribute_instance } module_keyword [ lifetime ] module_identifier [ parameter_port_list ]

         list_of_ports ; [ timeunits_declaration ] { module_item }

endmodule

| { attribute_instance } module_keyword [ lifetime ] module_identifier [ parameter_port_list ]

        [ list_of_port_declarations ] ; [ timeunits_declaration ] { non_port_module_item }

endmodule

 

task_declaration ::=

task [ lifetime ] [ interface_identifier . ] task_identifier ;

{ task_item_declaration }

{ statement }

endtask [ : task_identifier ]

          | task [ lifetime ] [ interface_identifier . ] task_identifier ( task_port_list ) ;

{ block_item_declaration }

{ statement }

endtask [ : task_identifier ]

 

function_declaration ::=

function [ lifetime ] [ signing ] [ range_or_type ]

[ interface_identifier . ] function_identifier ;

{ function_item_declaration }

{ function_statement }

endfunction [ : function_identifier ]

          | function [ lifetime ] [ signing ] [ range_or_type ]

[ interface_identifier . ] function_identifier ( function_port_list ) ;

{ block_item_declaration }

{ function_statement }

endfunction [ : function_identifier ]

 

lifetime ::= static | automatic                // This production already exists

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Action Item 47

            Add const (plus example), include comment on simulation semantic for var updates, add restriction on wire usage.

Section 10.5.2

Change as shown in red:

 

When the argument is passed by reference, both the caller and the subroutine share the same representation of the argument, so any changes made to the argument either within the caller or the subroutine will be visible to each other. The semantics of assignments to variables passed by reference is that changes are seen outside the subroutine immediately (before the subroutine returns). Only variables, not wires, can be passed by reference.

 

Add the following paragraph at the end of the section.

 

To protect arguments passed by reference from being modified by a subroutine, the const qualifier can be used together with ref to indicate that the argument, although passed by reference, is a read-only variable.

 

task show( const ref char [] data );

for( int j = 0; j < data.size ; j++ )

    $display( data[j] );      // data can be read but not written

endtask

 

When the formal argument is declared as a const ref, the subroutine cannot alter the variable, and an attempt to do so will generate compiler error.

 

Action Item 48

Add clarification about mixed named and default argument usage.

Section 10.5.4

Add paragraph at end of section as shown in red:

 

If the arguments have default values, they are treated like parameters to module instances. If the arguments do not have a default, then they must be given or the compiler shall issue an error.

 

If both positional and named arguments are specified in a single subroutine call then all the positional arguments must come before the named arguments. Then, using the same example as above:

 

fun( .s("yes"), 2 );            // illegal

fun( 2, .s("yes") );            // OK

Action Item 56

Write a proposal to have c++ like namescope to access members.

With the addition of the :: operator enables reference to both static data members and static members. With this new feature (defined in 11.20) it is now useful to include static methods (11.8.1).

Section 11.8.1

Add the following section after Section 11.8 as shown in red:

 

11.8.1 Static methods

 

Methods can be declared as static. A static method is subject to all the class scoping and access rules, but behaves like a regular subroutine that can be called outside the class, even with no class instantiation. A static method has no access to non-static members (properties or methods), but it may directly access static class properties or call static methods of the same class. Access to non-static members or to the special this handle within the body of a static method is illegal and results in a compiler error. Static methods cannot be virtual.

 

class id;

static int current = 0;

static function int next_id();

next_id = ++current;               // OK to access static class property

endfunction

endclass

 

A static method is different from a method with static lifetime. The former refers to the lifetime of the method within the class, while the latter refers to the lifetime of the arguments and variables within the task.

 

class TwoTasks;

static task foo(); ... endtask                  // static class method with automatic variable lifetime

task static bar(); ... endtask                  // non-static class method with static variable lifetime

endclass

Section 11.20

Add the following section between Section 11.19 and Section 11.20 (with this being the new Section 11.20) as shown in red:

 

11. 20 Class scope resolution operator ::

 

The class scope operator :: is used to specify an identifier defined within the scope of a class, and it has the following form:

 

scoped_expression ::= class_name :: {class_name :: } identifier

 

Identifiers on the left side of the scope-resolution operator (::) can be only class names.

 

Because classes and other scopes can have the same identifiers, the scope resolution operator uniquely identifies a member of a particular class. In addition to disambiguating class scope identifiers, the :: operator also allows access to static members (properties and methods) from outside the class, as well as access to public or protected elements of a super-classes from within the derived classes.

 

class Base;

typedef enum {bin,oct,dec,hex} radix;

static task print( radix r, integer n ); ... endtask

endclass

...

 

Base b = new;

int bin = 123;

b->print( Base::bin, bin );       // Base::bin and bin are different

Base::print( Base::hex, 66 );

 

In SystemVerilog the class scope operator applies to all static elements of a class: static class properties, static methods, typedefs, enumerations, struct, union, and nested class declarations. Class-scope resolved expressions can be read (in expressions), written (in assignments or subroutines calls) or triggered off (in event expressions). They can also be used as the name of a type or a method call.

 

Like modules, classes are scopes and can nest. Nesting allows hiding of local names and local allocation of resources. This is often desirable when a new type is needed as part of the implementation of a class. Declaring types within a class helps prevent name collisions, and cluttering the outer scope with symbols that are used only by that class. Type declarations nested inside a class scope are public and can be accessed outside the class.

 

class StringList;

class Node;             // Nested class for a node in a linked list.

string name;

Node link;

endclass

endclass

 

class StringTree;

class Node;             // Nested class for a node in a binary tree.

string name;

Node left, right;

endclass

endclass

 

// StringList::Node is different from StringTree::Node

 

The scope resolution operator enables:

 

_ Access to static public members (methods and properties) from outside the class hierarchy.

 

_ Access to public or protected class members of a super-class from within the derived classes.

 

_ Access to type declarations and enumeration labels declared inside the class from outside the class hierarchy or from within derived classes.

Action Item 70

Clarify order that semaphores and mailboxes do something

Section 12.2.3

Change as shown in red:

 

The semaphore waiting queue is First-In First-Out (FIFO). This does not guarantee the order in which processes will arrive at the queue, only that their arrival order will be preserved by the semaphore.

Section 12.4.5

Change as shown in red:

 

The mailbox waiting queue is FIFO. This does not guarantee the order in which processes will arrive at the queue, only that their arrival order will be preserved by the mailbox.

Action Item 73

Resolve Editor’s Note: Has the changed keyword been removed from SystemVerilog?

Section 13.3

Change as shown in red:

 

clocking dram @(changed clk);

input #1ps address;

input #5 output #6 data;

endclocking

 

Editor’s Note: Has the changed keyword been removed from SystemVerilog?

Action Item 73

Resolve Editor’s Note: Has the changed keyword been removed from SystemVerilog?

Section 13.4

Change as shown in red:

 

clocking mem @(changed clock);

input instruction = { opcode, regA, regB[3:1] };

endclocking

 

Editor’s Note: Has the changed keyword been removed from SystemVerilog?

Action Item 73/84

Resolve Editor’s Note: The addition in the preceding paragraph from EC-CH81 of a step being the “smallest global precision” is ambiguous. What if no global timeprecision was specified? Is the module’s precision used? Is the timescale precision used? What’s the precedence? I suspect what was intended is that “a step is an increment of 1 simulator time unit. The simulator time unit is defined in the Verilog 1364 standard”. [1364-2001 section 19.8 defines the simulator time as “The smallest time_precision argument of all the `timescale compiler directives in the design determines the precision of the time unit of the simulation.“. The PLI sections also refer to “simulator time unit” in several places, and refer to 19.8 for the definition of the simulator time unit”.

 

Note: The definition in the 1364 standard does not define a useable term, it describes what determines the “precision of the time unit of simulation”, but is incomplete since it does not account for the timeprecision and timeunit statements of SystemVerilog.

Section 2.2

Change as shown in red:

 

time_literal ::= // from Annex A.8.4

unsigned_number time_unit

| fixed_point_number time_unit

 

time_unit ::= s | ms | us | ns | ps | fs | step

Section 2.5

Change as shown in red:

 

Time is written in integer or fixed point format, followed without a space by a time unit (fs ps ns us ms s step).

Section 13.2

Change as shown in red:

 

Unless otherwise specified, the default input skew is 1step and the default output skew is 0. A step is a special time unit whose value is defined in Section 17.6. Like all other time units, step is not a keyword. A 1step input skew allows input signals to sample their steady-state values immediately before the clock event (i.e., at read-only-synchronize immediately before time advanced to the clock event). Unlike other time units, which represent physical units, a step cannot be used to set or modify the either the precision or the timeunit.

 

Editor’s Note: The addition in the preceding paragraph from EC-CH81 of a step being the “smallest global precision” is ambiguous. What if no global timeprecision was specified? Is the module’s precision used? Is the ‘timescale precision used? What’s the precedence. I suspect what was intended is that “a step is an increment of 1 simulator time unit. The simulator time unit is defined in the Verilog 1364 standard”. [1364-2001 section 19.8 defines the simulator time as “The smallest time_precision argument of all the `timescale compiler directives in the design determines the precision of the time unit of the simulation.“. The PLI sections also refer to “simulator time unit” in several places, and refer to 19.8 for the definition of the simulator time unit”.

 

Section 17.6

Add the following as a new paragraph at the end of the section as shown in red:

 

The timeunit and timeprecision keywords shall precede any other item in the top level, module, or interface, because the other items can contain delays and therefore can be dependent on the time unit.

 

The global time precision is the minimum of all the timeprecision statements and the smallest time precision argument of all the `timescale compiler directives (known as the precision of the time unit of the simulation in Section 19.8 of the IEEE 1364-2001 standard) in the design. The step time unit is equal to the global time precision.

Annex A.8.4

Change as shown in red:

 

time_unit ::= s | ms | us | ns | ps | fs | step

 

Action Item 80

For syntax of disabling constraints and random variables constraint methods, or system task take a look at this in more detail.

Section 20.15

Change as shown in red:

 

 

20.15 Disabling random variables

 

The rand_mode() method can be used to control whether a random variable is active or inactive. When a random variable is inactive, it is treated the same as if it had not been declared rand or randc.  Inactive variables are not randomized by the randomize() method, and their values are treated as state variables by the solver.  All random variables are initially active.

 

20.15.1 rand_mode()

 

The syntax for the rand_mode() method is:

 

task object[.random_variable]::rand_mode( bit on_off );

 

or

 

function int object.random_variable::rand_mode();

 

object is any expression that yields the object handle in which the random variable is defined.

 

random_variable is the name of the random variable to which the operation is applied.  If it is not specified (only allowed when called as a task), the action is applied to all random variables within the specified object.

 

When called as a task, the argument to the rand_mode method determines the operation to be performed:

 

Table 20-1: rand_mode first argument

 

Value

Meaning

Description

0

OFF

Sets the specified variables to inactive so that they are not randomized on subsequent calls to the randomize() method.

1

ON

Sets the specified variables to active so that they are randomized on subsequent calls to the randomize() method.

 

For array variables, random_variable can specify individual elements using the corresponding index. Omitting the index results in all the elements of the array being affected by the call.

 

If the random_variable is an object handle, only the mode of the variable is changed, not the mode of random variables within that object (see Global Constraints in Section 20.11).

 

A compiler error is issued if the specified variable does not exist within the class hierarchy or it exists but is not declared as rand or randc.

 

When called as a function, rand_mode() returns the current active state of the specified random variable. It returns 1 if the variable is active (ON), and 0 if the variable is inactive (OFF).

 

The function form of rand_mode() only accepts singular variables, thus, if the specified variable is an array, a single element must be selected via its index.

 

Example:

 

class Packet;

rand integer source_value, dest_value;

... other declarations

endclass

 

int ret;

Packet packet_a = new;

// Turn off all variables in object.

packet_a.rand_mode(0);

 

// ... other code

// Enable source_value.

packet_a.source_value.rand_mode(1);

 

ret = packet_a.dest_value.rand_mode();

 

This example first disables all random variables in the object packet_a, and then enables only the source_value variable.  Finally, it sets the ret variable to the active status of variable dest_value.

 

The rand_mode() method is built-in and cannot be overridden.

Section 20.16

Change as shown in red:

 

20.16 Disabling constraints

 

The constaint_mode() method can be used to control whether a constraint is active or inactive.  When a constraint is inactive, it is not considered by the randomize() method.  All constraints are initially active.

 

20.16.1 constraint_mode()

 

The syntax for the constraint_mode() method is:

 

task object[.constraint_name]::constraint_mode( bit on_off );

 

or

 

function int object.constraint_name::constraint_mode();

 

object is any expression that yields the object handle in which the constraint is defined.

 

constraint_name is the name of the constraint block to which the operation is applied. The constraint name can be the name of any constraint block in the class hierarchy.  If no constraint name is specified (only allowed when called as a task), the operation is applied to all constraints within the specified object.

 

When called as a task, the argument to the constraint_mode method determines the operation to be performed:

 

Table 20-2: constraint_mode first argument

 

Value

Meaning

Description

0

OFF

Sets the specified constraint block to active so that it is considered      by subsequent calls to the randomize() method.

1

ON

Sets the specified constraint block to inactive so that it is not

enforced on subsequent calls to the randomize() method.

 

A compiler error is issued if the specified constraint block does not exist within the class hierarchy.

 

When called as a function, constraint_mode() returns the current active state of the specified constraint block.  It returns 1 if the constraint is active (ON), and 0 if the constraint is inactive (OFF).

 

Example:

 

class Packet;

rand integer source_value;

constraint filter1 { source_value > 2 * m; }

endclass

 

function integer toggle_rand( Packet p );

if( p.filter1.constraint_mode() )

p.filter1.constraint_mode(0);

else

p.filter1.constraint_mode(1);

 

toggle_rand = p.randomize();

endfunction

 

In this example, the toggle_rand function first checks the current active state of the constraint filter1 in the specified Packet object p. If the constraint is active then the function will deactivate it; if it’s inactive the function will activate it.  Finally, the function calls the randomize method to generate a new random value for variable source_value.

 

The constraint_mode() method is built-in and cannot be overridden.