2016-12-01 11 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; 
NumN

場合とNumIN層依存性であり、NbitWは定数です。

私がしたいことは、このRAMを定数で初期化することです。

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:私は、一般的な層の数Lnumに一定の良いと考えを選択する機能を宣言した層の内部

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'))); 

エンティティ:私は次を含むパッケージを作成しましたこれを行うには上記のように定義される。

私は次のエラーを取得GHDLで分析する場合:のModelSimで

conversion not allowed between not closely related types

を、私はこの1つを得る:

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

を私は問題はそのシミュレータによるlayer_ramlayer_ram0であることを取得密接に関連しているわけではありません。なぜなら、配列要素には異なるタイプのramdramd0があるからです。

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

アム右I:私にとって、これは時に配列型が密接に関連していると述べている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; 
+0

問題は、要素タイプが異なると、一方がramd_typeの要素タイプとramd_type0の他の要素のタイプは、両方の配列型を有する:ここで上記投稿最小例の修正です。定数NumNの値は表示されません。詳細な情報([最小限、完全かつ検証可能な例](http://stackoverflow.com/help/mcve))がなければ、是正処置がどのようなものになるかは不明です。また、w0、w1、およびw2の次元数が異なることにも注意してください。あなたのw_init関数は、おそらく3つの関数になりたいと思うか、手続き的に間違っているだけです。 – user1155120

+0

NumNは定数ではなく一般的なものです。この関数は、総称LNumに応じて異なる配列サイズを返します。 LNum = 0のとき、NumNとNumInはw0の次元に等しくなります。全体のポイントは、私はジェネリック値に応じて異なる次元を持つことができる配列の配列を初期化したいと思います。 –

+0

IEEE Std 1076-2008 6.5.6.1 *汎用インタフェースリストは、完全にインタフェース定数宣言、インタフェース型宣言、インタフェースサブプログラム宣言、およびインタフェースパッケージ宣言で構成されます。* NumN'はインタフェース定数、予約語定数は任意です(6.5 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;