Module Definition
dashboard | hierarchy | modlist | groups | tests | asserts

Module : prim_prince
SCORELINECONDTOGGLEFSMBRANCHASSERT
100.00 100.00 100.00 100.00 100.00 100.00

Source File(s) :
/workspaces/repo/scratch/os_regression_2024_10_11/prim_prince-sim-vcs/default/sim-vcs/../src/lowrisc_prim_cipher_0/rtl/prim_prince.sv

Module self-instances :
NAMESCORELINECONDTOGGLEFSMBRANCHASSERT
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[0].gen_duts[0].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[0].gen_duts[1].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[0].gen_duts[2].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[0].gen_duts[3].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[0].gen_duts[4].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[1].gen_duts[0].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[1].gen_duts[1].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[1].gen_duts[2].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[1].gen_duts[3].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[1].gen_duts[4].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[0].gen_duts[0].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[0].gen_duts[1].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[0].gen_duts[2].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[0].gen_duts[3].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[0].gen_duts[4].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[1].gen_duts[0].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[1].gen_duts[1].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[1].gen_duts[2].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[1].gen_duts[3].dut 100.00 100.00 100.00 100.00 100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[1].gen_duts[4].dut 100.00 100.00 100.00 100.00 100.00 100.00

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[0].gen_duts[0].dut

Line No.TotalCoveredPercent
TOTAL3535100.00
ALWAYS5677100.00
ALWAYS7533100.00
CONT_ASSIGN9911100.00
CONT_ASSIGN10011100.00
CONT_ASSIGN10111100.00
ALWAYS11433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
ALWAYS15433100.00
CONT_ASSIGN18611100.00
CONT_ASSIGN18711100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 assign k0_new_d = k1_d; 71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 1/1 if (dec_i) begin Tests: T1 T2 T3  78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  79 end MISSING_ELSE 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 if (!rst_ni) begin 86 k1_q <= '0; 87 k0_prime_q <= '0; 88 k0_new_q <= '0; 89 end else begin 90 if (valid_i) begin 91 k1_q <= k1_d; 92 k0_prime_q <= k0_prime_d; 93 k0_new_q <= k0_new_d; 94 end 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 1/1 assign k1_q = k1_d; Tests: T1 T2 T3  100 1/1 assign k0_prime_q = k0_prime_d; Tests: T1 T2 T3  101 1/1 assign k0_new_q = k0_new_d; Tests: T1 T2 T3  102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 1/1 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  145 end else begin : gen_fwd_key_even 146 assign data_state_lo[k] = data_state_xor ^ k1_d; 147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 if (!rst_ni) begin 174 valid_q <= 1'b0; 175 data_state_middle_q <= '0; 176 end else begin 177 valid_q <= valid_i; 178 if (valid_i) begin 179 data_state_middle_q <= data_state_middle_d; 180 end 181 end 182 end 183 assign valid_o = valid_q; 184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 1/1 assign data_state_middle_q = data_state_middle_d; Tests: T1 T2 T3  187 1/1 assign valid_o = valid_i; Tests: T1 T2 T3  188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; 200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 1/1 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[0].gen_duts[1].dut

Line No.TotalCoveredPercent
TOTAL4545100.00
ALWAYS5677100.00
ALWAYS7533100.00
CONT_ASSIGN9911100.00
CONT_ASSIGN10011100.00
CONT_ASSIGN10111100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
CONT_ASSIGN18611100.00
CONT_ASSIGN18711100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 assign k0_new_d = k1_d; 71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 1/1 if (dec_i) begin Tests: T1 T2 T3  78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  79 end MISSING_ELSE 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 if (!rst_ni) begin 86 k1_q <= '0; 87 k0_prime_q <= '0; 88 k0_new_q <= '0; 89 end else begin 90 if (valid_i) begin 91 k1_q <= k1_d; 92 k0_prime_q <= k0_prime_d; 93 k0_new_q <= k0_new_d; 94 end 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 1/1 assign k1_q = k1_d; Tests: T1 T2 T3  100 1/1 assign k0_prime_q = k0_prime_d; Tests: T1 T2 T3  101 1/1 assign k0_new_q = k0_new_d; Tests: T1 T2 T3  102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 2/2 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  145 end else begin : gen_fwd_key_even 146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 if (!rst_ni) begin 174 valid_q <= 1'b0; 175 data_state_middle_q <= '0; 176 end else begin 177 valid_q <= valid_i; 178 if (valid_i) begin 179 data_state_middle_q <= data_state_middle_d; 180 end 181 end 182 end 183 assign valid_o = valid_q; 184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 1/1 assign data_state_middle_q = data_state_middle_d; Tests: T1 T2 T3  187 1/1 assign valid_o = valid_i; Tests: T1 T2 T3  188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 2/2 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 2 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[0].gen_duts[2].dut

Line No.TotalCoveredPercent
TOTAL5555100.00
ALWAYS5677100.00
ALWAYS7533100.00
CONT_ASSIGN9911100.00
CONT_ASSIGN10011100.00
CONT_ASSIGN10111100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
CONT_ASSIGN18611100.00
CONT_ASSIGN18711100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 assign k0_new_d = k1_d; 71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 1/1 if (dec_i) begin Tests: T1 T2 T3  78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  79 end MISSING_ELSE 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 if (!rst_ni) begin 86 k1_q <= '0; 87 k0_prime_q <= '0; 88 k0_new_q <= '0; 89 end else begin 90 if (valid_i) begin 91 k1_q <= k1_d; 92 k0_prime_q <= k0_prime_d; 93 k0_new_q <= k0_new_d; 94 end 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 1/1 assign k1_q = k1_d; Tests: T1 T2 T3  100 1/1 assign k0_prime_q = k0_prime_d; Tests: T1 T2 T3  101 1/1 assign k0_new_q = k0_new_d; Tests: T1 T2 T3  102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 2 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 3/3 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  | T1 T2 T3  145 end else begin : gen_fwd_key_even 146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 if (!rst_ni) begin 174 valid_q <= 1'b0; 175 data_state_middle_q <= '0; 176 end else begin 177 valid_q <= valid_i; 178 if (valid_i) begin 179 data_state_middle_q <= data_state_middle_d; 180 end 181 end 182 end 183 assign valid_o = valid_q; 184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 1/1 assign data_state_middle_q = data_state_middle_d; Tests: T1 T2 T3  187 1/1 assign valid_o = valid_i; Tests: T1 T2 T3  188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  | T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 3/3 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 3 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 4 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[0].gen_duts[3].dut

