Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

what's wrong with my division function?

Status
Not open for further replies.

shaiko

Advanced Member level 5
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.
 
  • Like
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.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top