2017-01-23 122 views
1

我嘗試來合成一些VHDL 2008代碼Vivado 2016.3(同樣的情況在2016.4)Vivado 2016.3記錄的約束陣列不受約束std_logic_vector

的想法是能夠有不受約束的陣列中的記錄,並在同時有無限制的這些記錄數組。

相關代碼:

(axi_pkg.vhd)

-- axi_pkg.vhd 
-- Author: Bruno Kremel (CERN BE-RF-FB) 
-- Date: 2016-01-23 
-- Description: AXI4 Package 

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 
use work.misc_pkg.all; 

package axi_pkg is 
    type axis_in is record 
     tdata : std_logic_vector; 
     tvalid : std_logic; 
     tlast : std_logic; 
     tuser : std_logic_vector; 
    end record; 

    type axis_out is record 
     tready : std_logic; 
    end record; 

    type axis_in_vector is array (natural range <>) of axis_in; 
    type axis_out_vector is array (natural range <>) of axis_out; 
end package; 

(axis_reg.vhd)

-- axis_reg.vhd 
-- Author: Bruno Kremel (CERN BE-RF-FB) 
-- Date: 2016-11-22 
-- Description: AXI4 Stream register 

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 
use work.misc_pkg.all; 
use work.axi_pkg.all; 

entity axis_reg is 
    generic (
     DATA_TYPE : string := "signed" 
     ); 
    port (
     aresetn : in std_logic; 
     aclk : in std_logic; 

     -- Input stream 
     in_axis_in : in axis_in; 
     in_axis_out : out axis_out; 

     -- Output stream 
     out_axis_in : out axis_in; 
     out_axis_out : in axis_out 
     ); 
end entity axis_reg; 

architecture basic of axis_reg is 
    constant OUT_DATA_W :natural := out_axis_in.tdata'length; 
    constant IN_DATA_W :natural := in_axis_in.tdata'length; 
    signal in_tdata_conv : std_logic_vector(OUT_DATA_W-1 downto 0); 
    signal in_tuser_conv : std_logic_vector(OUT_DATA_W/8-1 downto 0); 
    signal in_tdata_shd : std_logic_vector(IN_DATA_W-1 downto 0); 
    signal in_tuser_shd : std_logic_vector(IN_DATA_W/8-1 downto 0); 
begin 

    gen_signed: if DATA_TYPE = "signed" generate 
     in_tdata_conv <= std_logic_vector(resize(signed(in_tdata_shd), OUT_DATA_W)); 
     in_tuser_conv <= std_logic_vector(resize(signed(in_tuser_shd), OUT_DATA_W/8)); 
    end generate; 

    gen_unsigned: if DATA_TYPE = "unsigned" generate 
     in_tdata_conv <= std_logic_vector(resize(unsigned(in_tdata_shd), OUT_DATA_W)); 
     in_tuser_conv <= std_logic_vector(resize(unsigned(in_tuser_shd), OUT_DATA_W/8)); 
    end generate; 

    reg_ctrl_inst : entity work.axis_reg_ctrl 
     port map (
      aresetn => aresetn, 
      aclk => aclk, 

      next_tdata => in_tdata_conv, 
      next_tuser => in_tuser_conv, 
      next_update => open, 

      in_tvalid => in_axis_in.tvalid, 
      in_tready => in_axis_out.tready, 
      in_tlast => in_axis_in.tlast, 

      out_tdata => out_axis_in.tdata, 
      out_tvalid => out_axis_in.tvalid, 
      out_tready => out_axis_out.tready, 
      out_tlast => out_axis_in.tlast, 
      out_tuser => out_axis_in.tuser 
      ); 
end architecture; 

(test_entity.vhd)

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 
use work.axi_pkg.all; 

entity test_entity is 
    port (
     aresetn : std_logic; 
     aclk : std_logic; 

     -- Input stream 
     in_axis_in : in axis_in_vector; 
     in_axis_out : out axis_out_vector; 

     -- Output stream 
     out_axis_in : out axis_in_vector; 
     out_axis_out : in axis_out_vector 
     ); 
end entity; 

architecture test of test_entity is 