Line No.TotalCoveredPercent
TOTAL6565100.00
ALWAYS5677100.00
ALWAYS7533100.00
CONT_ASSIGN9911100.00
CONT_ASSIGN10011100.00
CONT_ASSIGN10111100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
CONT_ASSIGN18611100.00
CONT_ASSIGN18711100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 assign k0_new_d = k1_d; 71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 1/1 if (dec_i) begin Tests: T1 T2 T3  78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  79 end MISSING_ELSE 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 if (!rst_ni) begin 86 k1_q <= '0; 87 k0_prime_q <= '0; 88 k0_new_q <= '0; 89 end else begin 90 if (valid_i) begin 91 k1_q <= k1_d; 92 k0_prime_q <= k0_prime_d; 93 k0_new_q <= k0_new_d; 94 end 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 1/1 assign k1_q = k1_d; Tests: T1 T2 T3  100 1/1 assign k0_prime_q = k0_prime_d; Tests: T1 T2 T3  101 1/1 assign k0_new_q = k0_new_d; Tests: T1 T2 T3  102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 2 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 3 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 4/4 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  | T1 T2 T3  145 end else begin : gen_fwd_key_even 146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  | T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 if (!rst_ni) begin 174 valid_q <= 1'b0; 175 data_state_middle_q <= '0; 176 end else begin 177 valid_q <= valid_i; 178 if (valid_i) begin 179 data_state_middle_q <= data_state_middle_d; 180 end 181 end 182 end 183 assign valid_o = valid_q; 184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 1/1 assign data_state_middle_q = data_state_middle_d; Tests: T1 T2 T3  187 1/1 assign valid_o = valid_i; Tests: T1 T2 T3  188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  | T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  | T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 4/4 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 4 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 5 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 6 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[0].gen_duts[4].dut

Line No.TotalCoveredPercent
TOTAL7575100.00
ALWAYS5677100.00
ALWAYS7533100.00
CONT_ASSIGN9911100.00
CONT_ASSIGN10011100.00
CONT_ASSIGN10111100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
CONT_ASSIGN18611100.00
CONT_ASSIGN18711100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 assign k0_new_d = k1_d; 71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 1/1 if (dec_i) begin Tests: T1 T2 T3  78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  79 end MISSING_ELSE 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 if (!rst_ni) begin 86 k1_q <= '0; 87 k0_prime_q <= '0; 88 k0_new_q <= '0; 89 end else begin 90 if (valid_i) begin 91 k1_q <= k1_d; 92 k0_prime_q <= k0_prime_d; 93 k0_new_q <= k0_new_d; 94 end 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 1/1 assign k1_q = k1_d; Tests: T1 T2 T3  100 1/1 assign k0_prime_q = k0_prime_d; Tests: T1 T2 T3  101 1/1 assign k0_new_q = k0_new_d; Tests: T1 T2 T3  102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 2 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 3 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 4 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 5/5 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 3/3 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  145 end else begin : gen_fwd_key_even 146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  | T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 if (!rst_ni) begin 174 valid_q <= 1'b0; 175 data_state_middle_q <= '0; 176 end else begin 177 valid_q <= valid_i; 178 if (valid_i) begin 179 data_state_middle_q <= data_state_middle_d; 180 end 181 end 182 end 183 assign valid_o = valid_q; 184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 1/1 assign data_state_middle_q = data_state_middle_d; Tests: T1 T2 T3  187 1/1 assign valid_o = valid_i; Tests: T1 T2 T3  188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 3/3 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  | T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 5/5 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 5 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 6 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 7 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 8 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[1].gen_duts[0].dut

Line No.TotalCoveredPercent
TOTAL4545100.00
ALWAYS5677100.00
ALWAYS7533100.00
ALWAYS8588100.00
ALWAYS11433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
ALWAYS15433100.00
ALWAYS17366100.00
CONT_ASSIGN18311100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 assign k0_new_d = k1_d; 71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 1/1 if (dec_i) begin Tests: T1 T2 T3  78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  79 end MISSING_ELSE 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 1/1 if (!rst_ni) begin Tests: T1 T2 T3  86 1/1 k1_q <= '0; Tests: T1 T2 T3  87 1/1 k0_prime_q <= '0; Tests: T1 T2 T3  88 1/1 k0_new_q <= '0; Tests: T1 T2 T3  89 end else begin 90 1/1 if (valid_i) begin Tests: T1 T2 T3  91 1/1 k1_q <= k1_d; Tests: T1 T2 T3  92 1/1 k0_prime_q <= k0_prime_d; Tests: T1 T2 T3  93 1/1 k0_new_q <= k0_new_d; Tests: T1 T2 T3  94 end MISSING_ELSE 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 assign k1_q = k1_d; 100 assign k0_prime_q = k0_prime_d; 101 assign k0_new_q = k0_new_d; 102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 1/1 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  145 end else begin : gen_fwd_key_even 146 assign data_state_lo[k] = data_state_xor ^ k1_d; 147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 1/1 if (!rst_ni) begin Tests: T1 T2 T3  174 1/1 valid_q <= 1'b0; Tests: T1 T2 T3  175 1/1 data_state_middle_q <= '0; Tests: T1 T2 T3  176 end else begin 177 1/1 valid_q <= valid_i; Tests: T1 T2 T3  178 1/1 if (valid_i) begin Tests: T1 T2 T3  179 1/1 data_state_middle_q <= data_state_middle_d; Tests: T1 T2 T3  180 end MISSING_ELSE 181 end 182 end 183 1/1 assign valid_o = valid_q; Tests: T1 T2 T3  184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 assign data_state_middle_q = data_state_middle_d; 187 assign valid_o = valid_i; 188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; 200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 1/1 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[1].gen_duts[1].dut

Line No.TotalCoveredPercent
TOTAL5555100.00
ALWAYS5677100.00
ALWAYS7533100.00
ALWAYS8588100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
ALWAYS17366100.00
CONT_ASSIGN18311100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 assign k0_new_d = k1_d; 71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 1/1 if (dec_i) begin Tests: T1 T2 T3  78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  79 end MISSING_ELSE 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 1/1 if (!rst_ni) begin Tests: T1 T2 T3  86 1/1 k1_q <= '0; Tests: T1 T2 T3  87 1/1 k0_prime_q <= '0; Tests: T1 T2 T3  88 1/1 k0_new_q <= '0; Tests: T1 T2 T3  89 end else begin 90 1/1 if (valid_i) begin Tests: T1 T2 T3  91 1/1 k1_q <= k1_d; Tests: T1 T2 T3  92 1/1 k0_prime_q <= k0_prime_d; Tests: T1 T2 T3  93 1/1 k0_new_q <= k0_new_d; Tests: T1 T2 T3  94 end MISSING_ELSE 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 assign k1_q = k1_d; 100 assign k0_prime_q = k0_prime_d; 101 assign k0_new_q = k0_new_d; 102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 2/2 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  145 end else begin : gen_fwd_key_even 146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 1/1 if (!rst_ni) begin Tests: T1 T2 T3  174 1/1 valid_q <= 1'b0; Tests: T1 T2 T3  175 1/1 data_state_middle_q <= '0; Tests: T1 T2 T3  176 end else begin 177 1/1 valid_q <= valid_i; Tests: T1 T2 T3  178 1/1 if (valid_i) begin Tests: T1 T2 T3  179 1/1 data_state_middle_q <= data_state_middle_d; Tests: T1 T2 T3  180 end MISSING_ELSE 181 end 182 end 183 1/1 assign valid_o = valid_q; Tests: T1 T2 T3  184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 assign data_state_middle_q = data_state_middle_d; 187 assign valid_o = valid_i; 188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 2/2 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 2 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[1].gen_duts[2].dut

