1
\$\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?

\$\endgroup\$
  • 1
    \$\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\$ – user8352 Nov 10 '17 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\$ – cr4150n Nov 11 '17 at 18:17
0
\$\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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.