|
|
  |
Размещение массива в M9K |
|
|
|
Dec 25 2011, 08:07
|
Знающий
   
Группа: Свой
Сообщений: 549
Регистрация: 1-06-05
Пользователь №: 5 644

|
Цитата(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".
|
|
|
|
|
Dec 25 2011, 09:06
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
QUOTE (Timmy @ Dec 25 2011, 13:31)  Обычно компилятору указывать ничего не надо, но поведенческое описание массива должно точно соотвествовать аппаратной архитектуре M9K. Поищите у Гугла на тему "altera memory inference", там есть разъяснения и примеры кода. +1. Память М9К (как и всякая другая блочная память в альтеровских FPGA) не может работать как угодно. В частности, у неё адрес и входные данные всегда сперва попадают во входные регистры, только потом уже достают до внутреннего массива. Поэтому, если описать работу с памятью без учёта этого момента, то синтезатор просто не сможет имплементировать описанную логику с помощью аппаратного блока памяти. Имхо, лучше использовать инстансы модулей, чем заставлять синтезатор инферить аппаратные блоки из кода. Результат будет надёжнее и предсказуемее. Да и переносимость кода, пожалуй, тоже будет лучше.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Dec 25 2011, 16:03
|
Знающий
   
Группа: Свой
Сообщений: 802
Регистрация: 11-05-07
Из: Томск
Пользователь №: 27 650

|
Цитата(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 регистров? Это вам подходит?
|
|
|
|
|
Dec 26 2011, 01:57
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(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 при таком раскладе за такт нельзя будет записать/прочитать данные массива регистров?
Сообщение отредактировал juvf - Dec 26 2011, 01:59
|
|
|
|
|
Dec 26 2011, 06:18
|
Знающий
   
Группа: Свой
Сообщений: 802
Регистрация: 11-05-07
Из: Томск
Пользователь №: 27 650

|
Цитата(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).Несоответствие задержек может привести к плачевныи результатам. Для меня идеалом было бы такое поведение синтезатора, при котором большая часть кода была бы описана в "платформонезависимом виде", а синтезатор сам (или с помощью мягкого подпинывания) укладывал уже этот код в вендоровские примитивы. Довольно часто такой подход даёт результат, однако иногда выскакивают и довольно неожиданные плюшки от синтезатора. Тогда приходится допиливать проблемные куски "вручную", с помощью корегена и какой-то матери...
|
|
|
|
|
Dec 26 2011, 12:06
|

Профессионал
    
Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045

|
Цитата(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к?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|