[dv/kmac] kmac_burst_write test
This PR implements the kmac_burst_wr test as described in the testplan.
Signed-off-by: Udi Jonnalagadda <udij@google.com>
diff --git a/hw/ip/kmac/data/kmac_base_testplan.hjson b/hw/ip/kmac/data/kmac_base_testplan.hjson
index 0caa858..02b16e8 100644
--- a/hw/ip/kmac/data/kmac_base_testplan.hjson
+++ b/hw/ip/kmac/data/kmac_base_testplan.hjson
@@ -54,13 +54,13 @@
tests: ["{name}_long_msg_and_output"]
}
{
- name: burst_wr
+ name: burst_write
desc: '''
This is the same as the long_message test, except we burst-write chunks of the message
into the msg_fifo, and disable intermediate status/CSR checks.
'''
milestone: V2
- tests: ["{name}_burst_wr"]
+ tests: ["{name}_burst_write"]
}
{
name: test_vectors
diff --git a/hw/ip/kmac/dv/env/kmac_env.core b/hw/ip/kmac/dv/env/kmac_env.core
index ff99fc8..65dcb11 100644
--- a/hw/ip/kmac/dv/env/kmac_env.core
+++ b/hw/ip/kmac/dv/env/kmac_env.core
@@ -33,6 +33,7 @@
- seq_lib/kmac_test_vectors_shake_vseq.sv: {is_include_file: true}
- seq_lib/kmac_test_vectors_kmac_vseq.sv: {is_include_file: true}
- seq_lib/kmac_test_vectors_kmac_xof_vseq.sv: {is_include_file: true}
+ - seq_lib/kmac_burst_write_vseq.sv: {is_include_file: true}
file_type: systemVerilogSource
generate:
diff --git a/hw/ip/kmac/dv/env/kmac_env_pkg.sv b/hw/ip/kmac/dv/env/kmac_env_pkg.sv
index e44e5e7..aebe938 100644
--- a/hw/ip/kmac/dv/env/kmac_env_pkg.sv
+++ b/hw/ip/kmac/dv/env/kmac_env_pkg.sv
@@ -45,6 +45,16 @@
parameter bit [TL_AW-1:0] KMAC_FIFO_BASE = 32'h800;
parameter bit [TL_AW-1:0] KMAC_FIFO_END = 32'hFFC;
+ // width and depth of the msgfifo
+ parameter int KMAC_FIFO_DEPTH = kmac_pkg::MsgFifoDepth;
+ parameter int KMAC_FIFO_WIDTH = kmac_pkg::MsgWidth;
+
+ parameter int KMAC_FIFO_WORDS_PER_ENTRY = KMAC_FIFO_WIDTH / TL_DW;
+
+ parameter int KMAC_FIFO_NUM_WORDS = KMAC_FIFO_DEPTH * KMAC_FIFO_WORDS_PER_ENTRY;
+
+ parameter int KMAC_FIFO_NUM_BYTES = KMAC_FIFO_NUM_WORDS * 4;
+
// Represents the max bit-width of some value to be encoded with either
// `right_encode()` or `left_encode()`.
parameter int MAX_ENCODE_WIDTH = 2040;
diff --git a/hw/ip/kmac/dv/env/seq_lib/kmac_base_vseq.sv b/hw/ip/kmac/dv/env/seq_lib/kmac_base_vseq.sv
index b721030..3563484 100644
--- a/hw/ip/kmac/dv/env/seq_lib/kmac_base_vseq.sv
+++ b/hw/ip/kmac/dv/env/seq_lib/kmac_base_vseq.sv
@@ -241,7 +241,9 @@
endtask
virtual function string convert2string();
- return {$sformatf("enable_intr: %0p\n", enable_intr),
+ return {$sformatf("intr_en[KmacDone]: %0b\n", enable_intr[KmacDone]),
+ $sformatf("intr_en[KmacFifoEmpty]: %0b\n", enable_intr[KmacFifoEmpty]),
+ $sformatf("intr_en[KmacErr]: %0b\n", enable_intr[KmacErr]),
$sformatf("kmac_en: %0b\n", kmac_en),
$sformatf("xof_en: %0b\n", xof_en),
$sformatf("hash_mode: %0s\n", hash_mode.name()),
@@ -511,6 +513,60 @@
// TODO: final csr checks might be needed
endtask
+ // This task burst writes 32-bit chunks of the message into the msgfifo
+ virtual task burst_write_msg(bit [7:0] msg_arr[]);
+ bit [TL_DW-1:0] data_word;
+ bit [7:0] msg_q[$];
+
+ if (msg_endian) dv_utils_pkg::endian_swap_byte_arr(msg_arr);
+
+ msg_q = msg_arr;
+
+ `uvm_info(`gfn, $sformatf("initial msg: %0p", msg_q), UVM_HIGH)
+
+ while (msg_q.size() > 0) begin
+ `uvm_info(`gfn, $sformatf("msg size: %0d", msg_q.size()), UVM_HIGH)
+
+ if (msg_q.size() >= KMAC_FIFO_NUM_BYTES) begin
+ repeat (KMAC_FIFO_NUM_WORDS) begin
+ `DV_CHECK_MEMBER_RANDOMIZE_FATAL(fifo_addr)
+ `DV_CHECK_MEMBER_RANDOMIZE_WITH_FATAL(data_mask, data_mask == '1;)
+
+ for (int i = 0; i < TL_DBW; i++) begin
+ data_word[i*8 +: 8] = msg_q.pop_front();
+ `uvm_info(`gfn, $sformatf("intermediate data_word: 0x%0x", data_word), UVM_HIGH)
+ end
+
+ // print some debug info before performing the TLUL write
+ `uvm_info(`gfn, $sformatf("msg_size: %0d", msg_q.size()), UVM_HIGH)
+ `uvm_info(`gfn, $sformatf("fifo_addr = 0x%0x", fifo_addr), UVM_HIGH)
+ `uvm_info(`gfn, $sformatf("data_word = 0x%0x", data_word), UVM_HIGH)
+ `uvm_info(`gfn, $sformatf("data_mask = 0x%0x", data_mask), UVM_HIGH)
+
+ tl_access(.addr(ral.get_addr_from_offset(fifo_addr)),
+ .write(1),
+ .data(data_word),
+ .mask(data_mask),
+ .blocking($urandom_range(0, 1)));
+ end
+ // wait for the fifo to be empty before writing more msg
+ //
+ // spinwait instead of checking the interrupt because it's not guaranteed
+ // that the interrupt will remain high after writing the last word,
+ // depending on how long the input message is.
+ csr_spinwait(.ptr(ral.status.fifo_empty), .exp_data(1));
+ end else begin
+ // if we reach this case, means that the remaining message
+ // is smaller in size than the fifo, so we can just write it normally
+ // using `write_msg()`.
+ write_msg(msg_q);
+ break;
+ end
+ end
+ // wait for all fifo accesses to complete
+ wait_no_outstanding_access();
+ endtask
+
// This task checks the fifo_empty interrupt (if enabled) and clears it,
// then waits for STATUS.fifo_full to be 0.
virtual task wait_fifo_has_capacity();
diff --git a/hw/ip/kmac/dv/env/seq_lib/kmac_burst_write_vseq.sv b/hw/ip/kmac/dv/env/seq_lib/kmac_burst_write_vseq.sv
new file mode 100644
index 0000000..aa31a51
--- /dev/null
+++ b/hw/ip/kmac/dv/env/seq_lib/kmac_burst_write_vseq.sv
@@ -0,0 +1,15 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+class kmac_burst_write_vseq extends kmac_long_msg_and_output_vseq;
+
+ `uvm_object_utils(kmac_burst_write_vseq)
+ `uvm_object_new
+
+ virtual task pre_start();
+ burst_write = 1;
+ super.pre_start();
+ endtask
+
+endclass
diff --git a/hw/ip/kmac/dv/env/seq_lib/kmac_smoke_vseq.sv b/hw/ip/kmac/dv/env/seq_lib/kmac_smoke_vseq.sv
index 761da6a..1fd6e20 100644
--- a/hw/ip/kmac/dv/env/seq_lib/kmac_smoke_vseq.sv
+++ b/hw/ip/kmac/dv/env/seq_lib/kmac_smoke_vseq.sv
@@ -8,6 +8,9 @@
`uvm_object_utils(kmac_smoke_vseq)
`uvm_object_new
+ // Set this bit if we want to burst write the message into the msgfifo
+ bit burst_write = 0;
+
// TODO: 200 is chosen as upper bound due to large configuration space for KMAC.
// If this large range causes noticeable simulation slowdown, reduce it.
constraint num_trans_c {
@@ -117,7 +120,11 @@
// write the message into msgfifo
`uvm_info(`gfn, $sformatf("msg: %0p", msg), UVM_HIGH)
- write_msg(msg);
+ if (burst_write) begin
+ burst_write_msg(msg);
+ end else begin
+ write_msg(msg);
+ end
// if using KMAC, need to write either encoded output length or 0 to msgfifo
if (kmac_en) begin
diff --git a/hw/ip/kmac/dv/env/seq_lib/kmac_vseq_list.sv b/hw/ip/kmac/dv/env/seq_lib/kmac_vseq_list.sv
index 6580c48..4da7714 100644
--- a/hw/ip/kmac/dv/env/seq_lib/kmac_vseq_list.sv
+++ b/hw/ip/kmac/dv/env/seq_lib/kmac_vseq_list.sv
@@ -12,3 +12,4 @@
`include "kmac_test_vectors_shake_vseq.sv"
`include "kmac_test_vectors_kmac_vseq.sv"
`include "kmac_test_vectors_kmac_xof_vseq.sv"
+`include "kmac_burst_write_vseq.sv"
diff --git a/hw/ip/kmac/dv/kmac_base_sim_cfg.hjson b/hw/ip/kmac/dv/kmac_base_sim_cfg.hjson
index 3a33da6..1fd24c0 100644
--- a/hw/ip/kmac/dv/kmac_base_sim_cfg.hjson
+++ b/hw/ip/kmac/dv/kmac_base_sim_cfg.hjson
@@ -81,6 +81,10 @@
uvm_test_seq: kmac_sideload_vseq
}
{
+ name: "{variant}_burst_write"
+ uvm_test_seq: kmac_burst_write_vseq
+ }
+ {
name: "{variant}_test_vectors_sha3_224"
uvm_test_seq: kmac_test_vectors_sha3_vseq
run_opts: ["+test_vectors_dir={build_dir}/src/lowrisc_dv_test_vectors_0",