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.