[prim] Use prim_pkg::impl_e instead of int for Impl

All target-dependent primitives are supplied with an Impl parameter,
which chooses the implementation target. The potential values for this
parameter are listed in the prim_pkg::impl_e enum, which is based on
int.

This commit switches Impl over to use prim_pkg::impl_e as type, instead
of int. Doing so avoids many casts over the code base, at the cost of
having to pass an enum type name to the tool in the PRIM_DEFAULT_IMPL
define. This approach is standards-compliant, but seems fragile.
Let's give it a try nonetheless, and see how tools react to it.

Tested with
- Verilator 4.019
- Xilinx Vivado synthesis 2018.3
- Synopsys VCS 2019.06

Note for the future: revert this commit if you run into tool issues.
diff --git a/hw/ip/padctrl/fpv/tb/padctrl_tb.sv b/hw/ip/padctrl/fpv/tb/padctrl_tb.sv
index 91939b0..d3e3d0b 100644
--- a/hw/ip/padctrl/fpv/tb/padctrl_tb.sv
+++ b/hw/ip/padctrl/fpv/tb/padctrl_tb.sv
@@ -5,11 +5,11 @@
 // Testbench module for padctrl. Intended to use with a formal tool.
 
 `ifndef PRIM_DEFAULT_IMPL
-  `define PRIM_DEFAULT_IMPL integer'(prim_pkg::ImplGeneric)
+  `define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
 `endif
 
 module padctrl_tb #(
-  parameter integer Impl = `PRIM_DEFAULT_IMPL
+  parameter prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL
 ) (
   input wire                                    clk_i,
   input wire                                    rst_ni,
diff --git a/hw/ip/padctrl/fpv/vip/padctrl_assert.sv b/hw/ip/padctrl/fpv/vip/padctrl_assert.sv
index 150de48..3621f11 100644
--- a/hw/ip/padctrl/fpv/vip/padctrl_assert.sv
+++ b/hw/ip/padctrl/fpv/vip/padctrl_assert.sv
@@ -7,11 +7,11 @@
 
 
 `ifndef PRIM_DEFAULT_IMPL
