A disable named block statement stops the execution of all blocks with that same name in all threads, which probably causes unexpected behavior.this
Specific to this test, the 「disable PM_LINK_WAIT_USB2_L1」 statement will stops all active threads of PM_LINK_WAIT_USB2_L1 blocks, even if these PM_LINK_WAIT_USB2_L1 blocks are in different sequences.spa
Below I list the process of this issue.orm
1. In sequence 「fch_usb_multi_port_trans_seqs」, sequence 「fch_usb_lpm_trans_seqs」 was called twice for each Port.blog
//Start transfers for devicesci
for(int dn=0;dn<number_of_device;dn++) beginget
automatic int j=dn;it
forkio
beginform
for(int k=0;k<2;k++) beginthread
usb_lpm_trans_seqs[j].otg_xhc_device_transfer= otg_xhc_device_transfer[j];
usb_lpm_trans_seqs[j].start(p_sequencer, this);
end
end
join_none
end
2. In sequence 「fch_usb_lpm_trans_seqs」, we need to read register PORTSC_20 to check whether Port is in L1 LPM state.
//Enter low power
reg_port_num = otg_xhc_device_transfer.device_cfg.port_number;
if( pm_controller.pm_link_state == fch_otg_pm_controller::U1_L1 ||
pm_controller.pm_link_state == fch_otg_pm_controller::U2_L1 ) begin
fork : PM_LINK_WAIT_USB2_L1
begin
do begin
#5us;
expected_pm_link_state = 4'd2;
uvm_ext_fd_reg_access(`uvm_ext_fileline,RD,"dwc_usb3_reg","PORTSC_20",reg_data, reg_port_num);
end while(reg_data[8:5] != 4'd2);
end
begin
if(otg_xhc_device_transfer.device_cfg.connected_bus_speed == svt_usb_types::LS) begin
#3500us;
end else if(otg_xhc_device_transfer.device_cfg.connected_bus_speed == svt_usb_types::FS) begin
#2500us;
end else begin
#500us;
end
`uvm_fatal(get_type_name(), $psprintf("PM: Link, waiting for USB2.0 L1 failed for port %0d", otg_xhc_device_transfer.device_cfg.port_number));
end
join_any
disable PM_LINK_WAIT_USB2_L1;
`uvm_info(get_type_name(), $psprintf("PM: Link, Port %0d is L1", otg_xhc_device_transfer.device_cfg.port_number), UVM_LOW);
end
3. below waveform snapshot,
At #T1, usb_lpm_trans_seqs_0 read register PORTSC_20, and the RDATA is 32’h603
At #T2, usb_lpm_trans_seqs_1 read register PORTSC_20, and the RDATA is 32’h643.
That is, Port0 is in L1 state, and Port1 is not.
4. However, The sequence mistakenly checked the Port0 and Port1 were both in L1 state, which was reported in below log.