Quantcast
Channel: Cadence Functional Verification
Viewing all articles
Browse latest Browse all 652

Don’t Lose Extra Simulation Cycles

$
0
0

After reading the rest of this blog, you might guess the truth, which is that my "designing" skills go back to the 8086 processor! In this blog, I have used a 64-bit register (Well, I could make it 16-bit, but…)  in the example, just to show that this issue is still relevant today.

At any rate, the e verification issue that I describe here seems to be a common issue for many users.

Assume that, in the e verification code for a CPU HDL model, you read a general-purpose register with a 64-bit width (r0) and compare its value to a value computed in an e reference model. In other words, your e code contains a port declaration like the following:

r0: in simple_port of uint(bits:64) is instance;

keep bind(r0,external);
keep r0.hdl_path() == "dut.cpu.r0";

Assume also that bits 0 to 8 of r0 are used as status bits—that is, carry, overflow, parity, and so on. They are updated when a given arithmetic operation completes and reset when a new operation begins. Completing the arithmetic operation might take a couple of clock cycles. Naturally, you will want to avoid checking the status change on each clock cycle. You will also want to avoid checking each change in r0.

To achieve this, you might try:

event r0_event is change($r0)@sim;

However, this code will almost certainly NOT work because Specman supports events on objects up to 32 bits. Even if it does work, it results in your checking code being triggered on each change of bits 9 to 63--not exactly what you intended.

What you want is to make your verification check take place only on a status change. The way to do it is to define a port linked to the required slice, such as:

r0_status : in simple_port of uint(bits:9) is instance;
keep bind(r0_status,external);
keep r0_status.hdl_path() == "dut.cpu.r0[8:0]";

And also define an event like:

event  r0_status_change is rise(r0_status$)@sim;

Finally, your verification code might look like:

type status_bit : [carry,overflow,parity=0b00100000];
verify() @r0_status_change is {
        var status := r0$[8:0].as_a(status_bit);  //Note that Specman interface optimizations are used and 
        var data := r0$[63:9];                                // register r0 is accessed only once in a simulation cycle

        case status {
                [parity]: { do_something_with_data(data);};
        . . .

As you can see, going far back to an example from the '70a can still be helpful these days.

Roman Shenkar
e Interface team, Specman R&D 


Viewing all articles
Browse latest Browse all 652

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>