begin 

    gen_reg : for i in 0 to in_axis_in'length-1 generate 
    begin 
     reg_i : entity work.axis_reg 
      generic map (
       DATA_TYPE => "signed" 
       ) 
      port map (aresetn  => aresetn, 
         aclk   => aclk, 
         in_axis_in => in_axis_in(i), 
         in_axis_out => in_axis_out(i), 
         out_axis_in => out_axis_in(i), 
         out_axis_out => out_axis_out(i)); 
    end generate; 

end architecture; 

最後test_entity_top .vhd這基本上是缺點用於合成的尺寸:

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 
use work.axi_pkg.all; 

entity test_entity_top is 
end entity; 

architecture test of test_entity_top is 
    constant SIZE : natural := 10; 
    constant DATA_W : natural := 16; 
    signal test_axis_in : axis_in(tdata(DATA_W-1 downto 0), 
            tuser(DATA_W/8-1 downto 0)); 
    signal test_axis_out : axis_out; 
    signal in_axis_in : axis_in_vector(SIZE-1 downto 0)(tdata(DATA_W-1 downto 0), 
                 tuser(DATA_W/8-1 downto 0)); 
    signal in_axis_out : axis_out_vector(SIZE-1 downto 0); 
    signal out_axis_in : axis_in_vector(SIZE-1 downto 0)(tdata(DATA_W-1 downto 0), 
                 tuser(DATA_W/8-1 downto 0)); 
    signal out_axis_out : axis_out_vector(SIZE-1 downto 0); 
    signal aresetn  : std_logic; 
    signal aclk   : std_logic; 
begin 

    tst : entity work.test_entity 
     port map (aresetn  => aresetn, 
        aclk   => aclk, 
        in_axis_in => in_axis_in, 
        in_axis_out => in_axis_out, 
        out_axis_in => out_axis_in, 
        out_axis_out => out_axis_out 
       ); 
end architecture; 

這一切都很好地編譯在ModelSim中。但Vivado不願意sythesise吧...因爲這個錯誤:

ERROR: [Synth 8-2190] illegal syntax for subtype indication [/home/bkremel/test_vivado/test_entity_top.vhd:15] 
ERROR: [Synth 8-2235] indexed name prefix type axis_in_vector expects 1 dimensions [/home/bkremel/test_vivado/test_entity_top.vhd:15] 
ERROR: [Synth 8-2190] illegal syntax for subtype indication [/home/bkremel/test_vivado/test_entity_top.vhd:18] 
ERROR: [Synth 8-2235] indexed name prefix type axis_in_vector expects 1 dimensions [/home/bkremel/test_vivado/test_entity_top.vhd:18] 
ERROR: [Synth 8-1031] in_axis_in is not declared [/home/bkremel/test_vivado/test_entity_top.vhd:28] 
ERROR: [Synth 8-1031] out_axis_in is not declared [/home/bkremel/test_vivado/test_entity_top.vhd:30] 
ERROR: [Synth 8-1568] actual of formal out port out_axis_in cannot be an expression [/home/bkremel/test_vivado/test_entity_top.vhd:30] 
INFO: [Synth 8-2810] unit test ignored due to previous errors [/home/bkremel/test_vivado/test_entity_top.vhd:9] 

這表明它實際上接受記錄約束的語法:

signal test_axis_in : axis_in(tdata(DATA_W-1 downto 0), 
           tuser(DATA_W/8-1 downto 0)); 

雖然它不喜歡:

signal in_axis_in : axis_in_vector(SIZE-1 downto 0)(tdata(DATA_W-1 downto 0), 
               tuser(DATA_W/8-1 downto 0)); 

你會建議使用無約束數組和記錄的intead嗎?

問題是,我的設計經常改變流的位大小。所以使用通用包將是相當不雅的(特別是這個寄存器是一個很好的例子,當在一個文件中你有不同大小的數據總線)

到目前爲止,我已經使用一個維的SLV不使用功能/程序與手工索引記錄,但是這是相當混亂,以保持...

我還添加相關代碼https://www.edaplayground.com/x/eiC edaplayground例如(證明它在模擬器中工作)...

編輯:

有趣的是,它實際上合成,如果我下面:

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 
use work.axi_pkg.all; 

entity test_entity_top is 
end entity; 

