blob: 8fa7b0655c2acda91746f249985993364f662d81 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
class chip_sw_power_sleep_load_vseq extends chip_sw_base_vseq;
`uvm_object_utils(chip_sw_power_sleep_load_vseq)
uint timeout_ns = 1;
int duty_cycle[NUM_PWM_CHANNELS] = '{6,11,27,8,17,7};
uint pkt_cnt[NUM_PWM_CHANNELS] = '{default : 0};
localparam uint CLOCK_PERIOD = 32;
`uvm_object_new
virtual task cpu_init;
bit core_clk_off;
bit io_clk_off;
bit usb_slp_clk_off;
bit usb_act_clk_off;
bit deep_sleep_on;
{core_clk_off, io_clk_off, usb_slp_clk_off, usb_act_clk_off, deep_sleep_on} = $urandom();
super.cpu_init();
void'($value$plusargs("SW_CORE_CLK_OFF=%d", core_clk_off));
void'($value$plusargs("SW_IO_CLK_OFF=%d", io_clk_off));
void'($value$plusargs("SW_USB_SLP_CLK_OFF=%d", usb_slp_clk_off));
void'($value$plusargs("SW_USB_ACT_CLK_OFF=%d", usb_act_clk_off));
void'($value$plusargs("SW_DEEP_SLEEP_ON=%d", deep_sleep_on));
sw_symbol_bkdr_overwr_scalar("kCoreClkOff", core_clk_off);
sw_symbol_bkdr_overwr_scalar("kIoClkOff", io_clk_off);
sw_symbol_bkdr_overwr_scalar("kUsbSlpOff", usb_slp_clk_off);
sw_symbol_bkdr_overwr_scalar("kUsbActOff", usb_act_clk_off);
sw_symbol_bkdr_overwr_scalar("kDeepSleep", deep_sleep_on);
endtask
virtual task body();
super.body();
fork
begin : GPIO_CHECK
// Check IOA2 = 0
`DV_WAIT(cfg.sw_logger_vif.printed_log == "GPIO active",
"timeout waiting for SW sync GPIO (1)",
cfg.sw_test_timeout_ns)
`DV_WAIT(cfg.chip_vif.gpios_if.pins[2] == '0,
$sformatf("Timed out waiting for IOA2 == %0h", 0),
timeout_ns)
// Check IOA2 = 1
`DV_WAIT(cfg.sw_logger_vif.printed_log == "all HW is active",
"timeout waiting for SW sync GPIO (2)",
cfg.sw_test_timeout_ns)
`DV_WAIT(cfg.chip_vif.gpios_if.pins[2] == '1,
$sformatf("Timed out waiting for IOA2 == %0h", 1),
timeout_ns)
// Check IOA2 = 0
`DV_WAIT(cfg.sw_logger_vif.printed_log == "Prepare to exit",
"timeout waiting for SW sync GPIO (3)",
cfg.sw_test_timeout_ns)
`DV_WAIT(cfg.chip_vif.gpios_if.pins[2] == '0,
$sformatf("Timed out waiting for IOA2 == %0h", 0),
timeout_ns)
end : GPIO_CHECK
begin : PWM_CHECK
`DV_WAIT(cfg.sw_logger_vif.printed_log == "PWM active",
"timeout waiting for SW sync PWM (1)",
cfg.sw_test_timeout_ns)
foreach (cfg.m_pwm_monitor_cfg[i]) begin
cfg.m_pwm_monitor_cfg[i].active = 1;
end
fork
collect_pwm_data(); // this is infinite task
join_none
`DV_WAIT(cfg.sw_logger_vif.printed_log == "Prepare to exit",
"timeout waiting for SW PWM (2)",
cfg.sw_test_timeout_ns)
foreach (cfg.m_pwm_monitor_cfg[i]) begin
cfg.m_pwm_monitor_cfg[i].active = 0;
end
end : PWM_CHECK
join
endtask : body
virtual task collect_pwm_data();
pwm_item item[NUM_PWM_CHANNELS];
foreach(p_sequencer.pwm_rx_fifo[i]) begin
automatic int j = i;
fork begin
forever begin
process_pwm_data(j);
end
end join_none
end
endtask : collect_pwm_data
virtual task process_pwm_data(int channel);
pwm_item item;
p_sequencer.pwm_rx_fifo[channel].get(item);
pkt_cnt[channel]++;
// During device init, pulse at each channel started with its
// default value(1) at random time, which creates false
// duration initially.
// Flushing first 2 packets will remove such a false alarm.
if (pkt_cnt[channel] <= 2) return;
if (item.period != CLOCK_PERIOD) begin
`uvm_error(`gfn, $sformatf("PWMCH%0d : pkt%0d Clock period is wrong. rcv : %0d exp : %0d",
channel, pkt_cnt[channel], item.period, CLOCK_PERIOD))
end
if (item.active_cnt != duty_cycle[channel]) begin
`uvm_error(`gfn, $sformatf("PWMCH%0d : Dutycy mismatch. invert : %0d rcv : %0d exp : %0d",
channel, item.invert, item.active_cnt, duty_cycle[channel]))
end
endtask // process_pwm_data
virtual task post_start();
super.post_start();
foreach(p_sequencer.pwm_rx_fifo[i]) begin
if(pkt_cnt[i] <= 3) begin
`uvm_error(`gfn, $sformatf("PWMCH%0d : no toggling signal", i))
end
end
endtask : post_start
virtual task sw_symbol_bkdr_overwr_scalar(string str, bit [7:0] data);
bit [7:0] array_data[1] = {data};
sw_symbol_backdoor_overwrite(str, array_data);
endtask
endclass : chip_sw_power_sleep_load_vseq