shaiko
Advanced Member level 5
- Joined
- Aug 20, 2011
- Messages
- 2,644
- Helped
- 303
- Reputation
- 608
- Reaction score
- 297
- Trophy points
- 1,363
- Activity points
- 18,302
function restoring_divide ( numerator : unsigned ; denominator : unsigned ) return unsigned is
variable temp_numerator : unsigned ( numerator ' range ) := numerator ;
variable temp_denominator : unsigned ( denominator ' range ) := denominator ;
variable temp_remainder : unsigned ( denominator ' length downto 0 ) := ( others => '0' ) ;
begin
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 ;
end function restoring_divide ;
int_vector_signal := (to_integer(temp_numerator));
--and similar for variables. where int_vector_signal is variable of type integer
--After you perform all calucations you can reconvert it back to unsigned.
--Use unsigned(<final_result>, , denominator'length);
den1(3 downto 0)
The problem is that when the "numerator" and "denumerator" are of different length, the division fails.
I want the denumerator to adjust its length "automatically" to the length of the numerator. for example:
If the numerator is "10000010" and the denumerator is "110" - I want the denumerator to be "padded" with zeroes to fit itself to the bit width of the numerator and become: "00000110"
if numerator'length > demonitor'length then
x := resize(denominator, numerator'length);
end if;
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 ;
How is it called ?There is already a divide function in numeric_std for signed and unsigned
- Besides speed, the other big drawback to simply using '/' is that it will take a lot of logicI'm aware of the limitations of pure combinatorial division logic. I don't intend to use it for high throughput applications.
I simply wanted something that's abstract, works correctly and synthesizes with ANY tool...
Other than very low throughput - do you see something wrong with my code above ?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?