2017-01-23 14 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)); 

Что бы вы посоветовали использовать без ограничений массивы и записи?

Дело в том, что мой проект довольно часто меняет размер бита потока. Поэтому использование общих пакетов было бы довольно неэлегантным (особенно этот регистр является хорошим примером, когда в одном файле у вас есть шина с шинами данных различного размера)

до сих пор я использовал одну мерную SLV без записей с ручной индексации с помощью функции/процедуры, но это весьма запутанна, чтобы поддерживать ...

Я также добавить edaplayground пример соответствующего кода https://www.edaplayground.com/x/eiC (чтобы показать, что он работает в симуляторе) ...

Редактировать:

Что интересно, что это на самом деле обобщать, если я следующее:

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; 

Так что означает, что массив записей с неограниченным массивом фактически поддерживается, но прямой синтаксис ограничения не является.

Любые идеи, как определить его менее продуманно? Несмотря на то, что это не большое дело, чтобы определить, на высшем уровне, как это .. Тем не менее, я бы не возражал, чтобы избежать этого, он выглядит немного Hacky ...

Благодаря Бруно

+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

С Xilinx 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; 

Проблема в том, что не все файлы были отмечены как 2008 в Vivado (моя ошибка). Но я размещаю этот минимальный пример, чтобы он хорошо отвечал на вопрос. Также Edaplayground link: https://www.edaplayground.com/x/3sKr