uvmspecmane

Specman e: A sequence drives its BFM also its MAIN was not defined in a test


I'm building UART verification environment. I have 2 sequenceses:

  1. For driving DUT UART configuration - vr_ad_sequence
  2. For driving frames to DUT UART Rx - uart_sequence

Both sequences, their drivers and BFMs work Ok. BUT, when I created a simple test that ONLY uses configuration sequence, the DUT UART Rx is driven by the verification environment (also there is NO extension of MAIN uart_sequence)! The test looks like this:

// The test that drives ALSO uart_sequence
extend MAIN vr_ad_sequence {  // Configuration sequence
   body()@driver.clock is only {
       // Configuration logic
   };
};

The only way I succeeded to stop Rx to be driven is by "overwriting" the MAIN uart_sequence body():

// The test that does not drives UART Rx
extend MAIN uart_sequence { // Rx sequence
    body() @driver.clock is only {
    };
};

extend MAIN vr_ad_sequence {  // Configuration sequence
   body()@driver.clock is only {
       // Configuration logic
   };
};

Here is the how the UART Rx sequence, driver and BFM are defined in the verification environment:

sequence uart_sequence using 
   item           = uart_frame_s,
   created_driver = uart_driver_u;


extend uart_driver_u {
   event clock is only rise(port_clk$) @sim;
};


extend uart_rx_agent_u {
   driver: uart_driver_u is instance;
};


extend uart_rx_agent_u {
   uart_monitor : uart_rx_monitor_u is instance; // like uvm_monitor
   uart_bfm     : uart_rx_bfm_u is instance; // like uvm_bfm
};


extend uart_rx_bfm_u {
   !cur_frame: uart_frame_s;

   run() is also {
      start execute_items();
   };

   execute_items() @rx_clk is {
      while (TRUE) do{
         cur_frame = p_agent.driver.get_next_item();
         drive_frame(cur_frame);
      }; 
   }; 

   drive_frame(cur_frame : uart_frame_s) @rx_clk is {
       // Drive frame logic
   };
};  

Do you have any idea why uart_sequence drives its BFM even when its MAIN was not extended? Thank you for your help


Solution

  • In the Specman documentation there is an example and the explanation states:

    The MAIN sequence creates count sequences of any kind, randomly selected from the currently loaded ATM sequences.

    The MAIN sequence is also described in its own section:

    The MAIN sequence subtype is defined directly under the sequence driver, and is started by default. It is the root for the whole sequence tree.

    The code for it is:

    extend MAIN sequence_name {
        count: uint;
        !sequence: sequence_name;
    
        keep soft count > 0;
        keep soft count <= MAX_RANDOM_COUNT;
        keep sequence.kind not in [RANDOM, MAIN];
    
        body() @driver.clock is only {
            for i from 1 to count do {
                do sequence;
            };
        };
    };
    

    By extending it and overwriting its body() you are disabling the automatically generated code that starts random sequences.

    You can also disable the MAIN sequence by constraining gen_and_start_main in the UART sequence driver.