mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-24 13:57:19 -04:00
Update lowrisc_ip to lowRISC/opentitan@34ba5e45f
Update code from upstream repository https://github.com/lowRISC/opentitan to revision 34ba5e45f9af7d8ca6c9bdae8bd11eeeeb669d6c * [dv] Add new ECC code options to mem_bkdr_util (Michael Schaffner) * [secded_gen] Define and generate inverted ECC enc/dec modules (Michael Schaffner) * [dv] Only run registers through one csr_rw sequence at once (Rupert Swarbrick) * [alert_handler] Minor lint fix (Michael Schaffner) * [prim_clock_div] Fix minor Verilator lint warning (Michael Schaffner) * [dvsim/lint] Make message reporting more flexible (Michael Schaffner) * [lint] Unify lint parser scripts (Michael Schaffner) * [rom_cntrl, dv] Test to verify successful rom check (Prajwala Puttappa) * [dv, dv_macros] Enhance `DV_GET_ENUM_PLUSARG` macro (Srikrishna Iyer) * [sram/dv] Fix mem data check (Weicai Yang) * [prim] Add flop wrapper for sparse fsm (Timothy Chen) * [flash_ctrl] Make data / metadata memories a single entry (Timothy Chen) * [dv] Teach encrypt/decrypt_sram_data to support OTBN (Rupert Swarbrick) Signed-off-by: Michael Schaffner <msf@google.com>
This commit is contained in:
parent
53b1732b19
commit
4df2221dee
99 changed files with 4611 additions and 1321 deletions
35
vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_vseq.sv
vendored
35
vendor/lowrisc_ip/dv/sv/dv_lib/dv_base_vseq.sv
vendored
|
@ -187,14 +187,27 @@ class dv_base_vseq #(type RAL_T = dv_base_reg_block,
|
|||
// arg csr_test_type: what csr test to run {hw_reset, rw, bit_bash, aliasing}
|
||||
// arg num_test_csrs:instead of testing the entire ral model or passing test chunk info via
|
||||
// plusarg, provide ability to set a random number of csrs to test from higher level sequence
|
||||
virtual task run_csr_vseq(string csr_test_type = "",
|
||||
int num_test_csrs = 0,
|
||||
bit do_rand_wr_and_reset = 1);
|
||||
csr_base_seq m_csr_seq;
|
||||
virtual task run_csr_vseq(string csr_test_type = "",
|
||||
int num_test_csrs = 0,
|
||||
bit do_rand_wr_and_reset = 1,
|
||||
string ral_name = "");
|
||||
csr_base_seq m_csr_seq;
|
||||
dv_base_reg_block models[string];
|
||||
|
||||
// env needs to have a ral instance
|
||||
// env needs to have at least one ral instance
|
||||
`DV_CHECK_GE_FATAL(cfg.ral_models.size(), 1)
|
||||
|
||||
// If ral_name is specified, only use registers on that named interface. Otherwise, use all
|
||||
// registers.
|
||||
if (ral_name != "") begin
|
||||
`DV_CHECK_FATAL(cfg.ral_models.exists(ral_name))
|
||||
models[ral_name] = cfg.ral_models[ral_name];
|
||||
end else begin
|
||||
foreach (cfg.ral_models[i]) begin
|
||||
models[i] = cfg.ral_models[i];
|
||||
end
|
||||
end
|
||||
|
||||
// check which csr test type
|
||||
case (csr_test_type)
|
||||
"hw_reset": csr_base_seq::type_id::set_type_override(csr_hw_reset_seq::get_type());
|
||||
|
@ -206,8 +219,8 @@ class dv_base_vseq #(type RAL_T = dv_base_reg_block,
|
|||
endcase
|
||||
|
||||
// Print the list of available exclusions that are in effect for debug.
|
||||
foreach (cfg.ral_models[i]) begin
|
||||
csr_excl_item csr_excl = csr_utils_pkg::get_excl_item(cfg.ral_models[i]);
|
||||
foreach (models[i]) begin
|
||||
csr_excl_item csr_excl = csr_utils_pkg::get_excl_item(models[i]);
|
||||
if (csr_excl != null) csr_excl.print_exclusions();
|
||||
end
|
||||
|
||||
|
@ -227,8 +240,8 @@ class dv_base_vseq #(type RAL_T = dv_base_reg_block,
|
|||
m_csr_write_seq = csr_write_seq::type_id::create("m_csr_write_seq");
|
||||
// We have to assign this array in a loop because the element types aren't equivalent, so
|
||||
// the array types aren't assignment compatible.
|
||||
foreach (cfg.ral_models[i]) begin
|
||||
m_csr_write_seq.models[i] = cfg.ral_models[i];
|
||||
foreach (models[i]) begin
|
||||
m_csr_write_seq.models[i] = models[i];
|
||||
end
|
||||
m_csr_write_seq.external_checker = cfg.en_scb;
|
||||
m_csr_write_seq.en_rand_backdoor_write = 1'b1;
|
||||
|
@ -248,8 +261,8 @@ class dv_base_vseq #(type RAL_T = dv_base_reg_block,
|
|||
m_csr_seq = csr_base_seq::type_id::create("m_csr_seq");
|
||||
// We have to assign this array in a loop because the element types aren't equivalent, so
|
||||
// the array types aren't assignment compatible.
|
||||
foreach (cfg.ral_models[i]) begin
|
||||
m_csr_seq.models[i] = cfg.ral_models[i];
|
||||
foreach (models[i]) begin
|
||||
m_csr_seq.models[i] = models[i];
|
||||
end
|
||||
m_csr_seq.external_checker = cfg.en_scb;
|
||||
m_csr_seq.num_test_csrs = num_test_csrs;
|
||||
|
|
23
vendor/lowrisc_ip/dv/sv/dv_utils/dv_macros.svh
vendored
23
vendor/lowrisc_ip/dv/sv/dv_utils/dv_macros.svh
vendored
|
@ -413,20 +413,25 @@
|
|||
end
|
||||
`endif
|
||||
|
||||
// This macro converts a string input from plusarg to an enum variable
|
||||
// ENUM_: the name of enum type
|
||||
// PLUSARG_: the name of the plusargs, which is also the name of the enum variable
|
||||
// CHECK_EXIST_: set to 1, `$value$plusargs()` should return true
|
||||
// Retrieves a plusarg value representing an enum literal.
|
||||
//
|
||||
// The plusarg is parsed as a string, which needs to be converted into the enum literal whose name
|
||||
// matches the string. This functionality is provided by the UVM helper function below.
|
||||
//
|
||||
// ENUM_: The enum type.
|
||||
// VAR_: The enum variable to which the plusarg value will be set (must be declared already).
|
||||
// PLUSARG_: the name of the plusarg (as raw text). This is typically the same as the enum variable.
|
||||
// CHECK_EXISTS_: Throws a fatal error if the plusarg is not set.
|
||||
`ifndef DV_GET_ENUM_PLUSARG
|
||||
`define DV_GET_ENUM_PLUSARG(ENUM_, PLUSARG_, CHECK_EXIST_ = 0, ID_ = `gfn) \
|
||||
`define DV_GET_ENUM_PLUSARG(ENUM_, VAR_, PLUSARG_ = VAR_, CHECK_EXISTS_ = 0, ID_ = `gfn) \
|
||||
begin \
|
||||
string str; \
|
||||
if ($value$plusargs("``PLUSARG_``=%0s", str)) begin \
|
||||
if (!uvm_enum_wrapper#(ENUM_)::from_name(str, PLUSARG_)) begin \
|
||||
`uvm_fatal(ID_, $sformatf("Cannot find %s from enum ``ENUM_``", PLUSARG_.name)) \
|
||||
if (!uvm_enum_wrapper#(ENUM_)::from_name(str, VAR_)) begin \
|
||||
`uvm_fatal(ID_, $sformatf("Cannot find %s from enum ``ENUM_``", VAR_.name())) \
|
||||
end \
|
||||
end else if (CHECK_EXIST_) begin \
|
||||
`uvm_fatal(ID_, "Can't find plusargs ``PLUSARG_``") \
|
||||
end else if (CHECK_EXISTS_) begin \
|
||||
`uvm_fatal(ID_, "Please pass the plusarg +``PLUSARG_``=<``ENUM_``-literal>") \
|
||||
end \
|
||||
end
|
||||
`endif
|
||||
|
|
|
@ -313,6 +313,27 @@ class mem_bkdr_util extends uvm_object;
|
|||
EccHamming_76_68: begin
|
||||
rw_data = prim_secded_pkg::prim_secded_hamming_76_68_enc(rw_data[63:0]);
|
||||
end
|
||||
EccInv_22_16: begin
|
||||
rw_data = prim_secded_pkg::prim_secded_inv_22_16_enc(rw_data[15:0]);
|
||||
end
|
||||
EccInvHamming_22_16: begin
|
||||
rw_data = prim_secded_pkg::prim_secded_inv_hamming_22_16_enc(rw_data[15:0]);
|
||||
end
|
||||
EccInv_39_32: begin
|
||||
rw_data = prim_secded_pkg::prim_secded_inv_39_32_enc(rw_data[31:0]);
|
||||
end
|
||||
EccInvHamming_39_32: begin
|
||||
rw_data = prim_secded_pkg::prim_secded_inv_hamming_39_32_enc(rw_data[31:0]);
|
||||
end
|
||||
EccInv_72_64: begin
|
||||
rw_data = prim_secded_pkg::prim_secded_inv_72_64_enc(rw_data[63:0]);
|
||||
end
|
||||
EccInvHamming_72_64: begin
|
||||
rw_data = prim_secded_pkg::prim_secded_inv_hamming_72_64_enc(rw_data[63:0]);
|
||||
end
|
||||
EccInvHamming_76_68: begin
|
||||
rw_data = prim_secded_pkg::prim_secded_inv_hamming_76_68_enc(rw_data[63:0]);
|
||||
end
|
||||
default: begin
|
||||
`uvm_error(`gfn, $sformatf("ECC scheme %0s is unsupported.", err_detection_scheme))
|
||||
end
|
||||
|
@ -383,6 +404,12 @@ class mem_bkdr_util extends uvm_object;
|
|||
EccHamming_22_16: begin
|
||||
return prim_secded_pkg::prim_secded_hamming_22_16_dec(data);
|
||||
end
|
||||
EccInv_22_16: begin
|
||||
return prim_secded_pkg::prim_secded_inv_22_16_dec(data);
|
||||
end
|
||||
EccInvHamming_22_16: begin
|
||||
return prim_secded_pkg::prim_secded_inv_hamming_22_16_dec(data);
|
||||
end
|
||||
default: return 'x;
|
||||
endcase
|
||||
endfunction
|
||||
|
@ -399,6 +426,12 @@ class mem_bkdr_util extends uvm_object;
|
|||
EccHamming_39_32: begin
|
||||
return prim_secded_pkg::prim_secded_hamming_39_32_dec(data);
|
||||
end
|
||||
EccInv_39_32: begin
|
||||
return prim_secded_pkg::prim_secded_inv_39_32_dec(data);
|
||||
end
|
||||
EccInvHamming_39_32: begin
|
||||
return prim_secded_pkg::prim_secded_inv_hamming_39_32_dec(data);
|
||||
end
|
||||
default: return 'x;
|
||||
endcase
|
||||
endfunction
|
||||
|
@ -415,6 +448,12 @@ class mem_bkdr_util extends uvm_object;
|
|||
EccHamming_72_64: begin
|
||||
return prim_secded_pkg::prim_secded_hamming_72_64_dec(data);
|
||||
end
|
||||
EccInv_72_64: begin
|
||||
return prim_secded_pkg::prim_secded_inv_72_64_dec(data);
|
||||
end
|
||||
EccInvHamming_72_64: begin
|
||||
return prim_secded_pkg::prim_secded_inv_hamming_72_64_dec(data);
|
||||
end
|
||||
default: return 'x;
|
||||
endcase
|
||||
endfunction
|
||||
|
|
|
@ -66,3 +66,57 @@ virtual function bit [38:0] rom_encrypt_read32(bit [bus_params_pkg::BUS_AW-1:0]
|
|||
|
||||
return data;
|
||||
endfunction
|
||||
|
||||
|
||||
virtual function void rom_encrypt_write32_integ(logic [bus_params_pkg::BUS_AW-1:0] addr,
|
||||
logic [31:0] data,
|
||||
logic [SRAM_KEY_WIDTH-1:0] key,
|
||||
logic [SRAM_BLOCK_WIDTH-1:0] nonce,
|
||||
bit scramble_data);
|
||||
logic [bus_params_pkg::BUS_AW-1:0] bus_addr = '0;
|
||||
logic [38:0] integ_data;
|
||||
logic [38:0] scrambled_data;
|
||||
|
||||
logic wdata_arr [] = new[39];
|
||||
logic scrambled_addr [] = new[addr_width];
|
||||
logic rom_addr [] = new[addr_width];
|
||||
logic key_arr [] = new[SRAM_KEY_WIDTH];
|
||||
logic nonce_arr [] = new[SRAM_BLOCK_WIDTH];
|
||||
|
||||
key_arr = {<<{key}};
|
||||
nonce_arr = {<<{nonce}};
|
||||
|
||||
for (int i = 0; i < addr_width; i++) begin
|
||||
rom_addr[i] = addr[addr_lsb + i];
|
||||
end
|
||||
|
||||
// Calculate the scrambled address
|
||||
scrambled_addr = sram_scrambler_pkg::encrypt_sram_addr(rom_addr, addr_width, nonce_arr);
|
||||
|
||||
if(scramble_data) begin
|
||||
// Calculate the integrity constant
|
||||
integ_data = prim_secded_pkg::prim_secded_39_32_enc(data);
|
||||
|
||||
// Calculate the scrambled data
|
||||
wdata_arr = {<<{integ_data}};
|
||||
wdata_arr = sram_scrambler_pkg::encrypt_sram_data(
|
||||
wdata_arr, 39, 0, rom_addr, addr_width, key_arr, nonce_arr
|
||||
);
|
||||
scrambled_data = {<<{wdata_arr}};
|
||||
end
|
||||
else begin
|
||||
scrambled_data = data;
|
||||
end
|
||||
|
||||
// Construct bus representation of the address
|
||||
for (int i = 0; i < addr_lsb; i++) begin
|
||||
bus_addr[i] = addr[i];
|
||||
end
|
||||
for (int i = 0; i < addr_width; i++) begin
|
||||
bus_addr[addr_lsb + i] = scrambled_addr[i];
|
||||
end
|
||||
|
||||
// Write the scrambled data to memory
|
||||
write39integ(bus_addr, scrambled_data);
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ virtual function logic [7:0] sram_encrypt_read8(logic [bus_params_pkg::BUS_AW-1:
|
|||
rdata = read8(bus_addr);
|
||||
rdata_arr = {<<{rdata}};
|
||||
rdata_arr = sram_scrambler_pkg::decrypt_sram_data(
|
||||
rdata_arr, 8, 1, sram_addr, addr_width, key_arr, nonce_arr
|
||||
rdata_arr, 8, 8, sram_addr, addr_width, key_arr, nonce_arr
|
||||
);
|
||||
rdata = {<<{rdata_arr}};
|
||||
return rdata;
|
||||
|
@ -79,7 +79,7 @@ virtual function logic [15:0] sram_encrypt_read16(logic [bus_params_pkg::BUS_AW-
|
|||
rdata = read16(bus_addr);
|
||||
rdata_arr = {<<{rdata}};
|
||||
rdata_arr = sram_scrambler_pkg::decrypt_sram_data(
|
||||
rdata_arr, 16, 1, sram_addr, addr_width, key_arr, nonce_arr
|
||||
rdata_arr, 16, 8, sram_addr, addr_width, key_arr, nonce_arr
|
||||
);
|
||||
rdata = {<<{rdata_arr}};
|
||||
return rdata;
|
||||
|
@ -118,7 +118,7 @@ virtual function logic [31:0] sram_encrypt_read32(logic [bus_params_pkg::BUS_AW-
|
|||
rdata = read32(bus_addr);
|
||||
rdata_arr = {<<{rdata}};
|
||||
rdata_arr = sram_scrambler_pkg::decrypt_sram_data(
|
||||
rdata_arr, 32, 1, sram_addr, addr_width, key_arr, nonce_arr
|
||||
rdata_arr, 32, 8, sram_addr, addr_width, key_arr, nonce_arr
|
||||
);
|
||||
rdata = {<<{rdata_arr}};
|
||||
return rdata;
|
||||
|
@ -159,7 +159,7 @@ virtual function logic [38:0] sram_encrypt_read32_integ(logic [bus_params_pkg::B
|
|||
`uvm_info(`gfn, $sformatf("scr data: 0x%0x", rdata), UVM_HIGH)
|
||||
rdata_arr = {<<{rdata}};
|
||||
rdata_arr = sram_scrambler_pkg::decrypt_sram_data(
|
||||
rdata_arr, 39, 0, sram_addr, addr_width, key_arr, nonce_arr
|
||||
rdata_arr, 39, 39, sram_addr, addr_width, key_arr, nonce_arr
|
||||
);
|
||||
rdata = {<<{rdata_arr}};
|
||||
// Only return the data payload without ECC bits.
|
||||
|
@ -201,7 +201,7 @@ virtual function logic [63:0] sram_encrypt_read64(logic [bus_params_pkg::BUS_AW-
|
|||
rdata = read64(bus_addr);
|
||||
rdata_arr = {<<{rdata}};
|
||||
rdata_arr = sram_scrambler_pkg::decrypt_sram_data(
|
||||
rdata_arr, 64, 1, sram_addr, addr_width, key_arr, nonce_arr
|
||||
rdata_arr, 64, 8, sram_addr, addr_width, key_arr, nonce_arr
|
||||
);
|
||||
rdata = {<<{rdata_arr}};
|
||||
return rdata;
|
||||
|
@ -234,7 +234,7 @@ virtual function void sram_encrypt_write8(logic [bus_params_pkg::BUS_AW-1:0] add
|
|||
// Calculate the scrambled data
|
||||
wdata_arr = {<<{data}};
|
||||
wdata_arr = sram_scrambler_pkg::encrypt_sram_data(
|
||||
wdata_arr, 8, 1, sram_addr, addr_width, key_arr, nonce_arr
|
||||
wdata_arr, 8, 8, sram_addr, addr_width, key_arr, nonce_arr
|
||||
);
|
||||
scrambled_data = {<<{wdata_arr}};
|
||||
|
||||
|
@ -276,7 +276,7 @@ virtual function void sram_encrypt_write16(logic [bus_params_pkg::BUS_AW-1:0] ad
|
|||
// Calculate the scrambled data
|
||||
wdata_arr = {<<{data}};
|
||||
wdata_arr = sram_scrambler_pkg::encrypt_sram_data(
|
||||
wdata_arr, 16, 1, sram_addr, addr_width, key_arr, nonce_arr
|
||||
wdata_arr, 16, 8, sram_addr, addr_width, key_arr, nonce_arr
|
||||
);
|
||||
scrambled_data = {<<{wdata_arr}};
|
||||
|
||||
|
@ -318,7 +318,7 @@ virtual function void sram_encrypt_write32(logic [bus_params_pkg::BUS_AW-1:0] ad
|
|||
// Calculate the scrambled data
|
||||
wdata_arr = {<<{data}};
|
||||
wdata_arr = sram_scrambler_pkg::encrypt_sram_data(
|
||||
wdata_arr, 32, 1, sram_addr, addr_width, key_arr, nonce_arr
|
||||
wdata_arr, 32, 8, sram_addr, addr_width, key_arr, nonce_arr
|
||||
);
|
||||
scrambled_data = {<<{wdata_arr}};
|
||||
|
||||
|
@ -359,12 +359,12 @@ virtual function void sram_encrypt_write32_integ(logic [bus_params_pkg::BUS_AW-1
|
|||
scrambled_addr = sram_scrambler_pkg::encrypt_sram_addr(sram_addr, addr_width, nonce_arr);
|
||||
|
||||
// Calculate the integrity constant
|
||||
integ_data = prim_secded_pkg::prim_secded_39_32_enc(data);
|
||||
integ_data = prim_secded_pkg::prim_secded_inv_39_32_enc(data);
|
||||
|
||||
// Calculate the scrambled data
|
||||
wdata_arr = {<<{integ_data}};
|
||||
wdata_arr = sram_scrambler_pkg::encrypt_sram_data(
|
||||
wdata_arr, 39, 0, sram_addr, addr_width, key_arr, nonce_arr
|
||||
wdata_arr, 39, 39, sram_addr, addr_width, key_arr, nonce_arr
|
||||
);
|
||||
scrambled_data = {<<{wdata_arr}};
|
||||
|
||||
|
@ -406,7 +406,7 @@ virtual function void sram_encrypt_write64(logic [bus_params_pkg::BUS_AW-1:0] ad
|
|||
// Calculate the scrambled data
|
||||
wdata_arr = {<<{data}};
|
||||
wdata_arr = sram_scrambler_pkg::encrypt_sram_data(
|
||||
wdata_arr, 64, 1, sram_addr, addr_width, key_arr, nonce_arr
|
||||
wdata_arr, 64, 8, sram_addr, addr_width, key_arr, nonce_arr
|
||||
);
|
||||
scrambled_data = {<<{wdata_arr}};
|
||||
|
||||
|
|
|
@ -26,6 +26,15 @@ package mem_bkdr_util_pkg;
|
|||
EccHamming_39_32 = prim_secded_pkg::SecdedHamming_39_32,
|
||||
EccHamming_72_64 = prim_secded_pkg::SecdedHamming_72_64,
|
||||
EccHamming_76_68 = prim_secded_pkg::SecdedHamming_76_68,
|
||||
EccInv_22_16 = prim_secded_pkg::SecdedInv_22_16,
|
||||
EccInv_28_22 = prim_secded_pkg::SecdedInv_28_22,
|
||||
EccInv_39_32 = prim_secded_pkg::SecdedInv_39_32,
|
||||
EccInv_64_57 = prim_secded_pkg::SecdedInv_64_57,
|
||||
EccInv_72_64 = prim_secded_pkg::SecdedInv_72_64,
|
||||
EccInvHamming_22_16 = prim_secded_pkg::SecdedInvHamming_22_16,
|
||||
EccInvHamming_39_32 = prim_secded_pkg::SecdedInvHamming_39_32,
|
||||
EccInvHamming_72_64 = prim_secded_pkg::SecdedInvHamming_72_64,
|
||||
EccInvHamming_76_68 = prim_secded_pkg::SecdedInvHamming_76_68,
|
||||
ParityEven,
|
||||
ParityOdd
|
||||
} err_detection_e;
|
||||
|
|
|
@ -216,17 +216,15 @@ package sram_scrambler_pkg;
|
|||
// and then XOR the result with the data.
|
||||
//
|
||||
// After that, the XORed data neeeds to them be passed through the S&P network one byte at a time.
|
||||
//
|
||||
// TODO: We currently do not support data size of >64bits.
|
||||
function automatic state_t encrypt_sram_data(logic data[], int data_width, bit byte_diff,
|
||||
function automatic state_t encrypt_sram_data(logic data[], int data_width, int sp_width,
|
||||
logic addr[], int addr_width,
|
||||
logic key[], logic nonce[]);
|
||||
// Generate the keystream
|
||||
logic keystream[] = new[SRAM_BLOCK_WIDTH];
|
||||
logic data_enc[] = new[data_width];
|
||||
logic byte_to_enc[] = new[8];
|
||||
logic enc_byte[] = new[8];
|
||||
logic zero_key[] = new[data_width];
|
||||
int ks_width = (data_width < 64) ? data_width : 64;
|
||||
|
||||
// the key used for byte diffusion is all-zero.
|
||||
for (int i = 0; i < data_width; i++) begin
|
||||
|
@ -237,27 +235,44 @@ package sram_scrambler_pkg;
|
|||
keystream = gen_keystream(addr, addr_width, key, nonce);
|
||||
|
||||
// XOR keystream with input data
|
||||
// Assumes data width <= 64.
|
||||
// Assumes ks_width <= 64.
|
||||
for (int i = 0; i < data_width; i++) begin
|
||||
data_enc[i] = data[i] ^ keystream[i];
|
||||
data_enc[i] = data[i] ^ keystream[i % ks_width];
|
||||
end
|
||||
|
||||
// pass each byte of the encoded result through the subst/perm network
|
||||
if (byte_diff) begin
|
||||
if (data_width == sp_width) begin
|
||||
// pass the entire word through the subst/perm network at once (the next cases would give the
|
||||
// same results too, but this should be a bit more efficient)
|
||||
data_enc = sp_encrypt(data_enc, data_width, zero_key);
|
||||
end else if (sp_width == 8) begin
|
||||
// pass each byte of the encoded result through the subst/perm network (special case of the
|
||||
// general code below)
|
||||
for (int i = 0; i < data_width / 8; i++) begin
|
||||
byte_to_enc = data_enc[i*8 +: 8];
|
||||
enc_byte = sp_encrypt(byte_to_enc, 8, zero_key);
|
||||
data_enc[i*8 +: 8] = enc_byte;
|
||||
end
|
||||
// pass the entire word through the subst/perm network
|
||||
end else begin
|
||||
data_enc = sp_encrypt(data_enc, data_width, zero_key);
|
||||
// divide the word into sp_width chunks to pass it through the subst/perm network
|
||||
for (int chunk_lsb = 0; chunk_lsb < data_width; chunk_lsb += sp_width) begin
|
||||
int bits_remaining = data_width - chunk_lsb;
|
||||
int chunk_width = (bits_remaining < sp_width) ? bits_remaining : sp_width;
|
||||
logic chunk[] = new[chunk_width];
|
||||
|
||||
for (int j = 0; j < chunk_width; j++) begin
|
||||
chunk[j] = data_enc[chunk_lsb + j];
|
||||
end
|
||||
chunk = sp_encrypt(chunk, chunk_width, zero_key);
|
||||
for (int j = 0; j < chunk_width; j++) begin
|
||||
data_enc[chunk_lsb + j] = chunk[j];
|
||||
end
|
||||
end
|
||||
end
|
||||
return data_enc;
|
||||
|
||||
endfunction : encrypt_sram_data
|
||||
|
||||
function automatic state_t decrypt_sram_data(logic data[], int data_width, bit byte_diff,
|
||||
function automatic state_t decrypt_sram_data(logic data[], int data_width, int sp_width,
|
||||
logic addr[], int addr_width,
|
||||
logic key[], logic nonce[]);
|
||||
logic keystream[] = new[SRAM_BLOCK_WIDTH];
|
||||
|
@ -265,6 +280,7 @@ package sram_scrambler_pkg;
|
|||
logic byte_to_dec[] = new[8];
|
||||
logic dec_byte[] = new[8];
|
||||
logic zero_key[] = new[data_width];
|
||||
int ks_width = (data_width < 64) ? data_width : 64;
|
||||
|
||||
// the key used for byte diffusion is all-zero.
|
||||
for (int i = 0; i < data_width; i++) begin
|
||||
|
@ -274,21 +290,38 @@ package sram_scrambler_pkg;
|
|||
// Generate the keystream
|
||||
keystream = gen_keystream(addr, addr_width, key, nonce);
|
||||
|
||||
// pass each byte of the data through the subst/perm network
|
||||
if (byte_diff) begin
|
||||
if (data_width == sp_width) begin
|
||||
// pass the entire word through the subst/perm network at once (the next cases would give the
|
||||
// same results too, but this should be a bit more efficient)
|
||||
data_dec = sp_decrypt(data, data_width, zero_key);
|
||||
end else if (sp_width == 8) begin
|
||||
// pass each byte of the data through the subst/perm network (special case of the general code
|
||||
// below)
|
||||
for (int i = 0; i < data_width / 8; i++) begin
|
||||
byte_to_dec = data[i*8 +: 8];
|
||||
dec_byte = sp_decrypt(byte_to_dec, 8, zero_key);
|
||||
data_dec[i*8 +: 8] = dec_byte;
|
||||
end
|
||||
// pass the entire word through the subst/perm network
|
||||
end else begin
|
||||
data_dec = sp_decrypt(data, data_width, zero_key);
|
||||
// divide the word into sp_width chunks to pass it through the subst/perm network
|
||||
for (int chunk_lsb = 0; chunk_lsb < data_width; chunk_lsb += sp_width) begin
|
||||
int bits_remaining = data_width - chunk_lsb;
|
||||
int chunk_width = (bits_remaining < sp_width) ? bits_remaining : sp_width;
|
||||
logic chunk[] = new[chunk_width];
|
||||
|
||||
for (int j = 0; j < chunk_width; j++) begin
|
||||
chunk[j] = data[chunk_lsb + j];
|
||||
end
|
||||
chunk = sp_decrypt(chunk, chunk_width, zero_key);
|
||||
for (int j = 0; j < chunk_width; j++) begin
|
||||
data_dec[chunk_lsb + j] = chunk[j];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// XOR result data with the keystream
|
||||
for (int i = 0; i < data_width; i++) begin
|
||||
data_dec[i] = data_dec[i] ^ keystream[i];
|
||||
data_dec[i] = data_dec[i] ^ keystream[i % ks_width];
|
||||
end
|
||||
|
||||
return data_dec;
|
||||
|
|
17
vendor/lowrisc_ip/dv/sv/mem_model/mem_model.sv
vendored
17
vendor/lowrisc_ip/dv/sv/mem_model/mem_model.sv
vendored
|
@ -16,6 +16,10 @@ class mem_model #(int AddrWidth = bus_params_pkg::BUS_AW,
|
|||
|
||||
`uvm_object_new
|
||||
|
||||
function void init();
|
||||
system_memory.delete();
|
||||
endfunction
|
||||
|
||||
function int get_written_bytes();
|
||||
return system_memory.size();
|
||||
endfunction
|
||||
|
@ -33,14 +37,13 @@ class mem_model #(int AddrWidth = bus_params_pkg::BUS_AW,
|
|||
endfunction
|
||||
|
||||
function void write_byte(mem_addr_t addr, bit [7:0] data);
|
||||
`uvm_info(`gfn, $sformatf("Write Mem : Addr[0x%0h], Data[0x%0h]", addr, data), UVM_HIGH)
|
||||
`uvm_info(`gfn, $sformatf("Write Mem : Addr[0x%0h], Data[0x%0h]", addr, data), UVM_MEDIUM)
|
||||
system_memory[addr] = data;
|
||||
endfunction
|
||||
|
||||
function void compare_byte(mem_addr_t addr, bit [7:0] act_data);
|
||||
`uvm_info(`gfn, $sformatf("Compare Mem : Addr[0x%0h], Act Data[0x%0h], Exp Data[0x%0h]",
|
||||
addr, act_data, system_memory[addr]), UVM_HIGH)
|
||||
system_memory[addr] = act_data;
|
||||
addr, act_data, system_memory[addr]), UVM_MEDIUM)
|
||||
`DV_CHECK_EQ(act_data, system_memory[addr], $sformatf("addr 0x%0h read out mismatch", addr))
|
||||
endfunction
|
||||
|
||||
|
@ -67,12 +70,14 @@ class mem_model #(int AddrWidth = bus_params_pkg::BUS_AW,
|
|||
return data;
|
||||
endfunction
|
||||
|
||||
function void compare(mem_addr_t addr, mem_data_t act_data, mem_mask_t mask = '1);
|
||||
function void compare(mem_addr_t addr, mem_data_t act_data, mem_mask_t mask = '1,
|
||||
bit compare_exist_addr_only = 1);
|
||||
bit [7:0] byte_data;
|
||||
for (int i = 0; i < DataWidth / 8; i++) begin
|
||||
mem_addr_t byte_addr = addr + i;
|
||||
byte_data = act_data[7:0];
|
||||
if (mask[0]) begin
|
||||
compare_byte(addr + i, byte_data);
|
||||
if (mask[0] && (!compare_exist_addr_only || system_memory.exists(byte_addr))) begin
|
||||
compare_byte(byte_addr, byte_data);
|
||||
end else begin
|
||||
// Nothing to do here: since this byte wasn't selected by the mask, there are no
|
||||
// requirements about what data came back.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue