blob: b97be1499692b077aba88f729775245140601a9d [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
class aes_env_cfg extends cip_base_env_cfg #(.RAL_T(aes_reg_block));
`uvm_object_utils_begin(aes_env_cfg)
`uvm_object_utils_end
`uvm_object_new
virtual pins_if #($bits(lc_ctrl_pkg::lc_tx_t) + 1) lc_escalate_vif;
virtual pins_if #(1) idle_vif;
virtual aes_reseed_if aes_reseed_vif;
virtual aes_masking_reseed_if aes_masking_reseed_vif;
virtual force_if#(.Signal("aes_ctrl_cs"),
.SignalWidth(aes_env_pkg::StateWidth)
) aes_fi_vif[Sp2VWidth];
virtual force_if#(.Signal("aes_cipher_ctrl_cs"),
.SignalWidth(aes_env_pkg::StateWidth)
) aes_cipher_fi_vif[Sp2VWidth];
virtual force_if#(.Signal("aes_ctr_cs"),
.SignalWidth(aes_env_pkg::StateWidth)
) aes_ctr_fi_vif[Sp2VWidth];
virtual fi_control_if aes_control_fi_vif[Sp2VWidth];
virtual fi_cipher_if aes_cipher_control_fi_vif[Sp2VWidth];
virtual fi_ctr_fsm_if aes_ctr_fsm_fi_vif[Sp2VWidth];
virtual fi_core_if aes_core_fi_vif;
rand key_sideload_agent_cfg keymgr_sideload_agent_cfg;
// test environment constraints //
typedef enum { VerySlow, Slow, Fast, VeryFast } tl_ul_access_e;
// Message Knobs //
int num_messages_min = 1;
int num_messages_max = 1;
int message_len_min = 128;
int message_len_max = 128;
bit use_key_mask = 0;
bit use_c_model_pct = 0;
// clear registers with 0's or rand
bit clear_reg_w_rand = 1;
// if set the order of which key iv and data is written will be randomized and interleaved
bit random_data_key_iv_order = 1;
// Mode distribution //
// There are 5 modes (ecb, cbc, ofb, cfb, ctr). The weight for mode X is called X_weight. By
// default, all weights are set equal at 10 (so each is selected 10/50 = 20% of the time).
int ecb_weight = 10;
int cbc_weight = 10;
int ofb_weight = 10;
int cfb_weight = 10;
int ctr_weight = 10;
// KEYLEN weights
// change of selecting 128b key
// 128b/(128+192+256) = 10/30 = (33%)
int key_128b_weight = 10;
int key_192b_weight = 10;
int key_256b_weight = 10;
// reseed weigth
int per8_weight = 60;
int per64_weight = 30;
int per8k_weight = 10;
// use manual operation mode percentage
int manual_operation_pct = 10;
// enable reseed on key touch
int reseed_en = 1;
// debug / directed test knobs
// use fixed key
bit fixed_key_en = 0;
// use fixed data (same data for each block in a message)
bit fixed_data_en = 0;
// fixed operation
bit fixed_operation_en = 0;
bit fixed_operation = 1'b0;
// fixed iv (will set all to bits 0)
bit fixed_iv_en = 0;
bit fixed_keylen_en = 0;
bit [2:0] fixed_keylen = 3'b001;
// [0]: configuration errors
// [1]: malicous injection
// [2]: random resets
// [3]: inject Lc_escalate
error_types_t error_types = 4'b1111;
// [2]: reseed error
// [1]: mode error
// [0]: key_len
cfg_error_type_t config_error_type = 3'b000;
int config_error_pct = 30;
// min and max wait (clk) before an error injection
// this is only for injection and random reset
int inj_min_delay = 10;
int inj_max_delay = 1000;
rand int inj_delay;
rand flip_rst_lc_esc_e flip_rst_lc_esc;
// number of messages that was selected to be corrupt
// these should be excluded from the num_messages count
// when checking that all messages was processed
int num_corrupt_messages = 0;
// clear register percentage
// percentage of items that will try to clear
// one or more registers
int clear_reg_pct = 0;
// should the read vs write be unbalanced.
bit unbalanced = 0;
// chance of reading valid output (for each status poll)
int read_prob = 80;
// chance of writing data when DUT is ready (for each status poll)
int write_prob = 90;
// sideload enable
int sideload_pct = 0;
///////////////////////////////
// dont touch updated by env //
///////////////////////////////
// keep track of how many packets was split
int split_cnt = 0;
// rand variables
// 0: C model 1: OPEN_SSL/BORING_SSL
rand bit ref_model;
// randomly select if we force unused key bits to 0
rand bit key_mask;
// number of messages to encrypt/decrypt
rand int num_messages;
// TL UL contraints //
rand tl_ul_access_e host_resp_speed;
rand bit do_reseed;
rand bit [2:0] reseed_rate;
// constraints
constraint do_reseed_c { if (reseed_en == 0) { do_reseed == 0};}
constraint num_messages_c {num_messages inside {[num_messages_min : num_messages_max]};}
constraint ref_model_c {ref_model dist { 0 :/ use_c_model_pct,
1 :/ (100 - use_c_model_pct)};}
constraint inj_delay_c {inj_delay inside {[inj_min_delay : inj_max_delay]};}
constraint flip_rst_lc_esc_c { if ( |error_types[3:1]) {
flip_rst_lc_esc dist { Flip_bits :/ error_types.mal_inject,
Pull_reset :/ error_types.reset,
Lc_escalate :/ error_types.lc_esc};
} else {
flip_rst_lc_esc == Flip_bits;
}
}
constraint reseed_rate_c {reseed_rate dist { 3'b001 :/ 1,
3'b010 :/ 1,
3'b100 :/ 1 };}
function void post_randomize();
`uvm_info(`gfn, $sformatf("Use KEY MAST: %b", use_key_mask), UVM_LOW)
if (use_key_mask) key_mask = 1;
case(host_resp_speed)
VerySlow: begin
m_tl_agent_cfg.d_ready_delay_min = 10;
m_tl_agent_cfg.d_ready_delay_max = 10;
end
Slow: begin
m_tl_agent_cfg.d_ready_delay_min = 4;
m_tl_agent_cfg.d_ready_delay_max = 10;
end
Fast: begin
m_tl_agent_cfg.d_ready_delay_min = 0;
m_tl_agent_cfg.d_ready_delay_max = 5;
end
VeryFast: begin
m_tl_agent_cfg.d_ready_delay_min = 0;
m_tl_agent_cfg.d_ready_delay_max = 0;
zero_delays = 1;
end
endcase
endfunction
virtual function string convert2string();
string str = "";
str = super.convert2string();
str = {str, $sformatf("\n\t ----| AES ENVIRONMENT CONFIG \t ") };
str = {str, $sformatf("\n\t ----| Max Number of message %d \t ", num_messages_max)};
str = {str, $sformatf("\n\t ----| Min Number of message %d \t ", num_messages_min)};
str = {str, $sformatf("\n\t ----| Max message len %d bytes \t ", message_len_max)};
str = {str, $sformatf("\n\t ----| Min message len %d bytes \t ", message_len_min)};
str = {str, $sformatf("\n\t ----| Host response speed %s \t ", host_resp_speed.name())};
str = {str, $sformatf("\n\t ----| Reference model:\t %s \t ",
(ref_model==0) ? "C-MODEL" : "OPEN_SSL" )};
str = {str, $sformatf("\n\t ----| num_messages # %d \t ", num_messages)};
str = {str, $sformatf("\n\t ----| ECB Weight: %d \t ", ecb_weight)};
str = {str, $sformatf("\n\t ----| CBC Weight: %d \t ", cbc_weight)};
str = {str, $sformatf("\n\t ----| CFB Weight: %d \t ", cfb_weight)};
str = {str, $sformatf("\n\t ----| OFB Weight: %d \t ", ofb_weight)};
str = {str, $sformatf("\n\t ----| CTR Weight: %d \t ", ctr_weight)};
str = {str, $sformatf("\n\t ----| key mask: %b \t ", key_mask)};
str = {str, $sformatf("\n\t ----| inj delay: %d \t ", inj_delay)};
str = {str, "\n"};
return str;
endfunction
virtual function void initialize(bit [TL_AW-1:0] csr_base_addr = '1);
list_of_alerts = aes_env_pkg::LIST_OF_ALERTS;
keymgr_sideload_agent_cfg = key_sideload_agent_cfg#(keymgr_pkg::hw_key_req_t)::type_id
::create("keymgr_sideload_agent_cfg");
keymgr_sideload_agent_cfg.start_default_seq = 0;
num_edn = 1;
super.initialize(csr_base_addr);
tl_intg_alert_fields[ral.status.alert_fatal_fault] = 1;
shadow_update_err_status_fields[ral.status.alert_recov_ctrl_update_err] = 1;
shadow_storage_err_status_fields[ral.status.alert_fatal_fault] = 1;
// get aes reseed check interface handle
if (!uvm_config_db#(virtual aes_reseed_if)::get(null, "*.env" , "aes_reseed_vif",
aes_reseed_vif)) begin
`uvm_fatal(`gfn, $sformatf("FAILED TO GET HANDLE TO AES RESEED IF"))
end
if (`EN_MASKING) begin
if (!uvm_config_db#(virtual aes_masking_reseed_if)::get(null, "*.env" ,
"aes_masking_reseed_vif", aes_masking_reseed_vif)) begin
`uvm_fatal(`gfn, $sformatf("FAILED TO GET HANDLE TO AES MASKING RESEED IF"))
end
end
foreach (aes_fi_vif[nn]) begin
if (!uvm_config_db#(virtual force_if#(.Signal("aes_ctrl_cs"),
.SignalWidth(aes_env_pkg::StateWidth))
)::get(null, "*.env", $sformatf("aes_fi_vif_%0d", nn),
aes_fi_vif[nn])) begin
`uvm_fatal(`gfn, $sformatf("FAILED TO GET HANDLE TO FALT INJECT INTERFACE %d",nn))
end
end
foreach (aes_cipher_fi_vif[nn]) begin
if (!uvm_config_db#(virtual force_if#(.Signal("aes_cipher_ctrl_cs"),
.SignalWidth(aes_env_pkg::StateWidth))
)::get(null, "*.env",
$sformatf("aes_cipher_fi_vif_%0d", nn), aes_cipher_fi_vif[nn])) begin
`uvm_fatal(`gfn, $sformatf("FAILED TO GET HANDLE TO CIPHER FALT INJECT INTERFACE %d",nn))
end
end
foreach (aes_ctr_fi_vif[nn]) begin
if (!uvm_config_db#(virtual force_if#(.Signal("aes_ctr_cs"),
.SignalWidth(aes_env_pkg::StateWidth))
)::get(null, "*.env",
$sformatf("aes_ctr_fi_vif_%0d", nn), aes_ctr_fi_vif[nn])) begin
`uvm_fatal(`gfn, $sformatf("FAILED TO GET HANDLE TO ROUND COUNTER INJECT INTERFACE %d",nn))
end
end
foreach (aes_control_fi_vif[nn]) begin
if (!uvm_config_db#(virtual fi_control_if)::get(null, "*.env",
$sformatf("aes_control_fi_vif_%0d", nn), aes_control_fi_vif[nn])) begin
`uvm_fatal(`gfn, $sformatf("FAILED TO GET HANDLE TO ROUND COUNTER INJECT INTERFACE %d",nn))
end
end
foreach (aes_cipher_control_fi_vif[nn]) begin
if (!uvm_config_db#(virtual fi_cipher_if)::get(null, "*.env",
$sformatf("aes_cipher_control_fi_vif_%0d", nn),
aes_cipher_control_fi_vif[nn])) begin
`uvm_fatal(`gfn, $sformatf("FAILED TO GET HANDLE TO ROUND COUNTER INJECT INTERFACE %d",nn))
end
end
foreach (aes_ctr_fsm_fi_vif[nn]) begin
if (!uvm_config_db#(virtual fi_ctr_fsm_if)::get(null, "*.env",
$sformatf("aes_ctr_fsm_fi_vif_%0d", nn),
aes_ctr_fsm_fi_vif[nn])) begin
`uvm_fatal(`gfn, $sformatf("FAILED TO GET HANDLE TO ROUND COUNTER INJECT INTERFACE %d",nn))
end
end
if (!uvm_config_db#(virtual fi_core_if)::get(null, "*.env", "aes_core_fi_vif",
aes_core_fi_vif)) begin
`uvm_fatal(`gfn, "FAILED TO GET HANDLE TO CORE FAULT INJECTION INTERFACE")
end
// only support 1 outstanding TL item
m_tl_agent_cfg.max_outstanding_req = 1;
endfunction
endclass