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