Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Размещение массива в M9K
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
juvf
Написал свой блок. в нем использую массив регистров

reg [7:0]memRxD [0:255];

После компиляции блок съел около 6000 logical cell и 0 М9К. в засусеках квартуса нашел атрибут ramstyle, написал так:

(* ramstyle = "M9K" *) reg [7:0]memRxD [0:255];

пересобрал с таким атрибутом..... в результате те же 6000 селов и 0 м9к. Как указать компилятору чтоб он поменьше ел вентилей и по больше памяти?
Timmy
Обычно компилятору указывать ничего не надо, но поведенческое описание массива должно точно соотвествовать аппаратной архитектуре M9K. Поищите у Гугла на тему "altera memory inference", там есть разъяснения и примеры кода.
Konst_777
Цитата(juvf @ Dec 25 2011, 06:57) *
...Как указать компилятору чтоб он поменьше ел вентилей и по больше памяти?

"Assigments->Settings->Analysis & Synthesis Settings->More Settings..." - попробуйте изменить опции:
"Allow Any Ram Size For Recognition" в "On";
"Auto RAM Replacement" в "On";
"Auto RAM to Logic Cell Conversion" в "Off".
dxp
QUOTE (Timmy @ Dec 25 2011, 13:31) *
Обычно компилятору указывать ничего не надо, но поведенческое описание массива должно точно соотвествовать аппаратной архитектуре M9K. Поищите у Гугла на тему "altera memory inference", там есть разъяснения и примеры кода.

+1. Память М9К (как и всякая другая блочная память в альтеровских FPGA) не может работать как угодно. В частности, у неё адрес и входные данные всегда сперва попадают во входные регистры, только потом уже достают до внутреннего массива. Поэтому, если описать работу с памятью без учёта этого момента, то синтезатор просто не сможет имплементировать описанную логику с помощью аппаратного блока памяти.

Имхо, лучше использовать инстансы модулей, чем заставлять синтезатор инферить аппаратные блоки из кода. Результат будет надёжнее и предсказуемее. Да и переносимость кода, пожалуй, тоже будет лучше.
barabek
Как и советовали выше необходимо правильно описать поведение памяти. Прочтите соответствующий раздел в : Recommended HDL Coding Styles
Bad0512
Цитата(dxp @ Dec 25 2011, 16:06) *
Имхо, лучше использовать инстансы модулей, чем заставлять синтезатор инферить аппаратные блоки из кода. Результат будет надёжнее и предсказуемее. Да и переносимость кода, пожалуй, тоже будет лучше.

По поводу переносимости - позволю себе возразить.Переносимость (например при перетаскивании из Altera в Xilinx) при повсеместном использовании примитивов очень страдает.


Цитата(juvf @ Dec 25 2011, 09:57) *
Написал свой блок. в нем использую массив регистров

reg [7:0]memRxD [0:255];

После компиляции блок съел около 6000 logical cell и 0 М9К. в засусеках квартуса нашел атрибут ramstyle, написал так:

(* ramstyle = "M9K" *) reg [7:0]memRxD [0:255];

пересобрал с таким атрибутом..... в результате те же 6000 селов и 0 м9к. Как указать компилятору чтоб он поменьше ел вентилей и по больше памяти?

А вы осознаёте, что доступ по чтению в один момент времени у вас будет только к одному из 256 регистров? Это вам подходит?
dxp
QUOTE (Bad0512 @ Dec 25 2011, 23:03) *
По поводу переносимости - позволю себе возразить.Переносимость (например при перетаскивании из Altera в Xilinx) при повсеместном использовании примитивов очень страдает.

Я имел в виду следующее. При использовании модулей есть возможность сделать формализованный интерфейс к памяти, а нюансы реализации скрыть внутри этих модулей. Таким образом, при портировании достаточно будет портировать только сами модули, в то время как при переносе того же самого, "размазанного" по коду всего проекта, придётся перелопачивать весь код и искать все места использования.
juvf
Цитата(Bad0512 @ Dec 25 2011, 22:03) *
А вы осознаёте, что доступ по чтению в один момент времени у вас будет только к одному из 256 регистров? Это вам подходит?

Нет, не подходит. есть блоки, например.....

Код
always @ (posedge clk)
begin
  if(cs)
  begin
   memRxD[0] <= a;
   memRxD[1] <= b;
   memRxD[2] <= c;
  end
  else
  begin
   d<= memRxD[3];
   e<= memRxD[4];
   f<= memRxD[5];
  end
end

при таком раскладе за такт нельзя будет записать/прочитать данные массива регистров?
Bad0512
Цитата(juvf @ Dec 26 2011, 08:57) *
Нет, не подходит. есть блоки, например.....

Код
always @ (posedge clk)
begin
  if(cs)
  begin
   memRxD[0] <= a;
   memRxD[1] <= b;
   memRxD[2] <= c;
  end
  else
  begin
   d<= memRxD[3];
   e<= memRxD[4];
   f<= memRxD[5];
  end
end

при таком раскладе за такт нельзя будет записать/прочитать данные массива регистров?

Просто представьте себе как физически устроена блочная память. У неё есть шина данных на запись конечной ширины (точнее 2 шины данных в случае двухпортовой памяти, но сейчас нам это неважно).И точно такая же, конечной ширины шина данных на чтение. То есть единовременно вы можете прочитать всегда только ОДИН регистр.В следующий момент времени - другой регистр и так далее.Но доступа к каждому конкретному биту этой памяти в каждый момент времени у вас нет и быть не может. Для реализации такой фичи пришлось бы вытаскивать наружу из примитива памяти столько верёвок, сколько бит у памяти. А это ООООЧЕНЬ дорого...

Цитата(dxp @ Dec 25 2011, 23:12) *
Я имел в виду следующее. При использовании модулей есть возможность сделать формализованный интерфейс к памяти, а нюансы реализации скрыть внутри этих модулей. Таким образом, при портировании достаточно будет портировать только сами модули, в то время как при переносе того же самого, "размазанного" по коду всего проекта, придётся перелопачивать весь код и искать все места использования.

Это известный подход, так называемые врапперы.В принципе способ неплохой, однако требует достаточной аккуратности при переносе на другую архитектуру. К примеру если говорить о тех же примитивах памяти, надо обязательно документировать в верхнем уровне требуемую латентность памяти (она может меняться как для альтеры так и для Xilinx).Несоответствие задержек может привести к плачевныи результатам.
Для меня идеалом было бы такое поведение синтезатора, при котором большая часть кода была бы описана в "платформонезависимом виде", а синтезатор сам (или с помощью мягкого подпинывания) укладывал уже этот код в вендоровские примитивы. Довольно часто такой подход даёт результат, однако иногда выскакивают и довольно неожиданные плюшки от синтезатора. Тогда приходится допиливать проблемные куски "вручную", с помощью корегена и какой-то матери...
bogaev_roman
Цитата(juvf @ Dec 26 2011, 05:57) *
Нет, не подходит. есть блоки, например.....

Эти блоки не реализуемы на M9K. Чтобы понять как работает M9K прочитайте мануал, можно вручную из визарда создать тестовую память и разобраться для начала с ней, плоть до реализации на самой ПЛИС в chipplanner.
juvf
Цитата(bogaev_roman @ Dec 26 2011, 14:28) *
Эти блоки не реализуемы на M9K.
ну это я понял. а в другом блоке нет параллельного обращения к памяти, тогда массив регистров разместится в м9к?

посмотрел шаблоны. там
Код
// Quartus II Verilog Template
// Single port RAM with single read/write address

module single_port_ram
#(parameter DATA_WIDTH=8, parameter ADDR_WIDTH=6)
(
    input [(DATA_WIDTH-1):0] data,
    input [(ADDR_WIDTH-1):0] addr,
    input we, clk,
    output [(DATA_WIDTH-1):0] q
);

    // Declare the RAM variable
    reg [DATA_WIDTH-1:0] ram[2**ADDR_WIDTH-1:0];

    // Variable to hold the registered read address
    reg [ADDR_WIDTH-1:0] addr_reg;

    always @ (posedge clk)
    begin
        // Write
        if (we)
            ram[addr] <= data;

        addr_reg <= addr;
    end

    // Continuous assignment implies read returns NEW data.
    // This is the natural behavior of the TriMatrix memory
    // blocks in Single Port mode.  
    assign q = ram[addr_reg];

endmodule
В таком блоке нет параллельных обращений, поэтому такой блок квартус уже разместит в м9к?
bogaev_roman
Цитата(juvf @ Dec 26 2011, 16:06) *
В таком блоке нет параллельных обращений, поэтому такой блок квартус уже разместит в м9к?

Запись/чтение одновременно в/из нескольких элементов возможны только в регисрах (ну или на комбинационной логике в крайнем случае). Пример действительно соответствует простейшей версии именно памяти, но на чем квартус ее сделает лучше прописать каким-нибудь атрибутом или настройками. В некоторых случаях он может решить что выгоднее ее сделать на m144k или регистрах.
Чем сделанные в визарде не устраивают, Вам переносимость нужна на другие платформы? Просто попытаясь сделать память на визарде Вы наглядно увидите все/входы выходы, задежки ну и различные варианты конфигурации, ну и так гораздо проще разобраться с принципом работы.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.