Line No.TotalCoveredPercent
TOTAL6565100.00
ALWAYS5677100.00
ALWAYS7533100.00
ALWAYS8588100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
ALWAYS17366100.00
CONT_ASSIGN18311100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 assign k0_new_d = k1_d; 71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 1/1 if (dec_i) begin Tests: T1 T2 T3  78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  79 end MISSING_ELSE 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 1/1 if (!rst_ni) begin Tests: T1 T2 T3  86 1/1 k1_q <= '0; Tests: T1 T2 T3  87 1/1 k0_prime_q <= '0; Tests: T1 T2 T3  88 1/1 k0_new_q <= '0; Tests: T1 T2 T3  89 end else begin 90 1/1 if (valid_i) begin Tests: T1 T2 T3  91 1/1 k1_q <= k1_d; Tests: T1 T2 T3  92 1/1 k0_prime_q <= k0_prime_d; Tests: T1 T2 T3  93 1/1 k0_new_q <= k0_new_d; Tests: T1 T2 T3  94 end MISSING_ELSE 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 assign k1_q = k1_d; 100 assign k0_prime_q = k0_prime_d; 101 assign k0_new_q = k0_new_d; 102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 2 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 3/3 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  | T1 T2 T3  145 end else begin : gen_fwd_key_even 146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 1/1 if (!rst_ni) begin Tests: T1 T2 T3  174 1/1 valid_q <= 1'b0; Tests: T1 T2 T3  175 1/1 data_state_middle_q <= '0; Tests: T1 T2 T3  176 end else begin 177 1/1 valid_q <= valid_i; Tests: T1 T2 T3  178 1/1 if (valid_i) begin Tests: T1 T2 T3  179 1/1 data_state_middle_q <= data_state_middle_d; Tests: T1 T2 T3  180 end MISSING_ELSE 181 end 182 end 183 1/1 assign valid_o = valid_q; Tests: T1 T2 T3  184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 assign data_state_middle_q = data_state_middle_d; 187 assign valid_o = valid_i; 188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  | T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 3/3 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 3 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 4 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[1].gen_duts[3].dut

Line No.TotalCoveredPercent
TOTAL7575100.00
ALWAYS5677100.00
ALWAYS7533100.00
ALWAYS8588100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
ALWAYS17366100.00
CONT_ASSIGN18311100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 assign k0_new_d = k1_d; 71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 1/1 if (dec_i) begin Tests: T1 T2 T3  78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  79 end MISSING_ELSE 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 1/1 if (!rst_ni) begin Tests: T1 T2 T3  86 1/1 k1_q <= '0; Tests: T1 T2 T3  87 1/1 k0_prime_q <= '0; Tests: T1 T2 T3  88 1/1 k0_new_q <= '0; Tests: T1 T2 T3  89 end else begin 90 1/1 if (valid_i) begin Tests: T1 T2 T3  91 1/1 k1_q <= k1_d; Tests: T1 T2 T3  92 1/1 k0_prime_q <= k0_prime_d; Tests: T1 T2 T3  93 1/1 k0_new_q <= k0_new_d; Tests: T1 T2 T3  94 end MISSING_ELSE 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 assign k1_q = k1_d; 100 assign k0_prime_q = k0_prime_d; 101 assign k0_new_q = k0_new_d; 102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 2 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 3 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 4/4 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  | T1 T2 T3  145 end else begin : gen_fwd_key_even 146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  | T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 1/1 if (!rst_ni) begin Tests: T1 T2 T3  174 1/1 valid_q <= 1'b0; Tests: T1 T2 T3  175 1/1 data_state_middle_q <= '0; Tests: T1 T2 T3  176 end else begin 177 1/1 valid_q <= valid_i; Tests: T1 T2 T3  178 1/1 if (valid_i) begin Tests: T1 T2 T3  179 1/1 data_state_middle_q <= data_state_middle_d; Tests: T1 T2 T3  180 end MISSING_ELSE 181 end 182 end 183 1/1 assign valid_o = valid_q; Tests: T1 T2 T3  184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 assign data_state_middle_q = data_state_middle_d; 187 assign valid_o = valid_i; 188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  | T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  | T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 4/4 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 4 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 5 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 6 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[1].gen_duts[4].dut

Line No.TotalCoveredPercent
TOTAL8585100.00
ALWAYS5677100.00
ALWAYS7533100.00
ALWAYS8588100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
ALWAYS17366100.00
CONT_ASSIGN18311100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 assign k0_new_d = k1_d; 71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 1/1 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 1/1 if (dec_i) begin Tests: T1 T2 T3  78 1/1 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  79 end MISSING_ELSE 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 1/1 if (!rst_ni) begin Tests: T1 T2 T3  86 1/1 k1_q <= '0; Tests: T1 T2 T3  87 1/1 k0_prime_q <= '0; Tests: T1 T2 T3  88 1/1 k0_new_q <= '0; Tests: T1 T2 T3  89 end else begin 90 1/1 if (valid_i) begin Tests: T1 T2 T3  91 1/1 k1_q <= k1_d; Tests: T1 T2 T3  92 1/1 k0_prime_q <= k0_prime_d; Tests: T1 T2 T3  93 1/1 k0_new_q <= k0_new_d; Tests: T1 T2 T3  94 end MISSING_ELSE 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 assign k1_q = k1_d; 100 assign k0_prime_q = k0_prime_d; 101 assign k0_new_q = k0_new_d; 102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 2 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 3 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 4 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 5/5 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 3/3 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  145 end else begin : gen_fwd_key_even 146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  | T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 1/1 if (!rst_ni) begin Tests: T1 T2 T3  174 1/1 valid_q <= 1'b0; Tests: T1 T2 T3  175 1/1 data_state_middle_q <= '0; Tests: T1 T2 T3  176 end else begin 177 1/1 valid_q <= valid_i; Tests: T1 T2 T3  178 1/1 if (valid_i) begin Tests: T1 T2 T3  179 1/1 data_state_middle_q <= data_state_middle_d; Tests: T1 T2 T3  180 end MISSING_ELSE 181 end 182 end 183 1/1 assign valid_o = valid_q; Tests: T1 T2 T3  184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 assign data_state_middle_q = data_state_middle_d; 187 assign valid_o = valid_i; 188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 3/3 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  | T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 5/5 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 5 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 6 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 7 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 8 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[0].gen_duts[0].dut

