2.9 Variables of Condition 25 exceed some high-water mark so that the queue can be emptied more quickly and thereby prevent overflow. The prior example of a PCI-Express link width might also be considered to be an indirect condition. Such a condition could be classified either way as convenient for the verification software. Finally, it is practical to consider not only those conditions that govern the operation of the target but also those that govern the operation of its external context. Considering both the internal conditions and the external conditions relevant to the target are necessary to ensure that the target is thoroughly exercised. For example, a target residing on a shared bus might behave differently depending on the conditions established in the external bus arbiter that de- termine priorities for granting access. Similarly, as a consequence of activ- ity on this shared bus, the arbiter itself might enter an indirect condition such that priority for access to the bus is temporarily changed to favor some other bus-resident agent that is temporarily starved for bus band- width. To ensure that a target responds as expected to all defined stimuli, it should be exercised with a carefully chosen subset (or perhaps all) of the combinations of defined conditions, both internal and external. Choosing the values of the internal conditional variables determines the operation of an instance within its context. The process of establishing the initial operational conditions is called initialization. 2.9.1 Example – Conditions Consider the operation of the processor IP from our previous examples. (see Fig. 2.5) It is designed to be flexible in its attachment to the system bus, having either 32 bits or 64 bits for address and data. It can also be set up to operate in big-endian or little-endian mode. An internal prefetch con- troller can be enabled or disabled under control of a software-writable bit. Finally, the store queue has a software-adjustable high-water mark that de- termines whether priority should be given to draining the queue or not. 26 Chapter 2 – Analytical Foundation Fig. 2.5. External and Internal Conditions These variables of condition can be expressed in e as follows: <’ struct ext_condition_vars { bus_width: int; keep bus_width in [32, 64]; } struct int_condition_vars { prefetch_enable: [OFF, ON]; bus_endianess: [BIG, LITTLE]; store_queue_priority: [NORMAL, DRAIN]; } ‘> The value for the prefetch enable bit would be established typically during initialization via firmware, but might also be changed during post-silicon verification or other diagnostic testing. This is an example of a direct inter- nal condition. 2.10 Morphs 27 The endianess of the bus might be programmed by firmware or perhaps by sensing the value of an external pin. Similarly, the bus width might be detected automatically by the bus interface (as is done during PCI-Express link training). As mentioned earlier in this chapter, these variables might instead be considered as variables of external connectivity if external jumpers are present (or absent) to determine the values. The value for store queue priority cannot be set by software. The queue controller determines priority for this queue automatically. When the num- ber of entries in the queue reaches the high-water mark, an indirect condi- tion occurs that causes a shift from normal operation to one that drains the queue as quickly as possible. When the queue has been emptied (or per- haps nearly emptied), operation shifts back to normal. 2.10 Morphs Another consideration is whether a given instance’s operation can be ef- fectively redefined by establishing certain conditions. One typical example is when an instance is placed into scan mode for testing purposes. See Fig. 2.6 for an example of how an instance is transformed into one long scan chain by changing the value of test_mode from 0 to 1. Once set up for scanning, the instance is effectively governed by a dif- ferent set of variables (except for those of internal connectivity). It is prac- tical to regard such functionality as a metamorphosis (or “morph”) of the instance. Similarly, many other test or diagnostic modes of operation can be treated as different morphs of the instance, each with its own set of defined stimuli, conditions, and special cases. They will also be subject to an en- tirely separate set of rules and guidelines. The term mode is commonly used when referring to a morph, but it is also used in many other contexts, such as low-speed mode or high-speed mode in USB terminology and PCI mode or PCI-X mode in PCI terminol- ogy. To avoid this frequent ambiguity in the use of the term mode, the new term morph is introduced to identify the distinctly different metamorphosis of a target. 28 Chapter 2 – Analytical Foundation Fig. 2.6. Metamorphosis of a target Most designs nearly always specify at least 2 morphs for a given in- stance, one for ordinary operation and one for testing. However, some designs will also allow for a 3rd morph that facilitates diagnosis and troubleshooting. Such a morph might autonomously, often in response to some internally observable condition, save some internal state and make it available for later external access. Similarly, a diagnostic morph might respond to a distinct set of commands that provide data essential for di- agnosis of problems. An instance will be realized (usually) as two or more morphs. Usually, the first morph that is defined (call it morph 0 ) implements the principle function of the device and the second morph (morph 1 ) implements scan chains of the memory elements of the device. The connectivity of this test- ability morph is dependent upon the layout of the device (flip-flops are wired together into scan chains based on geometric proximity), whereas the connectivity of other morphs is usually independent of layout. Values for variables that determine the morph are usually always cho- sen deterministically rather than randomly. A much larger fraction of verification resources (engineering time, compute cycles, etc.) are typically 2.11 Variables of Stimulus and Response 29 applied to the default morph with a much smaller fraction reserved for the other morph(s). 2.11 Variables of Stimulus and Response A stimulus is applied directly to an input port or bi-directional port of the target, or, for many types of target, indirectly to some specially designated internal node, such as for targets which process instructions or commands (for example, microprocessors, DMA controllers, and USB port control- lers). The values of individual stimuli vary over time, and the responses to the stimuli at the output ports or bi-directional ports (or at specially desig- nated internal nodes) of the target are observed to determine whether the target is exhibiting correct or faulty behavior. Variables of stimulus and response are grouped together because many variables pertain to both a stimulus and a response, particularly for shared busses and other shared signals. For example, the number of wait states permitted on a shared READY signal on a bus applies equally whether the target drives the signal as a response or whether some other bus agent drives the signal as a stimulus. A distinguishing characteristic of variables of stimulus (and response) is that there sure are a lot of them. Fortunately, we can further divide this vast sub-space into smaller sub-spaces. In particular, stimulus and response variables can be classified along two dimensions, spatial and temporal, i.e. variables of composition and variables of time. Variables of time are those that indicate when values are produced as either a stimulus or response. Variables of time represent different levels of abstraction with regard to time and may be further distinguished as follows: • actual time: These are durations, intervals, latencies, and so forth usu- ally expressed in terms of the smallest unit of time relevant to the target, namely clock cycles. If timing simulation is performed, then sub-cycle Variables of composition are those which indicate what values may be assigned to the various bit positions of a multi-bit signal (whether stimulus or response, and whether applied in parallel or applied serially). For exam- ple, a simple bus transaction will contain different fields, the values of which are drawn from the individual ranges for the variables describing those fields. Similarly, verification of a superscalar processor must account for the possible instruction bundles that may be presented to the front of the processing pipeline at each instruction fetch cycle. 30 Chapter 2 – Analytical Foundation ranges for rise-time, fall-time, and set-up time may be defined as well. Functional verification may need to account for sub-cycle timing in tar- gets which capture data on both rising and falling edges of clocks. • relative time: These are related to the order of arrival of stimuli or re- sponses relative to one another; i.e. sequences, or what can follow what. For example, in verifying the execution engine in pipelined processors the possible sequences of instructions must be considered in evaluating coverage of the instruction pipeline. • inverse time: In these variables time appears in the denominator, such as throughput, bandwidth, MIPS, and so forth. Or, these may count events over some interval of time, such as retry attempts, For example, a re- quirement that states that average bandwidth over any interval of length T will be sustained at a level of x MB/s is defining a variable of inverse time. There may be numerous other abstractions of variables of stimulus and response as appropriate for the target. For example, activity on a shared bus is usually described in terms of atomic transactions that are joined in sequence to form a sequence. These abstractions are defined for program- ming convenience and are readily accommodated by commercially avail- able verification tools. 2.11.1 Internal Stimuli and Responses As a practical matter, certain classes of stimulus are applied not by the verification software to the input ports of the target, but rather are applied by internal logic to internal nodes. These are regarded as internal stimuli. For example, verification of a microprocessor with an embedded in- struction cache benefits greatly by considering the stream of instructions received at the input of a processor’s instruction pipeline as stimuli for the execution pipeline. The movement of instructions into the internal cache usually does not correspond directly to the stream of instructions executed within the processor’s pipeline. So, to determine how thoroughly the exe- cution pipeline is exercised, these internal stimuli (as applied by fetching instructions from the internal cache) are observed and analyzed to provide an indication of how well the pipeline is exercised. Likewise, internal responses, such as the results of executing and retir- ing an instruction, may need to be observed and analyzed to determine how well the execution pipeline is exercised. Of course, internal responses could be propagated to external output ports, but in simulation this is usually not expeditious to efficient failure 2.11 Variables of Stimulus and Response 31 analysis, because the observation at the output port usually lags the actual production of the response. On the other hand, in a hard prototype observing internal responses di- rectly is usually not possible, and additional steps are needed to reveal inter- nal responses at observable output ports. See chapter 4 for further discussion of designing observability into a target for the purposes of verification of the hard prototype. An important subset of internal response contains those that are pro- duced as a consequence of activation. The values of bits in internal regis- ters immediately after deassertion of reset are often required to have spe- cific values, and these must be monitored accordingly. Similarly, these same registers might be defined to have different values as a consequence of hard reset as compared to soft reset, which often preserves the values of certain bits from before the target experienced the reset. 2.11.2 Autonomous Responses Some responses of a target will appear spontaneously and disassociated from any particular stimulus. These responses may be regarded as autono- mous responses and include target-initiated activity such as the fetch of the first instruction by a microprocessor upon coming out of reset or the expi- ration of an interval timer due to the passage of time. Similarly, a change in internal condition (such as a queue becoming empty or full) can cause responses that are not associated with any particular stimulus. These examples show that there are varying degrees of autonomy for re- sponses. Responses that occur independent of all stimuli and arise simply as a consequence of activation may be said to be completely autonomous. A free-running timer produces completely autonomous responses. Responses that occur after excitation of the target may be said to be par- tially autonomous. These include those that occur as a consequence of ini- tialization, such as enabling an interval timer, or as a consequence of some indirect condition, such as the sudden appearance of wait states on a bus when a related queue becomes full or empty. 2.11.3 Conditions and Responses How does a variable of condition differ from a variable of response? Isn’t a condition simply a response of the target to some stimuli? Many an ordinary response is more or less discarded after it is produced. The data returned on a read command, the item removed from a queue, and 32 Chapter 2 – Analytical Foundation the ACK (acknowledge) of some transaction have no further influence on the behavior of the target producing the response. Conditions, on the other hand, persist and exert their influence over the behavior of the target. It may be more correct to consider variables of condition a proper subset of variables of response. From a practical standpoint, whether a particular variable is classified as one of condition or as one of response is a decision to be made by the verification team (or by the standards body defining the standard variables for some standard protocol under its care, such as USB or PCI-Express). 2.11.4 Example – Stimulus and Response Consider the format of a 32-bit instruction for a hypothetical processor (see Fig. 2.7). The 32-bit word has been defined to contain 5 distinct fields: a 3-bit field for the major opcode, three 5-bit fields for register ad- dresses, and a 14-bit field containing a secondary opcode. Fig. 2.7. Composition of an instruction The values assigned to each field are variable and constitute standard variables of stimulus. Meaningful pseudo-random programs for this proc- essor can be generated by constraining the values assigned to each field of each instruction. This can be expressed in e as follows: <’ struct instr { %major_op: uint (bits: 3); define LD 4; define ST 2; define ALU 3; define BR 1; define SYS 7; keep major_op in [LD, ST, ALU, BR, SYS]; %src_regA: uint (bits: 5); %src_regB: uint (bits: 5); %dst_reg: uint (bits: 5); %subop: uint (bits: 14); } ‘> 2.12 Error Imposition 33 If this processor has a 3-stage pipeline, there are implicit variables of relative time reflecting the possible instructions that can be present in the pipeline simultaneously and whose execution might interact. For example, a LD instruction whose destination register is used by an immediately- following (in time) ALU instruction will exercise functionality associated with ensuring that the ALU instruction uses the newly loaded value rather than the value in the register prior to execution of the LD instruction. Notice that rules that apply to stimuli are the constraints for generating and assigning pseudo-random values. 2.12 Error Imposition Many targets are designed to tolerate errors of various sorts, and exercising this functionality requires the imposition of errors onto the stimuli 4 . These classes of error vary widely and include: • value errors, such as CRC and parity errors, encoding, and bit-stuffing errors • temporal errors, such as delays in the arrival of data or packets of data (with a negative delay corresponding to early arrival), overflow and un- derflow of queues • ordering errors, such as reading a memory location before a prior write has completed. 2.12.1 Example – Errors The bulk of CRV will typically be conducted without imposing errors on any stimuli, but a significant fraction of the CRV must be devoted to error testing, constraining generation to produce occasional errors in sufficient density to reduce the risk of a bug in error-handling logic. 4 Other texts often refer to this as error injection, but because injection implies that something has been added to the stimulus, the term error imposition is used to better describe the many classes of potential error, including those that remove or reorder values or events. A short packet in an Ethernet subsystem is an ex- ample of error imposition where something has been effectively removed from the stimulus. 34 Chapter 2 – Analytical Foundation Consider a bus whose operation is defined such that an acknowledge- ment to a command issued to an addressed agent must be supplied within 16 or fewer cycles. Fig. 2.8. Error imposition To impose a temporal error in this circumstance the following code might be used: <’ struct response is also { event bus_clk is rise (‘~/top/BUS_CLK’) @sim; event start_cmd is rise(‘~/top/ADR’) @bus_clk; event ack; // Emit this event after waiting some // random number of cycles. response_time: int; keep impose_error == FALSE => response_time <= 16; keep impose_error == TRUE => response_time == 17; gen response_time; wait [response_time]*@bus_clk; emit ack; } ‘> This simple example relies on the field impose_error that is assumed to be defined elsewhere in the testbench. If this field has been assigned the value true, then the rule governing response time will be intentionally vio- lated (by one cycle), thereby exercising the functionality related to han- dling errors on this bus. Imposing a value error is also easily accomplished. For example, if a stream of data is protected by a final CRC value, this CRC value can be corrupted intentionally as follows: . set of variables (except for those of internal connectivity). It is prac- tical to regard such functionality as a metamorphosis (or “morph”) of the instance. Similarly, many other test or diagnostic. Analytical Foundation ranges for rise-time, fall-time, and set-up time may be defined as well. Functional verification may need to account for sub-cycle timing in tar- gets which capture data. destination register is used by an immediately- following (in time) ALU instruction will exercise functionality associated with ensuring that the ALU instruction uses the newly loaded value rather