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

Quartus - странная ситуация с IP умножителя

Приветствую!

Словил на днях  странную ситуацию  с IP  LPM_MULT  -  Есть у меня в дизайне модуль где стоит простенький умножитель - i96 = i64 x i32,  pipeline 4 такта  С генерировал я этот умножитель в IP wizard (LPM_MULT), работал он на ~160 MHz в StratixV  все было замечательно.
Но вот решил я (от скуки сидя в карантине) поднять рабочую частоту дизайна до 250 MHz.   Переписал пару узких мест,  сделал P&R и ... получил кучу ошибок тайминга  в этом самом умножителе :shok: Ну думаю - может подкину ему еще  1-2 дополнительных pipeline и все будет ок. Ан нет  - ситуация не изменилась. Причем ошибки ну уж очень странно большие, отрицательные слаки -2 -3 нс.  Мой дизайн не маленький - собирается с час. Думаю надо бы по экспериментировать на маленьких "кошечках"  Сделал  тест-модуль с этим умножителям и минимальной  обвязкой. Собрал P&R - получил частоту ~400 MHz. Чертовщина!  :superstition:

Полез в нетлист разбираться  в чем разница. Оказалось  что корка LPM_MULT   в Qu это не корка а так  - чистый  надувательство  RTL типа C = A*B  и в хвосте паровозиком регистры pipeline (а я то наивный, Xilinx разбалованный, думал что там уже если не нетлист то хотя-бы жестко на примитивах собрано) .  Предполагается что Qu при P&R должен растянуть регистры эти в нужные места в примитивы DSP.   И вот для частоты 160 MHz (и тестового дизайна) он  это делает  - а в новом варианте дизайна нет - лепит умножитель на чистой комбинаторике из DSP, а сзади цепляет к нему регистры (и даже пытается оптимизировать их в shift-ram, ха-ха-ха).  Наблюдаю такое безобразие и в 14.1  и в 19.1 версии.  :ireful1:.   

Понятное дело что из за такого "леса ошибок" не видно деревьев - моих узких мест которые реально могут давать ошибки времянки.  :search:Пришлось делать ход конем - экспортировать  post-fit нетлист из тестового дизайна как partition и импортировать его в основной. И о чудо - все собралось с пол пинка. 
Вот и сижу гадаю что это такое.  Толи Qu-роно вирус какой,  толи что связанно с чрезмерно ушлым оптимизатором  который видя что какую-то цепь  не удастся уложить в ограничения  бросает и все остальное - "и так сойдет" :tease:.  Кто нибудь попадал на такое?  

Удачи! Rob.

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


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

Сравните по ресурсам - блок на 160 МГц, 250, 400, и когда слак получился отрицательный. Существует ведь несколько реализаций умножителя, все они различаются по скорости и площади. Очевидно, что быстрый вариант использует распараллеливание, и потому избыточен - имеет наибольшую площадь. Причем, если включен ретайминг (ваш случай), в распараллеленной реализации площадь особенно сильно увеличится. Думаю, что отрицательный слак - получился умножитель с длинным последовательным переносом, самый медленный, но и самый компактный. Скорее всего тул его выбрал для экономии ресурсов, поскольку проект большой (как я понял). Ну а 400 МГц должен быть самым толстым по ресурсам.

 

Что делать - вам виднее, но расскажу про одну особенность (любых) синтезаторов. Когда формула задана в виде c=a*b, синтезатору ничего не остается, как использовать встроенные шаблоны, из которых тул выбирает вариант по ситуации, исходя из требований скорости/площади/потребления. Если же умножитель (сумматор и т.д.) прямо в RTL задан в развернутом виде на комбинационной логике (только OR/AND/NOT), то синтезатор уже не может принципиально заменить весь блок на другой из шаблона - результат будет не эквивалентен. И синтезатору останется только минимизировать заданную через RTL функцию; ничего принципиально он поменять уже не может.

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

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


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

16 hours ago, RobFPGA said:

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

А вот этот пункт в меню: "Use the dedicated multiplier circuitry", он для большого проекта точно выбран?

LPM_MULT.jpg

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


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

Приветствую!

4 hours ago, blackfin said:

А вот этот пункт в меню: "Use the dedicated multiplier circuitry", он для большого проекта точно выбран?

Естественно!   Вот что представляет собой генерируемая "корка" LPM_MULT

Spoiler

