Цикл ВДХЛ с переменной вне процесса (как быть)

Как я могу избежать переменной в этом цикле (вне процесса)?

variable var1 : std_logic_vector (ADRESS_WIDTH-1 downto 0) := (others => '0');

        for i in 0 to ADRESS_WIDTH-2 loop
            var1 := var1 + '1';
            with r_addr select
             fifo_data_out <= array_reg(i) when var1,
        end loop;
        array_reg(ADRESS_WIDTH-1) when others;

Эта версия (в процессе) тоже неверна - синтаксические ошибки

process (r_addr, r_addr1, fifo_data_out, array_reg, r_data1)
variable var1 : std_logic_vector (ADRESS_WIDTH-1 downto 0) := (others => '0');

begin

case r_addr is
    when "0000000000" => fifo_data_out <= array_reg(0);
        for i in 1 to ADRESS_WIDTH-2 loop
            when var1 => fifo_data_out <= array_reg(i);
            var1 := var1 + '1';
        end loop;
     when others => fifo_data_out <= array_reg(ADRESS_WIDTH-1);
end case;

person xornonop    schedule 17.06.2013    source источник
comment
Поправьте меня если я ошибаюсь. Разве 'var1' не всегда будет != '0000...' в строке 'fifo_data_out ‹= array_reg(i) когда var1' ?   -  person Thanushan    schedule 17.06.2013
comment
Я думаю, вы правы - этот код является черновиком, но я не могу понять, как его правильно реализовать :)   -  person xornonop    schedule 17.06.2013
comment
В этом есть много вещей, которые заставляют меня слегка съежиться, ваш процесс должен иметь только то, от чего он зависит в списке чувствительности, поэтому, если вы не хотите, чтобы он корректировался каждый раз, когда изменения array_reg не помещают его туда, а что такое r_data1, его нигде нет даже в вашем процессе. Кроме того, что вы пытаетесь сделать, это похоже на блок регистрации мультиплексирования, но я не уверен на 100%. Ваш случай, вероятно, должен быть чем-то более конкретным (т.е. каждый элемент случая является статическим, а не var1) s.t. вы не создаете ненужное оборудование в процессе работы. И это только то, что я пока замечаю.   -  person Jeff Langemeier    schedule 17.06.2013
comment
Кроме того, если вы просто просматриваете список регистров в массиве, просто увеличьте r_address, а когда он достигнет другого состояния, сбросьте r_address на 0x000, если это действительно базовый кольцевой буфер, это будет ваш лучший подход . Я могу превратить это в ответ, если вы подтвердите мое подозрение в том, что вы пытаетесь реализовать. Кроме того, я только что заметил, что вы делаете что-то действительно очень неправильно с вашим оператором for/embedded-when для var1, каждый вложенный шаг должен быть закрыт, поэтому ваш синтаксис просто не работает.   -  person Jeff Langemeier    schedule 17.06.2013
comment
Почему у тебя нигде нет часов? В большинстве случаев наличие одних часов упрощает целую кучу вещей.   -  person Martin Thompson    schedule 18.06.2013


Ответы (1)


Есть куча вещей, которые не совсем подходят для вашей реализации. Совершенно независимо от того, чего вы пытаетесь достичь, есть некоторые вещи с VHDL, которые следует помнить:

  • Каждое вступительное заявление должно иметь заключительное.
  • Каждый уровень вложенности должен иметь закрывающий оператор, чтобы «разложить» его.
  • Вы не можете поместить части одного набора операторов (внутренние элементы case) в другой оператор (цикл for), это кажется странным, но подумайте об этом, к какому case он будет присоединяться.
  • VHDL и аппаратное программирование в целом смехотворно параллельны, от одной итерации к другой процесс полностью независим от всех других процессов.

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

async_process : process (r_addr, fifo_data_out, array_reg)

begin
    case r_addr is
        when "0000000000" => fifo_data_out <= array_reg(0);
        when "0000000001" => fifo_data_out <= array_reg(1);
        when "0000000002" => fifo_data_out <= array_reg(2);
        when others => fifo_data_out <= array_reg(ADRESS_WIDTH-1);
    end case;
end process;

r_addr_inc_process : process (clock <or other trigger>, reset)
    <This is where you would deal with the bounds of the register address.  
     If you still want to deal with that variable, do it here.>
end process;

Итак, как вы можете видеть из этого, вы хотите обновлять как можно меньше вещей, когда имеете дело с процессом, таким образом, ваш список конфиденциальности является чрезвычайно конкретным, и вы можете заставить большинство обновлений происходить синхронно, а не асинхронно. Причина, по которой ваш асинхронный процесс может быть таким, заключается в том, что он будет обновляться каждый раз, когда обновляется r_addr, и это происходит при каждом чтении часов или при каком-либо флаге, и это дает вам согласованное состояние сброса.

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

person Jeff Langemeier    schedule 17.06.2013