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

[kmac/dv] initial version of KMAC smoke test #4674

Merged
merged 4 commits into from
Jan 20, 2021
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion hw/dv/sv/dv_utils/dv_utils_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,20 @@ package dv_utils_pkg;
return val >= 0 ? val : -val;
endfunction

// endian swap
// endian swaps a 32-bit data word
function automatic logic [31:0] endian_swap(logic [31:0] data);
return {<<8{data}};
endfunction

// endian swaps bytes at a word granularity, while preserving overall word ordering.
//
// e.g. if `arr[] = '{'h0, 'h1, 'h2, 'h3, 'h4, 'h5, 'h6, 'h7}`, this function will produce:
// `'{'h3, 'h2, 'h1, 'h0, 'h7, 'h6, 'h5, 'h4}`
function automatic void endian_swap_byte_arr(ref bit [7:0] arr[]);
arr = {<< byte {arr}};
arr = {<< 32 {arr}};
endfunction

`ifdef UVM
// Simple function to set max errors before quitting sim
function automatic void set_max_quit_count(int n);
Expand Down
9 changes: 9 additions & 0 deletions hw/dv/sv/str_utils/str_utils_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,15 @@ package str_utils_pkg;
end
endfunction : str_to_bytes

// Converts an array of bytes to a string.
function automatic string bytes_to_str(byte bytes[]);
string s;
foreach (bytes[i]) begin
s = {s, string'(bytes[i])};
end
return s;
sriyerg marked this conversation as resolved.
Show resolved Hide resolved
endfunction

/************************/
/* File path functions. */
/************************/
Expand Down
4 changes: 2 additions & 2 deletions hw/ip/kmac/data/kmac_base_testplan.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
- Set function name to "KMAC" and set customization string as empty if applicable.
- Randomly set endianness of input msg and internal keccak state.
- Randomly provide a sideloaded key, do not set cfg.sideload.
- Set output length between 1-1600 bits if applicable.
- Set output length between 1-`keccak_rate` bytes if applicable.
- Trigger KMAC to start absorbing input message.
- During absorption stage randomly read from STATE window, expect 0.
- Write message to MSG_FIFO window, maximum length of 32 bytes.
Expand All @@ -44,7 +44,7 @@
input size for DV, but will enable easy extensibility for emulation testing where we can
enable much larger messages.
Allow output length to vary up to 1KB (for XOF functions).
If output length is greater than 1600 bits, keccak rounds will be run manually to
If output length is greater than `keccak_rate` bytes, keccak rounds will be run manually to
squeeze extra output data.
Set function name as "KMAC" and enable full randomization of customization string (if
applicable).
Expand Down
37 changes: 28 additions & 9 deletions hw/ip/kmac/dv/dpi/digestpp_dpi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <list>

#include "svdpi.h"
#include "vendor/kerukuro_digestpp/algorithm/kmac.hpp"
Expand All @@ -24,12 +26,17 @@ extern "C" {
*/
static void load_arr_from_simulator(const svOpenArrayHandle arr,
uint8_t *array_out, uint64_t array_len) {
svBitVecVal val;

if (array_len == 0) {
return;
}

uint8_t *arr_ptr = (uint8_t *)svGetArrayPtr(arr);
memcpy(array_out, arr_ptr, array_len);
for (int i = 0; i < array_len; i++) {
svGetBitArrElem1VecVal(&val, arr, i);
array_out[i] = (uint8_t)val;
}
}

/**
Expand Down Expand Up @@ -160,6 +167,7 @@ extern void c_dpi_shake256(const svOpenArrayHandle msg, uint64_t msg_len,
// CSHAKE128 //
///////////////
extern void c_dpi_cshake128(const svOpenArrayHandle msg,
const char *function_name,
const char *customization_str, uint64_t msg_len,
uint64_t output_len, svOpenArrayHandle digest) {
// Load message from SV memory
Expand All @@ -170,7 +178,8 @@ extern void c_dpi_cshake128(const svOpenArrayHandle msg,

// Compute the digest
digestpp::cshake128 shake;
shake.set_customization(customization_str);
shake.set_function_name(function_name, strlen(function_name));
shake.set_customization(customization_str, strlen(customization_str));
shake.absorb(msg_arr, msg_len);
shake.squeeze(digest_arr, output_len);

Expand All @@ -186,6 +195,7 @@ extern void c_dpi_cshake128(const svOpenArrayHandle msg,
// CSHAKE256 //
///////////////
extern void c_dpi_cshake256(const svOpenArrayHandle msg,
const char *function_name,
const char *customization_str, uint64_t msg_len,
uint64_t output_len, svOpenArrayHandle digest) {
// Load message from SV memory
Expand All @@ -196,7 +206,8 @@ extern void c_dpi_cshake256(const svOpenArrayHandle msg,

// Compute the digest
digestpp::cshake256 shake;
shake.set_customization(customization_str);
shake.set_function_name(function_name, strlen(function_name));
shake.set_customization(customization_str, strlen(customization_str));
shake.absorb(msg_arr, msg_len);
shake.squeeze(digest_arr, output_len);

Expand All @@ -213,7 +224,8 @@ extern void c_dpi_cshake256(const svOpenArrayHandle msg,
/////////////
extern void c_dpi_kmac128(const svOpenArrayHandle msg, uint64_t msg_len,
const svOpenArrayHandle key, uint64_t key_len,
uint64_t output_len, svBitVecVal *digest) {
const char *customization_str, uint64_t output_len,
svBitVecVal *digest) {
uint64_t output_len_bits = output_len * 8;

// Load message from SV memory
Expand All @@ -228,9 +240,10 @@ extern void c_dpi_kmac128(const svOpenArrayHandle msg, uint64_t msg_len,

// Compute the digest
digestpp::kmac128 kmac(output_len_bits);
kmac.set_customization(customization_str, strlen(customization_str));
kmac.set_key(key_arr, key_len);
kmac.absorb(msg_arr, msg_len);
kmac.digest(digest_arr, output_len);
kmac.digest(digest_arr, sizeof(digest_arr));

if (msg_arr != nullptr) {
free(msg_arr);
Expand All @@ -249,6 +262,7 @@ extern void c_dpi_kmac128(const svOpenArrayHandle msg, uint64_t msg_len,
/////////////////
extern void c_dpi_kmac128_xof(const svOpenArrayHandle msg, uint64_t msg_len,
const svOpenArrayHandle key, uint64_t key_len,
const char *customization_str,
uint64_t output_len, svBitVecVal *digest) {
// Load message from SV memory
uint8_t *msg_arr = (uint8_t *)malloc(msg_len * sizeof(uint8_t));
Expand All @@ -262,9 +276,10 @@ extern void c_dpi_kmac128_xof(const svOpenArrayHandle msg, uint64_t msg_len,

// Compute the digest
digestpp::kmac128_xof kmac;
kmac.set_customization(customization_str, strlen(customization_str));
kmac.set_key(key_arr, key_len);
kmac.absorb(msg_arr, msg_len);
kmac.squeeze(digest_arr, output_len);
kmac.squeeze(digest_arr, sizeof(digest_arr));

if (msg_arr != nullptr) {
free(msg_arr);
Expand All @@ -283,7 +298,8 @@ extern void c_dpi_kmac128_xof(const svOpenArrayHandle msg, uint64_t msg_len,
/////////////
extern void c_dpi_kmac256(const svOpenArrayHandle msg, uint64_t msg_len,
const svOpenArrayHandle key, uint64_t key_len,
uint64_t output_len, svBitVecVal *digest) {
const char *customization_str, uint64_t output_len,
svBitVecVal *digest) {
uint64_t output_len_bits = output_len * 8;

// Load message from SV memory
Expand All @@ -298,9 +314,10 @@ extern void c_dpi_kmac256(const svOpenArrayHandle msg, uint64_t msg_len,

// Compute the digest
digestpp::kmac256 kmac(output_len_bits);
kmac.set_customization(customization_str, strlen(customization_str));
kmac.set_key(key_arr, key_len);
kmac.absorb(msg_arr, msg_len);
kmac.digest(digest_arr, output_len);
kmac.digest(digest_arr, sizeof(digest_arr));

if (msg_arr != nullptr) {
free(msg_arr);
Expand All @@ -319,6 +336,7 @@ extern void c_dpi_kmac256(const svOpenArrayHandle msg, uint64_t msg_len,
/////////////////
extern void c_dpi_kmac256_xof(const svOpenArrayHandle msg, uint64_t msg_len,
const svOpenArrayHandle key, uint64_t key_len,
const char *customization_str,
uint64_t output_len, svBitVecVal *digest) {
// Load message from SV memory
uint8_t *msg_arr = (uint8_t *)malloc(msg_len * sizeof(uint8_t));
Expand All @@ -332,9 +350,10 @@ extern void c_dpi_kmac256_xof(const svOpenArrayHandle msg, uint64_t msg_len,

// Compute the digest
digestpp::kmac256_xof kmac;
kmac.set_customization(customization_str, strlen(customization_str));
kmac.set_key(key_arr, key_len);
kmac.absorb(msg_arr, msg_len);
kmac.squeeze(digest_arr, output_len);
kmac.squeeze(digest_arr, sizeof(digest_arr));

if (msg_arr != nullptr) {
free(msg_arr);
Expand Down
6 changes: 6 additions & 0 deletions hw/ip/kmac/dv/dpi/digestpp_dpi_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ package digestpp_dpi_pkg;

import "DPI-C" context function void c_dpi_cshake128(
input bit[7:0] msg[],
input string function_name,
input string customization_str,
input longint unsigned msg_len,
input longint unsigned output_len,
Expand All @@ -59,6 +60,7 @@ package digestpp_dpi_pkg;

import "DPI-C" context function void c_dpi_cshake256(
input bit[7:0] msg[],
input string function_name,
input string customization_str,
input longint unsigned msg_len,
input longint unsigned output_len,
Expand All @@ -70,6 +72,7 @@ package digestpp_dpi_pkg;
input longint unsigned msg_len,
input bit[7:0] key[],
input longint unsigned key_len,
input string customization_str,
input longint unsigned output_len,
output bit[7:0] digest[]
);
Expand All @@ -79,6 +82,7 @@ package digestpp_dpi_pkg;
input longint unsigned msg_len,
input bit[7:0] key[],
input longint unsigned key_len,
input string customization_str,
input longint unsigned output_len,
output bit[7:0] digest[]
);
Expand All @@ -88,6 +92,7 @@ package digestpp_dpi_pkg;
input longint unsigned msg_len,
input bit[7:0] key[],
input longint unsigned key_len,
input string customization_str,
input longint unsigned output_len,
output bit[7:0] digest[]
);
Expand All @@ -97,6 +102,7 @@ package digestpp_dpi_pkg;
input longint unsigned msg_len,
input bit[7:0] key[],
input longint unsigned key_len,
input string customization_str,
input longint unsigned output_len,
output bit[7:0] digest[]
);
Expand Down
2 changes: 2 additions & 0 deletions hw/ip/kmac/dv/env/kmac_env.core
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ filesets:
- lowrisc:dv:ralgen
- lowrisc:dv:cip_lib
- lowrisc:dv:push_pull_agent
- lowrisc:dv:str_utils
- lowrisc:dv:test_vectors
- lowrisc:dv:digestpp_dpi:0.1
- lowrisc:ip:kmac
files:
- kmac_env_pkg.sv
- kmac_sideload_if.sv
Expand Down
3 changes: 3 additions & 0 deletions hw/ip/kmac/dv/env/kmac_env_cfg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ class kmac_env_cfg extends cip_base_env_cfg #(.RAL_T(kmac_reg_block));
idle_vif idle_vif;
sideload_vif sideload_vif;

// Masked KMAC is the default configuration
bit enable_masking = 1;

`uvm_object_utils_begin(kmac_env_cfg)
`uvm_object_utils_end

Expand Down
30 changes: 28 additions & 2 deletions hw/ip/kmac/dv/env/kmac_env_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ package kmac_env_pkg;
import dv_utils_pkg::*;
import dv_lib_pkg::*;
import tl_agent_pkg::*;
import str_utils_pkg::*;
import test_vectors_pkg::*;
import digestpp_dpi_pkg::*;
import cip_base_pkg::*;
import csr_utils_pkg::*;
import push_pull_agent_pkg::*;
import kmac_ral_pkg::*;
import kmac_pkg::*;
import keymgr_pkg::*;

// macro includes
Expand All @@ -23,6 +25,27 @@ package kmac_env_pkg;

// parameters

// max number of shares in design
parameter int KMAC_NUM_SHARES = 2;

parameter int KMAC_NUM_KEYS_PER_SHARE = 16;

// share1 of the 1600-bit KMAC state memory
parameter bit [TL_AW-1:0] KMAC_STATE_SHARE0_BASE = 32'h400;
parameter bit [TL_AW-1:0] KMAC_STATE_SHARE0_END = 32'h4C7;

// share2 of the 1600-bit KMAC state memory
parameter bit [TL_AW-1:0] KMAC_STATE_SHARE1_BASE = 32'h500;
parameter bit [TL_AW-1:0] KMAC_STATE_SHARE1_END = 32'h5C7;

// base and end addresses of the KAMC message FIFO.
parameter bit [TL_AW-1:0] KMAC_FIFO_BASE = 32'h800;
parameter bit [TL_AW-1:0] KMAC_FIFO_END = 32'hFFC;

// Represents the max bit-width of some value to be encoded with either
// `right_encode()` or `left_encode()`.
parameter int MAX_ENCODE_WIDTH = 2040;

// Sideload data has 2*KeyWidth bits of key shares and 1 bit valid.
parameter int SIDELOAD_KEY_SIZE = $bits(hw_key_req_t);
// KDF request data has 1 bit for last, and the rest are for data/strb.
Expand All @@ -33,10 +56,13 @@ package kmac_env_pkg;
parameter int KDF_DIGEST_SIZE = $bits(kmac_data_rsp_t) - 1;

// types
typedef enum {

// interrupt types
typedef enum logic [1:0] {
KmacDone,
KmacFifoEmpty,
KmacErr
KmacErr,
KmacNumIntrs
} kmac_intr_e;

typedef virtual pins_if#(1) idle_vif;
Expand Down
25 changes: 19 additions & 6 deletions hw/ip/kmac/dv/env/kmac_scoreboard.sv
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ class kmac_scoreboard extends cip_base_scoreboard #(

virtual task process_tl_access(tl_seq_item item, tl_channels_e channel = DataChannel);
uvm_reg csr;
bit do_read_check = 1'b1;
bit write = item.is_write();
uvm_reg_addr_t csr_addr = ral.get_word_aligned_addr(item.a_addr);
bit do_read_check = 1'b1;
bit write = item.is_write();
uvm_reg_addr_t csr_addr = ral.get_word_aligned_addr(item.a_addr);
bit [TL_AW-1:0] csr_addr_mask = ral.get_addr_mask();

bit addr_phase_read = (!write && channel == AddrChannel);
bit addr_phase_write = (write && channel == AddrChannel);
Expand All @@ -44,8 +45,15 @@ class kmac_scoreboard extends cip_base_scoreboard #(
if (csr_addr inside {cfg.csr_addrs}) begin
csr = ral.default_map.get_reg_by_offset(csr_addr);
`DV_CHECK_NE_FATAL(csr, null)
end
else begin
end else if ((csr_addr & csr_addr_mask) inside {[KMAC_FIFO_BASE:KMAC_FIFO_END]}) begin
// msgfifo window
return;
end else if ((csr_addr & csr_addr_mask) inside
{[KMAC_STATE_SHARE0_BASE:KMAC_STATE_SHARE0_END],
[KMAC_STATE_SHARE1_BASE:KMAC_STATE_SHARE1_END]}) begin
// state digest window
return;
end else begin
`uvm_fatal(`gfn, $sformatf("Access unexpected addr 0x%0h", csr_addr))
end

Expand All @@ -69,8 +77,13 @@ class kmac_scoreboard extends cip_base_scoreboard #(
"intr_test": begin
// FIXME
end
"status": begin
// STATUS is read only
do_read_check = 1'b0;
end
default: begin
`uvm_fatal(`gfn, $sformatf("invalid csr: %0s", csr.get_full_name()))
// TODO: uncomment after implementing scoreboard
//`uvm_fatal(`gfn, $sformatf("invalid csr: %0s", csr.get_full_name()))
end
endcase

Expand Down
Loading