2015-04-27 4 views
0

Я нашел код VHDL FIFO и попытался изменить его для использования с двумя разными часами: один для записи и один для чтения. Я судимый код и, кажется, работаю в симуляции, но когда я пытаюсь синтезировать я получаю эту ошибку:Ошибка FIFO: не удается найти управляющий сигнал - VHDL

"Can't find control signal for Full"

library IEEE; 
USE IEEE.STD_LOGIC_1164.ALL; 
USE IEEE.NUMERIC_STD.ALL; 

entity FIFO is 
    Generic (
     constant DATA_WIDTH : positive := 8; 
     constant FIFO_DEPTH : positive := 100 
    ); 
    Port ( 
     WCLOCK  : in STD_LOGIC; 
     RCLOCK  : in STD_LOGIC; 
     WriteEn : in STD_LOGIC; 
     DataIn : in STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0); 
     ReadEn : in STD_LOGIC; 
     DataOut : out STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0); 
     Empty : out STD_LOGIC; 
     Full : out STD_LOGIC; 
     ModuleRESET : in STD_LOGIC 
    ); 
end FIFO; 

architecture FIFO_archi of FIFO is 
    type FIFO_Memory is array (0 to FIFO_DEPTH - 1) of STD_LOGIC_VECTOR (DATA_WIDTH - 1 downto 0); 
    signal Memory : FIFO_Memory; 
    signal Head : natural range 0 to FIFO_DEPTH - 1; 
    signal Tail : natural range 0 to FIFO_DEPTH - 1; 


    begin 
     -- Memory Pointer Process 
     process (WCLOCK, RCLOCK, ModuleRESET) 
      variable Looped : boolean; 
     begin 
      if ModuleRESET = '0' then 
       Head <= 0; 
       Tail <= 0; 
       Looped := false; 
       Full <= '0'; 
       Empty <= '1'; 
       DataOut <= (others => '0'); 
      elsif ReadEn = '1' then 
       if rising_edge(RCLOCK) then      
        if ((Looped = true) or (Head /= Tail)) then 
         -- Update data output 
         DataOut <= Memory(Tail); 

         -- Update Tail pointer as needed 
         if (Tail = FIFO_DEPTH - 1) then 
          Tail <= 0; 
          Looped := false; 
          else 
           Tail <= Tail + 1; 
          end if; 
         end if; 
        end if; 
       -- Update Empty and Full flags 
       if (Head = Tail) then 
        if Looped then 
         Full <= '1'; 
         else 
          Empty <= '1'; 
         end if; 
        else 
         Empty <= '0'; 
         Full <= '0'; 
       end if; 
      elsif WriteEn = '1' then 
       if rising_edge(WCLOCK) then 
         if ((Looped = false) or (Head /= Tail)) then 
          -- Write Data to Memory 
          Memory(Head) <= DataIn; 

          -- Increment Head pointer as needed 
          if (Head = FIFO_DEPTH - 1) then 
           Head <= 0; 
           Looped := true; 
          else 
           Head <= Head + 1; 
          end if; 
         end if; 
       -- Update Empty and Full flags 
       if (Head = Tail) then 
        if Looped then 
         Full <= '1'; 
         else 
          Empty <= '1'; 
         end if; 
        else 
         Empty <= '0'; 
         Full <= '0'; 
       end if; 
       end if; 
      end if; 
     end process; 

end FIFO_archi; 

Как я могу решить эту ошибку?

+1

Вы не можете этого сделать. FIFO с другим CLK для чтения и записи сильно отличается от простого FIFO одним часом. Вы должны выполнить повторную синхронизацию указателей, используя сериальную логику счетчика, которая может быть вне зоны комфорта. Каждый инструмент синтеза имеет IP-ядра для двухфазного FIFO, почему бы вам не использовать его вместо этого? –

+1

Действительно. Вы не можете просто изменить однократный FIFO и ожидать, что он станет CDC FIFO. Пересечение домена - это совсем другое зверь. –

ответ

0

Попытка изменить один тактовый FIFO, чтобы стать перекрестком с тактовой частотой FIFO - задача не из легких. Это два совершенно разных зверя.

Я попытался нарисовать блок-схему простейшего возможного тактового домена, пересекающего структуру FIFO. Извините за грубость моих навыков рисования. Мой пример - 16-байтовый FIFO, но его можно расширить до произвольной глубины и ширины, если глубина равна двум.

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

Нет ярлыков. Если вы хотите создать свой собственный тактовый домен, пересекающий FIFO, то эта блок-схема представляет собой минимальный минимум, который вы должны сделать.

CDC FIFO block diagram

0

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

Начните с проверки в руководстве/userguide для вашего инструмента синтеза, чтобы убедиться, что он поддерживает вывод FIFO с отдельными часами чтения/записи. Если да, то, скорее всего, предложит поддерживаемое описание поведения HDL, которое вы должны смоделировать после этого кода.

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

+0

У меня есть два модуля, один из которых записывает FIFO, а другой, когда FIFO заполнен, начните читать с FIFO. Таким образом, у меня есть два разных такта, и когда я пишу FIFO, я не буду читать данные, и когда я прочитаю FIFO, я не буду писать данные на нем, так что указатель или синхронизация часов никогда не произойдут. Другим решением является использование модуля с двумя входными тактами и 1 выходным тактовым сигналом. Но это создаст те же проблемы с часами? – Yaro

+0

@Yaro Когда вы пишете или читаете FIFO, это не имеет никакого отношения к часам, которые использует FIFO. Эти часы действительно независимы? Нужно ли им быть? Например, они генерируются из полностью независимых источников синхронизации, которые никоим образом не связаны (то есть отдельные генераторы)? Если вам не нужны действительно независимые часы, используйте общие часы. Это будет описывать синхронный FIFO вместо асинхронного FIFO. Синхронный FIFO намного проще реализовать. – Josh

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