Nektarios
Nektarios

Reputation: 10371

Use a generic to determine (de)mux size in VHDL?

I want to use a generic 'p' to define how many outputs a demux will have. Input and all outputs are 1 bit. The outputs, control, and input can be something simple like:

 signal control : std_logic_vector(log 2 p downto 0); -- I can use a generic for the log2..
 signal input : std_logic;
 signal outputs : std_logic_vector(p-1 downto 0);

But what would the mux implementation code be? Is it even possible?

Upvotes: 4

Views: 3603

Answers (3)

Martin Thompson
Martin Thompson

Reputation: 16792

No generics required:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity demux is
    port(
        control : in unsigned;
        input   : in std_logic;
        outputs : out std_logic_vector
        );
end entity demux;

architecture rtl of demux is
    -- Check size of input vectors
    assert 2**control'length = outputs'length 
           report "outputs length must be 2**control length" 
           severity failure;
    -- actually do the demuxing - this will cause feedback latches to be inferred
    outputs(to_integer(unsigned(control)) <= input;

end architecture;

(Untested, just typed in off the top of my head...)

This will infer latches though - is that what you want?

Upvotes: 3

Charles Steinkuehler
Charles Steinkuehler

Reputation: 3365

You need to pass both the number of outputs and the size of the control array as generics, unless you are always using powers of two.

Outside of your (de)mux module (ie: when you instantiate), you can use code to calculate the number of bits for the control bus. I have a function in a common package I use to initialize various configuration constants and generics that get passed to code similar to your (de)mux application:

-- Calculate the number of bits required to represent a given value
function NumBits(val : integer) return integer is
    variable result : integer;
begin
    if val=0 then
        result := 0;
    else
        result  := natural(ceil(log2(real(val))));
    end if;
    return result;
end;

...which allows you to do things like:

constant NumOut : integer := 17;
signal CtrlBus  : std_logic_vector(NumBits(NumOut)-1 downto 0);

my_mux : demux
generic map (
    NumOut  => NumOut,
    NumCtrl => NumBits(NumOut) )
port map (
    control => CtrlBus,
...
...

Upvotes: 0

Philippe
Philippe

Reputation: 3730

You need to feed log_p as generic and compute p as you go.

library ieee;
use ieee.std_logic_1164.all;
entity demux is
    generic (
        log_p: integer);
    port(
        control : in std_logic_vector(log_p downto 0);
        input :in std_logic;
        outputs : out std_logic_vector(2**log_p - 1 downto 0)
        );
end entity demux;

Upvotes: 0

Related Questions