Line No.TotalCoveredPercent
TOTAL3333100.00
ALWAYS5677100.00
CONT_ASSIGN7011100.00
CONT_ASSIGN9911100.00
CONT_ASSIGN10011100.00
CONT_ASSIGN10111100.00
ALWAYS11433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
ALWAYS15433100.00
CONT_ASSIGN18611100.00
CONT_ASSIGN18711100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 1/1 assign k0_new_d = k1_d; Tests: T1 T2 T3  71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; 76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 if (dec_i) begin 78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; 79 end 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 if (!rst_ni) begin 86 k1_q <= '0; 87 k0_prime_q <= '0; 88 k0_new_q <= '0; 89 end else begin 90 if (valid_i) begin 91 k1_q <= k1_d; 92 k0_prime_q <= k0_prime_d; 93 k0_new_q <= k0_new_d; 94 end 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 1/1 assign k1_q = k1_d; Tests: T1 T2 T3  100 1/1 assign k0_prime_q = k0_prime_d; Tests: T1 T2 T3  101 1/1 assign k0_new_q = k0_new_d; Tests: T1 T2 T3  102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 1/1 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  145 end else begin : gen_fwd_key_even 146 assign data_state_lo[k] = data_state_xor ^ k1_d; 147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 if (!rst_ni) begin 174 valid_q <= 1'b0; 175 data_state_middle_q <= '0; 176 end else begin 177 valid_q <= valid_i; 178 if (valid_i) begin 179 data_state_middle_q <= data_state_middle_d; 180 end 181 end 182 end 183 assign valid_o = valid_q; 184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 1/1 assign data_state_middle_q = data_state_middle_d; Tests: T1 T2 T3  187 1/1 assign valid_o = valid_i; Tests: T1 T2 T3  188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; 200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 1/1 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[0].gen_duts[1].dut

Line No.TotalCoveredPercent
TOTAL4343100.00
ALWAYS5677100.00
CONT_ASSIGN7011100.00
CONT_ASSIGN9911100.00
CONT_ASSIGN10011100.00
CONT_ASSIGN10111100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
CONT_ASSIGN18611100.00
CONT_ASSIGN18711100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 1/1 assign k0_new_d = k1_d; Tests: T1 T2 T3  71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; 76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 if (dec_i) begin 78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; 79 end 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 if (!rst_ni) begin 86 k1_q <= '0; 87 k0_prime_q <= '0; 88 k0_new_q <= '0; 89 end else begin 90 if (valid_i) begin 91 k1_q <= k1_d; 92 k0_prime_q <= k0_prime_d; 93 k0_new_q <= k0_new_d; 94 end 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 1/1 assign k1_q = k1_d; Tests: T1 T2 T3  100 1/1 assign k0_prime_q = k0_prime_d; Tests: T1 T2 T3  101 1/1 assign k0_new_q = k0_new_d; Tests: T1 T2 T3  102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 2/2 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  145 end else begin : gen_fwd_key_even 146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 if (!rst_ni) begin 174 valid_q <= 1'b0; 175 data_state_middle_q <= '0; 176 end else begin 177 valid_q <= valid_i; 178 if (valid_i) begin 179 data_state_middle_q <= data_state_middle_d; 180 end 181 end 182 end 183 assign valid_o = valid_q; 184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 1/1 assign data_state_middle_q = data_state_middle_d; Tests: T1 T2 T3  187 1/1 assign valid_o = valid_i; Tests: T1 T2 T3  188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 2/2 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 2 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[0].gen_duts[2].dut

Line No.TotalCoveredPercent
TOTAL5353100.00
ALWAYS5677100.00
CONT_ASSIGN7011100.00
CONT_ASSIGN9911100.00
CONT_ASSIGN10011100.00
CONT_ASSIGN10111100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
CONT_ASSIGN18611100.00
CONT_ASSIGN18711100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 1/1 assign k0_new_d = k1_d; Tests: T1 T2 T3  71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; 76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 if (dec_i) begin 78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; 79 end 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 if (!rst_ni) begin 86 k1_q <= '0; 87 k0_prime_q <= '0; 88 k0_new_q <= '0; 89 end else begin 90 if (valid_i) begin 91 k1_q <= k1_d; 92 k0_prime_q <= k0_prime_d; 93 k0_new_q <= k0_new_d; 94 end 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 1/1 assign k1_q = k1_d; Tests: T1 T2 T3  100 1/1 assign k0_prime_q = k0_prime_d; Tests: T1 T2 T3  101 1/1 assign k0_new_q = k0_new_d; Tests: T1 T2 T3  102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 2 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 3/3 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  | T1 T2 T3  145 end else begin : gen_fwd_key_even 146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 if (!rst_ni) begin 174 valid_q <= 1'b0; 175 data_state_middle_q <= '0; 176 end else begin 177 valid_q <= valid_i; 178 if (valid_i) begin 179 data_state_middle_q <= data_state_middle_d; 180 end 181 end 182 end 183 assign valid_o = valid_q; 184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 1/1 assign data_state_middle_q = data_state_middle_d; Tests: T1 T2 T3  187 1/1 assign valid_o = valid_i; Tests: T1 T2 T3  188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  | T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 3/3 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 3 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 4 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[0].gen_duts[3].dut

Line No.TotalCoveredPercent
TOTAL6363100.00
ALWAYS5677100.00
CONT_ASSIGN7011100.00
CONT_ASSIGN9911100.00
CONT_ASSIGN10011100.00
CONT_ASSIGN10111100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
CONT_ASSIGN18611100.00
CONT_ASSIGN18711100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 1/1 assign k0_new_d = k1_d; Tests: T1 T2 T3  71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; 76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 if (dec_i) begin 78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; 79 end 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 if (!rst_ni) begin 86 k1_q <= '0; 87 k0_prime_q <= '0; 88 k0_new_q <= '0; 89 end else begin 90 if (valid_i) begin 91 k1_q <= k1_d; 92 k0_prime_q <= k0_prime_d; 93 k0_new_q <= k0_new_d; 94 end 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 1/1 assign k1_q = k1_d; Tests: T1 T2 T3  100 1/1 assign k0_prime_q = k0_prime_d; Tests: T1 T2 T3  101 1/1 assign k0_new_q = k0_new_d; Tests: T1 T2 T3  102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 2 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 3 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 4/4 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  | T1 T2 T3  145 end else begin : gen_fwd_key_even 146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  | T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 if (!rst_ni) begin 174 valid_q <= 1'b0; 175 data_state_middle_q <= '0; 176 end else begin 177 valid_q <= valid_i; 178 if (valid_i) begin 179 data_state_middle_q <= data_state_middle_d; 180 end 181 end 182 end 183 assign valid_o = valid_q; 184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 1/1 assign data_state_middle_q = data_state_middle_d; Tests: T1 T2 T3  187 1/1 assign valid_o = valid_i; Tests: T1 T2 T3  188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  | T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  | T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 4/4 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 4 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 5 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 6 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[0].gen_duts[4].dut

