From 081a6acc6745c102bbacdf72ab2e88d46e4241dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20D=C3=B6rfelt?= Date: Sun, 25 Apr 2021 10:57:13 +0200 Subject: [PATCH] add batch normalization with unsigned values This is needed for the first convolution layer, where MACs are done with possible negative result. At the other layers we do XOR with positive only results. --- src/batch_normalization.vhd | 49 ++++++++++++++++++++------- src/window_convolution_activation.vhd | 13 ++++++- 2 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/batch_normalization.vhd b/src/batch_normalization.vhd index 6a15836..0ec61bb 100644 --- a/src/batch_normalization.vhd +++ b/src/batch_normalization.vhd @@ -8,7 +8,8 @@ library ieee; entity batch_normalization is generic ( - C_POST_CONVOLUTION_BITWIDTH : integer := 8 + C_POST_CONVOLUTION_BITWIDTH : integer := 8; + C_UNSIGNED : integer range 0 to 1 := 1 ); port ( isl_clk : in std_logic; @@ -27,23 +28,47 @@ architecture behavioral of batch_normalization is begin - proc_batch_normalization : process (isl_clk) is - begin + gen_batch_normalization : if C_UNSIGNED = 1 generate - if (rising_edge(isl_clk)) then - sl_valid_out <= '0'; - slv_data_out(0) <= '0'; + proc_batch_normalization : process (isl_clk) is + begin - if (isl_valid = '1') then - if (unsigned(islv_data) > unsigned(islv_threshold)) then - slv_data_out(0) <= '1'; + if (rising_edge(isl_clk)) then + sl_valid_out <= '0'; + slv_data_out(0) <= '0'; + + if (isl_valid = '1') then + if (unsigned(islv_data) > unsigned(islv_threshold)) then + slv_data_out(0) <= '1'; + end if; + + sl_valid_out <= '1'; end if; + end if; + + end process proc_batch_normalization; + + else generate - sl_valid_out <= '1'; + proc_batch_normalization : process (isl_clk) is + begin + + if (rising_edge(isl_clk)) then + sl_valid_out <= '0'; + slv_data_out(0) <= '0'; + + if (isl_valid = '1') then + if (signed(islv_data) > signed(islv_threshold)) then + slv_data_out(0) <= '1'; + end if; + + sl_valid_out <= '1'; + end if; end if; - end if; - end process proc_batch_normalization; + end process proc_batch_normalization; + + end generate gen_batch_normalization; oslv_data <= slv_data_out; osl_valid <= sl_valid_out; diff --git a/src/window_convolution_activation.vhd b/src/window_convolution_activation.vhd index 6e1649f..e12f6bc 100644 --- a/src/window_convolution_activation.vhd +++ b/src/window_convolution_activation.vhd @@ -49,6 +49,16 @@ architecture behavioral of window_convolution_activation is constant C_POST_CONVOLUTION_BITWIDTH : integer := C_INPUT_CHANNEL_BITWIDTH + log2(C_KERNEL_SIZE ** 2 * C_INPUT_CHANNEL + 1) + 1; signal a_data_convolution : t_slv_array_1d(0 to C_OUTPUT_CHANNEL - 1)(C_POST_CONVOLUTION_BITWIDTH - 1 downto 0); + function is_batch_normalization_unsigned return integer is + begin + + if (C_INPUT_CHANNEL_BITWIDTH = 1) then + return 1; + end if; + + return 0; + end function is_batch_normalization_unsigned; + signal slv_valid_batch_normalization : std_logic_vector(C_OUTPUT_CHANNEL - 1 downto 0); signal slv_data_batch_normalization : std_logic_vector(C_OUTPUT_CHANNEL * C_OUTPUT_CHANNEL_BITWIDTH - 1 downto 0); signal a_data_batch_normalization : t_slv_array_1d(0 to C_OUTPUT_CHANNEL - 1)(C_OUTPUT_CHANNEL_BITWIDTH - 1 downto 0); @@ -106,7 +116,8 @@ begin i_batch_normalization : entity cnn_lib.batch_normalization generic map ( - C_POST_CONVOLUTION_BITWIDTH => C_POST_CONVOLUTION_BITWIDTH + C_POST_CONVOLUTION_BITWIDTH => C_POST_CONVOLUTION_BITWIDTH, + C_UNSIGNED => is_batch_normalization_unsigned ) port map ( isl_clk => isl_clk,