2014-12-18 4 views
0

Выход определенного объекта зависит от его собственного местоположения в векторе и всех входах. Самый простой способ реализовать это, по-видимому, является циклом for-loop. Однако Quartus II 13.0sp1 терпит неудачу на втором для цикла:For-loop in another for-loop VHDL

VHDL syntax error at mcve.vhd(24) near text "IN"; expecting "(", or "'", or "." 

я бы испортил синтаксис, но я уверен, что VHDL способен зацикливание в цикле.

Какова правильная реализация цикла for for loop? Вот что я получил до сих пор.

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL; 

TYPE ANAT_SLV16 IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(15 DOWNTO 0); 

ENTITY mcve IS 
    GENERIC(
     PORTS : POSITIVE := 256; 
     HPORTS : POSITIVE := 128 
    ); 
PORT(
    X : IN ANAT_SLV16(PORTS - 1 DOWNTO 0); 
    Y : OUT ANAT_SLV16(HPORTS - 1 DOWNTO 0); 
    ); 
END mcve; 

ARCHITECTURE loops OF mcve IS 
    SIGNAL to_Y : ANAT_SLV16(HPORTS - 1 DOWNTO 0) := (others -> '0'); 
BEGIN 

    gen : FOR i IN 0 TO HPORTS - 1 GENERATE 
     FOR j IN 0 TO PORTS - 1 GENERATE -- error near text "IN"; expecting "(", or "'", or "." 
      to_Y((i)) <= to_Y((i)) + X(j); 
     END GENERATE; 
    END GENERATE; 

    Y <= to_Y; 

END loops; 
+2

Вам не следует указывать метку во втором цикле? – grorel

+0

Объявление типа должно быть в пакете, видимом в предложении use. В конце строки в конце объявления 'y' есть дополнительная точка с запятой. '->' должно быть '=>', а выражение по умолчанию должно быть '(others => (others => '0'))' - 'to_y' - это массив std_logic_vector. Чтобы обе границы диапазонов имели одинаковый базовый тип, эти дженерики должны быть «естественными» (правые границы 0). Чтобы использовать оператор '' + "' из пакета numeric_std, операнды должны быть преобразованы в unsigned, а результат - в std_logic_vector. Затем MVCe является полным и проверяемым и фиксируемым с ярлыком Брайана. – user1155120

+0

Я сделал поспешный MCVE и пропустил ошибки. Однако проблема очевидна. Я полностью согласен с пакетом, оригинал построен таким образом. Тем не менее, я чувствую, что для MCVE он должен быть более компактным и не иметь подобных конструкций. – Mast

ответ

3

Это не петли. Это инструкции FOR..GENERATE, и каждый из них нуждается в собственном ярлыке.

gen : FOR i IN 0 TO HPORTS - 1 GENERATE 
    gen2: FOR j IN 0 TO PORTS - 1 GENERATE 
     to_Y((i)) <= to_Y((i)) + X(j); 
    END GENERATE; 
END GENERATE; 

Надеюсь, у вас есть хорошее ощущение размера аппаратного обеспечения, которое это создаст.

+0

Вау, это была глупая ошибка. И да, окончательный код будет использовать тысячи LE. Я только создаю прототип, следующий парень должен будет беспокоиться об оптимизации. – Mast

+1

Хотя это исправит вашу синтаксическую ошибку, ваш дизайн все равно не сработает. 'to_Y ((i)) <= to_Y ((i)) + X (j);' создаст комбинаторный цикл (и многочисленные ошибки присваивания для 'to_Y (i)'), поскольку он не находится в тактическом процессе. Если вы переключитесь на циклы внутри тактового процесса, ваш внутренний цикл ничего не сделает, потому что только последнее присваивание 'to_Y (i) <= to_Y (i) + X (PORTS-1);' вступит в силу для каждый 'i', потому что to_Y является сигналом. Это один из тех редких случаев, когда я предлагаю использовать переменную новичку. – QuantumRipple

+0

Кроме того, «тысячи LE» являются преуменьшением примерно на два порядка. Если они реализованы с явно предполагаемой функциональностью и значениями по умолчанию «ПОРТЫ» и «ХОРОШИЕ», будут установлены 16-кратные трехъядерные 16-разрядные сумматоры (более эффективные с современными LUT6, чем с двойными сумматорами), которые будут потреблять около 250 тыс. LUT6. Самая маленькая 7-серия FPGA с 250k + LUT - это 7k410t, что является абсолютно огромным FPGA для такой простой логики. Если вы просто пытаетесь сделать доказательство концепции в симуляции, это прекрасно, но если вы хотите сделать физический прототип, вам сначала нужно будет сделать ** некоторую ** оптимизацию. – QuantumRipple