Line No.TotalCoveredPercent
TOTAL7373100.00
ALWAYS5677100.00
CONT_ASSIGN7011100.00
CONT_ASSIGN9911100.00
CONT_ASSIGN10011100.00
CONT_ASSIGN10111100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
CONT_ASSIGN18611100.00
CONT_ASSIGN18711100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 1/1 assign k0_new_d = k1_d; Tests: T1 T2 T3  71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; 76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 if (dec_i) begin 78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; 79 end 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 if (!rst_ni) begin 86 k1_q <= '0; 87 k0_prime_q <= '0; 88 k0_new_q <= '0; 89 end else begin 90 if (valid_i) begin 91 k1_q <= k1_d; 92 k0_prime_q <= k0_prime_d; 93 k0_new_q <= k0_new_d; 94 end 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 1/1 assign k1_q = k1_d; Tests: T1 T2 T3  100 1/1 assign k0_prime_q = k0_prime_d; Tests: T1 T2 T3  101 1/1 assign k0_new_q = k0_new_d; Tests: T1 T2 T3  102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 2 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 3 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 4 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 5/5 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 3/3 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  145 end else begin : gen_fwd_key_even 146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  | T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 if (!rst_ni) begin 174 valid_q <= 1'b0; 175 data_state_middle_q <= '0; 176 end else begin 177 valid_q <= valid_i; 178 if (valid_i) begin 179 data_state_middle_q <= data_state_middle_d; 180 end 181 end 182 end 183 assign valid_o = valid_q; 184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 1/1 assign data_state_middle_q = data_state_middle_d; Tests: T1 T2 T3  187 1/1 assign valid_o = valid_i; Tests: T1 T2 T3  188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 3/3 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  | T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 5/5 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 5 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 6 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 7 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 8 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[1].gen_duts[0].dut

Line No.TotalCoveredPercent
TOTAL4343100.00
ALWAYS5677100.00
CONT_ASSIGN7011100.00
ALWAYS8588100.00
ALWAYS11433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
ALWAYS15433100.00
ALWAYS17366100.00
CONT_ASSIGN18311100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 1/1 assign k0_new_d = k1_d; Tests: T1 T2 T3  71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; 76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 if (dec_i) begin 78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; 79 end 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 1/1 if (!rst_ni) begin Tests: T1 T2 T3  86 1/1 k1_q <= '0; Tests: T1 T2 T3  87 1/1 k0_prime_q <= '0; Tests: T1 T2 T3  88 1/1 k0_new_q <= '0; Tests: T1 T2 T3  89 end else begin 90 1/1 if (valid_i) begin Tests: T1 T2 T3  91 1/1 k1_q <= k1_d; Tests: T1 T2 T3  92 1/1 k0_prime_q <= k0_prime_d; Tests: T1 T2 T3  93 1/1 k0_new_q <= k0_new_d; Tests: T1 T2 T3  94 end MISSING_ELSE 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 assign k1_q = k1_d; 100 assign k0_prime_q = k0_prime_d; 101 assign k0_new_q = k0_new_d; 102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 1/1 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  145 end else begin : gen_fwd_key_even 146 assign data_state_lo[k] = data_state_xor ^ k1_d; 147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 1/1 if (!rst_ni) begin Tests: T1 T2 T3  174 1/1 valid_q <= 1'b0; Tests: T1 T2 T3  175 1/1 data_state_middle_q <= '0; Tests: T1 T2 T3  176 end else begin 177 1/1 valid_q <= valid_i; Tests: T1 T2 T3  178 1/1 if (valid_i) begin Tests: T1 T2 T3  179 1/1 data_state_middle_q <= data_state_middle_d; Tests: T1 T2 T3  180 end MISSING_ELSE 181 end 182 end 183 1/1 assign valid_o = valid_q; Tests: T1 T2 T3  184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 assign data_state_middle_q = data_state_middle_d; 187 assign valid_o = valid_i; 188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; 200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 1/1 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[1].gen_duts[1].dut

Line No.TotalCoveredPercent
TOTAL5353100.00
ALWAYS5677100.00
CONT_ASSIGN7011100.00
ALWAYS8588100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
ALWAYS17366100.00
CONT_ASSIGN18311100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 1/1 assign k0_new_d = k1_d; Tests: T1 T2 T3  71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; 76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 if (dec_i) begin 78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; 79 end 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 1/1 if (!rst_ni) begin Tests: T1 T2 T3  86 1/1 k1_q <= '0; Tests: T1 T2 T3  87 1/1 k0_prime_q <= '0; Tests: T1 T2 T3  88 1/1 k0_new_q <= '0; Tests: T1 T2 T3  89 end else begin 90 1/1 if (valid_i) begin Tests: T1 T2 T3  91 1/1 k1_q <= k1_d; Tests: T1 T2 T3  92 1/1 k0_prime_q <= k0_prime_d; Tests: T1 T2 T3  93 1/1 k0_new_q <= k0_new_d; Tests: T1 T2 T3  94 end MISSING_ELSE 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 assign k1_q = k1_d; 100 assign k0_prime_q = k0_prime_d; 101 assign k0_new_q = k0_new_d; 102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 2/2 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 1/1 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  145 end else begin : gen_fwd_key_even 146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 1/1 if (!rst_ni) begin Tests: T1 T2 T3  174 1/1 valid_q <= 1'b0; Tests: T1 T2 T3  175 1/1 data_state_middle_q <= '0; Tests: T1 T2 T3  176 end else begin 177 1/1 valid_q <= valid_i; Tests: T1 T2 T3  178 1/1 if (valid_i) begin Tests: T1 T2 T3  179 1/1 data_state_middle_q <= data_state_middle_d; Tests: T1 T2 T3  180 end MISSING_ELSE 181 end 182 end 183 1/1 assign valid_o = valid_q; Tests: T1 T2 T3  184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 assign data_state_middle_q = data_state_middle_d; 187 assign valid_o = valid_i; 188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 2/2 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 2 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[1].gen_duts[2].dut

Line No.TotalCoveredPercent
TOTAL6363100.00
ALWAYS5677100.00
CONT_ASSIGN7011100.00
ALWAYS8588100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
ALWAYS17366100.00
CONT_ASSIGN18311100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 1/1 assign k0_new_d = k1_d; Tests: T1 T2 T3  71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; 76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 if (dec_i) begin 78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; 79 end 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 1/1 if (!rst_ni) begin Tests: T1 T2 T3  86 1/1 k1_q <= '0; Tests: T1 T2 T3  87 1/1 k0_prime_q <= '0; Tests: T1 T2 T3  88 1/1 k0_new_q <= '0; Tests: T1 T2 T3  89 end else begin 90 1/1 if (valid_i) begin Tests: T1 T2 T3  91 1/1 k1_q <= k1_d; Tests: T1 T2 T3  92 1/1 k0_prime_q <= k0_prime_d; Tests: T1 T2 T3  93 1/1 k0_new_q <= k0_new_d; Tests: T1 T2 T3  94 end MISSING_ELSE 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 assign k1_q = k1_d; 100 assign k0_prime_q = k0_prime_d; 101 assign k0_new_q = k0_new_d; 102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 2 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 3/3 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  | T1 T2 T3  145 end else begin : gen_fwd_key_even 146 1/1 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 1/1 if (!rst_ni) begin Tests: T1 T2 T3  174 1/1 valid_q <= 1'b0; Tests: T1 T2 T3  175 1/1 data_state_middle_q <= '0; Tests: T1 T2 T3  176 end else begin 177 1/1 valid_q <= valid_i; Tests: T1 T2 T3  178 1/1 if (valid_i) begin Tests: T1 T2 T3  179 1/1 data_state_middle_q <= data_state_middle_d; Tests: T1 T2 T3  180 end MISSING_ELSE 181 end 182 end 183 1/1 assign valid_o = valid_q; Tests: T1 T2 T3  184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 assign data_state_middle_q = data_state_middle_d; 187 assign valid_o = valid_i; 188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  | T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 1/1 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 3/3 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 3 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 4 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[1].gen_duts[3].dut

Line No.TotalCoveredPercent
TOTAL7373100.00
ALWAYS5677100.00
CONT_ASSIGN7011100.00
ALWAYS8588100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
ALWAYS17366100.00
CONT_ASSIGN18311100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 1/1 assign k0_new_d = k1_d; Tests: T1 T2 T3  71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; 76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 if (dec_i) begin 78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; 79 end 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 1/1 if (!rst_ni) begin Tests: T1 T2 T3  86 1/1 k1_q <= '0; Tests: T1 T2 T3  87 1/1 k0_prime_q <= '0; Tests: T1 T2 T3  88 1/1 k0_new_q <= '0; Tests: T1 T2 T3  89 end else begin 90 1/1 if (valid_i) begin Tests: T1 T2 T3  91 1/1 k1_q <= k1_d; Tests: T1 T2 T3  92 1/1 k0_prime_q <= k0_prime_d; Tests: T1 T2 T3  93 1/1 k0_new_q <= k0_new_d; Tests: T1 T2 T3  94 end MISSING_ELSE 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 assign k1_q = k1_d; 100 assign k0_prime_q = k0_prime_d; 101 assign k0_new_q = k0_new_d; 102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 2 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 3 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 4/4 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 2/2 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  | T1 T2 T3  145 end else begin : gen_fwd_key_even 146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  | T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 1/1 if (!rst_ni) begin Tests: T1 T2 T3  174 1/1 valid_q <= 1'b0; Tests: T1 T2 T3  175 1/1 data_state_middle_q <= '0; Tests: T1 T2 T3  176 end else begin 177 1/1 valid_q <= valid_i; Tests: T1 T2 T3  178 1/1 if (valid_i) begin Tests: T1 T2 T3  179 1/1 data_state_middle_q <= data_state_middle_d; Tests: T1 T2 T3  180 end MISSING_ELSE 181 end 182 end 183 1/1 assign valid_o = valid_q; Tests: T1 T2 T3  184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 assign data_state_middle_q = data_state_middle_d; 187 assign valid_o = valid_i; 188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  | T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  | T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 4/4 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 4 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 5 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 6 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Line Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 )
Line Coverage for Module self-instances :
SCORELINE
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[1].gen_duts[4].dut

Line No.TotalCoveredPercent
TOTAL8383100.00
ALWAYS5677100.00
CONT_ASSIGN7011100.00
ALWAYS8588100.00
ALWAYS11433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
ALWAYS12433100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14011100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14411100.00
CONT_ASSIGN14611100.00
CONT_ASSIGN14611100.00
ALWAYS15433100.00
ALWAYS17366100.00
CONT_ASSIGN18311100.00
CONT_ASSIGN19011100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19711100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN19911100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
CONT_ASSIGN20211100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS20833100.00
ALWAYS22733100.00

55 always_comb begin : p_key_expansion 56 1/1 k0 = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  57 1/1 k0_prime_d = {k0[0], k0[DataWidth-1:2], k0[DataWidth-1] ^ k0[1]}; Tests: T1 T2 T3  58 1/1 k1_d = key_i[DataWidth-1:0]; Tests: T1 T2 T3  59 60 // modify key for decryption 61 1/1 if (dec_i) begin Tests: T1 T2 T3  62 1/1 k0 = k0_prime_d; Tests: T1 T2 T3  63 1/1 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; Tests: T1 T2 T3  64 1/1 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; Tests: T1 T2 T3  65 end MISSING_ELSE 66 end 67 68 if (UseOldKeySched) begin : gen_legacy_keyschedule 69 // In this case we constantly use k1. 70 1/1 assign k0_new_d = k1_d; Tests: T1 T2 T3  71 end else begin : gen_new_keyschedule 72 // Imroved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 73 // In this case we alternate between k1 and k0. 74 always_comb begin : p_new_keyschedule_k0_alpha 75 k0_new_d = key_i[2*DataWidth-1 : DataWidth]; 76 // We need to apply the alpha constant here as well, just as for k1 in decryption mode. 77 if (dec_i) begin 78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; 79 end 80 end 81 end 82 83 if (HalfwayKeyReg) begin : gen_key_reg 84 always_ff @(posedge clk_i or negedge rst_ni) begin : p_key_reg 85 1/1 if (!rst_ni) begin Tests: T1 T2 T3  86 1/1 k1_q <= '0; Tests: T1 T2 T3  87 1/1 k0_prime_q <= '0; Tests: T1 T2 T3  88 1/1 k0_new_q <= '0; Tests: T1 T2 T3  89 end else begin 90 1/1 if (valid_i) begin Tests: T1 T2 T3  91 1/1 k1_q <= k1_d; Tests: T1 T2 T3  92 1/1 k0_prime_q <= k0_prime_d; Tests: T1 T2 T3  93 1/1 k0_new_q <= k0_new_d; Tests: T1 T2 T3  94 end MISSING_ELSE 95 end 96 end 97 end else begin : gen_no_key_reg 98 // just pass the key through in this case 99 assign k1_q = k1_d; 100 assign k0_prime_q = k0_prime_d; 101 assign k0_new_q = k0_new_d; 102 end 103 104 ////////////// 105 // datapath // 106 ////////////// 107 108 // State variable for holding the rounds 109 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_lo; 110 logic [NumRoundsHalf:0][DataWidth-1:0] data_state_hi; 111 112 // pre-round XOR 113 always_comb begin : p_pre_round_xor 114 1/1 data_state_lo[0] = data_i ^ k0; Tests: T1 T2 T3  115 1/1 data_state_lo[0] ^= k1_d; Tests: T1 T2 T3  116 1/1 data_state_lo[0] ^= prim_cipher_pkg::PRINCE_ROUND_CONST[0][DataWidth-1:0]; Tests: T1 T2 T3  117 end 118 119 // forward pass 120 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_fwd_pass 121 logic [DataWidth-1:0] data_state_round; 122 if (DataWidth == 64) begin : gen_fwd_d64 123 always_comb begin : p_fwd_d64 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 1 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 2 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 3 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  ***repeat 4 124 1/1 data_state_round = prim_cipher_pkg::sbox4_64bit(data_state_lo[k-1], Tests: T1 T2 T3  125 prim_cipher_pkg::PRINCE_SBOX4); 126 1/1 data_state_round = prim_cipher_pkg::prince_mult_prime_64bit(data_state_round); Tests: T1 T2 T3  127 1/1 data_state_round = prim_cipher_pkg::prince_shiftrows_64bit(data_state_round, Tests: T1 T2 T3  128 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 129 end 130 end else begin : gen_fwd_d32 131 always_comb begin : p_fwd_d32 132 data_state_round = prim_cipher_pkg::sbox4_32bit(data_state_lo[k-1], 133 prim_cipher_pkg::PRINCE_SBOX4); 134 data_state_round = prim_cipher_pkg::prince_mult_prime_32bit(data_state_round); 135 data_state_round = prim_cipher_pkg::prince_shiftrows_32bit(data_state_round, 136 prim_cipher_pkg::PRINCE_SHIFT_ROWS64); 137 end 138 end 139 logic [DataWidth-1:0] data_state_xor; 140 5/5 assign data_state_xor = data_state_round ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  141 prim_cipher_pkg::PRINCE_ROUND_CONST[k][DataWidth-1:0]; 142 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 143 if (k % 2 == 1) begin : gen_fwd_key_odd 144 3/3 assign data_state_lo[k] = data_state_xor ^ k0_new_d; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  145 end else begin : gen_fwd_key_even 146 2/2 assign data_state_lo[k] = data_state_xor ^ k1_d; Tests: T1 T2 T3  | T1 T2 T3  147 end 148 end 149 150 // middle part 151 logic [DataWidth-1:0] data_state_middle_d, data_state_middle_q, data_state_middle; 152 if (DataWidth == 64) begin : gen_middle_d64 153 always_comb begin : p_middle_d64 154 1/1 data_state_middle_d = prim_cipher_pkg::sbox4_64bit(data_state_lo[NumRoundsHalf], Tests: T1 T2 T3  155 prim_cipher_pkg::PRINCE_SBOX4); 156 1/1 data_state_middle = prim_cipher_pkg::prince_mult_prime_64bit(data_state_middle_q); Tests: T1 T2 T3  157 1/1 data_state_middle = prim_cipher_pkg::sbox4_64bit(data_state_middle, Tests: T1 T2 T3  158 prim_cipher_pkg::PRINCE_SBOX4_INV); 159 end 160 end else begin : gen_middle_d32 161 always_comb begin : p_middle_d32 162 data_state_middle_d = prim_cipher_pkg::sbox4_32bit(data_state_middle[NumRoundsHalf], 163 prim_cipher_pkg::PRINCE_SBOX4); 164 data_state_middle = prim_cipher_pkg::prince_mult_prime_32bit(data_state_middle_q); 165 data_state_middle = prim_cipher_pkg::sbox4_32bit(data_state_middle, 166 prim_cipher_pkg::PRINCE_SBOX4_INV); 167 end 168 end 169 170 if (HalfwayDataReg) begin : gen_data_reg 171 logic valid_q; 172 always_ff @(posedge clk_i or negedge rst_ni) begin : p_data_reg 173 1/1 if (!rst_ni) begin Tests: T1 T2 T3  174 1/1 valid_q <= 1'b0; Tests: T1 T2 T3  175 1/1 data_state_middle_q <= '0; Tests: T1 T2 T3  176 end else begin 177 1/1 valid_q <= valid_i; Tests: T1 T2 T3  178 1/1 if (valid_i) begin Tests: T1 T2 T3  179 1/1 data_state_middle_q <= data_state_middle_d; Tests: T1 T2 T3  180 end MISSING_ELSE 181 end 182 end 183 1/1 assign valid_o = valid_q; Tests: T1 T2 T3  184 end else begin : gen_no_data_reg 185 // just pass data through in this case 186 assign data_state_middle_q = data_state_middle_d; 187 assign valid_o = valid_i; 188 end 189 190 1/1 assign data_state_hi[0] = data_state_middle; Tests: T1 T2 T3  191 192 // backward pass 193 for (genvar k = 1; k <= NumRoundsHalf; k++) begin : gen_bwd_pass 194 logic [DataWidth-1:0] data_state_xor0, data_state_xor1; 195 // improved keyschedule proposed by https://eprint.iacr.org/2014/656.pdf 196 if ((NumRoundsHalf + k + 1) % 2 == 1) begin : gen_bkwd_key_odd 197 3/3 assign data_state_xor0 = data_state_hi[k-1] ^ k0_new_q; Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  198 end else begin : gen_bkwd_key_even 199 2/2 assign data_state_xor0 = data_state_hi[k-1] ^ k1_q; Tests: T1 T2 T3  | T1 T2 T3  200 end 201 // the construction is reflective, hence the subtraction with NumRoundsHalf 202 5/5 assign data_state_xor1 = data_state_xor0 ^ Tests: T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  | T1 T2 T3  203 prim_cipher_pkg::PRINCE_ROUND_CONST[10-NumRoundsHalf+k][DataWidth-1:0]; 204 205 logic [DataWidth-1:0] data_state_bwd; 206 if (DataWidth == 64) begin : gen_bwd_d64 207 always_comb begin : p_bwd_d64 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 5 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 6 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 7 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  ***repeat 8 208 1/1 data_state_bwd = prim_cipher_pkg::prince_shiftrows_64bit(data_state_xor1, Tests: T1 T2 T3  209 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 210 1/1 data_state_bwd = prim_cipher_pkg::prince_mult_prime_64bit(data_state_bwd); Tests: T1 T2 T3  211 1/1 data_state_hi[k] = prim_cipher_pkg::sbox4_64bit(data_state_bwd, Tests: T1 T2 T3  212 prim_cipher_pkg::PRINCE_SBOX4_INV); 213 end 214 end else begin : gen_bwd_d32 215 always_comb begin : p_bwd_d32 216 data_state_bwd = prim_cipher_pkg::prince_shiftrows_32bit(data_state_xor1, 217 prim_cipher_pkg::PRINCE_SHIFT_ROWS64_INV); 218 data_state_bwd = prim_cipher_pkg::prince_mult_prime_32bit(data_state_bwd); 219 data_state_hi[k] = prim_cipher_pkg::sbox4_32bit(data_state_bwd, 220 prim_cipher_pkg::PRINCE_SBOX4_INV); 221 end 222 end 223 end 224 225 // post-rounds 226 always_comb begin : p_post_round_xor 227 1/1 data_o = data_state_hi[NumRoundsHalf] ^ Tests: T1 T2 T3  228 prim_cipher_pkg::PRINCE_ROUND_CONST[11][DataWidth-1:0]; 229 1/1 data_o ^= k1_q; Tests: T1 T2 T3  230 1/1 data_o ^= k0_prime_q; Tests: T1 T2 T3 

Cond Coverage for Module : prim_prince
TotalCoveredPercent
Conditions44100.00
Logical44100.00
Non-Logical00
Event00

 LINE       57
 SUB-EXPRESSION (k0[(DataWidth - 1)] ^ k0[1])
                 ---------1---------   --2--
-1--2-StatusTests
00CoveredT1,T2,T3
01CoveredT1,T2,T3
10CoveredT1,T2,T3
11CoveredT1,T2,T3

Toggle Coverage for Module : prim_prince
TotalCoveredPercent
Totals 8 8 100.00
Total Bits 522 522 100.00
Total Bits 0->1 261 261 100.00
Total Bits 1->0 261 261 100.00

Ports 8 8 100.00
Port Bits 522 522 100.00
Port Bits 0->1 261 261 100.00
Port Bits 1->0 261 261 100.00

Port Details
NameToggleToggle 1->0TestsToggle 0->1TestsDirection
clk_i Yes Yes T1,T2,T3 Yes T1,T2,T3 INPUT
rst_ni Yes Yes T1,T2,T3 Yes T1,T2,T3 INPUT
valid_i Yes Yes T1,T2,T3 Yes T1,T2,T3 INPUT
data_i[63:0] Yes Yes T1,T2,T3 Yes T1,T2,T3 INPUT
key_i[127:0] Yes Yes T1,T2,T3 Yes T1,T2,T3 INPUT
dec_i Yes Yes T1,T2,T3 Yes T1,T2,T3 INPUT
valid_o Yes Yes T1,T2,T3 Yes T1,T2,T3 OUTPUT
data_o[63:0] Yes Yes T1,T2,T3 Yes T1,T2,T3 OUTPUT


Branch Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=1,HalfwayDataReg=0,HalfwayKeyReg=0 )
Branch Coverage for Module self-instances :
SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[0].gen_duts[0].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[0].gen_duts[1].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[0].gen_duts[2].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[0].gen_duts[3].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[0].gen_duts[4].dut

Line No.TotalCoveredPercent
Branches 2 2 100.00
IF 61 2 2 100.00


61 if (dec_i) begin -1- 62 k0 = k0_prime_d; ==> 63 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; 64 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; 65 end MISSING_ELSE ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T1,T2,T3


Branch Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=1,HalfwayDataReg=1,HalfwayKeyReg=1 )
Branch Coverage for Module self-instances :
SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[1].gen_duts[0].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[1].gen_duts[1].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[1].gen_duts[2].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[1].gen_duts[3].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[1].gen_registered_variant[1].gen_duts[4].dut

Line No.TotalCoveredPercent
Branches 8 8 100.00
IF 61 2 2 100.00
IF 85 3 3 100.00
IF 173 3 3 100.00


61 if (dec_i) begin -1- 62 k0 = k0_prime_d; ==> 63 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; 64 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; 65 end MISSING_ELSE ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T1,T2,T3


85 if (!rst_ni) begin -1- 86 k1_q <= '0; ==> 87 k0_prime_q <= '0; 88 k0_new_q <= '0; 89 end else begin 90 if (valid_i) begin -2- 91 k1_q <= k1_d; ==> 92 k0_prime_q <= k0_prime_d; 93 k0_new_q <= k0_new_d; 94 end MISSING_ELSE ==>

Branches:
-1--2-StatusTests
1 - Covered T1,T2,T3
0 1 Covered T1,T2,T3
0 0 Covered T1,T2,T3


173 if (!rst_ni) begin -1- 174 valid_q <= 1'b0; ==> 175 data_state_middle_q <= '0; 176 end else begin 177 valid_q <= valid_i; 178 if (valid_i) begin -2- 179 data_state_middle_q <= data_state_middle_d; ==> 180 end MISSING_ELSE ==>

Branches:
-1--2-StatusTests
1 - Covered T1,T2,T3
0 1 Covered T1,T2,T3
0 0 Covered T1,T2,T3


Branch Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 + DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=0,HalfwayDataReg=0,HalfwayKeyReg=0 )
Branch Coverage for Module self-instances :
SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[0].gen_duts[0].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[0].gen_duts[1].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[0].gen_duts[2].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[0].gen_duts[3].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[0].gen_duts[4].dut

Line No.TotalCoveredPercent
Branches 4 4 100.00
IF 61 2 2 100.00
IF 77 2 2 100.00


61 if (dec_i) begin -1- 62 k0 = k0_prime_d; ==> 63 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; 64 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; 65 end MISSING_ELSE ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T1,T2,T3


77 if (dec_i) begin -1- 78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; ==> 79 end MISSING_ELSE ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T1,T2,T3


Branch Coverage for Module : prim_prince ( parameter DataWidth=64,KeyWidth=128,NumRoundsHalf=1,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=2,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=3,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=4,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 + DataWidth=64,KeyWidth=128,NumRoundsHalf=5,UseOldKeySched=0,HalfwayDataReg=1,HalfwayKeyReg=1 )
Branch Coverage for Module self-instances :
SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[1].gen_duts[0].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[1].gen_duts[1].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[1].gen_duts[2].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[1].gen_duts[3].dut

SCOREBRANCH
100.00 100.00
prim_prince_tb.gen_new_key_schedule[0].gen_registered_variant[1].gen_duts[4].dut

Line No.TotalCoveredPercent
Branches 10 10 100.00
IF 61 2 2 100.00
IF 77 2 2 100.00
IF 85 3 3 100.00
IF 173 3 3 100.00


61 if (dec_i) begin -1- 62 k0 = k0_prime_d; ==> 63 k0_prime_d = key_i[2*DataWidth-1 : DataWidth]; 64 k1_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; 65 end MISSING_ELSE ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T1,T2,T3


77 if (dec_i) begin -1- 78 k0_new_d ^= prim_cipher_pkg::PRINCE_ALPHA_CONST[DataWidth-1:0]; ==> 79 end MISSING_ELSE ==>

Branches:
-1-StatusTests
1 Covered T1,T2,T3
0 Covered T1,T2,T3


85 if (!rst_ni) begin -1- 86 k1_q <= '0; ==> 87 k0_prime_q <= '0; 88 k0_new_q <= '0; 89 end else begin 90 if (valid_i) begin -2- 91 k1_q <= k1_d; ==> 92 k0_prime_q <= k0_prime_d; 93 k0_new_q <= k0_new_d; 94 end MISSING_ELSE ==>

Branches:
-1--2-StatusTests
1 - Covered T1,T2,T3
0 1 Covered T1,T2,T3
0 0 Covered T1,T2,T3


173 if (!rst_ni) begin -1- 174 valid_q <= 1'b0; ==> 175 data_state_middle_q <= '0; 176 end else begin 177 valid_q <= valid_i; 178 if (valid_i) begin -2- 179 data_state_middle_q <= data_state_middle_d; ==> 180 end MISSING_ELSE ==>

Branches:
-1--2-StatusTests
1 - Covered T1,T2,T3
0 1 Covered T1,T2,T3
0 0 Covered T1,T2,T3


Assert Coverage for Module : prim_prince
TotalAttemptedPercentSucceeded/MatchedPercent
Assertions 2 2 100.00 2 100.00
Cover properties 0 0 0
Cover sequences 0 0 0
Total 2 2 100.00 2 100.00




Assertion Details

NameAttemptsReal SuccessesFailuresIncomplete
SupportedNumRounds_A 10000 10000 0 0
SupportedWidths_A 10000 10000 0 0


SupportedNumRounds_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 10000 10000 0 0
T1 20 20 0 0
T2 20 20 0 0
T3 20 20 0 0
T4 20 20 0 0
T5 20 20 0 0
T6 20 20 0 0
T7 20 20 0 0
T8 20 20 0 0
T9 20 20 0 0
T10 20 20 0 0

SupportedWidths_A
NameAttemptsReal SuccessesFailuresIncomplete
Total 10000 10000 0 0
T1 20 20 0 0
T2 20 20 0 0
T3 20 20 0 0
T4 20 20 0 0
T5 20 20 0 0
T6 20 20 0 0
T7 20 20 0 0
T8 20 20 0 0
T9 20 20 0 0
T10 20 20 0 0

0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%