-  `define PRIM_DEFAULT_IMPL integer'(prim_pkg::ImplGeneric)
+  `define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
 `endif
 
 module padctrl_assert #(
-  parameter integer Impl = `PRIM_DEFAULT_IMPL
+  parameter prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL
 ) (
   input                                       clk_i,
   input                                       rst_ni,
@@ -38,14 +38,14 @@
   `ASSUME(NMioRange_M, mio_sel < padctrl_reg_pkg::NMioPads, clk_i, !rst_ni)
   `ASSUME(NMioStable_M, ##1 $stable(mio_sel), clk_i, !rst_ni)
 
-  if (impl_e'(Impl) == ImplGeneric) begin : gen_mio_generic
+  if (Impl == ImplGeneric) begin : gen_mio_generic
     `ASSERT(MioWarl_A, padctrl.reg2hw.mio_pads[mio_sel].qe |=>
         !(|padctrl.mio_attr_q[mio_sel][padctrl_reg_pkg::AttrDw-1:6]),
         clk_i, !rst_ni)
     `ASSERT(MioAttr_A, padctrl.reg2hw.mio_pads[mio_sel].qe |=>
       mio_attr_o[mio_sel][5:0] == $past(padctrl.reg2hw.mio_pads[mio_sel].q[5:0]),
       clk_i, !rst_ni)
-  end else if (impl_e'(Impl) == ImplXilinx) begin : gen_mio_xilinx
+  end else if (Impl == ImplXilinx) begin : gen_mio_xilinx
     `ASSERT(MioWarl_A, padctrl.reg2hw.mio_pads[mio_sel].qe |=>
         !(|padctrl.mio_attr_q[mio_sel][padctrl_reg_pkg::AttrDw-1:2]),
         clk_i, !rst_ni)
@@ -63,14 +63,14 @@
 
   `ASSUME(NDioRange_M, dio_sel < padctrl_reg_pkg::NDioPads, clk_i, !rst_ni)
   `ASSUME(NDioStable_M, ##1 $stable(dio_sel), clk_i, !rst_ni)
-  if (impl_e'(Impl) == ImplGeneric) begin : gen_dio_generic
+  if (Impl == ImplGeneric) begin : gen_dio_generic
     `ASSERT(DioWarl_A, padctrl.reg2hw.dio_pads[dio_sel].qe |=>
         !(|padctrl.dio_attr_q[dio_sel][padctrl_reg_pkg::AttrDw-1:6]),
         clk_i, !rst_ni)
     `ASSERT(DioAttr_A, padctrl.reg2hw.dio_pads[dio_sel].qe |=>
       dio_attr_o[dio_sel][5:0] == $past(padctrl.reg2hw.dio_pads[dio_sel].q[5:0]),
       clk_i, !rst_ni)
-  end else if (impl_e'(Impl) == ImplXilinx) begin : gen_dio_xilinx
+  end else if (Impl == ImplXilinx) begin : gen_dio_xilinx
     `ASSERT(DioWarl_A, padctrl.reg2hw.dio_pads[dio_sel].qe |=>
         !(|padctrl.dio_attr_q[dio_sel][5:2]),
         clk_i, !rst_ni)
diff --git a/hw/ip/padctrl/rtl/padctrl.sv b/hw/ip/padctrl/rtl/padctrl.sv
index c6e84ee..2824779 100644
--- a/hw/ip/padctrl/rtl/padctrl.sv
+++ b/hw/ip/padctrl/rtl/padctrl.sv
@@ -8,11 +8,11 @@
 //
 
 `ifndef PRIM_DEFAULT_IMPL
-  `define PRIM_DEFAULT_IMPL integer'(prim_pkg::ImplGeneric)
+  `define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
 `endif
 
 module padctrl #(
-  parameter integer Impl = `PRIM_DEFAULT_IMPL
+  parameter prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL
 ) (
   input                                       clk_i,
   input                                       rst_ni,
@@ -35,10 +35,10 @@
   //////////////////////////////////////////////////////
 
   logic [padctrl_reg_pkg::AttrDw-1:0] warl_mask;
-  if (impl_e'(Impl) == ImplGeneric) begin : gen_generic
+  if (Impl == ImplGeneric) begin : gen_generic
     // all attributes supported
     assign warl_mask = padctrl_reg_pkg::AttrDw'(6'h3F);
-  end else if (impl_e'(Impl) == ImplXilinx) begin : gen_xilinx
+  end else if (Impl == ImplXilinx) begin : gen_xilinx
     // only OD and INV supported
     assign warl_mask = padctrl_reg_pkg::AttrDw'(2'h3);
   end else begin : gen_failure
diff --git a/hw/ip/padctrl/rtl/padring.sv b/hw/ip/padctrl/rtl/padring.sv
index 5e0a96a..9a3ac11 100644
--- a/hw/ip/padctrl/rtl/padring.sv
+++ b/hw/ip/padctrl/rtl/padring.sv
@@ -8,11 +8,11 @@
 //
 
 `ifndef PRIM_DEFAULT_IMPL
-  `define PRIM_DEFAULT_IMPL integer'(prim_pkg::ImplGeneric)
+  `define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
 `endif
 
 module padring #(
-  parameter integer Impl = `PRIM_DEFAULT_IMPL // this determines the pad implementation
+  parameter prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL // this determines the pad implementation
 ) (
   // pad input
   input wire                                   clk_pad_i,
diff --git a/hw/ip/prim/abstract/prim_clock_gating.sv b/hw/ip/prim/abstract/prim_clock_gating.sv
index 07cf223..7ffee23 100644
--- a/hw/ip/prim/abstract/prim_clock_gating.sv
+++ b/hw/ip/prim/abstract/prim_clock_gating.sv
@@ -6,11 +6,11 @@
 // "abstract module". This module is to be replaced by generated code.
 
 `ifndef PRIM_DEFAULT_IMPL
-  `define PRIM_DEFAULT_IMPL integer'(prim_pkg::ImplGeneric)
+  `define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
 `endif
 
 module prim_clock_gating #(
-  parameter integer Impl = `PRIM_DEFAULT_IMPL
+  parameter prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL
 ) (
   input        clk_i,
   input        en_i,
@@ -20,14 +20,14 @@
 
   import prim_pkg::*;
 
-  if (impl_e'(Impl) == ImplGeneric) begin : gen_generic
+  if (Impl == ImplGeneric) begin : gen_generic
     prim_generic_clock_gating u_impl_generic (
       .clk_i,
       .en_i,
       .test_en_i,
       .clk_o
     );
-  end else if (impl_e'(Impl) == ImplXilinx) begin : gen_xilinx
+  end else if (Impl == ImplXilinx) begin : gen_xilinx
     prim_xilinx_clock_gating u_impl_xilinx (
       .clk_i,
       .en_i,
diff --git a/hw/ip/prim/abstract/prim_flash.sv b/hw/ip/prim/abstract/prim_flash.sv
index f09fdef..0fc8152 100644
--- a/hw/ip/prim/abstract/prim_flash.sv
+++ b/hw/ip/prim/abstract/prim_flash.sv
@@ -6,11 +6,11 @@
 // "abstract module". This module is to be replaced by generated code.
 
 `ifndef PRIM_DEFAULT_IMPL
-  `define PRIM_DEFAULT_IMPL integer'(prim_pkg::ImplGeneric)
+  `define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
 `endif
 
 module prim_flash #(
-  parameter integer Impl = `PRIM_DEFAULT_IMPL,
+  parameter prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL,
 
   parameter int PagesPerBank = 256, // pages per bank
   parameter int WordsPerPage = 256, // words per page
@@ -43,7 +43,7 @@
 
   import prim_pkg::*;
 
-  if (impl_e'(Impl) == ImplGeneric || impl_e'(Impl) == ImplXilinx) begin : gen_flash
+  if (Impl == ImplGeneric || Impl == ImplXilinx) begin : gen_flash
     prim_generic_flash #(
       .PagesPerBank(PagesPerBank),
       .WordsPerPage(WordsPerPage),
diff --git a/hw/ip/prim/abstract/prim_pad_wrapper.sv b/hw/ip/prim/abstract/prim_pad_wrapper.sv
index 2584cdb..fb9d56d 100644
--- a/hw/ip/prim/abstract/prim_pad_wrapper.sv
+++ b/hw/ip/prim/abstract/prim_pad_wrapper.sv
@@ -7,11 +7,11 @@
 
 
 `ifndef PRIM_DEFAULT_IMPL
-  `define PRIM_DEFAULT_IMPL integer'(prim_pkg::ImplGeneric)
+  `define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
 `endif
 
 module prim_pad_wrapper #(
-  parameter int          Impl   = `PRIM_DEFAULT_IMPL,
+  parameter prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL,
   parameter int unsigned AttrDw = 6
 ) (
   inout  wire        inout_io, // bidirectional pad
@@ -25,7 +25,7 @@
   import prim_pkg::*;
 
   // The generic implementation is NOT synthesizable
-  if (impl_e'(Impl) == ImplGeneric) begin : gen_pad_generic
+  if (Impl == ImplGeneric) begin : gen_pad_generic
     prim_generic_pad_wrapper #(
       .AttrDw(AttrDw)
     ) i_pad_wrapper (
@@ -35,7 +35,7 @@
       .oe_i,
       .attr_i
     );
-  end else if (impl_e'(Impl) == ImplXilinx) begin : gen_pad_xilinx
+  end else if (Impl == ImplXilinx) begin : gen_pad_xilinx
     prim_xilinx_pad_wrapper #(
       .AttrDw(AttrDw)
     ) i_pad_wrapper (
diff --git a/hw/ip/prim/abstract/prim_ram_1p.sv b/hw/ip/prim/abstract/prim_ram_1p.sv
index 9da25f0..092bbed 100644
--- a/hw/ip/prim/abstract/prim_ram_1p.sv
+++ b/hw/ip/prim/abstract/prim_ram_1p.sv
@@ -6,11 +6,11 @@
 // "abstract module". This module is to be replaced by generated code.
 
 `ifndef PRIM_DEFAULT_IMPL
-  `define PRIM_DEFAULT_IMPL integer'(prim_pkg::ImplGeneric)
+  `define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
 `endif
 
 module prim_ram_1p #(
-  parameter integer Impl            = `PRIM_DEFAULT_IMPL,
+  parameter prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL,
 
   parameter int Width           = 32, // bit
   parameter int Depth           = 128,
@@ -33,7 +33,7 @@
 
   `ASSERT_INIT(paramCheckAw, Aw == $clog2(Depth))
 
-  if (impl_e'(Impl) == ImplGeneric || impl_e'(Impl) == ImplXilinx) begin : gen_mem_generic
+  if (Impl == ImplGeneric || Impl == ImplXilinx) begin : gen_mem_generic
     prim_generic_ram_1p #(
       .Width(Width),
       .Depth(Depth),
diff --git a/hw/ip/prim/abstract/prim_ram_2p.sv b/hw/ip/prim/abstract/prim_ram_2p.sv
index 3f25fe7..e906592 100644
--- a/hw/ip/prim/abstract/prim_ram_2p.sv
+++ b/hw/ip/prim/abstract/prim_ram_2p.sv
@@ -7,11 +7,11 @@
 
 
 `ifndef PRIM_DEFAULT_IMPL
-  `define PRIM_DEFAULT_IMPL integer'(prim_pkg::ImplGeneric)
+  `define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
 `endif
 
 module prim_ram_2p #(
-  parameter integer Impl  = `PRIM_DEFAULT_IMPL,
+  parameter prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL,
 
   parameter int Width = 32, // bit
   parameter int Depth = 128,
@@ -39,7 +39,7 @@
 
   `ASSERT_INIT(paramCheckAw, Aw == $clog2(Depth))
 
-  if (impl_e'(Impl) == ImplGeneric) begin : gen_mem_generic
+  if (Impl == ImplGeneric) begin : gen_mem_generic
     prim_generic_ram_2p #(
       .Width(Width),
       .Depth(Depth)
@@ -57,7 +57,7 @@
       .b_wdata_i,
       .b_rdata_o
     );
-  end else if (impl_e'(Impl) == ImplXilinx) begin : gen_mem_xilinx
+  end else if (Impl == ImplXilinx) begin : gen_mem_xilinx
     prim_xilinx_ram_2p #(
       .Width(Width),
       .Depth(Depth)
diff --git a/hw/ip/prim/abstract/prim_rom.sv b/hw/ip/prim/abstract/prim_rom.sv
index 51600b7..bb49be1 100644
--- a/hw/ip/prim/abstract/prim_rom.sv
+++ b/hw/ip/prim/abstract/prim_rom.sv
@@ -6,10 +6,10 @@
 // "abstract module". This module is to be replaced by generated code.
 
 `ifndef PRIM_DEFAULT_IMPL
-  `define PRIM_DEFAULT_IMPL integer'(prim_pkg::ImplGeneric)
+  `define PRIM_DEFAULT_IMPL prim_pkg::ImplGeneric
 `endif
 module prim_rom #(
-  parameter integer Impl  = `PRIM_DEFAULT_IMPL,
+  parameter prim_pkg::impl_e Impl = `PRIM_DEFAULT_IMPL,
   parameter int Width = 32,
   parameter int Depth = 2048, // 8kB default
   parameter int Aw    = $clog2(Depth)
@@ -24,7 +24,7 @@
 
   import prim_pkg::*;
 
-  if (impl_e'(Impl) == ImplGeneric) begin: gen_mem_generic
+  if (Impl == ImplGeneric) begin: gen_mem_generic
     prim_generic_rom #(
       .Width(Width),
       .Depth(Depth)
@@ -36,7 +36,7 @@
       .dout_o,
       .dvalid_o
     );
-  end else if (impl_e'(Impl) == ImplXilinx) begin: gen_rom_xilinx
+  end else if (Impl == ImplXilinx) begin: gen_rom_xilinx
     prim_xilinx_rom #(
       .Width(Width),
       .Depth(Depth)
diff --git a/hw/top_earlgrey/top_earlgrey.core b/hw/top_earlgrey/top_earlgrey.core
index 15128fd..5905d78 100644
--- a/hw/top_earlgrey/top_earlgrey.core
+++ b/hw/top_earlgrey/top_earlgrey.core
@@ -40,22 +40,22 @@
     paramtype: vlogdefine
   # For value definition, please see ip/prim/rtl/prim_pkg.sv
   PRIM_DEFAULT_IMPL:
-    datatype: int
+    datatype: str
     paramtype: vlogdefine
-    description: Primitives implementation to use. 0=Generic, 1=Xilinx
-    default: 0 # generic
+    description: Primitives implementation to use, e.g. "prim_pkg::ImplGeneric".
+    default: prim_pkg::ImplGeneric
 
 targets:
   default: &default_target
     filesets:
       - files_rtl_generic
     parameters:
-      - PRIM_DEFAULT_IMPL=0 # generic
+      - PRIM_DEFAULT_IMPL=prim_pkg::ImplGeneric
     toplevel: top_earlgrey
   sim:
     default_tool: icarus
     filesets:
       - files_rtl_generic
     parameters:
-      - PRIM_DEFAULT_IMPL=0 # generic
+      - PRIM_DEFAULT_IMPL=prim_pkg::ImplGeneric
     toplevel: top_earlgrey
diff --git a/hw/top_earlgrey/top_earlgrey_artys7-50.core b/hw/top_earlgrey/top_earlgrey_artys7-50.core
index ca784f8..9864d41 100644
--- a/hw/top_earlgrey/top_earlgrey_artys7-50.core
+++ b/hw/top_earlgrey/top_earlgrey_artys7-50.core
@@ -32,9 +32,9 @@
     paramtype: vlogdefine
   # For value definition, please see ip/prim/rtl/prim_pkg.sv
   PRIM_DEFAULT_IMPL:
-    datatype: int
+    datatype: str
     paramtype: vlogdefine
-    description: Primitives implementation to use. 0=Generic, 1=Xilinx
+    description: Primitives implementation to use, e.g. "prim_pkg::ImplGeneric".
 
 targets:
   synth:
@@ -45,7 +45,7 @@
     toplevel: top_earlgrey_artys7
     parameters:
       - SRAM_INIT_FILE
-      - PRIM_DEFAULT_IMPL=1 # xilinx
+      - PRIM_DEFAULT_IMPL=prim_pkg::ImplXilinx
     tools:
       vivado:
         part: "xc7s50csga324-1" # Arty S7-50
diff --git a/hw/top_earlgrey/top_earlgrey_nexysvideo.core b/hw/top_earlgrey/top_earlgrey_nexysvideo.core
index d163e4a..c9d0529 100644
--- a/hw/top_earlgrey/top_earlgrey_nexysvideo.core
+++ b/hw/top_earlgrey/top_earlgrey_nexysvideo.core
@@ -33,9 +33,9 @@
     paramtype: vlogdefine
   # For value definition, please see ip/prim/rtl/prim_pkg.sv
   PRIM_DEFAULT_IMPL:
-    datatype: int
+    datatype: str
     paramtype: vlogdefine
-    description: Primitives implementation to use. 0=Generic, 1=Xilinx
+    description: Primitives implementation to use, e.g. "prim_pkg::ImplGeneric".
 
 targets:
   synth:
@@ -46,7 +46,7 @@
     toplevel: top_earlgrey_nexysvideo
     parameters:
       - ROM_INIT_FILE
-      - PRIM_DEFAULT_IMPL=1 # xilinx
+      - PRIM_DEFAULT_IMPL=prim_pkg::ImplXilinx
     tools:
       vivado:
         part: "xc7a200tsbg484-1" # Nexys Video
diff --git a/hw/top_earlgrey/top_earlgrey_usb_nexysvideo.core b/hw/top_earlgrey/top_earlgrey_usb_nexysvideo.core
index 79a6f2e..edbc907 100644
--- a/hw/top_earlgrey/top_earlgrey_usb_nexysvideo.core
+++ b/hw/top_earlgrey/top_earlgrey_usb_nexysvideo.core
@@ -31,9 +31,9 @@
     default: "../../../../../sw/examples/hello_usbdev/hello_usbdev.vmem"
     paramtype: vlogdefine
   PRIM_DEFAULT_IMPL:
-    datatype: int
+    datatype: str
     paramtype: vlogdefine
-    description: Primitives implementation to use. 0=Generic, 1=Xilinx
+    description: Primitives implementation to use, e.g. "prim_pkg::ImplGeneric".
 
 targets:
   synth:
@@ -44,7 +44,7 @@
     toplevel: top_earlgrey_usb_nexysvideo
     parameters:
       - SRAM_INIT_FILE
-      - PRIM_DEFAULT_IMPL=1 # xilinx
+      - PRIM_DEFAULT_IMPL=prim_pkg::ImplXilinx
     tools:
       vivado:
         part: "xc7a200tsbg484-1" # Nexys Video
diff --git a/hw/top_earlgrey/top_earlgrey_usb_verilator.core b/hw/top_earlgrey/top_earlgrey_usb_verilator.core
index b2aa8c4..00ccd8b 100644
--- a/hw/top_earlgrey/top_earlgrey_usb_verilator.core
+++ b/hw/top_earlgrey/top_earlgrey_usb_verilator.core
@@ -21,14 +21,14 @@
 parameters:
   # For value definition, please see ip/prim/rtl/prim_pkg.sv
   PRIM_DEFAULT_IMPL:
-    datatype: int
+    datatype: str
     paramtype: vlogdefine
-    description: Primitives implementation to use. 0=Generic, 1=Xilinx
+    description: Primitives implementation to use, e.g. "prim_pkg::ImplGeneric".
 
 targets:
   sim:
     parameters:
-      - PRIM_DEFAULT_IMPL=0 # generic
+      - PRIM_DEFAULT_IMPL=prim_pkg::ImplGeneric
     default_tool: verilator
     filesets:
       - files_sim_verilator
diff --git a/hw/top_earlgrey/top_earlgrey_verilator.core b/hw/top_earlgrey/top_earlgrey_verilator.core
index d1cd469..b338e61 100644
--- a/hw/top_earlgrey/top_earlgrey_verilator.core
+++ b/hw/top_earlgrey/top_earlgrey_verilator.core
@@ -22,9 +22,9 @@
 parameters:
   # For value definition, please see ip/prim/rtl/prim_pkg.sv
   PRIM_DEFAULT_IMPL:
-    datatype: int
+    datatype: str
     paramtype: vlogdefine
-    description: Primitives implementation to use. 0=Generic, 1=Xilinx
+    description: Primitives implementation to use, e.g. "prim_pkg::ImplGeneric".
   RVFI:
     datatype: bool
     paramtype: vlogdefine
@@ -33,7 +33,7 @@
 targets:
   sim:
     parameters:
-      - PRIM_DEFAULT_IMPL=0 # generic
+      - PRIM_DEFAULT_IMPL=prim_pkg::ImplGeneric
       - RVFI=true
     default_tool: verilator
     filesets: