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

[DV/HMAC] hmac support config blocking and wr key #1023

Merged
merged 1 commit into from
Nov 21, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion hw/ip/hmac/dv/env/hmac_env_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ package hmac_env_pkg;
typedef enum {
NoError,
SwPushMsgWhenShaDisabled,
SwHashStartWhenShaDisabled
SwHashStartWhenShaDisabled,
SwUpdateSecretKeyInProcess
} err_code_e;

typedef class hmac_env_cfg;
Expand Down
81 changes: 47 additions & 34 deletions hw/ip/hmac/dv/env/hmac_scoreboard.sv
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ class hmac_scoreboard extends cip_base_scoreboard #(.CFG_T (hmac_env_cfg),
bit [7:0] msg_q[$];
bit hmac_start, hmac_process;
bit fifo_full;
bit wr_cnt_updated = 1; // flag to indicate if the msg is written to msg_fifo
int hmac_wr_cnt;
int hmac_rd_cnt;

Expand Down Expand Up @@ -66,14 +65,9 @@ class hmac_scoreboard extends cip_base_scoreboard #(.CFG_T (hmac_env_cfg),
msg = (ral.cfg.endian_swap.get_mirrored_value()) ? {bytes[i], msg} : {msg, bytes[i]};
end
end
foreach (msg[i]) begin
msg_q.push_back(msg[i]);
if (msg_q.size() % 4 == 0) incr_wr_and_check_fifo_full();
end
foreach (msg[i]) msg_q.push_back(msg[i]);
end
end else begin
// csr write: predict and update according to the csr names
void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask)));
case (csr.get_name())
"cmd": begin
if (sha_en) begin
Expand All @@ -82,8 +76,6 @@ class hmac_scoreboard extends cip_base_scoreboard #(.CFG_T (hmac_env_cfg),
// check if msg all streamed in, could happen during wr msg or trigger process
predict_digest(msg_q);
update_wr_msg_length(msg_q.size());
// any bytes left after hmac_process will be added to the wr_cnt
if (msg_q.size() % 4 != 0) incr_wr_and_check_fifo_full();
msg_q.delete();
end else if (hmac_start) begin
msg_q.delete(); // make sure did not include previous msg
Expand All @@ -99,12 +91,24 @@ class hmac_scoreboard extends cip_base_scoreboard #(.CFG_T (hmac_env_cfg),
void'(ral.intr_state.predict(.value(intr_state_exp), .kind(UVM_PREDICT_DIRECT)));
end
"cfg": begin
if (hmac_start) return; // won't update configs if hash start
if (cfg.en_cov) cov.cfg_cg.sample(item.a_data);
sha_en = item.a_data[ShaEn];
if (!sha_en) predict_digest(msg_q);
if (!sha_en) begin
void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask)));
predict_digest(msg_q);
return;
end
end
"key0", "key1", "key2", "key3", "key4", "key5", "key6", "key7": begin
if (hmac_start) begin
void'(ral.intr_state.hmac_err.predict(.value(1), .kind(UVM_PREDICT_DIRECT)));
void'(ral.err_code.predict(.value(SwUpdateSecretKeyInProcess),
.kind(UVM_PREDICT_DIRECT)));
return;
end
end
"wipe_secret", "key0", "key1", "key2", "key3", "key4", "key5", "key6", "key7",
"intr_enable", "intr_state": begin
"wipe_secret", "intr_enable", "intr_state": begin
// Do nothing
end
"digest0", "digest1", "digest2", "digest3", "digest4", "digest5", "digest6", "digest7",
Expand All @@ -116,6 +120,8 @@ class hmac_scoreboard extends cip_base_scoreboard #(.CFG_T (hmac_env_cfg),
`uvm_fatal(`gfn, $sformatf("invalid csr: %0s", csr.get_full_name()))
end
endcase
// csr write: predict and update according to the csr names
void'(csr.predict(.value(item.a_data), .kind(UVM_PREDICT_WRITE), .be(item.a_mask)));
end
end

Expand Down Expand Up @@ -209,7 +215,6 @@ class hmac_scoreboard extends cip_base_scoreboard #(.CFG_T (hmac_env_cfg),
sha_en = 0;
hmac_wr_cnt = 0;
hmac_rd_cnt = 0;
wr_cnt_updated = 1'b1;
endfunction

// clear variables after expected digest is calculated
Expand All @@ -219,18 +224,36 @@ class hmac_scoreboard extends cip_base_scoreboard #(.CFG_T (hmac_env_cfg),
msg_q.delete();
endfunction

virtual task incr_wr_and_check_fifo_full();
wait (wr_cnt_updated == 1 && !under_reset);
if (sha_en) begin
// if fifo full, tlul will not write next data until fifo has space again
if (fifo_full) begin
wait (hmac_wr_cnt - hmac_rd_cnt < HMAC_MSG_FIFO_DEPTH)
fifo_full = 0;
// hmac_wr_cnt was incremented every time when msg_q has 4 bytes streamed in
// or when hash_process is triggered, and there are some remaining bytes
virtual task hmac_process_fifo_wr();
fork
begin : insolation_fork_process_fifo_wr
forever begin
wait(!under_reset);
fork
begin : increase_wr_cnt
wait(msg_q.size() >= (hmac_wr_cnt + 1) * 4 || (hmac_process && msg_q.size() % 4 != 0));
if (sha_en) begin
// if fifo full, tlul will not write next data until fifo has space again
if (fifo_full) begin
wait(hmac_wr_cnt - hmac_rd_cnt < HMAC_MSG_FIFO_DEPTH)
fifo_full = 0;
end
@(negedge cfg.clk_rst_vif.clk);
hmac_wr_cnt++;
`uvm_info(`gfn, $sformatf("increase wr cnt %0d", hmac_wr_cnt), UVM_HIGH)
cfg.clk_rst_vif.wait_clks(HMAC_WR_WORD_CYCLE);
end
end
begin : reset_increase_wr_cnt
wait(under_reset);
end
join_any
disable fork;
end // end forever
end
@(negedge cfg.clk_rst_vif.clk);
hmac_wr_cnt++;
`uvm_info(`gfn, $sformatf("increase wr cnt %0d", hmac_wr_cnt), UVM_HIGH)
end
join
endtask

virtual task hmac_process_fifo_full();
Expand All @@ -246,16 +269,6 @@ class hmac_scoreboard extends cip_base_scoreboard #(.CFG_T (hmac_env_cfg),
end
endtask

// internal msg_fifo model will take 2 clk cycles to update write info.
// will gate the write process with wr_cnt_updated signal if user uses non-blocking mode
virtual task hmac_process_fifo_wr();
forever @(hmac_wr_cnt) begin
wr_cnt_updated = 0;
cfg.clk_rst_vif.wait_clks(HMAC_WR_WORD_CYCLE);
wr_cnt_updated = 1;
end
endtask

// internal msg_fifo model to check fifo status and interrupt.
// monitor rd_cnt and wr_cnt on the negedge of the clk
// rd_cnt followed by wr_cnt with a clk cycle delay, except:
Expand Down
30 changes: 30 additions & 0 deletions hw/ip/hmac/dv/env/seq_lib/hmac_base_vseq.sv
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,40 @@ class hmac_base_vseq extends cip_base_vseq #(.CFG_T (hmac_env_cfg)
cfg_interrupts(.interrupts(interrupts), .enable(1'b1));
endtask

virtual task write_discard_config_and_key(bit do_wr_config, bit do_wr_key);
if (do_wr_config) write_discard_config();
if (do_wr_key) begin
write_discard_key();
check_error_code();
end
endtask

// keep all the config values, but enable sha_en
virtual task sha_enable();
ral.cfg.sha_en.set(1'b1);
csr_update(.csr(ral.cfg));
endtask

// attempt to change config reg during msg write, design will ignore the change
virtual task write_discard_config();
bit [TL_DW-1:0] rand_config_value = $urandom();
csr_wr(ral.cfg, rand_config_value);
endtask

virtual task write_discard_key();
bit [TL_DW-1:0] rand_key_value = $urandom();
randcase
1: csr_wr(ral.key0, rand_key_value);
1: csr_wr(ral.key1, rand_key_value);
1: csr_wr(ral.key2, rand_key_value);
1: csr_wr(ral.key3, rand_key_value);
1: csr_wr(ral.key4, rand_key_value);
1: csr_wr(ral.key5, rand_key_value);
1: csr_wr(ral.key6, rand_key_value);
1: csr_wr(ral.key7, rand_key_value);
endcase
endtask

// trigger hash computation to start
virtual task trigger_hash();
csr_wr(.csr(ral.cmd), .value(1'b1 << HashStart));
Expand Down Expand Up @@ -184,6 +212,8 @@ class hmac_base_vseq extends cip_base_vseq #(.CFG_T (hmac_env_cfg)
if (ral.cfg.sha_en.get_mirrored_value()) begin
if (!do_back_pressure) check_status_intr_fifo_full();
else clear_intr_fifo_full();
// randomly change key, config regs during msg wr, should trigger error or be discarded
write_discard_config_and_key($urandom_range(0, 20) == 0, $urandom_range(0, 20) == 0);
end else begin
check_error_code();
end
Expand Down