[aes/dv] updated dv to support RTL changes
Signed-off-by: Rasmus Madsen <rasmus.madsen@wdc.com>
diff --git a/hw/ip/aes/data/aes_testplan.hjson b/hw/ip/aes/data/aes_testplan.hjson
index 94fd5cf..12a2272 100644
--- a/hw/ip/aes/data/aes_testplan.hjson
+++ b/hw/ip/aes/data/aes_testplan.hjson
@@ -85,7 +85,7 @@
Exercise trigger and clear registers at random times to make sure we handle the different cornercases correctly.
Example of a cornercases clearing data input or data output before the data is consumed or the DUT finishes an operation.'''
milestone: V2
- tests: []
+ tests: ["aes_clear"]
}
{
name: nist_test_vectors
diff --git a/hw/ip/aes/dv/env/aes_env_pkg.sv b/hw/ip/aes/dv/env/aes_env_pkg.sv
index 0881587..a3f1294 100644
--- a/hw/ip/aes/dv/env/aes_env_pkg.sv
+++ b/hw/ip/aes/dv/env/aes_env_pkg.sv
@@ -28,10 +28,8 @@
typedef enum int { AES_CFG=0, AES_DATA=1, AES_ERR_INJ=2 } aes_item_type_e;
typedef struct packed {
- bit data_out;
- bit data_in;
- bit iv;
- bit key;
+ bit dataout;
+ bit key_iv_data_in;
} clear_t;
typedef struct packed {
diff --git a/hw/ip/aes/dv/env/aes_message_item.sv b/hw/ip/aes/dv/env/aes_message_item.sv
index 8369a0e..a952de2 100644
--- a/hw/ip/aes/dv/env/aes_message_item.sv
+++ b/hw/ip/aes/dv/env/aes_message_item.sv
@@ -199,8 +199,6 @@
output_cleared = { output_cleared, item.data_was_cleared, item.data_was_cleared,
item.data_was_cleared, item.data_was_cleared};
end
-
-
endfunction // add_data_item
diff --git a/hw/ip/aes/dv/env/aes_scoreboard.sv b/hw/ip/aes/dv/env/aes_scoreboard.sv
index ff75e85..af66900 100644
--- a/hw/ip/aes/dv/env/aes_scoreboard.sv
+++ b/hw/ip/aes/dv/env/aes_scoreboard.sv
@@ -88,22 +88,23 @@
case (1)
// add individual case item for each csr
(!uvm_re_match("ctrl_shadowed", csr_name)): begin
- input_item.manual_op = item.a_data[10];
- input_item.key_len = item.a_data[9:7];
- `downcast(input_item.operation, item.a_data[0]);
- input_item.valid = 1'b1;
- case (item.a_data[6:1])
- 6'b00_0001: input_item.mode = AES_ECB;
- 6'b00_0010: input_item.mode = AES_CBC;
- 6'b00_0100: input_item.mode = AES_CFB;
- 6'b00_1000: input_item.mode = AES_OFB;
- 6'b01_0000: input_item.mode = AES_CTR;
- 6'b10_0000: input_item.mode = AES_NONE;
- default: input_item.mode = AES_NONE;
- endcase // case item.a_data[4:1]
- input_item.clean();
- input_item.start_item = 1;
-
+ if (write) begin
+ input_item.manual_op = item.a_data[10];
+ input_item.key_len = item.a_data[9:7];
+ `downcast(input_item.operation, item.a_data[0]);
+ input_item.valid = 1'b1;
+ case (item.a_data[6:1])
+ 6'b00_0001: input_item.mode = AES_ECB;
+ 6'b00_0010: input_item.mode = AES_CBC;
+ 6'b00_0100: input_item.mode = AES_CFB;
+ 6'b00_1000: input_item.mode = AES_OFB;
+ 6'b01_0000: input_item.mode = AES_CTR;
+ 6'b10_0000: input_item.mode = AES_NONE;
+ default: input_item.mode = AES_NONE;
+ endcase // case item.a_data[4:1]
+ input_item.clean();
+ input_item.start_item = 1;
+ end
end
(!uvm_re_match("key_share0*", csr_name)): begin
@@ -161,9 +162,10 @@
// this is seen as the beginning of a new message
if (!input_item.start_item) begin
input_item.start_item = 1;
+ input_item.split_item = 1;
`uvm_info(`gfn, $sformatf("splitting message"), UVM_MEDIUM)
end
- `uvm_info(`gfn, $sformatf("\n\t ----clearing KEY"), UVM_MEDIUM)
+ `uvm_info(`gfn, $sformatf("\n\t ----| clearing KEY"), UVM_MEDIUM)
`uvm_info(`gfn, $sformatf("\n\t ----| clearing IV"), UVM_MEDIUM)
`uvm_info(`gfn, $sformatf("\n\t ----| clearing DATA_IN"), UVM_MEDIUM)
end
@@ -293,8 +295,8 @@
end
end else begin
// verify that all 4 data_in and all 8 and all 4 IV key are clean
- `uvm_info(`gfn, $sformatf("\n\t ----|data_inv_vld? %b, key clean ? %b",input_item.data_in_valid(), input_item.key_clean(1,0)),
- UVM_MEDIUM)
+ `uvm_info(`gfn, $sformatf("\n\t ----|data_inv_vld? %b, key clean ? %b",input_item.data_in_valid(),
+ input_item.key_clean(1,0)),UVM_MEDIUM)
if (input_item.data_in_valid() && input_item.key_clean(1,0) && input_item.iv_clean(1,0)) begin
//clone and add to ref and rec data fifo
ok_to_fwd = 1;
@@ -312,10 +314,16 @@
if (ok_to_fwd) begin
ok_to_fwd = 0;
`downcast(input_clone, input_item.clone());
- `uvm_info(`gfn, $sformatf("\n\t AES INPUT ITEM RECEIVED - \n %s", input_clone.convert2string()),
+ `uvm_info(`gfn, $sformatf("\n\t AES INPUT ITEM RECEIVED - \n %s \n\t split message: %0b",
+ input_clone.convert2string(), input_clone.split_item),
UVM_MEDIUM)
rcv_item_q.push_front(input_clone);
input_item.clean();
+ // only reset the split here
+ // in the case the reset comes after data input
+ // having it in clean will reset it when the ctrl
+ // is written
+ input_item.split_item = 0;
end
end
@@ -356,6 +364,10 @@
// and no output is ready
// there won't be a response for this item
// reset/clear was triggered
+ `uvm_info(`gfn, $sformatf("\n\t ---| Status read: \n\t idle %0b \n\t output lost %0b ",
+ get_field_val(ral.status.idle, item.d_data),
+ get_field_val(ral.status.output_lost, item.d_data)), UVM_MEDIUM)
+
if (get_field_val(ral.status.idle, item.d_data) &&
get_field_val(ral.status.output_lost, item.d_data)) begin
if (rcv_item_q.size() != 0) begin
@@ -366,7 +378,7 @@
end
endcase // case (csr.get_name())
- if (output_item.data_out_valid()) begin
+ if (output_item.data_out_valid() || output_item.data_was_cleared) begin
// if data_out is read multipletimes in a row we should not pop input more than once
if (rcv_item_q.size() == 0) begin
output_item = new();
@@ -375,6 +387,13 @@
complete_item = rcv_item_q.pop_back();
complete_item.data_out = output_item.data_out;
complete_item.data_was_cleared = output_item.data_was_cleared;
+ // if message was split and data was read out.
+ // we will have one more message than expected.
+ if (complete_item.split_item) begin
+ cfg.split_cnt++;
+ `uvm_info(`gfn, $sformatf("\n\t ----| incrementing split count now at: %d",
+ cfg.split_cnt), UVM_MEDIUM)
+ end
`downcast(complete_clone, complete_item.clone());
item_fifo.put(complete_clone);
@@ -495,7 +514,7 @@
`uvm_fatal(`gfn, $sformatf(" # %0d \n\t %s \n", good_cnt, txt))
end
end
- `uvm_info(`gfn, $sformatf("\n\t ----| MESSAGE #%0d MATCHED |-----", good_cnt),
+ `uvm_info(`gfn, $sformatf("\n\t ----| MESSAGE #%0d MATCHED %s |-----", good_cnt, msg.aes_mode.name() ),
UVM_MEDIUM)
good_cnt++;
end else begin
@@ -534,6 +553,8 @@
virtual task wait_fifo_empty();
`uvm_info(`gfn, $sformatf("item fifo entries %d", item_fifo.num()), UVM_MEDIUM)
+ `uvm_info(`gfn, $sformatf("rcv_queue entries %d", rcv_item_q.size()), UVM_MEDIUM)
+ `uvm_info(`gfn, $sformatf("msg fifo entries %d", msg_fifo.num()), UVM_MEDIUM)
wait (rcv_item_q.size() == 0);
wait (item_fifo.num() == 0);
wait (msg_fifo.num() == 0);
diff --git a/hw/ip/aes/dv/env/aes_seq_item.sv b/hw/ip/aes/dv/env/aes_seq_item.sv
index 3cac6a5..d27f2b2 100644
--- a/hw/ip/aes/dv/env/aes_seq_item.sv
+++ b/hw/ip/aes/dv/env/aes_seq_item.sv
@@ -62,6 +62,8 @@
// indicate message start in manual mode
bit start_item = 0;
+ // indicate a message was split in two with this item.
+ bit split_item = 0;
///////////////////////////////////////
@@ -104,10 +106,8 @@
clr_reg_dist_select == 0 -> clear_reg == 0;
clr_reg_dist_select == 1 -> $countones(clear_reg) > 1;
- clr_reg_dist_select == 2 -> clear_reg dist { 1 :/ clear_reg_pct/4,
- 2 :/ clear_reg_pct/4,
- 4 :/ clear_reg_pct/4,
- 8 :/ clear_reg_pct/4
+ clr_reg_dist_select == 2 -> clear_reg dist { 1 :/ clear_reg_pct/2,
+ 2 :/ clear_reg_pct/2
};
}
@@ -259,7 +259,7 @@
iv_vld = '0;
key_vld = '{default: '0};
data_out_vld = '0;
- start_item = 0;
+ start_item = 0;
endfunction // clean
@@ -285,6 +285,7 @@
aes_mode = rhs_.aes_mode;
clear_reg = rhs_.clear_reg;
start_item = rhs_.start_item;
+ split_item = rhs_.split_item;
data_was_cleared = rhs_.data_was_cleared;
endfunction // copy
diff --git a/hw/ip/aes/dv/env/seq_lib/aes_base_vseq.sv b/hw/ip/aes/dv/env/seq_lib/aes_base_vseq.sv
index 12e9bac..ebd4a66 100644
--- a/hw/ip/aes/dv/env/seq_lib/aes_base_vseq.sv
+++ b/hw/ip/aes/dv/env/seq_lib/aes_base_vseq.sv
@@ -62,17 +62,14 @@
virtual task clear_regs(clear_t clr_vector);
string txt="";
bit [TL_DW:0] reg_val = '0;
-
- txt = $sformatf("\n data_out: \t %0b", clr_vector.data_out);
- txt = {txt, $sformatf("\n data_in: \t %0b", clr_vector.data_in)};
- txt = {txt, $sformatf("\n data_iv: \t %0b", clr_vector.iv)};
- txt = {txt, $sformatf("\n data_key: \t %0b", clr_vector.key)};
+ txt = {txt, $sformatf("\n data_out: \t %0b", clr_vector.dataout)};
+ txt = {txt, $sformatf("\n key_iv_data_in: \t %0b", clr_vector.key_iv_data_in)};
txt = {txt, $sformatf("\n vector: \t %0b", clr_vector)};
`uvm_info(`gfn, $sformatf("%s",txt), UVM_MEDIUM)
ral.trigger.set(0);
- ral.trigger.key_iv_data_in_clear.set(|clr_vector[2:0]);
- ral.trigger.data_out_clear.set(clr_vector.data_out);
+ ral.trigger.key_iv_data_in_clear.set(clr_vector.key_iv_data_in);
+ ral.trigger.data_out_clear.set(clr_vector.dataout);
csr_update(ral.trigger);
endtask // clear_registers
@@ -98,7 +95,6 @@
virtual task set_key_len(bit [2:0] key_len);
ral.ctrl_shadowed.key_len.set(key_len);
- `uvm_info(`gfn, $sformatf("Writing Key LEN: %b", key_len), UVM_LOW)
csr_update(.csr(ral.ctrl_shadowed), .en_shadow_wr(1'b1), .blocking(1));
endtask
@@ -368,6 +364,7 @@
// the manual operation should be included in the unbalanced =1 also
if (new_msg) setup_dut(cfg_item);
if (unbalanced == 0 || manual_operation) begin
+ data_item = new();
while (aes_item_queue.size() > 0) begin
status_fsm(cfg_item, data_item, new_msg, manual_operation, 0, status);
if (status.input_ready) begin
@@ -381,6 +378,8 @@
end
end else begin
+ data_item = new();
+
while ((aes_item_queue.size() > 0) || (read_queue.size() > 0)) begin
// get the status to make sure we can provide data - but don't wait for output //
status_fsm(cfg_item, data_item, new_msg, manual_operation, 0, status);
@@ -467,6 +466,7 @@
bit done = 0;
string txt = "";
+ txt = "\n Entering FSM";
// enable get status when provided with an empty Item.
if (data_item.mode === 'X) begin
csr_rd(.ptr(ral.status), .value(status), .blocking(is_blocking));
@@ -476,6 +476,7 @@
while(!done && (data_item.mode != AES_NONE)) begin
//read the status register to see that we have triggered the operation
csr_rd(.ptr(ral.status), .value(status), .blocking(is_blocking));
+ txt = {txt, "\n ----|reading STATUS", status2string(status)};
// check status and act accordingly //
if (status.alert_fatal_fault) begin
// stuck pull reset //
@@ -485,9 +486,12 @@
if (status.output_valid && read_output) begin
read_data(data_item.data_out, is_blocking);
txt = {txt, $sformatf("\n\t ----| status state 0 ")};
+ done = 1;
+ end else if (!read_output) begin
+ done = 1; // get more data
+ end else begin
+ try_recover(cfg_item, data_item, manual_operation);
end
- done = 1;
-
end else if (status.idle && !status.input_ready) begin
// state 1 //
// if data ready just read and return
@@ -497,30 +501,9 @@
end else begin
// if data is not ready the DUT is missing
// KEY and IV - or the configuration
- csr_rd(.ptr(ral.ctrl_shadowed), .value(ctrl), .blocking(is_blocking));
- ral.ctrl_shadowed.operation.set(cfg_item.operation);
- ral.ctrl_shadowed.mode.set(cfg_item.mode);
- ral.ctrl_shadowed.key_len.set(cfg_item.key_len);
- ral.ctrl_shadowed.manual_operation.set(cfg_item.manual_op);
-
- if (ral.ctrl_shadowed.get_mirrored_value() != ctrl) begin
- `uvm_info(`gfn, $sformatf("\n\t ----| configuration does not match actual - re-confguring"), UVM_LOW)
- txt = { txt, $sformatf("\n\t ----| configuration does not match actual - re-confguring")};
- csr_update(.csr(ral.ctrl_shadowed), .en_shadow_wr(1'b1), .blocking(is_blocking));
- end else begin
- // key and IV missing clear all and rewrite (a soon to come update will merge
- // the clear options into a single bit)
- clear_regs(4'b1111);
- // wait for idle
- csr_spinwait(.ptr(ral.status.idle) , .exp_data(1'b1));
- write_key(cfg_item.key, is_blocking);
- write_iv(cfg_item.iv, is_blocking);
- add_data(data_item.data_in, is_blocking);
- if (manual_operation) trigger();
- end
+ try_recover(cfg_item, data_item, manual_operation);
txt = {txt, $sformatf("\n\t ----| status state 1 ")};
end
-
end else if (status.output_valid) begin
// state 2 //
// data ready to be read out
@@ -549,13 +532,42 @@
txt = {txt, $sformatf("\n ----| OUTPUT_VALID %0b",status.output_valid)};
`uvm_fatal(`gfn, $sformatf("\n\t %s",txt))
end
- `uvm_info(`gfn, $sformatf("\n\t %s",txt), UVM_MEDIUM)
end // else: !if(status.alert_fatal_fault)
end // while (!done)
-
+ `uvm_info(`gfn, $sformatf("\n\t %s",txt), UVM_MEDIUM)
endtask // transmit_fsm
+ virtual task try_recover(
+ aes_seq_item cfg_item, // sequence item with configuraton
+ aes_seq_item data_item, // sequence item with data to process
+ bit manual_operation
+ );
+ // if data is not ready the DUT is missing
+ // KEY and IV - or the configuration
+ ctrl_reg_t ctrl;
+ bit is_blocking = ~cfg_item.do_b2b;
+
+ csr_rd(.ptr(ral.ctrl_shadowed), .value(ctrl), .blocking(is_blocking));
+ ral.ctrl_shadowed.operation.set(cfg_item.operation);
+ ral.ctrl_shadowed.mode.set(cfg_item.mode);
+ ral.ctrl_shadowed.key_len.set(cfg_item.key_len);
+ ral.ctrl_shadowed.manual_operation.set(cfg_item.manual_op);
+ // key and IV missing clear all and rewrite (a soon to come update will merge
+ // the clear options into a single bit)
+
+ clear_regs(2'b11);
+ // wait for idle
+ csr_spinwait(.ptr(ral.status.idle), .exp_data(1'b1));
+ csr_update(.csr(ral.ctrl_shadowed), .en_shadow_wr(1'b1), .blocking(is_blocking));
+ csr_spinwait(.ptr(ral.status.idle), .exp_data(1'b1));
+ write_key(cfg_item.key, is_blocking);
+ write_iv(cfg_item.iv, is_blocking);
+ add_data(data_item.data_in, is_blocking);
+ if (manual_operation) trigger();
+ endtask // try_recover
+
+
virtual task send_msg_queue (
bit unbalanced, // uses the probablilites to randomize if we read or write
int read_prob, // chance of reading an availabout output
@@ -657,4 +669,18 @@
`uvm_info(`gfn, $sformatf("%s", print_item.convert2string()), UVM_MEDIUM)
end
endfunction // aes_print_item_queue
+
+
+ function string status2string(status_t status);
+ string txt="";
+ txt ={txt, $sformatf("\n\t ---| IDLE: %0b", status.idle)};
+ txt ={txt, $sformatf("\n\t ---| STALL: %0b", status.stall)};
+ txt ={txt, $sformatf("\n\t ---| Output Lost: %0b", status.output_lost)};
+ txt ={txt, $sformatf("\n\t ---| Output Valid: %0b", status.output_valid)};
+ txt ={txt, $sformatf("\n\t ---| Input Ready: %0b", status.input_ready)};
+ txt ={txt, $sformatf("\n\t ---| Alert - Recov: %0b", status.alert_recov_ctrl_update_err)};
+ txt ={txt, $sformatf("\n\t ---| Alert -Fatal: %0b", status.alert_fatal_fault)};
+ return txt;
+ endfunction // status2string
+
endclass : aes_base_vseq
diff --git a/hw/ip/aes/dv/tests/aes_clear_test.sv b/hw/ip/aes/dv/tests/aes_clear_test.sv
index 3fdf30f..28f5387 100644
--- a/hw/ip/aes/dv/tests/aes_clear_test.sv
+++ b/hw/ip/aes/dv/tests/aes_clear_test.sv
@@ -43,7 +43,7 @@
cfg.fixed_iv_en = 0;
cfg.random_data_key_iv_order = 1;
- cfg.clear_reg_pct = 100;
+ cfg.clear_reg_pct = 80;
`DV_CHECK_RANDOMIZE_FATAL(cfg)
endfunction