mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 12:57:13 -04:00
Update lowrisc_ip to lowRISC/opentitan@1740ccd1a
Update code from upstream repository https://github.com/lowRISC/opentitan to revision 1740ccd1ad19f83bf2cec120c87b807b9af2ca1b * [prim_onehot_check] Add address-based check (Michael Schaffner) * [flash_ctrl] convert flash config to mubi (Timothy Chen) * [sw,tests] Enter RMA LC_STATE and check flash access and wipe (Dave Williams) * [prim_onehot_check] Add lint waivers (Michael Schaffner) * [prim] Stub out guts of prim_cdc_rand_delay for Verilator (Rupert Swarbrick) * [prim] Add missing waiver (Timothy Chen) * [prim_onehot_check] Add prim_onehot_check (Michael Schaffner) * [dv] Add TL error case - write with instr_type = True (Weicai Yang) * [cdc-rand] Enable CDC random delay injection (Srikrishna Iyer) * [fpv/pinmux] Add tl integrity error check (Cindy Chen) * [prim_assert] Add static assertion macro for checks in pkgs (Michael Schaffner) * [prim] Add prim_blanker (Greg Chadwick) * [prim, rtl] Add new onehot primitives (Greg Chadwick) * [dvsim] Fix looping through old result directories (Cindy Chen) * [chip dv] Fixes for tests failing in nightly (Srikrishna Iyer) * [present] Rewrite TB to avoid non-freely licensed code (Rupert Swarbrick) * [secded_gen] Fix a bug in inverted Hamming codes (Michael Schaffner) * [prim,rtl] Fix RW collision bug in prim_1p_ram_scr (Greg Chadwick) * [dvsim,xcelium] Fix sed commands to generate plusargs (Rupert Swarbrick) * [dvsim,xcelium] Split two plusarg strings (Rupert Swarbrick) * [dvsim] Add a missing newline to error message (Rupert Swarbrick) Signed-off-by: Michael Schaffner <msf@google.com>
This commit is contained in:
parent
d819fa6296
commit
91745a076c
60 changed files with 1464 additions and 1408 deletions
2
vendor/lowrisc_ip.lock.hjson
vendored
2
vendor/lowrisc_ip.lock.hjson
vendored
|
@ -9,6 +9,6 @@
|
|||
upstream:
|
||||
{
|
||||
url: https://github.com/lowRISC/opentitan
|
||||
rev: 3a33c4df2ed31b0d7a8936531a4ae9a275177f1b
|
||||
rev: 1740ccd1ad19f83bf2cec120c87b807b9af2ca1b
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,6 +69,7 @@ class csr_base_seq extends uvm_reg_sequence #(uvm_sequence #(uvm_reg_item));
|
|||
models[i].get_registers(all_csrs);
|
||||
end
|
||||
|
||||
void'($value$plusargs("num_test_csrs=%0d", num_test_csrs));
|
||||
if (num_test_csrs != 0) begin
|
||||
num_csr_chunks = all_csrs.size / num_test_csrs + 1;
|
||||
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(test_csr_chunk,
|
||||
|
|
|
@ -541,3 +541,11 @@
|
|||
`ifndef BUILD_SEED
|
||||
`define BUILD_SEED 1
|
||||
`endif
|
||||
|
||||
// Max value out of 2 given expressions.
|
||||
//
|
||||
// Duplicate of dv_utils_pkg::max2() function, but this is better because
|
||||
// it can consume different data types directly without the need for casting.
|
||||
`ifndef DV_MAX2
|
||||
`define DV_MAX2(a, b) ((a) > (b) ? (a) : (b))
|
||||
`endif
|
||||
|
|
|
@ -53,6 +53,37 @@ virtual function void otp_write_secret0_partition(
|
|||
write64(Secret0DigestOffset, digest);
|
||||
endfunction
|
||||
|
||||
virtual function void otp_write_secret2_partition(bit [RmaTokenSize*8-1:0] rma_unlock_token,
|
||||
bit [CreatorRootKeyShare0Size*8-1:0] creator_root_key0,
|
||||
bit [CreatorRootKeyShare1Size*8-1:0] creator_root_key1
|
||||
);
|
||||
|
||||
bit [Secret2DigestSize*8-1:0] digest;
|
||||
|
||||
bit [RmaTokenSize*8-1:0] scrambled_unlock_token;
|
||||
bit [CreatorRootKeyShare0Size*8-1:0] scrambled_root_key0;
|
||||
bit [CreatorRootKeyShare1Size*8-1:0] scrambled_root_key1;
|
||||
bit [bus_params_pkg::BUS_DW-1:0] secret_data[$];
|
||||
|
||||
for (int i = 0; i < RmaTokenSize; i+=8) begin
|
||||
scrambled_unlock_token[i*8+:64] = scramble_data(rma_unlock_token[i*8+:64], Secret2Idx);
|
||||
write64(i + RmaTokenOffset, scrambled_unlock_token[i*8+:64]);
|
||||
end
|
||||
for (int i = 0; i < CreatorRootKeyShare0Size; i+=8) begin
|
||||
scrambled_root_key0[i*8+:64] = scramble_data(creator_root_key0[i*8+:64], Secret2Idx);
|
||||
write64(i + CreatorRootKeyShare0Offset, scrambled_root_key0[i*8+:64]);
|
||||
end
|
||||
for (int i = 0; i < CreatorRootKeyShare1Size; i+=8) begin
|
||||
scrambled_root_key1[i*8+:64] = scramble_data(creator_root_key1[i*8+:64], Secret2Idx);
|
||||
write64(i + CreatorRootKeyShare1Offset, scrambled_root_key1[i*8+:64]);
|
||||
end
|
||||
|
||||
secret_data = {<<32 {scrambled_root_key1, scrambled_root_key0, scrambled_unlock_token}};
|
||||
digest = cal_digest(Secret2Idx, secret_data);
|
||||
|
||||
write64(Secret2DigestOffset, digest);
|
||||
endfunction
|
||||
|
||||
virtual function void otp_write_hw_cfg_partition(
|
||||
bit [DeviceIdSize*8-1:0] device_id, bit [ManufStateSize*8-1:0] manuf_state,
|
||||
bit [EnSramIfetchSize*8-1:0] en_sram_ifetch,
|
||||
|
|
|
@ -27,12 +27,11 @@ package otp_scrambler_pkg;
|
|||
);
|
||||
|
||||
int secret_idx = part_idx - Secret0Idx;
|
||||
bit [NUM_ROUND-1:0][SCRAMBLE_DATA_SIZE-1:0] output_data;
|
||||
crypto_dpi_present_pkg::sv_dpi_present_encrypt(input_data,
|
||||
RndCnstKey[secret_idx],
|
||||
SCRAMBLE_KEY_SIZE == 80,
|
||||
output_data);
|
||||
scramble_data = output_data[NUM_ROUND-1];
|
||||
SCRAMBLE_KEY_SIZE,
|
||||
NUM_ROUND,
|
||||
scramble_data);
|
||||
endfunction
|
||||
|
||||
// When secret data read out of otp_array, it will be descrambled.
|
||||
|
@ -42,25 +41,20 @@ package otp_scrambler_pkg;
|
|||
);
|
||||
|
||||
int secret_idx = part_idx - Secret0Idx;
|
||||
bit [NUM_ROUND-1:0][SCRAMBLE_DATA_SIZE-1:0] output_data;
|
||||
bit [NUM_ROUND-1:0][SCRAMBLE_DATA_SIZE-1:0] padded_input;
|
||||
|
||||
padded_input[NUM_ROUND-1] = input_data;
|
||||
crypto_dpi_present_pkg::sv_dpi_present_decrypt(padded_input,
|
||||
crypto_dpi_present_pkg::sv_dpi_present_decrypt(input_data,
|
||||
RndCnstKey[secret_idx],
|
||||
SCRAMBLE_KEY_SIZE == 80,
|
||||
output_data);
|
||||
descramble_data = output_data[NUM_ROUND-1];
|
||||
if (input_data != 0) begin
|
||||
end
|
||||
SCRAMBLE_KEY_SIZE,
|
||||
NUM_ROUND,
|
||||
descramble_data);
|
||||
endfunction
|
||||
|
||||
function automatic bit [SCRAMBLE_DATA_SIZE-1:0] cal_digest(int part_idx,
|
||||
ref bit [BUS_DW-1:0] mem_q[$]);
|
||||
int array_size = mem_q.size();
|
||||
real key_factor = SCRAMBLE_KEY_SIZE / BUS_DW;
|
||||
bit [NUM_ROUND-1:0] [SCRAMBLE_DATA_SIZE-1:0] enc_array;
|
||||
bit [SCRAMBLE_DATA_SIZE-1:0] init_vec = RndCnstDigestIV[0];
|
||||
bit [SCRAMBLE_DATA_SIZE-1:0] enc_data;
|
||||
bit [SCRAMBLE_DATA_SIZE-1:0] digest;
|
||||
|
||||
for (int i = 0; i < $ceil(array_size / key_factor); i++) begin
|
||||
|
@ -76,19 +70,19 @@ package otp_scrambler_pkg;
|
|||
end
|
||||
|
||||
// Trigger 32 round of PRESENT encrypt.
|
||||
crypto_dpi_present_pkg::sv_dpi_present_encrypt(input_data, key, SCRAMBLE_KEY_SIZE == 80,
|
||||
enc_array);
|
||||
crypto_dpi_present_pkg::sv_dpi_present_encrypt(input_data, key, SCRAMBLE_KEY_SIZE,
|
||||
NUM_ROUND, enc_data);
|
||||
// XOR the previous state into the digest result according to the Davies-Meyer scheme.
|
||||
digest = enc_array[NUM_ROUND-1] ^ input_data;
|
||||
digest = enc_data ^ input_data;
|
||||
end
|
||||
|
||||
// Last 32 round of digest is calculated with a digest constant.
|
||||
crypto_dpi_present_pkg::sv_dpi_present_encrypt(digest,
|
||||
RndCnstDigestConst[0],
|
||||
SCRAMBLE_KEY_SIZE == 80,
|
||||
enc_array);
|
||||
SCRAMBLE_KEY_SIZE, NUM_ROUND,
|
||||
enc_data);
|
||||
// XOR the previous state into the digest result according to the Davies-Meyer scheme.
|
||||
digest ^= enc_array[NUM_ROUND-1];
|
||||
digest ^= enc_data;
|
||||
return digest;
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -70,7 +70,9 @@
|
|||
"+define+DUT_HIER={dut_instance}"]
|
||||
|
||||
run_opts: ["+UVM_NO_RELNOTES",
|
||||
"+UVM_VERBOSITY={expand_uvm_verbosity_{verbosity}}"]
|
||||
"+UVM_VERBOSITY={expand_uvm_verbosity_{verbosity}}",
|
||||
// TODO: remove once smoke regr passes:
|
||||
"+prim_cdc_rand_delay_mode=disable"]
|
||||
|
||||
// Default list of things to export to shell
|
||||
exports: [
|
||||
|
@ -116,22 +118,27 @@
|
|||
name: smoke
|
||||
tests: []
|
||||
reseed: 1
|
||||
// Knob used to configure an existing test / vseq to have a shorter runtime.
|
||||
run_opts: ["+smoke_test=1"]
|
||||
run_opts: [// Knob used to configure an existing test / vseq to have a shorter runtime.
|
||||
"+smoke_test=1",
|
||||
// Enable CDC random delay once, at the start of the sim.
|
||||
// TODO: uncomment once smoke regr passes:
|
||||
// "+prim_cdc_rand_delay_mode=once"
|
||||
]
|
||||
}
|
||||
|
||||
{
|
||||
name: all
|
||||
}
|
||||
|
||||
{
|
||||
name: all_once
|
||||
reseed: 1
|
||||
}
|
||||
|
||||
{
|
||||
name: nightly
|
||||
en_sim_modes: ["cov"]
|
||||
run_opts: [// Enable CDC random delay changes every 10 source data changes.
|
||||
// TODO: Uncomment once nightly regr passes:
|
||||
// "+prim_cdc_rand_delay_mode=interval", "+prim_cdc_rand_delay_interval=10"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
|
|
|
@ -28,7 +28,8 @@
|
|||
- write a CSR less than its width, e.g. when CSR is 2 bytes wide, only write 1 byte
|
||||
- write a memory with `a_mask != '1` when it doesn't support partial accesses
|
||||
- read a WO (write-only) memory
|
||||
- write a RO (read-only) memory'''
|
||||
- write a RO (read-only) memory
|
||||
- write with `instr_type = True`'''
|
||||
milestone: V2
|
||||
tests: ["{name}_tl_errors"]
|
||||
}
|
||||
|
|
|
@ -49,8 +49,8 @@
|
|||
// Xcelium generates an error (*E,OPTP2ND) if you pass an empty plusarg. To avoid doing so, these
|
||||
// two variables expand to e.g. "+UVM_TESTNAME=foo" if we have a test and the empty string if
|
||||
// not.
|
||||
uvm_testname_plusarg: "{eval_cmd} echo {uvm_test} | sed 's/\\(.+\\)/+UVM_TESTNAME=\\1/'"
|
||||
uvm_testseq_plusarg: "{eval_cmd} echo {uvm_test_seq} | sed 's/\\(.+\\)/+UVM_TEST_SEQ=\\1/'"
|
||||
uvm_testname_plusarg: "{eval_cmd} echo {uvm_test} | sed -E 's/(.+)/+UVM_TESTNAME=\\1/'"
|
||||
uvm_testseq_plusarg: "{eval_cmd} echo {uvm_test_seq} | sed -E 's/(.+)/+UVM_TEST_SEQ=\\1/'"
|
||||
|
||||
run_opts: ["-input {run_script}",
|
||||
"-licqueue",
|
||||
|
@ -58,7 +58,8 @@
|
|||
// Use the same snapshot name set during the build step.
|
||||
"-r {tb}",
|
||||
"+SVSEED={seed}",
|
||||
"{uvm_testname_plusarg} {uvm_testseq_plusarg}",
|
||||
"{uvm_testname_plusarg}",
|
||||
"{uvm_testseq_plusarg}",
|
||||
// Ignore "IEEE 1800-2009 SystemVerilog simulation semantics" warning
|
||||
"-nowarn DSEM2009",
|
||||
]
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
/*
|
||||
* S-Boxes and P-Boxes for
|
||||
* Implementation of PRESENT in C
|
||||
* v2.1, 10/13/2008
|
||||
*
|
||||
* Implementation is located at http://www.lightweightcrypto.org/implementations.php,
|
||||
* under the title "Testvectors for PRESENT".
|
||||
*
|
||||
* Thomas Siebert, thomas.siebert@rub.de
|
||||
*/
|
||||
|
||||
const uint8_t Sbox[16] = {12, 5, 6, 11, 9, 0, 10, 13, 3, 14, 15, 8, 4, 7, 1, 2};
|
||||
|
||||
const uint8_t SboxInv[16] = {5, 14, 15, 8, 12, 1, 2, 13,
|
||||
11, 4, 6, 3, 0, 7, 9, 10};
|
||||
|
||||
const uint8_t PboxInv[64] = {0, 16, 32, 48, 1, 17, 33, 49, 2, 18, 34, 50, 3,
|
||||
19, 35, 51, 4, 20, 36, 52, 5, 21, 37, 53, 6, 22,
|
||||
38, 54, 7, 23, 39, 55, 8, 24, 40, 56, 9, 25, 41,
|
||||
57, 10, 26, 42, 58, 11, 27, 43, 59, 12, 28, 44, 60,
|
||||
13, 29, 45, 61, 14, 30, 46, 62, 15, 31, 47, 63};
|
||||
|
||||
const uint8_t Pbox[64] = {0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48,
|
||||
52, 56, 60, 1, 5, 9, 13, 17, 21, 25, 29, 33, 37,
|
||||
41, 45, 49, 53, 57, 61, 2, 6, 10, 14, 18, 22, 26,
|
||||
30, 34, 38, 42, 46, 50, 54, 58, 62, 3, 7, 11, 15,
|
||||
19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63};
|
|
@ -1,196 +0,0 @@
|
|||
/*
|
||||
* Commandline-Option-Fetcher for
|
||||
* Implementation of PRESENT in C
|
||||
* v2.1, 10/13/2008
|
||||
*
|
||||
* Implementation is located at http://www.lightweightcrypto.org/implementations.php,
|
||||
* under the title "Testvectors for PRESENT".
|
||||
*
|
||||
* Thomas Siebert, thomas.siebert@rub.de
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
|
||||
//----------------------------------
|
||||
// Function prototype
|
||||
//----------------------------------
|
||||
// void comline_fetch_options( struct Options * , int , char ** );
|
||||
|
||||
//----------------------------------
|
||||
// Struct declaration
|
||||
//----------------------------------
|
||||
struct Options {
|
||||
_Bool Error;
|
||||
_Bool Mode;
|
||||
_Bool KeySize80;
|
||||
uint8_t Verbose;
|
||||
uint64_t KeyHigh;
|
||||
uint64_t KeyLow;
|
||||
uint64_t Text;
|
||||
uint16_t Rounds;
|
||||
};
|
||||
|
||||
#define Encrypt_Mode 1
|
||||
#define Decrypt_Mode 0
|
||||
|
||||
//----------------------------------
|
||||
// Functions
|
||||
//----------------------------------
|
||||
void comline_fetch_options(struct Options *sOpt, int argc, char **const argv) {
|
||||
int c;
|
||||
_Bool Opt_Decrypt = 0, Opt_Encrypt = 0, Opt_File = 0, Opt_Verbose = 0;
|
||||
char *Opt_Text = NULL, *Opt_Key = NULL, *Opt_Rounds = NULL;
|
||||
FILE *KeyFile = NULL, *TextFile = NULL;
|
||||
int keyres;
|
||||
|
||||
sOpt->Error = 0;
|
||||
sOpt->Verbose = 1;
|
||||
|
||||
while ((c = getopt(argc, argv, "defv:r:k:t:")) !=
|
||||
-1) // Cycle through Options
|
||||
{
|
||||
switch (c) // set flags
|
||||
{
|
||||
case 'd':
|
||||
if (Opt_Encrypt || Opt_Decrypt)
|
||||
sOpt->Error = 1;
|
||||
else
|
||||
Opt_Decrypt = 1;
|
||||
break;
|
||||
case 'e':
|
||||
if (Opt_Encrypt || Opt_Decrypt)
|
||||
sOpt->Error = 1;
|
||||
else
|
||||
Opt_Encrypt = 1;
|
||||
break;
|
||||
case 'f':
|
||||
if (Opt_File)
|
||||
sOpt->Error = 1;
|
||||
else
|
||||
Opt_File = 1;
|
||||
break;
|
||||
case 'v':
|
||||
if (Opt_Verbose)
|
||||
sOpt->Error = 1;
|
||||
else if (optarg != NULL) {
|
||||
if (strcmp(optarg, "0") == 0)
|
||||
sOpt->Verbose = 0;
|
||||
else if (strcmp(optarg, "1") == 0)
|
||||
sOpt->Verbose = 1;
|
||||
else if (strcmp(optarg, "2") == 0)
|
||||
sOpt->Verbose = 2;
|
||||
else
|
||||
sOpt->Error = 1;
|
||||
} else
|
||||
sOpt->Error = 1;
|
||||
Opt_Verbose = 1;
|
||||
break;
|
||||
case 'k':
|
||||
if (Opt_Key != NULL)
|
||||
sOpt->Error = 1;
|
||||
else
|
||||
Opt_Key = optarg;
|
||||
break;
|
||||
case 'r':
|
||||
if (Opt_Rounds)
|
||||
sOpt->Error = 1;
|
||||
else
|
||||
Opt_Rounds = optarg;
|
||||
break;
|
||||
case 't':
|
||||
if (Opt_Text != NULL)
|
||||
sOpt->Error = 1;
|
||||
else
|
||||
Opt_Text = optarg;
|
||||
break;
|
||||
case '?':
|
||||
sOpt->Error = 1;
|
||||
break;
|
||||
}
|
||||
} // End Option-Cycle
|
||||
|
||||
// Set Error if Parameters missing
|
||||
if (Opt_Key == NULL || Opt_Text == NULL || (!(Opt_Decrypt || Opt_Encrypt))) {
|
||||
sOpt->Error = 1;
|
||||
}
|
||||
|
||||
else {
|
||||
// Handle Rounds Parameter
|
||||
if (Opt_Rounds != NULL) // if Round Param there...
|
||||
{
|
||||
if (strlen(Opt_Rounds) < 6) // check length
|
||||
{
|
||||
uint32_t Rounds;
|
||||
sscanf(Opt_Rounds, "%5" SCNu32 "", &Rounds); // get round no.
|
||||
if ((Rounds > 65534) || Rounds == 0)
|
||||
sOpt->Error = 1; // check 0<Rounds<65535
|
||||
else
|
||||
sOpt->Rounds = Rounds; // override roundno.
|
||||
} else
|
||||
sOpt->Error = 1;
|
||||
} else
|
||||
sOpt->Rounds = 32; //...else use standard
|
||||
|
||||
// Check if decrypt or encrypt mode
|
||||
if (Opt_Encrypt)
|
||||
sOpt->Mode = Encrypt_Mode;
|
||||
else
|
||||
sOpt->Mode = Decrypt_Mode;
|
||||
|
||||
// Read key and text (file mode)
|
||||
if (Opt_File) {
|
||||
KeyFile = fopen(Opt_Key, "r");
|
||||
TextFile = fopen(Opt_Text, "r");
|
||||
|
||||
if (!((KeyFile == NULL) || (TextFile) == NULL)) {
|
||||
fseek(KeyFile, 0, SEEK_END);
|
||||
if ((ftell(KeyFile)) >= 32) {
|
||||
fseek(KeyFile, 0, SEEK_SET);
|
||||
if (fscanf(KeyFile, "%016" SCNx64 "", &sOpt->KeyHigh) == 0)
|
||||
sOpt->Error = 1;
|
||||
if (fscanf(KeyFile, "%016" SCNx64 "", &sOpt->KeyLow) == 0)
|
||||
sOpt->Error = 1;
|
||||
sOpt->KeySize80 = 0;
|
||||
} else if ((ftell(KeyFile)) >= 20) {
|
||||
fseek(KeyFile, 0, SEEK_SET);
|
||||
if (fscanf(KeyFile, "%016" SCNx64 "", &sOpt->KeyHigh) == 0)
|
||||
sOpt->Error = 1;
|
||||
if (fscanf(KeyFile, "%04" SCNx16 "", &sOpt->KeyLow) == 0)
|
||||
sOpt->Error = 1;
|
||||
sOpt->KeySize80 = 1;
|
||||
} else
|
||||
sOpt->Error = 1;
|
||||
if (fscanf(TextFile, "%016" SCNx64 "", &sOpt->Text) == EOF)
|
||||
sOpt->Error = 1;
|
||||
} else
|
||||
sOpt->Error = 1;
|
||||
if (!(KeyFile == NULL))
|
||||
fclose(KeyFile);
|
||||
if (!(TextFile == NULL))
|
||||
fclose(TextFile);
|
||||
}
|
||||
|
||||
// Read key and text (commandline mode)
|
||||
else {
|
||||
if (((strlen(Opt_Key) != 32) && (strlen(Opt_Key) != 20)) ||
|
||||
(strlen(Opt_Text) != 16)) { // if wrong length...
|
||||
sOpt->Error = 1; // set error
|
||||
}
|
||||
|
||||
if (!(sOpt->Error)) // if no error...
|
||||
{
|
||||
sscanf(Opt_Key, "%016" SCNx64 "", &sOpt->KeyHigh); // get values
|
||||
if (strlen(Opt_Key) == 20) // set key + size
|
||||
{
|
||||
sOpt->KeySize80 = 1;
|
||||
sscanf(Opt_Key + 16, "%016" SCNx16 "", &sOpt->KeyLow);
|
||||
} else {
|
||||
sOpt->KeySize80 = 0;
|
||||
sscanf(Opt_Key + 16, "%016" SCNx64 "", &sOpt->KeyLow);
|
||||
}
|
||||
sscanf(Opt_Text, "%016" SCNx64 "", &sOpt->Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#include "present.inc"
|
||||
#include "svdpi.h"
|
||||
|
||||
typedef unsigned long long int ull_t;
|
||||
|
||||
// Helper function used only by this C file.
|
||||
// Returns the key schedule corresponding to the input key.
|
||||
uint64_t *get_key_schedule(uint64_t key_high, uint64_t key_low,
|
||||
uint8_t num_rounds, uint8_t key_size_80) {
|
||||
return key_schedule(key_high, key_low, num_rounds, (_Bool)key_size_80, 0);
|
||||
}
|
||||
|
||||
extern void c_dpi_key_schedule(uint64_t key_high, uint64_t key_low,
|
||||
uint8_t num_rounds, uint8_t key_size_80,
|
||||
svBitVecVal *key_array) {
|
||||
uint64_t *key_schedule = (uint64_t *)malloc(num_rounds * sizeof(uint64_t));
|
||||
uint64_t key;
|
||||
svBitVecVal key_hi;
|
||||
svBitVecVal key_lo;
|
||||
|
||||
// get the key schedule from the C model
|
||||
key_schedule = get_key_schedule(key_high, key_low, num_rounds, key_size_80);
|
||||
|
||||
// write the key schedule to simulation
|
||||
int i;
|
||||
for (i = 0; i < num_rounds; i++) {
|
||||
key = key_schedule[i];
|
||||
key_hi = (svBitVecVal)(key >> 32);
|
||||
key_lo = (svBitVecVal)(key & 0xFFFFFFFF);
|
||||
key_array[i * 2] = key_lo;
|
||||
key_array[i * 2 + 1] = key_hi;
|
||||
}
|
||||
|
||||
// free allocated memory
|
||||
free(key_schedule);
|
||||
}
|
||||
|
||||
extern uint64_t c_dpi_encrypt(uint64_t plaintext, uint64_t key_high,
|
||||
uint64_t key_low, uint8_t num_rounds,
|
||||
uint8_t key_size_80) {
|
||||
uint64_t encrypt_result;
|
||||
uint64_t *key_schedule = (uint64_t *)malloc(num_rounds * sizeof(uint64_t));
|
||||
|
||||
key_schedule = get_key_schedule(key_high, key_low, num_rounds, key_size_80);
|
||||
encrypt_result = (uint64_t)encrypt(plaintext, key_schedule, num_rounds, 0);
|
||||
free(key_schedule);
|
||||
return encrypt_result;
|
||||
}
|
||||
|
||||
extern uint64_t c_dpi_decrypt(uint64_t ciphertext, uint64_t key_high,
|
||||
uint64_t key_low, uint8_t num_rounds,
|
||||
uint8_t key_size_80) {
|
||||
uint64_t decrypt_result;
|
||||
uint64_t *key_schedule = (uint64_t *)malloc(sizeof(uint64_t));
|
||||
|
||||
key_schedule = get_key_schedule(key_high, key_low, num_rounds, key_size_80);
|
||||
decrypt_result = (uint64_t)decrypt(ciphertext, key_schedule, num_rounds, 0);
|
||||
free(key_schedule);
|
||||
return decrypt_result;
|
||||
}
|
257
vendor/lowrisc_ip/ip/prim/dv/prim_present/crypto_dpi_present/crypto_dpi_present.cc
vendored
Normal file
257
vendor/lowrisc_ip/ip/prim/dv/prim_present/crypto_dpi_present/crypto_dpi_present.cc
vendored
Normal file
|
@ -0,0 +1,257 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// Simple unhardened reference implementation of the PRESENT cipher, following
|
||||
// the description in
|
||||
//
|
||||
// [1] Bognadov et al, PRESENT: An Ultra-Lightweight Block Cipher. LNCS 4727:
|
||||
// 450–466. doi:10.1007/978-3-540-74735-2_31.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <svdpi.h>
|
||||
#include <vector>
|
||||
|
||||
static const uint8_t sbox4[16] = {0xc, 0x5, 0x6, 0xb, 0x9, 0x0, 0xa, 0xd,
|
||||
0x3, 0xe, 0xf, 0x8, 0x4, 0x7, 0x1, 0x2};
|
||||
|
||||
static const uint8_t sbox4_inv[16] = {0x5, 0xe, 0xf, 0x8, 0xc, 0x1, 0x2, 0xd,
|
||||
0xb, 0x4, 0x6, 0x3, 0x0, 0x7, 0x9, 0xa};
|
||||
|
||||
static const uint8_t bit_perm[64] = {
|
||||
0, 16, 32, 48, 1, 17, 33, 49, 2, 18, 34, 50, 3, 19, 35, 51,
|
||||
4, 20, 36, 52, 5, 21, 37, 53, 6, 22, 38, 54, 7, 23, 39, 55,
|
||||
8, 24, 40, 56, 9, 25, 41, 57, 10, 26, 42, 58, 11, 27, 43, 59,
|
||||
12, 28, 44, 60, 13, 29, 45, 61, 14, 30, 46, 62, 15, 31, 47, 63};
|
||||
|
||||
static const uint8_t bit_perm_inv[64] = {
|
||||
0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60,
|
||||
1, 5, 9, 13, 17, 21, 25, 29, 33, 37, 41, 45, 49, 53, 57, 61,
|
||||
2, 6, 10, 14, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 62,
|
||||
3, 7, 11, 15, 19, 23, 27, 31, 35, 39, 43, 47, 51, 55, 59, 63};
|
||||
|
||||
static uint64_t mask64(int bits) { return ((uint64_t)1 << bits) - 1; }
|
||||
|
||||
namespace {
|
||||
struct key128_t {
|
||||
uint64_t hi, lo;
|
||||
};
|
||||
|
||||
class PresentState {
|
||||
public:
|
||||
PresentState(unsigned key_size, key128_t key);
|
||||
|
||||
// This is the body of the for loop in Fig. 1 of the paper ([1], above). If
|
||||
// is_last_round, then it also includes the call to addRoundKey that follows.
|
||||
uint64_t enc_round(uint64_t input, unsigned round, bool is_last_round) const;
|
||||
|
||||
// The inverse of enc_round. Note that a decryption should start with a high
|
||||
// round and with is_last_round set, then count down.
|
||||
uint64_t dec_round(uint64_t input, unsigned round, bool is_last_round) const;
|
||||
|
||||
private:
|
||||
static key128_t next_round_key(const key128_t &k, unsigned key_size,
|
||||
unsigned round_count);
|
||||
|
||||
static uint64_t add_round_key(uint64_t data, const key128_t &k,
|
||||
unsigned key_size);
|
||||
static uint64_t sbox_layer(bool inverse, uint64_t data);
|
||||
static uint64_t perm_layer(bool inverse, uint64_t data);
|
||||
|
||||
unsigned key_size;
|
||||
std::vector<key128_t> key_schedule;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
PresentState::PresentState(unsigned key_size, key128_t key)
|
||||
: key_size(key_size) {
|
||||
assert(key_size == 80 || key_size == 128);
|
||||
key_schedule.reserve(32);
|
||||
key_schedule.push_back(key);
|
||||
for (int i = 1; i <= 31; ++i) {
|
||||
key = next_round_key(key, key_size, i);
|
||||
key_schedule.push_back(key);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t PresentState::enc_round(uint64_t input, unsigned round,
|
||||
bool is_last_round) const {
|
||||
assert(1 <= round && round < key_schedule.size());
|
||||
const key128_t &key = key_schedule[round - 1];
|
||||
|
||||
// addRoundKey
|
||||
uint64_t w1 = add_round_key(input, key, key_size);
|
||||
|
||||
// sBoxLayer
|
||||
uint64_t w2 = sbox_layer(false, w1);
|
||||
|
||||
// pLayer
|
||||
uint64_t w3 = perm_layer(false, w2);
|
||||
|
||||
// On the final round, call addRoundKey with the following key.
|
||||
uint64_t w4 =
|
||||
is_last_round ? add_round_key(w3, key_schedule[round], key_size) : w3;
|
||||
|
||||
return w4;
|
||||
}
|
||||
|
||||
uint64_t PresentState::dec_round(uint64_t input, unsigned round,
|
||||
bool is_last_round) const {
|
||||
assert(1 <= round && round < key_schedule.size());
|
||||
const key128_t &key = key_schedule[round - 1];
|
||||
|
||||
// If we're undoing the last round, start by calling addRoundKey with the
|
||||
// following key.
|
||||
uint64_t w1 = is_last_round
|
||||
? add_round_key(input, key_schedule[round], key_size)
|
||||
: input;
|
||||
|
||||
// pLayer^{-1}
|
||||
uint64_t w2 = perm_layer(true, w1);
|
||||
|
||||
// sBoxLayer^{-1}
|
||||
uint64_t w3 = sbox_layer(true, w2);
|
||||
|
||||
// addRoundKey
|
||||
uint64_t w4 = add_round_key(w3, key, key_size);
|
||||
|
||||
return w4;
|
||||
}
|
||||
|
||||
key128_t PresentState::next_round_key(const key128_t &k, unsigned key_size,
|
||||
unsigned round_count) {
|
||||
assert((round_count >> 5) == 0);
|
||||
assert(key_size == 80 || key_size == 128);
|
||||
|
||||
if (key_size == 80) {
|
||||
assert((k.hi >> 16) == 0);
|
||||
|
||||
// Rotate the key left by 61 bits
|
||||
//
|
||||
// The top word (bits 79:64) will come from bits (18:3). The
|
||||
// bottom word (bits 63:0) will have bits 2:0 at the top, then
|
||||
// bits 79:64 (from the top word) and finally bits 63:19.
|
||||
uint64_t rot_hi = (k.lo >> 3) & mask64(16);
|
||||
uint64_t rot_lo =
|
||||
((((k.lo >> 0) & mask64(3)) << 61) | (((k.hi >> 0)) << 45) |
|
||||
(((k.lo >> 19) & mask64(45)) << 0));
|
||||
assert((rot_hi >> 16) == 0);
|
||||
|
||||
// Pass the top 4 bits through sbox4
|
||||
uint64_t subst_hi =
|
||||
(((uint64_t)sbox4[rot_hi >> 12] << 12) | (rot_hi & mask64(12)));
|
||||
uint64_t subst_lo = rot_lo;
|
||||
|
||||
// XOR bits 19:15 with the round counter
|
||||
uint64_t xored_hi = subst_hi;
|
||||
uint64_t xored_lo =
|
||||
((subst_lo & ~mask64(20)) |
|
||||
((((subst_lo >> 15) & mask64(5)) ^ round_count) << 15) |
|
||||
(subst_lo >> 0 & mask64(15)));
|
||||
|
||||
key128_t next = {.hi = xored_hi, .lo = xored_lo};
|
||||
return next;
|
||||
} else {
|
||||
// Rotate the key left by 61 bits
|
||||
//
|
||||
// The top word (bits 127:64) will come from bits 66:64 (from the
|
||||
// top word) and then bits 63:3 (from the bottom word). The bottom
|
||||
// word (bits 63:0) will have bits 2:0 at the top and then bits
|
||||
// 127:67.
|
||||
uint64_t rot_hi = (((k.hi & mask64(3)) << 61) | (k.lo >> 3));
|
||||
uint64_t rot_lo = (((k.lo & mask64(3)) << 61) | (k.hi >> 3));
|
||||
|
||||
// Pass top 8 bits through a pair of sbox4's
|
||||
uint64_t rot_nib124 = (rot_hi >> 60) & mask64(4);
|
||||
uint64_t rot_nib120 = (rot_hi >> 56) & mask64(4);
|
||||
|
||||
uint64_t subst_hi =
|
||||
(((uint64_t)sbox4[rot_nib124] << 60) |
|
||||
((uint64_t)sbox4[rot_nib120] << 56) | (rot_hi & mask64(56)));
|
||||
uint64_t subst_lo = rot_lo;
|
||||
|
||||
// XOR bits 66:62
|
||||
uint64_t xored_hi = subst_hi ^ ((uint64_t)round_count >> 2);
|
||||
uint64_t xored_lo = subst_lo ^ ((uint64_t)round_count << 62);
|
||||
|
||||
key128_t next = {.hi = xored_hi, .lo = xored_lo};
|
||||
return next;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t PresentState::add_round_key(uint64_t data, const key128_t &k,
|
||||
unsigned key_size) {
|
||||
assert(key_size == 80 || key_size == 128);
|
||||
uint64_t k64 = (key_size == 80) ? ((k.hi << 48) | (k.lo >> 16)) : k.hi;
|
||||
return data ^ k64;
|
||||
}
|
||||
|
||||
uint64_t PresentState::sbox_layer(bool inverse, uint64_t data) {
|
||||
uint64_t ret = 0;
|
||||
for (int i = 0; i < 64 / 4; ++i) {
|
||||
unsigned nibble = (data >> (4 * i)) & 0xf;
|
||||
uint64_t subst = inverse ? sbox4_inv[nibble] : sbox4[nibble];
|
||||
ret |= subst << (4 * i);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint64_t PresentState::perm_layer(bool inverse, uint64_t data) {
|
||||
uint64_t ret = 0;
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
uint64_t bit = (data >> i) & 1;
|
||||
ret |= bit << (inverse ? bit_perm_inv[i] : bit_perm[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
PresentState *c_dpi_present_mk(unsigned key_size, const svBitVecVal *key) {
|
||||
assert(key_size == 80 || key_size == 128);
|
||||
|
||||
// Each element of key represents 32 bits. Unpack into a key128_t, zeroing
|
||||
// the top bits if key size was 80.
|
||||
uint32_t w32s[4];
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
unsigned lsb = 32 * i;
|
||||
unsigned bits_left = (lsb < key_size) ? key_size - lsb : 0;
|
||||
unsigned mask =
|
||||
(bits_left < 32) ? ((uint32_t)1 << bits_left) - 1 : ~(uint32_t)0;
|
||||
w32s[i] = key[i] & mask;
|
||||
}
|
||||
key128_t k128 = {.hi = ((uint64_t)w32s[3] << 32) | w32s[2],
|
||||
.lo = ((uint64_t)w32s[1] << 32) | w32s[0]};
|
||||
|
||||
return new PresentState(key_size, k128);
|
||||
}
|
||||
|
||||
void c_dpi_present_free(PresentState *ps) { delete ps; }
|
||||
|
||||
void c_dpi_present_enc_round(const PresentState *ps, unsigned round,
|
||||
unsigned char is_last_round,
|
||||
const svBitVecVal *src, svBitVecVal *dst) {
|
||||
assert(ps);
|
||||
assert(is_last_round == 0 || is_last_round == 1);
|
||||
|
||||
uint64_t in64 = ((uint64_t)src[1] << 32) | src[0];
|
||||
uint64_t out64 = ps->enc_round(in64, round, is_last_round != 0);
|
||||
|
||||
dst[1] = out64 >> 32;
|
||||
dst[0] = (uint32_t)out64;
|
||||
}
|
||||
|
||||
void c_dpi_present_dec_round(const PresentState *ps, unsigned round,
|
||||
unsigned char is_last_round,
|
||||
const svBitVecVal *src, svBitVecVal *dst) {
|
||||
assert(ps);
|
||||
assert(is_last_round == 0 || is_last_round == 1);
|
||||
|
||||
uint64_t in64 = ((uint64_t)src[1] << 32) | src[0];
|
||||
uint64_t out64 = ps->dec_round(in64, round, is_last_round != 0);
|
||||
|
||||
dst[1] = out64 >> 32;
|
||||
dst[0] = (uint32_t)out64;
|
||||
}
|
||||
}
|
|
@ -7,11 +7,7 @@ description: "PRESENT block cipher reference implementation in C from Ruhr-Unive
|
|||
filesets:
|
||||
files_dv:
|
||||
files:
|
||||
- boxes.inc: {file_type: cSource, is_include_file: true}
|
||||
- comline.inc: {file_type: cSource, is_include_file: true}
|
||||
- verbose.inc: {file_type: cSource, is_include_file: true}
|
||||
- present.inc: {file_type: cSource, is_include_file: true}
|
||||
- crypto_dpi_present.c: {file_type: cSource}
|
||||
- crypto_dpi_present.cc: {file_type: cppSource}
|
||||
- crypto_dpi_present_pkg.sv: {file_type: systemVerilogSource}
|
||||
file_type: cSource
|
||||
|
||||
|
|
|
@ -3,117 +3,76 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package crypto_dpi_present_pkg;
|
||||
|
||||
// dep packages
|
||||
import uvm_pkg::*;
|
||||
|
||||
// parameters
|
||||
|
||||
// This is defined here so we can size all arrays properly.
|
||||
parameter int unsigned NumRounds = 31;
|
||||
// PRESENT expects up to 31 rounds in total
|
||||
localparam int unsigned MaxRounds = 31;
|
||||
localparam int unsigned MaxKeyWidth = 128;
|
||||
localparam int unsigned DataWidth = 64;
|
||||
|
||||
// DPI-C imports
|
||||
import "DPI-C" context function void c_dpi_key_schedule(
|
||||
input longint unsigned key_high,
|
||||
input longint unsigned key_low,
|
||||
input int unsigned num_rounds,
|
||||
input int unsigned key_size_80,
|
||||
output bit [NumRounds:0][63:0] key_schedule
|
||||
);
|
||||
import "DPI-C" function chandle c_dpi_present_mk(int unsigned key_size,
|
||||
bit [MaxKeyWidth-1:0] key);
|
||||
import "DPI-C" function void c_dpi_present_free(chandle h);
|
||||
|
||||
import "DPI-C" context function longint c_dpi_encrypt(
|
||||
input longint unsigned plaintext,
|
||||
input longint unsigned key_high,
|
||||
input longint unsigned key_low,
|
||||
input int unsigned num_rounds,
|
||||
input int unsigned key_size_80
|
||||
);
|
||||
import "DPI-C" function void c_dpi_present_enc_round(chandle h,
|
||||
int unsigned round,
|
||||
bit is_last_round,
|
||||
bit [DataWidth-1:0] in,
|
||||
output bit [DataWidth-1:0] out);
|
||||
import "DPI-C" function void c_dpi_present_dec_round(chandle h,
|
||||
int unsigned round,
|
||||
bit is_last_round,
|
||||
bit [DataWidth-1:0] in,
|
||||
output bit [DataWidth-1:0] out);
|
||||
|
||||
import "DPI-C" context function longint c_dpi_decrypt(
|
||||
input longint unsigned ciphertext,
|
||||
input longint unsigned key_high,
|
||||
input longint unsigned key_low,
|
||||
input int unsigned num_rounds,
|
||||
input int unsigned key_size_80
|
||||
);
|
||||
|
||||
// Helper Functions
|
||||
function automatic void get_keys(input bit [127:0] key,
|
||||
input bit key_size_80,
|
||||
output bit [63:0] key_high,
|
||||
output bit [63:0] key_low);
|
||||
key_high = (key_size_80) ? key[79:16] : key[127:64];
|
||||
key_low = (key_size_80) ? key[15:0] : key[63:0];
|
||||
endfunction
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// SV wrapper functions to be used by the testbench //
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
// This function takes in a 128 bit key by default, it determines how to
|
||||
// split this key for the DPI calls based on the value of key_size_80.
|
||||
// This function encrypts the input plaintext with the PRESENT encryption algorithm.
|
||||
//
|
||||
// This returns the list of round keys used during the course of the algorithm.
|
||||
function automatic void sv_dpi_present_get_key_schedule(
|
||||
input bit [127:0] key,
|
||||
input bit key_size_80,
|
||||
output bit [NumRounds:0][63:0] key_schedule
|
||||
);
|
||||
bit [63:0] key_high, key_low;
|
||||
bit [(NumRounds*2)+1:0][31:0] compressed_key_schedule;
|
||||
|
||||
get_keys(key, key_size_80, key_high, key_low);
|
||||
|
||||
c_dpi_key_schedule(key_high, key_low, NumRounds+1, key_size_80, compressed_key_schedule);
|
||||
|
||||
for (int i = 0; i < NumRounds+1; i++) begin
|
||||
key_schedule[i][31:0] = compressed_key_schedule[i*2];
|
||||
key_schedule[i][63:32] = compressed_key_schedule[i*2+1];
|
||||
end
|
||||
|
||||
endfunction
|
||||
|
||||
// This function encrypts the input plaintext with the PRESENT encryption
|
||||
// algorithm using the specified number of rounds.
|
||||
//
|
||||
// This produces a list of all intermediate values produced after each round
|
||||
// of the algorithm, including the final encrypted ciphertext value.
|
||||
// This produces a list of all intermediate values produced after each round of the algorithm,
|
||||
// including the final encrypted ciphertext value.
|
||||
function automatic void sv_dpi_present_encrypt(
|
||||
input bit [63:0] plaintext,
|
||||
input bit [127:0] key,
|
||||
input bit key_size_80,
|
||||
output bit [NumRounds-1:0][63:0] encrypted_values
|
||||
input bit [DataWidth-1:0] plaintext,
|
||||
input bit [MaxKeyWidth-1:0] key,
|
||||
input int unsigned key_size,
|
||||
input int unsigned num_rounds,
|
||||
output bit [DataWidth-1:0] ciphertext
|
||||
);
|
||||
|
||||
bit [63:0] key_high, key_low;
|
||||
bit [DataWidth-1:0] round_in, round_out;
|
||||
chandle h = c_dpi_present_mk(key_size, key);
|
||||
|
||||
get_keys(key, key_size_80, key_high, key_low);
|
||||
|
||||
for (int i = 1; i <= NumRounds; i++) begin
|
||||
encrypted_values[i-1] = c_dpi_encrypt(plaintext, key_high, key_low, i+1, key_size_80);
|
||||
round_out = plaintext;
|
||||
for (int i = 1; i <= num_rounds; i++) begin
|
||||
round_in = round_out;
|
||||
c_dpi_present_enc_round(h, i, i == num_rounds, round_in, round_out);
|
||||
end
|
||||
ciphertext = round_out;
|
||||
|
||||
c_dpi_present_free(h);
|
||||
|
||||
endfunction
|
||||
|
||||
// This function decrypts the input ciphertext with the PRESENT decryption
|
||||
// algorithm using the specified number of rounds.
|
||||
// This function decrypts the input ciphertext with the PRESENT decryption algorithm.
|
||||
//
|
||||
// This produces a list of all intermediate values produced after each round
|
||||
// of the algorithm, including the final decrypted plaintext value.
|
||||
// This produces a list of all intermediate values produced after each round of the algorithm,
|
||||
// including the final decrypted plaintext value.
|
||||
function automatic void sv_dpi_present_decrypt(
|
||||
input bit [NumRounds-1:0][63:0] ciphertext,
|
||||
input bit [127:0] key,
|
||||
input bit key_size_80,
|
||||
output bit [NumRounds-1:0][63:0] decrypted_values
|
||||
input bit [DataWidth-1:0] ciphertext,
|
||||
input bit [MaxKeyWidth-1:0] key,
|
||||
input int unsigned key_size,
|
||||
input int unsigned num_rounds,
|
||||
output bit [DataWidth-1:0] plaintext
|
||||
);
|
||||
|
||||
bit [63:0] key_high, key_low;
|
||||
bit [DataWidth-1:0] round_in, round_out;
|
||||
chandle h = c_dpi_present_mk(key_size, key);
|
||||
|
||||
get_keys(key, key_size_80, key_high, key_low);
|
||||
|
||||
for (int i = 1; i <= NumRounds; i++) begin
|
||||
decrypted_values[i-1] = c_dpi_decrypt(ciphertext[i-1], key_high, key_low, i+1, key_size_80);
|
||||
round_in = ciphertext;
|
||||
for (int i = num_rounds; i > 0; i--) begin
|
||||
c_dpi_present_dec_round(h, i, i == num_rounds, round_in, round_out);
|
||||
round_in = round_out;
|
||||
end
|
||||
plaintext = round_out;
|
||||
|
||||
c_dpi_present_free(h);
|
||||
|
||||
endfunction
|
||||
|
||||
|
|
|
@ -1,396 +0,0 @@
|
|||
/*
|
||||
* Implementation of PRESENT in C
|
||||
* v2.1, 10/13/2008
|
||||
*
|
||||
* Implementation is located at http://www.lightweightcrypto.org/implementations.php,
|
||||
* under the title "Testvectors for PRESENT".
|
||||
*
|
||||
* Thomas Siebert, thomas.siebert@rub.de
|
||||
*
|
||||
*
|
||||
* Your Compiler currently should support
|
||||
* the ANSI-C99-standard.
|
||||
*
|
||||
* Tested with gcc (with Option -std=c99)
|
||||
*/
|
||||
|
||||
//----------------------------------
|
||||
// Includes
|
||||
//----------------------------------
|
||||
#include "verbose.inc" //For verbose output
|
||||
#include "comline.inc" //Command Line
|
||||
#include "boxes.inc" //S-Boxes and P-Boxes
|
||||
#include <stdlib.h>
|
||||
|
||||
//----------------------------------
|
||||
// Macros for bit manipulation
|
||||
//----------------------------------
|
||||
//returns...
|
||||
#define high45_64(h45in) ((uint64_t)h45in >> 9) // 45 msb as lsb
|
||||
#define high61_64(h4in) ((uint64_t)h4in >> 3) // 61 msb as lsb
|
||||
#define high4_64(h4in) ((uint64_t)h4in >> 60) // 4 msb as lsb
|
||||
#define high8to4_64(h8in) (((uint64_t)h8in >> 56) & 0x0F) // 4 msb as 2. lsb
|
||||
#define high16_64(h16in) ((uint64_t)h16in >> 48) // 16 msb as lsb
|
||||
#define high1_64(h1in) ((uint64_t)h1in >> 63) // msb as lsb
|
||||
#define low4_64(l4in) ((uint64_t)l4in << 60) // 4 lsb as msb
|
||||
#define low8to4_64(l4in) ((uint64_t)l4in << 56) // 4 lsb as 2. msb
|
||||
#define low16_64(l4in) ((uint64_t)l4in << 48) // 4 lsb as msb
|
||||
#define rotate1l_64(r1lin) \
|
||||
(high1_64(r1lin) | (r1lin << 1)) // input rotated left (1x)
|
||||
#define rotate1r_64(r1rin) \
|
||||
(high1_64(r1rin) | (r1rin >> 1)) // input rotated right (1x)
|
||||
#define rotate4l_64(r4lin) \
|
||||
(high4_64(r4lin) | (r4lin << 4)) // input rotated left (4x)
|
||||
#define rotate4r_64(r4rin) \
|
||||
(high4_64(r4rin) | (r4rin >> 4)) // input rotated right (4x)
|
||||
|
||||
//----------------------------------
|
||||
// Function prototypes
|
||||
//----------------------------------
|
||||
uint64_t encrypt(uint64_t, uint64_t *, uint16_t, _Bool);
|
||||
uint64_t decrypt(uint64_t, uint64_t *, uint16_t, _Bool);
|
||||
uint64_t *key_schedule(uint64_t, uint64_t, uint16_t, _Bool, _Bool);
|
||||
|
||||
// We have commented out the main(...) function of the C model as the testbench is directly
|
||||
// calling encrypt(), decrypt(), and key_schedule() functions.
|
||||
// It also contains unnecessary command line parsing functionality that is not needed for
|
||||
// the testbench.
|
||||
//
|
||||
//----------------------------------
|
||||
// Start of code
|
||||
//----------------------------------
|
||||
// int main( int argc, char ** const argv )
|
||||
//{
|
||||
// // Initialize variables
|
||||
// uint64_t result;
|
||||
// struct Options Opt;
|
||||
//
|
||||
// // Get Commandline Options
|
||||
// comline_fetch_options( &Opt, argc, argv );
|
||||
//
|
||||
// // Banner
|
||||
// if ( Opt.Verbose != 0 )
|
||||
// {
|
||||
// printf( "---------------------------------------\n" );
|
||||
// printf( "PRESENT Commandline Tool v2.1\n" );
|
||||
// printf( "Thomas Siebert, thomas.siebert@rub.de\n" );
|
||||
// printf( "---------------------------------------\n\n" );
|
||||
// }
|
||||
//
|
||||
// if ( !Opt.Error )
|
||||
// {
|
||||
// uint64_t *subkey;
|
||||
//
|
||||
// if ( Opt.Mode == Encrypt_Mode )
|
||||
// {
|
||||
// // Put out Values
|
||||
// if ( Opt.Verbose != 0 )
|
||||
// {
|
||||
// printf( "Starting values\n" );
|
||||
// printf( "Plaintext: %016"PRIx64" \n", Opt.Text);
|
||||
// if (Opt.KeySize80) printf( "Given Key (80bit):
|
||||
//%016"PRIx64" %04"PRIx64"\n\n", Opt.KeyHigh, (Opt.KeyLow&0xFFFF) ); else
|
||||
//printf( "Given Key (128bit): %016"PRIx64" %016"PRIx64"\n\n", Opt.KeyHigh,
|
||||
//Opt.KeyLow );
|
||||
// }
|
||||
//
|
||||
// // Generate Subkeys
|
||||
// subkey=key_schedule( Opt.KeyHigh, Opt.KeyLow, Opt.Rounds,
|
||||
//Opt.KeySize80, (Opt.Verbose>1) );
|
||||
//
|
||||
// // Start Encryption
|
||||
// if ( Opt.Verbose != 0 ) printf( "Starting
|
||||
//encryption...\n" ); result=encrypt(Opt.Text, subkey, Opt.Rounds,
|
||||
//(Opt.Verbose>1) ); if ( Opt.Verbose != 0 ) printf( "Resulting Cipher:
|
||||
//%016"PRIx64" \n\n", result); else printf( "%016"PRIx64"\n", result);
|
||||
// }
|
||||
//
|
||||
// else if ( Opt.Mode == Decrypt_Mode )
|
||||
// {
|
||||
// // Put out Values
|
||||
// if ( Opt.Verbose != 0 )
|
||||
// {
|
||||
// printf( "Starting values\n" );
|
||||
// printf( "Ciphertext: %016"PRIx64" \n",
|
||||
//Opt.Text); if (Opt.KeySize80) printf( "Given Key (80bit): %016"PRIx64"
|
||||
//%04"PRIx64"\n\n", Opt.KeyHigh, (Opt.KeyLow&0xFFFF) ); else printf( "Given Key
|
||||
//(128bit): %016"PRIx64" %016"PRIx64"\n\n", Opt.KeyHigh, Opt.KeyLow );
|
||||
// }
|
||||
//
|
||||
// // Generate Subkeys
|
||||
// subkey=key_schedule( Opt.KeyHigh, Opt.KeyLow, Opt.Rounds,
|
||||
//Opt.KeySize80, (Opt.Verbose>1) );
|
||||
//
|
||||
// // Start Decryption
|
||||
// if ( Opt.Verbose != 0 ) printf( "Starting
|
||||
//decryption...\n" ); result=decrypt(Opt.Text, subkey, Opt.Rounds,
|
||||
//(Opt.Verbose>1) ); if ( Opt.Verbose != 0 ) printf( "Resulting Plaintext:
|
||||
//%016"PRIx64" \n", result); else printf( "%016"PRIx64"\n", result);
|
||||
// }
|
||||
//
|
||||
// free(subkey);
|
||||
//
|
||||
// }
|
||||
//
|
||||
// else
|
||||
// {
|
||||
// // Put out Syntax
|
||||
// printf( "Syntax:\n");
|
||||
// printf( "PRESENT -d|e [-f] [-r rounds] [-v level] -k key -t
|
||||
//text\n\n"); printf( "Choose -d to decrypt, or -e to encrypt one block\n\n");
|
||||
// printf( "-f (optional): File input, see below\n");
|
||||
// printf( "-r rounds (optional): Change number of rounds (up
|
||||
//to 65534, standard is 32)\n"); printf( "-v level (optional): Specify verbose
|
||||
//level:\n"); printf( " 0 for result-output only\n"); printf( " 1 for output
|
||||
//of mode, input, result (standard)\n"); printf( " 2 for roundwise
|
||||
//output\n\n"); printf( "-k key: Key in hexadecimal (length: *EXACTLY* 20
|
||||
//chars(80bit)/32 chars(128bit))\n"); printf( "-t text: Text in hexadecimal
|
||||
//(length: *EXACTLY* 16 chars)\n"); printf( "If -f is set, key and text
|
||||
//represent files containing the values,\n"); printf( "otherwise they must be
|
||||
//passed directly via commandline.\n\n"); printf( "Returned Errorlevel: 0 if
|
||||
//successful, 1 if non-successful\n");
|
||||
// }
|
||||
// return Opt.Error;
|
||||
//}
|
||||
|
||||
//----------------------------------
|
||||
// Key Scheduling
|
||||
//----------------------------------
|
||||
uint64_t *key_schedule(uint64_t key_high, uint64_t key_low, uint16_t Rounds,
|
||||
_Bool KeySize80, _Bool Output) {
|
||||
uint64_t temp64;
|
||||
uint64_t i;
|
||||
|
||||
uint64_t *subkey = (uint64_t *)malloc(Rounds * sizeof(uint64_t));
|
||||
|
||||
if (subkey != NULL) {
|
||||
if (Output)
|
||||
v_key_start();
|
||||
|
||||
if (KeySize80) {
|
||||
key_low &= 0xFFFF;
|
||||
|
||||
if (Output)
|
||||
v_k80_init(key_high, key_low);
|
||||
|
||||
for (i = 0; i < Rounds; i++) {
|
||||
subkey[i] = key_high;
|
||||
|
||||
//----------------------------------
|
||||
// Shift
|
||||
//----------------------------------
|
||||
temp64 = key_high;
|
||||
key_high <<= 61;
|
||||
key_high |= (key_low << 45);
|
||||
key_high |= (temp64 >> 19);
|
||||
key_low = (temp64 >> 3) & 0xFFFF;
|
||||
|
||||
if (Output && (i + 2 <= Rounds))
|
||||
v_k80_shift(key_high, key_low);
|
||||
|
||||
//----------------------------------
|
||||
// S-Box
|
||||
//----------------------------------
|
||||
temp64 = high4_64(key_high); // get highest nibble
|
||||
key_high &= 0x0FFFFFFFFFFFFFFF; // kill highest nibble
|
||||
temp64 = Sbox[temp64];
|
||||
key_high |= low4_64(temp64); // put new value to highest nibble (sbox)
|
||||
|
||||
if (Output && (i + 2 <= Rounds))
|
||||
v_k80_sbox(key_high, key_low);
|
||||
|
||||
//----------------------------------
|
||||
// Round Salt
|
||||
//----------------------------------
|
||||
key_low ^= (((i + 1) & 0x01) << 15);
|
||||
key_high ^= ((i + 1) >> 1);
|
||||
|
||||
if (Output && (i + 2 <= Rounds))
|
||||
v_k80_round(key_high, key_low, i);
|
||||
}
|
||||
} else // 128 Bit
|
||||
{
|
||||
if (Output)
|
||||
v_k128_init(key_high, key_low);
|
||||
|
||||
for (i = 0; i < Rounds; i++) {
|
||||
subkey[i] = key_high;
|
||||
|
||||
//----------------------------------
|
||||
// Shift
|
||||
//----------------------------------
|
||||
temp64 = high61_64(key_high);
|
||||
key_high <<= 61;
|
||||
key_high |= high61_64(key_low);
|
||||
key_low <<= 61;
|
||||
key_low |= temp64;
|
||||
|
||||
if (Output && (i + 2 <= Rounds))
|
||||
v_k128_shift(key_high, key_low);
|
||||
|
||||
//----------------------------------
|
||||
// S-Box
|
||||
//----------------------------------
|
||||
temp64 = high4_64(key_high); // get highest nibble
|
||||
key_high &= 0x0FFFFFFFFFFFFFFF; // kill highest nibble
|
||||
temp64 = Sbox[temp64];
|
||||
key_high |= low4_64(temp64); // put new value to highest nibble (sbox)
|
||||
temp64 = high8to4_64(key_high); // get 2. highest nibble
|
||||
key_high &= 0xF0FFFFFFFFFFFFFF; // kill 2. highest nibble
|
||||
temp64 = Sbox[temp64];
|
||||
key_high |=
|
||||
low8to4_64(temp64); // put new value to 2. highest nibble (sbox)
|
||||
|
||||
if (Output && (i + 2 <= Rounds))
|
||||
v_k128_sbox(key_high, key_low);
|
||||
|
||||
//----------------------------------
|
||||
// Round Salt
|
||||
//----------------------------------
|
||||
key_low ^= (((i + 1) & 0x03) << 62); // add counter to lower key part
|
||||
key_high ^= ((i + 1) >> 2); // add counter to higher key part
|
||||
|
||||
if (Output && (i + 2 <= Rounds))
|
||||
v_k128_round(key_high, key_low, i);
|
||||
}
|
||||
}
|
||||
if (Output)
|
||||
v_final();
|
||||
} else {
|
||||
printf("RAM problem!\n");
|
||||
exit(0);
|
||||
}
|
||||
return subkey;
|
||||
}
|
||||
|
||||
//----------------------------------
|
||||
// Encryption
|
||||
//----------------------------------
|
||||
uint64_t encrypt(uint64_t in, uint64_t *subkey, uint16_t Rounds,
|
||||
_Bool Roundwise) { // Start encryption
|
||||
|
||||
#define out in
|
||||
uint16_t RoundNr;
|
||||
uint64_t text;
|
||||
|
||||
if (Roundwise)
|
||||
v_enc_start(in);
|
||||
|
||||
for (RoundNr = 1; RoundNr < Rounds; RoundNr++) { // Start "for"
|
||||
uint16_t temp;
|
||||
#define SboxNr temp
|
||||
#define PBit temp
|
||||
|
||||
if (Roundwise)
|
||||
v_roundstart(RoundNr, subkey[RoundNr - 1]);
|
||||
|
||||
//----------------------------------
|
||||
// Xor with roundkey
|
||||
//----------------------------------
|
||||
text = in ^ subkey[RoundNr - 1];
|
||||
|
||||
if (Roundwise)
|
||||
v_after_xor(text);
|
||||
|
||||
//----------------------------------
|
||||
// S-Boxes
|
||||
//----------------------------------
|
||||
for (SboxNr = 0; SboxNr < 16; SboxNr++) {
|
||||
uint16_t SboxVal;
|
||||
|
||||
SboxVal = text & 0x0F; // get lowest nibble
|
||||
text &= 0xFFFFFFFFFFFFFFF0; // kill lowest nibble
|
||||
text |= Sbox[SboxVal]; // put new value to lowest nibble (sbox)
|
||||
text = rotate4l_64(text); // next(rotate by one nibble)
|
||||
}
|
||||
|
||||
if (Roundwise)
|
||||
v_after_s(text);
|
||||
|
||||
//----------------------------------
|
||||
// P-Box
|
||||
//----------------------------------
|
||||
for (PBit = 0, out = 0; PBit < 64; PBit++) {
|
||||
out = rotate1l_64(out); // next(rotate by one bit)
|
||||
out |= ((text >> 63 - Pbox[PBit]) &
|
||||
1); // put new value to lowest bit (pbox)
|
||||
}
|
||||
|
||||
if (Roundwise)
|
||||
v_after_p(in);
|
||||
|
||||
} // End "for"
|
||||
|
||||
text = in ^ subkey[RoundNr - 1];
|
||||
|
||||
if (Roundwise)
|
||||
v_enc_final(text, subkey[RoundNr - 1]);
|
||||
|
||||
return text;
|
||||
|
||||
} // End encryption
|
||||
|
||||
//----------------------------------
|
||||
// Decryption
|
||||
//----------------------------------
|
||||
uint64_t decrypt(uint64_t in, uint64_t *subkey, uint16_t Rounds,
|
||||
_Bool Roundwise) { // Start decryption
|
||||
#define out in
|
||||
uint16_t RoundNr;
|
||||
uint64_t text;
|
||||
|
||||
if (Roundwise)
|
||||
v_dec_start(in);
|
||||
|
||||
for (RoundNr = 1; RoundNr <= Rounds; RoundNr++) { // Start "for"
|
||||
uint64_t key_temp;
|
||||
uint16_t temp;
|
||||
#define SboxNr temp
|
||||
#define PBit temp
|
||||
|
||||
if (Roundwise)
|
||||
v_roundstart(RoundNr, subkey[Rounds - RoundNr]);
|
||||
|
||||
//----------------------------------
|
||||
// Xor with roundkey
|
||||
//----------------------------------
|
||||
text = in ^ subkey[Rounds - RoundNr];
|
||||
|
||||
if (Roundwise)
|
||||
v_after_xor(text);
|
||||
|
||||
//----------------------------------
|
||||
// P-Box
|
||||
//----------------------------------
|
||||
for (PBit = 0, out = 0; PBit < 64; PBit++) {
|
||||
out = rotate1l_64(out); // next(rotate by one bit)
|
||||
out |= ((text >> 63 - PboxInv[PBit]) &
|
||||
1); // put new value to lowest bit (pbox)
|
||||
}
|
||||
|
||||
if (Roundwise)
|
||||
v_after_p(out);
|
||||
|
||||
//----------------------------------
|
||||
// S-Boxes
|
||||
//----------------------------------
|
||||
for (SboxNr = 0; SboxNr < 16; SboxNr++) {
|
||||
uint16_t SboxVal;
|
||||
|
||||
SboxVal = out & 0x0F;
|
||||
out &= 0xFFFFFFFFFFFFFFF0;
|
||||
out |= SboxInv[SboxVal];
|
||||
out = rotate4l_64(out);
|
||||
}
|
||||
|
||||
if (Roundwise)
|
||||
v_after_s(out);
|
||||
|
||||
} // End "for"
|
||||
|
||||
if (Roundwise)
|
||||
v_final();
|
||||
|
||||
return text;
|
||||
|
||||
} // End decryption
|
|
@ -1,125 +0,0 @@
|
|||
/*
|
||||
* Verbose-Functions for
|
||||
* Implementation of PRESENT in C
|
||||
* v2.1, 10/13/2008
|
||||
*
|
||||
* Implementation is located at http://www.lightweightcrypto.org/implementations.php,
|
||||
* under the title "Testvectors for PRESENT".
|
||||
*
|
||||
* Thomas Siebert, thomas.siebert@rub.de
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
//----------------------------------
|
||||
// Function prototypes
|
||||
//----------------------------------
|
||||
void v_enc_start(uint64_t);
|
||||
void v_enc_final(uint64_t, uint64_t);
|
||||
void v_dec_start(uint64_t);
|
||||
void v_roundstart(uint16_t, uint64_t);
|
||||
void v_after_xor(uint64_t);
|
||||
void v_after_s(uint64_t);
|
||||
void v_after_p(uint64_t);
|
||||
void v_final(void);
|
||||
void v_k80_init(uint64_t, uint64_t);
|
||||
void v_k80_shift(uint64_t, uint64_t);
|
||||
void v_k80_sbox(uint64_t, uint64_t);
|
||||
void v_k80_round(uint64_t, uint64_t, uint16_t);
|
||||
void v_k128_init(uint64_t, uint64_t);
|
||||
void v_k128_shift(uint64_t, uint64_t);
|
||||
void v_k128_sbox(uint64_t, uint64_t);
|
||||
void v_k128_round(uint64_t, uint64_t, uint16_t);
|
||||
void v_key_start(void);
|
||||
|
||||
//----------------------------------
|
||||
// Functions
|
||||
//----------------------------------
|
||||
void v_enc_start(uint64_t v_plain) {
|
||||
printf("************************************\n");
|
||||
printf("Verbose output of PRESENT-encryption\n");
|
||||
printf("************************************\n\n");
|
||||
printf("Given Plaintext: %016" PRIx64 " \n\n", v_plain);
|
||||
}
|
||||
|
||||
void v_dec_start(uint64_t v_plain) {
|
||||
printf("************************************\n");
|
||||
printf("Verbose output of PRESENT-decryption\n");
|
||||
printf("************************************\n\n");
|
||||
printf("Given Ciphertext: %016" PRIx64 " \n", v_plain);
|
||||
}
|
||||
|
||||
void v_roundstart(uint16_t v_round, uint64_t v_key) {
|
||||
printf("--------------------------------------\n");
|
||||
printf("Round %" PRIu16 "\n", v_round);
|
||||
printf("Subkey: %016" PRIx64 "\n\n", v_key);
|
||||
printf("Text after...\n");
|
||||
}
|
||||
|
||||
void v_enc_final(uint64_t v_final_text, uint64_t v_key) {
|
||||
printf("--------------------------------------\n");
|
||||
printf("Final Round\n\n");
|
||||
printf("Subkey: %016" PRIx64 "\n", v_key);
|
||||
printf("Text: %016" PRIx64 " \n\n", v_final_text);
|
||||
v_final();
|
||||
}
|
||||
|
||||
void v_final(void) {
|
||||
printf("************************************\n");
|
||||
printf("End of verbose output\n");
|
||||
printf("************************************\n");
|
||||
}
|
||||
|
||||
void v_after_xor(uint64_t v_xor) {
|
||||
printf("...Key-Xor: %016" PRIx64 " \n", v_xor);
|
||||
}
|
||||
|
||||
void v_after_s(uint64_t v_s) { printf(".....S-Box: %016" PRIx64 " \n", v_s); }
|
||||
|
||||
void v_after_p(uint64_t v_p) { printf(".....P-Box: %016" PRIx64 " \n", v_p); }
|
||||
|
||||
void v_k128_init(uint64_t key_high, uint64_t key_low) {
|
||||
printf("Input: %016" PRIx64 " %016" PRIx64 "\n\n", key_high, key_low);
|
||||
printf("Subkey Round 1: >>%016" PRIx64 "<<\n\n", key_high);
|
||||
}
|
||||
|
||||
void v_k128_shift(uint64_t key_high, uint64_t key_low) {
|
||||
printf("...after Shift: %016" PRIx64 " %016" PRIx64 "\n", key_high, key_low);
|
||||
}
|
||||
|
||||
void v_k128_sbox(uint64_t key_high, uint64_t key_low) {
|
||||
printf("...after S-Box: %016" PRIx64 " %016" PRIx64 "\n", key_high, key_low);
|
||||
}
|
||||
|
||||
void v_k128_round(uint64_t key_high, uint64_t key_low, uint16_t i) {
|
||||
printf("Subkey Round %" PRIu16 " (after Salt): >>%016" PRIx64 "<< %016" PRIx64
|
||||
"\n\n",
|
||||
i + 2, key_high, key_low);
|
||||
}
|
||||
|
||||
void v_k80_init(uint64_t key_high, uint64_t key_low) {
|
||||
printf("Input: %016" PRIx64 " %04" PRIx64 "\n\n", key_high,
|
||||
(key_low & 0xFFFF));
|
||||
printf("Subkey Round 1: >>%016" PRIx64 "<<\n\n", key_high);
|
||||
}
|
||||
|
||||
void v_k80_shift(uint64_t key_high, uint64_t key_low) {
|
||||
printf("...after Shift: %016" PRIx64 " %04" PRIx64 "\n", key_high, key_low);
|
||||
}
|
||||
|
||||
void v_k80_sbox(uint64_t key_high, uint64_t key_low) {
|
||||
printf("...after S-Box: %016" PRIx64 " %04" PRIx64 "\n", key_high, key_low);
|
||||
}
|
||||
|
||||
void v_k80_round(uint64_t key_high, uint64_t key_low, uint16_t i) {
|
||||
printf("Subkey Round %" PRIu16 " (after Salt): >>%016" PRIx64 "<< %04" PRIx64
|
||||
"\n\n",
|
||||
i + 2, key_high, key_low);
|
||||
}
|
||||
void v_key_start(void) {
|
||||
printf("**************************************\n");
|
||||
printf("Verbose output of PRESENT-Key-Schedule\n");
|
||||
printf("**************************************\n\n");
|
||||
}
|
|
@ -13,19 +13,15 @@
|
|||
module prim_present_tb;
|
||||
`include "dv_macros.svh"
|
||||
|
||||
import crypto_dpi_present_pkg::MaxRounds;
|
||||
import crypto_dpi_present_pkg::MaxKeyWidth;
|
||||
import crypto_dpi_present_pkg::DataWidth;
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// config
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
// Default to {data_width:64, key_width:128} configuration.
|
||||
// Data width and key width can be overriden from command-line if desired.
|
||||
|
||||
`ifdef DATA_WIDTH
|
||||
localparam int unsigned DataWidth = `DATA_WIDTH;
|
||||
`else
|
||||
localparam int unsigned DataWidth = 64;
|
||||
`endif
|
||||
|
||||
// Key width can be set with a define, but must be 80 or 128
|
||||
`ifdef KEY_WIDTH
|
||||
localparam int unsigned KeyWidth = `KEY_WIDTH;
|
||||
`else
|
||||
|
@ -34,17 +30,10 @@ module prim_present_tb;
|
|||
|
||||
localparam string MSG_ID = $sformatf("%m");
|
||||
|
||||
// Max number of rounds according to spec.
|
||||
// We redefine this parameter here to avoid clutter from the long package identifier.
|
||||
localparam int unsigned NumRounds = crypto_dpi_present_pkg::NumRounds;
|
||||
|
||||
// used to index the data arrays
|
||||
localparam bit Encrypt = 1'b0;
|
||||
localparam bit Decrypt = 1'b1;
|
||||
|
||||
// this parameter is required for the DPI model.
|
||||
localparam bit KeySize80 = (KeyWidth == 80);
|
||||
|
||||
// This bit can be set from the command line to indicate that we are running a smoke regression,
|
||||
// and to run just a single iteration of the test.
|
||||
// This helps drastically reduce runtimes in the CI flows.
|
||||
|
@ -56,15 +45,15 @@ module prim_present_tb;
|
|||
|
||||
// data_in[0]: encryption, data_in[1]: decryption.
|
||||
// Same scheme used for key_in, data_out, key_out.
|
||||
logic [1:0][NumRounds-1:0][DataWidth-1:0] data_in;
|
||||
logic [1:0][NumRounds-1:0][KeyWidth-1 :0] key_in;
|
||||
logic [1:0][NumRounds-1:0][4:0] idx_in;
|
||||
logic [1:0][NumRounds-1:0][DataWidth-1:0] data_out;
|
||||
logic [1:0][NumRounds-1:0][KeyWidth-1 :0] key_out;
|
||||
logic [1:0][NumRounds-1:0][4:0] idx_out;
|
||||
logic [1:0][MaxRounds-1:0][DataWidth-1:0] data_in;
|
||||
logic [1:0][MaxRounds-1:0][KeyWidth-1 :0] key_in;
|
||||
logic [1:0][MaxRounds-1:0][4:0] idx_in;
|
||||
logic [1:0][MaxRounds-1:0][DataWidth-1:0] data_out;
|
||||
logic [1:0][MaxRounds-1:0][KeyWidth-1 :0] key_out;
|
||||
logic [1:0][MaxRounds-1:0][4:0] idx_out;
|
||||
|
||||
for (genvar j = 0; j < 2; j++) begin : gen_encrypt_decrypt
|
||||
for (genvar k = 0; k < NumRounds; k++) begin : gen_duts
|
||||
for (genvar k = 0; k < MaxRounds; k++) begin : gen_duts
|
||||
if (j == 0) begin : gen_encrypt
|
||||
assign idx_in[j][k] = 5'd1;
|
||||
end else begin : gen_decrypt
|
||||
|
@ -96,15 +85,10 @@ module prim_present_tb;
|
|||
task automatic test_present(bit [DataWidth-1:0] plaintext,
|
||||
bit [KeyWidth-1:0] key);
|
||||
|
||||
bit [NumRounds:0][63:0] key_schedule;
|
||||
bit [NumRounds-1:0][DataWidth-1:0] encrypted_text;
|
||||
|
||||
crypto_dpi_present_pkg::sv_dpi_present_get_key_schedule(key, KeySize80, key_schedule);
|
||||
|
||||
check_encryption(plaintext, key, key_schedule, encrypted_text);
|
||||
bit [MaxRounds-1:0][DataWidth-1:0] encrypted_text;
|
||||
|
||||
check_encryption(plaintext, key, encrypted_text);
|
||||
check_decryption(encrypted_text, key, key_out[Encrypt]);
|
||||
|
||||
endtask
|
||||
|
||||
|
||||
|
@ -112,11 +96,10 @@ module prim_present_tb;
|
|||
// Calls a subroutine to perform checks on the outputs (once they are available).
|
||||
task automatic check_encryption(input bit [DataWidth-1:0] plaintext,
|
||||
input bit [KeyWidth-1:0] key,
|
||||
input bit [NumRounds:0][63:0] key_schedule,
|
||||
output bit [NumRounds-1:0][DataWidth-1:0] expected_ciphertext);
|
||||
output bit [MaxRounds-1:0][DataWidth-1:0] expected_ciphertext);
|
||||
|
||||
// Drive input into encryption instances.
|
||||
for (int unsigned i = 0; i < NumRounds; i++) begin
|
||||
for (int unsigned i = 0; i < MaxRounds; i++) begin
|
||||
data_in[Encrypt][i] = plaintext;
|
||||
key_in[Encrypt][i] = key;
|
||||
end
|
||||
|
@ -124,30 +107,22 @@ module prim_present_tb;
|
|||
// Wait a bit for the DUTs to finish calculations.
|
||||
#100ns;
|
||||
|
||||
// query DPI model for expected encrypted output.
|
||||
crypto_dpi_present_pkg::sv_dpi_present_encrypt(plaintext, key,
|
||||
KeySize80, expected_ciphertext);
|
||||
for (int unsigned i = 0; i < MaxRounds; i++) begin
|
||||
crypto_dpi_present_pkg::sv_dpi_present_encrypt(plaintext, MaxKeyWidth'(key),
|
||||
KeyWidth, i + 1, expected_ciphertext[i]);
|
||||
|
||||
check_output(key_schedule[NumRounds:1], expected_ciphertext,
|
||||
key_out[Encrypt], data_out[Encrypt], "Encryption");
|
||||
check_output(data_out[Encrypt][i],
|
||||
expected_ciphertext[i],
|
||||
$sformatf("Encryption; %0d rounds, key width %0d", i + 1, KeyWidth));
|
||||
end
|
||||
endtask
|
||||
|
||||
|
||||
// Helper task to drive ciphertext and key into each decryption instance.
|
||||
// Calls a subroutine to perform checks on the outputs (once they are available).
|
||||
task automatic check_decryption(input bit [NumRounds-1:0][DataWidth-1:0] ciphertext,
|
||||
task automatic check_decryption(input bit [MaxRounds-1:0][DataWidth-1:0] ciphertext,
|
||||
input bit [KeyWidth-1:0] key,
|
||||
input bit [NumRounds-1:0][KeyWidth-1:0] decryption_keys);
|
||||
|
||||
// the expected plaintext after decryption will be provided by the C model.
|
||||
bit [NumRounds-1:0][DataWidth-1:0] expected_plaintext;
|
||||
|
||||
// the expected key after decryption will simply be the original key.
|
||||
// the C model only provides a key schedule, which is not useful here.
|
||||
bit [NumRounds-1:0][63:0] expected_key;
|
||||
for (int i = 0; i < NumRounds; i++) begin
|
||||
expected_key[i] = key[KeyWidth-1:KeyWidth-64];
|
||||
end
|
||||
input bit [MaxRounds-1:0][KeyWidth-1:0] decryption_keys);
|
||||
|
||||
// Drive input into decryption instances.
|
||||
data_in[Decrypt] = ciphertext;
|
||||
|
@ -157,49 +132,29 @@ module prim_present_tb;
|
|||
#100ns;
|
||||
|
||||
// query DPI model for expected decrypted output.
|
||||
crypto_dpi_present_pkg::sv_dpi_present_decrypt(ciphertext, key, KeySize80, expected_plaintext);
|
||||
|
||||
check_output(expected_key, expected_plaintext,
|
||||
key_out[Decrypt], data_out[Decrypt], "Decryption");
|
||||
for (int unsigned i = 0; i < MaxRounds; i++) begin
|
||||
bit [DataWidth-1:0] expected_plaintext;
|
||||
crypto_dpi_present_pkg::sv_dpi_present_decrypt(ciphertext[i],
|
||||
key, KeyWidth,
|
||||
i + 1,
|
||||
expected_plaintext);
|
||||
check_output(data_out[Decrypt][i],
|
||||
expected_plaintext,
|
||||
$sformatf("Decryption; %0d rounds, key width %0d", i + 1, KeyWidth));
|
||||
end
|
||||
endtask
|
||||
|
||||
|
||||
// Helper subroutine to compare key and data output values from
|
||||
// the C-reference model and the DUTs.
|
||||
//
|
||||
// For each instance of PRESENT (whether encryption or decryption),
|
||||
// we need to perform two checks:
|
||||
// 1) Check that the output key matches the corresponding key in the schedule.
|
||||
// 2) Check that the output data matches the output of the reference model.
|
||||
//
|
||||
// If any comparison error is seen, this task short-circuits immediately,
|
||||
// printing out some debug information and the correct failure signature.
|
||||
task automatic check_output(input bit [NumRounds-1:0][63:0] expected_key,
|
||||
input bit [NumRounds-1:0][DataWidth-1:0] expected_text,
|
||||
input bit [NumRounds-1:0][KeyWidth-1:0] actual_key,
|
||||
input bit [NumRounds-1:0][DataWidth-1:0] actual_data,
|
||||
input string msg);
|
||||
|
||||
bit error = 1'b0;
|
||||
|
||||
for (int unsigned i = 0; i < NumRounds; i++) begin
|
||||
// compare the output key to the corresponding key in the schedule.
|
||||
if (expected_key[i] != actual_key[i][KeyWidth-1:KeyWidth-64]) begin
|
||||
error = 1'b1;
|
||||
$error("%s output key mismatch at round %0d! Expected[0x%0x] - Actual[0x%0x]",
|
||||
msg, i, expected_key[i], actual_key[i][KeyWidth-1:KeyWidth-64]);
|
||||
break;
|
||||
end
|
||||
// compare encrypted output text to reference model
|
||||
if (expected_text[i] != actual_data[i]) begin
|
||||
error = 1'b1;
|
||||
$error("%s output text mismatch at round %0d! Expected[0x%0x] - Actual[0x%0x]",
|
||||
msg, i, expected_text[i], actual_data[i]);
|
||||
break;
|
||||
end
|
||||
function automatic void check_output(bit [DataWidth-1:0] dut_value,
|
||||
bit [DataWidth-1:0] exp_value,
|
||||
string desc);
|
||||
if (dut_value != exp_value) begin
|
||||
$error("%s: MISMATCH. Expected[0x%0x] - Actual[0x%0x]", desc, exp_value, dut_value);
|
||||
dv_test_status_pkg::dv_test_status(.passed(1'b0));
|
||||
end
|
||||
if (error) dv_test_status_pkg::dv_test_status(.passed(1'b0));
|
||||
endtask
|
||||
endfunction
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
|
10
vendor/lowrisc_ip/ip/prim/lint/prim_cdc_rand_delay.vlt
vendored
Normal file
10
vendor/lowrisc_ip/ip/prim/lint/prim_cdc_rand_delay.vlt
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
`verilator_config
|
||||
|
||||
// When running this prim through Verilator, we stub out all of its contents.
|
||||
// This, in turn, generates UNUSED warnings which we can waive here. No need to
|
||||
// be fine-grained: this is DV code anyway.
|
||||
lint_off -rule UNUSED -file "*/rtl/prim_cdc_rand_delay.sv" -match "*"
|
19
vendor/lowrisc_ip/ip/prim/lint/prim_cdc_rand_delay.waiver
vendored
Normal file
19
vendor/lowrisc_ip/ip/prim/lint/prim_cdc_rand_delay.waiver
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
# Copyright lowRISC contributors.
|
||||
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# waiver file for prim_cdc_rand_delay
|
||||
|
||||
waive -rules {IFDEF_CODE} -location {prim_cdc_rand_delay.sv} -regexp {.*contained within \`else block.*} \
|
||||
-comment "Ifdefs are required for prim_rand_cdc_delay since it is turned on only for simulation."
|
||||
|
||||
waive -rules {HIER_BRANCH_NOT_READ} -location {prim_cdc_rand_delay.sv} -regexp {.*dst_clk.*} \
|
||||
-comment "Destination clock is only used when attempting to simulate random delays."
|
||||
|
||||
waive -rules {INPUT_NOT_READ} -location {prim_cdc_rand_delay.sv} -regexp {dst_clk|src_clk} \
|
||||
-comment "Source/Destination clock is only used when attempting to simulate random delays."
|
||||
|
||||
waive -rules {PARAM_NOT_USED} -location {prim_cdc_rand_delay.sv} -regexp {UseSourceClock|LatencyPs|JitterPs} \
|
||||
-comment "Randomization parameters are only used when attempting to simulate random delays."
|
||||
|
||||
|
18
vendor/lowrisc_ip/ip/prim/lint/prim_onehot_check.vlt
vendored
Normal file
18
vendor/lowrisc_ip/ip/prim/lint/prim_onehot_check.vlt
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
`verilator_config
|
||||
|
||||
// Tell the Verilator scheduler to split up these variables into
|
||||
// separate pieces when it's figuring out process scheduling. This
|
||||
// avoids spurious UNOPTFLAT warnings caused by the fact that the
|
||||
// arrays feed into themselves (with different bits for different
|
||||
// positions in the tree).
|
||||
split_var -module "prim_onehot_check" -var "or_tree"
|
||||
split_var -module "prim_onehot_check" -var "and_tree"
|
||||
split_var -module "prim_onehot_check" -var "err_tree"
|
||||
|
||||
// The clock and reset are only used for assertions in this module.
|
||||
lint_off -rule UNUSED -file "*/rtl/prim_onehot_check.sv" -match "Signal is not used: 'clk_i'"
|
||||
lint_off -rule UNUSED -file "*/rtl/prim_onehot_check.sv" -match "Signal is not used: 'rst_ni'"
|
8
vendor/lowrisc_ip/ip/prim/lint/prim_onehot_check.waiver
vendored
Normal file
8
vendor/lowrisc_ip/ip/prim/lint/prim_onehot_check.waiver
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
# Copyright lowRISC contributors.
|
||||
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# waiver file for prim_onehot_check
|
||||
|
||||
waive -rules {HIER_BRANCH_NOT_READ INPUT_NOT_READ} -location {prim_onehot_check.sv} -regexp {.*'(clk_i|rst_ni)' is not read from in module 'prim_onehot_check'.*} \
|
||||
-comment "clk_ and rst_ni are only used for assertions in this module."
|
31
vendor/lowrisc_ip/ip/prim/pre_dv/prim_flop_2sync/prim_flop_2sync_sim.core
vendored
Normal file
31
vendor/lowrisc_ip/ip/prim/pre_dv/prim_flop_2sync/prim_flop_2sync_sim.core
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
CAPI=2:
|
||||
# Copyright lowRISC contributors.
|
||||
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
name: "lowrisc:dv:prim_flop_2sync_sim:0.1"
|
||||
description: "prim_flop_2sync_sim sim target"
|
||||
filesets:
|
||||
files_rtl:
|
||||
depend:
|
||||
- lowrisc:prim:flop_2sync
|
||||
|
||||
files_dv:
|
||||
depend:
|
||||
- lowrisc:dv:common_ifs
|
||||
- lowrisc:dv:dv_macros
|
||||
- lowrisc:dv:dv_utils
|
||||
- lowrisc:dv:dv_test_status
|
||||
files:
|
||||
- tb.sv
|
||||
file_type: systemVerilogSource
|
||||
|
||||
targets:
|
||||
sim: &sim_target
|
||||
toplevel: tb
|
||||
filesets:
|
||||
- files_rtl
|
||||
- files_dv
|
||||
default_tool: vcs
|
||||
|
||||
lint:
|
||||
<<: *sim_target
|
41
vendor/lowrisc_ip/ip/prim/pre_dv/prim_flop_2sync/prim_flop_2sync_sim_cfg.hjson
vendored
Normal file
41
vendor/lowrisc_ip/ip/prim/pre_dv/prim_flop_2sync/prim_flop_2sync_sim_cfg.hjson
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
{
|
||||
// Name of the sim cfg - typically same as the name of the DUT.
|
||||
name: prim_flop_2sync
|
||||
|
||||
// Top level dut name (sv module).
|
||||
dut: prim_flop_2sync
|
||||
|
||||
// Top level testbench name (sv module).
|
||||
tb: tb
|
||||
|
||||
// Simulator used to sign off this block
|
||||
tool: vcs
|
||||
|
||||
// Fusesoc core file used for building the file list.
|
||||
fusesoc_core: lowrisc:dv:prim_flop_2sync_sim:0.1
|
||||
|
||||
// Import additional common sim cfg files.
|
||||
import_cfgs: [// Project wide common sim cfg file
|
||||
"{proj_root}/hw/dv/tools/dvsim/common_sim_cfg.hjson"]
|
||||
|
||||
// Default iterations for all tests - each test entry can override this.
|
||||
reseed: 5
|
||||
|
||||
// List of test specifications.
|
||||
tests: [
|
||||
{
|
||||
name: unit_test
|
||||
}
|
||||
]
|
||||
|
||||
// List of regressions.
|
||||
regressions: [
|
||||
{
|
||||
name: smoke
|
||||
tests: ["unit_test"]
|
||||
}
|
||||
]
|
||||
}
|
85
vendor/lowrisc_ip/ip/prim/pre_dv/prim_flop_2sync/tb.sv
vendored
Normal file
85
vendor/lowrisc_ip/ip/prim/pre_dv/prim_flop_2sync/tb.sv
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Basic testbench for prim_flop_2sync with CDC random delay enabled.
|
||||
module tb;
|
||||
`include "dv_macros.svh"
|
||||
|
||||
localparam string MsgId = $sformatf("%m");
|
||||
|
||||
logic [31:0] src_d, src_q;
|
||||
wire clk, rst_n;
|
||||
|
||||
clk_rst_if clk_rst_if(.clk, .rst_n);
|
||||
|
||||
prim_flop_2sync #(.Width(32)) dut (
|
||||
// source clock domain
|
||||
.d_i (src_d),
|
||||
// destination clock domain
|
||||
.clk_i (clk),
|
||||
.rst_ni (rst_n),
|
||||
.q_o (src_q)
|
||||
);
|
||||
|
||||
initial begin
|
||||
clk_rst_if.set_active();
|
||||
clk_rst_if.apply_reset(.reset_width_clks(10));
|
||||
|
||||
$display("Using prim_cdc_rand_delay_mode slow");
|
||||
dut.u_prim_cdc_rand_delay.set_prim_cdc_rand_delay_mode(1);
|
||||
repeat (100) begin
|
||||
src_d <= $urandom();
|
||||
clk_rst_if.wait_clks($urandom_range(1, 20));
|
||||
end
|
||||
clk_rst_if.wait_clks(200);
|
||||
|
||||
$display("Using prim_cdc_rand_delay_mode once");
|
||||
dut.u_prim_cdc_rand_delay.set_prim_cdc_rand_delay_mode(2);
|
||||
repeat (100) begin
|
||||
src_d <= $urandom();
|
||||
clk_rst_if.wait_clks($urandom_range(1, 20));
|
||||
end
|
||||
clk_rst_if.wait_clks(200);
|
||||
|
||||
$display("Using prim_cdc_rand_delay_mode interval = 10");
|
||||
dut.u_prim_cdc_rand_delay.set_prim_cdc_rand_delay_mode(3);
|
||||
dut.u_prim_cdc_rand_delay.set_prim_cdc_rand_delay_interval(10);
|
||||
repeat (100) begin
|
||||
src_d <= $urandom();
|
||||
clk_rst_if.wait_clks($urandom_range(1, 20));
|
||||
end
|
||||
clk_rst_if.wait_clks(200);
|
||||
|
||||
$display("Using prim_cdc_rand_delay_mode interval = 1");
|
||||
dut.u_prim_cdc_rand_delay.set_prim_cdc_rand_delay_interval(1);
|
||||
repeat (100) begin
|
||||
src_d <= $urandom();
|
||||
clk_rst_if.wait_clks($urandom_range(1, 20));
|
||||
end
|
||||
clk_rst_if.wait_clks(200);
|
||||
|
||||
$display("Using prim_cdc_rand_delay_mode interval = 0");
|
||||
dut.u_prim_cdc_rand_delay.set_prim_cdc_rand_delay_interval(0);
|
||||
repeat (100) begin
|
||||
src_d <= $urandom();
|
||||
clk_rst_if.wait_clks($urandom_range(1, 20));
|
||||
end
|
||||
clk_rst_if.wait_clks(200);
|
||||
|
||||
// TODO: Add more checks.
|
||||
dv_test_status_pkg::dv_test_status(.passed(1));
|
||||
`DV_CHECK(!src_d_q.size(), , , MsgId)
|
||||
$finish;
|
||||
end
|
||||
|
||||
// Verify src_d to src_q consistency.
|
||||
logic [31:0] src_d_q[$];
|
||||
initial begin
|
||||
fork
|
||||
forever @src_d if (rst_n) src_d_q.push_back(src_d);
|
||||
forever @src_q `DV_CHECK_EQ(src_q, src_d_q.pop_front(), , , MsgId)
|
||||
join_none
|
||||
end
|
||||
|
||||
endmodule
|
42
vendor/lowrisc_ip/ip/prim/prim_blanker.core
vendored
Normal file
42
vendor/lowrisc_ip/ip/prim/prim_blanker.core
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
CAPI=2:
|
||||
# Copyright lowRISC contributors.
|
||||
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: "lowrisc:prim:blanker"
|
||||
description: "Primitive for blanking signals"
|
||||
filesets:
|
||||
files_rtl:
|
||||
depend:
|
||||
- lowrisc:prim:and2
|
||||
files:
|
||||
- rtl/prim_blanker.sv
|
||||
file_type: systemVerilogSource
|
||||
|
||||
files_verilator_waiver:
|
||||
depend:
|
||||
# common waivers
|
||||
- lowrisc:lint:common
|
||||
files:
|
||||
file_type: vlt
|
||||
|
||||
files_ascentlint_waiver:
|
||||
depend:
|
||||
# common waivers
|
||||
- lowrisc:lint:common
|
||||
files:
|
||||
- lint/prim_and2.waiver
|
||||
file_type: waiver
|
||||
|
||||
files_veriblelint_waiver:
|
||||
depend:
|
||||
# common waivers
|
||||
- lowrisc:lint:common
|
||||
|
||||
targets:
|
||||
default:
|
||||
filesets:
|
||||
- tool_verilator ? (files_verilator_waiver)
|
||||
- tool_ascentlint ? (files_ascentlint_waiver)
|
||||
- tool_veriblelint ? (files_veriblelint_waiver)
|
||||
- files_rtl
|
|
@ -18,6 +18,7 @@ filesets:
|
|||
# common waivers
|
||||
- lowrisc:lint:common
|
||||
files:
|
||||
- lint/prim_cdc_rand_delay.vlt
|
||||
file_type: vlt
|
||||
|
||||
files_ascentlint_waiver:
|
||||
|
@ -25,7 +26,7 @@ filesets:
|
|||
# common waivers
|
||||
- lowrisc:lint:common
|
||||
files:
|
||||
- lint/prim_cdc_rand_delay.waiver
|
||||
#- lint/prim_cdc_rand_delay.waiver
|
||||
file_type: waiver
|
||||
|
||||
files_veriblelint_waiver:
|
||||
|
@ -35,6 +36,10 @@ filesets:
|
|||
|
||||
targets:
|
||||
default:
|
||||
tools:
|
||||
verilator:
|
||||
verilator_options:
|
||||
- '-DDISABLE_PRIM_CDC_RAND_DELAY'
|
||||
filesets:
|
||||
- files_rtl
|
||||
- tool_verilator ? (files_verilator_waiver)
|
||||
|
|
|
@ -12,6 +12,7 @@ filesets:
|
|||
# Needed because the generic prim_flop_2sync has a
|
||||
# dependency on prim:flop.
|
||||
- lowrisc:prim:flop
|
||||
- lowrisc:prim:cdc_rand_delay
|
||||
files:
|
||||
- rtl/prim_flop_2sync.sv
|
||||
file_type: systemVerilogSource
|
||||
|
|
44
vendor/lowrisc_ip/ip/prim/prim_onehot.core
vendored
Normal file
44
vendor/lowrisc_ip/ip/prim/prim_onehot.core
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
CAPI=2:
|
||||
# Copyright lowRISC contributors.
|
||||
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: "lowrisc:prim:onehot"
|
||||
description: "Utilities for working with one-hot encoding"
|
||||
filesets:
|
||||
files_rtl:
|
||||
depend:
|
||||
- lowrisc:prim:util
|
||||
files:
|
||||
- rtl/prim_onehot_enc.sv
|
||||
- rtl/prim_onehot_mux.sv
|
||||
file_type: systemVerilogSource
|
||||
|
||||
files_verilator_waiver:
|
||||
depend:
|
||||
# common waivers
|
||||
- lowrisc:lint:common
|
||||
#files:
|
||||
# - lint/prim_onehot.vlt
|
||||
file_type: vlt
|
||||
|
||||
files_ascentlint_waiver:
|
||||
depend:
|
||||
# common waivers
|
||||
- lowrisc:lint:common
|
||||
#files:
|
||||
# - lint/prim_onehot.waiver
|
||||
file_type: waiver
|
||||
|
||||
files_veriblelint_waiver:
|
||||
depend:
|
||||
# common waivers
|
||||
- lowrisc:lint:common
|
||||
|
||||
targets:
|
||||
default:
|
||||
filesets:
|
||||
- tool_verilator ? (files_verilator_waiver)
|
||||
- tool_ascentlint ? (files_ascentlint_waiver)
|
||||
- tool_veriblelint ? (files_veriblelint_waiver)
|
||||
- files_rtl
|
49
vendor/lowrisc_ip/ip/prim/prim_onehot_check.core
vendored
Normal file
49
vendor/lowrisc_ip/ip/prim/prim_onehot_check.core
vendored
Normal file
|
@ -0,0 +1,49 @@
|
|||
CAPI=2:
|
||||
# Copyright lowRISC contributors.
|
||||
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: "lowrisc:prim:onehot_check"
|
||||
description: "One-hot encoding checker"
|
||||
filesets:
|
||||
files_rtl:
|
||||
depend:
|
||||
- lowrisc:prim:util
|
||||
- lowrisc:prim:assert
|
||||
files:
|
||||
- rtl/prim_onehot_check.sv
|
||||
file_type: systemVerilogSource
|
||||
|
||||
files_verilator_waiver:
|
||||
depend:
|
||||
# common waivers
|
||||
- lowrisc:lint:common
|
||||
files:
|
||||
- lint/prim_onehot_check.vlt
|
||||
file_type: vlt
|
||||
|
||||
files_ascentlint_waiver:
|
||||
depend:
|
||||
# common waivers
|
||||
- lowrisc:lint:common
|
||||
files:
|
||||
- lint/prim_onehot_check.waiver
|
||||
file_type: waiver
|
||||
|
||||
files_veriblelint_waiver:
|
||||
depend:
|
||||
# common waivers
|
||||
- lowrisc:lint:common
|
||||
|
||||
targets:
|
||||
default:
|
||||
filesets:
|
||||
- tool_verilator ? (files_verilator_waiver)
|
||||
- tool_ascentlint ? (files_ascentlint_waiver)
|
||||
- tool_veriblelint ? (files_veriblelint_waiver)
|
||||
- files_rtl
|
||||
|
||||
formal:
|
||||
filesets:
|
||||
- files_rtl
|
||||
toplevel: prim_onehot_check
|
|
@ -304,12 +304,16 @@ module prim_alert_sender
|
|||
sequence AckSigInt_S;
|
||||
alert_rx_i.ping_p == alert_rx_i.ping_n [*2];
|
||||
endsequence
|
||||
|
||||
`ifndef FPV_ALERT_NO_SIGINT_ERR
|
||||
// check propagation of sigint issues to output within three cycles
|
||||
// shift sequence to the right to avoid reset effects.
|
||||
`ASSERT(SigIntPing_A, ##1 PingSigInt_S |->
|
||||
##3 alert_tx_o.alert_p == alert_tx_o.alert_n)
|
||||
`ASSERT(SigIntAck_A, ##1 AckSigInt_S |->
|
||||
##3 alert_tx_o.alert_p == alert_tx_o.alert_n)
|
||||
`endif
|
||||
|
||||
// Test in-band FSM reset request (via signal integrity error)
|
||||
`ASSERT(InBandInitFsm_A, PingSigInt_S or AckSigInt_S |-> ##3 state_q == Idle)
|
||||
`ASSERT(InBandInitPing_A, PingSigInt_S or AckSigInt_S |-> ##3 !ping_set_q)
|
||||
|
@ -332,11 +336,15 @@ module prim_alert_sender
|
|||
sequence AckSigInt_S;
|
||||
alert_rx_i.ping_p == alert_rx_i.ping_n;
|
||||
endsequence
|
||||
|
||||
`ifndef FPV_ALERT_NO_SIGINT_ERR
|
||||
// check propagation of sigint issues to output within one cycle
|
||||
`ASSERT(SigIntPing_A, PingSigInt_S |=>
|
||||
alert_tx_o.alert_p == alert_tx_o.alert_n)
|
||||
`ASSERT(SigIntAck_A, AckSigInt_S |=>
|
||||
alert_tx_o.alert_p == alert_tx_o.alert_n)
|
||||
`endif
|
||||
|
||||
// Test in-band FSM reset request (via signal integrity error)
|
||||
`ASSERT(InBandInitFsm_A, PingSigInt_S or AckSigInt_S |=> state_q == Idle)
|
||||
`ASSERT(InBandInitPing_A, PingSigInt_S or AckSigInt_S |=> !ping_set_q)
|
||||
|
@ -374,7 +382,7 @@ module prim_alert_sender
|
|||
clk_i, !rst_ni || (alert_tx_o.alert_p == alert_tx_o.alert_n))
|
||||
`endif
|
||||
|
||||
`ifdef FPV_SEC_CM_ON
|
||||
`ifdef FPV_ALERT_NO_SIGINT_ERR
|
||||
// Assumptions for FPV security countermeasures to ensure the alert protocol functions collectly.
|
||||
`ASSUME_FPV(AckPFollowsAlertP_S, alert_rx_i.ack_p == $past(alert_tx_o.alert_p))
|
||||
`ASSUME_FPV(AckNFollowsAlertN_S, alert_rx_i.ack_n == $past(alert_tx_o.alert_n))
|
||||
|
|
9
vendor/lowrisc_ip/ip/prim/rtl/prim_assert.sv
vendored
9
vendor/lowrisc_ip/ip/prim/rtl/prim_assert.sv
vendored
|
@ -43,6 +43,15 @@
|
|||
unused_assert_static_lint_error = __name'(1'b1); \
|
||||
end
|
||||
|
||||
// Static assertions for checks inside SV packages. If the conditions is not true, this will
|
||||
// trigger an error during elaboration.
|
||||
`define ASSERT_STATIC_IN_PACKAGE(__name, __prop) \
|
||||
function automatic bit assert_static_in_package_``__name(); \
|
||||
bit unused_bit [((__prop) ? 1 : -1)]; \
|
||||
unused_bit = '{default: 1'b0}; \
|
||||
return unused_bit[0]; \
|
||||
endfunction
|
||||
|
||||
// The basic helper macros are actually defined in "implementation headers". The macros should do
|
||||
// the same thing in each case (except for the dummy flavour), but in a way that the respective
|
||||
// tools support.
|
||||
|
|
20
vendor/lowrisc_ip/ip/prim/rtl/prim_blanker.sv
vendored
Normal file
20
vendor/lowrisc_ip/ip/prim/rtl/prim_blanker.sv
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Convenience module for wrapping prim_and2 for use in blanking.
|
||||
// When en_i == 1 the input is fed through to the output.
|
||||
// When en_i == 0 the output is 0.
|
||||
module prim_blanker #(
|
||||
parameter int Width = 1
|
||||
) (
|
||||
input logic [Width-1:0] in_i,
|
||||
input logic en_i,
|
||||
output logic [Width-1:0] out_o
|
||||
);
|
||||
prim_and2 #(.Width(Width)) u_blank_and (
|
||||
.in0_i(in_i),
|
||||
.in1_i({Width{en_i}}),
|
||||
.out_o
|
||||
);
|
||||
endmodule
|
281
vendor/lowrisc_ip/ip/prim/rtl/prim_cdc_rand_delay.sv
vendored
281
vendor/lowrisc_ip/ip/prim/rtl/prim_cdc_rand_delay.sv
vendored
|
@ -17,26 +17,22 @@
|
|||
// This is meant to model skew between synchronizer bits and wire delay between the src and dst
|
||||
// flops.
|
||||
//
|
||||
// Five (5) different random delay modes are available:
|
||||
// Four different random delay modes are available:
|
||||
//
|
||||
// - PrimCdcRandDelayDisable: If this delay mode is picked, this module acts as a simple
|
||||
// passthrough.
|
||||
// - RandDelayDisable: If this delay mode is picked, this module acts as a passthrough.
|
||||
//
|
||||
// - PrimCdcRandDelaySlow: If this delay mode is picked, the output to the dst domain is
|
||||
// continuously driven to `src_data_delayed`.
|
||||
// - RandDelaySlow: If this delay mode is picked, the output to the dst domain is
|
||||
// continuously driven to `src_data_delayed`.
|
||||
//
|
||||
// - PrimCdcRandDelayOnce: If this delay mode is picked, the mask `out_data_mask` used to combine
|
||||
// `src_data_with_latency` and `src_data_delayed` is fully randomized
|
||||
// once at the beginning of the simulation.
|
||||
// - RandDelayOnce: If this delay mode is picked, the mask `out_data_mask` used to combine
|
||||
// `src_data_with_latency` and `src_data_delayed` is randomized once at the
|
||||
// start of the simulation.
|
||||
//
|
||||
// - PrimCdcRandDelayInterval: If this delay mode is picked, the mask `out_data_mask` used to
|
||||
// combine `src_data_with_latency` and `src_data_delayed` is fully
|
||||
// randomized every `prim_cdc_num_src_data_changes` times that
|
||||
// `src_data_with_latency` changes.
|
||||
//
|
||||
// - PrimCdcRandDelayFull: If this delay mode is picked, the mask `out_data_mask` used to combine
|
||||
// `src_data_with_latency` and `src_data_delayed` is fully randomized
|
||||
// any time `src_data_with_latency` changes.
|
||||
// - RandDelayInterval: If this delay mode is picked, the mask `out_data_mask` used to
|
||||
// combine `src_data_with_latency` and `src_data_delayed` is fully
|
||||
// randomized every `prim_cdc_rand_delay_interval` times the src_data
|
||||
// value changes. If the `prim_cdc_rand_delay_interval` is set to 0,
|
||||
// then out_data_mask is randomized on every src_data change.
|
||||
//
|
||||
// DV has control of the weights corresponding to each random delay mode when the delay mode is
|
||||
// randomized, but can also directly override the delay mode as desired.
|
||||
|
@ -47,8 +43,8 @@
|
|||
module prim_cdc_rand_delay #(
|
||||
parameter int DataWidth = 1,
|
||||
parameter bit UseSourceClock = 1,
|
||||
parameter int LatencyPs = 500,
|
||||
parameter int JitterPs = 500
|
||||
parameter int LatencyPs = 1000,
|
||||
parameter int JitterPs = 1000
|
||||
) (
|
||||
input logic src_clk,
|
||||
input logic [DataWidth-1:0] src_data,
|
||||
|
@ -57,148 +53,181 @@ module prim_cdc_rand_delay #(
|
|||
output logic [DataWidth-1:0] dst_data
|
||||
);
|
||||
|
||||
`ASSERT_INIT(LegalWidth_A, DataWidth > 0)
|
||||
`ASSERT_INIT(LegalDataWidth_A, DataWidth > 0)
|
||||
`ASSERT_INIT(LegalLatencyPs_A, LatencyPs >= 0)
|
||||
`ASSERT_INIT(LegalJitterPs_A, JitterPs >= 0)
|
||||
|
||||
int prim_cdc_latency_ps = LatencyPs;
|
||||
int prim_cdc_jitter_ps = JitterPs;
|
||||
`ifdef SIMULATION
|
||||
`ifndef DISABLE_PRIM_CDC_RAND_DELAY
|
||||
|
||||
// Only applies with using CdcRandDelayInterval randomization mode.
|
||||
//
|
||||
// This is the number of times that `src_data_with_latency` is allowed to change before
|
||||
// we re-randomize `out_data_mask`.
|
||||
int prim_cdc_num_src_data_changes = 10;
|
||||
int counter = 0;
|
||||
typedef enum bit [1:0] {
|
||||
RandDelayModeDisable,
|
||||
RandDelayModeSlow,
|
||||
RandDelayModeOnce,
|
||||
RandDelayModeInterval
|
||||
} rand_delay_mode_e;
|
||||
|
||||
task automatic set_prim_cdc_latency_ps(int val);
|
||||
prim_cdc_latency_ps = val;
|
||||
`ASSERT_I(LegalLatency_A, prim_cdc_latency_ps > 0)
|
||||
endtask
|
||||
rand_delay_mode_e prim_cdc_rand_delay_mode;
|
||||
int unsigned prim_cdc_rand_delay_interval = 10;
|
||||
int unsigned prim_cdc_rand_delay_disable_weight = 1;
|
||||
int unsigned prim_cdc_rand_delay_slow_weight = 2;
|
||||
int unsigned prim_cdc_rand_delay_once_weight = 4;
|
||||
int unsigned prim_cdc_rand_delay_interval_weight = 3;
|
||||
bit [3:0] mode; // onehot encoded version of prim_cdc_rand_delay_mode.
|
||||
|
||||
task automatic set_prim_cdc_jitter_ps(int val);
|
||||
prim_cdc_jitter_ps = val;
|
||||
`ASSERT_I(LegalJitter_A, prim_cdc_jitter_ps > 0)
|
||||
endtask
|
||||
|
||||
task automatic set_prim_cdc_num_src_data_changes(int val);
|
||||
prim_cdc_num_src_data_changes = val;
|
||||
endtask
|
||||
|
||||
typedef enum bit [2:0] {
|
||||
PrimCdcRandDelayDisable,
|
||||
PrimCdcRandDelaySlow,
|
||||
PrimCdcRandDelayOnce,
|
||||
PrimCdcRandDelayInterval,
|
||||
PrimCdcRandDelayFull
|
||||
} prim_cdc_rand_delay_mode_e;
|
||||
|
||||
prim_cdc_rand_delay_mode_e prim_cdc_rand_mode;
|
||||
int unsigned prim_cdc_jitter_ps = JitterPs;
|
||||
int unsigned prim_cdc_latency_ps = LatencyPs;
|
||||
|
||||
logic [DataWidth-1:0] out_data_mask;
|
||||
|
||||
bit en_passthru = 1'b0;
|
||||
|
||||
bit out_randomize_en = 1'b0;
|
||||
|
||||
bit en_rand_interval_mask = 1'b0;
|
||||
|
||||
logic [DataWidth-1:0] src_data_with_latency;
|
||||
logic [DataWidth-1:0] src_data_delayed;
|
||||
|
||||
int unsigned prim_cdc_rand_disable_weight = 0;
|
||||
int unsigned prim_cdc_rand_slow_weight = 20;
|
||||
int unsigned prim_cdc_rand_once_weight = 50;
|
||||
int unsigned prim_cdc_rand_interval_weight = 20;
|
||||
int unsigned prim_cdc_rand_full_weight = 10;
|
||||
function automatic void set_prim_cdc_rand_delay_mode(int val);
|
||||
prim_cdc_rand_delay_mode = rand_delay_mode_e'(val);
|
||||
update_settings();
|
||||
endfunction
|
||||
|
||||
function automatic void set_prim_cdc_rand_delay_interval(int unsigned val);
|
||||
prim_cdc_rand_delay_interval = val;
|
||||
endfunction
|
||||
|
||||
function automatic void set_prim_cdc_jitter_ps(int val);
|
||||
`ASSERT_I(LegalJitter_A, prim_cdc_jitter_ps >= 0)
|
||||
prim_cdc_jitter_ps = val;
|
||||
endfunction
|
||||
|
||||
function automatic void set_prim_cdc_latency_ps(int val);
|
||||
`ASSERT_I(LegalLatencyPs_A, val >= 0)
|
||||
prim_cdc_latency_ps = val;
|
||||
endfunction
|
||||
|
||||
// Internal method called after prim_cdc_rand_delay_mode is set.
|
||||
function automatic void update_settings();
|
||||
mode = '0;
|
||||
mode[prim_cdc_rand_delay_mode] = 1'b1;
|
||||
if (prim_cdc_rand_delay_mode == RandDelayModeSlow) out_data_mask = '1;
|
||||
if (prim_cdc_rand_delay_mode == RandDelayModeOnce) fast_randomize(out_data_mask);
|
||||
endfunction
|
||||
|
||||
// A slightly more performant version of std::randomize(), using $urandom.
|
||||
//
|
||||
// Empirically, using std::randomize() has been found to be slower than $urandom, since the latter
|
||||
// operates on a fixed data width of 32-bits. There may be an incredibly large number of instances
|
||||
// of this module in the DUT, causing this preformance hit to be noticeable. This method
|
||||
// randomizes the data piece-wise, 32-bits at a time using $urandom instead.
|
||||
function automatic void fast_randomize(output logic [DataWidth-1:0] data);
|
||||
for (int i = 0; i < DataWidth; i += 32) data = (data << 32) | $urandom();
|
||||
endfunction
|
||||
|
||||
// Retrieves settings via plusargs.
|
||||
//
|
||||
// prefix is a string prefix to retrieve the plusarg.
|
||||
// Returns 1 if prim_cdc_rand_delay_mode was set, else 0.
|
||||
function automatic bit get_plusargs(string prefix = "");
|
||||
string mode = "";
|
||||
int unsigned val;
|
||||
if (prefix != "") prefix = {prefix, "."};
|
||||
void'($value$plusargs({prefix, "prim_cdc_rand_delay_mode=%0s"}, mode));
|
||||
`ASSERT_I(ValidMode_A, mode inside {"", "disable", "slow", "once", "interval"})
|
||||
void'($value$plusargs({prefix, "prim_cdc_rand_delay_interval=%0d"},
|
||||
prim_cdc_rand_delay_interval));
|
||||
void'($value$plusargs({prefix, "prim_cdc_rand_delay_disable_weight=%0d"},
|
||||
prim_cdc_rand_delay_disable_weight));
|
||||
void'($value$plusargs({prefix, "prim_cdc_rand_delay_slow_weight=%0d"},
|
||||
prim_cdc_rand_delay_slow_weight));
|
||||
void'($value$plusargs({prefix, "prim_cdc_rand_delay_once_weight=%0d"},
|
||||
prim_cdc_rand_delay_once_weight));
|
||||
void'($value$plusargs({prefix, "prim_cdc_rand_delay_interval_weight=%0d"},
|
||||
prim_cdc_rand_delay_interval_weight));
|
||||
void'($value$plusargs({prefix, "prim_cdc_jitter_ps=%0d"}, prim_cdc_jitter_ps));
|
||||
void'($value$plusargs({prefix, "prim_cdc_latency_ps=%0d"}, prim_cdc_latency_ps));
|
||||
|
||||
case (mode)
|
||||
"disable": prim_cdc_rand_delay_mode = RandDelayModeDisable;
|
||||
"slow": prim_cdc_rand_delay_mode = RandDelayModeSlow;
|
||||
"once": prim_cdc_rand_delay_mode = RandDelayModeOnce;
|
||||
"interval": prim_cdc_rand_delay_mode = RandDelayModeInterval;
|
||||
default: return 0;
|
||||
endcase
|
||||
return 1;
|
||||
endfunction
|
||||
|
||||
initial begin
|
||||
// DV can override these from command line as desired.
|
||||
void'($value$plusargs("prim_cdc_latency_ps=%0d", prim_cdc_latency_ps));
|
||||
void'($value$plusargs("prim_cdc_jitter_ps=%0d", prim_cdc_jitter_ps));
|
||||
void'($value$plusargs("prim_cdc_num_src_data_changes=%0d", prim_cdc_num_src_data_changes));
|
||||
void'($value$plusargs("prim_cdc_rand_disable_weight=%0d", prim_cdc_rand_disable_weight));
|
||||
void'($value$plusargs("prim_cdc_rand_slow_weight=%0d", prim_cdc_rand_slow_weight));
|
||||
void'($value$plusargs("prim_cdc_rand_once_weight=%0d", prim_cdc_rand_once_weight));
|
||||
void'($value$plusargs("prim_cdc_rand_interval_weight=%0d", prim_cdc_rand_interval_weight));
|
||||
void'($value$plusargs("prim_cdc_rand_full_weight=%0d", prim_cdc_rand_full_weight));
|
||||
bit res;
|
||||
|
||||
if (!$value$plusargs("prim_cdc_rand_mode=%0d", prim_cdc_rand_mode)) begin
|
||||
// By default pick the most performant(*) random delay mode for normal test
|
||||
// development/simulation.
|
||||
//
|
||||
// (*): Need to do some performance experiments to check that the chosen mode is actually the
|
||||
// most performant.
|
||||
prim_cdc_rand_mode = PrimCdcRandDelaySlow;
|
||||
// Command-line override via plusargs (global, applies to ALL instances).
|
||||
// Example: +prim_cdc_rand_delay_mode=once
|
||||
res = get_plusargs();
|
||||
|
||||
// Command-line override via plusargs (instance-specific).
|
||||
// Example: +tb.dut.u_foo.u_bar.u_flop_2sync.u_prim_cdc_rand_delay.prim_cdc_latency_ps=200
|
||||
res |= get_plusargs($sformatf("%m"));
|
||||
|
||||
if (!res) begin
|
||||
`DV_CHECK_STD_RANDOMIZE_WITH_FATAL(prim_cdc_rand_delay_mode,
|
||||
prim_cdc_rand_delay_mode dist {
|
||||
RandDelayModeDisable :/ prim_cdc_rand_delay_disable_weight,
|
||||
RandDelayModeSlow :/ prim_cdc_rand_delay_slow_weight,
|
||||
RandDelayModeOnce :/ prim_cdc_rand_delay_once_weight,
|
||||
RandDelayModeInterval :/ prim_cdc_rand_delay_interval_weight
|
||||
};,
|
||||
, $sformatf("%m"))
|
||||
end
|
||||
|
||||
unique case (prim_cdc_rand_mode)
|
||||
PrimCdcRandDelayDisable: begin
|
||||
// If CDC randomization disabled, behave like a passthrough
|
||||
en_passthru = 1'b1;
|
||||
end
|
||||
PrimCdcRandDelaySlow: begin
|
||||
out_data_mask = '1;
|
||||
end
|
||||
PrimCdcRandDelayOnce: begin
|
||||
void'(std::randomize(out_data_mask));
|
||||
end
|
||||
PrimCdcRandDelayInterval: begin
|
||||
out_randomize_en = 1'b1;
|
||||
en_rand_interval_mask = 1'b1;
|
||||
end
|
||||
PrimCdcRandDelayFull: begin
|
||||
out_randomize_en = 1'b1;
|
||||
end
|
||||
default: begin
|
||||
$fatal("%0d is an invalid randomization mode", prim_cdc_rand_mode);
|
||||
end
|
||||
endcase
|
||||
update_settings();
|
||||
end
|
||||
|
||||
// TODO: Run some performance experiments using this implementation versus an implementation that
|
||||
// primarily uses `forever` blocks rather than RTL constructs.
|
||||
// Need to also check if this alternate implementation is still valid when
|
||||
// compiling/simulating the design.
|
||||
// primarily uses `forever` blocks rather than RTL constructs. Need to also check if this
|
||||
// alternate implementation is still valid when compiling/simulating the design.
|
||||
if (UseSourceClock) begin : gen_use_source_clock
|
||||
// If relying on src_clk, insert a delay on the fastest clock
|
||||
|
||||
// If relying on src_clk, insert a delay on the faster clock.
|
||||
always_ff @(posedge src_clk or posedge dst_clk) begin
|
||||
src_data_delayed <= src_data;
|
||||
end
|
||||
assign src_data_with_latency = src_data;
|
||||
|
||||
end else begin : gen_no_use_source_clock
|
||||
// If not relying on src_clk, delay by a fixed number of ps determined by the module parameters
|
||||
always_comb begin
|
||||
|
||||
// If not relying on src_clk, delay by a fixed number of ps determined by the module parameters.
|
||||
always @(src_data) begin
|
||||
src_data_with_latency <= #(prim_cdc_latency_ps * 1ps) src_data;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
always @(src_data_with_latency) begin
|
||||
src_data_delayed <= #(prim_cdc_jitter_ps * 1ps) src_data_with_latency;
|
||||
end
|
||||
|
||||
end : gen_no_use_source_clock
|
||||
|
||||
// Randomize delayed random data selection only when input data changes
|
||||
// Randomize delayed random data selection when input data changes, every
|
||||
// prim_cdc_rand_delay_interval number of changes.
|
||||
int counter = 0;
|
||||
always @(src_data_with_latency) begin
|
||||
if ((out_randomize_en && !en_rand_interval_mask) ||
|
||||
(en_rand_interval_mask && counter == prim_cdc_num_src_data_changes) begin
|
||||
for (int i = 0; i < DataWidth; i += 32) begin
|
||||
// As of VCS 2017.12-SP2-6, it is slower to randomize for a DataWidth <= 32 with
|
||||
// std::randomize() than using $urandom(), which may be more noticeable here as this module
|
||||
// can potentially have a large number of instances.
|
||||
//
|
||||
// Whenever time permits, it will be interesting to run some perf tests with the current VCS
|
||||
// version and see what updated performance looks like.
|
||||
out_data_mask = (out_data_mask << 32) | $urandom();
|
||||
end
|
||||
end
|
||||
|
||||
if (en_rand_interval_mask) begin
|
||||
counter <= (counter == prim_cdc_num_src_data_changes) ? 0 : counter + 1;
|
||||
if (mode[RandDelayModeInterval]) begin
|
||||
counter <= (counter >= prim_cdc_rand_delay_interval) ? '0 : counter + 1;
|
||||
if (counter == prim_cdc_rand_delay_interval) fast_randomize(out_data_mask);
|
||||
end else begin
|
||||
counter <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
assign dst_data = (en_passthru) ?
|
||||
(src_data) :
|
||||
assign dst_data = mode[RandDelayModeDisable] ? src_data :
|
||||
((src_data_delayed & out_data_mask) | (src_data_with_latency & ~out_data_mask));
|
||||
|
||||
`else
|
||||
|
||||
// Direct pass through.
|
||||
assign dst_data = src_data;
|
||||
|
||||
`endif // DISABLE_PRIM_CDC_RAND_DELAY
|
||||
|
||||
`else
|
||||
|
||||
// Direct pass through.
|
||||
assign dst_data = src_data;
|
||||
|
||||
`endif // SIMULATION
|
||||
|
||||
//TODO: coverage
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -233,6 +233,7 @@ module prim_diff_decode #(
|
|||
end
|
||||
end
|
||||
|
||||
`ifndef FPV_ALERT_NO_SIGINT_ERR
|
||||
// correctly detect sigint issue (only one transition cycle of permissible due to skew)
|
||||
`ASSERT(SigintCheck0_A, hlp_diff_pq == hlp_diff_nq [*2] |-> ##[0:1] sigint_o)
|
||||
// the synchronizer adds 2 cycles of latency with respect to input signals.
|
||||
|
@ -256,6 +257,8 @@ module prim_diff_decode #(
|
|||
$fell(hlp_diff_nq) && $stable(hlp_diff_pq) ##1 $stable(hlp_diff_nq) && $rose(hlp_diff_pq)
|
||||
|->
|
||||
##1 rise_o)
|
||||
`endif
|
||||
|
||||
// correctly detect edges
|
||||
`ASSERT(RiseCheck_A, ##1 $rose(hlp_diff_pq) && (hlp_diff_pq ^ hlp_diff_nq) |->
|
||||
##[1:2] rise_o, clk_i, !rst_ni || sigint_o)
|
||||
|
@ -270,8 +273,12 @@ module prim_diff_decode #(
|
|||
`endif
|
||||
end else begin : gen_sync_assert
|
||||
// assertions for synchronous case
|
||||
|
||||
`ifndef FPV_ALERT_NO_SIGINT_ERR
|
||||
// correctly detect sigint issue
|
||||
`ASSERT(SigintCheck_A, diff_pi == diff_ni |-> sigint_o)
|
||||
`endif
|
||||
|
||||
// correctly detect edges
|
||||
`ASSERT(RiseCheck_A, ##1 $rose(diff_pi) && (diff_pi ^ diff_ni) |-> rise_o)
|
||||
`ASSERT(FallCheck_A, ##1 $fell(diff_pi) && (diff_pi ^ diff_ni) |-> fall_o)
|
||||
|
|
20
vendor/lowrisc_ip/ip/prim/rtl/prim_flop_2sync.sv
vendored
20
vendor/lowrisc_ip/ip/prim/rtl/prim_flop_2sync.sv
vendored
|
@ -8,7 +8,9 @@
|
|||
|
||||
module prim_flop_2sync #(
|
||||
parameter int Width = 16,
|
||||
parameter logic [Width-1:0] ResetValue = '0
|
||||
parameter logic [Width-1:0] ResetValue = '0,
|
||||
parameter int CdcLatencyPs = 1000,
|
||||
parameter int CdcJitterPs = 1000
|
||||
) (
|
||||
input clk_i,
|
||||
input rst_ni,
|
||||
|
@ -16,7 +18,19 @@ module prim_flop_2sync #(
|
|||
output logic [Width-1:0] q_o
|
||||
);
|
||||
|
||||
// TODO(#10432): Add CDC instrumentation for simulations
|
||||
logic [Width-1:0] d_o;
|
||||
|
||||
prim_cdc_rand_delay #(
|
||||
.DataWidth(Width),
|
||||
.UseSourceClock(0),
|
||||
.LatencyPs(CdcLatencyPs),
|
||||
.JitterPs(CdcJitterPs)
|
||||
) u_prim_cdc_rand_delay (
|
||||
.src_clk(),
|
||||
.src_data(d_i),
|
||||
.dst_clk(clk_i),
|
||||
.dst_data(d_o)
|
||||
);
|
||||
|
||||
logic [Width-1:0] intq;
|
||||
|
||||
|
@ -26,7 +40,7 @@ module prim_flop_2sync #(
|
|||
) u_sync_1 (
|
||||
.clk_i,
|
||||
.rst_ni,
|
||||
.d_i,
|
||||
.d_i(d_o),
|
||||
.q_o(intq)
|
||||
);
|
||||
|
||||
|
|
122
vendor/lowrisc_ip/ip/prim/rtl/prim_onehot_check.sv
vendored
Normal file
122
vendor/lowrisc_ip/ip/prim/rtl/prim_onehot_check.sv
vendored
Normal file
|
@ -0,0 +1,122 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Onehot checker.
|
||||
//
|
||||
// This module checks whether the input vector oh_i is onehot0 and generates an error if not.
|
||||
//
|
||||
// Optionally, two additional checks can be activated:
|
||||
//
|
||||
// 1) EnableCheck: this check performs an OR reduction of the onehot vector, and compares
|
||||
// the result with en_i. If there is a mismatch, an error is generated.
|
||||
// 2) AddrCheck: this checks whether the bit at a certain location is equal to en_i.
|
||||
// It requires an additional address addr_i to be supplied to the module.
|
||||
// This check can only be enabled if EnableCheck is enabled.
|
||||
//
|
||||
// All checks make use of an explicit binary tree implementation in order to minimize the delay.
|
||||
//
|
||||
|
||||
`include "prim_assert.sv"
|
||||
|
||||
module prim_onehot_check #(
|
||||
parameter int unsigned AddrWidth = 5,
|
||||
// The onehot width can be <= 2**AddrWidth and does not have to be a power of two.
|
||||
parameter int unsigned OneHotWidth = 2**AddrWidth,
|
||||
// If set to 0, the addr_i input will not be used for the check and can be tied off.
|
||||
parameter bit AddrCheck = 1,
|
||||
// If set to 0, the en_i value will not be used for the check and can be tied off.
|
||||
parameter bit EnableCheck = 1
|
||||
) (
|
||||
// The module is combinational - the clock and reset are only used for assertions.
|
||||
input clk_i,
|
||||
input rst_ni,
|
||||
|
||||
input logic [OneHotWidth-1:0] oh_i,
|
||||
input logic [AddrWidth-1:0] addr_i,
|
||||
input logic en_i,
|
||||
|
||||
output logic err_o
|
||||
);
|
||||
|
||||
///////////////////////
|
||||
// Binary tree logic //
|
||||
///////////////////////
|
||||
|
||||
// This only works with 2 or more sources.
|
||||
`ASSERT_INIT(NumSources_A, OneHotWidth >= 2)
|
||||
`ASSERT_INIT(AddrSize_A, OneHotWidth <= 2**AddrWidth)
|
||||
`ASSERT_INIT(AddrImpliesEnable_A, AddrCheck && EnableCheck || !AddrCheck)
|
||||
|
||||
// Align to powers of 2 for simplicity.
|
||||
// A full binary tree with N levels has 2**N + 2**N-1 nodes.
|
||||
localparam int NumLevels = $clog2(OneHotWidth);
|
||||
logic [2**(NumLevels+1)-2:0] or_tree;
|
||||
logic [2**(NumLevels+1)-2:0] and_tree; // Used for the address check
|
||||
logic [2**(NumLevels+1)-2:0] err_tree; // Used for the enable check
|
||||
|
||||
for (genvar level = 0; level < NumLevels+1; level++) begin : gen_tree
|
||||
//
|
||||
// level+1 C0 C1 <- "Base1" points to the first node on "level+1",
|
||||
// \ / these nodes are the children of the nodes one level below
|
||||
// level Pa <- "Base0", points to the first node on "level",
|
||||
// these nodes are the parents of the nodes one level above
|
||||
//
|
||||
// hence we have the following indices for the paPa, C0, C1 nodes:
|
||||
// Pa = 2**level - 1 + offset = Base0 + offset
|
||||
// C0 = 2**(level+1) - 1 + 2*offset = Base1 + 2*offset
|
||||
// C1 = 2**(level+1) - 1 + 2*offset + 1 = Base1 + 2*offset + 1
|
||||
//
|
||||
localparam int Base0 = (2**level)-1;
|
||||
localparam int Base1 = (2**(level+1))-1;
|
||||
|
||||
for (genvar offset = 0; offset < 2**level; offset++) begin : gen_level
|
||||
localparam int Pa = Base0 + offset;
|
||||
localparam int C0 = Base1 + 2*offset;
|
||||
localparam int C1 = Base1 + 2*offset + 1;
|
||||
|
||||
// This assigns the input values, their corresponding IDs and valid signals to the tree leafs.
|
||||
if (level == NumLevels) begin : gen_leafs
|
||||
if (offset < OneHotWidth) begin : gen_assign
|
||||
assign or_tree[Pa] = oh_i[offset];
|
||||
assign and_tree[Pa] = oh_i[offset];
|
||||
end else begin : gen_tie_off
|
||||
assign or_tree[Pa] = 1'b0;
|
||||
assign and_tree[Pa] = 1'b0;
|
||||
end
|
||||
assign err_tree[Pa] = 1'b0;
|
||||
// This creates the node assignments.
|
||||
end else begin : gen_nodes
|
||||
assign or_tree[Pa] = or_tree[C0] || or_tree[C1];
|
||||
assign and_tree[Pa] = (!addr_i[AddrWidth-1-level] && and_tree[C0]) ||
|
||||
(addr_i[AddrWidth-1-level] && and_tree[C1]);
|
||||
assign err_tree[Pa] = (or_tree[C0] && or_tree[C1]) || err_tree[C0] || err_tree[C1];
|
||||
end
|
||||
end : gen_level
|
||||
end : gen_tree
|
||||
|
||||
// Check whether:
|
||||
// 1) more than 1 bit is set in the vector
|
||||
// 2) whether en_i agrees with (|oh_i)
|
||||
// 3) the bit that is set is actually in the correct position
|
||||
logic enable_err, addr_err, oh0_err;
|
||||
assign oh0_err = err_tree[0];
|
||||
if (EnableCheck) begin : gen_enable_check
|
||||
assign enable_err = or_tree[0] ^ en_i;
|
||||
`ASSERT(EnableCheck_A, ($countones(oh_i) != en_i) |-> err_o)
|
||||
if (AddrCheck) begin : gen_addr_check
|
||||
assign addr_err = and_tree[0] ^ en_i;
|
||||
`ASSERT(AddrCheck_A, oh_i[addr_i] != en_i |-> err_o)
|
||||
end else begin : gen_no_addr_check
|
||||
assign addr_err = 1'b0;
|
||||
end
|
||||
end else begin : gen_no_enable_check
|
||||
assign enable_err = 1'b0;
|
||||
assign addr_err = 1'b0;
|
||||
end
|
||||
|
||||
assign err_o = oh0_err || enable_err || addr_err;
|
||||
|
||||
`ASSERT(Onehot0Check_A, !$onehot0(oh_i) |-> err_o)
|
||||
|
||||
endmodule : prim_onehot_check
|
21
vendor/lowrisc_ip/ip/prim/rtl/prim_onehot_enc.sv
vendored
Normal file
21
vendor/lowrisc_ip/ip/prim/rtl/prim_onehot_enc.sv
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// One-hot encoder
|
||||
// Outputs a one-hot encoded version of an integer input.
|
||||
|
||||
module prim_onehot_enc #(
|
||||
parameter int unsigned OneHotWidth = 32,
|
||||
localparam int unsigned InputWidth = $clog2(OneHotWidth)
|
||||
) (
|
||||
input logic [InputWidth-1:0] in_i,
|
||||
input logic en_i, // out_o == '0 when en_i == 0
|
||||
|
||||
output logic [OneHotWidth-1:0] out_o
|
||||
);
|
||||
|
||||
for (genvar i = 0; i < OneHotWidth; ++i) begin : g_out
|
||||
assign out_o[i] = (in_i == i) & en_i;
|
||||
end
|
||||
endmodule
|
48
vendor/lowrisc_ip/ip/prim/rtl/prim_onehot_mux.sv
vendored
Normal file
48
vendor/lowrisc_ip/ip/prim/rtl/prim_onehot_mux.sv
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
// Copyright lowRISC contributors.
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// One-hot mux
|
||||
// A AND/OR mux with a one-hot select input.
|
||||
|
||||
`include "prim_assert.sv"
|
||||
|
||||
module prim_onehot_mux #(
|
||||
parameter int Width = 32,
|
||||
parameter int Inputs = 8
|
||||
) (
|
||||
// Clock and reset only for assertions
|
||||
input clk_i,
|
||||
input rst_ni,
|
||||
|
||||
input logic [Width-1:0] in_i [Inputs],
|
||||
input logic [Inputs-1:0] sel_i, // Must be one-hot or zero
|
||||
output logic [Width-1:0] out_o
|
||||
);
|
||||
logic [Inputs-1:0] in_mux [Width];
|
||||
|
||||
for (genvar b = 0; b < Width; ++b) begin : g_in_mux_outer
|
||||
logic [Inputs-1:0] out_mux_bits;
|
||||
|
||||
for (genvar i = 0; i < Inputs; ++i) begin : g_in_mux_inner
|
||||
assign in_mux[b][i] = in_i[i][b];
|
||||
end
|
||||
|
||||
prim_and2 #(.Width(Inputs)) u_mux_bit_and(
|
||||
.in0_i(in_mux[b]),
|
||||
.in1_i(sel_i),
|
||||
.out_o(out_mux_bits)
|
||||
);
|
||||
|
||||
assign out_o[b] = |out_mux_bits;
|
||||
end
|
||||
|
||||
logic unused_clk;
|
||||
logic unused_rst_n;
|
||||
|
||||
// clock and reset only needed for assertion
|
||||
assign unused_clk = clk_i;
|
||||
assign unused_rst_n = rst_ni;
|
||||
|
||||
`ASSERT(SelIsOnehot_A, $onehot0(sel_i))
|
||||
endmodule
|
|
@ -320,6 +320,8 @@ module prim_ram_1p_scr import prim_ram_1p_pkg::*; #(
|
|||
for (int k = 0; k < Width; k++) begin
|
||||
if (wmask_q[k]) begin
|
||||
rdata_o[k] = wdata_q[k];
|
||||
end else begin
|
||||
rdata_o[k] = rdata[k];
|
||||
end
|
||||
end
|
||||
// regular reads. note that we just return zero in case
|
||||
|
|
|
@ -11,12 +11,12 @@ module prim_secded_22_16_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 22'(data_i);
|
||||
data_o[16] = 1'b0 ^ ^(data_o & 22'h00496E);
|
||||
data_o[17] = 1'b0 ^ ^(data_o & 22'h00F20B);
|
||||
data_o[18] = 1'b0 ^ ^(data_o & 22'h008ED8);
|
||||
data_o[19] = 1'b0 ^ ^(data_o & 22'h007714);
|
||||
data_o[20] = 1'b0 ^ ^(data_o & 22'h00ACA5);
|
||||
data_o[21] = 1'b0 ^ ^(data_o & 22'h0011F3);
|
||||
data_o[16] = ^(data_o & 22'h00496E);
|
||||
data_o[17] = ^(data_o & 22'h00F20B);
|
||||
data_o[18] = ^(data_o & 22'h008ED8);
|
||||
data_o[19] = ^(data_o & 22'h007714);
|
||||
data_o[20] = ^(data_o & 22'h00ACA5);
|
||||
data_o[21] = ^(data_o & 22'h0011F3);
|
||||
end
|
||||
|
||||
endmodule : prim_secded_22_16_enc
|
||||
|
|
|
@ -11,12 +11,12 @@ module prim_secded_28_22_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 28'(data_i);
|
||||
data_o[22] = 1'b0 ^ ^(data_o & 28'h03003FF);
|
||||
data_o[23] = 1'b0 ^ ^(data_o & 28'h010FC0F);
|
||||
data_o[24] = 1'b0 ^ ^(data_o & 28'h0271C71);
|
||||
data_o[25] = 1'b0 ^ ^(data_o & 28'h03B6592);
|
||||
data_o[26] = 1'b0 ^ ^(data_o & 28'h03DAAA4);
|
||||
data_o[27] = 1'b0 ^ ^(data_o & 28'h03ED348);
|
||||
data_o[22] = ^(data_o & 28'h03003FF);
|
||||
data_o[23] = ^(data_o & 28'h010FC0F);
|
||||
data_o[24] = ^(data_o & 28'h0271C71);
|
||||
data_o[25] = ^(data_o & 28'h03B6592);
|
||||
data_o[26] = ^(data_o & 28'h03DAAA4);
|
||||
data_o[27] = ^(data_o & 28'h03ED348);
|
||||
end
|
||||
|
||||
endmodule : prim_secded_28_22_enc
|
||||
|
|
|
@ -11,13 +11,13 @@ module prim_secded_39_32_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 39'(data_i);
|
||||
data_o[32] = 1'b0 ^ ^(data_o & 39'h002606BD25);
|
||||
data_o[33] = 1'b0 ^ ^(data_o & 39'h00DEBA8050);
|
||||
data_o[34] = 1'b0 ^ ^(data_o & 39'h00413D89AA);
|
||||
data_o[35] = 1'b0 ^ ^(data_o & 39'h0031234ED1);
|
||||
data_o[36] = 1'b0 ^ ^(data_o & 39'h00C2C1323B);
|
||||
data_o[37] = 1'b0 ^ ^(data_o & 39'h002DCC624C);
|
||||
data_o[38] = 1'b0 ^ ^(data_o & 39'h0098505586);
|
||||
data_o[32] = ^(data_o & 39'h002606BD25);
|
||||
data_o[33] = ^(data_o & 39'h00DEBA8050);
|
||||
data_o[34] = ^(data_o & 39'h00413D89AA);
|
||||
data_o[35] = ^(data_o & 39'h0031234ED1);
|
||||
data_o[36] = ^(data_o & 39'h00C2C1323B);
|
||||
data_o[37] = ^(data_o & 39'h002DCC624C);
|
||||
data_o[38] = ^(data_o & 39'h0098505586);
|
||||
end
|
||||
|
||||
endmodule : prim_secded_39_32_enc
|
||||
|
|
|
@ -11,13 +11,13 @@ module prim_secded_64_57_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 64'(data_i);
|
||||
data_o[57] = 1'b0 ^ ^(data_o & 64'h0103FFF800007FFF);
|
||||
data_o[58] = 1'b0 ^ ^(data_o & 64'h017C1FF801FF801F);
|
||||
data_o[59] = 1'b0 ^ ^(data_o & 64'h01BDE1F87E0781E1);
|
||||
data_o[60] = 1'b0 ^ ^(data_o & 64'h01DEEE3B8E388E22);
|
||||
data_o[61] = 1'b0 ^ ^(data_o & 64'h01EF76CDB2C93244);
|
||||
data_o[62] = 1'b0 ^ ^(data_o & 64'h01F7BB56D5525488);
|
||||
data_o[63] = 1'b0 ^ ^(data_o & 64'h01FBDDA769A46910);
|
||||
data_o[57] = ^(data_o & 64'h0103FFF800007FFF);
|
||||
data_o[58] = ^(data_o & 64'h017C1FF801FF801F);
|
||||
data_o[59] = ^(data_o & 64'h01BDE1F87E0781E1);
|
||||
data_o[60] = ^(data_o & 64'h01DEEE3B8E388E22);
|
||||
data_o[61] = ^(data_o & 64'h01EF76CDB2C93244);
|
||||
data_o[62] = ^(data_o & 64'h01F7BB56D5525488);
|
||||
data_o[63] = ^(data_o & 64'h01FBDDA769A46910);
|
||||
end
|
||||
|
||||
endmodule : prim_secded_64_57_enc
|
||||
|
|
|
@ -11,14 +11,14 @@ module prim_secded_72_64_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 72'(data_i);
|
||||
data_o[64] = 1'b0 ^ ^(data_o & 72'h00B9000000001FFFFF);
|
||||
data_o[65] = 1'b0 ^ ^(data_o & 72'h005E00000FFFE0003F);
|
||||
data_o[66] = 1'b0 ^ ^(data_o & 72'h0067003FF003E007C1);
|
||||
data_o[67] = 1'b0 ^ ^(data_o & 72'h00CD0FC0F03C207842);
|
||||
data_o[68] = 1'b0 ^ ^(data_o & 72'h00B671C711C4438884);
|
||||
data_o[69] = 1'b0 ^ ^(data_o & 72'h00B5B65926488C9108);
|
||||
data_o[70] = 1'b0 ^ ^(data_o & 72'h00CBDAAA4A91152210);
|
||||
data_o[71] = 1'b0 ^ ^(data_o & 72'h007AED348D221A4420);
|
||||
data_o[64] = ^(data_o & 72'h00B9000000001FFFFF);
|
||||
data_o[65] = ^(data_o & 72'h005E00000FFFE0003F);
|
||||
data_o[66] = ^(data_o & 72'h0067003FF003E007C1);
|
||||
data_o[67] = ^(data_o & 72'h00CD0FC0F03C207842);
|
||||
data_o[68] = ^(data_o & 72'h00B671C711C4438884);
|
||||
data_o[69] = ^(data_o & 72'h00B5B65926488C9108);
|
||||
data_o[70] = ^(data_o & 72'h00CBDAAA4A91152210);
|
||||
data_o[71] = ^(data_o & 72'h007AED348D221A4420);
|
||||
end
|
||||
|
||||
endmodule : prim_secded_72_64_enc
|
||||
|
|
|
@ -11,12 +11,12 @@ module prim_secded_hamming_22_16_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 22'(data_i);
|
||||
data_o[16] = 1'b0 ^ ^(data_o & 22'h00AD5B);
|
||||
data_o[17] = 1'b0 ^ ^(data_o & 22'h00366D);
|
||||
data_o[18] = 1'b0 ^ ^(data_o & 22'h00C78E);
|
||||
data_o[19] = 1'b0 ^ ^(data_o & 22'h0007F0);
|
||||
data_o[20] = 1'b0 ^ ^(data_o & 22'h00F800);
|
||||
data_o[21] = 1'b0 ^ ^(data_o & 22'h1FFFFF);
|
||||
data_o[16] = ^(data_o & 22'h00AD5B);
|
||||
data_o[17] = ^(data_o & 22'h00366D);
|
||||
data_o[18] = ^(data_o & 22'h00C78E);
|
||||
data_o[19] = ^(data_o & 22'h0007F0);
|
||||
data_o[20] = ^(data_o & 22'h00F800);
|
||||
data_o[21] = ^(data_o & 22'h1FFFFF);
|
||||
end
|
||||
|
||||
endmodule : prim_secded_hamming_22_16_enc
|
||||
|
|
|
@ -11,13 +11,13 @@ module prim_secded_hamming_39_32_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 39'(data_i);
|
||||
data_o[32] = 1'b0 ^ ^(data_o & 39'h0056AAAD5B);
|
||||
data_o[33] = 1'b0 ^ ^(data_o & 39'h009B33366D);
|
||||
data_o[34] = 1'b0 ^ ^(data_o & 39'h00E3C3C78E);
|
||||
data_o[35] = 1'b0 ^ ^(data_o & 39'h0003FC07F0);
|
||||
data_o[36] = 1'b0 ^ ^(data_o & 39'h0003FFF800);
|
||||
data_o[37] = 1'b0 ^ ^(data_o & 39'h00FC000000);
|
||||
data_o[38] = 1'b0 ^ ^(data_o & 39'h3FFFFFFFFF);
|
||||
data_o[32] = ^(data_o & 39'h0056AAAD5B);
|
||||
data_o[33] = ^(data_o & 39'h009B33366D);
|
||||
data_o[34] = ^(data_o & 39'h00E3C3C78E);
|
||||
data_o[35] = ^(data_o & 39'h0003FC07F0);
|
||||
data_o[36] = ^(data_o & 39'h0003FFF800);
|
||||
data_o[37] = ^(data_o & 39'h00FC000000);
|
||||
data_o[38] = ^(data_o & 39'h3FFFFFFFFF);
|
||||
end
|
||||
|
||||
endmodule : prim_secded_hamming_39_32_enc
|
||||
|
|
|
@ -11,14 +11,14 @@ module prim_secded_hamming_72_64_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 72'(data_i);
|
||||
data_o[64] = 1'b0 ^ ^(data_o & 72'h00AB55555556AAAD5B);
|
||||
data_o[65] = 1'b0 ^ ^(data_o & 72'h00CD9999999B33366D);
|
||||
data_o[66] = 1'b0 ^ ^(data_o & 72'h00F1E1E1E1E3C3C78E);
|
||||
data_o[67] = 1'b0 ^ ^(data_o & 72'h0001FE01FE03FC07F0);
|
||||
data_o[68] = 1'b0 ^ ^(data_o & 72'h0001FFFE0003FFF800);
|
||||
data_o[69] = 1'b0 ^ ^(data_o & 72'h0001FFFFFFFC000000);
|
||||
data_o[70] = 1'b0 ^ ^(data_o & 72'h00FE00000000000000);
|
||||
data_o[71] = 1'b0 ^ ^(data_o & 72'h7FFFFFFFFFFFFFFFFF);
|
||||
data_o[64] = ^(data_o & 72'h00AB55555556AAAD5B);
|
||||
data_o[65] = ^(data_o & 72'h00CD9999999B33366D);
|
||||
data_o[66] = ^(data_o & 72'h00F1E1E1E1E3C3C78E);
|
||||
data_o[67] = ^(data_o & 72'h0001FE01FE03FC07F0);
|
||||
data_o[68] = ^(data_o & 72'h0001FFFE0003FFF800);
|
||||
data_o[69] = ^(data_o & 72'h0001FFFFFFFC000000);
|
||||
data_o[70] = ^(data_o & 72'h00FE00000000000000);
|
||||
data_o[71] = ^(data_o & 72'h7FFFFFFFFFFFFFFFFF);
|
||||
end
|
||||
|
||||
endmodule : prim_secded_hamming_72_64_enc
|
||||
|
|
|
@ -11,14 +11,14 @@ module prim_secded_hamming_76_68_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 76'(data_i);
|
||||
data_o[68] = 1'b0 ^ ^(data_o & 76'h00AAB55555556AAAD5B);
|
||||
data_o[69] = 1'b0 ^ ^(data_o & 76'h00CCD9999999B33366D);
|
||||
data_o[70] = 1'b0 ^ ^(data_o & 76'h000F1E1E1E1E3C3C78E);
|
||||
data_o[71] = 1'b0 ^ ^(data_o & 76'h00F01FE01FE03FC07F0);
|
||||
data_o[72] = 1'b0 ^ ^(data_o & 76'h00001FFFE0003FFF800);
|
||||
data_o[73] = 1'b0 ^ ^(data_o & 76'h00001FFFFFFFC000000);
|
||||
data_o[74] = 1'b0 ^ ^(data_o & 76'h00FFE00000000000000);
|
||||
data_o[75] = 1'b0 ^ ^(data_o & 76'h7FFFFFFFFFFFFFFFFFF);
|
||||
data_o[68] = ^(data_o & 76'h00AAB55555556AAAD5B);
|
||||
data_o[69] = ^(data_o & 76'h00CCD9999999B33366D);
|
||||
data_o[70] = ^(data_o & 76'h000F1E1E1E1E3C3C78E);
|
||||
data_o[71] = ^(data_o & 76'h00F01FE01FE03FC07F0);
|
||||
data_o[72] = ^(data_o & 76'h00001FFFE0003FFF800);
|
||||
data_o[73] = ^(data_o & 76'h00001FFFFFFFC000000);
|
||||
data_o[74] = ^(data_o & 76'h00FFE00000000000000);
|
||||
data_o[75] = ^(data_o & 76'h7FFFFFFFFFFFFFFFFFF);
|
||||
end
|
||||
|
||||
endmodule : prim_secded_hamming_76_68_enc
|
||||
|
|
|
@ -11,12 +11,13 @@ module prim_secded_inv_22_16_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 22'(data_i);
|
||||
data_o[16] = 1'b0 ^ ^(data_o & 22'h00496E);
|
||||
data_o[17] = 1'b1 ^ ^(data_o & 22'h00F20B);
|
||||
data_o[18] = 1'b0 ^ ^(data_o & 22'h008ED8);
|
||||
data_o[19] = 1'b1 ^ ^(data_o & 22'h007714);
|
||||
data_o[20] = 1'b0 ^ ^(data_o & 22'h00ACA5);
|
||||
data_o[21] = 1'b1 ^ ^(data_o & 22'h0011F3);
|
||||
data_o[16] = ^(data_o & 22'h00496E);
|
||||
data_o[17] = ^(data_o & 22'h00F20B);
|
||||
data_o[18] = ^(data_o & 22'h008ED8);
|
||||
data_o[19] = ^(data_o & 22'h007714);
|
||||
data_o[20] = ^(data_o & 22'h00ACA5);
|
||||
data_o[21] = ^(data_o & 22'h0011F3);
|
||||
data_o ^= 22'h2A0000;
|
||||
end
|
||||
|
||||
endmodule : prim_secded_inv_22_16_enc
|
||||
|
|
|
@ -11,12 +11,13 @@ module prim_secded_inv_28_22_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 28'(data_i);
|
||||
data_o[22] = 1'b0 ^ ^(data_o & 28'h03003FF);
|
||||
data_o[23] = 1'b1 ^ ^(data_o & 28'h010FC0F);
|
||||
data_o[24] = 1'b0 ^ ^(data_o & 28'h0271C71);
|
||||
data_o[25] = 1'b1 ^ ^(data_o & 28'h03B6592);
|
||||
data_o[26] = 1'b0 ^ ^(data_o & 28'h03DAAA4);
|
||||
data_o[27] = 1'b1 ^ ^(data_o & 28'h03ED348);
|
||||
data_o[22] = ^(data_o & 28'h03003FF);
|
||||
data_o[23] = ^(data_o & 28'h010FC0F);
|
||||
data_o[24] = ^(data_o & 28'h0271C71);
|
||||
data_o[25] = ^(data_o & 28'h03B6592);
|
||||
data_o[26] = ^(data_o & 28'h03DAAA4);
|
||||
data_o[27] = ^(data_o & 28'h03ED348);
|
||||
data_o ^= 28'hA800000;
|
||||
end
|
||||
|
||||
endmodule : prim_secded_inv_28_22_enc
|
||||
|
|
|
@ -11,13 +11,14 @@ module prim_secded_inv_39_32_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 39'(data_i);
|
||||
data_o[32] = 1'b0 ^ ^(data_o & 39'h002606BD25);
|
||||
data_o[33] = 1'b1 ^ ^(data_o & 39'h00DEBA8050);
|
||||
data_o[34] = 1'b0 ^ ^(data_o & 39'h00413D89AA);
|
||||
data_o[35] = 1'b1 ^ ^(data_o & 39'h0031234ED1);
|
||||
data_o[36] = 1'b0 ^ ^(data_o & 39'h00C2C1323B);
|
||||
data_o[37] = 1'b1 ^ ^(data_o & 39'h002DCC624C);
|
||||
data_o[38] = 1'b0 ^ ^(data_o & 39'h0098505586);
|
||||
data_o[32] = ^(data_o & 39'h002606BD25);
|
||||
data_o[33] = ^(data_o & 39'h00DEBA8050);
|
||||
data_o[34] = ^(data_o & 39'h00413D89AA);
|
||||
data_o[35] = ^(data_o & 39'h0031234ED1);
|
||||
data_o[36] = ^(data_o & 39'h00C2C1323B);
|
||||
data_o[37] = ^(data_o & 39'h002DCC624C);
|
||||
data_o[38] = ^(data_o & 39'h0098505586);
|
||||
data_o ^= 39'h2A00000000;
|
||||
end
|
||||
|
||||
endmodule : prim_secded_inv_39_32_enc
|
||||
|
|
|
@ -11,13 +11,14 @@ module prim_secded_inv_64_57_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 64'(data_i);
|
||||
data_o[57] = 1'b0 ^ ^(data_o & 64'h0103FFF800007FFF);
|
||||
data_o[58] = 1'b1 ^ ^(data_o & 64'h017C1FF801FF801F);
|
||||
data_o[59] = 1'b0 ^ ^(data_o & 64'h01BDE1F87E0781E1);
|
||||
data_o[60] = 1'b1 ^ ^(data_o & 64'h01DEEE3B8E388E22);
|
||||
data_o[61] = 1'b0 ^ ^(data_o & 64'h01EF76CDB2C93244);
|
||||
data_o[62] = 1'b1 ^ ^(data_o & 64'h01F7BB56D5525488);
|
||||
data_o[63] = 1'b0 ^ ^(data_o & 64'h01FBDDA769A46910);
|
||||
data_o[57] = ^(data_o & 64'h0103FFF800007FFF);
|
||||
data_o[58] = ^(data_o & 64'h017C1FF801FF801F);
|
||||
data_o[59] = ^(data_o & 64'h01BDE1F87E0781E1);
|
||||
data_o[60] = ^(data_o & 64'h01DEEE3B8E388E22);
|
||||
data_o[61] = ^(data_o & 64'h01EF76CDB2C93244);
|
||||
data_o[62] = ^(data_o & 64'h01F7BB56D5525488);
|
||||
data_o[63] = ^(data_o & 64'h01FBDDA769A46910);
|
||||
data_o ^= 64'h5400000000000000;
|
||||
end
|
||||
|
||||
endmodule : prim_secded_inv_64_57_enc
|
||||
|
|
|
@ -11,14 +11,15 @@ module prim_secded_inv_72_64_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 72'(data_i);
|
||||
data_o[64] = 1'b0 ^ ^(data_o & 72'h00B9000000001FFFFF);
|
||||
data_o[65] = 1'b1 ^ ^(data_o & 72'h005E00000FFFE0003F);
|
||||
data_o[66] = 1'b0 ^ ^(data_o & 72'h0067003FF003E007C1);
|
||||
data_o[67] = 1'b1 ^ ^(data_o & 72'h00CD0FC0F03C207842);
|
||||
data_o[68] = 1'b0 ^ ^(data_o & 72'h00B671C711C4438884);
|
||||
data_o[69] = 1'b1 ^ ^(data_o & 72'h00B5B65926488C9108);
|
||||
data_o[70] = 1'b0 ^ ^(data_o & 72'h00CBDAAA4A91152210);
|
||||
data_o[71] = 1'b1 ^ ^(data_o & 72'h007AED348D221A4420);
|
||||
data_o[64] = ^(data_o & 72'h00B9000000001FFFFF);
|
||||
data_o[65] = ^(data_o & 72'h005E00000FFFE0003F);
|
||||
data_o[66] = ^(data_o & 72'h0067003FF003E007C1);
|
||||
data_o[67] = ^(data_o & 72'h00CD0FC0F03C207842);
|
||||
data_o[68] = ^(data_o & 72'h00B671C711C4438884);
|
||||
data_o[69] = ^(data_o & 72'h00B5B65926488C9108);
|
||||
data_o[70] = ^(data_o & 72'h00CBDAAA4A91152210);
|
||||
data_o[71] = ^(data_o & 72'h007AED348D221A4420);
|
||||
data_o ^= 72'hAA0000000000000000;
|
||||
end
|
||||
|
||||
endmodule : prim_secded_inv_72_64_enc
|
||||
|
|
|
@ -11,12 +11,13 @@ module prim_secded_inv_hamming_22_16_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 22'(data_i);
|
||||
data_o[16] = 1'b0 ^ ^(data_o & 22'h00AD5B);
|
||||
data_o[17] = 1'b1 ^ ^(data_o & 22'h00366D);
|
||||
data_o[18] = 1'b0 ^ ^(data_o & 22'h00C78E);
|
||||
data_o[19] = 1'b1 ^ ^(data_o & 22'h0007F0);
|
||||
data_o[20] = 1'b0 ^ ^(data_o & 22'h00F800);
|
||||
data_o[21] = 1'b1 ^ ^(data_o & 22'h1FFFFF);
|
||||
data_o[16] = ^(data_o & 22'h00AD5B);
|
||||
data_o[17] = ^(data_o & 22'h00366D);
|
||||
data_o[18] = ^(data_o & 22'h00C78E);
|
||||
data_o[19] = ^(data_o & 22'h0007F0);
|
||||
data_o[20] = ^(data_o & 22'h00F800);
|
||||
data_o[21] = ^(data_o & 22'h1FFFFF);
|
||||
data_o ^= 22'h2A0000;
|
||||
end
|
||||
|
||||
endmodule : prim_secded_inv_hamming_22_16_enc
|
||||
|
|
|
@ -11,13 +11,14 @@ module prim_secded_inv_hamming_39_32_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 39'(data_i);
|
||||
data_o[32] = 1'b0 ^ ^(data_o & 39'h0056AAAD5B);
|
||||
data_o[33] = 1'b1 ^ ^(data_o & 39'h009B33366D);
|
||||
data_o[34] = 1'b0 ^ ^(data_o & 39'h00E3C3C78E);
|
||||
data_o[35] = 1'b1 ^ ^(data_o & 39'h0003FC07F0);
|
||||
data_o[36] = 1'b0 ^ ^(data_o & 39'h0003FFF800);
|
||||
data_o[37] = 1'b1 ^ ^(data_o & 39'h00FC000000);
|
||||
data_o[38] = 1'b0 ^ ^(data_o & 39'h3FFFFFFFFF);
|
||||
data_o[32] = ^(data_o & 39'h0056AAAD5B);
|
||||
data_o[33] = ^(data_o & 39'h009B33366D);
|
||||
data_o[34] = ^(data_o & 39'h00E3C3C78E);
|
||||
data_o[35] = ^(data_o & 39'h0003FC07F0);
|
||||
data_o[36] = ^(data_o & 39'h0003FFF800);
|
||||
data_o[37] = ^(data_o & 39'h00FC000000);
|
||||
data_o[38] = ^(data_o & 39'h3FFFFFFFFF);
|
||||
data_o ^= 39'h2A00000000;
|
||||
end
|
||||
|
||||
endmodule : prim_secded_inv_hamming_39_32_enc
|
||||
|
|
|
@ -11,14 +11,15 @@ module prim_secded_inv_hamming_72_64_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 72'(data_i);
|
||||
data_o[64] = 1'b0 ^ ^(data_o & 72'h00AB55555556AAAD5B);
|
||||
data_o[65] = 1'b1 ^ ^(data_o & 72'h00CD9999999B33366D);
|
||||
data_o[66] = 1'b0 ^ ^(data_o & 72'h00F1E1E1E1E3C3C78E);
|
||||
data_o[67] = 1'b1 ^ ^(data_o & 72'h0001FE01FE03FC07F0);
|
||||
data_o[68] = 1'b0 ^ ^(data_o & 72'h0001FFFE0003FFF800);
|
||||
data_o[69] = 1'b1 ^ ^(data_o & 72'h0001FFFFFFFC000000);
|
||||
data_o[70] = 1'b0 ^ ^(data_o & 72'h00FE00000000000000);
|
||||
data_o[71] = 1'b1 ^ ^(data_o & 72'h7FFFFFFFFFFFFFFFFF);
|
||||
data_o[64] = ^(data_o & 72'h00AB55555556AAAD5B);
|
||||
data_o[65] = ^(data_o & 72'h00CD9999999B33366D);
|
||||
data_o[66] = ^(data_o & 72'h00F1E1E1E1E3C3C78E);
|
||||
data_o[67] = ^(data_o & 72'h0001FE01FE03FC07F0);
|
||||
data_o[68] = ^(data_o & 72'h0001FFFE0003FFF800);
|
||||
data_o[69] = ^(data_o & 72'h0001FFFFFFFC000000);
|
||||
data_o[70] = ^(data_o & 72'h00FE00000000000000);
|
||||
data_o[71] = ^(data_o & 72'h7FFFFFFFFFFFFFFFFF);
|
||||
data_o ^= 72'hAA0000000000000000;
|
||||
end
|
||||
|
||||
endmodule : prim_secded_inv_hamming_72_64_enc
|
||||
|
|
|
@ -11,14 +11,15 @@ module prim_secded_inv_hamming_76_68_enc (
|
|||
|
||||
always_comb begin : p_encode
|
||||
data_o = 76'(data_i);
|
||||
data_o[68] = 1'b0 ^ ^(data_o & 76'h00AAB55555556AAAD5B);
|
||||
data_o[69] = 1'b1 ^ ^(data_o & 76'h00CCD9999999B33366D);
|
||||
data_o[70] = 1'b0 ^ ^(data_o & 76'h000F1E1E1E1E3C3C78E);
|
||||
data_o[71] = 1'b1 ^ ^(data_o & 76'h00F01FE01FE03FC07F0);
|
||||
data_o[72] = 1'b0 ^ ^(data_o & 76'h00001FFFE0003FFF800);
|
||||
data_o[73] = 1'b1 ^ ^(data_o & 76'h00001FFFFFFFC000000);
|
||||
data_o[74] = 1'b0 ^ ^(data_o & 76'h00FFE00000000000000);
|
||||
data_o[75] = 1'b1 ^ ^(data_o & 76'h7FFFFFFFFFFFFFFFFFF);
|
||||
data_o[68] = ^(data_o & 76'h00AAB55555556AAAD5B);
|
||||
data_o[69] = ^(data_o & 76'h00CCD9999999B33366D);
|
||||
data_o[70] = ^(data_o & 76'h000F1E1E1E1E3C3C78E);
|
||||
data_o[71] = ^(data_o & 76'h00F01FE01FE03FC07F0);
|
||||
data_o[72] = ^(data_o & 76'h00001FFFE0003FFF800);
|
||||
data_o[73] = ^(data_o & 76'h00001FFFFFFFC000000);
|
||||
data_o[74] = ^(data_o & 76'h00FFE00000000000000);
|
||||
data_o[75] = ^(data_o & 76'h7FFFFFFFFFFFFFFFFFF);
|
||||
data_o ^= 76'hAA00000000000000000;
|
||||
end
|
||||
|
||||
endmodule : prim_secded_inv_hamming_76_68_enc
|
||||
|
|
261
vendor/lowrisc_ip/ip/prim/rtl/prim_secded_pkg.sv
vendored
261
vendor/lowrisc_ip/ip/prim/rtl/prim_secded_pkg.sv
vendored
|
@ -244,12 +244,12 @@ package prim_secded_pkg;
|
|||
prim_secded_22_16_enc (logic [15:0] data_i);
|
||||
logic [21:0] data_o;
|
||||
data_o = 22'(data_i);
|
||||
data_o[16] = 1'b0 ^ ^(data_o & 22'h00496E);
|
||||
data_o[17] = 1'b0 ^ ^(data_o & 22'h00F20B);
|
||||
data_o[18] = 1'b0 ^ ^(data_o & 22'h008ED8);
|
||||
data_o[19] = 1'b0 ^ ^(data_o & 22'h007714);
|
||||
data_o[20] = 1'b0 ^ ^(data_o & 22'h00ACA5);
|
||||
data_o[21] = 1'b0 ^ ^(data_o & 22'h0011F3);
|
||||
data_o[16] = ^(data_o & 22'h00496E);
|
||||
data_o[17] = ^(data_o & 22'h00F20B);
|
||||
data_o[18] = ^(data_o & 22'h008ED8);
|
||||
data_o[19] = ^(data_o & 22'h007714);
|
||||
data_o[20] = ^(data_o & 22'h00ACA5);
|
||||
data_o[21] = ^(data_o & 22'h0011F3);
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -302,12 +302,12 @@ package prim_secded_pkg;
|
|||
prim_secded_28_22_enc (logic [21:0] data_i);
|
||||
logic [27:0] data_o;
|
||||
data_o = 28'(data_i);
|
||||
data_o[22] = 1'b0 ^ ^(data_o & 28'h03003FF);
|
||||
data_o[23] = 1'b0 ^ ^(data_o & 28'h010FC0F);
|
||||
data_o[24] = 1'b0 ^ ^(data_o & 28'h0271C71);
|
||||
data_o[25] = 1'b0 ^ ^(data_o & 28'h03B6592);
|
||||
data_o[26] = 1'b0 ^ ^(data_o & 28'h03DAAA4);
|
||||
data_o[27] = 1'b0 ^ ^(data_o & 28'h03ED348);
|
||||
data_o[22] = ^(data_o & 28'h03003FF);
|
||||
data_o[23] = ^(data_o & 28'h010FC0F);
|
||||
data_o[24] = ^(data_o & 28'h0271C71);
|
||||
data_o[25] = ^(data_o & 28'h03B6592);
|
||||
data_o[26] = ^(data_o & 28'h03DAAA4);
|
||||
data_o[27] = ^(data_o & 28'h03ED348);
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -366,13 +366,13 @@ package prim_secded_pkg;
|
|||
prim_secded_39_32_enc (logic [31:0] data_i);
|
||||
logic [38:0] data_o;
|
||||
data_o = 39'(data_i);
|
||||
data_o[32] = 1'b0 ^ ^(data_o & 39'h002606BD25);
|
||||
data_o[33] = 1'b0 ^ ^(data_o & 39'h00DEBA8050);
|
||||
data_o[34] = 1'b0 ^ ^(data_o & 39'h00413D89AA);
|
||||
data_o[35] = 1'b0 ^ ^(data_o & 39'h0031234ED1);
|
||||
data_o[36] = 1'b0 ^ ^(data_o & 39'h00C2C1323B);
|
||||
data_o[37] = 1'b0 ^ ^(data_o & 39'h002DCC624C);
|
||||
data_o[38] = 1'b0 ^ ^(data_o & 39'h0098505586);
|
||||
data_o[32] = ^(data_o & 39'h002606BD25);
|
||||
data_o[33] = ^(data_o & 39'h00DEBA8050);
|
||||
data_o[34] = ^(data_o & 39'h00413D89AA);
|
||||
data_o[35] = ^(data_o & 39'h0031234ED1);
|
||||
data_o[36] = ^(data_o & 39'h00C2C1323B);
|
||||
data_o[37] = ^(data_o & 39'h002DCC624C);
|
||||
data_o[38] = ^(data_o & 39'h0098505586);
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -442,13 +442,13 @@ package prim_secded_pkg;
|
|||
prim_secded_64_57_enc (logic [56:0] data_i);
|
||||
logic [63:0] data_o;
|
||||
data_o = 64'(data_i);
|
||||
data_o[57] = 1'b0 ^ ^(data_o & 64'h0103FFF800007FFF);
|
||||
data_o[58] = 1'b0 ^ ^(data_o & 64'h017C1FF801FF801F);
|
||||
data_o[59] = 1'b0 ^ ^(data_o & 64'h01BDE1F87E0781E1);
|
||||
data_o[60] = 1'b0 ^ ^(data_o & 64'h01DEEE3B8E388E22);
|
||||
data_o[61] = 1'b0 ^ ^(data_o & 64'h01EF76CDB2C93244);
|
||||
data_o[62] = 1'b0 ^ ^(data_o & 64'h01F7BB56D5525488);
|
||||
data_o[63] = 1'b0 ^ ^(data_o & 64'h01FBDDA769A46910);
|
||||
data_o[57] = ^(data_o & 64'h0103FFF800007FFF);
|
||||
data_o[58] = ^(data_o & 64'h017C1FF801FF801F);
|
||||
data_o[59] = ^(data_o & 64'h01BDE1F87E0781E1);
|
||||
data_o[60] = ^(data_o & 64'h01DEEE3B8E388E22);
|
||||
data_o[61] = ^(data_o & 64'h01EF76CDB2C93244);
|
||||
data_o[62] = ^(data_o & 64'h01F7BB56D5525488);
|
||||
data_o[63] = ^(data_o & 64'h01FBDDA769A46910);
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -543,14 +543,14 @@ package prim_secded_pkg;
|
|||
prim_secded_72_64_enc (logic [63:0] data_i);
|
||||
logic [71:0] data_o;
|
||||
data_o = 72'(data_i);
|
||||
data_o[64] = 1'b0 ^ ^(data_o & 72'h00B9000000001FFFFF);
|
||||
data_o[65] = 1'b0 ^ ^(data_o & 72'h005E00000FFFE0003F);
|
||||
data_o[66] = 1'b0 ^ ^(data_o & 72'h0067003FF003E007C1);
|
||||
data_o[67] = 1'b0 ^ ^(data_o & 72'h00CD0FC0F03C207842);
|
||||
data_o[68] = 1'b0 ^ ^(data_o & 72'h00B671C711C4438884);
|
||||
data_o[69] = 1'b0 ^ ^(data_o & 72'h00B5B65926488C9108);
|
||||
data_o[70] = 1'b0 ^ ^(data_o & 72'h00CBDAAA4A91152210);
|
||||
data_o[71] = 1'b0 ^ ^(data_o & 72'h007AED348D221A4420);
|
||||
data_o[64] = ^(data_o & 72'h00B9000000001FFFFF);
|
||||
data_o[65] = ^(data_o & 72'h005E00000FFFE0003F);
|
||||
data_o[66] = ^(data_o & 72'h0067003FF003E007C1);
|
||||
data_o[67] = ^(data_o & 72'h00CD0FC0F03C207842);
|
||||
data_o[68] = ^(data_o & 72'h00B671C711C4438884);
|
||||
data_o[69] = ^(data_o & 72'h00B5B65926488C9108);
|
||||
data_o[70] = ^(data_o & 72'h00CBDAAA4A91152210);
|
||||
data_o[71] = ^(data_o & 72'h007AED348D221A4420);
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -653,12 +653,12 @@ package prim_secded_pkg;
|
|||
prim_secded_hamming_22_16_enc (logic [15:0] data_i);
|
||||
logic [21:0] data_o;
|
||||
data_o = 22'(data_i);
|
||||
data_o[16] = 1'b0 ^ ^(data_o & 22'h00AD5B);
|
||||
data_o[17] = 1'b0 ^ ^(data_o & 22'h00366D);
|
||||
data_o[18] = 1'b0 ^ ^(data_o & 22'h00C78E);
|
||||
data_o[19] = 1'b0 ^ ^(data_o & 22'h0007F0);
|
||||
data_o[20] = 1'b0 ^ ^(data_o & 22'h00F800);
|
||||
data_o[21] = 1'b0 ^ ^(data_o & 22'h1FFFFF);
|
||||
data_o[16] = ^(data_o & 22'h00AD5B);
|
||||
data_o[17] = ^(data_o & 22'h00366D);
|
||||
data_o[18] = ^(data_o & 22'h00C78E);
|
||||
data_o[19] = ^(data_o & 22'h0007F0);
|
||||
data_o[20] = ^(data_o & 22'h00F800);
|
||||
data_o[21] = ^(data_o & 22'h1FFFFF);
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -711,13 +711,13 @@ package prim_secded_pkg;
|
|||
prim_secded_hamming_39_32_enc (logic [31:0] data_i);
|
||||
logic [38:0] data_o;
|
||||
data_o = 39'(data_i);
|
||||
data_o[32] = 1'b0 ^ ^(data_o & 39'h0056AAAD5B);
|
||||
data_o[33] = 1'b0 ^ ^(data_o & 39'h009B33366D);
|
||||
data_o[34] = 1'b0 ^ ^(data_o & 39'h00E3C3C78E);
|
||||
data_o[35] = 1'b0 ^ ^(data_o & 39'h0003FC07F0);
|
||||
data_o[36] = 1'b0 ^ ^(data_o & 39'h0003FFF800);
|
||||
data_o[37] = 1'b0 ^ ^(data_o & 39'h00FC000000);
|
||||
data_o[38] = 1'b0 ^ ^(data_o & 39'h3FFFFFFFFF);
|
||||
data_o[32] = ^(data_o & 39'h0056AAAD5B);
|
||||
data_o[33] = ^(data_o & 39'h009B33366D);
|
||||
data_o[34] = ^(data_o & 39'h00E3C3C78E);
|
||||
data_o[35] = ^(data_o & 39'h0003FC07F0);
|
||||
data_o[36] = ^(data_o & 39'h0003FFF800);
|
||||
data_o[37] = ^(data_o & 39'h00FC000000);
|
||||
data_o[38] = ^(data_o & 39'h3FFFFFFFFF);
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -787,14 +787,14 @@ package prim_secded_pkg;
|
|||
prim_secded_hamming_72_64_enc (logic [63:0] data_i);
|
||||
logic [71:0] data_o;
|
||||
data_o = 72'(data_i);
|
||||
data_o[64] = 1'b0 ^ ^(data_o & 72'h00AB55555556AAAD5B);
|
||||
data_o[65] = 1'b0 ^ ^(data_o & 72'h00CD9999999B33366D);
|
||||
data_o[66] = 1'b0 ^ ^(data_o & 72'h00F1E1E1E1E3C3C78E);
|
||||
data_o[67] = 1'b0 ^ ^(data_o & 72'h0001FE01FE03FC07F0);
|
||||
data_o[68] = 1'b0 ^ ^(data_o & 72'h0001FFFE0003FFF800);
|
||||
data_o[69] = 1'b0 ^ ^(data_o & 72'h0001FFFFFFFC000000);
|
||||
data_o[70] = 1'b0 ^ ^(data_o & 72'h00FE00000000000000);
|
||||
data_o[71] = 1'b0 ^ ^(data_o & 72'h7FFFFFFFFFFFFFFFFF);
|
||||
data_o[64] = ^(data_o & 72'h00AB55555556AAAD5B);
|
||||
data_o[65] = ^(data_o & 72'h00CD9999999B33366D);
|
||||
data_o[66] = ^(data_o & 72'h00F1E1E1E1E3C3C78E);
|
||||
data_o[67] = ^(data_o & 72'h0001FE01FE03FC07F0);
|
||||
data_o[68] = ^(data_o & 72'h0001FFFE0003FFF800);
|
||||
data_o[69] = ^(data_o & 72'h0001FFFFFFFC000000);
|
||||
data_o[70] = ^(data_o & 72'h00FE00000000000000);
|
||||
data_o[71] = ^(data_o & 72'h7FFFFFFFFFFFFFFFFF);
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -897,14 +897,14 @@ package prim_secded_pkg;
|
|||
prim_secded_hamming_76_68_enc (logic [67:0] data_i);
|
||||
logic [75:0] data_o;
|
||||
data_o = 76'(data_i);
|
||||
data_o[68] = 1'b0 ^ ^(data_o & 76'h00AAB55555556AAAD5B);
|
||||
data_o[69] = 1'b0 ^ ^(data_o & 76'h00CCD9999999B33366D);
|
||||
data_o[70] = 1'b0 ^ ^(data_o & 76'h000F1E1E1E1E3C3C78E);
|
||||
data_o[71] = 1'b0 ^ ^(data_o & 76'h00F01FE01FE03FC07F0);
|
||||
data_o[72] = 1'b0 ^ ^(data_o & 76'h00001FFFE0003FFF800);
|
||||
data_o[73] = 1'b0 ^ ^(data_o & 76'h00001FFFFFFFC000000);
|
||||
data_o[74] = 1'b0 ^ ^(data_o & 76'h00FFE00000000000000);
|
||||
data_o[75] = 1'b0 ^ ^(data_o & 76'h7FFFFFFFFFFFFFFFFFF);
|
||||
data_o[68] = ^(data_o & 76'h00AAB55555556AAAD5B);
|
||||
data_o[69] = ^(data_o & 76'h00CCD9999999B33366D);
|
||||
data_o[70] = ^(data_o & 76'h000F1E1E1E1E3C3C78E);
|
||||
data_o[71] = ^(data_o & 76'h00F01FE01FE03FC07F0);
|
||||
data_o[72] = ^(data_o & 76'h00001FFFE0003FFF800);
|
||||
data_o[73] = ^(data_o & 76'h00001FFFFFFFC000000);
|
||||
data_o[74] = ^(data_o & 76'h00FFE00000000000000);
|
||||
data_o[75] = ^(data_o & 76'h7FFFFFFFFFFFFFFFFFF);
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -1011,12 +1011,13 @@ package prim_secded_pkg;
|
|||
prim_secded_inv_22_16_enc (logic [15:0] data_i);
|
||||
logic [21:0] data_o;
|
||||
data_o = 22'(data_i);
|
||||
data_o[16] = 1'b0 ^ ^(data_o & 22'h00496E);
|
||||
data_o[17] = 1'b1 ^ ^(data_o & 22'h00F20B);
|
||||
data_o[18] = 1'b0 ^ ^(data_o & 22'h008ED8);
|
||||
data_o[19] = 1'b1 ^ ^(data_o & 22'h007714);
|
||||
data_o[20] = 1'b0 ^ ^(data_o & 22'h00ACA5);
|
||||
data_o[21] = 1'b1 ^ ^(data_o & 22'h0011F3);
|
||||
data_o[16] = ^(data_o & 22'h00496E);
|
||||
data_o[17] = ^(data_o & 22'h00F20B);
|
||||
data_o[18] = ^(data_o & 22'h008ED8);
|
||||
data_o[19] = ^(data_o & 22'h007714);
|
||||
data_o[20] = ^(data_o & 22'h00ACA5);
|
||||
data_o[21] = ^(data_o & 22'h0011F3);
|
||||
data_o ^= 22'h2A0000;
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -1069,12 +1070,13 @@ package prim_secded_pkg;
|
|||
prim_secded_inv_28_22_enc (logic [21:0] data_i);
|
||||
logic [27:0] data_o;
|
||||
data_o = 28'(data_i);
|
||||
data_o[22] = 1'b0 ^ ^(data_o & 28'h03003FF);
|
||||
data_o[23] = 1'b1 ^ ^(data_o & 28'h010FC0F);
|
||||
data_o[24] = 1'b0 ^ ^(data_o & 28'h0271C71);
|
||||
data_o[25] = 1'b1 ^ ^(data_o & 28'h03B6592);
|
||||
data_o[26] = 1'b0 ^ ^(data_o & 28'h03DAAA4);
|
||||
data_o[27] = 1'b1 ^ ^(data_o & 28'h03ED348);
|
||||
data_o[22] = ^(data_o & 28'h03003FF);
|
||||
data_o[23] = ^(data_o & 28'h010FC0F);
|
||||
data_o[24] = ^(data_o & 28'h0271C71);
|
||||
data_o[25] = ^(data_o & 28'h03B6592);
|
||||
data_o[26] = ^(data_o & 28'h03DAAA4);
|
||||
data_o[27] = ^(data_o & 28'h03ED348);
|
||||
data_o ^= 28'hA800000;
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -1133,13 +1135,14 @@ package prim_secded_pkg;
|
|||
prim_secded_inv_39_32_enc (logic [31:0] data_i);
|
||||
logic [38:0] data_o;
|
||||
data_o = 39'(data_i);
|
||||
data_o[32] = 1'b0 ^ ^(data_o & 39'h002606BD25);
|
||||
data_o[33] = 1'b1 ^ ^(data_o & 39'h00DEBA8050);
|
||||
data_o[34] = 1'b0 ^ ^(data_o & 39'h00413D89AA);
|
||||
data_o[35] = 1'b1 ^ ^(data_o & 39'h0031234ED1);
|
||||
data_o[36] = 1'b0 ^ ^(data_o & 39'h00C2C1323B);
|
||||
data_o[37] = 1'b1 ^ ^(data_o & 39'h002DCC624C);
|
||||
data_o[38] = 1'b0 ^ ^(data_o & 39'h0098505586);
|
||||
data_o[32] = ^(data_o & 39'h002606BD25);
|
||||
data_o[33] = ^(data_o & 39'h00DEBA8050);
|
||||
data_o[34] = ^(data_o & 39'h00413D89AA);
|
||||
data_o[35] = ^(data_o & 39'h0031234ED1);
|
||||
data_o[36] = ^(data_o & 39'h00C2C1323B);
|
||||
data_o[37] = ^(data_o & 39'h002DCC624C);
|
||||
data_o[38] = ^(data_o & 39'h0098505586);
|
||||
data_o ^= 39'h2A00000000;
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -1209,13 +1212,14 @@ package prim_secded_pkg;
|
|||
prim_secded_inv_64_57_enc (logic [56:0] data_i);
|
||||
logic [63:0] data_o;
|
||||
data_o = 64'(data_i);
|
||||
data_o[57] = 1'b0 ^ ^(data_o & 64'h0103FFF800007FFF);
|
||||
data_o[58] = 1'b1 ^ ^(data_o & 64'h017C1FF801FF801F);
|
||||
data_o[59] = 1'b0 ^ ^(data_o & 64'h01BDE1F87E0781E1);
|
||||
data_o[60] = 1'b1 ^ ^(data_o & 64'h01DEEE3B8E388E22);
|
||||
data_o[61] = 1'b0 ^ ^(data_o & 64'h01EF76CDB2C93244);
|
||||
data_o[62] = 1'b1 ^ ^(data_o & 64'h01F7BB56D5525488);
|
||||
data_o[63] = 1'b0 ^ ^(data_o & 64'h01FBDDA769A46910);
|
||||
data_o[57] = ^(data_o & 64'h0103FFF800007FFF);
|
||||
data_o[58] = ^(data_o & 64'h017C1FF801FF801F);
|
||||
data_o[59] = ^(data_o & 64'h01BDE1F87E0781E1);
|
||||
data_o[60] = ^(data_o & 64'h01DEEE3B8E388E22);
|
||||
data_o[61] = ^(data_o & 64'h01EF76CDB2C93244);
|
||||
data_o[62] = ^(data_o & 64'h01F7BB56D5525488);
|
||||
data_o[63] = ^(data_o & 64'h01FBDDA769A46910);
|
||||
data_o ^= 64'h5400000000000000;
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -1310,14 +1314,15 @@ package prim_secded_pkg;
|
|||
prim_secded_inv_72_64_enc (logic [63:0] data_i);
|
||||
logic [71:0] data_o;
|
||||
data_o = 72'(data_i);
|
||||
data_o[64] = 1'b0 ^ ^(data_o & 72'h00B9000000001FFFFF);
|
||||
data_o[65] = 1'b1 ^ ^(data_o & 72'h005E00000FFFE0003F);
|
||||
data_o[66] = 1'b0 ^ ^(data_o & 72'h0067003FF003E007C1);
|
||||
data_o[67] = 1'b1 ^ ^(data_o & 72'h00CD0FC0F03C207842);
|
||||
data_o[68] = 1'b0 ^ ^(data_o & 72'h00B671C711C4438884);
|
||||
data_o[69] = 1'b1 ^ ^(data_o & 72'h00B5B65926488C9108);
|
||||
data_o[70] = 1'b0 ^ ^(data_o & 72'h00CBDAAA4A91152210);
|
||||
data_o[71] = 1'b1 ^ ^(data_o & 72'h007AED348D221A4420);
|
||||
data_o[64] = ^(data_o & 72'h00B9000000001FFFFF);
|
||||
data_o[65] = ^(data_o & 72'h005E00000FFFE0003F);
|
||||
data_o[66] = ^(data_o & 72'h0067003FF003E007C1);
|
||||
data_o[67] = ^(data_o & 72'h00CD0FC0F03C207842);
|
||||
data_o[68] = ^(data_o & 72'h00B671C711C4438884);
|
||||
data_o[69] = ^(data_o & 72'h00B5B65926488C9108);
|
||||
data_o[70] = ^(data_o & 72'h00CBDAAA4A91152210);
|
||||
data_o[71] = ^(data_o & 72'h007AED348D221A4420);
|
||||
data_o ^= 72'hAA0000000000000000;
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -1420,12 +1425,13 @@ package prim_secded_pkg;
|
|||
prim_secded_inv_hamming_22_16_enc (logic [15:0] data_i);
|
||||
logic [21:0] data_o;
|
||||
data_o = 22'(data_i);
|
||||
data_o[16] = 1'b0 ^ ^(data_o & 22'h00AD5B);
|
||||
data_o[17] = 1'b1 ^ ^(data_o & 22'h00366D);
|
||||
data_o[18] = 1'b0 ^ ^(data_o & 22'h00C78E);
|
||||
data_o[19] = 1'b1 ^ ^(data_o & 22'h0007F0);
|
||||
data_o[20] = 1'b0 ^ ^(data_o & 22'h00F800);
|
||||
data_o[21] = 1'b1 ^ ^(data_o & 22'h1FFFFF);
|
||||
data_o[16] = ^(data_o & 22'h00AD5B);
|
||||
data_o[17] = ^(data_o & 22'h00366D);
|
||||
data_o[18] = ^(data_o & 22'h00C78E);
|
||||
data_o[19] = ^(data_o & 22'h0007F0);
|
||||
data_o[20] = ^(data_o & 22'h00F800);
|
||||
data_o[21] = ^(data_o & 22'h1FFFFF);
|
||||
data_o ^= 22'h2A0000;
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -1478,13 +1484,14 @@ package prim_secded_pkg;
|
|||
prim_secded_inv_hamming_39_32_enc (logic [31:0] data_i);
|
||||
logic [38:0] data_o;
|
||||
data_o = 39'(data_i);
|
||||
data_o[32] = 1'b0 ^ ^(data_o & 39'h0056AAAD5B);
|
||||
data_o[33] = 1'b1 ^ ^(data_o & 39'h009B33366D);
|
||||
data_o[34] = 1'b0 ^ ^(data_o & 39'h00E3C3C78E);
|
||||
data_o[35] = 1'b1 ^ ^(data_o & 39'h0003FC07F0);
|
||||
data_o[36] = 1'b0 ^ ^(data_o & 39'h0003FFF800);
|
||||
data_o[37] = 1'b1 ^ ^(data_o & 39'h00FC000000);
|
||||
data_o[38] = 1'b0 ^ ^(data_o & 39'h3FFFFFFFFF);
|
||||
data_o[32] = ^(data_o & 39'h0056AAAD5B);
|
||||
data_o[33] = ^(data_o & 39'h009B33366D);
|
||||
data_o[34] = ^(data_o & 39'h00E3C3C78E);
|
||||
data_o[35] = ^(data_o & 39'h0003FC07F0);
|
||||
data_o[36] = ^(data_o & 39'h0003FFF800);
|
||||
data_o[37] = ^(data_o & 39'h00FC000000);
|
||||
data_o[38] = ^(data_o & 39'h3FFFFFFFFF);
|
||||
data_o ^= 39'h2A00000000;
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -1554,14 +1561,15 @@ package prim_secded_pkg;
|
|||
prim_secded_inv_hamming_72_64_enc (logic [63:0] data_i);
|
||||
logic [71:0] data_o;
|
||||
data_o = 72'(data_i);
|
||||
data_o[64] = 1'b0 ^ ^(data_o & 72'h00AB55555556AAAD5B);
|
||||
data_o[65] = 1'b1 ^ ^(data_o & 72'h00CD9999999B33366D);
|
||||
data_o[66] = 1'b0 ^ ^(data_o & 72'h00F1E1E1E1E3C3C78E);
|
||||
data_o[67] = 1'b1 ^ ^(data_o & 72'h0001FE01FE03FC07F0);
|
||||
data_o[68] = 1'b0 ^ ^(data_o & 72'h0001FFFE0003FFF800);
|
||||
data_o[69] = 1'b1 ^ ^(data_o & 72'h0001FFFFFFFC000000);
|
||||
data_o[70] = 1'b0 ^ ^(data_o & 72'h00FE00000000000000);
|
||||
data_o[71] = 1'b1 ^ ^(data_o & 72'h7FFFFFFFFFFFFFFFFF);
|
||||
data_o[64] = ^(data_o & 72'h00AB55555556AAAD5B);
|
||||
data_o[65] = ^(data_o & 72'h00CD9999999B33366D);
|
||||
data_o[66] = ^(data_o & 72'h00F1E1E1E1E3C3C78E);
|
||||
data_o[67] = ^(data_o & 72'h0001FE01FE03FC07F0);
|
||||
data_o[68] = ^(data_o & 72'h0001FFFE0003FFF800);
|
||||
data_o[69] = ^(data_o & 72'h0001FFFFFFFC000000);
|
||||
data_o[70] = ^(data_o & 72'h00FE00000000000000);
|
||||
data_o[71] = ^(data_o & 72'h7FFFFFFFFFFFFFFFFF);
|
||||
data_o ^= 72'hAA0000000000000000;
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
@ -1664,14 +1672,15 @@ package prim_secded_pkg;
|
|||
prim_secded_inv_hamming_76_68_enc (logic [67:0] data_i);
|
||||
logic [75:0] data_o;
|
||||
data_o = 76'(data_i);
|
||||
data_o[68] = 1'b0 ^ ^(data_o & 76'h00AAB55555556AAAD5B);
|
||||
data_o[69] = 1'b1 ^ ^(data_o & 76'h00CCD9999999B33366D);
|
||||
data_o[70] = 1'b0 ^ ^(data_o & 76'h000F1E1E1E1E3C3C78E);
|
||||
data_o[71] = 1'b1 ^ ^(data_o & 76'h00F01FE01FE03FC07F0);
|
||||
data_o[72] = 1'b0 ^ ^(data_o & 76'h00001FFFE0003FFF800);
|
||||
data_o[73] = 1'b1 ^ ^(data_o & 76'h00001FFFFFFFC000000);
|
||||
data_o[74] = 1'b0 ^ ^(data_o & 76'h00FFE00000000000000);
|
||||
data_o[75] = 1'b1 ^ ^(data_o & 76'h7FFFFFFFFFFFFFFFFFF);
|
||||
data_o[68] = ^(data_o & 76'h00AAB55555556AAAD5B);
|
||||
data_o[69] = ^(data_o & 76'h00CCD9999999B33366D);
|
||||
data_o[70] = ^(data_o & 76'h000F1E1E1E1E3C3C78E);
|
||||
data_o[71] = ^(data_o & 76'h00F01FE01FE03FC07F0);
|
||||
data_o[72] = ^(data_o & 76'h00001FFFE0003FFF800);
|
||||
data_o[73] = ^(data_o & 76'h00001FFFFFFFC000000);
|
||||
data_o[74] = ^(data_o & 76'h00FFE00000000000000);
|
||||
data_o[75] = ^(data_o & 76'h7FFFFFFFFFFFFFFFFFF);
|
||||
data_o ^= 76'hAA00000000000000000;
|
||||
return data_o;
|
||||
endfunction
|
||||
|
||||
|
|
5
vendor/lowrisc_ip/util/dvsim/FlowCfg.py
vendored
5
vendor/lowrisc_ip/util/dvsim/FlowCfg.py
vendored
|
@ -6,6 +6,7 @@ import datetime
|
|||
import logging as log
|
||||
import os
|
||||
import pprint
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
from shutil import which
|
||||
|
@ -558,7 +559,9 @@ class FlowCfg():
|
|||
for rdir in results_dirs:
|
||||
dirname = rdir.replace(self.results_server_path, '')
|
||||
dirname = dirname.replace('/', '')
|
||||
if dirname == "latest":
|
||||
# Only track history directories with format
|
||||
# "year.month.date_hour.min.sec".
|
||||
if not bool(re.match('[\d*.]*_[\d*.]*', dirname)):
|
||||
continue
|
||||
rdirs.append(dirname)
|
||||
rdirs.sort(reverse=True)
|
||||
|
|
2
vendor/lowrisc_ip/util/dvsim/utils.py
vendored
2
vendor/lowrisc_ip/util/dvsim/utils.py
vendored
|
@ -36,7 +36,7 @@ TS_FORMAT_LONG = "%A %B %d %Y %H:%M:%S UTC"
|
|||
def run_cmd(cmd):
|
||||
(status, output) = subprocess.getstatusoutput(cmd)
|
||||
if status:
|
||||
sys.stderr.write("cmd " + cmd + " returned with status " + str(status))
|
||||
print(f'cmd {cmd} returned with status {status}', file=sys.stderr)
|
||||
sys.exit(status)
|
||||
return output
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue