--------------------------------------------------------------- --Izhikevich neuron model. --Universidad Politecnica de Victoria --------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; use std.textio.all; entity pipelined_32bits is --Generics. GENERIC( --Bit size values. bits:integer:=31 ); --Entity ports. PORT( --Clock. CLK : in std_logic; --Time variable. t : in std_logic_vector (bits downto 0); --Time derivative. dt : in std_logic_vector (bits downto 0); --Operation interval (start). tr0 : in std_logic_vector (bits downto 0); --Operation interval (end). tr1 : in std_logic_vector (bits downto 0); --Input current. Iapp: in std_logic_vector (bits downto 0); --Behavior control variables. a: in std_logic_vector (bits downto 0); b: in std_logic_vector (bits downto 0); c: in std_logic_vector (bits downto 0); d: in std_logic_vector (bits downto 0); --Reset neuron values. V_CERO : in std_logic_vector(bits downto 0); U_CERO : in std_logic_vector(bits downto 0); --Membrane potential. Nuevo_V : OUT std_logic_vector(bits downto 0); --Membrane recovery variable. Nuevo_U : OUT std_logic_vector(bits downto 0); --Input of neuron. --Input_V : in std_logic_vector(bits downto 0); --Threshold value. thr : in std_logic_vector(bits downto 0); --Enable port. EN : in std_logic ); end pipelined_32bits; architecture Behavioral of pipelined_32bits is shared variable vOld:std_logic_vector(bits downto 0):=(others => '0'); shared variable vNew:std_logic_vector(bits downto 0):=(others => '0'); shared variable uOld:std_logic_vector(bits downto 0):=(others => '0'); shared variable uNew:std_logic_vector(bits downto 0):=(others => '0'); signal zero:std_logic_vector(bits downto 0):=(others => '0'); signal uno:std_logic_vector(bits downto 0):="00000000000000010000000000000000"; shared variable flag:std_logic:='0'; --0.04 shared variable Const0:std_logic_vector(bits downto 0) := "00000000000000000000101000111101"; --5 shared variable Const1:std_logic_vector(bits downto 0) := "00000000000001010000000000000000"; --140 shared variable Const2:std_logic_vector(bits downto 0) := "00000000100011000000000000000000"; shared variable Input:std_logic_vector(bits downto 0):=(others=>'0'); shared variable V:std_logic_vector(bits downto 0):=(others=>'0'); shared variable V1:std_logic_vector((bits*2) + 1 downto 0):=(others=>'0'); shared variable V2:std_logic_vector(bits downto 0):=(others=>'0'); shared variable V3:std_logic_vector((bits*2) + 1 downto 0):=(others=>'0'); shared variable V4:std_logic_vector(bits downto 0):=(others=>'0'); shared variable V5:std_logic_vector(bits downto 0):=(others=>'0'); shared variable V6:std_logic_vector(bits downto 0):=(others=>'0'); shared variable V7:std_logic_vector((bits*2) + 1 downto 0):=(others=>'0'); shared variable V8:std_logic_vector((bits*2) + 1 downto 0):=(others=>'0'); shared variable V9:std_logic_vector(bits downto 0):=(others=>'0'); shared variable U:std_logic_vector(bits downto 0):=(others=>'0'); shared variable U1:std_logic_vector((bits*2) + 1 downto 0):=(others=>'0'); shared variable U2:std_logic_vector(bits downto 0):=(others=>'0'); shared variable U3:std_logic_vector((bits*2) + 1 downto 0):=(others=>'0'); shared variable U4:std_logic_vector((bits*2) + 1 downto 0):=(others=>'0'); shared variable U5:std_logic_vector(bits downto 0):=(others=>'0'); shared variable Vtmp1:std_logic_vector(bits downto 0):=(others => '0'); shared variable Vtmp2:std_logic_vector(bits downto 0):=(others => '0'); shared variable Vtmp3:std_logic_vector(bits downto 0):=(others => '0'); shared variable Vtmp4:std_logic_vector(bits downto 0):=(others => '0'); shared variable Vtmp5:std_logic_vector(bits downto 0):=(others => '0'); shared variable Vtmp6:std_logic_vector(bits downto 0):=(others => '0'); shared variable Vtmp7:std_logic_vector(bits downto 0):=(others => '0'); shared variable Vtmp8:std_logic_vector(bits downto 0):=(others => '0'); shared variable Vtmp9:std_logic_vector(bits downto 0):=(others => '0'); shared variable Vtmp10:std_logic_vector(bits downto 0):=(others => '0'); shared variable Vtmp11:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp1:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp2:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp3:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp4:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp5:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp6:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp7:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp8:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp9:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp10:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp11:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp12:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp13:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp14:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp15:std_logic_vector(bits downto 0):=(others => '0'); shared variable Utmp16:std_logic_vector(bits downto 0):=(others => '0'); shared variable dtVal1:std_logic_vector(bits downto 0):=(others=>'0'); shared variable dtVal2:std_logic_vector(bits downto 0):=(others=>'0'); shared variable dtVal3:std_logic_vector(bits downto 0):=(others=>'0'); shared variable dtVal4:std_logic_vector(bits downto 0):=(others=>'0'); shared variable dtVal5:std_logic_vector(bits downto 0):=(others=>'0'); shared variable dtVal6:std_logic_vector(bits downto 0):=(others=>'0'); shared variable dtVal7:std_logic_vector(bits downto 0):=(others=>'0'); shared variable dtVal8:std_logic_vector(bits downto 0):=(others=>'0'); shared variable dtVal9:std_logic_vector(bits downto 0):=(others=>'0'); begin --This line ensures neuron only pulses during intervals tr0 < t < tr1. PROCESS(Clk) --************************************** --File Storage --************************************** TYPE intfile IS FILE OF integer; -- file of integers FILE dataoutfile:text OPEN append_mode IS "voltage.txt"; VARIABLE vDataout : bit_vector(bits DOWNTO 0); -- variable written to line VARIABLE vDataoutline : line; -- line variable written to file --************************************** BEGIN if (t > tr0) and (t < tr1) then REPORT("ACTIVE"); --Receive value of input current Iapp. Input := Iapp; else Input := "00000000000000000000000000000000"; end if; -- vDataout := To_BitVector(Input); -- convert DataOut to bit_vector type -- write (vDataoutline, vDataout); -- write variable to line -- writeline (dataoutfile, vDataoutline); -- write line to file END PROCESS; --Here makes calculations for voltage potential. PROCESS(Clk) --************************************** --File Storage --************************************** TYPE intfile IS FILE OF integer; -- file of integers FILE dataoutfile:text OPEN append_mode IS "voltage.txt"; VARIABLE vDataout : bit_vector(bits DOWNTO 0); -- variable written to line VARIABLE vDataoutline : line; -- line variable written to file --************************************** BEGIN if(rising_edge(Clk)) then IF EN = '1' THEN --REPORT("PROCESANDO"); for i in 0 to 17 loop case i is when 0 => V := vOld; --0.04*V when 1 => V1 := std_logic_vector(signed(V) * signed(Const0)); --(0.04*V)+5 when 2 => V2 := std_logic_vector(signed(V1(47 downto 16)) + signed(Const1)); --[(0.04*V)+5]*V when 3 => V3 := std_logic_vector(signed(V2) * signed(Vtmp3)); --[(0.04*V)+5]*V + 140 when 4 => V4 := std_logic_vector(signed(V3(47 downto 16)) + signed(Const2)); --[(0.04*V)+5]*V + 140 - u when 5 => V5 := std_logic_vector(signed(V4) - signed(uOld)); --(0.04*V^2) + 0.5*V + 140 - u + I when 6 => V6 := std_logic_vector(signed(V5) + signed(Input)); --[(0.04*V^2) + 0.5*V + 140 - u + I]*dt when 7 => V7 := std_logic_vector(signed(V6) * signed(dtVal9)); --VNew = V + [(0.04*V^2) + 0.5*V + 140 - u + I]*dt when 8 => V8 := std_logic_vector(signed(Vtmp10) + signed(V7(47 downto 16))); when 9 => --Update neuron membrane potential. vOld := V8; Nuevo_V <= vOld; --[a*(b*V-U)]*dt when 11 => U1 := std_logic_vector(signed(b) * signed(Vtmp11)); when 12 => U2 := std_logic_vector(signed(U1(47 downto 16)) - signed(uOld)); when 13 => U3 := std_logic_vector(signed(a) * signed(U2)); --[a*(b*V-U)]*dt when 14 => U4 := std_logic_vector(signed(U3(47 downto 16)) * signed(dt)); --UNew = U + [a*(b*V-U)]*dt when 15 => U5 := std_logic_vector(signed(uOld) + signed(U4(47 downto 16))); when 16 => --Update neuron membrane potential. --uOld := std_logic_vector(signed(uOld)); uOld := U5; Nuevo_U <= uOld; when others => null; end case; end loop; if flag='1' then flag := '0'; vOld := c; Nuevo_V <= vOld; elsif (signed(vOld) >= signed(thr)) and flag='0' then flag := '1'; --Update neuron membrane potential. vOld := thr; Nuevo_V <= vOld; uOld := std_logic_vector(signed(uOld) + signed(d)); Nuevo_U <= uOld; end if; ELSE REPORT("ESTABLECIENDO VALORES"); vOld := V_CERO; uOld := U_CERO; END IF; vDataout := To_BitVector(vOld); -- convert DataOut to bit_vector type write (vDataoutline, vDataout); -- write variable to line writeline (dataoutfile, vDataoutline); -- write line to file end if; END PROCESS; --Process to keep V value. PROCESS(Clk) BEGIN if(rising_edge(Clk)) then for i in 0 to 10 loop case i is when 0 => Vtmp1 := vOld; when 1 => Vtmp2 := Vtmp1; when 2 => Vtmp3 := Vtmp2; when 3 => Vtmp4 := Vtmp3; when 4 => Vtmp5 := Vtmp4; when 5 => Vtmp6 := Vtmp5; when 6 => Vtmp7 := Vtmp6; when 7 => Vtmp8 := Vtmp7; when 8 => Vtmp9 := Vtmp8; when 9 => Vtmp10 := Vtmp9; when 10 => Vtmp11 := Vtmp10; when 11 => vOld := Vtmp11; when others => null; end case; end loop; end if; END PROCESS; --Process to keep U value. PROCESS(Clk) BEGIN if(rising_edge(Clk)) then for i in 0 to 15 loop case i is when 0 => Utmp1 := uOld; when 1 => Utmp2 := Utmp1; when 2 => Utmp3 := Utmp2; when 3 => Utmp4 := Utmp3; when 4 => Utmp5 := Utmp4; when 5 => Utmp6 := Utmp5; when 6 => Utmp7 := Utmp6; when 7 => Utmp8 := Utmp7; when 8 => Utmp9 := Utmp8; when 9 => Utmp10 := Utmp9; when 10 => Utmp11 := Utmp10; when 11 => Utmp12 := Utmp11; when 12 => Utmp13 := Utmp12; when 13 => Utmp14 := Utmp13; when 14 => Utmp15 := Utmp14; when 15 => uOld := Utmp15; when others => null; end case; end loop; end if; END PROCESS; PROCESS(Clk) BEGIN if(rising_edge(Clk)) then for i in 0 to 10 loop case i is when 0 => dtVal1 := dt; when 1 => dtVal2 := dtVal1; when 2 => dtVal3 := dtVal2; when 3 => dtVal4 := dtVal3; when 4 => dtVal5 := dtVal4; when 5 => dtVal6 := dtVal5; when 6 => dtVal7 := dtVal6; when 7 => dtVal8 := dtVal7; when 8 => dtVal9 := dtVal8; when others => null; end case; end loop; end if; END PROCESS; --NOTE: For some weird reason activating the registers messes with t1 value --and makes it go from 700.00 to 0.00. --Import the registers. -- Reg0: entity work.d_reg port map( -- CLK => CLK, -- RESET => reg_res0, -- EN => reg_store0, -- D => vOld, -- Q => vNew -- ); -- -- Reg1: entity work.d_reg port map( -- CLK => CLK, -- RESET => reg_res1, -- EN => reg_store1, -- D => uOld, -- Q => uNew -- ); end Behavioral;