Tuesday, April 26, 2011

Killing Sequences on Sequencer Abruptly

Sometimes you may need to drive input until you see come condition or some timer expires. Once you meet that condition, you need to stop generating stimulus. The code for this scenario look like below.


//Test
begin
    fork
    begin
        wait(rtl_linkup == 1);
    end
    begin
       forever
           idles_transmit.start(Sequencer);
    end
  join_any
  disable fork;
end


In the above code we are driving idles until rtl_linkup condition is observed. But here there is a problem, As we are trying kill idles_transmit sequence abruptly when condition is met, this may cause the sequencer to be in intermittent state. This will cause the problem on the next sequences which trigger on the same sequencer. As sequencer is in intermittent state it may not get grant and will wait for for grant forever. To avoid this problem we need to reset the sequencer after killing threads. The code look like below.


//Test
begin
   fork
      begin
        wait(rtl_linkup == 1);
      end
      begin
           forever
              idles_transmit.start(Sequencer);
      end
   join_any
   disable fork;
   Sequencer.stop_sequence();
end


In the above code the stop_sequences call will reset the sequencer variables and won't cause any problem for the next sequences which are triggered on same sequencer. Here also we have another problem with the sequence thread which is killed with disable fork. Sometimes by the time thread is killed request might have been sent to driver. if thread is killed and stop_sequence is called before receiving the item_done, item_done will cause fatal error as request fifo is empty. So we need to kill thread and call of stop_sequence only after receiving item_done from driver. The code will look like below.


//Sequence .
class idles_transmit extends ovm_sequence #(REQ= packet);
    bit received_item_done;
    task body();
       wait_for_grant();
       assert(req.randomize());
       send_req(req);
       received_item_done = 0;
       wait_for_item_done();
       received_item_done = 1;
   endtask
endclass


//Test
begin
    fork
        begin
            wait(rtl_linkup == 1);
        end
        begin
             forever
                  idles_transmit.start(Sequencer);
        end
     join_any
     @(posedge idles_transmit.received_item_done);
     disable fork;
      Sequencer.stop_sequence();
end


In the above code we are trying to kill the thread and reseting sequencer state only after receiving the ite_done for the request sent, which is the idle way to stop thread.

No comments:

Post a Comment