blob: 78bec6a212d662f76d3a582be4ba324d1700f7f2 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// This is base sequence for any data path drop test for target_mode i2c.
// Random data path drop event make difficult to predict sent/rcvd counter.
// This base sequence run the sequence for 'seq_runtime' and
// test execution does not rely on sent / rcvd counter.
class i2c_target_runtime_base_vseq extends i2c_target_smoke_vseq;
`uvm_object_utils(i2c_target_runtime_base_vseq)
`uvm_object_new
// sequence running time in us
// update this value using 'pre_start' in child sequence.
int seq_runtime = 0;
// set this bit to 1 to hold next sequence start.
bit pause_seq = 0;
// 1 bit cycle : thigh + tlow
// one acq entry can be popped every 9 bit cycles (8bit + ack)
int acq_rd_cyc;
i2c_target_base_seq m_i2c_host_seq;
virtual task body();
i2c_item txn_q[$];
bit timer_expired = 0;
initialization(Device);
`uvm_info("cfg_summary", $sformatf("target_addr0:0x%x target_addr1:0x%x num_trans:%0d",
target_addr0, target_addr1, num_trans), UVM_MEDIUM)
print_time_property();
get_timing_values();
program_registers();
acq_rd_cyc = 9 * (thigh + tlow);
fork
begin
fork
while (timer_expired == 0) begin
`uvm_create_obj(i2c_target_base_seq, m_i2c_host_seq)
create_txn(txn_q);
fetch_txn(txn_q, m_i2c_host_seq.req_q);
m_i2c_host_seq.start(p_sequencer.i2c_sequencer_h);
`DV_WAIT(cfg.m_i2c_agent_cfg.got_stop, "got_stop wait timeout occurred!",
cfg.spinwait_timeout_ns, "target_runtime_base_vseq")
cfg.m_i2c_agent_cfg.got_stop = 0;
// To avoid race between 'pause_seq set' and
// 'cfg.m_i2c_agent_cfg.got_stop = 1'
cfg.clk_rst_vif.wait_clks(1);
`DV_WAIT(pause_seq == 0, "pause_seq == 0 wait timeout occurred!",
cfg.spinwait_timeout_ns, "target_runtime_base_vseq")
end
process_target_interrupts();
join
end
begin
#(seq_runtime * 1us);
`uvm_info("seq", "timer expired", UVM_MEDIUM)
timer_expired = 1;
`DV_WAIT(cfg.m_i2c_agent_cfg.got_stop, "got_stop wait timeout occurred!",
cfg.spinwait_timeout_ns, "target_runtime_base_vseq")
cfg.stop_intr_handler = 1;
end
begin
test_event();
end
begin
process_acq();
end
join
endtask
virtual task test_event; endtask
virtual task process_acq; endtask
// If txfifo is not full,
// fill random size of tx data upon receiving txstretch interrupt.
// expected data will be stored at the scoreboard
task proc_intr_txstretch();
bit [7:0] wdata;
int lvl;
int delay;
uvm_reg_data_t data;
delay = $urandom_range(0, 10);
cfg.clk_rst_vif.wait_clks(delay * acq_rd_cyc);
csr_rd(.ptr(ral.fifo_status.txlvl), .value(data));
data = 64 - data;
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(lvl, lvl dist {[1:16] := 7, [17:63] := 1, 64 := 2};)
if (lvl > data) lvl = data;
repeat (lvl) begin
wdata = $urandom();
csr_wr(.ptr(ral.txdata), .value(wdata));
end
clear_interrupt(TxStretch, 0);
endtask // proc_intr_txstretch
endclass