[dv] Flash_ctrl enable polling before read/program
This PR switches randomly between backpressured reads / writes and
backpressured reads / writes.
Signed-off-by: Srikrishna Iyer <sriyer@google.com>
diff --git a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv
index 075802e..d5bc9cc 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_env_pkg.sv
@@ -42,7 +42,7 @@
parameter uint FlashMemAddrBankMsbBit = FlashDataByteWidth + FlashWordLineWidth +
FlashPageWidth + FlashBankWidth - 1;
-// types
+ // types
typedef enum int {
FlashCtrlIntrProgEmpty = 0,
FlashCtrlIntrProgLvl = 1,
diff --git a/hw/ip/flash_ctrl/dv/env/flash_ctrl_seq_cfg.sv b/hw/ip/flash_ctrl/dv/env/flash_ctrl_seq_cfg.sv
index b33ce0a..5889d00 100644
--- a/hw/ip/flash_ctrl/dv/env/flash_ctrl_seq_cfg.sv
+++ b/hw/ip/flash_ctrl/dv/env/flash_ctrl_seq_cfg.sv
@@ -42,6 +42,9 @@
uint op_erase_type_bank_pc = 0;
uint op_max_words = 512;
+ // Poll fifo status before writing to prog_fifo / reading from rd_fifo.
+ uint poll_fifo_status_pc = 30;
+
`uvm_object_new
endclass
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_base_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_base_vseq.sv
index e2b579f..cccb523 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_base_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_base_vseq.sv
@@ -113,6 +113,7 @@
// Wait for prog fifo to not be full.
virtual task wait_flash_ctrl_prog_fifo_not_full();
+ // TODO: if intr enabled, then check interrupt, else check status.
bit prog_full;
`DV_SPINWAIT(
do begin
@@ -124,6 +125,7 @@
// Wait for rd fifo to not be empty.
virtual task wait_flash_ctrl_rd_fifo_not_empty();
+ // TODO: if intr enabled, then check interrupt, else check status.
bit read_empty;
`DV_SPINWAIT(
do begin
@@ -149,12 +151,13 @@
// Program data into flash, stopping whenever full.
// The flash op is assumed to have already commenced.
- virtual task flash_ctrl_write(bit [TL_DW-1:0] data[$]);
+ virtual task flash_ctrl_write(bit [TL_DW-1:0] data[$], bit poll_fifo_status);
foreach (data[i]) begin
// Check if prog fifo is full. If yes, then wait for space to become available.
- // TODO: interface is backpressure enabled, so the above check is not needed atm.
- // TODO: if intr enabled, then check interrupt, else check status.
- // wait_flash_ctrl_prog_fifo_not_full();
+ // Note that this polling is not needed since the interface is backpressure enabled.
+ if (poll_fifo_status) begin
+ wait_flash_ctrl_prog_fifo_not_full();
+ end
mem_wr(.ptr(ral.prog_fifo), .offset(0), .data(data[i]));
`uvm_info(`gfn, $sformatf("flash_ctrl_write: 0x%0h", data[i]), UVM_MEDIUM)
end
@@ -162,12 +165,13 @@
// Read data from flash, stopping whenever empty.
// The flash op is assumed to have already commenced.
- virtual task flash_ctrl_read(uint num_words, ref bit [TL_DW-1:0] data[$]);
+ virtual task flash_ctrl_read(uint num_words, ref bit [TL_DW-1:0] data[$], bit poll_fifo_status);
for (int i = 0; i < num_words; i++) begin
// Check if rd fifo is empty. If yes, then wait for data to become available.
- // TODO: interface is backpressure enabled, so the above check is not needed atm.
- // TODO: if intr enabled, then check interrupt, else check status.
- // wait_flash_ctrl_rd_fifo_not_empty();
+ // Note that this polling is not needed since the interface is backpressure enabled.
+ if (poll_fifo_status) begin
+ wait_flash_ctrl_rd_fifo_not_empty();
+ end
mem_rd(.ptr(ral.rd_fifo), .offset(0), .data(data[i]));
`uvm_info(`gfn, $sformatf("flash_ctrl_read: 0x%0h", data[i]), UVM_MEDIUM)
end
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_vseq.sv
index 1dc1643..374da5a 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_rand_ops_vseq.sv
@@ -178,6 +178,18 @@
read_fifo_intr_level < flash_ctrl_pkg::FifoDepth;
}
+ // Indicates whether to poll before writing to prog_fifo or reading from rd_fifo. If interupts are
+ // enabled, the interrupt signals will be used instead. When set to 0, it will continuously write
+ // to prog_fifo / read from rd_fifo, relying on their natural backpressure mechanism.
+ rand bit poll_fifo_status;
+
+ constraint poll_fifo_status_c {
+ poll_fifo_status dist {
+ 0 :/ (100 - cfg.seq_cfg.poll_fifo_status_pc),
+ 1 :/ cfg.seq_cfg.poll_fifo_status_pc
+ };
+ }
+
`uvm_object_new
task body();
@@ -213,12 +225,14 @@
flash_ctrl_start_op(flash_op);
case (flash_op.op)
flash_ctrl_pkg::FlashOpRead: begin
- flash_ctrl_read(flash_op.num_words, flash_op_data);
+ `DV_CHECK_MEMBER_RANDOMIZE_FATAL(poll_fifo_status)
+ flash_ctrl_read(flash_op.num_words, flash_op_data, poll_fifo_status);
wait_flash_op_done();
flash_mem_bkdr_read_check(flash_op, flash_op_data);
end
flash_ctrl_pkg::FlashOpProgram: begin
- flash_ctrl_write(flash_op_data);
+ `DV_CHECK_MEMBER_RANDOMIZE_FATAL(poll_fifo_status)
+ flash_ctrl_write(flash_op_data, poll_fifo_status);
wait_flash_op_done();
flash_mem_bkdr_read_check(flash_op, flash_op_data);
end
diff --git a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_sanity_vseq.sv b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_sanity_vseq.sv
index f9899eb..b5f3711 100644
--- a/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_sanity_vseq.sv
+++ b/hw/ip/flash_ctrl/dv/env/seq_lib/flash_ctrl_sanity_vseq.sv
@@ -29,6 +29,8 @@
// Allow banks to be erased.
cfg.seq_cfg.bank_erase_en_pc = 100;
+
+ cfg.seq_cfg.poll_fifo_status_pc = 0;
endfunction
endclass : flash_ctrl_sanity_vseq