Перейти к содержанию
    

Я написал замечательный ФИФО, но у него есть один не достаток - он не синтезируется.

Описание:

 

library ieee;

use ieee.std_logic_1164.all;

 

entity fifo1 is

port(

reset : in std_logic;

data_in_fifo1 : in std_logic_vector(31 downto 0);

write_to_fifo1 : in std_logic;

fifo1_got : in std_logic;

data_TS: inout std_logic_vector(31 downto 0);

fifo1_full : out std_logic;

EN : in std_logic;

fifo1_empty : out std_logic

);

constant depth: integer := 32;

constant width : integer :=32;

end entity;

 

architecture fifo1_arh of fifo1 is

type cell is array (depth-1 downto 0) of std_logic_vector(width-1 downto 0);

signal empty_internal,full_internal: std_logic;

 

function ring_inc(num : integer; limit : integer) return integer is

variable tmp : integer;

begin

if (num=limit) then

tmp:=0;

else

tmp:=num+1;

end if;

return tmp;

end function;

 

begin

main : process(write_to_fifo1,fifo1_got,reset,en)

variable data_in : std_logic_vector(31 downto 0);

variable f_write,f_read: natural :=0;

variable data : cell;

begin

 

if rising_edge(write_to_fifo1) then

if full_internal='0' then

data(f_write):=data_in_fifo1;

f_write:=ring_inc(f_write,depth-1);

if f_write=f_read then

fifo1_full <= '1';

full_internal <= '1';

else

fifo1_empty <= '0';

empty_internal <= '0';

end if;

end if;

end if;

 

if fifo1_got'event and fifo1_got = '1' then

if (empty_internal='0') then

data_in := data(f_read);

f_read:=ring_inc(f_read,depth-1);

if f_write = f_read then

fifo1_empty <= '1';

empty_internal <= '1';

else

fifo1_full <= '0';

full_internal <= '0';

end if;

end if;

end if;

 

 

if en = '1' then data_TS <= data_in;

else data_TS <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"; end if;

 

if (reset='1') then

for i in 0 to depth-1 loop

for j in 0 to width-1 loop

data(i)(j):='0';

end loop;

end loop;

data_TS <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";

f_read:=0;

f_write:=0;

fifo1_full<='0';

fifo1_empty<='1';

empty_internal<='1';

full_internal<='0';

end if;

end process;

 

end architecture;

 

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

 

Должна быть методика, как это обойти. Поделитесь опытом.

 

Стандартными ФИФО, типа Xilinовсий пользовать не хочется. Хочется своим, компактрным, чтоб можно было если надо что-нибудь поменять.

Изменено пользователем Little_boo

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Обсуддалось в конфе НЕОДНОКРАТНО. Не ленитесь искать.

ЗЫ И выкиньте код

for i in 0 to depth-1 loop

for j in 0 to width-1 loop

data(i)(j):='0';

end loop;

end loop;

а то как-то неудобно такое читать. Hint - сброс делается за счет правильных указателей.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И выкиньте код

for i in 0 to depth-1 loop

for j in 0 to width-1 loop

data(i)(j):='0';

end loop;

end loop;

а то как-то неудобно такое читать.

+1. Вместо этого ужаса надо писать

  data <= (others => (others => '0'));

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

+1. Вместо этого ужаса надо писать

  data <= (others => (others => '0'));

Я имел в виду, что для fifo не надо обнулять внутреннюю память, а надо указатель чтения=указатель записи :)и

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Обсуддалось в конфе НЕОДНОКРАТНО. Не ленитесь искать.

ЗЫ И выкиньте код

for i in 0 to depth-1 loop

for j in 0 to width-1 loop

data(i)(j):='0';

end loop;

end loop;

а то как-то неудобно такое читать. Hint - сброс делается за счет правильных указателей.

 

Я поискал, на первых двух станицах выданных поисковиком, ничего пожходящего не вычитал. Нащел только обсуждение ФИФО на Верилоге. Ща ещё гляну..

 

Так обнулять совсем не надо или просто конструкцию надо упростить?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Такобнулять совсем не надо или просто конструкцию надо упростить?

