JamesC
JamesC

Reputation: 11

in VHDL, how to assign list of output ports to an array?

I have an entity that has hundreds of output such as tap0(15 downto 0), tap1(15 downto 0), ..., tap200(15 downto 0)

For each iteration, I would like to assign four of those outputs to a complex multiplier entity that has four inputs.

For example: on 1st iteration:

mult_in_A <= tap0;
mult_in_B <= tap1;
mult_in_C <= tap2;
mult_in_D <= tap3;

on 2nd iteration:

mult_in_A <= tap4;
mult_in_B <= tap5;
mult_in_C <= tap6;
mult_in_D <= tap7;

On 3rd iteration:

mult_in_A <= tap8;
mult_in_B <= tap9;
mult_in_C <= tap10;
mult_in_D <= tap11;

and so on...

How do I make the code above more efficient by having some kind of for loop and putting those output ports to an array? So that I can write the code as following:

mult_in_A <= tap_array(i);
mult_in_A <= tap_array(i+1);
mult_in_A <= tap_array(i+2);
mult_in_A <= tap_array(i+3);

Updated:

Here is the code example

ARCHITECTURE rtl_syn OF fir_filter_cntl IS

COMPONENT delay_line
PORT(
    aclr        : IN STD_LOGIC;
    clock       : IN STD_LOGIC;
    clken       : IN STD_LOGIC;
    shiftin     : IN STD_LOGIC_VECTOR (15 DOWNTO 0);
    shiftout    : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
    taps0x      : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
    taps1x      : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
    taps2x      : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
    taps3x      : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
    ...
    taps128x    : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
    taps129x    : OUT STD_LOGIC_VECTOR (15 DOWNTO 0));
END COMPONENT;

TYPE samples IS array (0 to 129) of std_logic_vector(15 downto 0);
SIGNAL sample_i: samples;

BEGIN

delay_line_i1 : delay_line
    PORT MAP (
    aclr        => rx_reset,
    clock       => rx_clock,
    clken       => i_clken,
    shiftin     => i_sample,
    shiftout    => open,
    taps0x      => sample_i(0),  -- <- this doesn't work. In simulation,
                                 -- I observed taps0x output has some valid
                                 -- values, but sample_i's value is unknown
    taps1x      => sample_i(1),
    taps2x      => sample_i(2),
    ...
    taps129x    => sample_i(129));

Then down below in some process I have the following:

sample_counter      <= (others => '0');

CASE device_number IS
    WHEN "000" =>
        complex_mult_0I_in  <= sample_i(conv_integer(sample_counter+0)); 
        complex_mult_1I_in  <= sample_i(conv_integer(sample_counter+1));
        complex_mult_2I_in  <= sample_i(conv_integer(sample_counter+2));
        complex_mult_3I_in  <= sample_i(conv_integer(sample_counter+3));

Several questions:
1. Why did the following port assignment work? taps0x => sample_i(0)
2. How can I use for..loop or for..generate to simplify the following codes?

taps0x => sample_i(0),
taps1x => sample_i(1), 
taps2x => sample_i(2),
taps3x => sample_i(3),
taps4x => sample_i(4), 
taps5x => sample_i(5),
and so on.

Upvotes: 1

Views: 2283

Answers (1)

JHBonarius
JHBonarius

Reputation: 11291

Well, you did good with type sample... so why not use that on the interface?

example:

-- custom package
library ieee;

package custom_types is
    use ieee.std_logic_1164.all;
    type std_logic_vector_vector is array (natural range <>) of std_logic_vector;
end package;

-- your component... simplified
library ieee;
use ieee.std_logic_1164.all;
use work.custom_types.all;

entity delay_line is
    port(
        -- note: 130 does not divide by 4
        tapsx : out std_logic_vector_vector(0 to 127)(15 downto 0)
    );
end entity;

architecture empty of delay_line is begin end architecture;

-- some entity using your component
entity use_delay_line is end entity;

library ieee;

architecture rtl of use_delay_line is
    use work.custom_types.all;
    signal tapsx : std_logic_vector_vector(0 to 127)(15 downto 0);
    use ieee.std_logic_1164.all;
    signal mult_a, mult_b, mult_c, mult_d : std_logic_vector(15 downto 0);
begin
    delay_line_inst : entity work.delay_line
        port map(
            tapsx => tapsx
            );

    process
    begin
        for it in 0 to 31 loop
            mult_a <= tapsx(it*4);
            mult_b <= tapsx(it*4+1);
            mult_c <= tapsx(it*4+2);
            mult_d <= tapsx(it*4+3);
            wait for 10 ns;
        end loop;
        wait;
    end process;
end architecture;

Upvotes: 0

Related Questions