I'm building UART verification environment. I have 2 sequenceses:
vr_ad_sequence
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
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.