Тут прав Gate, а я нет. Если обнулять, то вы гарантированно получите(если получите) FIFO на триггерах, понеже у памяти сброса нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И еще совет: возьмите генератор памяти (в квартусе genmem.exe, для ксайлинкса не знаю как называется, но есть точно) и сгенерите исходники фифо и посмотрите, как там сделано. Код синтезируемый и rtl.

Что касается обнуления - это операция лишняя, т.к. для фифо не бывает случая, когда происходит чтение данных, которые не были бы предварительно записаны. Как только Вы начнете обнулять память (за 1 такт конечно; никто не мешает написать КА, который последовательно пишет нули в память), она немедленно будет синтезироваться в виде набора триггеров, как справедливо указал andrew_b. Вам оно надо?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По поводу синтезабельности - у Вас несколько клоков, т.е. дизайн асинхронный. Для fpga это зло, д.б. 1 клок.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Gate

 

Про обнуление регистров я понял, это похоже и вправду не нужно. Но выходные сигналы "пустой", "полный" надо же обнулить? Иначе до первого обащения к буферу они будут не определены. А внутренние переменные?

 

Потом проблема-то не в ресете. А как раз в 2-х клоках. По 1 пинет, по другому читает. Я и хотел спросить нельзя ли как-нибудь это дело граммотно расписать?

 

Для Xilinxa есть Coregen, он генерит ФИФО. Но он требует несколько клоков инициализации, текста там на 100 страниц, т.е. саому что либо тяжело поправить. Плюс тело зашито в библиотеку Ксайлинковскую, а её не для всякого Софта её удается подцепить.

 

Вот я и хотел найти готовый ФИФО(компактный), это ходовой элемент, я думал их понаписано кучи. Или разрулить свой. Как Вам кажется он вообще может стать рабочим?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У Xilinx'а кроме Coregen'а имеются еще XAPP's. Там есть реализация ФИФО для Virtex (Spartan 2) с двумя независимыми тактовыми сигналами. Текста, конечно, многовато (но все-таки не сотня страниц), поскольку они почему-то generate не очень активно используют. Но если над этим кодом немного поработать творчески, на выходе получится очень даже ничего себе вещь. При большом желании его можно даже полностью параметризовать (глубина, ширина шин данных, тип памяти(распределенная, блочная), регистр на выходе (есть/нет)) - я это проделал для ФИФО с одним тактовым сигналом - восторг полный один и тот же модуль используется везде, только параметры в generic задать.

 

Кстати, для инициализации адресных счетчиков и флагов (FULL, EMPTY) как раз сброс и нужен. Во время, когда он активен, оба флага стоят в 1, чтобы исключить запись и чтение во время сброса.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Little_boo,

с genmem я Вас обманул - он генерит описание для моделирования, там везде барьеры для синтезатора translate_off :(

Исходники фифо были на www.opencores.org

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На сколько я Вас понял, код мой гиблый и реанимации не подвержен... :(

 

Решил пока посмотреть, что нам предлагает Coregen, и посмотреть что за XAPP.

 

Рекомендуете здесь искать свое счатье: http://www.opencores.org/cvsweb.shtml/ ? Поикс там видимо нереален...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотрите XAPP175, XAPP258, только вместо стандартных элементов лучше использовать синтезируемую память - тогда появится возможность использовать все те вкусности, о которых я говорил выше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

XAPP-ы не посмотрел, пошел по "легкому пути" - взял coregen (fifo_generator_v3.2).

Cгенерил асинхронное FIFO 17 бит * 1024 слова с разными клоками на вход и выход, с остальными дефолтовыми опциями.

Пока моделировал схему, все было прекрасно... потом синтезировал (ISE 8.2 SP3, Aldec 7.1 SP2, Sinplify 8.5).

Сигналы управляющие FIFO: CLK_WR_TO_FIFO, DATA_WR_TO_FIFO, FIFO_WRITE_EN.

 

На диаграмме видно, что последнее слово в каждом пакете данных, записываемое в FIFO 0xXEXF.

Однако при выдаче данных FIFO выдает наружу 0xXCXD, а потом выставляет EMPTY. Спустя некоторое время оставшееся слово можно прочитать. Может кто нибудь сталкивался с подобным явлением и может объяснить такое странное поведение корки ?.

real.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...