what's wrong with my division function?

Status
Not open for further replies.

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Visit site
Activity points
18,302
I wrote this division function:

Code:
function restoring_divide 
( numerator : 	unsigned ; 
denominator : 	unsigned ) return unsigned is
    variable temp_numerator : unsigned ( numerator ' range ) := numerator ;
    variable temp_numerator_with_denominator_length : unsigned ( denominator ' range ) := (others => '0' ) ;	
    variable temp_denominator : unsigned ( denominator ' range ) := denominator ;
    variable temp_denominator_with_numerator_length : unsigned ( numerator ' range ) := ( others => '0' ) ;	
    variable temp_remainder : unsigned ( denominator ' length downto 0 ) := ( others => '0' ) ;
    variable temp_remainder_with_numerator_length : 	
    unsigned ( numerator ' length downto 0 ) := ( others => '0' ) ;	



begin
if numerator ' length = denominator ' length then 
for index in 0 to denominator ' length - 1 
loop
temp_remainder ( denominator ' length - 1 downto 1 ) := 
temp_remainder ( denominator ' length - 2 downto 0 ) ;
temp_remainder ( 0 ) := temp_numerator ( numerator ' length - 1 ) ;
temp_numerator ( numerator ' length - 1 downto 1 ) := temp_numerator  ( numerator ' length - 2 downto 0 ) ;
temp_remainder := temp_remainder - temp_denominator ;
if ( temp_remainder ( denominator ' length ) = '1' ) then
temp_numerator ( 0 ) := '0' ;
temp_remainder := temp_remainder + temp_denominator ;
else
temp_numerator ( 0 ) := '1' ;
end if ;
end loop ;
return temp_numerator ;
		


elsif numerator ' length > denominator ' length then 



temp_denominator_with_numerator_length := resize ( denominator , numerator ' length ) ;	
for index in 0 to temp_denominator_with_numerator_length ' length - 1 
loop
temp_remainder_with_numerator_length ( temp_denominator_with_numerator_length ' length - 1 downto 1 ) := 
temp_remainder_with_numerator_length ( temp_denominator_with_numerator_length ' length - 2 downto 0 ) ;
temp_remainder_with_numerator_length ( 0 ) := temp_numerator ( numerator ' length - 1 ) ;
temp_numerator ( numerator ' length - 1 downto 1 ) := temp_numerator ( numerator ' length - 2 downto 0 ) ;
temp_remainder_with_numerator_length := temp_remainder_with_numerator_length - temp_denominator ;
if ( temp_remainder_with_numerator_length ( temp_denominator_with_numerator_length ' length ) = '1' ) then
temp_numerator ( 0 ) := '0' ;
temp_remainder_with_numerator_length := temp_remainder_with_numerator_length + temp_denominator ;
else
temp_numerator ( 0 ) := '1' ;
end if ;
end loop ;
return temp_numerator ;

			
else 


temp_numerator_with_denominator_length := resize ( numerator , denominator ' length ) ;	
for index in 0 to denominator ' length - 1 
loop
temp_remainder ( denominator ' length - 1 downto 1 ) := temp_remainder ( denominator ' length - 2 downto 0 ) ;
temp_remainder ( 0 ) := temp_numerator_with_denominator_length ( temp_numerator_with_denominator_length ' length - 1 ) ;
temp_numerator_with_denominator_length ( temp_numerator_with_denominator_length ' length - 1 downto 1 ) := 
temp_numerator_with_denominator_length ( temp_numerator_with_denominator_length ' length - 2 downto 0 ) ;
temp_remainder := temp_remainder - temp_denominator ;
if ( temp_remainder ( denominator ' length ) = '1' ) then
temp_numerator_with_denominator_length ( 0 ) := '0' ;
temp_remainder := temp_remainder + temp_denominator ;
else
temp_numerator_with_denominator_length ( 0 ) := '1' ;
end if ;
end loop ;
return temp_numerator_with_denominator_length ;
end if ;			
end function restoring_divide ;

For some reason, it shows a fixed output value.
Example:

signal x,y,z : unsigned ( 13 downto 0 ) ;
x <= "00000000010100" ;
y <= "10011100010000" ;
z <= restoring_divide ( y , x ) ;

At simulation signal z becomes: "11111111111111"

- - - Updated - - -

When I rewrite it to:
Code:
z <= restoring_divide ( to_unsigned ( 10000 , 14 ) , to_unsigned ( 20 , 14 ) ) ;
-- instead of using :
--x <= "00000000010100" ;
--y <= "10011100010000" ;
Everything works fine...
 
Last edited:

For me both methods work fine.
Simulated both versions in Active-HDL.
 
Last edited:

I can confirm that the code simulates fine for me, embedding the function in an entity with ports x,y and z. (each 14 bit unsigned)
Code:
begin
z <= restoring_divide ( y , x ) ;
end;
Presumed you have created a difference between both simulation setups, the code snippets don't allow to recognize it.

What we can simulate without unambiguities would be an entity and a testbench.
 
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
strange.
I'll post my TB soon enough.

- - - Updated - - -

I think I found the source of the problem.
When the run key is hit, the test bench generates a fatal error on a completely different line of code (one that has nothing to do with the function).

I think that for some reason, Modelsim assigns ("behind the scene") an initial value of "11111111111111" to signal Z.
Then, when the run key is hit - the fatal error terminates the simulation and asserts value of Z without actually running:
z <= restoring_divide ( y , x ) ;

As soon I fix the cause of the fatal error, Z gets a proper value.

- - - Updated - - -

The cause of the fatal error is a subject for a new discussion.
I'm really baffled by it...you input will be much appreciated.
https://www.edaboard.com/threads/321801/
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…