A disable named block statement stops the execution of all blocks with that same name in all threads, which probably causes unexpected behavior.

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.

Below I list the process of this issue.

1. In sequence “fch_usb_multi_port_trans_seqs”, sequence “fch_usb_lpm_trans_seqs” was called twice for each Port.

       //Start transfers for devices

        for(int dn=0;dn<number_of_device;dn++) begin

            automatic int j=dn;

            fork

                begin

                    for(int k=0;k<2;k++)   begin

                       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.

sometimes we should use "disable fork" instead of "disable block_name"

4. However, The sequence mistakenly checked the Port0 and Port1 were both in L1 state, which was reported in below log.

sometimes we should use "disable fork" instead of "disable block_name"

相关文章:

  • 2022-12-23
  • 2021-12-28
  • 2022-02-23
  • 2022-12-23
  • 2021-10-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2021-07-25
  • 2021-08-20
  • 2021-12-16
  • 2021-04-04
  • 2022-12-23
  • 2021-12-05
相关资源
相似解决方案