0
\$\begingroup\$

I was thinking about the range a result signal should have to acommodate an unsigned fixed point division. Suppose we have:

SIGNAL a : UFIXED (3 DOWNTO -3);

SIGNAL b : UFIXED (4 DOWNTO -2);

am I wrong assuming:

SIGNAL y <= a/b should have

y'RANGE = (a'LEFT - b'RIGHT DOWNTO a'RIGHT - b'LEFT +1)

to acommodate any resulting y from this division?

asked Nov 10, 2017 at 13:43
\$\endgroup\$
2
  • 2
    \$\begingroup\$ According to the source the for fixed_generic_pkg body the return value will have a range calculated by -- ufixed(a downto b) / ufixed(c downto d) = ufixed(a-d downto b-c-1),"/" [UNRESOLVED_ufixed, UNRESOLVED_ufixed return UNRESOLVED_ufixed] calls an internal function divide where the comment is found. That'd be 3 - -2 downto -3 - 4 - 1 or y(5 downto -8). divide converts the l and r arguments to unsigned and uses numeric_std "/"[unsigned, unsigned return unsigned] converting the return value to the result range. \$\endgroup\$ Commented Nov 10, 2017 at 17:47
  • \$\begingroup\$ Oh, I realized I typoed my question, it is supposed to be -1 on the right side (DOWNTO a'RIGHT - b'LEFT -1), of course. The question arised after spotting an inconsistency in the V.Pedroni's book on Circuit Design and Simulation with VHDL 2nd ed. Page 57. "a/b unsigned: Range is a'LEFT - b'RIGHT DOWNTO a'RIGHT + b'LEFT - 1." \$\endgroup\$ Commented Nov 11, 2017 at 18:17

1 Answer 1

2
\$\begingroup\$

There's a divide function declared in IEEE package that demonstrates the correct arithmetic for finding the bounds of the divide operator:

-- ufixed(a downto b) / ufixed(c downto d) = ufixed(a-d downto b-c-1)

And because the rules for bounds can be complex there are functions (ufixed_high, ufixed_low) where you pass the operation:

library ieee;
use ieee.std_logic_1164.all;
use ieee.fixed_pkg.all;
entity ufixed_div_range is
end entity;
architecture fum of ufixed_div_range is
 signal a : ufixed (3 downto -3); 
 signal b : ufixed (4 downto -2);
begin
 a <= to_ufixed(1.75, a'LEFT, a'RIGHT);
 b <= to_ufixed(2.5, b'LEFT, b'RIGHT);
 process 
 variable result: ufixed 
 (ufixed_high(a, '/', b) downto ufixed_low(a, '/', b));
 begin
 wait for 1 ns;
 result := a/b;
 report LF & HT & "to_real(result) = " & real'image(to_real(result))
 & LF & HT & "result'LEFT = " & integer'image(result'left)
 & LF & HT &"result'RIGHT = " & integer'image(result'right);
 wait;
 end process;
end architecture;

And when run this gives:

ufixed_div_range.vhdl:35:9:@1ns:(report note):
 to_real(result) = 6.9921875e-1
 result'LEFT = 5
 result'RIGHT = -8

Noting that the real value is dependent on both the result accuracy (number of fraction bits) and rounding modes. (And reals are approximate anyway).

This was demonstrated using VHDL-2008.

answered Nov 11, 2017 at 19:00
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.