2016-12-01 77 views
0

我正在使用由David Aledo开发的前馈神经网络(请参阅OpenCores项目Artificial Neural Network (ANN)),并且在代码生成的实例中初始化RAM阵列时遇到问题。神经网络中阵列阵列的VHDL类型转换

代码生成神经网络的图层作为实例。这些实例中的每一个具有与层权重矩阵关联的块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; 

其中NumNNumIN是层依赖性和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'))); 

,层内部的实体,我宣布其选择定apropriate层号通用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分析我得到以下错误:

conversion not allowed between not closely related types

在的ModelSim我得到这个:

Illegal type conversion from work.wb_init.layer_ram0 to layer_ram (array element type difference).

我得到的问题是,根据模拟的layer_ramlayer_ram0并不紧密相关,这是因为数组元素具有不同的类型ramdramd0。对我来说,这似乎违背了1993年的标准,其中指出阵列类型密切相关时:

-- For each index position, the index types are either the same or are closely related;

我是对的吗?我怎么可以用常量初始化这些数组而不将layer_ram类型更改为std_logic_vector数组?


编辑:

再现我的问题的最小工作的例子可以看这里: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; 
+0

的问题是,该元件的类型是不同的,一个具有ramd_type的元件类型和ramd_type0的以外的元件的类型,两个数组类型。你不显示常数NumN的值。如果没有更多信息([最小,完整和可验证的示例](http://stackoverflow.com/help/mcve)),则不清楚纠正措施是什么。还要注意w0,w1和w2的维数是不同的。你的w_init函数可能想成为三个函数,或者你只是在做一些程序错误的事情。 – user1155120

+0

NumN不是一个常量,而是一个泛型。该函数根据通用的LNum返回不同的数组大小。当LNum = 0时,则NumN和NumIn等于w0尺寸,依此类推。整个问题是我想根据通用值初始化可能具有不同维度的数组数组。 –

+0

IEEE Std 1076-2008 6.5.6.1 *通用接口列表完全由接口常量声明,接口类型声明,接口子程序声明和接口声明组成。* NumN'是接口常量,保留字常量是可选的(6.5 0.2)。你的工具链是否支持接口类型声明(6.5.3)? – user1155120

回答

0

我终于成功通过由元素分配给它元素初始化数组的数组功能winit。下面是上面贴的最小例的修正:(https://gist.github.com/jstefanowicz/abad35de9b0a930033e54ed0deeed771

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 ; 
     NumIn : natural  
    ); 

    port 
    (
     inputs : in std_logic_vector(17 downto 0); 
     outputs : out std_logic_vector(17 downto 0) 
    ); 

end test_gen; 

architecture beh of test_gen is 


    type ramd_type is array (NumN-1 downto 0) of std_logic_vector(17 downto 0); 
    type layer_ram is array (NumIn-1 downto 0) of ramd_type; 


    function w_init(LNum : natural) return layer_ram is 
    variable tmp_arr : layer_ram ; 
    begin 
    if LNum = 0 then 
     for i in 0 to NumIn-1 loop 
     for j in 0 to NumN-1 loop 
      tmp_arr(i)(j) := w0(i)(j); 
     end loop; 
    end loop; 
    elsif LNum = 1 then 
     for i in 0 to NumIn-1 loop 
     for j in 0 to NumN-1 loop 
      tmp_arr(i)(j) := w1(i)(j); 
     end loop; 
     end loop; 
    else 
     for i in 0 to NumIn-1 loop 
     for j in 0 to NumN-1 loop 
      tmp_arr(i)(j) := (others => '0'); 
     end loop; 
     end loop; 
    end if; 

    return tmp_arr ; 
    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 ; 
    NumN : natural ; 
    NumIn : natural 
); 

    port 
    (
    inputs : in std_logic_vector(17 downto 0); 
    outputs : out std_logic_vector(17 downto 0) 
); 

    end component; 
    type gen_ar is array (1 downto 0) of natural; 
    signal NumN_ar : gen_ar := (3,2); 
    signal NumIn_ar : gen_ar := (5,4); 
    signal inputs,outputs : std_logic_vector(17 downto 0); 

begin 

    test_gen_inst: 
    for i in 0 to 1 generate 
    tg:test_gen 
    generic map (
    LNum => i, 
    NumN => NumN_ar(i), 
    NumIn => NumIn_ar(i) 
) 
    port map (
    inputs => inputs, 
    outputs => outputs 
); 
    end generate; 

end beh;