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

LUT help!!!

Altera_Forum
Honored Contributor II
7,519 Views

I have wrote this code for implementing a neural network.What it does is to take some values(inputs) and some weights and computes the SUM(values*weigths).What i want to do is to check if the total sum(values*weights)< threshold and correct the weights in order to sum(values*weights)>=threshold.I think that i have to store the weights on a look up table and change the values in order to sum(values*weights)>=threshold.How i can do this?.My code is : 

LIBRARY IEEE; 

USE IEEE.STD_LOGIC_1164.ALL; 

USE IEEE.STD_LOGIC_ARITH.ALL; 

USE IEEE.STD_LOGIC_UNSIGNED.ALL; 

USE IEEE.STD_LOGIC_SIGNED.ALL; 

 

ENTITY ANN IS 

 

GENERIC ( m : INTEGER := 4; -- Number of inputs or weights 

b : INTEGER := 8); --Number of bits per input or weight 

 

PORT ( x1,x2,x3,x4: IN UNSIGNED(b-1 DOWNTO 0); 

w : IN UNSIGNED(b-1 DOWNTO 0); 

clk: IN STD_LOGIC; 

y : buffer UNSIGNED(2*b-1 DOWNTO 0); 

id : buffer bit); 

END ANN; 

 

ARCHITECTURE NEURAL OF ANN IS 

TYPE weights IS ARRAY (1 TO m) OF UNSIGNED(b-1 DOWNTO 0); 

TYPE inputs IS ARRAY (1 TO m) OF UNSIGNED(b-1 DOWNTO 0); 

BEGIN 

 

PROCESS(clk,w,x1,x2,x3,x4) 

 

VARIABLE weight : weights; 

VARIABLE input : inputs; 

VARIABLE prod,acc : UNSIGNED(2*b-1 DOWNTO 0); 

VARIABLE sub : UNSIGNED(2*b-1 DOWNTO 0); 

BEGIN 

 