module mul_i64_i32_i96_p4 (
	clock,
	dataa,
	datab,
	result);

	input         clock ;
	input  [63:0] dataa ;
	input  [31:0] datab ;
	output [95:0] result;

	wire [95:0] sub_wire0                  ;
	wire [95:0] result    = sub_wire0[95:0];

	lpm_mult lpm_mult_component (
		.clock (clock    ),
		.dataa (dataa    ),
		.datab (datab    ),
		.result(sub_wire0),
		.aclr  (1'b0     ),
		.clken (1'b1     ),
		.sclr  (1'b0     ),
		.sum   (1'b0     )
	);

	defparam
		lpm_mult_component.lpm_hint           = "DEDICATED_MULTIPLIER_CIRCUITRY=YES,MAXIMIZE_SPEED=9," // or for defaut - "MAXIMIZE_SPEED=9",
		lpm_mult_component.lpm_pipeline       = 4,
		lpm_mult_component.lpm_representation = "SIGNED",
		lpm_mult_component.lpm_type           = "LPM_MULT",
		lpm_mult_component.lpm_widtha         = 64,
		lpm_mult_component.lpm_widthb         = 32,
		lpm_mult_component.lpm_widthp         = 96;

endmodule

// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info : PRIVATE   : AutoSizeResult NUMERIC           "1"
// Retrieval info : PRIVATE   : B_isConstant NUMERIC             "0"
// Retrieval info : PRIVATE   : ConstantB NUMERIC                "0"
// Retrieval info : PRIVATE   : INTENDED_DEVICE_FAMILY STRING    "Stratix V"
// Retrieval info : PRIVATE   : LPM_PIPELINE NUMERIC             "4"
// Retrieval info : PRIVATE   : Latency NUMERIC                  "1"
// Retrieval info : PRIVATE   : SYNTH_WRAPPER_GEN_POSTFIX STRING "1"
// Retrieval info : PRIVATE   : SignedMult NUMERIC               "1"
// Retrieval info : PRIVATE   : USE_MULT NUMERIC                 "1"
// Retrieval info : PRIVATE   : ValidConstant NUMERIC            "0"
// Retrieval info : PRIVATE   : WidthA NUMERIC                   "64"
// Retrieval info : PRIVATE   : WidthB NUMERIC                   "32"
// Retrieval info : PRIVATE   : WidthP NUMERIC                   "96"
// Retrieval info : PRIVATE   : aclr NUMERIC                     "0"
// Retrieval info : PRIVATE   : clken NUMERIC                    "0"
// Retrieval info : PRIVATE   : new_diagram STRING               "1"
// Retrieval info : PRIVATE   : optimize NUMERIC                 "1"
// Retrieval info : LIBRARY   : lpm lpm.lpm_components.all
// Retrieval info : CONSTANT  : LPM_HINT STRING "DEDICATED_MULTIPLIER_CIRCUITRY=YES,MAXIMIZE_SPEED=9" // or for defaut - "MAXIMIZE_SPEED=9" 
// Retrieval info : CONSTANT  : LPM_PIPELINE NUMERIC             "4"
// Retrieval info : CONSTANT  : LPM_REPRESENTATION STRING        "SIGNED"
// Retrieval info : CONSTANT  : LPM_TYPE STRING                  "LPM_MULT"
// Retrieval info : CONSTANT  : LPM_WIDTHA NUMERIC               "64"
// Retrieval info : CONSTANT  : LPM_WIDTHB NUMERIC               "32"
// Retrieval info : CONSTANT  : LPM_WIDTHP NUMERIC               "96"
// Retrieval info : USED_PORT : clock  0 0  0 0 INPUT NODEFVAL   "clock"
// Retrieval info : USED_PORT : dataa  0 0 64 0 INPUT NODEFVAL   "dataa[63..0]"
// Retrieval info : USED_PORT : datab  0 0 32 0 INPUT NODEFVAL   "datab[31..0]"
// Retrieval info : USED_PORT : result 0 0 96 0 OUTPUT NODEFVAL  "result[95..0]"
// Retrieval info : CONNECT   : @clock 0 0  0 0 clock   0 0  0 0
// Retrieval info : CONNECT   : @dataa 0 0 64 0 dataa   0 0 64 0
// Retrieval info : CONNECT   : @datab 0 0 32 0 datab   0 0 32 0
// Retrieval info : CONNECT   : result 0 0 96 0 @result 0 0 96 0
// Retrieval info : GEN_FILE  : TYPE_NORMAL mul_i64_i32_i96_p4.v TRUE
// Retrieval info : GEN_FILE  : TYPE_NORMAL mul_i64_i32_i96_p4.inc FALSE
// Retrieval info : GEN_FILE  : TYPE_NORMAL mul_i64_i32_i96_p4.cmp FALSE
// Retrieval info : GEN_FILE  : TYPE_NORMAL mul_i64_i32_i96_p4.bsf FALSE
// Retrieval info : GEN_FILE  : TYPE_NORMAL mul_i64_i32_i96_p4_inst.v TRUE
// Retrieval info : GEN_FILE  : TYPE_NORMAL mul_i64_i32_i96_p4_bb.v TRUE
// Retrieval info : GEN_FILE  : TYPE_NORMAL mul_i64_i32_i96_p4_syn.v TRUE
// Retrieval info : LIB_FILE  : lpm

 

Я перепробовал разные варианты за исключением умножителя на чистой логике.  Все варианты после синтеза в Qu  дают нетлист  (post-mapping) в котором сначала  комбинаторный умножитель на DSP блоках и доп. сумматорах на логике (без единого регистра внутри),  а затем уж паровозик pipeline регистров.  И только после P&R (если звезды сложатся удачно)  эти регистры будут вдвинуты в DSP блоки и промежуточные сумматоры. :unknw:

Чесно говоря я в недоумении.   Вот только что - сделал clean рабочего проекта  забыв при этом что после этого надо опять сделать import  partitions. В результате через час опять туча ошибок времянке в этом не оптимизированном умножителе.  

Удачи! Rob.

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


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

Тоже когда то столкнулся с подобным поведением IP комплексного умножителя когда нужно было выжать высокую рабочую частоту. Тоже видел чудеса "на чистой логике", попытки увеличения количества регистров приводили к "паровозику pipeline регистров". Нужную частоту выжать так и не удалось. Немного покувыркавшись забил на это дело, написал свой умножитель и пользуюсь им до сих пор. А по слэкам даже небольшой запас образовался. Если что-то нароете - делитесь.

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


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

On 4/24/2020 at 7:09 PM, RobFPGA said:

Есть у меня в дизайне модуль где стоит простенький умножитель - i96 = i64 x i32,  pipeline 4 такта..

Но вот решил я (от скуки сидя в карантине) поднять рабочую частоту дизайна до 250 MHz.

Ну думаю - может подкину ему еще  1-2 дополнительных pipeline и все будет ок.

11 hours ago, RobFPGA said:

И только после P&R (если звезды сложатся удачно)  эти регистры будут вдвинуты в DSP блоки и промежуточные сумматоры.

На мой взгляд, нужно все-таки увеличивать длину конвейера.

 

Ради спортивного интереса только что сделал pipeline FFT на 4096 комплексных точек.

Вся арифметика в комплексных 48-ми битных числах.

ALTMULT_COMPLEX для 48-ми битных чисел с latency = 12 clock cycles.

LPM_MULT не используется.

Чип 5SEEBH40I2,

Total DSP Blocks = 180,

Fmax = 376 MHz.

 

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


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

Приветствую!

1 minute ago, blackfin said:

На мой взгляд, нужно все-таки увеличивать длину конвейера.

Вы не поняли - дело не в длине конвейера. А в том что Qu по непонятной причине иногда не размещает эти регистры в нужных местах этого конвейера.

Для моих частот и 4 такта  вполне достаточно.  На тестовой "кошечке"  при 4 тактах умножитель давал ~390 MHz, а при 5 и более  ~420. 

Удачи! Rob

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


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

На местном фтп должен лежать тул Synopsys DC. После установки, если порыться в его папках, можно найти библиотеки dw (design ware) на верилоге - это параметризуемые модули для всевозможных исполнений сумматоров, умножителей, сдвигателей и прочей мелкой логики, вот полный список https://www.synopsys.com/dw/buildingblock.php

Берете оттуда какой нибудь DW02_mult_4_stage и вставляете себе в проект с нужными параметрами. Как вариант, чтобы не зависеть от рандома синтезатора. Исходник лучше обфусцировать, на всякий.

 

p.s.

Вероятно, даже инсталлировать не надо - просто растарить архив с дистрибутивом. И лучше брать старую версию тула - года 2010-2013, т.к. в более новых может и не оказаться исходников (давно не искал эти файлы).

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

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


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

18 часов назад, blackfin сказал:

На мой взгляд, нужно все-таки увеличивать длину конвейера.

Очень странно от вас это слышать, вы не обращаете внимания на "паровозик pipeline регистров"

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


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

18 hours ago, _sda said:

Очень странно от вас это слышать, вы не обращаете внимания на "паровозик pipeline регистров"

Да, признаю, штатными настройками ни в Q18, ни в Q20_Pro решить эту проблему не удается.. Удивлен..

Но, справедливости ради, в реальных задачах ЦОС умножать комплексные числа с разрядностью больше 24 бит не приходилось.

Потому даже не догадывался о существовании таких проблем.

Ну и Quartus я уже давно заменил на Vivado и, как видно, не зря..

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


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

Приветствую!

On 4/25/2020 at 7:31 PM, Aleх said:

Берете оттуда какой нибудь DW02_mult_4_stage и вставляете себе в проект с нужными параметрами.

У меня и своего похожего добра есть немало. Но правда в основном под Xilinx заточено.
Вопрос скорее не в том как сделать mult,  а понять  тонкости работы с Qu чтобы упростить себе работу в будущем и получать прогнозируемые результаты. Ведь не факт что похожее только с mult случается.  Например похожая по непонятности  ситуация  с  атрибутом синтеза maxfan.  На который как я вижу Qu кладет свой maxfuck.  Есть  регистр кормящий  адреса памяти. Памяти много, соответственно fanout на линии адреса получается под 400. И как назло на одной линии вылазит slack -0.059 ns!!!   Ставлю атрибут ограничение maxfan 64 -  получаю болт переменной толщины - часть адреса с fanout 50 часть с 100, часть все так же ~400 :shok:

Удачи! Rob.

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


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

Проблема понятна, вся наша работа - борьба с тулами ) К сожалению, работа одних тулов еще както прозрачна, а вот других - абсолютно черный ящик. Я решение подобных проблем называю костылями, к примеру - проблему с фанаутом я бы решил, продублировав регистр в коде (и распределив фанаут), и запретив синтезатору вычищать дубликаты. Иначе как костылем не назовешь. А вот мой бывший шеф очень не любит это слово. Но - костыли повсюду.

 

Возвращаясь к работе тула - квартус, это капитально черный ящик, и слишком много влияющих факторов, чтобы придумать 100% рабочий рецепт. Но, кое что о работе синтезаторов известно. В частности, консультанты по тулам прямо рекомендуют - не пытайтесь вылизывать мелкие нарушения, если где то сидит огромное нарушение тайминга - тул будет пытаться вылечить большое нарушение, гробя все остальное в дизайне. Второй их совет - тул дает намного лучший результат, когда нарушения в целом по дизайну около нулевые. Эффективность работы тула тем больше, чем меньше его зажимают констрейнтами, а под прессом он работает соверщенно отвратительно. Таким образом, алгоритм работы: сначала капитально лопатим код и констрейнты, пока не уйдут гигантские слаки (можно слегка понизить частоту, чтобы совсем уж не насиловать тул - это прямо влияет на рантайм), и лишь затем накатываем боевые констрейнты и приступаем к тюнингу. Такие вот рекомендации. Конечно, сами консультанты тоже не знают, как работает тул, но всех их рекомендации исходят от r&d. А вот этих ребят уже надо слушать.

 

Сорри за простыню текста - карантин ) И сорри, если написал очевидное. Но, резюмирую конкретно по вашей проблеме - попробуйте расслабить другие узкие места, понизить частоты. Возможно, маленькая проблема с умножителем - только следствие большой проблемы в каком то другом месте. 

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


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

Как назло, какуса давно нет на машине, но вот, ЕМНИП там есть очень интересная настройка, как воспринимать регистры вокруг аппаратных макросов. Я всегда ее ставил в режим : тащи все в ДСП ячейчки, экономь мне ресурс. Тогда как часто ква, по непонятным мне причинам, делал асинхронные ДСП ячейки и все регистры наружу) 

еще у него косяк был, не помню с какой версии, но он перестал разбивать ДСП ячейки, штатно у него умножитель в доке 4 9х9 или 2 18х18, но вот он их не склеивал, делал все раздельно, даже в проектах с высоким уровнем заполнения и  использования ДСП

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


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

12 hours ago, des00 said:

... там есть очень интересная настройка, как воспринимать регистры вокруг аппаратных макросов...

Там есть две настройки, которые вроде бы должны влиять:

DSP_Block_Balancing.thumb.jpg.cef5b6ffd4b4aa4dd5d8bf3d2f75516c.jpg

Auto_Packed_Registers.thumb.jpg.4c669b4c097e621b587be88184444e87.jpg

 

Два дня назад я все их перепробовал (есс-но, за исключением "Logic Elements" и "Off").

Оба Quartus'а (Q18 и Q20) их успешно проигнорировали. :)

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


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

1 hour ago, blackfin said:

Там есть две настройки, которые вроде бы должны влиять:

DSP_Block_Balancing.thumb.jpg.cef5b6ffd4b4aa4dd5d8bf3d2f75516c.jpg

Auto_Packed_Registers.thumb.jpg.4c669b4c097e621b587be88184444e87.jpg

 

Два дня назад я все их перепробовал (есс-но, за исключением "Logic Elements" и "Off").

Оба Quartus'а (Q18 и Q20) их успешно проигнорировали. :)

они, у меня всегда стояло DSP blocks, Minimize Area. правда я выше 15.1 квартуса не прыгал, не меняю коней на переправах) Ну а про игнор в последних - индусы( 

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


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

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

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

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

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

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

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

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

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

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