Search code examples
vhdl

VHDL : Assign specific wires from a bus?


I'm fairly new to VHDL: is there a way to select specific elements from a larger sized vector to pass as a smaller vector to a port? I have the following example to demonstrate my problem:

-- tst.vhd: a 4 input AND gate
library ieee;
use ieee.std_logic_1164.all;

entity tst is
    port(x : in  std_logic_vector(3 downto 0);
         y : out std_logic);
end tst;

architecture dataflow of tst is
begin
    y <= x(0) and x(1) and x(2) and x(3);
end dataflow;

-- foo.vhd: demonstrate the issue
library ieee;
use ieee.std_logic_1164.all;

entity foo is
end foo;

architecture sim of foo is
    signal data : std_logic_vector(15 downto 0) := x"FA01";
    signal y : std_logic;
begin
    uut : entity work.foo(sim)
          port map(input => data(3, 5, 9, 11), y => y); -- problematic line
    process begin
        wait for 10 ns;
        report "data: " & to_string(data(3, 5, 9, 11)); -- problematic line
        report "y: "    & to_string(y);
        wait;
    end process;
end sim;

As you can see I only want lines numbered 3, 5, 9, 11 from the 16-bit bus name "data" to be converted into another 4-bit vector. However I get the following compilation error:

ghdl -a --std=08 tst.vhd
ghdl -a --std=08 foo.vhd
foo.vhd:12:41: number of indexes mismatches array dimension
                  port map(input => data(3, 5, 9, 11), y => y);
                                        ^
foo.vhd:15:49: number of indexes mismatches array dimension
                report "data: " & to_string(data(3, 5, 9, 11));
                                                ^
make: *** [Makefile:3: all] Error 1

Is there a proper way to do this?


Solution

  • You can concatenate all "snippets" as you like to an intermediate signal.

    architecture sim of foo is
        signal data : std_logic_vector(15 downto 0) := x"FA01";
        signal x : std_logic_vector(3 downto 0);
        signal y : std_logic;
    begin
        x <= data(3) & data(5) & data(9) & data(11);
        uut : entity work.tst(dataflow)
              port map(x => x, y => y);
        process begin
            wait for 10 ns;
            report "data: " & to_string(x);
            report "y: "    & to_string(y);
            wait;
        end process;
    end sim;
    

    More issues of your source, already correct above:

    • Architecture and entity of your unit under test were the ones of the test bench, not the entity you want to test.
    • The input signal had changed names.