IEEE 200X Fast Track Change Proposal ID: FT-07 Proposer: Steve Bailey (stephen@srbailey.com) Status: Open Proposed: 1-Jan-2003 Analyzed: 04-April-2005, 27-Jan-2004 Resolved: Date Revisions: Analysis #2 4-April-2005 Revised to follow package based approach Rev 4-April-2005-2 Revised format for value used by get_value and force to be more compatible with new textio Enhancement Summary: Standard Signal Spy / XMR capability (package/procedural based) Related issues: Relevant LRM section: =============================================================================== Enhancement Detail: -------------------- Based on either the packages from EDA Vendors. Would need to request donation. Request: Compatible with both VCD or VHDL Instance Paths Request: Allow relative paths and ".." to be embedded in the string Proposal 1: Signal Spy MTI Signal Spy contains: init_signal_driver(src, dest, delay, delay_type, verbose) ; init_signal_spy(src_object, dest_object, verbose) ; signal_force( dest, value, rel_time, force_type, cancel_period, verbose ) ; signal_release( dest_object, verbose ) ; -- Missing get_value function? -- difficult to provide a good general purpose routine as -- what should the return value be ?String? Get_Value( dest, verbose) ; -- function that returns value Proposal 2: Aliases -- Some issues, perhaps read only would scope this? Alias A : std_logic is ":tb:uut:b:d:a_sig" ; Alias B : std_logic is ":tb:uut:b:" & "d:C_sig" ; Alias C : std_logic is MY_GENERIC & "d:C_sig" ; Proposal 3: Associate with signal direction signal A : std_logic probe(. . .) ; signal B : integer drive(. . . ) := 5 ; ============================================================================= Analysis #1 Overview -- See Analysis #2 -------------- [Editors Note: The portion of this proposal for aliases was rejected due to complexity and timing of fast track - it may be reconsidered at a later date if necessary] There are a number of requirements implied and covered by the Mentor SignalSpy and Cadence NC Mirror capabilities. There are also requirements which assertion-based verification (the planned incorporation of PSL as VHDL's property specification capability) bring to the table as well. The enumerated requirements are: ------- 1. The ability to read the current value of a signal somewhere in the design hierarchy from a location that does not have visibility of that signal name according to VHDL-2002 scope and visibility rules. Examples: Within a testbench, it may be important to verify that an internal register has a proper state during the course of verification. In PSL, a property may be specified that relates signals scattered throughout the design hierarchy. For example, a transaction event at one level may imply a sequence of events at a lower level. Signals that reflect each event(s) from one level would not be visible to the other level. ------- 2. The ability to change the current value of (force) a signal somewhere in the design hierarchy. Examples: Within a testbench, it may be desirable to force a fault to ensure the design recovers from it. Within a testbench, it may be desirable to "seed" a specific known state that is difficult to reach via only primary inputs in order to cover certain types of tests. ------- 3. The ability to release a forced signal. Once you have the ability to force a signal to a value, a method for releasing the forced value so the signal can return to its normal value updating is required. ------- 4. The ability to create a driver for a signal somewhere in the design hierarchy. Example: In order to force a fault and properly detect the design's ability to recover from it, it may be important that the erroneouse signal value actually initiate activity. One form of fault is the creation of unknown values on a bus. One way to do this is to create another set of drivers for the bus. The testbench can mimic a device connected to a system bus that is not part of the design. But, that device's behavior on the bus is relevant to verification of the device. Analysis #1 Approach: The proposed resolution is to use the existing alias capability to satisfy requirements 1 (probing) and 4 (driving) and to provide utility routine located in a standard package that will satisfy requirements 2 (forcing a signal) and 3 (releasing a forced signal). Why not a procedural resolution for requirements 1 and 4? Primarily, the problem with this approach is that it is more cumbersome to use than the alternative. Both donations have similar approaches: 1. Declare a local signal that is to mirror or spy on another signal. 2. Call a routine to create the mirror/spy association between the local signal and some source signal somewhere in the design. 3. Ensure the call is a concurrent call so it creates the relationship only once. This is contrasted to the alias approach which simply requires the alias declaration and can take full advantange of the existing alias capabilities of aliasing a slice or subelement of a composite to a simple (local) name. This approach can also work with non-signal objects and non-objects as well. However, the desirability of extending this capability beyond object aliases is questionable. Specifically, it should not be extended to non-object aliases (types, functions, procedures, etc.) which should be declared in packages if they are to be used in multiple scopes. An alias designator denotes the object aliased. Therefore, the alias designator can be used to reference the object value or to assign to the object. Since it is important to know whether the hierarchically aliased object is a signal, variable or constant, the alias declaration syntax requires modification to allow the specification of this information. (Otherwise, the compiler won't know if a signal or variable assignment is appropriate.) Also, the alias declaration requirements for a hierarchically aliased object mandates a subtype_indication. This information is imperative for run-time checks and which operations are legal and defined. For non-hierarchically aliased objects, this information is easily accessible as the object being aliased is visible. To make it easier to manage changes in the design hierarchy, it should be possible to specify a string for the hierarchical name of the object being aliased. This will allow the concatenation of string generics and/or constants to construct the hierarchical path. Use of generics and constants provides a mechanism by which impacts to hierarchical names due to changes in the design hierarchy can be localized. Hierarchical references can significantly impact the ability of tools to apply optimizations. Also, the types of optimizations that remain possible depend on whether the aliased object is read, written or both. Therefore, a mechanism to provide use intent would help ensure the easiest application of optimizations at a minimal burden to the user. A procedural resolution for the signal forcing and releasing capabilities is required as the language defines no such capabilities for signals today. Analysis #1 SUGGESTED LANGUAGE CHANGES: 4.3.3 Alias declarations alias_declaration ::= *alias* alias_designator [ : subtype_indication ] [ entity_class ] *is* alias_reference ; alias_reference ::= name_and_signature | hierarchical_reference name_and_signature ::= name [ signature ] hierarchical_reference ::= [ mode ] *string*_expression (Note: Annex A Syntax summary must also be updated.) 4.3.3.1 Object aliases ... e) If an entity class is specified, it must be one of signal, shared variable, constant or signal. 4.3.3.1.1 Hierarchical object aliases A hierarchical alias declaration creates a local name for any object in the design whether or not that object is visible in the current scope. A hierarchical object alias is denoted by the presence of a hierarchical reference in place of a name as the alias reference. In addition to the rules for object aliases, the following rules apply to hierarchical object aliases: a) The subtype indication must be specified. b) The entity class (see 5.1) must be specified and must be one of: signal, shared variable or constant. d) The mode must be specified and the mode must be one of *in*, *out* or *inout*. e) A mode of *in* indicates that the alias reference will only be read (see 4.3.2) via the alias designator. It is an error if the alias designator is used to assign to the object denoted by the alias reference. f) A mode of *out* indicates that the alias reference will only be updated (see 4.3.2) via the alias designator. It is an error if the alias designator is used to read the object denoted by the alias reference. g) A mode of *inout* permits assignment and reading via the alias designator of the object denoted by the alias reference. h) It is an error if the object denoted by the alias reference does not exist after the design has been elaborated (see 12.1). i) It is an error if the object denoted by the alias reference is not of the specified entity class. j) It is an error if the mode specifies access inconsistent with the class or mode of the alias reference. The string expression denoted in the alias reference is a string structured according to the following syntactic grammar and semantic description for a hierarchical name: hierarchical_name ::= absolute_instance_based_path | relative_instance_based_path absolute_instance_based_path ::= leader entity_name leader full_instance_path hier_name relative_instance_based_path ::= { up_scope leader } full_instance_path hier_name full_instance_path ::= { instance_path leader } instance_path ::= *component_instantiation*_label | *block*_label | generate_label | process_label hier_name ::= simple_name | selected_name | indexed_name | slice_name up_scope ::= .. (NOTE: leader is defined in clause 14 ('instance_name attribute) and simple_name, selected_name, indexed_name and slice_name are defined in clause 6.) An absolute hierarchical name starts with the leader character (:) followed by the name of the entity that is the root of the design hierarchy followed by another leader character followed by the instance path. A relative hierarchical name starts at the current instance scope. Navigation down the hierarchy is performed by using the appropriate label. Navigation up the hierarchy is indicated by the up scope symbol (..). Each up scope symbol represents one level up the hierarchy. Consecutive up scope symbols are separated using the same leader character (:) used to separate labels in the instance path. The named entity identified by the hierarchical name must be an object of signal, constant or shared variable entity class. The name can be a simple name, selected name (e.g., a record element), indexed name (e.g., element of an array) or slice name (e.g., consecutive elements of an array). NOTES A hierarchical object alias cannot violate the read/update access of the alias reference. For example, the hierarchical object alias cannot specify a mode of INOUT or OUT (write/assign access) to an alias reference that denotes a constant or generic or an IN mode port. 4.3.3.2 Nonobject aliases The following rules apply to nonobject aliases: ... f) The entity class, if specified, must not be label or an object entity class (signal, variable, constant or file). 14.4 Package Utils (new section) (NOTE: The subprograms documented here should be combined with any other subprograms to be added to a general utility package.) package UTILS is type force_mode is ( DEPOSIT, -- Changes the effective value until next signal update or forced again DRIVE, -- Attaches a driver and drives the value until forced again or released -- The signal being forced with DRIVE must be resolved. FREEZE); -- Changes the effective value and holds it until forced again or released -- The format of the destination_signal string parameter in signal_force and -- signal_release is as defined for hierarchical_string in 4.3.3.1.1 Hierarchical -- object aliases. -- force_value is a string value that complies with the syntax for a literal -- of the type of the object being forced. For example: -- Integer = "1234" -- Real = "12.34" -- std_logic = "'1'" -- std_logic_vector = "X\"DEADBEEF\"" -- string = "\"A String\"" -- Some record = "(1234, 12.34, '1', X\"DEADBEEF\")" -- -- Note: A 0 time delay results in the forced value applying immediately but does -- not activate processes (no event is created) unless delta_event is true. -- delta_event is ignored unless force_delay is 0. procedure signal_force ( destination_signal : IN STRING; force_value : IN STRING; force_delay : IN TIME := 0 ps; force_how : IN force_mode := DEPOSIT; cancel_period : IN TIME := -1 ps; delta_event : IN BOOLEAN := FALSE ); -- Releases a signal from previous force. Signal update proceeds normally. procedure signal_release ( destination_signal : IN STRING ); end package UTILS; =============================================================================== Analysis #2 Overview -- Procedure based approach -------------------- There are a number of requirements implied and covered by the Mentor SignalSpy and Cadence NC Mirror capabilities. There are also requirements which assertion-based verification (the planned incorporation of PSL as VHDL's property specification capability) bring to the table as well. The enumerated requirements are: ------- 1. The ability to read the current value of a signal somewhere in the design hierarchy from a location that does not have visibility of that signal name according to VHDL-2002 scope and visibility rules. Examples: Within a testbench, it may be important to verify that an internal register has a proper state during the course of verification. In PSL, a property may be specified that relates signals scattered throughout the design hierarchy. For example, a transaction event at one level may imply a sequence of events at a lower level. Signals that reflect each event(s) from one level would not be visible to the other level. ------- 2. The ability to change the current value of (force) a signal somewhere in the design hierarchy. Examples: Within a testbench, it may be desirable to force a fault to ensure the design recovers from it. Within a testbench, it may be desirable to "seed" a specific known state that is difficult to reach via only primary inputs in order to cover certain types of tests. ------- 3. The ability to release a forced signal. Once you have the ability to force a signal to a value, a method for releasing the forced value so the signal can return to its normal value updating is required. ------- 4. The ability to create a driver for a signal somewhere in the design hierarchy. Example: In order to force a fault and properly detect the design's ability to recover from it, it may be important that the erroneouse signal value actually initiate activity. One form of fault is the creation of unknown values on a bus. One way to do this is to create another set of drivers for the bus. The testbench can mimic a device connected to a system bus that is not part of the design. But, that device's behavior on the bus is relevant to verification of the device. Analysis #2 Language Changes ---------------------------- It was decided that for the time frame VHDL-200X Fast Track the use of alias required too many fundamental language changes (when alias is elaborated vs. when lower level designs are elaborated and hence signals available for selection). This approach will be entirely procedural. The following procedures and/or functions will meet the requirements of the overview: 1: probe -- attach to signal for reading 2: drive -- attach to signal for driving 3: get_value -- return current value of a signal as a string 4: force -- deposit a value onto a signal 5: release -- stop driving a previously deposited -- value of a signal if it was driven in a -- persistant manner Analysis #2 Language Changes Clause 14.XX Hierarchical Name The hierachical name used by the probe, drive, get_value, force, and release subprograms is a string structured according to the following syntactic grammar and semantic description: hierarchical_name ::= absolute_instance_based_path | relative_instance_based_path absolute_instance_based_path ::= leader entity_name leader full_instance_path hier_name relative_instance_based_path ::= { up_scope leader } full_instance_path hier_name full_instance_path ::= { instance_path leader } instance_path ::= *component_instantiation*_label | *block*_label | generate_label | process_label hier_name ::= simple_name | selected_name | indexed_name | slice_name up_scope ::= .. (NOTE: leader is defined in clause 14 ('instance_name attribute) and simple_name, selected_name, indexed_name and slice_name are defined in clause 6.) An absolute hierarchical name starts with the leader character (:) followed by the name of the entity that is the root of the design hierarchy followed by another leader character followed by the instance path. A relative hierarchical name starts at the current instance scope. Navigation down the hierarchy is performed by using the appropriate label. Navigation up the hierarchy is indicated by the up scope symbol (..). Each up scope symbol represents one level up the hierarchy. Consecutive up scope symbols are separated using the same leader character (:) used to separate labels in the instance path. The named entity identified by the hierarchical name must be an object of signal class. The name can be a simple name, selected name (e.g., a record element), indexed name (e.g., element of an array) or slice name (e.g., consecutive elements of an array). 14.XX Additions to package standard (NOTE: The subprograms documented here should be merged into the package standard.) package proposed_addition_standard is -- The format for the observer, source and target string -- parameters used by the subprograms probe, drive, -- get_value, force, and release -- is as defined for hierarchical string in 14.XX. -- -- Probe -- Connect the signal observer to the signal source in -- a read-only fashion -- procedure probe( observer : in string ; source : in string ; verbose : in boolean := false ) ; type force_mode_type is ( DEFAULT, -- DRIVE if object is resolved; FREEZE if unresolved DRIVE, -- Attaches a driver and drives the value until forced again or released -- The signal being forced with DRIVE must be resolved. FREEZE, -- Attaches a driver to the target signal and disconnects any other -- driver until it is cancelled with a call to subprogram release DEPOSIT -- Changes the effective value until next signal update or forced again -- No driver is created ); -- Note: Force_mode_type DEPOSIT will cancel any drivers previously created by -- this process and re-attach any driver that was disconnected by -- force_mode_type FREEZE. subtype drive_force_mode_type is force_mode_type range DEFAULT to FREEZE ; -- -- Drive -- Connect the source signal to the target signal for driving -- The force_mode parameter specifies how to handle multiple drivers -- on the target signal. -- procedure drive ( source : in string ; target : in string ; force_mode : in drive_force_mode_type := DEFAULT ; verbose : in boolean := false ) ; -- Note: If the source value is read, the value returned will be -- the value driven on source and not the resolved value on target -- value of procedure force and the string return value of -- get_value is a string value that complies -- with the syntax for a literal of the type of the object -- being forced. For example: -- Integer = "1234" -- Real = "12.34" -- std_logic = "'1'" -- std_logic_vector = "\"11011110101011011011111011101111\"" -- The '\' is not in the string -- string = "A String" -- Some record = "(1234, 12.34, '1', \"11011110101011011011111011101111\")" -- -- get_value -- Retrieve the current value of a source signal as a string -- function get_value( source : in string ; verbose : in boolean := false ) return string ; type delay_mode_type is ( TRANSPORT_DELAY, -- Changes the effective value until next signal update or forced again INERTIAL_DELAY -- Attaches a driver and drives the value until forced again or released ); -- -- force -- Drive a value to a target signal -- procedure force ( target : in string ; value : in string ; delay : in time := 0 ns ; delay_mode : in delay_mode_type := TRANSPORT_DELAY ; force_mode : in force_mode_type := DEFAULT ; cancel_period : in time := -1 ps ; -- negative means don't cancel verbose : in boolean := false ); -- -- Release -- Remove a driver created by this process for the target signal. -- Re-attach any driver that was disconnected by force_mode_type FREEZE. -- Signal update proceeds normally. -- If keep_value is true, keep the current value on target until the -- value is updated due to the next signal update or it is forced again -- If keep_value is false, update target to reflect its current drivers -- procedure release ( target : in string ; keep_value : in boolean := false ; verbose : in boolean := false ) ; end package proposed_addition_standard ; NOTES 1) A hierachical reference effected by the subprograms drive, force, and release subprograms cannot violate the read/update access of the referenced object. For example, an object of mode IN cannot be driven. 2) As a result of a hierarchical reference effected by the subprograms drive and force, a non-resolved signal cannot have multiple drivers on it. Examples: . . . To be Documented: ------------------------------------------------------------- 1) Value for force and get_value need to be cleaned up 2) Align terminology and definitions with VHPI 3) Decide whether Probe and Drive need a delta cycle. Vendors seem to support delta cycle (cyclic problems). signal A, B, C : std_logic ; . . . probe("A", "C") ; -- Interesting if sees the value of C immediately B <= A ; C <= B ; Some users prefer no delta cycle (attaching to clocks & seeing 'event at the right time). It is possible that the relevant clock is an internally generated clock. 4) Does force need a parameter for delta_event (from Analysis #1)? Relevant text from Analysis #1: -- Note: A 0 time delay results in the forced value applying immediately but does -- not activate processes (no event is created) unless delta_event is true. -- delta_event is ignored unless force_delay is 0. 5) return value from get_value needs to be (1 to length) 6) Implicitly defined force and get_value for every type? Hence get type safety and not require converting everything to string. 7) How does multiple Drive w/ freeze from separate processes work? Is it allowed or not? 8) Long term would like path names to go through VHDL & Verilog boundries. Nice to have, but is this necessary now? Recommendation: ---------------------------- Adopt Analysis #2 for VHDL-200X Fast Track Resolution: ---------------------------- [To be performed by the 200X Fast Track Working Group]