VHDL PLI IR number: 02 Classification: Simulation modification of values VHDL PLI version: 0.1 Title: Scheduling updates for drivers of a signal Summary: PLI support for signal assignments through drivers with zero and non-zero delays, follow rules of inertial and transport preemption. Ability to access current and future output waveform for a given driver. Ability to cancel a PLI scheduled transaction. Related IRs: 01, 03 Requestor Priority: Assigned Priority: Current Status: Approved Date Submitted: 05/12/97 Key Words: simulation cycle, signal, driver, delay Related sections in the LRM: 8.4 Author of Submission: Vish Raman Author's Affiliation: Synopsys Author's Phone Number: (650) 691-6421 Author's Net Address: vishwa@synopsys.com Secondary Authors: Rajesh Pavaskar, Francoise Martinolle Description of the Problem -------------------------- PLI functionality to schedule values for drivers for the next simulation cycle or for future time, and the ability to access current and future driving values of drivers, ability to cancel transactions that were scheduled by PLI. Rationale --------- Users of the PLI need the ability to schedule updates on drivers of a signal for the next simulation cycle or for future time. As opposed to the immediate update of signal values (please refer to IR01), values are scheduled on the driver of the signal. The behavior of scheduling values is the same as performing VHDL signal assignments. Scheduling values on drivers is required because resolved signals can have multiple drivers and unresolved signals can have at most one driver. Therefore it becomes necessary that the users of the PLI take responsibility to access the driver that is to be used for scheduling values (please refer to IR03 on accessing drivers). In the rest of this document, the phrase "scheduling updates" is to be construed as scheduling values on one or more drivers of the signal. To schedule a value on the driver requires the specification of a value, a delay and an optional delay mode. The delay modes that should be supported are inertial and transport. In the case of inertial delays, a user could specify an additional optional parameter, the pulse rejection limit. Analysis -------- Scheduling updates can happen only during the process execution phase. All updates with zero delay will be scheduled for the next delta cycle in the current simulation time and all larger than zero delay updates would result in updates to the future waveform of the drivers. The delay mode can be inertial or transport. Updates could be overwritten with future waveform additions/edits. A pulse rejection limit could be specified with an inertial delay mode, which is used during waveform edits, in order to remove all transitions that occur within the time specified by the rejection limit (LRM section 8.4). On scheduling updates, users can request the return of transaction handle. This transaction handle can be used to query the value on the transaction, determine whether or not the transaction has matured, and also remove the transaction if it has not matured. Scheduling updates is valid only on a driver and not on a signal. Users should obtain a driver handle (for drivers created normally during elaboration) before they can schedule an update. Creation of drivers through PLI should be provided to increase foreign models capabilities (see vhpi_create()). Creation of bundle of drivers is an advanced capability which may be provided in the future (vhpi_create()) to help scheduling transactions on composite unresolved types, arrays etc... The PLI should provide a mechanism to access the drivers of a signal (if any) that have been created during elaboration. If the signal does not have a driver, then users cannot schedule an update to that signal. For the mechanisms to access drivers, please refer to IR03. There is a mechanism to force the effective value of a signal (IR01). Within postponed processes the PLI will permit the scheduling of non-zero delay driver updates alone. It would be an error to try to schedule any zero delay updates. Proposed Solution ----------------- As discussed in the last sections, updates can be scheduled during process execution. The PLI function to update a driver will accept, 1. A handle to the driver on which a transaction has to be scheduled or a handle to the transaction if the transaction has to be removed 2. A value pointer (could be one (scalar driver) or more values structures (driver of a composite resolved at the composite level) 3. The number of values provided 4. A delay, which could be zero or more 5. A delay mode, either inertial or transport 6. A pulse rejection limit in the case of inertial delays or NULL 7. Flag bit for specifying to return a transaction handle or to cancel the given transaction. There could be sets of values that users can specify to define a waveform. NULL transactions can be posted by passing a NULL value parameter. VHPI only schedules a transaction value and cannot specify an entire waveform. Function prototype: vhpiHandleT vhpi_schedule_transaction(vhpiHandleT driver/transaction, vhpiValueT *array_value_p, int num_of_values, vhpiTimeT *time delay, int delay_mode, vhpiTimeT *pulse_rej, int flag) flag - if set to vhpiReturnHdl, vhpi_schedule_transaction will return a handle to the scheduled transaction otherwise will return NULL. - if set to vhpiCancelTransaction, vhpi_schedule_transaction will deschedule the transaction if the transaction has not matured. vhpi_schedule_transaction shall be used to schedule driver transactions. A driver can either be: 1. a scalar driver, 2. a composite driver for signals resolved at the composite level, 3. (not supported in the first version of the PLI): a bundle of drivers for only standard predefined logic types of signals such as std_logic vectors, bit_vectors, where a single value structure can describe the value (vector union field). (since we allow to get the value of these standard array types, we should also allow to schedule a value). In the next version of the PLI, vhpi_create (see below) will be enhanced to support the creation of bundle of drivers. Scheduling transaction for composite signals tha do not fall in categories 2 or 3, must be done by scheduling individual transactions on each of the sub-elements; Iteration on vhpiSelectedNames (to access the fields of a record type signal) or iteration on vhpiIndexedNames (to access each index of an array type signal) can be used to get handles to the sub-element basic signals and from there, to access a handle to the sub-signal associated driver. The format of the specified value must be appropriate with the VHDL type of the driver. For example, if the driver type is a record, the format cannot be vhpiIntVal. The table at the end of the IR (TBD) specifies the allowed format type for each VHDL basic type. Runtime type errors shall occur if the provided value is not within the range of the driver subtype. The execution of a vhpi_schedule_transaction involves runtime constraint type checking. For the driver type case 2: scheduling transactions for a driver of a record type signal or an array type signal (which does not belong to one of the basic array types) and which is resolved at the composite level is an advanced PLI capability. The scheduling needs to assign the entire value at once; the user is responsible to allocate as many as value structures that are necessary for scheduling a transaction on the composite. He should allocate an array of value structures and specify the format in each one. The number of value structures that are passed to vhpi_schedule_transaction is indicated by the 3rd argument. The format and corresponding union value field of each value structure of the array must be set by the user. The space for holding each individual value (value union field of each individual vhpiValueS structure) must be allocated by the user in accordance with the chosen format. In general there will not be any VHPI check that all values have been actually allocated and set but the simulator may issue an error for case 2 if the composite driver is not assigned as a whole. There will be a check that the specified format is allowed. The array of values follows the order defined by the LRM for array or record Aggregates. Then the values properly set are passed to the function vhpi_schedule_transaction. The specified delay is a relative delay and uses the existing time structure: vhpiTimeS by either: . providing a 64 bits value when the type is set to vhpiInt low, high fields and time unit field set . providing a double value when the type is set to vhpiReal, the real field and time unit fiel set. The vhpiAuto value for the type field is not allowed for passing time values to vhpi_schedule_transaction. delay_mode is either vhpiInertial or vhpiTransport. The delay is specified as relative to current simulation time. Delay value is truncated if smaller than the VHDL simulator resolution limit. The delay value must be legal as if it were the delay value of a VHDL signal assignment. Zero delay transactions are specified by setting the low and high fields to 0 or the real field to 0.0 All zero delay updates will be scheduled for the next delta cycle and all other delayed updates will be scheduled for the time that corresponds to the current simulation time added to the relative delay. Users are responsible for requesting the release of the memory created for a transaction handle when it is no longer needed. Errors (not exhaustive list) ------ 1. A negative relative delay or a simulation time that is before the current simulation time. 2. The value given is not compatible with the signal subtype. 3. The driver handle used to schedule an update is NULL. 4. The pulse rejection limit is greater than the inertial delay. 5. To schedule any zero delay updates within postponed processes. 6. The handle passed in does not denote a driver. 7. The flag is set to vhiCancelTransaction, but the handle provided does not denote a transaction handle.. Creation of drivers through the PLI The PLI provides mechanisms to create drivers of signals. A function is provided which takes a basicSignal and a process handles and returns a driver handle. vhpiHandle vhpi_create(int kind, vhpiHandleT basicSignalHdl, vhpiHandleT processHdl); - kind would be set to vhpiDriverK The function would return the driver associated with the basic signal and process. This function is to be used in foreign models to create VHPI drivers. This function is only allowed to be called at elaboration time. The same function is used to create VHPI processes for a foreign architecture. vhpiHandle vhpi_create(vhpiProcessK, archBodyHdl, NULL) - kind set to vhpiProcessK, - second parameter is a handle to the architecture body which must be a foreign architecture, - third parameter is NULL; returns a handle to a VHPI created process. This handle is then used to create VHPI drivers for that process. No difference is made between a VHPI created driver or process, and a VHDL driver or process. Recommendation -------------- We should always expect a user to provide a handle to a driver in order to schedule updates. These updates cannot be done with signal handles. Please refer to IR03 for more information on this. Recommendation for Future Revisions of Standard Creation of bundles of drivers through the PLI Special handling or differences with VHDL'87 -------------------------------------------- A simulator that is only VHDL'87 compliant will ignore the pulse rejection limit if provided by the PLI call. The PLI should warn the application, that this pulse time expression is being ignored. Table of formats ---------------------------------------------------------------------------- | TYPE FORMAT SUB-FORMAT FIELDS ---------------------------------------------------------------------------- - | vhpiIntTypeDecl vhpiIntVal - integer | size = 1 ----------------------------------------------------------------------------- | vhpiEnumTypeDecl vhpiIntVal - integer | additional formats size = 1 | can be used: | if base type CHAR vhpiCharVal - character size = 1 | if base type STD_LOGIC vhpiLogicVal - logic | BIT size = 1 | MVL7 ---------------------------------------------------------------------------- ---- | vhpiPhysTypeDecl vhpiPhysVal - phys,type,unit | low,high or real | if base type is TIME vhpiTimeVal - time,type,unit, | low,high or real | ---------------------------------------------------------------------------- ---- | vhpiAccessTypeDecl vhpiPtrVal - integer | size = 1 ---------------------------------------------------------------------------- ---- | vhpiArrayTypeDecl | | (1 dimension) vhpiVectorVal vector | of scalar or access of scalar types size =#elemValues | Depending on elemsubtype the subformat and elemValue fields are set according | to the previous rows of the table | ex: vhpiIntegerTypeDecl vhpiIntVal integer | | (multi-dimensions) vhpiVectorVal? size =#elemValues | (of arrays) needs to iterate on indexedNames | (of records} needs to iterate in indexedNames ---------------------------------------------------------------------------- ---- | vhpiRecordTypeDecl need to iterate on selectedNames | ---------------------------------------------------------------------------- ---- VHPI data structures --------------------- Below are the defined structures to represent values. This is extracted from the vhpi_get_value proposal. /* time value */ typedef struct vhpiTimeS { int type; /* vhpi{Real,Int,Auto] */ int unit; /* vhpiFS, vhpiPS, vhpiNS, vhpiUS, vhpiMS, vhpiS, vhpiMN, vhpiHR */ union { struct t_time { unsigned int high; unsigned int low; /* for vhpiInt or vhpiAuto */ } time; double real; /* for vhpiReal */ } utime; } vhpiTimeT; /* vector value */ typedef struct vhpiVecvalS { /* following fields are repeated enough times to contain vector */ union { char character; /* character value */ char logic; /* IEEE std logic */ int integer; /* integer or enumeration value */ double real; /* real value */ struct vhpiPhysS *phys; /* physical value */ struct vhpiTimeS *time; /* time value */ }elemValue; } vhpiVecvalT; /* value structure */ typedef struct vhpiValueS { int format; /* vhpi[[Bin,Oct,Dec,Hex]Str,Logic,Int,Real,Phys, Char, String,Vector, Ptr,Deref,Time,ObjType]Val */ int subFormat; /* vhpi[Logic,Int,Real,Phys,Time,Ptr]Val only for vectors or access types */ int size; /* different meanings depending on the format: vhpiStringVal, vhpi(Bin...}StrVal size of the string for array type values: the number of the array elements for record type values: the number of record fields */ /* size is 1 for vhpi[Int,Real,Logic,Char, Phys,Time,Ptr,Deref]Val formats */ union { char *str; /* string value */ char character; /* character value */ char logic; /* vhpi[U,X,0,1,Z, W,L,H, -] */ int integer; /* integer value */ double real; /* real value */ struct vhpiPhysS *phys; /* physical value */ struct vhpiTimeS *time; /* time value */ struct vhpiVecvalS *vector; /* vector value */ char *misc; /* ...other */ } value; }vhpiValueT; REMAINING ISSUES: (POSTPONED TO NEXT VHPI VERSION) 1. Definition of what is a bundle of drivers 2. how to create bundles