реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Block RAM на VHDL в Spartan3, Could not implement Block RAM. Is the read address registered using th
qwqw
сообщение Aug 23 2006, 09:08
Сообщение #16


Частый гость
**

Группа: Свой
Сообщений: 192
Регистрация: 23-11-05
Из: г. Москва
Пользователь №: 11 307



У меня Spartan2 а не 3, но думаю это непринципиально.
Мне нужно написать двухпортовую RAM с разными клоками на концах
с одной стороны только запись с we а с другой только чтение.
на сайте Xilinx есть примеры описания
НО мне нужна память с разной разрядностью шин на разных портах, там такого нет.
Есть вариант использовать готовую память типа RAMB4_Sm_Sn или, как говорилось выше, использовать COREGEN, но хочется иметь возможность изменять под себя (выбирать фронты и пр.) ну и по-возможности не использовать черных ящиков. Очевидно, что написать самому возможно, но пока не получается.
Вероятно кто-то уже возился с этим.
Пишу на VHDL, но Verilog тоже прочитаю.

Сообщение отредактировал qwqw - Aug 23 2006, 09:10
Go to the top of the page
 
+Quote Post
BSV
сообщение Aug 23 2006, 19:42
Сообщение #17


Знающий
****

Группа: Свой
Сообщений: 541
Регистрация: 11-04-05
Из: Москва
Пользователь №: 4 045



Пытался делать такую штуку в ISE 4.2. Были проблемы с синтезом (надо было писать и читать по обоим портам). Судя по тому, что приводится в Language templates, ситуация мало изменилась, хотя попробовать и не мешает:

Код
process (<clockA>)
begin
   if (<clockA>'event and <clockA> = '1') then
      if (<enableA> = '1') then
         if (<write_enableA> = '1') then
            <ram_name>(conv_integer(<addressA>)) <= <input_dataA>;
         end if;
         <ram_outputA> <= <ram_name>(conv_integer(<addressA>));
      end if;
   end if;
end process;

process (<clockB>)
begin
   if (<clockB>'event and <clockB> = '1') then
      if (<enableB> = '1') then
         <ram_outputB> <= <ram_name>(conv_integer(<addressB>));
      end if;
   end if;
end process;


Единственный выход в данном случае - использовать библиотечные элементы.

По поводу разной разрядности на портах - попробуйте все это описать на поведенческом уровне следующим образом - массив (который память) используйте с минимальной используемой разрядностью, а при описании чтения и записи по другому порту используйте несколько индексов массива. Например так:
Код
  
<ram_outputB> <= <ram_name>(conv_integer(<addressB>*2 + 1)) & <ram_name>(conv_integer(<addressB>*2));

Это в случае, если разрядность различается в 2 раза. Посмотрите, что Вам синтезатор на это скажет. Если схавает - ваша взяла, если нет - ничего не попишешь.

Кстати, тут возможна и другая проблема - в библиотечных элементах может не найтись памяти с нужной комбинацией разрядности портов и/или размером (например мне в Спартане 2е понадобилась память объемом 4КБайт и разрядностью 8 и 32). Тут может оказаться удобным объединение выходов нескольких BRAM при помощи OR или XOR и использовании входов сброса выходных регистров BRAM. Понятно как - на те BRAM, что не используем подаем сигнал сброса, после OR или XOR получаем то, что нужно. Правда, это может оказаться слишком медленно.

Сообщение отредактировал BSV - Aug 23 2006, 19:43


--------------------
Дурак, занимающий высокий пост, подобен человеку на вершине горы - все ему кажется маленьким, а всем остальным кажется маленьким он сам. /Законы Мерфи/
Go to the top of the page
 
+Quote Post
qwqw
сообщение Aug 24 2006, 08:44
Сообщение #18


Частый гость
**

Группа: Свой
Сообщений: 192
Регистрация: 23-11-05
Из: г. Москва
Пользователь №: 11 307



разрядность портов:
A (запись) = 8
B(чтение) = 32
глубина от 1024 байт и выше

ваш вариант (и смежные с ним) я уже пробовал
примерно так:
Код
-------------- A side -------------------------
my_RAM_A_side:process(clkA)
begin
if clkA'event and clkA = '1' then
---
if WEA='1' then ram_block(conv_integer(AddrA))<=DIA;end if;
---
end if; -- clk
end process my_RAM_A_side;
-----------------------------------------------
-------------- B side -------------------------
my_RAM_B_side:process(clkB)
begin
if clkB'event and clkB = '1' then
---
--read_addr<=4*AddrB;--conv_integer(AddrB);
read_addr0<=4*AddrB;
read_addr1<=4*AddrB+1;
read_addr2<=4*AddrB+2;
read_addr3<=4*AddrB+3;
---
end if; -- clk
end process my_RAM_B_side;
----
----
--DOB <= ram_block(read_addr)&ram_block(read_addr+1)&ram_block(read_addr+2)&ram_block(read_addr+3);
DOB( 7 downto  0)<= ram_block(read_addr0);
DOB(15 downto  8)<= ram_block(read_addr1);
DOB(23 downto 16)<= ram_block(read_addr2);
DOB(31 downto 24)<= ram_block(read_addr3);
-----------------------------------------------

но увы не получается
я могу использовать 2 закаскадированых RAMB4_S4_S16, но хочется все же самому закодить
Go to the top of the page
 
+Quote Post
BSV
сообщение Aug 24 2006, 10:59
Сообщение #19


Знающий
****

Группа: Свой
Сообщений: 541
Регистрация: 11-04-05
Из: Москва
Пользователь №: 4 045



А синтезатор-то что говорит? В Вашей реализации я вижу ошибку - чтение должно быть обязательно! по фронту клока, а вот адреса чтения как раз и не нужно делать регистровыми.


--------------------
Дурак, занимающий высокий пост, подобен человеку на вершине горы - все ему кажется маленьким, а всем остальным кажется маленьким он сам. /Законы Мерфи/
Go to the top of the page
 
+Quote Post
BSV
сообщение Aug 24 2006, 11:40
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 541
Регистрация: 11-04-05
Из: Москва
Пользователь №: 4 045



Попробовал - таки да, не хавает, говорит, что вместо памяти триггеров навставляет. Ну и шут с ним.
Для вас есть вариант - объединить 4 синтезированных блока xxx_S8_S8 способом, который я описал выше, хотя, вам же по 8-разрядному порту не надо читать - так что это и не нужно. С двумя блоками фокус не пройдет - выравнивание поедет (PORTB(x) /= PORTA(x*4+3) & PORTA(x*4+2) & PORTA(x*4+1) & PORTA(x*4)).


--------------------
Дурак, занимающий высокий пост, подобен человеку на вершине горы - все ему кажется маленьким, а всем остальным кажется маленьким он сам. /Законы Мерфи/
Go to the top of the page
 
+Quote Post
qwqw
сообщение Aug 24 2006, 14:05
Сообщение #21


Частый гость
**

Группа: Свой
Сообщений: 192
Регистрация: 23-11-05
Из: г. Москва
Пользователь №: 11 307



насчет ошибки я не согласен, если посмотрите в примерах там сделано аналогично.
Да и раньше я делал такую память(только с одинаковой разрядностью) и все благополучно паковалось в BRAM.
Цитата
Для вас есть вариант - объединить 4 синтезированных блока xxx_S8_S8 способом, который я описал выше, хотя, вам же по 8-разрядному порту не надо читать - так что это и не нужно. С двумя блоками фокус не пройдет - выравнивание поедет (PORTB(x) /= PORTA(x*4+3) & PORTA(x*4+2) & PORTA(x*4+1) & PORTA(x*4)).

я уже сделал, как говорил выше: каскадировал 2 блока RAMB4_S4_S16 и как раз получается 8/32
и глубина 1024. Соответственно 1-й RAMB4_S4_S16 - на вход младшая тетрада на 2-й - старшая
и выход разобран соответствующим образом.
Все работает и в BRAM упаковалось. Однако камень предкновения во фронтах.
Если не получится с положительными сделать, придется тратить GBUF с CLKDLL (брать противофазный клок), а с ними тоже напряг.
Go to the top of the page
 
+Quote Post
BSV
сообщение Aug 24 2006, 14:46
Сообщение #22


Знающий
****

Группа: Свой
Сообщений: 541
Регистрация: 11-04-05
Из: Москва
Пользователь №: 4 045



Зачем Вам противофазный клок? Если нужен отрицательный фронт - просто заводите на тактовый вход not CLK и все - а синтезатор, маппер или что там еще пусть разбирается (инверторы на тактовом входе имеются в любом блоке, в том числе и в BLOCKRAM).

Сообщение отредактировал BSV - Aug 24 2006, 14:47


--------------------
Дурак, занимающий высокий пост, подобен человеку на вершине горы - все ему кажется маленьким, а всем остальным кажется маленьким он сам. /Законы Мерфи/
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 9th August 2025 - 18:14
Рейтинг@Mail.ru


Страница сгенерированна за 0.01409 секунд с 7
ELECTRONIX ©2004-2016