Выход из петли с использованием внешнего сигнала в VHDL
Я пытаюсь записать блок данных (16 байтов, 4 слова) из моего кэша сущностей в мою другую память сущностей.
Память адресуется в байтах, поэтому я могу записать только 1 байт за раз. Память обновит mem_done до 1, когда будет записан байт.
Чтобы написать блок, мне нужно:
написать один байт,
дождитесь установки mem_done (объектом памяти),
приращение mem_address (следующий адрес для передачи в память), byte_count и каждые 4 байта приращение word_offset (смещение слова в кеше).
цикл до тех пор, пока все слова не будут записаны (word_offset = words_per_block-1).
При синтезе с Xilinx я получаю сообщение об ошибке "Превышен предел нестатического цикла" для wait_loop.
Я не могу использовать оператор ожидания до в цикле (ошибка: несколько операторов ожидания не допускаются).
Я не могу использовать FSM, потому что переходы состояния будут тратить один такт (и у меня есть ограничения по времени).
Как я могу сделать это иначе, не нарушая ограничения цикла?
-- block dirty in memory, write cache block back to memory
mem_enable <= '1'; -- out to memory, enable memory transfer
mem_rw <= '1'; -- out to memory. read/write bit
mem_addr_tmp <= cpu_addr; -- internal, address to write to
word_offset <= 0; -- internal, offset in cache
byte_count <= 31;
burst_loop: loop
-- Transfer 1 byte of data
mem_data <= CACHE(index).data(word_offset)(byte_count downto byte_count-7);
mem_addr <= mem_addr_tmp;
wait_loop: loop
if mem_done = '1' then -- mem_done comes from memory entity
exit wait_loop;
end if;
end loop wait_loop;
-- Update address, word offset, byte count
mem_addr_tmp <= std_logic_vector(to_unsigned(to_integer(unsigned(mem_addr_tmp)) + 1, mem_addr_tmp'length));
if (byte_count mod 4 = 0) then -- a word has been transfered, increment word_offset
word_offset <= word_offset + 1;
byte_count <= 31;
else -- a byte of a word has been transfered
byte_count <= byte_count - 7;
end if;
exit burst_loop when (mem_done = '1' and word_offset = words_per_block-1);
end loop burst_loop;
mem_enable <= '0';
1 ответ
wait_loop: loop
if mem_done = '1' then -- mem_done comes from memory entity
exit wait_loop;
end if;
end loop wait_loop;
Это бесконечный цикл, когда mem_done = '0'
, В VHDL время выполнения оператора является мгновенным, за очень важным исключением операторов ожидания. Таким образом, если mem_done равен "0" при входе в цикл, он никогда не завершится, так как время никогда не продвинется.
Кроме того, операторы ожидания обычно не являются синтезируемыми. Мы используем конечные автоматы для получения последовательных операторов в VHDL (в противном случае операторы выполняются параллельно).
Наконец, циклы в VHDL (для синтеза) используются для представления пространственных циклов, вы использовали их для временных циклов, как и в языке программирования (VHDL - это язык описания оборудования). Если хотите, циклы всегда развертываются и предлагают только более аккуратный способ написания нескольких похожих операторов. В симуляции вы можете использовать циклы, как в языках программирования, с помощью операторов ожидания.