blob: dd2c9eb5a7abd70e42610107aea0afa62aeccd94 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Testbench module for prim_lfsr. Intended to be used with a formal tool.
module prim_lfsr_tb #(
// LFSR entropy and output bitwidths (set to 1 here as they are unused)
parameter int unsigned EntropyDw = 1,
parameter int unsigned StateOutDw = 1,
// this specifies the range of differently
// parameterized LFSRs to instantiate and check
parameter int unsigned GalXorMinLfsrDw = 4,
parameter int unsigned GalXorMaxLfsrDw = 64,
parameter int unsigned FibXnorMinLfsrDw = 3,
parameter int unsigned FibXnorMaxLfsrDw = 168,
// LFSRs up to this bitwidth are checked for maximum length
parameter int unsigned MaxLenSVAThresh = 10,
// derived params
localparam int unsigned GalMaxGtFibMax = GalXorMaxLfsrDw > FibXnorMaxLfsrDw,
localparam int unsigned MaxLfsrDw = GalXorMaxLfsrDw * GalMaxGtFibMax +
FibXnorMaxLfsrDw * (1 - GalMaxGtFibMax),
localparam int unsigned NumDuts = 2*(FibXnorMaxLfsrDw - FibXnorMinLfsrDw + 1) +
2*(GalXorMaxLfsrDw - GalXorMinLfsrDw + 1)
) (
input clk_i,
input rst_ni,
input [NumDuts-1:0] load_ext_en_i,
input [NumDuts-1:0][MaxLfsrDw-1:0] seed_ext_i,
input [NumDuts-1:0] lfsr_en_i,
input [NumDuts-1:0][EntropyDw-1:0] entropy_i,
output logic [NumDuts-1:0][StateOutDw-1:0] state_o
);
for (genvar k = GalXorMinLfsrDw; k <= GalXorMaxLfsrDw; k++) begin : gen_gal_xor_duts
localparam int unsigned Idx = k - GalXorMinLfsrDw;
prim_lfsr #(.LfsrType("GAL_XOR"),
.LfsrDw ( k ),
.EntropyDw ( EntropyDw ),
.StateOutDw ( StateOutDw ),
.DefaultSeed ( 1 ),
// disabled for large LFSRs since this becomes prohibitive in runtime
.MaxLenSVA ( k <= MaxLenSVAThresh )
) u_prim_lfsr (
.clk_i,
.rst_ni,
.seed_en_i ( load_ext_en_i[Idx] ),
.seed_i ( k'(seed_ext_i[Idx]) ),
.lfsr_en_i ( lfsr_en_i[Idx] ),
.entropy_i ( entropy_i[Idx] ),
.state_o ( state_o[Idx] )
);
end
// same as above but with non-linear output enabled.
// only power-of-two widths are allowed.
for (genvar k = 16; k <= GalXorMaxLfsrDw; k = k*2)
begin : gen_gal_xor_duts_nonlinear
localparam int unsigned Idx = k - GalXorMinLfsrDw;
prim_lfsr #(.LfsrType("GAL_XOR"),
.LfsrDw ( k ),
.EntropyDw ( EntropyDw ),
.StateOutDw ( StateOutDw ),
.DefaultSeed ( 1 ),
// disabled for large LFSRs since this becomes prohibitive in runtime
.MaxLenSVA ( k <= MaxLenSVAThresh ),
.NonLinearOut (1)
) u_prim_lfsr (
.clk_i,
.rst_ni,
.seed_en_i ( load_ext_en_i[Idx] ),
.seed_i ( k'(seed_ext_i[Idx]) ),
.lfsr_en_i ( lfsr_en_i[Idx] ),
.entropy_i ( entropy_i[Idx] ),
.state_o ( state_o[Idx] )
);
end
for (genvar k = FibXnorMinLfsrDw; k <= FibXnorMaxLfsrDw; k++) begin : gen_fib_xnor_duts
localparam int unsigned Idx = k - FibXnorMinLfsrDw + GalXorMaxLfsrDw - GalXorMinLfsrDw + 1;
prim_lfsr #(.LfsrType("FIB_XNOR"),
.LfsrDw ( k ),
.EntropyDw ( EntropyDw ),
.StateOutDw ( StateOutDw ),
.DefaultSeed ( 1 ),
// disabled for large LFSRs since this becomes prohibitive in runtime
.MaxLenSVA ( k <= MaxLenSVAThresh )
) u_prim_lfsr (
.clk_i,
.rst_ni,
.seed_en_i ( load_ext_en_i[Idx] ),
.seed_i ( k'(seed_ext_i[Idx]) ),
.lfsr_en_i ( lfsr_en_i[Idx] ),
.entropy_i ( entropy_i[Idx] ),
.state_o ( state_o[Idx] )
);
end
// same as above but with non-linear output enabled.
// only power-of-two widths are allowed.
for (genvar k = 16; k <= FibXnorMaxLfsrDw; k = k*2)
begin : gen_fib_xnor_duts_nonlinear
localparam int unsigned Idx = k - FibXnorMinLfsrDw + GalXorMaxLfsrDw - GalXorMinLfsrDw + 1;
prim_lfsr #(.LfsrType("FIB_XNOR"),
.LfsrDw ( k ),
.EntropyDw ( EntropyDw ),
.StateOutDw ( StateOutDw ),
.DefaultSeed ( 1 ),
// disabled for large LFSRs since this becomes prohibitive in runtime
.MaxLenSVA ( k <= MaxLenSVAThresh ),
.NonLinearOut (1)
) u_prim_lfsr (
.clk_i,
.rst_ni,
.seed_en_i ( load_ext_en_i[Idx] ),
.seed_i ( k'(seed_ext_i[Idx]) ),
.lfsr_en_i ( lfsr_en_i[Idx] ),
.entropy_i ( entropy_i[Idx] ),
.state_o ( state_o[Idx] )
);
end
endmodule : prim_lfsr_tb