specman: how does a sequence get the result from a transaction it sent to BFM?

48 Views Asked by At

I have a sequence that drives transaction to a BFM. The bfm writes to a field in the transaction. The problem is that in the sequence it doesn't get the written value. it gets always zero. How can I propagate a value from the BFM back to the sequence?

The sequence is :

read( addr : uint (bits : 18)) : list of byte @driver.clock is {
        trans = new with {
            .address = addr;
            .wr_n = 1;
        };
        message(MEDIUM, "read Trans : address=", trans.address);            
        driver.wait_for_grant(me);
        driver.deliver_item(trans);
        out("trans =");
        print trans ;
        if trans != NULL {
            result = pack(packing.low, trans.rd_data);
        } else {
            out("trans is NULL");
        };

The BFM is :

    request_and_drive_packet() @clk_e is {
        
        while (TRUE) {
            gen gap_between_transactions;
            pkt = p_drv.get_next_item();
            message(MEDIUM, "mpif got packet to drive: data=", pkt.data);
            drive_if( pkt );
            for i from 0 to gap_between_transactions do {
                drive_idle()
            };
            emit p_drv.item_done;
        };
    };
        
    drive_if( pkt : mpif_packet_s )  @clk_e is {
        p_smp.select_n$ = 0;--.put_mvl(MVL_0) ;
        p_smp.wr_n$       = pkt.wr_n;
        p_smp.addr$       = pkt.address;
        p_smp.wr_data$    = pkt.data;
        while (p_smp.ack.get_mvl() == MVL_0)    {
            wait cycle; };
        pkt.rd_data = p_smp.rd_data$;
        wait cycle;      
        p_smp.select_n$ = 1; --.put_mvl(MVL_1); --$   = 1;
        wait cycle; 
    };

I need a way to update the transaction item that was sent to the BFM

2

There are 2 best solutions below

0
Thorsten On

The deliver_item() method is non-blocking (I think). Try execute_item() instead which waits for the item_done event. You can also forgo this API and just do a

do trans on driver;

in your sequence.

0
user3467290 On

your code calls deliver_item(), and does not wait for item_done. it means it continues, before the BFM has the chance to deliver the item. replace the wait_for_grant() and the deliver_item() with exectue_item().

driver.execute_item(packet);
    if packet != NULL {
      //...

the deliver_item() is good when the caller does not need to wait for results of the transaction. you can debug, set break points both in read() and in request_and_driver_packet(), and see the difference between deliver_item() and execute_item()