[uart/dv] Fix a corner issue
When tx starts, tx watermark needs 3 cycles to update the value
Signed-off-by: Weicai Yang <weicai@google.com>
diff --git a/hw/ip/uart/dv/env/uart_scoreboard.sv b/hw/ip/uart/dv/env/uart_scoreboard.sv
index 421d22a..f82550e 100644
--- a/hw/ip/uart/dv/env/uart_scoreboard.sv
+++ b/hw/ip/uart/dv/env/uart_scoreboard.sv
@@ -39,6 +39,10 @@
uart_item tx_processing_item_q[$];
uart_item rx_q[$];
+ // it takes 3 cycles to move item from fifo to process, which delays reg status change
+ // and it also takes 3 cycles to trigger tx matermark interrupt
+ parameter uint NUM_CLK_DLY_TO_UPDATE_TX_WATERMARK = 3;
+
bit obj_raised = 1'b0;
`uvm_component_new
@@ -142,9 +146,10 @@
virtual function void predict_rx_watermark_intr(uint rx_q_size = rx_q.size);
uint watermark = get_watermark_bytes_by_level(ral.fifo_ctrl.rxilvl.get_mirrored_value(),
UartRx);
- intr_exp[RxWatermark] = get_non_sticky_interrupt(.cur_intr(intr_exp[RxWatermark]),
- .new_intr(rx_q_size >= watermark && rx_enabled),
- .triggered(rx_watermark_triggered));
+ intr_exp[RxWatermark] = get_non_sticky_interrupt(
+ .cur_intr(intr_exp[RxWatermark]),
+ .new_intr(rx_q_size >= watermark && rx_enabled),
+ .triggered(rx_watermark_triggered));
endfunction
// we don't model uart cycle-acurrately, ignore checking when item is just/almost finished
@@ -195,7 +200,10 @@
if ((tx_q.size > 0 || tx_processing_item_q.size > 0) && tx_enabled) begin
if (tx_q.size > 0 && tx_processing_item_q.size == 0) begin
tx_processing_item_q.push_back(tx_q.pop_front());
- predict_tx_watermark_intr();
+ fork begin
+ cfg.clk_rst_vif.wait_n_clks(NUM_CLK_DLY_TO_UPDATE_TX_WATERMARK);
+ predict_tx_watermark_intr();
+ end join_none
end
process_objections(1'b1);
end
@@ -204,7 +212,7 @@
"wdata": begin
// if tx is enabled, push exp tx data to q
if (write && channel == AddrChannel) begin
- uart_item tx_item = uart_item::type_id::create("tx_item");;
+ uart_item tx_item = uart_item::type_id::create("tx_item");
tx_item.data = item.a_data;
if (tx_q.size() < UART_FIFO_DEPTH) begin
@@ -215,10 +223,9 @@
"Drop tx item: %0h, tx_q size: %0d, uart_tx_clk_pulses: %0d",
csr.get_mirrored_value(), tx_q.size(), uart_tx_clk_pulses), UVM_MEDIUM)
end
- // it takes 3 cycles to move item from fifo to process, which delays reg status change
- // and it also takes 3 cycles to trigger tx matermark interrupt
fork begin
- cfg.clk_rst_vif.wait_n_clks(3); // use negedge to avoid race condition
+ // use negedge to avoid race condition
+ cfg.clk_rst_vif.wait_n_clks(NUM_CLK_DLY_TO_UPDATE_TX_WATERMARK);
if (ral.ctrl.slpbk.get_mirrored_value()) begin
// if sys loopback is on, tx item isn't sent to uart pin but rx fifo
uart_item tx_item = tx_q.pop_front();