首页 > 解决方案 > VHDL Loops - 程序似乎使用以前的值

问题描述

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;

ENTITY WeightsUpdate IS
     GENERIC ( n: INTEGER := 1;
                  m: INTEGER := 3;
                  b: INTEGER := 8);
    PORT ( w0    : in   SIGNED (b-1 DOWNTO 0);
           w1    : in   SIGNED (b-1 DOWNTO 0);
           w2    : in   SIGNED (b-1 DOWNTO 0);
           y     : in   STD_LOGIC_VECTOR (b-1 DOWNTO 0);
           x1    : in   STD_LOGIC;
           x2    : in   STD_LOGIC;
           d     : in   STD_LOGIC_VECTOR (b-1 DOWNTO 0);
           up_w0 : out  SIGNED (b-1 DOWNTO 0);
           up_w1 : out  SIGNED (b-1 DOWNTO 0);
           up_w2 : out  SIGNED (b-1 DOWNTO 0));
END WeightsUpdate;

ARCHITECTURE Behavioral OF WeightsUpdate IS
    TYPE weights IS ARRAY (1 TO n*m) OF SIGNED(b-1 DOWNTO 0);
    TYPE new_weights IS ARRAY (1 TO n*m) OF SIGNED(b-1 DOWNTO 0);
    TYPE inputs IS ARRAY (1 TO m) OF SIGNED(b-1 DOWNTO 0);
    TYPE outputs IS ARRAY (1 TO n) OF SIGNED(b-1 DOWNTO 0);
    SIGNAL exp, act : SIGNED(b-1 DOWNTO 0);
BEGIN
    PROCESS(w0, w1, w2, y, x1, x2, d)
        VARIABLE weight: weights;
        VARIABLE new_weight: new_weights;
        VARIABLE input: inputs;
        VARIABLE output: outputs;
        VARIABLE error: SIGNED(b-1 DOWNTO 0);
        VARIABLE delta_weight: SIGNED(2*b-1 DOWNTO 0);
    BEGIN   
        input(1)  := "0000000" & x1;
        input(2)  := "0000000" & x2;
        input(3)  := "11111111";
        weight(1) := w1;
        weight(2) := w2;
        weight(3) := w0;
        exp <= SIGNED(d);
        act <= SIGNED(y);
        error := exp - act;
        L1: FOR i IN 1 TO m LOOP
            delta_weight := input(i) * error;
            new_weight(i) := weight(i) + delta_weight(b-1 DOWNTO 0);
        END LOOP L1;
        up_w0 <= new_weight(3);
        up_w1 <= new_weight(1);
        up_w2 <= new_weight(2);
    END PROCESS;
END Behavioral;

你好。今天我遇到了上述 VHDL 代码的问题。它是我的神经网络的一部分,这个模块负责更新权重。它是这样完成的:

d - expected_result
y - actual_result
error = expected_result - actual_result
new_weight = old_weight + (input * error)

误差计算一次。我有 3 个神经元输入(一个是偏差,所以我将他设置为 -1)和 3 个权重(w0、w1、w2 - old_weights),每个输入一个,所以我通过 3 次迭代循环更新。下面是测试台:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;

ENTITY WeightsUpdateTB IS
END WeightsUpdateTB;

ARCHITECTURE behavior OF WeightsUpdateTB IS 

    -- Component Declaration for the Unit Under Test (UUT)

    COMPONENT WeightsUpdate
    PORT(
         w0 : IN  SIGNED(7 downto 0);
         w1 : IN  SIGNED(7 downto 0);
         w2 : IN  SIGNED(7 downto 0);
         y : IN  std_logic_vector(7 downto 0);
         x1 : IN  std_logic;
         x2 : IN  std_logic;
         d : IN  std_logic_vector(7 downto 0);
         up_w0 : OUT  SIGNED(7 downto 0);
         up_w1 : OUT  SIGNED(7 downto 0);
         up_w2 : OUT  SIGNED(7 downto 0)
        );
    END COMPONENT;


   --Inputs
   signal w0 : SIGNED(7 downto 0) := (others => '0');
   signal w1 : SIGNED(7 downto 0) := (others => '0');
   signal w2 : SIGNED(7 downto 0) := (others => '0');
   signal y : std_logic_vector(7 downto 0) := (others => '0');
   signal x1 : std_logic := '0';
   signal x2 : std_logic := '0';
   signal d : std_logic_vector(7 downto 0) := (others => '0');

    --Outputs
   signal up_w0 : SIGNED(7 downto 0);
   signal up_w1 : SIGNED(7 downto 0);
   signal up_w2 : SIGNED(7 downto 0);

BEGIN

    -- Instantiate the Unit Under Test (UUT)
   uut: WeightsUpdate PORT MAP (
          w0 => w0,
          w1 => w1,
          w2 => w2,
          y => y,
          x1 => x1,
          x2 => x2,
          d => d,
          up_w0 => up_w0,
          up_w1 => up_w1,
          up_w2 => up_w2
        );

   -- Stimulus process
   stim_proc: process
   begin        
            w0 <= "00000000";
            w1 <= "00110000";
            w2 <= "00110000";
            y <= "00011111";
            x1 <= '1';
            x2 <= '1';
            d <= "00100000";
        wait for 100 ns;
            w0 <= "00000000";
            w1 <= "00110000";
            w2 <= "00110000";
            y <= "00011111";
            x1 <= '0';
            x2 <= '1';
            d <= "00000000";
        wait for 100 ns;
            w0 <= "00000000";
            w1 <= "00110000";
            w2 <= "00110000";
            y <= "00011111";
            x1 <= '1';
            x2 <= '0';
            d <= "00000000";
        wait for 100 ns;
            w0 <= "00000000";
            w1 <= "00110000";
            w2 <= "00110000";
            y <= "00011111";
            x1 <= '1';
            x2 <= '1';
            d <= "00100000";
      wait;
   end process;

END;

和模拟: 模拟

问题是似乎错误计算错误。在模拟的第一组输入中,当它应该为 1 时,错误为 0,然后在第二组中,当它应该等于 -31 时,它为 1,依此类推 - 看起来它从前一组中获取值?第一组的权重应该如下所示:

up_w0 = -1
up_w1 = 49
up_w2 = 49

第二组:

up_w0 = 31
up_w1 = 48
up_w2 = 17

第三:

up_w0 = 31
up_w1 = 17
up_w2 = 48

第四:

up_w0 = -1
up_w1 = 49
up_w2 = 49

标签: vhdl

解决方案


推荐阅读