EmbDev.net

Forum: FPGA, VHDL & Verilog Troubles using arithmetics with VHDL


Author: Diogo (Guest)
Posted on:

Rate this post
0 useful
not useful
Hi guys,

I'm having some problems on doing some basic operations (sum, 
multiplication and division) on logic vectors. I've googled and 
discovered that I should type cast them to unsigned and then back to 
vectors. However, my code aint working and I would like you to take a 
look at it.
signal current_state : INTEGER := 0;
signal next_state : INTEGER := 0;

variable value: std_logic_vector(15 downto 0);
variable counter: integer := 0;
variable temp: unsigned (15 downto 0);
-- Line and Row are std_logic_vector (2 downto 0) signals

    counter := counter + 1;  
    temp := resize(unsigned(Line), 16) - resize(unsigned(Row), 16) + 1;
    temp := temp/(resize(unsigned(Row), 16));
    temp := temp*unsigned(value);
    value := std_logic_vector(temp);
    if counter < Row then
        next_state <= 1;
    else
        next_state <= 2;
    end if;

Is what I'm doing acceptable?

My "state machine" also dosen't seem to be working. Here's it's basic 
code:
P : process (Line, Row, Start, current_state)
begin

next_state = current_state; -- default is to keep on the same state
Done <= '0';

case current_state is
    when 0 =>
        if Start = '1'
            next_state = 1;
        else
            next_state = 0;
    when 1 =>
        if counter < Row then
            next_state <= 1;
        else
            next_state <= 2;
    when 2 =>
        -- display result
    when others =>
         assert false report "Invalid State";
    end case;
end process;

Thanks in advance for any help.

Author: Christian Leber (Guest)
Posted on:

Rate this post
0 useful
not useful
1.) division is not so basic, it takes lots of time
2.) "aint working" is not the best problem description

Author: Diogo (Guest)
Posted on:

Rate this post
0 useful
not useful
But can I divide using the code above? Or do I need to create a complex 
logic to do so?

My state machine dosen't seem to bo reaching even the first state. I 
placed a "signal <= '1'" in the state 0, to test if it would alter the 
signal but it didn't. Maybe it's because I'm using integers as signals?

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
> 1.) division is not so basic, it takes lots of time
Maybe it isn't synthesizable at all.

> But can I divide using the code above?
For a simulation this will work fine.

> Or do I need to create a complex logic to do so?
There are two ways to do a division:
1. create a big slow combinatorial divider
Altera Quartus does that, but none of the others...
2. create a small slow registered divider
http://www.lothar-miller.de/s9y/archives/29-Divisi...
This is alos the way every FPGA supllier supports by macros...

> My state machine dosen't seem to bo reaching even the first state.
Post your complete code as VHDL attachment. It not able to tell from 
your snippets what goes wrong...

Author: Diogo (Guest)
Posted on:
Attached files:

Rate this post
0 useful
not useful
Here's the entire code (some of the variable names are in portuguese, 
but I hope that won't affect the comprehension of the program)

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
Diogo wrote:
>> Post your complete code as VHDL attachment.
> Here's the entire code
Its not the Code, its whole of the complete project. I had to dig around 
to find the REQUESTED VHDL FILES...  :-/

> But can I divide using the code above?
No. No....

You do not know, what you are doing. On FPGAs you have only flipflops 
and multifunctional combinatorial gates. But you don't hav "delaylines" 
like this:
Done :
process 
begin
  if (Fim'event and Fim = '1') then  
     Done_Tick <= '1'; wait for 10 ns;  -- only useful for simulation
    Done_Tick <= '0';
  else 
    Done_Tick <= '0';
  end if;  
end process;
[vhdl]
And you have plenty of things like this...  :-o
This is not synthesizeable, so you can use your code for simulation (maybe) but it will never run on a FPGA as you expect it.

Did you just do the "hello world!" of hardware (a blinking led) before programming a divider? I would say: No. But I urge you to do so. Its the only way to get a hardware-thinking into your mind.

So, do a blinking led and post your code. Its just 5 minutes, but you will learn for life... ;-)

BTW:
Use this:
[vhdl]
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
Or this (much better):
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
But never both of them together! Because otherwise you can get strange 
behavior due to a double definition of some types.

BTW2:
Give your integers ranges (from xxx to yyy). Here the synthesizer 
assumes a signal 32 bits wide:
signal estado_atual : INTEGER := 0;
signal prox_estado : INTEGER := 0;

BTW3:
Why do you use such a bunch of variables? Its not neccessary at all...

Author: Diogo (Guest)
Posted on:

Rate this post
0 useful
not useful
You're right. I don't know what I'm doing and I'm hating every second of 
it, but it's just something I have to do heheh

I think I understood your remark. I shouldn't be using "wait for" and 
instead turn it syncronous to the clock, right? I'll make the changes 
needed.

Do you beleive the problem with the state machine is conected to the use 
of these time delaying commands?

Also I won't be using this on a FPGA, but I do need the simulation to 
work.

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
> I shouldn't be using "wait for" and instead turn it syncronous to the
> clock, right?
Thats the only possibility.

> Also I won't be using this on a FPGA,
So just simulating?
> but I do need the simulation to work.
Then your task is fairly easy. You can use the whole language VHDL, not 
only those little parts of it which are synthesizable...

> Do you beleive the problem with the state machine is conected to the use
> of these time delaying commands?
No, its something like this:
   contador := contador + 1;
This "counter" runs in a combinatorial process. And so you created a 
combinational loop (aka. combinatorial loop). And that is a counter 
running without any clock with theoretically maximum speed. But 
practially its just a random noise generator...  :-/

And also:
   Done_Tick <= '0';
You cannot assign a value to a signal out of two processes. This will 
result in a driver conflict and you will get 'X' in your simulation...

Author: Diogo (Guest)
Posted on:

Rate this post
0 useful
not useful
How do I counter the combinational loop? Something like this?
if rising_edge(Clk) then
    contador := contador + 1;
end if;

Author: Diogo (Guest)
Posted on:

Rate this post
0 useful
not useful
tried it with:
wait until rising_edge (clk);
contador := contador + 1;

aswell

Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
>  Something like this? ...
Results in the same like this:
> tried it with: ...
And in both cases you will get registered flipflops and get rid of the 
combinational loop.

Of course you will encounter other problems, but to have a closer look 
at them you should post new questions... ;-)

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.