architecture test of test_entity_top is 
    constant SIZE : natural := 4; 
    constant DATA_W : natural := 16; 
    subtype axis_in_constr is axis_in(tdata(DATA_W-1 downto 0), 
             tuser(DATA_W/8-1 downto 0)); 
    subtype axis_out_constr is axis_out; 

    signal ch0, ch1, ch2, ch3 : axis_in_constr; 
    signal out0, out1, out2, out3 : axis_in_constr; 
    signal in_axis_in : axis_in_vector := (ch0, ch1, ch2, ch3); 
    signal out_axis_in : axis_in_vector := (out0, out1, out2, out3); 
    signal in_axis_out : axis_out_vector(SIZE-1 downto 0); 
    signal out_axis_out : axis_out_vector(SIZE-1 downto 0); 
    signal aresetn  : std_logic; 
    signal aclk   : std_logic; 
begin 

    tst : entity work.test_entity 
     port map (aresetn  => aresetn, 
        aclk   => aclk, 
        in_axis_in => in_axis_in, 
        in_axis_out => in_axis_out, 
        out_axis_in => out_axis_in, 
        out_axis_out => out_axis_out 
       ); 
end architecture; 

所以這意味着與無約束陣列的記錄陣列實際上是支持的,但直接約束語法是沒有的。

任何想法如何更精細地定義它?儘管這不是什麼大不了的定義是這樣的頂級..不過我不會介意,以避免它,它看起來有點哈克......

感謝 布魯諾

+0

不知道崩潰,但它看起來像你的'in_axis_in'和'out_axis_in'端口應該有類型'axis_in_vector'而不''axis_in'。要麼,要麼刪除這些端口上的範圍限制。 –

+1

是的。它包含錯誤。首先模擬它並修復它們。從缺少的庫/使用條款開始,然後是包中缺少的約束條件。編譯包:'ghdl -a axi_pkg.vhd axi_pkg.vhd:6:9:無約束數組類型的元素聲明「std_logic_vector」是不允許的,第一個問題很明顯。 –

+1

嗨布魯諾,正如其他人所說,有錯誤需要修復。我不喜歡唱片中的不受約束的領域,但似乎它在2008年是合法的(我學到了一些東西)。但是,使用它有點費勁:[https://www.edaplayground.com/x/5Gd3](https://www.edaplayground.com/x/5Gd3)。接下來的問題是你想讓'tuser'字段的寬度相同。我想不出你會怎麼做。我想知道通用軟件包是否可能是更好的方法,假設你可以綜合它們。 –

回答

0

與賽靈思SR我們是來工作期望的行爲的例子,所以我將它發佈在Vivado以及ModelSim/Edaplayground中。

-- axi_pkg.vhd 
-- Author: Bruno Kremel (CERN BE-RF-FB) 
-- Date: 2016-01-23 
-- Description: AXI4 Package 

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

package axi_pkg is 
    type axis_downstream is record 
     tdata : std_logic_vector; 
     tvalid : std_logic; 
     tlast : std_logic; 
     tuser : std_logic_vector; 
    end record; 

    type axis_upstream is record 
     tready : std_logic; 
    end record; 

    type axis_downstream_vector is array (natural range <>) of axis_downstream; 
    type axis_upstream_vector is array (natural range <>) of axis_upstream; 
end package; 


library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 
use work.axi_pkg.all; 

entity test_entity_top is 
end entity; 

architecture test of test_entity_top is 
    constant SIZE : natural := 4; 
    constant DATA_W : natural := 16; 

    signal axis_downstream : axis_downstream_vector(SIZE-1 downto 0)(tdata(DATA_W-1 downto 0), 
                    tuser(DATA_W/8-1 downto 0)); 
    signal axis_upstream : axis_upstream_vector(SIZE-1 downto 0); 
begin 
    assert axis_downstream'length = SIZE 
     report "SIZE is not correct" 
    severity failure; 

    assert axis_downstream(0).tdata'length = DATA_W 
     report "TDATA width is not correct" 
    severity failure; 

    assert axis_downstream(0).tuser'length = (DATA_W/8) 
     report "TUSER width is not correct" 
    severity failure; 

end architecture; 

問題是,並非所有文件在Vivado中都標記爲2008年(我的錯)。但我發佈這個最小的例子,以便它很好地適合這個問題。 也Edaplayground鏈接:https://www.edaplayground.com/x/3sKr