2016-12-01 4 views
0

Ich arbeite mit einem Feedforward neuronalen Netzwerk von David Aledo entwickelt (siehe OpenCores Projekt Artificial Neural Network (ANN)) und ich habe Probleme mit der Initialisierung RAM-Arrays in Instanzen durch den Code generiert.VHDL Typ Konvertierung für Array von Arrays im neuronalen Netzwerk

Der Code generiert Schichten des neuronalen Netzes als Instanzen. Jede dieser Instanzen weist Block-RAM auf, die einer Schichtgewichtsmatrix zugeordnet sind. Dieser RAM ist in dem Code als ein Array von Arrays von std_logic_vector dargestellt, wie unten gezeigt:

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; 

wo NumN und NumIN sind Schicht abhängig und NbitW konstant ist.

Was ich tun möchte, ist dieses RAM mit einer Konstante zu initialisieren. Um dies zu tun Ich habe ein Paket erstellt die folgenden enthalten:

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

Innerhalb der Schicht Entities I Funktionen deklariert haben, die die konstante apropriate auf die Schichtnummer generic Lnum wählen:

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; 

Wo layer_ram ist wie oben definiert.

Wenn mit GHDL analysieren ich folgende Fehlermeldung erhalten:

conversion not allowed between not closely related types

In Modelsim ich dieses:

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

ich, dass das Problem ist, dass die Simulatoren nach der layer_ram und layer_ram0 sind nicht eng verwandt und es ist, weil die Array-Elemente verschiedene Typen ramd und ramd0 haben. Für mich scheint dies gegen den 1993-Standard zu sein, der besagt, dass Array-Typen eng verwandt sind, wenn:

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

Bin ich richtig? Wie könnte ich diese Arrays mit Konstanten initialisieren, ohne den Typ layer_ram in ein Array von std_logic_vectors zu ändern?


edit:

Ein minimales Arbeitsbeispiel, das mein Problem reproduziert kann hier angesehen werden: 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

Das Problem ist, dass die Elementtypen voneinander verschieden sind, hat man einen Elementtyp von ramd_type und der anderes einen Elementtyp ramd_type0 beiden Array-Typen. Sie zeigen den Wert der konstanten NumN nicht an. Ohne weitere Informationen (ein [minimales, vollständiges und überprüfbares Beispiel] (http://stackoverflow.com/help/mcve)) ist nicht klar, was die Korrekturmaßnahme wäre. Beachten Sie auch, dass die Dimensionalität von w0, w1 und w2 unterschiedlich ist. Ihre w_init-Funktion möchte wahrscheinlich drei Funktionen haben, oder Sie tun einfach etwas, das verfahrenstechnisch falsch ist. – user1155120

+0

NumN ist keine Konstante, sondern eine generische.Die Funktion gibt abhängig vom generischen LNum unterschiedliche Array-Größen zurück. Wenn LNum = 0, dann sind NumN und NumIn gleich den Dimensionen von W0 und so weiter. Der springende Punkt ist, dass ich das Array von Arrays initialisieren möchte, die abhängig von den generischen Werten unterschiedliche Dimensionen haben können. –

+0

IEEE Std 1076-2008 6.5.6.1 * Eine generische Schnittstellenliste besteht vollständig aus Deklarationen der Schnittstellenkonstanten, Schnittstellentypdeklarationen, Schnittstellen-Unterprogrammdeklarationen und Schnittstellenpaketdeklarationen. * NumN' ist eine Schnittstellenkonstante, die reservierte Wortkonstante ist optional (6.5 .2). Wird Ihre Werkzeugkette Schnittstellen-Typdeklarationen (6.5.3) unterstützen? – user1155120

Antwort

0

ich schließlich durch die Zuordnung es Elements für Element der Array von Arrays zu initialisieren verwalten in die Funktion winit. Hier ist eine Lösung für das minimal Beispiel oben geschrieben: (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; 
Verwandte Themen