Выход из петли с использованием внешнего сигнала в 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 - это язык описания оборудования). Если хотите, циклы всегда развертываются и предлагают только более аккуратный способ написания нескольких похожих операторов. В симуляции вы можете использовать циклы, как в языках программирования, с помощью операторов ожидания.

Другие вопросы по тегам