2017-01-23 2 views
1

J'expérimente de synthétiser un code VHDL 2008 Vivado 2016,3 (la même situation est en 2016,4)Vivado 2016,3 array sans contrainte de record avec sans contrainte std_logic_vector

L'idée est de pouvoir avoir ensemble sans contrainte dans le dossier et à en même temps avoir un tableau sans contrainte de ces enregistrements.

Code pertinent:

(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; 

Et enfin test_entity_top .vhd qui par contre Entraîne les tailles pour la synthèse:

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; 

Tout cela se compile bien dans ModelSim. Mais Vivado hésite à sythesise ... avec cette erreur:

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] 

qui indiquent qu'il n'accepte réellement la syntaxe de contrainte d'enregistrement:

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

Bien qu'il n'aime pas:

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

Que suggérez-vous d'utiliser au lieu de tableaux et d'enregistrements non contraints? Le fait est que mon design change assez souvent la taille des bits du flux .. Donc l'utilisation de paquets génériques serait assez inélégante (surtout ce registre est un bon exemple quand dans un fichier vous avez le bus avec différentes tailles de bus de données)

jusqu'à présent, je l'ai utilisé une SLV dimensionnelle sans enregistrements avec indexation manuelle à l'aide de fonctions/procédures, mais est tout à fait désordre pour maintenir ...

ajouter également edaplayground exemple de code approprié https://www.edaplayground.com/x/eiC (pour démontrer que cela fonctionne dans le simulateur) ...

Editer:

Ce qui est intéressant est qu'il synthétisent en fait, si je suit:

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; 

Cela signifie donc que le tableau d'enregistrements avec tableau sans contrainte est en fait pris en charge, mais la syntaxe de contrainte directe n'est pas.

Des idées pour le définir moins élaborativement? Bien que ce n'est pas grand-chose à définir de haut niveau comme celui-ci .. Cependant, je ne me dérangerait pas de l'éviter, il semble un peu hacky ...

Merci Bruno

+0

Vous n'êtes pas sûr du crash, mais il semble que vos ports 'in_axis_in' et' out_axis_in' doivent avoir le type 'axis_in_vector' et non' axis_in'. Soit cela, ou supprimer la contrainte de plage sur ces ports. –

+1

Oui. Il contient des erreurs. Simulez-le d'abord et réparez-les. Commencez par les clauses bibliothèque/utilisation manquantes, puis les contraintes manquantes dans le paquet. Compilation du paquetage: 'ghdl -a axi_pkg.vhd axi_pkg.vhd: 6: 9: déclaration d'élément de type tableau sans contraintes" std_logic_vector "n'est pas autorisé'' le premier problème est assez clair. –

+1

Salut Bruno, comme disent les autres, il y a des erreurs à corriger. Je n'ai pas aimé le champ libre dans le disque, mais il semble que c'est légal en 2008 (j'ai appris quelque chose). C'est un peu fastidieux à utiliser, cependant: [https://www.edaplayground.com/x/5Gd3](https://www.edaplayground.com/x/5Gd3). Le prochain problème est que vous essayez de faire en sorte que le champ 'tuser' ait la même largeur. Je ne peux pas penser comment tu pourrais faire ça. Je me demande si les paquets génériques pourraient être une meilleure solution, en supposant que vous puissiez les synthétiser. –

Répondre

0

Avec Xilinx SR nous étions venus à travailler exemple de comportement désiré, donc je le poste ici car il fonctionne dans Vivado ainsi que 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; 

Le problème est que tous les fichiers n'ont pas été marqués comme 2008 dans Vivado (ma faute). Mais je poste cet exemple minimal pour qu'il corresponde bien à la question. Également lien Edaplayground: