Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers

Devide in VHLD

Altera_Forum
Honored Contributor II
6,026 Views

I want to implement this function : A<= B/x"A", when I compile, the Quartus put a notice: "/" used but didn't declare. 

When I try with "*" (multiply) or "+" (add), it is ok. 

I don't know this error, Please help me. 

Thank you very much.
0 Kudos
37 Replies
Altera_Forum
Honored Contributor II
1,148 Views

The Std_logic_arith library does not have a divide function. The numeric_std library has a divide function, so try that instead. 

 

BUT - Divide is very resource intensive, and doing it in 1 clock cycle will cause the FMax to drop. Use the lpm_divide megafunction instead.
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

 

--- Quote Start ---  

The Std_logic_arith library does not have a divide function. 

--- Quote End ---  

 

It has, but only for integer data type. numeric_std supports inference of divider MegaFunction for signed and unsigned data types.
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

"/" for integers is not part of std_logic_arith, it is part of the standar library.

0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

Thank you very much. I had finish my exercise. I used lpm_devide.

0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

When I use Modelsim to simulate VHDL code, It show an error with LPM library? 

I want to use devide command with lpm library, what should I do? 

Thank you very much.
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

take a look at the ModelSim documentation: 

 

http://www.altera.com/literature/hb/qts/qts_qii53001.pdf
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

 

--- Quote Start ---  

take a look at the ModelSim documentation: 

 

http://www.altera.com/literature/hb/qts/qts_qii53001.pdf 

--- Quote End ---  

 

 

Thank you very much.
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

Dear my friend 

I use While loop to implement divide algorithm in VHDL. But I met an error. Could you help me to solve this problem. 

Thank you very much. 

This is my code: 

library IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_arith.all; USE IEEE.std_logic_signed.all; Entity Devide_Modelsim is Port ( Devidend,Devider : In std_logic_vector(7 downto 0); Quotients : Out std_logic_vector(7 downto 0)); end Devide_Modelsim; Architecture structural of Devide_Modelsim is Signal Remainder : std_logic_vector(7 downto 0):=devidend; Signal Result : std_logic_vector(7 downto 0); Begin Process(Remainder,Devider,result) Begin While (Remainder > Devider) loop Result<=Result+"1"; Remainder<=Remainder-Devider; End loop; Quotients<=result; end process; end structural;  

and this is error: 

 

--- Quote Start ---  

 

Error (10536): VHDL Loop Statement error at Divide.vhd(17): loop must terminate within 10,000 iterations 

Error: Can't elaborate top-level user hierarchy 

Error: Quartus II Analysis & Synthesis was unsuccessful. 2 errors, 0 warnings 

Info: Allocated 324 megabytes of memory during processing 

Error: Processing ended: Fri Dec 10 18:47:32 2010 

Error: Elapsed time: 00:00:09 

Error: Quartus II Full Compilation was unsuccessful. 2 errors, 0 warnings 

 

--- Quote End ---  

 

In my opinion, this loop did not pass over 10.000 but it still error.
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

You should not use loops to calculate values. Loops unroll into parrallel hardware.  

 

For loops do this quite nicely. While loops are more complicated and do not really map into hardware very well. Avoid using while loops in synthesisable code at all costs.
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

The loop is infinite if 'Devider' is 0. No synthesizer will be able to synthesize this. It will also probably give strange results with a negative divider. 

While you are at it, you should use ieee.numeric_std and the signed and unsigned types rather than ieee.std_logic_signed. numeric_std is standard, makes it easier to mix signed and unsigned arithmetic, and makes the code more readable and maintainable. 

 

As tricky said even if you fixed this, it will result in massive parallel hardware, which probably isn't what you want. If you don't need the result in a single clock cycle, you should consider unrolling the operation over several cycles to get a much smaller hardware footprint.
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

And I didn't see it at first, but as the process is using signals and not variables, the Remainder and Result signals can be considered as fixed during the process execution, and only updated once you get out of the process. So in fact I think that the loop is infinite in any case.

0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

 

--- Quote Start ---  

You should not use loops to calculate values. Loops unroll into parrallel hardware.  

 

For loops do this quite nicely. While loops are more complicated and do not really map into hardware very well. Avoid using while loops in synthesisable code at all costs. 

--- Quote End ---  

 

 

Thank you very much. I'm very venous, I try a lot of method but now i still can not finish my project. I must try to make divide comment by code. If i don't use while or for loop, i can not have the result of divide comment. Do you have any suggest for this?
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

something like this... 

 

 

-- A_in/B_in = R (& rem remainder) 

-- R, rem initialised to zero 

-- A = abs(A_in), B = abs(B_in) 

 

clked process... rem <= A - B * R; if rem >= B then R <= R + 1; else result_out <= R; -- also decide sign here remainder_out <= rem; done <= '1'; end if; if B = 0 then alarm <= '1'; end if;
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

 

--- Quote Start ---  

The loop is infinite if 'Devider' is 0. No synthesizer will be able to synthesize this. It will also probably give strange results with a negative divider. 

While you are at it, you should use ieee.numeric_std and the signed and unsigned types rather than ieee.std_logic_signed. numeric_std is standard, makes it easier to mix signed and unsigned arithmetic, and makes the code more readable and maintainable. 

 

--- Quote End ---  

 

