blob: fd15df58bfe4b90ea8e2bc77fc08507448a82cdc [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
// basic fifo_overflow test vseq
class i2c_host_fifo_overflow_vseq extends i2c_rx_tx_vseq;
`uvm_object_utils(i2c_host_fifo_overflow_vseq)
`uvm_object_new
// fast write data to fmt_fifo to quickly trigger fmt_watermark interrupt
constraint fmt_fifo_access_dly_c { fmt_fifo_access_dly == 0;}
// fast read data from rd_fifo to quickly finish simulation (increasing sim. performance)
constraint rx_fifo_access_dly_c { rx_fifo_access_dly == 0;}
// write transaction length is more than fmt_fifo depth to cross fmtilvl
constraint num_wr_bytes_c {
solve num_data_ovf before num_wr_bytes;
num_wr_bytes == I2C_FMT_FIFO_DEPTH + num_data_ovf;
}
// send more one data than rx_fifo depth to trigger rx_overflow
constraint num_rd_bytes_c { num_rd_bytes == I2C_RX_FIFO_DEPTH + 1; }
// counting the number of received overflow interrupts
local uint cnt_fmt_overflow;
local uint cnt_rx_overflow;
virtual task pre_start();
super.pre_start();
// config fmt_overflow and rx_overflow tests
cfg.seq_cfg.en_fmt_overflow = 1'b1;
cfg.seq_cfg.en_rx_overflow = 1'b1;
print_seq_cfg_vars("pre-start");
endtask : pre_start
virtual task body();
bit check_fmt_overflow;
bit check_rx_overflow;
bit rxempty = 1'b0;
initialization(.mode(Host));
`uvm_info(`gfn, "\n--> start of i2c_host_fifo_overflow_vseq", UVM_DEBUG)
for (int i = 1; i <= num_trans; i++) begin
check_fmt_overflow = 1'b1; // set to gracefully stop process_fmt_overflow_intr
check_rx_overflow = 1'b1; // set to gracefully stop process_rx_overflow_intr
cnt_fmt_overflow = 0;
cnt_rx_overflow = 0;
`uvm_info(`gfn, $sformatf("\n run simulation %0d/%0d", i, num_trans), UVM_DEBUG)
fork
begin
//*** verify fmt_overflow irq:
// -> send write transaction -> pooling and counting fmt_overflow interrupt
// -> check write complete -> stop pooling fmt_overflow interrupt
// -> verify the number of received fmt_watermark interrupt
// -> verify fmt_data dropped is performed scoreboard
if (check_fmt_overflow) begin
host_send_trans(.max_trans(1), .trans_type(WriteOnly));
check_fmt_overflow = 1'b0;
// number of fmt_overflow received is at most num_data_ovf
// since fmt_fifo can be drained thus decreasing cnt_fmt_overflow counter
if (!cfg.under_reset) begin
`DV_CHECK_GT(cnt_fmt_overflow, 0)
`DV_CHECK_LE(cnt_fmt_overflow, num_data_ovf)
`uvm_info(`gfn, $sformatf("\n cnt_fmt_overflow %0d", cnt_fmt_overflow), UVM_DEBUG)
end
end
//*** verify rx_overflow irq:
// -> send read transaction -> pooling and counting rx_overflow interrupt
// -> check write complete -> stop pooling rx_overflow interrupt
// -> verify the number of received rx_overflow interrupt
// -> verify the rx_data dropped is performed in scoreboard
if (check_rx_overflow) begin
host_send_trans(.max_trans(1), .trans_type(ReadOnly));
check_rx_overflow = 1'b0;
if (!cfg.under_reset) begin
`DV_CHECK_EQ(cnt_rx_overflow, 1)
`uvm_info(`gfn, $sformatf("\n cnt_rx_overflow %d", cnt_rx_overflow), UVM_DEBUG)
end
end
end
begin
while (!cfg.under_reset && check_fmt_overflow) process_fmt_overflow_intr();
end
begin
while (!cfg.under_reset && check_rx_overflow) process_rx_overflow_intr();
end
join
end
`uvm_info(`gfn, "\n--> end of i2c_fifo_full_vseq", UVM_DEBUG)
endtask : body
// we use backdoor instead of blocking csr_rd since the
// overflow bits of intr_state can be asserted very fast
task process_fmt_overflow_intr();
bit fmt_overflow;
csr_rd(.ptr(ral.intr_state.fmt_overflow), .value(fmt_overflow), .backdoor(1'b1));
if (fmt_overflow) begin
cnt_fmt_overflow++;
clear_interrupt(FmtOverflow);
end else begin
cfg.clk_rst_vif.wait_clks(1);
end
endtask : process_fmt_overflow_intr
task process_rx_overflow_intr();
bit rx_overflow;
csr_rd(.ptr(ral.intr_state.rx_overflow), .value(rx_overflow), .backdoor(1'b1));
if (rx_overflow) begin
cnt_rx_overflow++;
clear_interrupt(RxOverflow);
end else begin
cfg.clk_rst_vif.wait_clks(1);
end
endtask : process_rx_overflow_intr
endclass : i2c_host_fifo_overflow_vseq