2015-07-10 2 views
1

У меня в основном есть два вектора (тип: целое, подписанное, неподписанное, std_logic_vector, на самом деле не имеет значения для элементализации).Сумма динамического количества векторов

Vector 1 имеет статический размер 16 (равный 1 слову). Вектор 2 имеет динамический размер X * 16 (равно X словам) X - динамический параметр.

Теперь я хочу, чтобы иметь конструкцию, где я могу подвести X слова из вектора 2 в зависимости от параметра X.

STH. например:

vector_1 <= for i in 0 to X generate 
      vector_2(X*16+15 downto X*16) + 
      end generate; 

Любой может представить себе что-то подобное в VHDL?

Приветствия, Штеффен

EDIT: Может быть, чтобы сделать его более ясным, что я хочу иметь:

accumulated_data <= std_logic_vector(signed(data_vector(0*16+15 downto 0*16)) + 
             signed(data_vector(1*16+15 downto 1*16)) + 
             ...                                        
             signed(data_vector(X*16+15 downto X*16))   
            ); 

X является статическим на синтезаторе.

+0

Должно ли 'X' быть в состоянии изменить во время выполнения? У вас не может быть синтезируемой конструкции VHDL, размер которой динамичен во время выполнения. –

+0

нет, X статичен при синтезе – Spyro

+0

Насколько велика была бы 'X'? Можно ли использовать ресурс блока памяти Vector 2? –

ответ

2

для вашего data_vector, я хотел бы использовать пользовательский тип, что-то вроде:

type WORD_ARRAY_type is array (integer range <>) of signed (15 downto 0); 
signal data_vector : WORD_ARRAY_type (2 downto 0); 

Ваша сумма является то более удобным для чтения, что-то вроде:

vector1 <= data_vector (0) + data_vector (1) + data_vector (2); 

Код однотактный будет что-то например:

process (clk) 
    variable sum : signed (vector1'range) := to_signed(0, vector1'length); 
begin 
    if (rising_edge(clk)) then 
     sum := to_signed(0, vector1'length); 
     for i in 0 to (data_vector'length - 1) loop 
      sum := sum + data_vector(i); 
     end loop; 
     vector1 <= sum; 
    end if; 
end process; 

Хотя это зависит от инструментов для интерпретации это как одноцилиндровая многозадачная сумма, которой они не могут.

Однако сумматор с 8 входами будет очень медленным. Мой подход будет примерно таким:

  • Счетчик, установленный для остановки после достижения X.
  • Аккумулятор, питаемый мультиплексором переменного размера.
  • Входы мультиплексора, подключенные к Vector 1 и Vector 2, управляемые счетчиком.
  • Государственная машина или аналогичная для управления аккумулятором на основе подсчета (т. Е. Прекращение добавления один раз X).
+0

Я думаю, вам нужно заменить (vector2'length - 1) в вашем цикле параметром (X-1). Мне нравится подход с пользовательским типом. Престижность для этого! :) – Spyro

+0

по вашему вопросу, 'vector2'length' будет таким же, как' X'. Если вы используете атрибуты, то «X» не обязательно должен быть общим в сущности. Пользовательский тип действительно полезен при изменении ширины битов ваших данных. –

+0

Если я возьму свой пример, vector_2'length будет X * 16, что приведет к ошибке вне диапазона для data_vector (i). Я считаю, что можно написать (длина вектора2/длина1). Означает ли это, что это более ясно, что я имею в виду? Как вы поняли мой вопрос в этой проблеме? – Spyro

0

решаемые его, а также:

process(clk) 
    variable TMP : std_logic_vector(accumulated_data'range) := (others => '0'); 
begin 
    if(rising_edge(clk)) then 
     for i in 0 to X-1 loop 
      TMP := std_logic_vector( signed(TMP) + 
             signed(data_vector(i*25+24 downto i*25)) 
            ); 
     end loop; 
     accumulated_data <= TMP; 
    end if; 
end process; 
+0

Работает в первый раз, но на следующих часах TMP сохраняет свое значение от предыдущего выполнения. Инициализация объекта переменной происходит только при разработке переменной. Для процесса это происходит один раз в начале времени - в подпрограмме (см. Решение Мортена), это происходит каждый раз, когда вызывается функция. В вашем процессе вместо инициализации TMP в его объявлении вам нужно сделать это сразу после if raise_edge (Clk) с явным назначением переменной. –

1

Функция может быть использована, чтобы сделать сумму, где Х определяется путем простой длины деления:

function vector_sum(vec_2 : std_logic_vector; len_1 : natural) return std_logic_vector is 
    variable res : std_logic_vector(len_1 - 1 downto 0) := (others => '0'); 
begin 
    for i in 0 to vec_2'length/len_1 - 1 loop 
    res := std_logic_vector(signed(res) + 
          signed(vec_2((i + 1) * len_1 - 1 + vec_2'right downto 
             i * len_1 + vec_2'right))); 
    end loop; 
    return res; 
end function; 

Функция затем используется как :

vector_1 <= vector_sum(vector_2, vector_1'length); 
+0

Для моего собственного понимания, по существу, по сути, тот же код в функцию, отличающуюся от того, что она является частью «основного» rtl, кроме каких-либо преимуществ повторного использования? –

+0

Функция не требует типа 'WORD_ARRAY_type' и допускает одновременное назначение' vector_2', поэтому без необходимости процесса. Таким образом, использование функции, принимающей аргумент 'std_logic_vector', является решением, которое ближе к типам и примеру кода в вопросе. –

+0

ОК, спасибо. Я задавался вопросом, может ли функция помочь инструменту синтеза сделать правильную вещь в комментарии JimLewis –

Смежные вопросы