1

Trying to do this

parameter integer PRECHARGE_CLOCKS = $ceil(PRECHARGE_NS / CLOCK_PERIOD_NS);

And then use the value in a comparion

if(InitPrechargeCounter < PRECHARGE_CLOCKS - 1)

But getting this error

Error (10174): Verilog HDL Unsupported Feature error at Ram.sv(23): system function "$ceil" is not supported for synthesis

Is there a way around this so that I get the value calculated at compile time?
Using some different language construct instead of parameter?

axk
  • 5,316
  • 12
  • 58
  • 96
  • This looks like a tool issue. Have you tried the latest version? This is a completely legal verilog and works on with other compilers. – Serge Sep 19 '18 at 02:08
  • Quartus Prime 18.0. I'm not a Verilog expert, but in my understanding there should be a way to make parameters calculations happen at compile time and it shouldn't be limited by what is synthesizable. But this is the way it is. – axk Sep 19 '18 at 12:05
  • yes, parameters should be resolved at elaboration time. One issue with this function is that it returns `real` value, which is not synthesizable. You can try to use `$rtoi($ceil(...))`. – Serge Sep 19 '18 at 16:09

2 Answers2

2

Try this:

parameter integer PRECHARGE_CLOCKS = ((PRECHARGE_NS + CLOCK_PERIOD_NS -1) / CLOCK_PERIOD_NS);

It should round up as what $ceil does.

Enze Chi
  • 1,733
  • 17
  • 28
  • There's a caveat to this, it only works if both PRECHARGE_NS and CLOCK_PERIOD_NS are integers, if they are not and then you're converting to integer Modelsim applies regular rounding rules as far as I see, so e.g. (66+10-1)/10 becomes 8 and not 7 as desired – axk Sep 18 '18 at 17:21
1

I ended up working around this with the following macro, this creates 2 extra parameters for the sake of rounding up, but this is the best solution I've found so far. This is not limited to integer arguments and works with real numbers. I've tested this with Quartus and Modelsim

`define Ceil(ParamName, Expression) \
 parameter ParamName``_F = Expression;\
 parameter integer ParamName``_R = ParamName``_F;\
 parameter integer ParamName = (ParamName``_R == ParamName``_F || ParamName``_R > ParamName``_F) ? ParamName``_R : (ParamName``_R + 1);

And then instead of

 parameter integer AUTOREFRESH_CLOCKS = $ceil(UTOREFRESH_NS/CLOCK_PERIOD_NS);

You would invoke the macro

`Ceil(AUTOREFRESH_CLOCKS, UTOREFRESH_NS/CLOCK_PERIOD_NS)

And this is not both synthesizable in Quartus and works in Modelsim

axk
  • 5,316
  • 12
  • 58
  • 96