Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the gpio_stress_all with random reset #25657

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions hw/ip/gpio/dv/env/gpio_env_cfg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class gpio_env_cfg extends cip_base_env_cfg #(

// only support 1 outstanding TL item
m_tl_agent_cfg.max_outstanding_req = 1;

// Used to allow reset operation during a stress all tests and check the CSR after that.
can_reset_with_csr_accesses = 1'b1;
endfunction : initialize

endclass
15 changes: 12 additions & 3 deletions hw/ip/gpio/dv/env/seq_lib/gpio_dout_din_regs_random_rw_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ class gpio_dout_din_regs_random_rw_vseq extends gpio_base_vseq;

`DV_CHECK_RANDOMIZE_FATAL(this)
// Insert some random delay
cfg.clk_rst_vif.wait_clks(delay);
cfg.clk_rst_vif.wait_clks_or_rst(delay);
// Skip if a reset is ongoing...
if (!cfg.clk_rst_vif.rst_n) return;

randcase
// drive new gpio data in
Expand All @@ -35,7 +37,11 @@ class gpio_dout_din_regs_random_rw_vseq extends gpio_base_vseq;
`DV_CHECK_STD_RANDOMIZE_FATAL(gpio_i)
// drive gpio_vif after setting all output enables to 0's
drive_gpio_in(gpio_i);
cfg.clk_rst_vif.wait_clks(1);
cfg.clk_rst_vif.wait_clks_or_rst(1);

// Skip if a reset is ongoing...
if (!cfg.clk_rst_vif.rst_n) break;

// read data_in register
csr_rd(.ptr(ral.data_in), .value(data_in));
end
Expand All @@ -52,7 +58,10 @@ class gpio_dout_din_regs_random_rw_vseq extends gpio_base_vseq;
1: begin
// Add single clock cycle delay to avoid update and predict at
// the same time due to weak pull-up after undrive_gpio_in()
cfg.clk_rst_vif.wait_clks(1);
cfg.clk_rst_vif.wait_clks_or_rst(1);

// Skip if a reset is ongoing...
if (!cfg.clk_rst_vif.rst_n) break;
// DATA_IN register is RO, but writing random value to it
// should have no impact on gpio functionality
csr_wr(.ptr(ral.data_in), .value(csr_val));
Expand Down
9 changes: 6 additions & 3 deletions hw/ip/gpio/dv/env/seq_lib/gpio_intr_rand_pgm_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ class gpio_intr_rand_pgm_vseq extends gpio_base_vseq;
string msg_id = {`gfn, $sformatf(" Transaction-%0d", tr_num)};

`DV_CHECK_MEMBER_RANDOMIZE_FATAL(delay)
cfg.clk_rst_vif.wait_clks(delay);
cfg.clk_rst_vif.wait_clks_or_rst(delay);
// Skip if a reset is ongoing...
if (!cfg.clk_rst_vif.rst_n) return;

randcase
// drive new gpio data in
Expand All @@ -36,7 +38,8 @@ class gpio_intr_rand_pgm_vseq extends gpio_base_vseq;
`uvm_info(msg_id, "drive random value on gpio_i", UVM_HIGH)
// drive gpio_vif after setting all output enables to 0's
drive_gpio_in(gpio_i);
cfg.clk_rst_vif.wait_clks(1);

cfg.clk_rst_vif.wait_clks_or_rst(1);
// read data_in register
csr_rd(.ptr(ral.data_in), .value(data_in));
end
Expand Down Expand Up @@ -79,7 +82,7 @@ class gpio_intr_rand_pgm_vseq extends gpio_base_vseq;
begin
bit [TL_DW-1:0] reg_rd_data;
`DV_CHECK_MEMBER_RANDOMIZE_FATAL(delay)
cfg.clk_rst_vif.wait_clks(delay);
cfg.clk_rst_vif.wait_clks_or_rst(delay);
// read intr_state register
csr_rd(.ptr(ral.intr_state), .value(reg_rd_data));
end
Expand Down
10 changes: 7 additions & 3 deletions hw/ip/gpio/dv/env/seq_lib/gpio_rand_intr_trigger_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class gpio_rand_intr_trigger_vseq extends gpio_base_vseq;
string msg_id = {`gfn, $sformatf(" Transaction-%0d", tr_num)};

`DV_CHECK_MEMBER_RANDOMIZE_FATAL(delay)
cfg.clk_rst_vif.wait_clks(delay);
cfg.clk_rst_vif.wait_clks_or_rst(delay);
`uvm_info(msg_id, $sformatf("delay = %0d", delay), UVM_HIGH)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't you need to return here if we're in reset?


// Step-1 Program interrupt registers
Expand All @@ -52,7 +52,7 @@ class gpio_rand_intr_trigger_vseq extends gpio_base_vseq;
cfg.gpio_vif.drive(gpio_i);
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(delay_before_gpio_change,
delay_before_gpio_change inside {[1:5]};)
cfg.clk_rst_vif.wait_clks(delay_before_gpio_change);
cfg.clk_rst_vif.wait_clks_or_rst(delay_before_gpio_change);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly, I think we probably want to return here if we're in reset?

end
gpio_tgl_cycle_done = 1'b1;
end
Expand All @@ -61,7 +61,11 @@ class gpio_rand_intr_trigger_vseq extends gpio_base_vseq;
uint rd_period;
bit [TL_DW-1:0] reg_rd_data;
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(rd_period, rd_period inside {[2:20]};)
cfg.clk_rst_vif.wait_clks(rd_period);

// Skip if a reset is ongoing...
if (!cfg.clk_rst_vif.rst_n) break;

cfg.clk_rst_vif.wait_clks_or_rst(rd_period);
`uvm_info(msg_id, $sformatf("Reading intr_state after %0d more clock cycles",
rd_period), UVM_HIGH)
randcase
Expand Down
10 changes: 8 additions & 2 deletions hw/ip/gpio/dv/env/seq_lib/gpio_random_dout_din_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class gpio_random_dout_din_vseq extends gpio_base_vseq;
for (uint tr_num = 0; tr_num < num_trans; tr_num++) begin

`DV_CHECK_RANDOMIZE_FATAL(this)
cfg.clk_rst_vif.wait_clks(delay);
cfg.clk_rst_vif.wait_clks_or_rst(delay);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you probably need to return after this line if we are in reset.


randcase
// drive new gpio data in
Expand All @@ -42,7 +42,13 @@ class gpio_random_dout_din_vseq extends gpio_base_vseq;
`DV_CHECK_STD_RANDOMIZE_FATAL(gpio_i)
// drive gpio_vif after setting all output enables to 0's
drive_gpio_in(gpio_i);
cfg.clk_rst_vif.wait_clks(1);

// Skip if a reset is ongoing...
if (!cfg.clk_rst_vif.rst_n) break;
cfg.clk_rst_vif.wait_clks_or_rst(1);

// Skip if a reset is ongoing...
if (!cfg.clk_rst_vif.rst_n) break;
// read data_in register
csr_rd(.ptr(ral.data_in), .value(data_in));
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@ class gpio_random_long_reg_writes_reg_reads_vseq extends gpio_base_vseq;
// Wait for minimum 1 clock cycle initially to avoid reading of data_in
// immediately as the first iteration after reset, while data_in prediction
// is still being processed
cfg.clk_rst_vif.wait_clks(1);
cfg.clk_rst_vif.wait_clks_or_rst(1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we need to return if we've seen a reset?


for (uint tr_num = 0; tr_num < num_trans; tr_num++) begin
string msg_id = {`gfn, $sformatf(" Transaction-%0d", tr_num)};
uint num_reg_op;
`DV_CHECK_MEMBER_RANDOMIZE_FATAL(delay)
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(num_reg_op, num_reg_op inside {[25:50]};)

cfg.clk_rst_vif.wait_clks(delay);
cfg.clk_rst_vif.wait_clks_or_rst(delay);
// Skip if a reset is ongoing...
if (!cfg.clk_rst_vif.rst_n) return;

randcase
// drive new gpio data in
1: begin
Expand All @@ -41,7 +44,7 @@ class gpio_random_long_reg_writes_reg_reads_vseq extends gpio_base_vseq;
// drive gpio_vif after setting all output enables to 0's
drive_gpio_in(gpio_i);
// Wait for one clock cycle for us to read data_in reg reliably
cfg.clk_rst_vif.wait_clks(1);
cfg.clk_rst_vif.wait_clks_or_rst(1);
end
// long reg write
1: begin
Expand Down
17 changes: 12 additions & 5 deletions hw/ip/gpio/dv/env/seq_lib/gpio_smoke_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ class gpio_smoke_vseq extends gpio_base_vseq;
task body();
// test gpio inputs
`DV_CHECK_MEMBER_RANDOMIZE_FATAL(num_trans)
`uvm_info(`gfn, $sformatf("No. of transactions (gpio_i) = %0d", num_trans), UVM_HIGH)
for (uint tr_num = 0; tr_num < num_trans; tr_num++) begin
bit [TL_DW-1:0] csr_rd_val;
string msg_id = {`gfn, $sformatf(" Transaction-%0d: ", tr_num)};
`DV_CHECK_MEMBER_RANDOMIZE_FATAL(gpio_i)
`uvm_info(msg_id, $sformatf("gpio_i = %0h", gpio_i), UVM_HIGH)
`uvm_info(msg_id, $sformatf("gpio_i = %0h", gpio_i), UVM_LOW)

cfg.gpio_vif.drive(gpio_i);
`ifdef GPIO_ASYNC_ON
// If the CDC synchronizer prims are instantiated, it takes 2-3 cycles longer for inputs
Expand All @@ -44,7 +44,11 @@ class gpio_smoke_vseq extends gpio_base_vseq;
// Wait at least one clock cycle
`DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(delay, delay >= 1;)
`endif
cfg.clk_rst_vif.wait_clks(delay);

cfg.clk_rst_vif.wait_clks_or_rst(delay);
// Skip if a reset is ongoing...
if (!cfg.clk_rst_vif.rst_n) return;

// Reading data_in will trigger a check inside scoreboard
csr_rd(.ptr(ral.data_in), .value(csr_rd_val));
`uvm_info(msg_id, {$sformatf("reading data_in after %0d clock cycles ", delay),
Expand All @@ -70,8 +74,11 @@ class gpio_smoke_vseq extends gpio_base_vseq;
csr_update(.csr(ral.direct_oe));
// Wait at least one clock cycle
`DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(delay, delay >= 1;)
cfg.clk_rst_vif.wait_clks(delay);
`uvm_info(msg_id, $sformatf("waiting for %0d clock cycles", delay), UVM_HIGH)

// Skip if a reset is ongoing...
if (!cfg.clk_rst_vif.rst_n) return;
cfg.clk_rst_vif.wait_clks_or_rst(delay);
`uvm_info(msg_id, $sformatf("waiting for %0d clock cycles", delay), UVM_LOW)
end
endtask : body

Expand Down
Loading