Search code examples
vhdlgeneric-programming

"template" VHDL entities


This has me bugging for quite some time, but is it possible to describe entities in VHDL similar to how templates work in C++ (or to lesser extend generics?). Simply leaving the actual port types to be only decided during synthesize/compilation?

An example would be a multiplexer, say I have a 4 input multiplexer, now I have several bus sizes I use this multiplexer for, -4,6,7,8-. Currently I wrote a different multiplexer for each different bus size; however the output is simply one of the chosen inputs forwarded, and is thus of the same type as the bus.

This seems overly redundant and error prone (choose correct multiplexer at correct times, keep them all in line, update them as I change the bus size). Is there no way to parameterize this?

non generic version below to show the idea.

entity mux_6bit_4input is
    port (  input_0 : in    std_logic_vector (5 downto 0);
        input_1 : in    std_logic_vector (5 downto 0);
        input_2 : in    std_logic_vector (5 downto 0);
        input_3 : in    std_logic_vector (5 downto 0);
        sel : in    std_logic_vector (1 downto 0);
        output  : out   std_logic_vector (5 downto 0)
    );
end entity mux_6bit_4input;

Solution

  • Maybe I misunderstood the question, but doesn't the common solution using generics solve your problem?

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity mux_4x1 is
        generic (
            DATA_WIDTH: integer := 8
        );
        port (
            input_0: in std_logic_vector(DATA_WIDTH-1 downto 0);
            input_1: in std_logic_vector(DATA_WIDTH-1 downto 0);
            input_2: in std_logic_vector(DATA_WIDTH-1 downto 0);
            input_3: in std_logic_vector(DATA_WIDTH-1 downto 0);
            sel: in std_logic_vector (1 downto 0);
            output: out std_logic_vector(DATA_WIDTH-1 downto 0)
        );
    end;
    
    architecture behavior of mux_4x1 is
    begin
        output <=
            input_0 when sel = "00" else
            input_1 when sel = "01" else
            input_2 when sel = "10" else
            input_3;
    end;
    

    Another solution, if you want to keep things really generic, is to use the cool generic types in VHDL-2008. My simulator doesn't yet support this feature, so here's an example from the excellent book VHDL 2008: Just the New Stuff:

    entity generic_mux2 is
        generic (type data_type);
        port (
            sel: in bit;
            a, b: in data_type;
            z: out data_type
        );
    end;
    
    architecture rtl of mux2 is
    begin
        z <= a when sel = '0' else b;
    end;