Krys 2 19 марта, 2016 Опубликовано 19 марта, 2016 · Жалоба Здравствуйте. Кто-нибудь может поделиться: нужны самодельные функции взамен системных для Verilog типа $clog2, $rtoi и т.д., а то тут внезапно выяснилось, что под старыми ПЛИСами xst не всё поддерживает. Берём одни и те же исходники, делаем синтез под spartan 6 - всё прекрасно. Меняем тип ПЛИС в свойствах проекта на Virtex 4 - синтезатор ругается на эти системные функции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Intekus 0 19 марта, 2016 Опубликовано 19 марта, 2016 · Жалоба Раз уж Вы забрели на тёмную территорию древних версий, делюсь тем, что есть :santa2: Более того, если функции двоичного логарифма используются для определения разрядности портов (а так чаще всего и бывает) - то там когда-то вылезала проблема, что iSim (или xst - не помню точно) не понимали, что функция - константная (т. е. может быть вычислена на этапе синтеза) и ругались, что переменную разрядность порта не допускают. Поэтому был рождён наиболее "дубовый" вариант - через макросы. Вопреки громоздкости (по идее) получающегося после подстановок кода - проблем не наблюдал. Выкладываю общеполезные, которые нашёл. Теоретически, там могут быть ошибки, но, вроде, всё работает. `define ISDEF(N) (^(N) >= 0 === 1'b1 || ^(N) < 0 === 1'b1) //"IS DEFined", is an //integer strictly defined; Xilinx warnings about "===" in synthesable //code - include in supression rules. //Why so complicated - I forgot :) `define TZER(N) (!`ISDEF(N) || (N) <= 0) ? 'hx : \ (~|((N)&'h7fff_ffff)?31:(~|((N)&'h3fff_ffff)?30: \ (~|((N)&'h1fff_ffff)?29:(~|((N)&'hfff_ffff)?28: \ (~|((N)&'h7ff_ffff)?27:(~|((N)&'h3ff_ffff)?26:(~|((N)&'h1ff_ffff)?25:(~|((N)&'hff_ffff)?24: \ (~|((N)&'h7f_ffff)?23:(~|((N)&'h3f_ffff)?22:(~|((N)&'h1f_ffff)?21:(~|((N)&'hf_ffff)?20: \ (~|((N)&'h7_ffff)?19:(~|((N)&'h3_ffff)?18:(~|((N)&'h1_ffff)?17:(~|((N)&'hffff)?16: \ (~|((N)&'h7fff)?15:(~|((N)&'h3fff)?14:(~|((N)&'h1fff)?13:(~|((N)&'hfff)?12: \ (~|((N)&'h7ff)?11:(~|((N)&'h3ff)?10:(~|((N)&'h1ff)?9:(~|((N)&'hff)?8: \ (~|((N)&'h7f)?7:(~|((N)&'h3f)?6:(~|((N)&'h1f)?5:(~|((N)&'hf)?4: \ (~|((N)&'h7)?3:(~|((N)&'h3)?2: \ (~N&'h1))))))))))))))))))))))))))))))) //"Trailong ZERoes". ONLY FOR ARGUMENTS <= 32 BITS! //Maximum 2's power divider of a number. Both for synthesis and simulation; bit //selection is not used since N could be an expression. `define CLOG2_CORE(N) \ ((N)&'h8000_0000 ?32:((N)&'h4000_0000 ?31:((N)&'h2000_0000 ?30:((N)&'h1000_0000 ?29: \ ((N)&'h800_0000 ?28:((N)&'h400_0000 ?27:((N)&'h200_0000 ?26:((N)&'h100_0000 ?25: \ ((N)&'h80_0000 ?24:((N)&'h40_0000 ?23:((N)&'h20_0000 ?22:((N)&'h10_0000 ?21: \ ((N)&'h8_0000 ?20:((N)&'h4_0000 ?19:((N)&'h2_0000 ?18:((N)&'h1_0000 ?17: \ ((N)&'h8000 ?16:((N)&'h4000 ?15:((N)&'h2000 ?14:((N)&'h1000 ?13: \ ((N)&'h800 ?12:((N)&'h400 ?11:((N)&'h200 ?10:((N)&'h100 ?9: \ ((N)&'h80 ?8:((N)&'h40 ?7:((N)&'h20 ?6:((N)&'h10 ?5: \ ((N)&'h8 ?4:((N)&'h4 ?3:((N)&'h2 ?2: \ ((N)&'h1)))))))))))))))))))))))))))))))) //"Core Ceil(LOG2(N+1))" for correctly defined //values (<= 32 bits). Both for synthesis and not; bit selection is not //used since N could be an expression. `define HZ2NS(F) (1.0e9 / (F)) //Convert frequency [Hz] to delay in [ns]. `define ABS(X) ((X >= 0) ? (X) : (-X)) //ABSolute value of X. `define CLOG2(N) ((!`ISDEF(N) || (N) <= 0) ? 'hx : `CLOG2_CORE((N)-1)) //"Ceil(LOG2(N))" //ONLY FOR ARGUMENTS <= 32 BITS! Ceil (nearest greater or equal integer) of //binary logarithm. `define WIDINPAR(W) ((W) >= 1 ? (W) : ((W) == 0 ? 1'b1 : 1'bx)) //"WIDth INdex from a //PARameter" ONLY FOR ARGUMENTS <= 32 BITS! High index of a bus from given //parameter, to avoid index "-1". //Ex.: bus with width W: "[widinpar(W)-1:0];" `define WIDC(N) (`ISDEF(N) && (N) == 0 ? 1 : `CLOG2((N) + 1)) //"WIDth Computation" //ONLY FOR ARGUMENTS <= 32 BITS! High index of a bus out of it's maximum //value (from 0). //Ex.: bus for holding numbers in range [0..N]: "wire [`WIDCF(N)-1:0] bus;" //Precision width of parameters: "localparam [`WIDCF(<expr>)-1:0] N = <expr>;" `define WIDCN(N) (`ISDEF(N) && ((N) == 0 || (N) == 1) ? 1 : `CLOG2(N)) //"WIDth Computation from N" //ONLY FOR ARGUMENTS <= 32 BITS! High index of a bus out of number of it's //different values. Handy for computation of high index of a bus. //Ex.: coder with N inputs output: "output [`WIDCFN(N)-1:0] out;"; //N-words RAM adress input: "input [`WIDCFN(N)-1:0] adr;" `define URAND(MIN, MAX) ((MAX) < (MIN) ? 1'bx : (((MAX) == (MIN)) ? (MIN) : \ (MIN + {$random} % ((MAX) - (MIN)))) ) //Form an unsigned random value in the range [MIN..MAX-1]; //"{}" makes unsigned. `define POS_FMOD(A, B) A - B * ($rtoi((A + 0.0) / B) + $signed(A < 0)) //Positive fraction //modulo. Only for POSITIVE dividers!!! `define ISHEXD(L) (`ISDEF(L) && ((L) >= "A" && (L) <= "F" || (L) >= "a" && (L) <= "f" || \ (L) >= "0" && (L) <= "9")) //IS byte a HEX Digit. x- and z- //bits are treated correctly. `define ISHEXDX(L) (`ISHEXD(L) || \ `ISDEF(L) && ((L) == "X" || (L) == "x")) //IS byte a HEX Digit or X/x. `define IS_DEC_INT_DIG(L) ((L) >= "0" && (L) <= "9") //Is a byte a valid decimal //integer digit. `define HEXD2DEC(L) (!`ISHEXD(L) ? \ 0 : \ ((L) >= "a" ? (L) - "a" + 10 : \ ((L) >= "A" ? (L) - "A" + 10 : \ (L) - "0"))) //Convert //HEXadecimal Digit to decimal number, on all incorrect inputs returns 0. Макросы сделаны так, что подставлять в них можно не только просто аргументы, но и выражения - точно как в функции. Аргументы везде взяты в скобки во избежание нарушения порядка операций. В основанных на двоичном логарифме - ограничение 32 бита на разрядность входа, будьте с этим аккуратны, когда вычисляется, например, разрядность счётчиков для задержек с очень большим ограничивающим сверху значением и т. д. А отсутствие $rtoi обходится использованием преобразования типа, выполняемым по умолчанию. В случае сложных выражений - приходится вводить временные переменные (или временные localparam'ы - смотря для чего используется). Вычисления везде практически "в лоб". За предложения упрощений и найденные ошибки буду благодарен - этот код до сих пор применяется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Sergei_Ilchenko 0 19 марта, 2016 Опубликовано 19 марта, 2016 · Жалоба О, а эти функции разве синтезируются? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 20 марта, 2016 Опубликовано 20 марта, 2016 · Жалоба О, а эти функции разве синтезируются? А почему бы и нет? Причём не только в константах. Для логарифма я использую простейшую функцию с циклом: function integer log2; input integer v; begin log2=0; while(2**log2 < v) log2=log2+1; end endfunction Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Krys 2 21 марта, 2016 Опубликовано 21 марта, 2016 · Жалоба Intekus большое спасибо! Я попробую ) А отсутствие $rtoi обходится использованием преобразования типа, выполняемым по умолчанию. В случае сложных выражений - приходится вводить временные переменные (или временные localparam'ы - смотря для чего используется).Вы могли бы подсказать, как обойти такую запись:localparam ACK_MIN_DUR_OUT = $rtoi(ACK_MIN_DUR_IN * CLK_RATIO + 0.5); Здесь CLK_RATIO может быть рациональным числом. Если я напрямую подставлю это в качестве ширины шины например, то будет ругаться, что только целые ему подавай. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 21 марта, 2016 Опубликовано 21 марта, 2016 · Жалоба Вы могли бы подсказать, как обойти такую запись:localparam ACK_MIN_DUR_OUT = $rtoi(ACK_MIN_DUR_IN * CLK_RATIO + 0.5); Здесь CLK_RATIO может быть рациональным числом. Если я напрямую подставлю это в качестве ширины шины например, то будет ругаться, что только целые ему подавай. Попробуйте localparam integer ACK_MIN_DUR_OUT = ACK_MIN_DUR_IN * CLK_RATIO + 0.5; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Krys 2 21 марта, 2016 Опубликовано 21 марта, 2016 · Жалоба Timmy, спасибо, попробую. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1891ВМ12Я 0 21 марта, 2016 Опубликовано 21 марта, 2016 · Жалоба Не думаю что будет большим оффтопом - речь об отсутствующих некоторых функциях: У кого есть функция синуса и косинуса? Такая что для тестбенчей, не для синтеза. О, а эти функции разве синтезируются? Это же макросы... ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
des00 25 21 марта, 2016 Опубликовано 21 марта, 2016 · Жалоба У кого есть функция синуса и косинуса? Такая что для тестбенчей, не для синтеза. $cos и $sin забанили ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 21 марта, 2016 Опубликовано 21 марта, 2016 · Жалоба $cos и $sin забанили ? В 2001-м году их ещё не открыли:). С другой стороны, непонятно, зачем использовать в тестбенчах 2001-й Верилог. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Krys 2 21 марта, 2016 Опубликовано 21 марта, 2016 · Жалоба И вообще верилог ))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Intekus 0 21 марта, 2016 Опубликовано 21 марта, 2016 · Жалоба Попробуйте localparam integer ACK_MIN_DUR_OUT = ACK_MIN_DUR_IN * CLK_RATIO + 0.5; Да, это я и имел в виду в А отсутствие $rtoi обходится использованием преобразования типа, выполняемым по умолчанию. В случае сложных выражений - приходится вводить временные переменные (или временные localparam'ы - смотря для чего используется). ALARM! При ACK_MIN_DUR_IN = 1,4 и CLK_RATIO = 1 Ваше исходное $rtoi выдаст "1", а предложенный вариант "2", т. к. при преобразовании типа выполняется округление, а не усечение дробной части (по крайней мере, в xst - проверил). Предполагаю, что "0.5" вводилось как раз для реализации округления через $rtoi, так что Вам предстоит убрать его во всех подобных выражениях и, вообще, все их перепроверить и адаптировать при необходимости. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Krys 2 21 марта, 2016 Опубликовано 21 марта, 2016 · Жалоба Именно так, для округления. Спасибо за подсказку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1891ВМ12Я 0 21 марта, 2016 Опубликовано 21 марта, 2016 · Жалоба $cos и $sin забанили ? Будь я проклят! Действительно есть, начиная с SystemVerilog-2005, видимо я всё время старый стандарт смотрел... Да там все мат функции что надо есть! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Krys 2 22 марта, 2016 Опубликовано 22 марта, 2016 · Жалоба Поэтому был рождён наиболее "дубовый" вариант - через макросы. `define URAND(MIN, MAX) ((MAX) < (MIN) ? 1'bx : (((MAX) == (MIN)) ? (MIN) : \ (MIN + {$random} % ((MAX) - (MIN)))) ) //Form an unsigned random value in the range [MIN..MAX-1]; //"{}" makes unsigned. `define POS_FMOD(A, B) A - B * ($rtoi((A + 0.0) / B) + $signed(A < 0)) //Positive fraction //modulo. Only for POSITIVE dividers!!! Тут вот тоже ненавистные синтезатору $rtoi встречаются ))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться