sazh 9 September 5, 2012 Posted September 5, 2012 · Report post Короче мы прикидывали, что отобьем деньги на разработку БМК уже за год, а договор - лет на 5 будет если будет конечно Свежо предание. БМК по несколько тысяч на каждый кристалл (для рентабельности). До 2022 года успеете реализовать? Всегда найдется дяденька, которому в 2022 году надо будет 2022 года изготовления. Впрочем, кусок хлеба на всю жизнь. Quote Share this post Link to post Share on other sites More sharing options...
ISK 0 September 5, 2012 Posted September 5, 2012 · Report post нет, теперь он согласен с тем, что память однопортовая. и даже не дает варнингов, но в логе раскопал вот такое инфо: Info: RAM logic "RAM_bloc:u1|VOB_RAM" is uninferred due to unsupported read-during-write behavior может типа такого? process(clk, WE, ADDRESS, DATA) begin if(rising_edge(clk)) then if(we = '1') then VOB_RAM(conv_integer(address)) <= data; else q <= VOB_RAM(conv_integer(addrress)); end if; end if; end process; Quote Share this post Link to post Share on other sites More sharing options...
Lubnin 0 September 6, 2012 Posted September 6, 2012 · Report post Свежо предание. БМК по несколько тысяч на каждый кристалл (для рентабельности). До 2022 года успеете реализовать? Всегда найдется дяденька, которому в 2022 году надо будет 2022 года изготовления. Впрочем, кусок хлеба на всю жизнь. На чем основано (личное мнение, аргументы, факты, опыт работы) Ваше высказывание? Производитель БМК дал нам ориентировачную стоимость разработки и изготовления одного кристала (партия от 200 штук). Основываясь на этих данных мы и оценивали рентабельность. Получалось, что стоимость кристала примерно в 2 раза меньше стоимости одной ПЛИС (планировалось одной БМК заменить две ПЛИС). Каюсь, оценивали только текущий вариант с двумя ПЛИС, стоимость варианта с одной большой отечественной ПЛИС - не рассматривали. Если у Вас есть опыт работы с производителями БМК, то прошу поделиться им. Может есть какие-то нюансы, которые мы пока не учитываем. может типа такого? process(clk, WE, ADDRESS, DATA) begin if(rising_edge(clk)) then if(we = '1') then VOB_RAM(conv_integer(address)) <= data; else q <= VOB_RAM(conv_integer(addrress)); end if; end if; end process; Так пробовал, и в обе ветки условия по weпробовал добавлять вывод данных (назначение q), и использовать сигнал чтения пробовал, и пробовал разные частоты заводить для чтения и записи, реализовывая их в одном и разных процесах, но никак он меня понять не может - либо двухпортовая память и не поддерживает, либо что-то не то с описанием процесса чтения-во время-записи. :crying: Quote Share this post Link to post Share on other sites More sharing options...
Confucij 0 December 27, 2012 Posted December 27, 2012 · Report post Не сочтите некропостером, но стоит та же задача - разместить память в ячейках памяти не используя альтеровский модуль. Как эта проблема - решилась-то или нет? У меня такие же проблемы как у топикстартера.. Пока единственно до чего дошел это вот такой код library ieee; use ieee.std_logic_1164.all; entity RAM is generic ( DATA_WIDTH : natural := 8; ADDR_WIDTH : natural := 6 ); port ( clk : in std_logic; addr : in natural range 0 to 2**ADDR_WIDTH - 1; data : in std_logic_vector((DATA_WIDTH-1) downto 0); we : in std_logic := '1'; q : out std_logic_vector((DATA_WIDTH -1) downto 0) ); end entity; architecture rtl of RAM is -- Build a 2-D array type for the RAM subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0); type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t; -- Declare the RAM signal. signal ram : memory_t; -- Register to hold the address signal addr_reg : natural range 0 to 2**ADDR_WIDTH-1; begin process(clk) begin if(rising_edge(clk)) then -- Register the address for reading addr_reg <= addr; end if; end process; B1:block (we = '0') is begin q <= guarded ram(addr_reg); end block B1; B2:block (we = '1') is begin ram(addr_reg) <= guarded data; end block B2; end rtl; В ячейки-то он размещает, но генерит столько защелок, что просто не влазит в кристал)) Quote Share this post Link to post Share on other sites More sharing options...
Lubnin 0 December 28, 2012 Posted December 28, 2012 · Report post Задача была "факультативная" ("Попробовать перевести критические куски проекта"). Поэтому была перебита текущей работой и заброшена. Сейчас порылся - у меня вариант с использованием мегафункции. Следовательно вопрос остался открытым. Похоже самый оптимальный вариант это использовать generic по рекомендации TRILLER. Quote Share this post Link to post Share on other sites More sharing options...
SM 9 December 28, 2012 Posted December 28, 2012 · Report post В ячейки-то он размещает, но генерит столько защелок, что просто не влазит в кристал)) А других вариантов и нету. Либо блочная память, либо по защелке на бит памяти. Quote Share this post Link to post Share on other sites More sharing options...
Confucij 0 December 29, 2012 Posted December 29, 2012 · Report post А других вариантов и нету. Либо блочная память, либо по защелке на бит памяти. Наверное я что-то не понимаю или не так выразился. В отчете после синтеза написано, что занято около 1.5К ячеек памяти и использовано ~900 логических ячеек. Тоесть как я понял была сгенерирована какая-то дополнительная логика для работы с памятью. Quote Share this post Link to post Share on other sites More sharing options...
SM 9 December 29, 2012 Posted December 29, 2012 · Report post так отчет в студию. а то не понятно. Quote Share this post Link to post Share on other sites More sharing options...
Confucij 0 December 29, 2012 Posted December 29, 2012 · Report post Вот кусок из map файла +----------------------------------------------+ ; Analysis & Synthesis Resource Usage Summary ; +--------------------------------+-------------+ ; Resource ; Usage ; +--------------------------------+-------------+ ; Total logic elements ; 927 ; ; Total combinational functions ; 921 ; ; -- Total 4-input functions; 401 ; ; -- Total 3-input functions; 520 ; ; -- Total 2-input functions; 0 ; ; -- Total 1-input functions; 0 ; ; -- Total 0-input functions; 0 ; ; Total registers ; 6 ; ; I/O pins ; 24 ; ; Total memory bits ; 1536 ; ; Maximum fan-out node ; addr_reg[1]; ; Maximum fan-out ; 145 ; ; Total fan-out ; 3268 ; ; Average fan-out ; 3.39 ; +--------------------------------+-------------+ и куча подобных сообщений в нем еще: Info (10041): Inferred latch for "ram[0][0]" at RAM.vhd(50) Quote Share this post Link to post Share on other sites More sharing options...
Timmy 1 December 30, 2012 Posted December 30, 2012 · Report post Проблемы такого рода возникают из-за недостаточно ясного описания принципов работы BRAM во всяких даташитах. Дело в том, что чтение в BRAM не является истинно асинхронным. По фронту клока адрес чтения записывается в регистр, а результат чтения через некоторое время, задаваемое одновибратором, запускаемым по фронту клока, защёлкивается во внутренней защёлке, и сохраняется там до завершения следующего такта чтения. Например, если считанная ячейка позднее будет перезаписана в цикле записи, значение в защёлке чтения, немедленно не изменится. В этом отличие блочной памяти от распределённой, которая истинно асинхронная. Таким образом, правильное поведенческое описание псевдоасинхронного чтения делается одной строчкой следующим образом: always @(posedge clk) if(rd_en) data_ir <= memory(rd_addr); где регистр data_ir символизирует внутреннюю защёлку. Регистр адреса чтения в явном виде описываться не должен, так как ему всегда соответствует содержимое data_ir. Полный пример описания однопортовой памяти в режиме write through с выходным регистром: library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; entity memory is port( clk:std_logic; ce, we:std_logic; di:std_logic_vector; addr:std_logic_vector; --integer range 0 to depth-1; do:out std_logic_vector ); end entity; architecture general of memory is subtype data_t is std_logic_vector(di'length-1 downto 0); type data_mem_t is array(0 to 2**addr'length-1) of data_t; signal data_ir:data_t; --внутренняя защёлка signal data_mem:data_mem_t; --вся память begin process(clk) is begin if rising_edge(clk) then if ce = '1' then do <= data_ir; --выходной регистр if we = '1' then data_mem(conv_integer(unsigned(addr))) <= di; data_ir <= di; --writethru else data_ir <= data_mem(conv_integer(unsigned(addr))); end if; end if; end if; end process; end architecture; Примерно в таком виде оно правильно синтезируется для lattice ecp2, в вашем случае режима "write through" может не быть, и потребуется слегка переделать управление data_ir. Quote Share this post Link to post Share on other sites More sharing options...
SM 9 January 3, 2013 Posted January 3, 2013 · Report post Дело в том, что чтение в BRAM не является истинно асинхронным. А Вы обратили внимание, что ПЛИС - FLEX10K - так тема называется? В ней истинно асинхронная память, как и в последующей за ней ACEX1K, и чтение ее там возможно истинно асинхронным образом, о чем в их даташитах сказано более чем ясно и конкретно. А распределенной памяти в этих семействах не было (и нет) вообще никакой (кроме массива защелок). Так что не вводите людей в заблуждение. Quote Share this post Link to post Share on other sites More sharing options...