rounding to integer

V

valentin tihomirov

This line is synthesizable but result is truncated (according to
simulation):
constant DIVIDER: integer := Frequency / BaudRate / 16;

The following rounds to closest integer but works only in simulator:
constant DIVIDER: integer := integer(real(Frequency) / real(BaudRate) /
real(16)); -- not synthetable
Synplify tells "Right argument must evaluate to a constant integer power of
2".


How could I implement a synthesizable round function? Please note, the
floating-point arithmetics is required at compile time only, not at
run-time.
 
E

Egbert Molenkamp

Interesting. I tried the following with Leonardo Spectrum.
Maybe as work around the second solution can be used?

library ieee;
use ieee.std_logic_1164.all;

entity funny is
port (d : out integer);
end entity funny is;

architecture demo of funny is
constant a : real := 10.0E2;
constant b : real := 0.50;
begin
-- d <= integer (a/b); --Leonardo Spectrum supports this

-- Work around .. multiply both operands with a (large) constant before
division?
d <= integer(1000.0*a)/integer(1000.0*b) ;

end architecture demo;

Egbert Molenkamp
 
J

Jonathan Bromley

hi Valentin,

This line is synthesizable but result is truncated (according to
simulation):
constant DIVIDER: integer := Frequency / BaudRate / 16;

The following rounds to closest integer but works only in simulator:
constant DIVIDER: integer := integer(real(Frequency) / real(BaudRate) /
real(16)); -- not synthetable
Synplify tells "Right argument must evaluate to a constant integer power of
2".

How could I implement a synthesizable round function? Please note, the
floating-point arithmetics is required at compile time only, not at
run-time.

As we have regretted here on many previous occasions, most simulators
do not allow you to perform floating-point arithmetic even at
compile time.

The integer divide operator / is defined to truncate, as you
observed. But I think you can easily modify it to make a
round-to-nearest divide, using this relationship:

round(A/B) == trunc( (A+B/2) / B)

So your constant could be defined like this...

constant DIVIDER: integer :=
(Frequency + 8 * BaudRate) / (16 * BaudRate);

cheers
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: (e-mail address removed)
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top