Ok. If the "Devider" is 0, the loop will infinite. Thank you for your advise. I will change to use numeric_std. 

 

 

--- Quote Start ---  

 

As tricky said even if you fixed this, it will result in massive parallel hardware, which probably isn't what you want. If you don't need the result in a single clock cycle, you should consider unrolling the operation over several cycles to get a much smaller hardware footprint. 

 

--- Quote End ---  

 

 

I want this process must finish before go to next step therefore i use loop. Do you have any idea for this process?
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

 

--- Quote Start ---  

something like this... 

 

 

-- A_in/B_in = R (& rem remainder) 

-- R, rem initialised to zero 

-- A = abs(A_in), B = abs(B_in) 

 

clked process... rem <= A - B * R; if rem >= B then R <= R + 1; else result_out <= R; -- also decide sign here remainder_out <= rem; done <= '1'; end if; if B = 0 then alarm <= '1'; end if;  

--- Quote End ---  

 

 

Thank Kaz very much. I try it now.
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

I had finished my program. But I don't know how to make sign for the value less than 0. Can you help me? 

This is my code 

library IEEE; USE IEEE.std_logic_1164.all; USE IEEE.std_logic_arith.all; --USE IEEE.numeric_std.all; USE IEEE.std_logic_unsigned.all; Entity Devide is Port ( A,B : In std_logic_vector(7 downto 0); --A/B Quotients,Remainder_out : Out std_logic_vector(7 downto 0); CLK : In std_logic); end Devide; Architecture structural of Devide is Signal Remainder,Divider : std_logic_vector(7 downto 0);--:=dividend; Signal Result : std_logic_vector(7 downto 0); Signal CNT : std_logic_vector(3 downto 0); Begin Process(clk) Begin if clk='1' and clk'event then cnt<=cnt+1; if cnt="0000" then if B="00000000" then cnt<="0000"; else Remainder<= ABS (signed(A)); --Remainder = ABS(A) Divider<= ABS (signed(B)); -- Divider = ABS(B) end if; elsif cnt="0001" and Remainder >= Divider then Result<=Result+1; Remainder<=Remainder-Divider; elsif cnt="0010" and Remainder >= Divider then cnt<="0001"; elsif cnt="0011" then Quotients<=result; Remainder_out<=Remainder; elsif cnt="0100" then cnt<="0000"; result<="00000000"; end if; end if; end process; end structural;
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

comment out std_logic_arith and std_logic_unsigned packages. Bring back numeric_std package. 

 

Then make remainder and divider signals signed types. You cannot assign a "signed" type to a std_logic_vector.
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

 

--- Quote Start ---  

comment out std_logic_arith and std_logic_unsigned packages. Bring back numeric_std package. 

 

Then make remainder and divider signals signed types. You cannot assign a "signed" type to a std_logic_vector. 

--- Quote End ---  

 

 

Thanks tricky 

I have a big problem with this code. If A,B> 0, It's OK. But A or B < 0. the result not correct. 

Could you help me? 

 

library IEEE; USE IEEE.std_logic_1164.all; USE IEEE.numeric_std.all; Entity Devide is Port ( A,B : In Signed(7 downto 0); --A/B Quotients,Remainder_out : Out Signed(7 downto 0); CLK : In std_logic); end Devide; Architecture structural of Devide is Signal Remainder,Divider : Signed(7 downto 0); Signal Result : Signed(7 downto 0); Signal CNT : unSigned(3 downto 0); Begin Process(clk) Begin if clk='1' and clk'event then cnt<=cnt+"1"; if cnt="0000" then if B="00000000" then cnt<="0000"; else Remainder<= A;--ABS (signed(A)); --Remainder = ABS(A) Divider<= B;--ABS (signed(B)); -- Divider = ABS(B) end if; elsif cnt="0001" and Remainder >= Divider then Result<=Result+1; Remainder<=Remainder-Divider; elsif cnt="0010" and Remainder >= Divider then cnt<="0001"; elsif cnt="0011" then Quotients<=result; Remainder_out<=Remainder; elsif cnt="0100" then cnt<="0000"; result<="00000000"; end if; end if; end process; end structural;
0 Kudos
Altera_Forum
Honored Contributor II
1,148 Views

what you want to do is take the absolute of A and B, but also store the signedness of them and follow these rules: 

 

If A and B are the same (ie. both positive or both negative), then result is positive. 

If A and B are different, then the result is negative. 

 

At the moment, you only ever create a postive result because you only ever add 1. You need to stick the XOR of MSBs of A and B into a shift register and then negate the output when needed.
0 Kudos
Altera_Forum
Honored Contributor II
1,040 Views

 

--- Quote Start ---  

what you want to do is take the absolute of A and B, but also store the signedness of them and follow these rules: 

 

If A and B are the same (ie. both positive or both negative), then result is positive. 

If A and B are different, then the result is negative. 

 

At the moment, you only ever create a postive result because you only ever add 1. You need to stick the XOR of MSBs of A and B into a shift register and then negate the output when needed. 

--- Quote End ---  

 

 

 

Oh. Thank you very much. That's a good idea. 

I have more question: 

To display -5 => 11111011 

-3 => 11111101 

How to change from 5 (00000101_binary) > -5 (11111011_binary)
0 Kudos
Reply