blob: 3960fb54d542f91baab267f926c60b14a824af22 [file]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
package lc_ctrl_dv_utils_pkg;
// dep packages
import uvm_pkg::*;
import top_pkg::*;
import dv_utils_pkg::*;
import dv_lib_pkg::*;
import lc_ctrl_pkg::*;
import lc_ctrl_state_pkg::*;
import otp_ctrl_pkg::*;
// associative array cannot declare parameter here, so we used const instead
// verilog_format: off - avoid bad formatting
const dec_lc_state_e VALID_NEXT_STATES [dec_lc_state_e][$] = '{
DecLcStRma: {DecLcStScrap},
DecLcStProdEnd: {DecLcStScrap},
DecLcStProd: {DecLcStScrap, DecLcStRma},
DecLcStDev: {DecLcStScrap, DecLcStRma},
DecLcStTestUnlocked7: {DecLcStScrap, DecLcStRma, DecLcStProdEnd, DecLcStProd, DecLcStDev},
DecLcStTestUnlocked6: {DecLcStScrap, DecLcStRma, DecLcStProdEnd, DecLcStProd, DecLcStDev,
DecLcStTestLocked6},
DecLcStTestUnlocked5: {DecLcStScrap, DecLcStRma, DecLcStProdEnd, DecLcStProd, DecLcStDev,
DecLcStTestLocked6, DecLcStTestLocked5},
DecLcStTestUnlocked4: {DecLcStScrap, DecLcStRma, DecLcStProdEnd, DecLcStProd, DecLcStDev,
DecLcStTestLocked6, DecLcStTestLocked5, DecLcStTestLocked4},
DecLcStTestUnlocked3: {DecLcStScrap, DecLcStRma, DecLcStProdEnd, DecLcStProd, DecLcStDev,
DecLcStTestLocked6, DecLcStTestLocked5, DecLcStTestLocked4,
DecLcStTestLocked3},
DecLcStTestUnlocked2: {DecLcStScrap, DecLcStRma, DecLcStProdEnd, DecLcStProd, DecLcStDev,
DecLcStTestLocked6, DecLcStTestLocked5, DecLcStTestLocked4,
DecLcStTestLocked3, DecLcStTestLocked2},
DecLcStTestUnlocked1: {DecLcStScrap, DecLcStRma, DecLcStProdEnd, DecLcStProd, DecLcStDev,
DecLcStTestLocked6, DecLcStTestLocked5, DecLcStTestLocked4,
DecLcStTestLocked3, DecLcStTestLocked2, DecLcStTestLocked1},
DecLcStTestUnlocked0: {DecLcStScrap, DecLcStRma, DecLcStProdEnd, DecLcStProd, DecLcStDev,
DecLcStTestLocked6, DecLcStTestLocked5, DecLcStTestLocked4,
DecLcStTestLocked3, DecLcStTestLocked2, DecLcStTestLocked1,
DecLcStTestLocked0},
DecLcStTestLocked6: {DecLcStScrap, DecLcStProdEnd, DecLcStProd, DecLcStDev,
DecLcStTestUnlocked7},
DecLcStTestLocked5: {DecLcStScrap, DecLcStProdEnd, DecLcStProd, DecLcStDev,
DecLcStTestUnlocked7, DecLcStTestUnlocked6},
DecLcStTestLocked4: {DecLcStScrap, DecLcStProdEnd, DecLcStProd, DecLcStDev,
DecLcStTestUnlocked7, DecLcStTestUnlocked6, DecLcStTestUnlocked5},
DecLcStTestLocked3: {DecLcStScrap, DecLcStProdEnd, DecLcStProd, DecLcStDev,
DecLcStTestUnlocked7, DecLcStTestUnlocked6, DecLcStTestUnlocked5,
DecLcStTestUnlocked4},
DecLcStTestLocked2: {DecLcStScrap, DecLcStProdEnd, DecLcStProd, DecLcStDev,
DecLcStTestUnlocked7, DecLcStTestUnlocked6, DecLcStTestUnlocked5,
DecLcStTestUnlocked4, DecLcStTestUnlocked3},
DecLcStTestLocked1: {DecLcStScrap, DecLcStProdEnd, DecLcStProd, DecLcStDev,
DecLcStTestUnlocked7, DecLcStTestUnlocked6, DecLcStTestUnlocked5,
DecLcStTestUnlocked4, DecLcStTestUnlocked3, DecLcStTestUnlocked2},
DecLcStTestLocked0: {DecLcStScrap, DecLcStProdEnd, DecLcStProd, DecLcStDev,
DecLcStTestUnlocked7, DecLcStTestUnlocked6, DecLcStTestUnlocked5,
DecLcStTestUnlocked4, DecLcStTestUnlocked3, DecLcStTestUnlocked2,
DecLcStTestUnlocked1},
DecLcStRaw: {DecLcStScrap, DecLcStTestUnlocked7, DecLcStTestUnlocked6, DecLcStTestUnlocked5,
DecLcStTestUnlocked4, DecLcStTestUnlocked3, DecLcStTestUnlocked2,
DecLcStTestUnlocked1, DecLcStTestUnlocked0}
};
// All valid decoded states as int
const int ValidDecodedStates[] = '{
int'(DecLcStRaw),
int'(DecLcStTestUnlocked0),
int'(DecLcStTestLocked0),
int'(DecLcStTestUnlocked1),
int'(DecLcStTestLocked1),
int'(DecLcStTestUnlocked2),
int'(DecLcStTestLocked2),
int'(DecLcStTestUnlocked3),
int'(DecLcStTestLocked3),
int'(DecLcStTestUnlocked4),
int'(DecLcStTestLocked4),
int'(DecLcStTestUnlocked5),
int'(DecLcStTestLocked5),
int'(DecLcStTestUnlocked6),
int'(DecLcStTestLocked6),
int'(DecLcStTestUnlocked7),
int'(DecLcStDev),
int'(DecLcStProd),
int'(DecLcStProdEnd),
int'(DecLcStRma),
int'(DecLcStScrap),
int'(DecLcStInvalid)
};
// Checks whether the current state is a test unlocked state within the given index range.
function automatic bit is_test_unlocked_state(dec_lc_state_e curr_state, int first, int last);
begin
int index;
index = (curr_state - DecLcStTestUnlocked0)/2;
case (curr_state)
DecLcStTestUnlocked0,
DecLcStTestUnlocked1,
DecLcStTestUnlocked2,
DecLcStTestUnlocked3,
DecLcStTestUnlocked4,
DecLcStTestUnlocked5,
DecLcStTestUnlocked6,
DecLcStTestUnlocked7: return (index >= first) && (index <= last);
default: return 0;
endcase
end
endfunction
// Checks whether the current state is a test locked state within the given index range.
function automatic bit is_test_locked_state(dec_lc_state_e curr_state, int first, int last);
begin
int index;
index = (curr_state - DecLcStTestLocked0)/2;
case (curr_state)
DecLcStTestLocked0,
DecLcStTestLocked1,
DecLcStTestLocked2,
DecLcStTestLocked3,
DecLcStTestLocked4,
DecLcStTestLocked5,
DecLcStTestLocked6: return (index >= first) && (index <= last);
default: return 0;
endcase
end
endfunction
// verilog_format: on
function automatic dec_lc_state_e dec_lc_state(lc_state_e curr_state);
case (curr_state)
LcStRaw: return DecLcStRaw;
LcStTestUnlocked0: return DecLcStTestUnlocked0;
LcStTestLocked0: return DecLcStTestLocked0;
LcStTestUnlocked1: return DecLcStTestUnlocked1;
LcStTestLocked1: return DecLcStTestLocked1;
LcStTestUnlocked2: return DecLcStTestUnlocked2;
LcStTestLocked2: return DecLcStTestLocked2;
LcStTestUnlocked3: return DecLcStTestUnlocked3;
LcStTestLocked3: return DecLcStTestLocked3;
LcStTestUnlocked4: return DecLcStTestUnlocked4;
LcStTestLocked4: return DecLcStTestLocked4;
LcStTestUnlocked5: return DecLcStTestUnlocked5;
LcStTestLocked5: return DecLcStTestLocked5;
LcStTestUnlocked6: return DecLcStTestUnlocked6;
LcStTestLocked6: return DecLcStTestLocked6;
LcStTestUnlocked7: return DecLcStTestUnlocked7;
LcStDev: return DecLcStDev;
LcStProd: return DecLcStProd;
LcStProdEnd: return DecLcStProdEnd;
LcStRma: return DecLcStRma;
LcStScrap: return DecLcStScrap;
default: return DecLcStInvalid;
endcase
endfunction
function automatic lc_state_e encode_lc_state(dec_lc_state_e curr_state);
case (curr_state)
DecLcStRaw: return LcStRaw;
DecLcStTestUnlocked0: return LcStTestUnlocked0;
DecLcStTestLocked0: return LcStTestLocked0;
DecLcStTestUnlocked1: return LcStTestUnlocked1;
DecLcStTestLocked1: return LcStTestLocked1;
DecLcStTestUnlocked2: return LcStTestUnlocked2;
DecLcStTestLocked2: return LcStTestLocked2;
DecLcStTestUnlocked3: return LcStTestUnlocked3;
DecLcStTestLocked3: return LcStTestLocked3;
DecLcStTestUnlocked4: return LcStTestUnlocked4;
DecLcStTestLocked4: return LcStTestLocked4;
DecLcStTestUnlocked5: return LcStTestUnlocked5;
DecLcStTestLocked5: return LcStTestLocked5;
DecLcStTestUnlocked6: return LcStTestUnlocked6;
DecLcStTestLocked6: return LcStTestLocked6;
DecLcStTestUnlocked7: return LcStTestUnlocked7;
DecLcStDev: return LcStDev;
DecLcStProd: return LcStProd;
DecLcStProdEnd: return LcStProdEnd;
DecLcStRma: return LcStRma;
DecLcStScrap: return LcStScrap;
default: begin
`uvm_fatal("lc_env_pkg", $sformatf("encode_lc_state: unknown lc_state 0x%0h", curr_state))
end
endcase
endfunction
function automatic int dec_lc_cnt(lc_cnt_e curr_cnt);
case (curr_cnt)
LcCnt0: return 0;
LcCnt1: return 1;
LcCnt2: return 2;
LcCnt3: return 3;
LcCnt4: return 4;
LcCnt5: return 5;
LcCnt6: return 6;
LcCnt7: return 7;
LcCnt8: return 8;
LcCnt9: return 9;
LcCnt10: return 10;
LcCnt11: return 11;
LcCnt12: return 12;
LcCnt13: return 13;
LcCnt14: return 14;
LcCnt15: return 15;
LcCnt16: return 16;
LcCnt17: return 17;
LcCnt18: return 18;
LcCnt19: return 19;
LcCnt20: return 20;
LcCnt21: return 21;
LcCnt22: return 22;
LcCnt23: return 23;
LcCnt24: return 24;
default: `uvm_fatal("lc_env_pkg", $sformatf("dec_lc_cnt: unknown lc_cnt 0x%0h", curr_cnt))
endcase
endfunction
// Arrays of digit values
parameter bit [15:0] A_VALUES[20] = '{
lc_ctrl_state_pkg::A0,
lc_ctrl_state_pkg::A1,
lc_ctrl_state_pkg::A2,
lc_ctrl_state_pkg::A3,
lc_ctrl_state_pkg::A4,
lc_ctrl_state_pkg::A5,
lc_ctrl_state_pkg::A6,
lc_ctrl_state_pkg::A7,
lc_ctrl_state_pkg::A8,
lc_ctrl_state_pkg::A9,
lc_ctrl_state_pkg::A10,
lc_ctrl_state_pkg::A11,
lc_ctrl_state_pkg::A12,
lc_ctrl_state_pkg::A13,
lc_ctrl_state_pkg::A14,
lc_ctrl_state_pkg::A15,
lc_ctrl_state_pkg::A16,
lc_ctrl_state_pkg::A17,
lc_ctrl_state_pkg::A18,
lc_ctrl_state_pkg::A19
};
parameter bit [15:0] B_VALUES[20] = '{
lc_ctrl_state_pkg::B0,
lc_ctrl_state_pkg::B1,
lc_ctrl_state_pkg::B2,
lc_ctrl_state_pkg::B3,
lc_ctrl_state_pkg::B4,
lc_ctrl_state_pkg::B5,
lc_ctrl_state_pkg::B6,
lc_ctrl_state_pkg::B7,
lc_ctrl_state_pkg::B8,
lc_ctrl_state_pkg::B9,
lc_ctrl_state_pkg::B10,
lc_ctrl_state_pkg::B11,
lc_ctrl_state_pkg::B12,
lc_ctrl_state_pkg::B13,
lc_ctrl_state_pkg::B14,
lc_ctrl_state_pkg::B15,
lc_ctrl_state_pkg::B16,
lc_ctrl_state_pkg::B17,
lc_ctrl_state_pkg::B18,
lc_ctrl_state_pkg::B19
};
parameter bit [15:0] C_VALUES[24] = '{
lc_ctrl_state_pkg::C0,
lc_ctrl_state_pkg::C1,
lc_ctrl_state_pkg::C2,
lc_ctrl_state_pkg::C3,
lc_ctrl_state_pkg::C4,
lc_ctrl_state_pkg::C5,
lc_ctrl_state_pkg::C6,
lc_ctrl_state_pkg::C7,
lc_ctrl_state_pkg::C8,
lc_ctrl_state_pkg::C9,
lc_ctrl_state_pkg::C10,
lc_ctrl_state_pkg::C11,
lc_ctrl_state_pkg::C12,
lc_ctrl_state_pkg::C13,
lc_ctrl_state_pkg::C14,
lc_ctrl_state_pkg::C15,
lc_ctrl_state_pkg::C16,
lc_ctrl_state_pkg::C17,
lc_ctrl_state_pkg::C18,
lc_ctrl_state_pkg::C19,
lc_ctrl_state_pkg::C20,
lc_ctrl_state_pkg::C21,
lc_ctrl_state_pkg::C22,
lc_ctrl_state_pkg::C23
};
parameter bit [15:0] D_VALUES[24] = '{
lc_ctrl_state_pkg::D0,
lc_ctrl_state_pkg::D1,
lc_ctrl_state_pkg::D2,
lc_ctrl_state_pkg::D3,
lc_ctrl_state_pkg::D4,
lc_ctrl_state_pkg::D5,
lc_ctrl_state_pkg::D6,
lc_ctrl_state_pkg::D7,
lc_ctrl_state_pkg::D8,
lc_ctrl_state_pkg::D9,
lc_ctrl_state_pkg::D10,
lc_ctrl_state_pkg::D11,
lc_ctrl_state_pkg::D12,
lc_ctrl_state_pkg::D13,
lc_ctrl_state_pkg::D14,
lc_ctrl_state_pkg::D15,
lc_ctrl_state_pkg::D16,
lc_ctrl_state_pkg::D17,
lc_ctrl_state_pkg::D18,
lc_ctrl_state_pkg::D19,
lc_ctrl_state_pkg::D20,
lc_ctrl_state_pkg::D21,
lc_ctrl_state_pkg::D22,
lc_ctrl_state_pkg::D23
};
// Binary representation of state and count types
typedef bit [NumLcStateValues - 1 : 0] lc_state_bin_t;
typedef bit [NumLcCountValues - 1 : 0] lc_count_bin_t;
//Convert an lc_state to a binary representation 0=Axx 1=Bxx
function static lc_state_bin_t lc_state_to_bin(bit [LcStateWidth-1:0] val);
lc_state_to_bin = 0;
for (int i = 0; i < $size(A_VALUES); i++) begin
if (val[i*16+:16] == A_VALUES[i]) begin
lc_state_to_bin[i] = 0;
end else if (val[i*16+:16] == B_VALUES[i]) begin
lc_state_to_bin[i] = 1;
end else begin
$fatal(0, "lc_ctrl_dv_utils_pkg lc_state_to_bin: state %x not valid", val);
end
end
endfunction
//Convert a binary representation to a lc_state representation 0=Axx 1=Bxx
function automatic bit [LcStateWidth-1:0] bin_to_lc_state(lc_state_bin_t val, bit err_inj = 0);
int err_inj_idx = -1;
bin_to_lc_state = 0;
if (err_inj) begin
// Select a symbol to invert
err_inj_idx = $urandom_range(0, $size(A_VALUES) - 1);
end
for (int i = 0; i < $size(A_VALUES); i++) begin
if (i != err_inj_idx) begin
// No error
bin_to_lc_state[i*16+:16] = val[i] ? B_VALUES[i] : A_VALUES[i];
end else begin
// Error inject - invert symbol
bin_to_lc_state[i*16+:16] = val[i] ? ~B_VALUES[i] : ~A_VALUES[i];
end
end
endfunction
//Convert an lc_count to a binary representation 0=Cxx 1=Dxx
function static lc_count_bin_t lc_count_to_bin(bit [LcCountWidth-1:0] val);
lc_count_to_bin = 0;
for (int i = 0; i < $size(C_VALUES); i++) begin
if (val[i*16+:16] == C_VALUES[i]) begin
lc_count_to_bin[i] = 0;
end else if (val[i*16+:16] == D_VALUES[i]) begin
lc_count_to_bin[i] = 1;
end else begin
$fatal(0, "lc_ctrl_dv_utils_pkg lc_count_to_bin: count %x not valid", val);
end
end
endfunction
//Convert a binary representation to a lc_count representation 0=Cxx 1=Dxx
function automatic bit [LcCountWidth-1:0] bin_to_lc_count(lc_count_bin_t val, bit err_inj = 0);
int err_inj_idx = -1;
bin_to_lc_count = 0;
if (err_inj) begin
// Select a symbol to invert
err_inj_idx = $urandom_range(0, $size(C_VALUES) - 1);
end
for (int i = 0; i < $size(C_VALUES); i++) begin
if (i != err_inj_idx) begin
// No error
bin_to_lc_count[i*16+:16] = val[i] ? D_VALUES[i] : C_VALUES[i];
end else begin
// Error inject - invert symbol
bin_to_lc_count[i*16+:16] = val[i] ? ~D_VALUES[i] : ~C_VALUES[i];
end
end
endfunction
// Array of valid LC states in binary representation
parameter lc_state_bin_t ValidLcStatesBin[NumLcStates] = '{
lc_state_to_bin(LcStRaw),
lc_state_to_bin(LcStTestUnlocked0),
lc_state_to_bin(LcStTestLocked0),
lc_state_to_bin(LcStTestUnlocked1),
lc_state_to_bin(LcStTestLocked1),
lc_state_to_bin(LcStTestUnlocked2),
lc_state_to_bin(LcStTestLocked2),
lc_state_to_bin(LcStTestUnlocked3),
lc_state_to_bin(LcStTestLocked3),
lc_state_to_bin(LcStTestUnlocked4),
lc_state_to_bin(LcStTestLocked4),
lc_state_to_bin(LcStTestUnlocked5),
lc_state_to_bin(LcStTestLocked5),
lc_state_to_bin(LcStTestUnlocked6),
lc_state_to_bin(LcStTestLocked6),
lc_state_to_bin(LcStTestUnlocked7),
lc_state_to_bin(LcStDev),
lc_state_to_bin(LcStProd),
lc_state_to_bin(LcStProdEnd),
lc_state_to_bin(LcStRma),
lc_state_to_bin(LcStScrap)
};
// Array of valid LC states in binary representation
parameter lc_count_bin_t ValidLcCountsBin[NumLcCountStates] = '{
lc_count_to_bin(LcCnt0),
lc_count_to_bin(LcCnt1),
lc_count_to_bin(LcCnt2),
lc_count_to_bin(LcCnt3),
lc_count_to_bin(LcCnt4),
lc_count_to_bin(LcCnt5),
lc_count_to_bin(LcCnt6),
lc_count_to_bin(LcCnt7),
lc_count_to_bin(LcCnt8),
lc_count_to_bin(LcCnt9),
lc_count_to_bin(LcCnt10),
lc_count_to_bin(LcCnt11),
lc_count_to_bin(LcCnt12),
lc_count_to_bin(LcCnt13),
lc_count_to_bin(LcCnt14),
lc_count_to_bin(LcCnt15),
lc_count_to_bin(LcCnt16),
lc_count_to_bin(LcCnt17),
lc_count_to_bin(LcCnt18),
lc_count_to_bin(LcCnt19),
lc_count_to_bin(LcCnt20),
lc_count_to_bin(LcCnt21),
lc_count_to_bin(LcCnt22),
lc_count_to_bin(LcCnt23),
lc_count_to_bin(LcCnt24)
};
// States with OTP test registers active
parameter lc_state_e LC_CTRL_OTP_TEST_REG_ENABLED_STATES[17] = '{
LcStRaw,
LcStTestUnlocked0,
LcStTestLocked0,
LcStTestUnlocked1,
LcStTestLocked1,
LcStTestUnlocked2,
LcStTestLocked2,
LcStTestUnlocked3,
LcStTestLocked3,
LcStTestUnlocked4,
LcStTestLocked4,
LcStTestUnlocked5,
LcStTestLocked5,
LcStTestUnlocked6,
LcStTestLocked6,
LcStTestUnlocked7,
LcStRma
};
// Counts with OTP test registers enabled
parameter lc_cnt_e LC_CTRL_OTP_TEST_REG_ENABLED_COUNTS[25] = '{
LcCnt0,
LcCnt1,
LcCnt2,
LcCnt3,
LcCnt4,
LcCnt5,
LcCnt6,
LcCnt7,
LcCnt8,
LcCnt9,
LcCnt10,
LcCnt11,
LcCnt12,
LcCnt13,
LcCnt14,
LcCnt15,
LcCnt16,
LcCnt17,
LcCnt18,
LcCnt19,
LcCnt20,
LcCnt21,
LcCnt22,
LcCnt23,
LcCnt24
};
endpackage