[prim_lfsr] Add FPV testbench
diff --git a/hw/formal/formal.core b/hw/formal/formal.core
index 4f056fa..979b6b9 100644
--- a/hw/formal/formal.core
+++ b/hw/formal/formal.core
@@ -10,6 +10,7 @@
filesets:
files_rtl_generic:
depend:
+ - lowrisc:fpv:prim_lfsr_fpv
- lowrisc:ip:rv_timer
- lowrisc:ip:hmac
- lowrisc:systems:top_earlgrey
diff --git a/hw/ip/prim/fpv/prim_lfsr_fpv.core b/hw/ip/prim/fpv/prim_lfsr_fpv.core
new file mode 100644
index 0000000..4103c79
--- /dev/null
+++ b/hw/ip/prim/fpv/prim_lfsr_fpv.core
@@ -0,0 +1,21 @@
+CAPI=2:
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+name: "lowrisc:fpv:prim_lfsr_fpv:0.1"
+description: "ALERT_HANDLER FPV target"
+filesets:
+ files_fpv:
+ depend:
+ - lowrisc:prim:all
+ files:
+ - tb/prim_lfsr_tb.sv
+ file_type: systemVerilogSource
+
+targets:
+ default: &default_target
+ toplevel:
+ - tb/prim_lfsr_tb.sv
+ filesets:
+ - files_fpv
+ default_tool: jg
diff --git a/hw/ip/prim/fpv/tb/prim_lfsr_tb.sv b/hw/ip/prim/fpv/tb/prim_lfsr_tb.sv
new file mode 100644
index 0000000..f582c29
--- /dev/null
+++ b/hw/ip/prim/fpv/tb/prim_lfsr_tb.sv
@@ -0,0 +1,64 @@
+// 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 use with a formal tool.
+
+module prim_lfsr_tb #(
+ parameter int unsigned InDw = 1,
+ parameter int unsigned OutDw = 1,
+ parameter int unsigned GalXorMinLfsrDw = 4,
+ parameter int unsigned GalXorMaxLfsrDw = 64,
+ parameter int unsigned FibXnorMinLfsrDw = 3,
+ parameter int unsigned FibXnorMaxLfsrDw = 168,
+ parameter int unsigned NumDuts = FibXnorMaxLfsrDw - FibXnorMinLfsrDw + 1 +
+ GalXorMaxLfsrDw - GalXorMinLfsrDw + 1,
+ // LFSRs up to this bitwidth are checked for maximum length
+ parameter int unsigned MaxLenSVAThresh = 10
+) (
+ input clk_i,
+ input rst_ni,
+ input [NumDuts-1:0] en_i,
+ input [NumDuts-1:0][InDw-1:0] data_i,
+ output logic [NumDuts-1:0][OutDw-1:0] data_o
+);
+
+ for (genvar k = GalXorMinLfsrDw; k <= GalXorMaxLfsrDw; k++) begin : gen_gal_xor_duts
+ prim_lfsr #(
+ .LfsrType("GAL_XOR"),
+ .LfsrDw(k),
+ .InDw(InDw),
+ .OutDw(OutDw),
+ .Seed(1),
+ .Custom('0),
+ // disabled for large LFSRs since this becomes prohibitive in runtime
+ .MaxLenSVA(k <= MaxLenSVAThresh)
+ ) i_prim_lfsr (
+ .clk_i,
+ .rst_ni,
+ .en_i(en_i[k-GalXorMinLfsrDw]),
+ .data_i(data_i[k-GalXorMinLfsrDw]),
+ .data_o(data_o[k-GalXorMinLfsrDw])
+ );
+ end
+
+ for (genvar k = FibXnorMinLfsrDw; k <= FibXnorMaxLfsrDw; k++) begin : gen_fib_xnor_duts
+ prim_lfsr #(
+ .LfsrType("FIB_XNOR"),
+ .LfsrDw(k),
+ .InDw(InDw),
+ .OutDw(OutDw),
+ .Seed(1),
+ .Custom('0),
+ // disabled for large LFSRs since this becomes prohibitive in runtime
+ .MaxLenSVA(k <= MaxLenSVAThresh)
+ ) i_prim_lfsr (
+ .clk_i,
+ .rst_ni,
+ .en_i(en_i[k - FibXnorMinLfsrDw + GalXorMaxLfsrDw - GalXorMinLfsrDw + 1]),
+ .data_i(data_i[k - FibXnorMinLfsrDw + GalXorMaxLfsrDw - GalXorMinLfsrDw + 1]),
+ .data_o(data_o[k - FibXnorMinLfsrDw + GalXorMaxLfsrDw - GalXorMinLfsrDw + 1])
+ );
+ end
+
+endmodule : prim_lfsr_tb