Sie sind auf Seite 1von 6

Cornering Those Corner Case Bugs: Functional Coverage On Multiple Interfaces

Sharan Basappa
HCL Technologies Limited

Introduction
Year after year design complexity has been increasing at almost unprecedented pace. To handle the ever increasing complexity, new verification techniques have evolved over a period of time. Constrained random verification is one such technique to get a high degree of confidence in a relatively short period. Constrained random verification relies heavily on functional coverage for verification cycle closure. So it is imperative to make functional coverage robust against possible design defect leaks.

Functional Coverage On Multiple Interfaces


Functional verification has normally been written keeping DUT interfaces and internal logic behavior in mind. But what is also important is the relationship between different interfaces. Specifically, it must be ensured that stimuli that bring out certain relationship between two or more interfaces are exercised. This can be ensured only if such interface relation is planned and captured in functional coverage. Figure 1 shows a very simple DUT with three interfaces. Interface if_c is the source for transactions that end up on interface if_a and if_b; it is also the sink for transactions originating on interfaces if_a and if_b. An example of such a design would be a SoC with a RISC processor and interfaces for protocols like Ethernet, USB, PCIe, DDR2 memory all integrated in a single chip.

Figure 1 A simple DUT with multiple interfaces

For this simple DUT, under some basic assumptions, the following scenarios are possible: Scenario a: traffic originating on if_a Scenario b: traffic originating on if_b Scenario c: traffic destined to if_a Scenario d: traffic destined to if_b Scenario e: traffic originating on if_a; traffic destined to if_b Scenario f: traffic originating on if_b; traffic destined to if_a Scenario g: traffic originating on both if_a and if_b simultaneously Scenario h: traffic originating on if_c and destined to both if_a and if_b simultaneously Since typically the functional coverage is written looking at only one interface at a time, one tends to cover scenario a to f pretty well but miss out scenario g and h. Needless to say, it is these kind of corner case conditions that bring out surprising design bugs. So functional coverage that ensures conditions on multiple interfaces should be included in the strategy. Of course, interfaces being active on chip periphery does not necessarily mean that it is also active within DUT internal logic where it matters. For example, due to processing differences, even though traffic is active on both if_a and if_b at the same time, by the time data from if_b reaches some internal arbiter, data from if_a might have been already processed. So one needs to keep such factors in mind while writing functional coverage. The active signals are generated in the testbench as shown in figure 2. Since each interface may run on a different clock, the active signals can be synchronized to a common clock (say core clock). It should also be noted that generating active signal on newer generation serial protocols like PCIe, Ethernet where only the serial interface is exposed is non trivial. In such cases, one can rely on DUT internal logic or testbench BFM.

If_a Testbench module

active Functional coverage

If_b

active

Figure 2 Active signal generation in testbench

The next few figures show multiple scenarios which could be the candidates for functional coverage. Signals act_1 and act_2 indicate whether the corresponding interface is active or not.

Figure 3 Scenario where traffic on both interfaces begin at the same time

Figure 4 Sustained traffic on both interfaces simultaneously

Notes: since designs tend to have deep pipelines, only a sustained traffic ensures that necessary logic is exercised.

act_1

act_2
Activate close to each other

property r13 (clk, act_1, act_2); @ (posedge clk) $rose (act_1) |=> ##[R13MIN:R13MAX] $rose (act_2); endproperty
Figure 5 Traffic on two interfaces begin close to each other

Notes: scenario to check DUT behavior when traffic on an interface begins when it is busy processing traffic from the other interface.

act_1

act_2
Inactive close to each other

property r14 (clk, act_1, act_2); @ (posedge clk) $fell (act_1) |=> ##[R14MIN:R13MAX] $fell (act_2); endproperty

Figure 6 Traffic from two interfaces end close to each other

Notes: In this scenario DUT is processing data from both the interfaces and then the traffic from one of the interface ends while the traffic on the other interface continues.

Figure 7 Traffic end on one interface and start on other are close to each other

The above examples mainly illustrate the need to write functional coverage keeping multiple interfaces in mind. There are many more conditions possible than what are described above. For example, active on transmit and receive for a single interface instead of taking only two interfaces as above, checking such conditions on three interfaces So one should evaluate their design and try to evolve properties that give sufficient coverage.

Conclusion
Functional coverage is probably one of the most important components of constrained random verification strategy. Given this fact, it should be written taking every useful aspect into account such that it is water tight against any design defects. Functional coverage on multiple interfaces is one such important dimension that should always be evaluated as a part of verification strategy.

About the Author


Sharan Basappa is a manager working in VLSI division of HCL Technologies Limited. One of his focus areas is advanced verification techniques and methodologies. Sharan holds a post graduate degree in Microelectronics from Birla Institute of Technology and Science, Pilani.

Das könnte Ihnen auch gefallen