EmbDev.net

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


von Diogo (Guest)


Rate this post
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.
1
signal current_state : INTEGER := 0;
2
signal next_state : INTEGER := 0;
3
4
variable value: std_logic_vector(15 downto 0);
5
variable counter: integer := 0;
6
variable temp: unsigned (15 downto 0);
7
-- Line and Row are std_logic_vector (2 downto 0) signals
8
9
    counter := counter + 1;  
10
    temp := resize(unsigned(Line), 16) - resize(unsigned(Row), 16) + 1;
11
    temp := temp/(resize(unsigned(Row), 16));
12
    temp := temp*unsigned(value);
13
    value := std_logic_vector(temp);
14
    if counter < Row then
15
        next_state <= 1;
16
    else
17
        next_state <= 2;
18
    end if;

Is what I'm doing acceptable?

My "state machine" also dosen't seem to be working. Here's it's basic 
code:
1
P : process (Line, Row, Start, current_state)
2
begin
3
4
next_state = current_state; -- default is to keep on the same state
5
Done <= '0';
6
7
case current_state is
8
    when 0 =>
9
        if Start = '1'
10
            next_state = 1;
11
        else
12
            next_state = 0;
13
    when 1 =>
14
        if counter < Row then
15
            next_state <= 1;
16
        else
17
            next_state <= 2;
18
    when 2 =>
19
        -- display result
20
    when others =>
21
         assert false report "Invalid State";
22
    end case;
23
end process;

Thanks in advance for any help.

von Christian Leber (Guest)


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

von Diogo (Guest)


Rate this post
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?

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
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-Division-in-VHDL.html
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...

von Diogo (Guest)


Attached files:

Rate this post
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)

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
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:
1
Done :
2
process 
3
begin
4
  if (Fim'event and Fim = '1') then  
5
     Done_Tick <= '1'; wait for 10 ns;  -- only useful for simulation
6
    Done_Tick <= '0';
7
  else 
8
    Done_Tick <= '0';
9
  end if;  
10
end process;
11
[vhdl]
12
And you have plenty of things like this...  :-o
13
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.
14
15
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.
16
17
So, do a blinking led and post your code. Its just 5 minutes, but you will learn for life... ;-)
18
19
BTW:
20
Use this:
21
[vhdl]
22
library IEEE;
23
use IEEE.std_logic_1164.all;
24
use IEEE.std_logic_unsigned.all;
Or this (much better):
1
library IEEE;
2
use IEEE.std_logic_1164.all;
3
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:
1
signal estado_atual : INTEGER := 0;
2
signal prox_estado : INTEGER := 0;

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

von Diogo (Guest)


Rate this post
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.

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
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:
1
   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:
1
   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...

von Diogo (Guest)


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

von Diogo (Guest)


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

aswell

von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
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... ;-)

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.