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

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.

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

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?

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-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...

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)

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...

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.

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...

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;

Rate this post
 0 ▲ useful ▼ not useful
tried it with:

 wait until rising_edge (clk); contador := contador + 1;

aswell

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... ;-)

• $formula (LaTeX syntax)$