Search code examples
genericsvhdlverilog

Instantiate VHDL in Verilog with generics containing std_logic


I am looking to replace some generic synchroniser code in a Verilog module (for this reason). The code a standard 2-flop synchroniser.

always @ (posedge clk_i or posedge rst)
begin
  if (rst)
    begin
      rx_sync_tmp <= 1'b1;
      rx_sync     <= 1'b1;
    end
  else
    begin
      rx_sync_tmp <= rx_i;
      rx_sync     <= rx_sync_tmp;
    end
end

The entity declaration in VHDL is also straightforward:

entity synchroniser_d_flip_flop_n is

    generic(
        NUM_STAGES          : natural   := 2;
        RESET_ACTIVE_STATE  : std_logic := '1';
        DEFAULT_AFTER_RESET : std_logic := '0'
    );

    port(
        clk_i       : in  std_logic;
        reset_i     : in  std_logic; 
      d_i           : in  std_logic;
        q_o         : out std_logic
    );

end synchroniser_d_flip_flop_n;

But if I attempt to instantiate this in verilog the obvious way:

synchroniser_d_flip_flop_n #(2, 1, 1) rx_sync_block(
    clk_i,
    rst, 
    rx_i,
    rx_sync
    );

Altera Quartus-II 15.0.2 gives the following error (target is MAX10):

Error (10517): VHDL type mismatch error at synchroniser_d_flip_flop.vhd(9): std_logic type does not match integer literal
Error (10517): VHDL type mismatch error at synchroniser_d_flip_flop.vhd(10): std_logic type does not match integer literal

That is, it appears not to accept 1 as std_logic.

Xilinx seems to suggest that VHDL generics containing std_logic are not possible to instantiate in Verilog:

Generics (Parameters) Mapping Following VHDL generic types (and their Verilog equivalents) are supported.

 integer
 real
 string
 boolean

Note Any other generic type found on mixed language boundary is considered an error.


tl;dr

Is there a standard way to instantiate VHDL generics containing std_logic in a Verilog file? If not, what might be suggested as a workaround?


Solution

  • There's no standard - you'll have to check your simulator docs. The Cadence docs say that "The LSB of the Verilog integer parameter is mapped to a single-bit std_logic generic". The relevant table rather unhelpfully refers to SV, but I'm pretty sure that this will also work for plain Verilog.

    The MoldelSim/QuestaSim docs say that you can instantiate a VHDL design unit in Verilog or SV if "The generics are of type bit, bit_vector, integer, real, std_logic, std_logic_vector, vl_logic, vl_logic_vector, time, physical, enumeration, or string".

    isim has always been a bit of a train wreck - are they still using it in Vivado? I'd rewrite the VHDL to take an integer generic if you're stuck with it.