【发布时间】:2016-12-01 20:28:54
【问题描述】:
我正在使用由 David Aledo 开发的前馈神经网络(请参阅 OpenCores 项目 Artificial Neural Network (ANN)),并且在代码生成的实例中初始化 RAM 数组时遇到了问题。
代码生成神经网络层作为实例。这些实例中的每一个都具有与层权重矩阵相关联的块 RAM。此 RAM 在代码中表示为 std_logic_vector 数组的数组,如下所示:
type ramd_type is array (NumN-1 downto 0) of std_logic_vector(NbitW -1 downto 0);
type layer_ram is array (NumIn-1 downto 0) of ramd_type;
其中NumN 和NumIN 是依赖于层的,NbitW 是常量。
我想要做的是用一个常数来初始化这个 RAM。为此,我创建了一个包含以下内容的包:
type ramd_type0 is array (33 downto 0) of std_logic_vector(NbitW-1 downto 0);
type layer_ram0 is array (26 downto 0) of ramd_type0;
type ramd_type1 is array (4 downto 0) of std_logic_vector(NbitW-1 downto 0);
type layer_ram1 is array (33 downto 0) of ramd_type1;
type ramd_type2 is array (0 downto 0) of std_logic_vector(NbitW-1 downto 0);
type layer_ram2 is array (4 downto 0) of ramd_type2;
constant w0 : layer_ram0 := (others => (others => (others => '0')));
constant w1 : layer_ram1 := (others => (others => (others => '0')));
constant w2 : layer_ram2 := (others => (others => (others => '0')));
在层实体中,我声明了选择与层号通用 Lnum 相适应的常量的函数:
function w_init(LNum : natural) return layer_ram is
begin
if LNum = 0 then
return layer_ram(w0);
elsif LNum = 1 then
return layer_ram(w1);
elsif LNum = 2 then
return layer_ram(w2);
else
return layer_ram(w2);
end if;
end w_init;
layer_ram 的定义如上。
使用 GHDL 分析时出现以下错误:
不允许在不密切相关的类型之间进行转换
在 Modelsim 中我得到了这个:
work.wb_init.layer_ram0 到 layer_ram 的非法类型转换(数组元素类型不同)。
我知道问题在于,根据模拟器,layer_ram 和 layer_ram0 并不密切相关,这是因为数组元素具有不同的类型 ramd 和 ramd0。对我来说,这似乎违反了 1993 年的标准,该标准规定数组类型在以下情况下密切相关:
--对于每个索引位置,索引类型要么相同,要么密切相关;
我说的对吗?如何在不将 layer_ram 类型更改为 std_logic_vectors 数组的情况下使用常量初始化这些数组?
编辑:
可以在此处查看重现我的问题的最小工作示例:https://gist.github.com/jstefanowicz/e4f43a822cf5dd46c2668bfffa33c66c
library ieee;
use ieee.std_logic_1164.all;
library work;
package wb_init is
constant NbitW : natural := 18;
type ramd_type0 is array (1 downto 0) of std_logic_vector(NbitW-1 downto 0);
type ramd_type1 is array (2 downto 0) of std_logic_vector(NbitW-1 downto 0);
type layer_ram0 is array (3 downto 0) of ramd_type0;
type layer_ram1 is array (4 downto 0) of ramd_type1;
constant w0 : layer_ram0 := (others => (others => (others => '0')));
constant w1 : layer_ram1 := (others => (others => (others => '0')));
end wb_init ;
--- test_gen:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
library work;
use work.wb_init.all;
entity test_gen is
generic
(
LNum : natural ;
NumN : natural := 8;
NumIn : natural := 8
);
port
(
inputs : in std_logic_vector(NbitW-1 downto 0);
outputs : out std_logic_vector(NbitW-1 downto 0)
);
end test_gen;
architecture beh of test_gen is
type ramd_type is array (NumN-1 downto 0) of std_logic_vector(NbitW-1 downto 0);
type layer_ram is array (NumIn-1 downto 0) of ramd_type;
function w_init(LNum : natural) return layer_ram is
begin
if LNum = 0 then
return layer_ram(w0);
elsif LNum = 1 then
return layer_ram(w1);
else
return layer_ram(w1);
end if;
end w_init;
signal lram : layer_ram := w_init(LNum);
begin
outputs<= inputs;
end beh;
--- test_gen_tb:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
library work;
use work.wb_init.all;
entity test_gen_tb is
end test_gen_tb;
architecture beh of test_gen_tb is
component test_gen is
generic
(
LNum : natural := 0;
NumN : natural := 64;
NumIn : natural := 8
);
port
(
inputs : in std_logic_vector(NbitW-1 downto 0);
outputs : out std_logic_vector(NbitW-1 downto 0)
);
end component;
type gen_ar is array (1 downto 0) of natural;
signal NumN_ar : gen_ar := (2,3);
signal NumIn_ar : gen_ar := (4,5);
signal inputs,outputs : std_logic_vector(NbitW-1 downto 0);
begin
test_gen_inst:
for i in 0 to 1 generate
test_gen
generic map (
LNum => i,
NumN => NumN_ar(i),
NumIn => NumIn_ar(i)
)
port map (
inputs => inputs,
outputs => outputs
);
end generate;
end beh;
【问题讨论】:
-
问题是元素类型不同,一种元素类型为 ramd_type,另一种元素类型为 ramd_type0,都是数组类型。您没有显示常量 NumN 的值。如果没有更多信息(Minimal, Complete and Verifiable Example),目前还不清楚纠正措施是什么。还要注意 w0、w1 和 w2 的维度是不同的。您的 w_init 函数可能想要三个函数,或者您只是在做一些程序错误。
-
NumN 不是常量而是泛型。该函数根据通用 LNum 返回不同的数组大小。当 LNum = 0 时,NumN 和 NumIn 等于 w0 维度,依此类推。重点是我想根据通用值初始化可以具有不同维度的数组数组。
-
IEEE Std 1076-2008 6.5.6.1 通用接口列表完全由接口常量声明、接口类型声明、接口子程序声明和接口包声明组成。 NumN` 是接口常量,保留字常量是可选的(6.5.2)。您的工具链是否支持接口类型声明 (6.5.3)?
-
另外,因为这些没有出现在实体接口列表中,所以只使用本地声明,并使它们始终依赖于泛型常量。
-
我担心我的工具链不会和通过接口传递的类型一起去。至于另一个选项,我已经尝试使用权重矩阵在本地声明的常量,但问题如下。如果我将 w0 声明为 3x3 数组,将 w1 声明为 5x3 数组,两者都具有类型 layer_ram(数组维度取决于泛型),那么我在编译期间会遇到绑定检查失败。我还尝试将权重矩阵 agregates 直接传递给函数 w_gen 的返回值(带有类型转换),但我得到了错误,说 agregates 不能是类型转换操作数。
标签: initialization neural-network type-conversion vhdl