- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"/" for integers is not part of std_logic_arith, it is part of the standar library.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you very much. I had finish my exercise. I used lpm_devide.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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)
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page