IF (clk'EVENT AND CLK='1') THEN 

weight:=w&weight(1 TO m-1); 

END IF; 

input(1):=x1; 

input(2):=x2; 

input(3):=x3; 

input(4):=x4; 

acc:=(OTHERS=>'0'); 

FOR j IN 1 TO m LOOP 

prod:=input(j)*weight(j); 

acc:=acc+prod; 

END LOOP; 

y<=acc; 

END IF; 

END PROCESS; 

END NEURAL;
0 Kudos
70 Replies
Altera_Forum
Honored Contributor II
1,330 Views

I notice a couple of problems with the code first: 

 

 

--- Quote Start ---  

 

LIBRARY IEEE; 

USE IEEE.STD_LOGIC_1164.ALL; 

USE IEEE.STD_LOGIC_ARITH.ALL; 

USE IEEE.STD_LOGIC_UNSIGNED.ALL; 

USE IEEE.STD_LOGIC_SIGNED.ALL; 

 

--- Quote End ---  

 

 

You cannot use signed and unsigned libraries the same file, only one or the other. if you need both, then replace arith/unsigned/signed with ieee.numeric_std.all instead. 

 

 

--- Quote Start ---  

 

PROCESS(clk,w,x1,x2,x3,x4) 

 

VARIABLE weight : weights; 

VARIABLE input : inputs; 

VARIABLE prod,acc : UNSIGNED(2*b-1 DOWNTO 0); 

VARIABLE sub : UNSIGNED(2*b-1 DOWNTO 0); 

BEGIN 

 

--- Quote End ---  

 

 

Why are you storing these as variables and not signals? Do you understand the differences between the 2 and how they both behave? It may simulate correctly but unless you are carefull the synthesiser may just do something you weren't expecting. You have to be more careful with variables and synthesis. 

 

 

--- Quote Start ---  

 

END IF; 

input(1):=x1; 

input(2):=x2; 

input(3):=x3; 

input(4):=x4; 

acc:=(OTHERS=>'0'); 

FOR j IN 1 TO m LOOP 

prod:=input(j)*weight(j); 

acc:=acc+prod; 

END LOOP; 

y<=acc; 

END IF; 

END PROCESS; 

END NEURAL; 

--- Quote End ---  

 

 

Again, I dont think you want to loop and have and accumulate like this. In your code, it will try and add up m values in 1 clock cycle, the more values there are, the slower your FMAX can be.  

 

For your actual question, you havent said how you need to change the weights if the sum is > theshold. Is there some formula for this (good), or do you have to work it out on an iterative basis (bad). 

 

There are many ways to store values in memories. You can instantiate an altsyncram or infer the ram from code. Until you explain how you intend to do such things, I dont think we can explain further.
0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

Looking again at your code: 

 

the stored value weight(m) is never used. 

you expect to multiply and accumulate unregistered values. 

 

At most, I recon the max clock speed will be very slow, maybe a 2Mhz if you are lucky!
0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

I store those as variables because every time i insert an input their values will be changed.As far as i know variables are used inside process(because their values change every clock time) and signals are constant values.(if i am right).I will try to explain you what exactly i want to do so you can help me. 

I want to insert some inputs(lets say 3),each of one has one weight(random).So i would like to multiply each input with its own weight and then compute the sum of them.Then i would like to compare this sum with a predetermined threshold and if the sum that i have computed is greated than this threshold its ok.But if the sum is less than the threshold i would like to correct the values of the weights so the total sum is greater than the threshold.I hope i explained it good. 

 

P.S Sorry for my bad english
0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

 

--- Quote Start ---  

I store those as variables because every time i insert an input their values will be changed.As far as i know variables are used inside process(because their values change every clock time) and signals are constant values.(if i am right).I will try to explain you what exactly i want to do so you can help me. 

 

--- Quote End ---  

 

 

this is incorrect. 

Variables can exist in any process, function or procedure. A signal exists inside an architecture. The difference is that variables are updated immediatly, whereas signals are updated at the next delta. This can have a huge effect on the code you are writing. Take a look at the following code: 

 

signal a, b, c : std_logic; process(clk) variable x, y, z : std_logic; begin if rising_edge(clk) x := input; y := x; z := y; output <= z; a <= input; b <= a; c <= b; output <= c; end if; end process; The version using variables desicribes a 1 register delay from input to output. The version using signals describes a 4 register delay from input to output. This is because the variables are updated imediatly, they pass the value straight through. Because the signals are all updated at the same time, they are all updated at the clock edge, therefore each one is a register. 

 

now, just to screw with your head, here is a version of the a/b/c method above, but using variables, that describes exactly the same behaviour. 

 

process(clk) variable a,b,c : std_logic; begin if rising_edge(clk) output := c; c := b; b := a; a := input; end if; end process; Now, because variables before the previous one updates, this will produce a pipeline of 4 registers as well. 

 

The trick to learning VHDL is not learning the language, but first understanding the hardware you are trying to discribe. Only then can you use tricks of the language to help you discribe things above. No offence, but it looks and sound like you are trying to write VHDL like a programming language, which it is not - it is a hardware description language. 

 

 

--- Quote Start ---  

 

I want to insert some inputs(lets say 3),each of one has one weight(random).So i would like to multiply each input with its own weight and then compute the sum of them.Then i would like to compare this sum with a predetermined threshold and if the sum that i have computed is greated than this threshold its ok.But if the sum is less than the threshold i would like to correct the values of the weights so the total sum is greater than the threshold.I hope i explained it good. 

 

P.S Sorry for my bad english 

--- Quote End ---  

And again, this points to you thinking VHDL is a programming language. FPGAs and hardware are very good at doing static things and doing repetative tasks. They are not good at decision making. What you want to do sounds like a very complicated task for an FPGA to do.
0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

Thanks for your quick response(again).You are right that i think most like vhdl is a programming language because i am a newbie in vhdl.But from the things you wrote you mean that what i want to do is difficult?The first step as far as i know is a simple MAC unit.The difficult part is the part that i have to adjust the weights in order for sum>threshold.Can you please tell me at least if the first part(the MAC unit) is correct?As i mentioned above i want to insert 3 inputs,each of one has a weight and then multiply each input with each weight and finally sum.Thanks again.

0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

First I recommend you got an modify your origional code into a proper multiply/accumulate pipeline before trying to modify it, otherwise it will never work on an FPGA at any useful speed. Then we can think about modifying the weights based on the result. 

 

The problem is, what you want to do would mean having a variable length pipeline as it going to require repeated iterations until the weights are correct, and with a properly built pipeline it will take more clocks to complete depending on the number of iterations. You will need a valid output to tell the next block when you have completed the weight adjustement.
0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

I found a vhdl code for a simple mac unit in this forum: 

http://www.altera.com/support/examples/vhdl/vhd-unsigned-multiplier.html 

http://www.altera.com/support/examples/vhdl/vhd-signed-multiply-accumulator.html 

 

Is it write to use one of them(with the diferrence that i will have 6 inputs,3 inputs and 3 weights).Or can i modify it somehow to use just 2 inputs?What i mean is to insert the first 2 inputs do the computation,then insert the next 2 inputs do the computation etc. 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

What you want is the multiply unit, with 4 of them in parallel and then sum the results from each one. 

 

With that, it will take 3/4 clocks to get your result.
0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

Why i want 4 of them and not 3?I am asking this because i have 3 pairs of inpputs-weights.So i need 3 multiply units and one accumulator to sum the results.Finally when you say in parallel what do you mean?

0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

you have 4 inputs x1/x2/x3 and x4. Also You are shifting the weights so you want to use the old weight values as there is only 1 weight input.

0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

Ok i will try to implement it and i will write my feedback tommorow.I hope will find you online to help me.Thank you very much

0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

Ok i manage to do the first part of the project.What it does is :i insert some values for inputs(that will remain constants through all the process) and then when a clock EVENT i do this computation : input1*weight1+input2*weight2+input3*weight3.This is the multiply-accumulator unit.The second thing that i want to do(for which i need your help) is to compare this result(from the previous step) with a threshold and then fix the weight values in order to : 

input1*weight1(new)+input2*weight2(new)+input3*weight3(new)>threshold.Here is my code 

library ieee; 

use ieee.std_logic_1164.all; 

use ieee.std_logic_unsigned.all; 

use ieee.std_logic_arith.all; 

entity neuron is  

port ( in1,in2,in3,w1,w2,w3 : in unsigned (7 downto 0); 

clk : in std_logic; 

id : out bit; 

output : out unsigned (15 downto 0)); 

end neuron; 

 

architecture behavioral of neuron is  

type inputs is array (1 to 3) of unsigned (7 downto 0); 

type weights is array (1 to 3) of unsigned (7 downto 0); 

constant threshold : unsigned(15 downto 0):="0000011011100111"; 

constant sum : unsigned:="1"; 

begin 

 

process(clk,w1,w2,w3) 

 

variable weight : weights; 

variable input : inputs; 

variable prod,acc : unsigned (15 downto 0); 

begin 

 

if(clk'EVENT AND clk='1') then  

input(1):=in1; 

input(2):=in2; 

input(3):=in3; 

weight(1):=w1; 

weight(2):=w2; 

weight(3):=w3; 

acc:=(others=>'0'); 

end if; 

for j in 1 to 3 loop 

prod:=input(j)*weight(j); 

acc:=acc+prod; 

end loop; 

if(acc>threshold) then id<='1'; 

else id<='0'; 

end if; 

output<=acc; 

end process; 

end behavioral; 

I attached and a photo with the simulation results
0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

Any help?Thanks

0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

I still think you need to read up on logic design. And stop using variables like you are - you're making it do a lot of work in 1 clock cycle!

0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

Thanks for the response.So what do you suggest?

0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

for a start - use signals instead of variables.

0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

At least this code does what i want to do?Is it correct from the view of behavior?

0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

Yes it does behave correctly. 

 

I just dont think it will work on a real FPGA, because it is not pipelined.
0 Kudos
Altera_Forum
Honored Contributor II
1,330 Views

To be honest the purpose of my project is to write some code that implements the thing i described in earlier posts.So i suppose it's ok.I will post the code that wrote for the weights update method.Thanks again

0 Kudos
Altera_Forum
Honored Contributor II
1,231 Views

I wrote this code.What i need to do is to insert 4 values at each clock which i store on a 2-dimensional array and i want to compute the sum of these values.  

 

LIBRARY IEEE;  

USE IEEE.STD_LOGIC_1164.ALL;  

USE IEEE.STD_LOGIC_ARITH.ALL;  

 

ENTITY test IS  

 

PORT( x1 : IN INTEGER RANGE 0 TO 255;  

clk,load : IN STD_LOGIC;  

output1 : out INTEGER RANGE 0 TO 1020);  

 

 

END test;  

 

ARCHITECTURE behavioral OF test IS  

 

TYPE windows IS ARRAY(0 TO 1,0 to 1) OF INTEGER RANGE 0 TO 255; 

BEGIN  

 

PROCESS(clk,x1)  

 

 

VARIABLE window : windows;  

VARIABLE sum : INTEGER RANGE 0 TO 1020;  

 

BEGIN  

IF(clk'EVENT AND clk='1') THEN  

IF(load='1') THEN  

FOR i IN 0 TO 1 LOOP  

FOR j IN 0 TO 1 LOOP  

window(i,j):=x1;  

sum:=sum+window(i,j);  

END LOOP;  

END LOOP;  

END IF;  

END IF;  

output1<=sum;  

END PROCESS;  

END behavioral;  

 

The code has no problem while compiling but in the simulation the results are wrong!!!.Please help.I set in the simulation for the x1 to take 2 values per clock but the result shows that something is wrong.
0 Kudos
Reply