Voici les types VHDL analysés dans la dernière implémentation de ctags :
static kindDefinition VhdlKinds[] = {
{true, 'c', "constant", "constant declarations"},
{true, 't', "type", "type definitions"},
{true, 'T', "subtype", "subtype definitions"},
{true, 'r', "record", "record names"},
{true, 'e', "entity", "entity declarations"},
{false, 'C', "component", "component declarations"},
{false, 'd', "prototype", "prototypes"},
{true, 'f', "function", "function prototypes and declarations"},
{true, 'p', "procedure", "procedure prototypes and declarations"},
{true, 'P', "package", "package definitions"},
{false, 'l', "local", "local definitions"}
};
https://github.com/universal-ctags/ctags/blob/master/parsers/vhdl.c
Veuillez ajouter trois types supplémentaires :
optional_label: process (optional sensitivity list)
declarations
begin
sequential statements
end process optional_label;
optional_label
est l'étiquette de processus facultative et doit être signalée comme balise (par exemple kind = process
). S'il manque, une chaîne aléatoire (par exemple 4534_process) doit être utilisée comme nom de balise à la place. Les structures anonymes analysées de ctags en C peuvent être considérées comme un exemple.
instance_label: component_name
generic map (generic_association_list)
port map (port_association_list);
instance_label
est l'étiquette d'instanciation de composant obligatoire et doit être signalée comme balise (par exemple, kind = component instance label
). component_name
est le nom du composant instancié et doit également être signalé comme balise (par exemple kind = component instance
), afin que les balises de composant/entité associées puissent être trouvées.
J'ai trouvé un exemple dans nos cas de test :
entity accumulator is port (
a: in std_logic_vector(3 downto 0);
clk, reset: in std_logic;
accum: out std_logic_vector(3 downto 0)
);
end accumulator;
architecture simple of accumulator is
signal accumL: unsigned(3 downto 0);
begin
accumulate: process (clk, reset) begin
if (reset = '1') then
accumL <= "0000";
elsif (clk'event and clk= '1') then
accumL <= accumL + to_unsigned(a);
end if;
end process;
accum <= std_logic_vector(accumL);
end simple;
Avant de parler de processus, j'ai une question. Je pense que "simple" devrait être étiqueté si nous devions créer une étiquette pour accumuler.
Ai-je raison? Dans ce cas, quel "type" devrions-nous utiliser pour "simple" ?
Oui, simple
devrait également être tagué. Chaque entité VHDL a une architecture qui définit le comportement de l'entité elle-même.
Ainsi, je proposerais d'ajouter un autre type VHDL : a
, pour architecture bodies
.
@pidgeon777 , merci.
entity accumulator is port (
a: in std_logic_vector(3 downto 0);
clk, reset: in std_logic;
accum: out std_logic_vector(3 downto 0)
);
end accumulator;
Je pense que a, clk, accum, accumL devrait aussi être étiqueté.
Pour taguer accumL, nous devrions introduire le type "signal".
Pour taguer a, clk, accum, ~quel type devrions-nous introduire ?~ Je suppose que nous devrions introduire le type "port".
les champs d'étendue ne sont pas remplis. Vous ne pouvez donc rien faire d'intéressant.
Pour taguer a, clk, accum, quel genre devrions-nous introduire ? Je suppose que nous devrions introduire le type "port".
Oui, ils devraient également être étiquetés, éventuellement comme port declarations
:
http://www.vhdl.renerta.com/mobile/source/vhd00051.htm
Pour taguer accumL, nous devrions introduire le type "signal".
signal declarations
serait également acceptable :
http://www.vhdl.renerta.com/source/vhd00064.htm
les champs d'étendue ne sont pas remplis. Vous ne pouvez donc rien faire d'intéressant.
Je n'ai pas compris le point ci-dessus.
Cependant, nous ne devons pas non plus oublier les génériques :
http://www.vhdl.renerta.com/source/vhd00034.htm
Celles-ci sont également très importantes en VHDL et doivent donc également être étiquetées.
Merci.
champ de portée représente les relations propriétaire/possédé ou parent/enfant.
Les outils clients peuvent créer une "arborescence" à partir des champs.
Je voudrais montrer un exemple en langage C.
entrée.c :
1 struct point {
2 int x, y;
3 };
4 int length (point *p0, point *p1)
5 {
6 int dx = p1->x - p0->x;
7 int dy = p1->y - p0->y;
8 return (int)sqrt((double)(dx*dx + dy*dy));
9 }
sortie ctags :
% u-ctags --sort=no --fields=+KkZzSe-lf -n --kinds-C=+zl -o - input.c
point input.c 1;" kind:struct end:3
x input.c 2;" kind:member scope:struct:point typeref:typename:int end:2
y input.c 2;" kind:member scope:struct:point typeref:typename:int end:2
length input.c 4;" kind:function typeref:typename:int signature:(point * p0,point * p1) end:9
p0 input.c 4;" kind:parameter scope:function:length typeref:typename:point *
p1 input.c 4;" kind:parameter scope:function:length typeref:typename:point *
dx input.c 6;" kind:local scope:function:length typeref:typename:int end:6
dy input.c 7;" kind:local scope:function:length typeref:typename:int end:7
Voir portée : dans la sortie.
Pensons au VHDL.
entity accumulator is port (
a: in std_logic_vector(3 downto 0);
clk, reset: in std_logic;
accum: out std_logic_vector(3 downto 0)
);
end accumulator;
La portée de a
, clk
et accum
peut être : " scope:entity :accumulator".
Ceux-ci sont faciles.
architecture simple of accumulator is
signal accumL: unsigned(3 downto 0);
begin
...
Que diriez-vous accumL
?
Une de mes idées est scope:architecture:simple
.
Ce sera mieux que scope:entity:accumulator
car l'accumulateur peut avoir plusieurs architectures.
VHDL: tag architectures #2687
est fusionné.
Les ports sont tagués : https://github.com/universal-ctags/ctags/pull/2695 .
Pour taguer a, clk, accum, quel genre devrions-nous introduire ? Je suppose que nous devrions introduire le type "port".
Oui, elles doivent également être étiquetées, éventuellement en tant que déclarations de port :
Voulez-vous dire que "déclaration de port" est préférable à "port" comme nom de genre pour a, clk, accum ?
J'ai fait une pull request (#2695) pour le marquage des ports. J'ai utilisé "port" comme nom de genre. Est-ce que je vais dans le mauvais sens ?
Me revoilà. Je pense que ctags
a beaucoup de potentiel pour baliser les langages HDL ( VHDL
, Verilog
, SystemVerilog
) même à des fins d'analyse de code/de peluchage, donc je ' Je suis plus qu'heureux de vous aider.
Il ne me sera peut-être pas possible de répondre rapidement certains jours, mais j'essaierai de répondre à toutes vos questions dès que possible.
De plus, j'ai quelques idées intéressantes à partager plus tard dans la journée, et je vous fournirai également les réponses que vous avez demandées.
Excellent!
@pidgeon777 ,
Pensez-vous que "port" est un mauvais nom?
$ ./ctags --list-kinds=SystemVerilog
c constants (define, parameter, specparam, enum values)
e events
f functions
m modules
n net data types
p ports
Je ne connais pas bien les langues pour le matériel. Cependant, "port" est utilisé dans SystemVerilog.
Je suppose donc que l'utilisation du même nom en VHDL peut convenir
Salut @masatake , la liste des types VHDL :
c constant declarations
t type definitions
T subtype definitions
r record names
e entity declarations
C component declarations [off]
d prototypes [off]
f function prototypes and declarations
p procedure prototypes and declarations
P package definitions
l local definitions [off]
port
pourrait convenir, mais si vous souhaitez conserver le même format utilisé dans ces types de VHDL, je pense que l'un des éléments suivants pourrait être plus approprié :
port declarations
← meilleurport definitions
Pourtant, je ne suis pas si sûr de la différence entre la définition et la déclaration en VHDL. Un cas C++ :
Plus tard dans la soirée, j'essaierai de répondre aux autres questions que vous avez posées, j'ai déjà pris quelques notes il y a quelques jours.
Je vois. Vous parlez de "DESCRIPTION".
$ ./ctags --list-kinds-full=VHDL
#LETTER NAME ENABLED REFONLY NROLES MASTER DESCRIPTION
C component no no 0 NONE component declarations
P package yes no 0 NONE package definitions
T subtype yes no 0 NONE subtype definitions
a architecture yes no 0 NONE architectures
c constant yes no 0 NONE constant declarations
d prototype no no 0 NONE prototypes
e entity yes no 0 NONE entity declarations
f function yes no 0 NONE function prototypes and declarations
l local no no 0 NONE local definitions
p procedure yes no 0 NONE procedure prototypes and declarations
r record yes no 0 NONE record names
t type yes no 0 NONE type definitions
Nous ne considérons pas DESCRIPTION comme la partie de la CLI ctags dont nous devrions conserver la compatibilité.
La valeur de DESCRIPTION n'apparaît pas dans la sortie des balises.
Ce que je voudrais savoir, c'est NOM. Le NOM fait partie de la CLI.
La valeur de NAME apparaît dans la sortie des balises. Ainsi, un outil lisant un fichier de balises peut dépendre de la valeur de NAME.
Ma question initiale est de savoir si "port" est un NOM de type approprié ou non.
Je pense que "port" comme NAME est correct. Ce que je dois mettre à jour est le champ DESCRIPTION pour le type "port":
diff --git a/parsers/vhdl.c b/parsers/vhdl.c
index 868c02e3..e276d978 100644
--- a/parsers/vhdl.c
+++ b/parsers/vhdl.c
@@ -204,7 +204,7 @@ static kindDefinition VhdlKinds[] = {
{true, 'P', "package", "package definitions"},
{false, 'l', "local", "local definitions"},
{true, 'a', "architecture", "architectures"},
- {false, 'q', "port", "ports"},
+ {false, 'q', "port", "port declarations"},
};
Avec ce changement, --list-kinds-full=VHDL
rapporte :
...
p procedure yes no 0 NONE procedure prototypes and declarations
q port no no 0 NONE port declarations
r record yes no 0 NONE record names
...
Je pense que "port" comme NAME est correct
Je confirme.
q port no no 0 NONE port declarations
Aussi ce serait parfait.
Mais, parlant d'un port, il serait essentiel à mon avis de le rattacher à un champ d'application. Ou, si vous préférez, étant donné un port appelé PORT_C
, cela pourrait être déclaré dans deux ou plusieurs entités différentes, ainsi le nom de l'entité doit être utilisé comme portée pour le port.
Exemple:
entity ENTITY_A is
generic (
GENERIC_C : integer := value;
);
port (
PORT_C : in std_logic
);
end entity;
entity ENTITY_B is
generic (
GENERIC_C : integer := value;
);
port (
PORT_C : in std_logic
);
end entity;
Balises analysées :
6:PORT_C scope:entity:ENTITY_A
15:PORT_C scope:entity:ENTITY_B
On pourrait aussi avoir :
component COMPONENT_A is
generic (
GENERIC_C : integer := value;
);
port (
PORT_C : in std_logic
);
end entity;
component COMPONENT_B is
generic (
GENERIC_C : integer := value;
);
port (
PORT_C : in std_logic
);
end entity;
Balises analysées :
6:PORT_C scope:component:COMPONENT_A
15:PORT_C scope:component:COMPONENT_B
Merci pour la description détaillée.
Dans #2695, j'ai déjà rempli les champs de portée des déclarations de port si elles sont dans des entités.
Je n'ai rien fait pour les déclarations de port dans les composants.
Je vais réviser mon changement.
Avec le changement proposé dans #2695, l'analyseur VHDL peut extraire les ports et les génériques déclarés dans une entité et un composant.
$ u-ctags --list-kinds-full=VHDL
#LETTER NAME ENABLED REFONLY NROLES MASTER DESCRIPTION
C component no no 0 NONE component declarations
P package yes no 0 NONE package definitions
T subtype yes no 0 NONE subtype definitions
a architecture yes no 0 NONE architectures
c constant yes no 0 NONE constant declarations
d prototype no no 0 NONE prototypes
e entity yes no 0 NONE entity declarations
f function yes no 0 NONE function prototypes and declarations
g generic no no 0 NONE generic declarations
l local no no 0 NONE local definitions
p procedure yes no 0 NONE procedure prototypes and declarations
q port no no 0 NONE port declarations
r record yes no 0 NONE record names
t type yes no 0 NONE type definitions
$ cat input.vhd
-- https://www.ics.uci.edu/~jmoorkan/vhdlref/Synario%20VHDL%20Manual.pdf
entity logical_ops_1 is
port (a, b, c, d: in bit;
m: out bit);
end logical_ops_1;
$ u-ctags --sort=no --kinds-VHDL='*' -o - input.vhd
logical_ops_1 input.vhd /^entity logical_ops_1 is$/;" e
a input.vhd /^ port (a, b, c, d: in bit;$/;" q entity:logical_ops_1
b input.vhd /^ port (a, b, c, d: in bit;$/;" q entity:logical_ops_1
c input.vhd /^ port (a, b, c, d: in bit;$/;" q entity:logical_ops_1
d input.vhd /^ port (a, b, c, d: in bit;$/;" q entity:logical_ops_1
m input.vhd /^ m: out bit);$/;" q entity:logical_ops_1
$ cat input-0.vhd
-- Taken from https://github.com/universal-ctags/ctags/issues/2678
-- commented by @pidgeon777.
entity ENTITY_A is
generic (
GENERIC_C : integer := value;
);
port (
PORT_C : in std_logic
);
end entity;
entity ENTITY_B is
generic (
GENERIC_C : integer := value;
);
port (
PORT_C : in std_logic
);
end entity;
$ u-ctags --sort=no --kinds-VHDL='*' -o - input-0.vhd
ENTITY_A input-0.vhd /^entity ENTITY_A is$/;" e
GENERIC_C input-0.vhd /^ GENERIC_C : integer := value;$/;" g entity:ENTITY_A
PORT_C input-0.vhd /^ PORT_C : in std_logic$/;" q entity:ENTITY_A
ENTITY_B input-0.vhd /^entity ENTITY_B is$/;" e
GENERIC_C input-0.vhd /^ GENERIC_C : integer := value;$/;" g entity:ENTITY_B
PORT_C input-0.vhd /^ PORT_C : in std_logic$/;" q entity:ENTITY_B
$ cat input-1.vhd
-- Taken from https://github.com/universal-ctags/ctags/issues/2678
-- commented by @pidgeon777.
component COMPONENT_A is
generic (
GENERIC_C : integer := value;
);
port (
PORT_C : in std_logic
);
end entity;
component COMPONENT_B is
generic (
GENERIC_C : integer := value;
);
port (
PORT_C : in std_logic
);
end entity;
$ u-ctags --sort=no --kinds-VHDL='*' -o - input-1.vhd
COMPONENT_A input-1.vhd /^component COMPONENT_A is$/;" C
GENERIC_C input-1.vhd /^ GENERIC_C : integer := value;$/;" g component:COMPONENT_A
PORT_C input-1.vhd /^ PORT_C : in std_logic$/;" q component:COMPONENT_A
COMPONENT_B input-1.vhd /^component COMPONENT_B is$/;" C
GENERIC_C input-1.vhd /^ GENERIC_C : integer := value;$/;" g component:COMPONENT_B
PORT_C input-1.vhd /^ PORT_C : in std_logic$/;" q component:COMPONENT_B
Le dernier est un signal sur lequel je devrais travailler avant de travailler sur le processus et l'instance.
Si j'ai fait quelque chose de mal, faites-le moi savoir.
@pidgeon777 ,
component COMPONENT_A is
generic (
GENERIC_C : integer := value;
);
port (
PORT_C : in std_logic
);
end entity;
Est la dernière ligne, "end entity ;" correct?
Après avoir lu quelques articles sur VHDL, je suppose que la ligne devrait être "composant de fin ;" ?
Est la dernière ligne, "end entity ;" correct?
Ma faute, quand j'ai copié-collé la déclaration du composant j'ai oublié de changer la dernière ligne. Je ferai plus attention la prochaine fois.
La déclaration de composant correcte est :
component COMPONENT_A is
generic (
GENERIC_C : integer := value
);
port (
PORT_C : in std_logic
);
end component [COMPONENT_A];
Notez que le nom du composant à la fin de end component
n'est pas obligatoire dans le code, seulement facultatif. Je l'ai donc mis entre crochets.
Plus généralement, pour la déclaration de composant :
component component_name [ is ]
[ generic ( generic_list ); ]
[ port ( port_list ); ]
end component [ component_name ];
Je suggère fortement cette référence pour les déclarations et définitions VHDL :
https://www.hdlworks.com/hdl_corner/vhdl_ref/
Avec le changement proposé dans #2695, l'analyseur VHDL peut extraire les ports et les génériques déclarés dans une entité et un composant.
Considérons maintenant la situation suivante. ENTITY_TOP
instancie à la fois ENTITY_1
et ENTITY_2
:
entrée.vhd :
library ieee;
use ieee.std_logic_1164.all;
entity ENTITY_TOP is
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end entity;
architecture arch of ENTITY_TOP is
signal sig : std_logic := '0';
component ENTITY_1
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end component;
component ENTITY_2
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end component;
begin
ENTITY_1_i : ENTITY_1
generic map(
GEN => 0
)
port map(
INP => '0'
);
ENTITY_2_i : ENTITY_2
generic map(
GEN => 0
)
port map(
INP => '0'
);
end architecture;
entrée-0.vhd :
library ieee;
use ieee.std_logic_1164.all;
entity ENTITY_1 is
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end entity;
architecture arch of ENTITY_1 is
signal sig : std_logic := '0';
begin
end architecture;
entrée-1.vhd :
library ieee;
use ieee.std_logic_1164.all;
entity ENTITY_2 is
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end entity;
architecture arch of ENTITY_2 is
signal sig : std_logic := '0';
begin
end architecture;
Nous pouvons noter ce qui suit :
1) GEN
générique est le même nom pour les trois entités, ainsi que les deux composants, et enfin les deux instanciations de composants. Le nom de l'entité ou du composant doit-il être utilisé comme étendue pour différencier les différentes balises GEN
? Exemple : GEN:scope:entity:ENTITY_TOP
, GEN:scope:entity:ENTITY_1
, GEN:scope:entity:ENTITY_2
, GEN:scope:component:ENTITY_1
, GEN:scope:component:ENTITY_2
, GEN:scope:instance:ENTITY_1
, GEN:scope:instance:ENTITY_2
.
2) INP
generic est le même nom pour les trois entités, ainsi que les deux composants, et enfin les deux instanciations de composants. Le nom de l'entité ou du composant doit-il être utilisé comme étendue pour différencier les différentes balises INP
? Exemple : INP:scope:entity:ENTITY_TOP
, INP:scope:entity:ENTITY_1
, INP:scope:entity:ENTITY_2
, INP:scope:component:ENTITY_1
, INP:scope:component:ENTITY_2
, INP:scope:instance:ENTITY_1
, INP:scope:instance:ENTITY_2
.
3) arch
est le même nom pour l'architecture des trois entités. Le nom de l'entité doit-il être utilisé comme étendue pour différencier les trois balises arch
? Exemple : arch:scope:ENTITY_TOP
, arch:scope:ENTITY_1
, arch:scope:ENTITY_2
.
4) sig
est le même nom pour le signal des trois architectures. Le nom de l'entité et de l'architecture doit-il être utilisé comme étendue pour différencier les trois balises arch
? Exemple : sig:scope:arch:ENTITY_TOP
, sig:scope:arch:ENTITY_1
, sig:scope:arch:ENTITY_2
. À la fois entité et architecture, car une entité peut avoir plusieurs architectures partageant la définition d'un signal avec le même nom, et le même nom de signal peut être utilisé dans l'architecture de différentes entités.
@masatake a ajouté des noms de fichiers pour chaque exemple de code.
Je voudrais que vous lisiez https://docs.ctags.io/en/latest/units.html. J'ai ajouté des cas de test en fonction de votre entrée à ma demande d'extraction.
Je voudrais que vous lisiez args.ctags, input(-[0-9])?.vhd et les balises attendues. Ils expliquent comment fonctionne mon amélioration.
J'expliquerai 3 plus tard.
Vous n'avez pas besoin de voir les modifications apportées aux fichiers sous Units/review-needed.r/test.vhd.t/. Ils sont trop grands.
Après avoir repensé à 3., je devrais utiliser le champ de portée au lieu du champ d'entité pour représenter la relation entre l'architecture et l'entité. Cela rompt les compatibilités.
process
a été ajouté dans #2695 .
instance_label: component_name
generic map (generic_association_list)
port map (port_association_list);
Je pense que instance_label
devrait être étiqueté avec le type "instance".
Le champ typeref peut être utilisé pour attacher "component_name" à la balise.
component_name
est étiqueté comme balise de référence avec le type "composant".
instance_label input.vhd /^...$/;" kind:instance scope:... typeref:component:component_name roles:def
component_nameinput.vhd /^...$/;" kind:component roles:instantiated instance:instance_label
instance:
est un champ spécifique au VHDL.
Je pense que je dois écrire une page de manuel pour l'analyseur VHDL.
Je voudrais que vous lisiez https://docs.ctags.io/en/latest/units.html. J'ai ajouté des cas de test en fonction de votre entrée à ma demande d'extraction.
Je voudrais que vous lisiez args.ctags, input(-[0-9])?.vhd et les balises attendues. Ils expliquent comment fonctionne mon amélioration.
Ok je vais lire ça.
Après avoir repensé à 3., je devrais utiliser le champ de portée au lieu du champ d'entité pour représenter la relation entre l'architecture et l'entité. Cela rompt les compatibilités.
Le fait est que :
Ainsi, par exemple :
ENTITY_1.vhd :
library ieee;
use ieee.std_logic_1164.all;
entity ENTITY_1 is
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end entity;
architecture arch1 of ENTITY_1 is
signal sig : std_logic := '0';
begin
end architecture;
architecture arch2 of ENTITY_1 is
signal sig : std_logic := '0';
begin
end architecture;
ENTITY_2.vhd :
library ieee;
use ieee.std_logic_1164.all;
entity ENTITY_2 is
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end entity;
architecture arch1 of ENTITY_2 is
signal sig : std_logic := '0';
begin
end architecture;
architecture arch2 of ENTITY_2 is
signal sig : std_logic := '0';
begin
end architecture;
ENTITY_TOP.vhd :
library ieee;
use ieee.std_logic_1164.all;
entity ENTITY_TOP is
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end entity;
architecture arch of ENTITY_TOP is
signal sig : std_logic := '0';
component ENTITY_1
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end component;
component ENTITY_2
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end component;
begin
ENTITY_1_i : entity work.ENTITY_1(arch1)
generic map(
GEN => 0
)
port map(
INP => '0'
);
ENTITY_2_i : entity work.ENTITY_2(arch2)
generic map(
GEN => 0
)
port map(
INP => '0'
);
end architecture;
````
Some examples of expected tags:
- ENTITY_TOP
ENTITY_TOP:entity
- ENTITY_1
ENTITY_1:entity
ENTITY_1:component:entity:ENTITY_TOP
ENTITY_1:component instance:entity:ENTITY_TOP
- ENTITY_2
ENTITY_2:entity
ENTITY_2:component:entity:ENTITY_TOP
ENTITY_2:component instance:entity:ENTITY_TOP
- GEN
GEN:generic:entity:ENTITY_TOP
GEN:generic:entity:ENTITY_1
GEN:generic:entity:ENTITY_2
GEN:generic:component:ENTITY_1:entity:ENTITY_TOP → Tag of the generic `GEN` of the component `ENTITY_1` in `ENTITY_TOP`
GEN:generic:component:ENTITY_2:entity:ENTITY_TOP → Tag of the generic `GEN` of the component `ENTITY_2` in `ENTITY_TOP`
GEN:generic:instance label:ENTITY_1_i:(component:ENTITY_1):entity:ENTITY_TOP ? Tag of the generic map `GEN` of the instance `ENTITY_1_i` of the component `ENTITY_1` in `ENTITY_TOP` (`instance label:ENTITY_1_i` has to be associated to `component:ENTITY_1`, so the latter may be redundant for this particular tag of `GEN`, thus reported between parenthesis)
GEN:generic:instance label:ENTITY_2_i:(component:ENTITY_2):entity:ENTITY_TOP ? Tag of the generic map `GEN` of the instance `ENTITY_2_i` of the component `ENTITY_2` in `ENTITY_TOP` (`instance label:ENTITY_2_i` has to be associated to `component:ENTITY_2`, so the latter may be redundant for this particular tag of `GEN`, thus reported between parenthesis)
- INP
INP:port:entity:ENTITY_TOP
INP:port:entity:ENTITY_1
INP:port:entity:ENTITY_2
INP:port:component:ENTITY_1:entity:ENTITY_TOP → Tag of the port `INP` of the component `ENTITY_1` in `ENTITY_TOP`
INP:port:component:ENTITY_2:entity:ENTITY_TOP → Tag of the port `INP` of the component `ENTITY_2` in `ENTITY_TOP`
INP:port:instance label:ENTITY_1_i:(component:ENTITY_1):entity:ENTITY_TOP → Tag of the port map `INP` of the instance `ENTITY_1_i` of the component `ENTITY_1` in `ENTITY_TOP` (`instance label:ENTITY_1_i` has to be associated to `component:ENTITY_1`, so the latter may be redundant for this particular tag of `INP`, thus reported between parenthesis)
INP:port:instance label:ENTITY_2_i:(component:ENTITY_2):entity:ENTITY_TOP → Tag of the port map `INP` of the instance `ENTITY_2_i` of the component `ENTITY_2` in `ENTITY_TOP` (`instance label:ENTITY_2_i` has to be associated to `component:ENTITY_2`, so the latter may be redundant for this particular tag of `INP`, thus reported between parenthesis)
- sig
sig:signal:architecture:arch1:entity:ENTITY_TOP
sig:signal:architecture:arch1:entity:ENTITY_1
sig:signal:architecture:arch2:entity:ENTITY_1
sig:signal:architecture:arch1:entity:ENTITY_2
sig:signal:architecture:arch2:entity:ENTITY_2
- arch
arch:architecture:entity:ENTITY_TOP
- arch1
arch1:architecture:entity:ENTITY_1
arch1:architecture:entity:ENTITY_2
(arch1:architecture:instance label:ENTITY_1_i) ? Should enabled architecture of instanced component be tagged too? See `ENTITY_1_i : entity work.ENTITY_1(arch1)`
(arch1:architecture:instance label:ENTITY_2_i) ? Should enabled architecture of instanced component be tagged too? See `ENTITY_2_i : entity work.ENTITY_2(arch1)`
- arch2
arch2:architecture:entity:ENTITY_1
arch2:architecture:entity:ENTITY_2
- ENTITY_1_i
ENTITY_1_i:instance label:component:ENTITY_1:entity:ENTITY_TOP → It is important to note that an instance label might not be associated to an instanced component (could be used for a generated statement instead, for example), so it could be a good idea to also use the component itself as a scope?
- ENTITY_2_i
ENTITY_2_i:instance label:component:ENTITY_2:entity:ENTITY_TOP → It is important to note that an instance label might not be associated to an instanced component (could be used for a generated statement instead, for example), so it could be a good idea to also use the component itself as a scope?
The most vital things of all, which is really missing and would be extremely useful, is a way to recognize the tags of the components instantiated inside an entity. It should thus include the following:
```vhdl
component ENTITY_1
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end component;
Balisage de base : component ENTITY_1
. Mais nous ne savons pas si ENTITY_1
sera réellement instancié ou non, à en juger uniquement par cette instruction de composant.
Et
ENTITY_1_i : entity work.ENTITY_1(arch1)
generic map(
GEN => 0
)
port map(
INP => '0'
);
Balisage complet : ENTITY_1_i : entity work.ENTITY_1(arch1)
. Nous savons maintenant que ENTITY_1
sera instancié.
Pourquoi est-ce une information vitale ? Car cela permettrait de construire une hiérarchie des composants. Ce serait d'une aide extrême avec:
Merci. J'ai trouvé qu'il faudrait plus de temps pour baliser les instanciations.
J'aimerais donc fusionner #2695 avant de travailler sur les instanciations.
Pourriez-vous essayer #2695 ? Avec la modification de la demande d'extraction, vous pouvez baliser les processus.
La ligne de commande suivante active toutes les fonctionnalités que j'ai implémentées dans #2695.
$ ./ctags --options=NONE -o - --sort=no '--fields=+Kpre' '--extras=+r' '--kinds-VHDL=+{local}{prototype}{component}' --fields=+e INPUT.vhd
Salut, malheureusement, je ne suis pas un expert Github. J'aimerais tester en profondeur vos dernières modifications, mais je ne sais pas comment je pourrais faire cela. Existe-t-il un exécutable disponible quelque part en téléchargement ? Ou est-ce quelque chose que je devrais compiler avec les outils appropriés ? Dans ce dernier cas, pourriez-vous me suggérer la documentation appropriée à suivre ?
Quel système d'exploitation utilisez-vous ?
Windows 10 x64 Pro et Windows 7 x64.
Avant d'essayer la branche VHDL, vous devez trouver un moyen de construire des ctags tirés de la branche master.
Ce que vous devez savoir sur git est très simple ; tapez "git clone https://github.com/universal-ctags/ctags.git ".
Le construire nécessite des préparations et des connaissances. Dans ce domaine, je ne peux pas vous aider car je n'utilise pas Windows.
Voir https://docs.ctags.io/en/latest/windows.html. Si vous pouvez créer un exécutable ctags avec succès, faites-le moi savoir.
Je vais vous expliquer la façon de construire le code à la branche pour VHDL.
Malheureusement, je pense que je ne pourrai pas exécuter ces tests bientôt, j'ai ce problème critique:
https://github.com/universal-ctags/ctags/issues/2725
Cela se produit lorsque j'essaie d'exécuter les versions de Ctags publiées au cours des derniers mois. Savez-vous s'il existe un moyen de résoudre ce problème ?
Il n'y a pas de binaire pré-construit pour #2695.
Pour essayer #2695, vous devez créer vous-même un exécutable ctags.
C'est maintenant clair, merci. Je vais essayer de construire un exécutable ctags en suivant vos instructions, alors.
Me revoilà. J'ai réussi à cloner le référentiel principal ctags
, en récupérant également votre demande d'extraction, en obtenant enfin le nouvel exécutable ctags
avec toutes vos nouvelles améliorations.
J'ai fait quelques tests en générant des balises pour les fichiers d'entrée suivants :
ENTITY_1.vhd :
library ieee;
use ieee.std_logic_1164.all;
entity ENTITY_1 is
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end entity;
architecture arch1 of ENTITY_1 is
signal sig : std_logic := '0';
begin
PROC_p: process(INP)
-----------------------------
variable var_v : integer := 0;
-----------------------------
begin
-----------------------------
var_v := 0;
-----------------------------
if (INP = '1') then
sig <= '1';
else
sig <= '0';
end if;
-----------------------------
end process;
-----------------------------
process
-----------------------------
variable var_v : integer := 0;
-----------------------------
begin
-----------------------------
var_v := 0;
-----------------------------
if (INP = '1') then
sig <= '1';
else
sig <= '0';
end if;
-----------------------------
end process;
-----------------------------
end architecture;
architecture arch2 of ENTITY_1 is
signal sig : std_logic := '0';
begin
PROC_p: process(INP)
-----------------------------
variable var_v : integer := 0;
-----------------------------
begin
-----------------------------
var_v := 0;
-----------------------------
if (INP = '1') then
sig <= '1';
else
sig <= '0';
end if;
-----------------------------
end process;
-----------------------------
process
-----------------------------
variable var_v : integer := 0;
-----------------------------
begin
-----------------------------
var_v := 0;
-----------------------------
if (INP = '1') then
sig <= '1';
else
sig <= '0';
end if;
-----------------------------
end process;
-----------------------------
end architecture;
ENTITY_2.vhd :
library ieee;
use ieee.std_logic_1164.all;
entity ENTITY_2 is
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end entity;
architecture arch1 of ENTITY_2 is
signal sig : std_logic := '0';
begin
PROC_p: process(INP)
-----------------------------
variable var_v : integer := 0;
-----------------------------
begin
-----------------------------
var_v := 0;
-----------------------------
if (INP = '1') then
sig <= '1';
else
sig <= '0';
end if;
-----------------------------
end process;
-----------------------------
process
-----------------------------
variable var_v : integer := 0;
-----------------------------
begin
-----------------------------
var_v := 0;
-----------------------------
if (INP = '1') then
sig <= '1';
else
sig <= '0';
end if;
-----------------------------
end process;
-----------------------------
end architecture;
architecture arch2 of ENTITY_2 is
signal sig : std_logic := '0';
begin
PROC_p: process(INP)
-----------------------------
variable var_v : integer := 0;
-----------------------------
begin
-----------------------------
var_v := 0;
-----------------------------
if (INP = '1') then
sig <= '1';
else
sig <= '0';
end if;
-----------------------------
end process;
-----------------------------
process
-----------------------------
variable var_v : integer := 0;
-----------------------------
begin
-----------------------------
var_v := 0;
-----------------------------
if (INP = '1') then
sig <= '1';
else
sig <= '0';
end if;
-----------------------------
end process;
-----------------------------
end architecture;
ENTITY_TOP.vhd :
library ieee;
use ieee.std_logic_1164.all;
entity ENTITY_TOP is
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end entity;
architecture arch of ENTITY_TOP is
signal sig : std_logic := '0';
component ENTITY_1
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end component;
component ENTITY_2
generic (
GEN : integer := 0
);
port (
INP : in std_logic
);
end component;
begin
ENTITY_1_1 : entity work.ENTITY_1(arch1)
generic map(
GEN => GEN
)
port map(
INP => INP
);
ENTITY_1_2 : entity work.ENTITY_1(arch2)
generic map(
GEN => GEN
)
port map(
INP => INP
);
ENTITY_2_1 : entity work.ENTITY_2(arch1)
generic map(
GEN => GEN
)
port map(
INP => INP
);
ENTITY_2_2 : entity work.ENTITY_2(arch2)
generic map(
GEN => GEN
)
port map(
INP => INP
);
PROC_p: process(INP)
-----------------------------
variable var_v : integer := 0;
-----------------------------
begin
-----------------------------
var_v := 0;
-----------------------------
if (INP = '1') then
sig <= '1';
else
sig <= '0';
end if;
-----------------------------
end process;
-----------------------------
process
-----------------------------
variable var_v : integer := 0;
-----------------------------
begin
-----------------------------
var_v := 0;
-----------------------------
if (INP = '1') then
sig <= '1';
else
sig <= '0';
end if;
-----------------------------
end process;
-----------------------------
end architecture;
Vos modifications récentes ont beaucoup amélioré l'analyseur VHDL, augmentant son potentiel.
Maintenant, voici quelques résultats après avoir effectué quelques tests :
La balise process
n'a pas de portée. Ça devrait être:
architecture:entity_name.arch_name
La portée de la balise variable
est actuellement :
process:proc_name
Ça devrait être:
process:entity_name.arch_name.proc_name
Concernant les balises manquantes, nous avons :
instance label
. Considérons cet extrait de code, utilisé pour instancier un composant à l'intérieur d'une architecture :
instance_label : entity library_name.entity_name(arch_name)
generic map(
GEN => GEN
)
port map(
PORT => PORT
);
instance_label
identifie l'instance particulière du composant entity_name
, dont l'entité est compilée dans la bibliothèque library_name
, en spécifiant également son architecture arch_name
comme celle à activer. Ainsi, en supposant qu'il soit instancié à l'intérieur de l'architecture $# top_arch
top_entity
l'entité top_entity, sa portée devrait théoriquement ressembler à :
architecture:top_entity.top_arch.library_name.entity_name.arch_name
.
Mais maintenant, une considération importante doit être faite. Tout d'abord, décrivons ce qu'est une bibliothèque en VHDL. Une bibliothèque est un conteneur dans lequel des entités et leurs architectures respectives doivent être compilées. Plusieurs entités portant le même nom ne peuvent pas être compilées dans la même bibliothèque, mais une entité peut être compilée dans plusieurs bibliothèques, sans changer son nom à chaque compilation. La bibliothèque de travail actuelle en VHDL est nommée work
.
En spécifiant la bibliothèque library_name
dans ce cas, nous supposons que le composant à instancier est donc associé à une entité compilée dans cette bibliothèque. Mais, en parsant simplement le fichier contenant la définition de cette entité, nous ne pourrions en aucun cas récupérer à l'avance le nom de la bibliothèque dans laquelle elle sera compilée.
En effet, l'élément library_name
dépend strictement des paramètres passés lors de la compilation de cette entité (par exemple, un argument de compilation est utilisé pour indiquer la bibliothèque dans laquelle le composant sélectionné doit être compilé).
C'est aussi la raison pour laquelle aucun élément library_name
n'est actuellement utilisé comme portée pour les types VHDL actuellement disponibles dans ctags
. Car, en somme, cet élément n'est généralement connu qu'à deux reprises :
Ainsi, jusqu'à ce qu'une solution ou une utilisation appropriée soit trouvée pour l'élément library_name
, ce qui suit pourrait être considéré comme une bonne portée pour la balise instance label
la place :
architecture:top_entity.top_arch.entity_name.arch_name
.
En omettant l'élément library_name
, l'hypothèse ici est qu'aucune entité multiple partageant le même nom ne sera analysée et étiquetée dans le projet de travail en cours et que l'entité analysée sera exactement celle qui serait compilée dans ce library_name
bibliothèque.
instance label generic/port
. En faisant également les mêmes considérations que ci-dessus, nous devrions également baliser le mappage générique/port du composant instancié (les mappages décrits dans l'étiquette du composant instancié instance_label
). La portée à la fois pour le générique et le port devrait être, pour les raisons décrites précédemment :
instance label:top_entity.top_arch.entity_name.arch_name.instance_label
.
Il n'y aura pas de cas de balises anonymes instance_label
, car une étiquette doit être spécifiée pour chaque composant instancié.
Maintenant, voici quelques résultats après avoir effectué quelques tests :
* `process` tag is missing a scope. It should be: `architecture:entity_name.arch_name` * `variable` tag scope is currently: `process:proc_name` It should be: `process:entity_name.arch_name.proc_name`
Merci d'avoir essayé.
Je mettrai à jour #2695 après avoir essayé de corriger les éléments ci-dessus.
Ensuite, je fusionnerai #2695. Les pull requests contiennent tellement de commits.
Je vais travailler sur le reste des éléments que vous avez mis dans les commentaires après avoir fusionné #2695.
Je pensais à une autre chose critique. Reprenons cet extrait :
instance_label : entity library_name.entity_name(arch_name)
generic map(
GEN => GEN
)
port map(
PORT => PORT
);
Comme je l'ai observé dans mon post précédent, une balise pour instance_label
(nommée par exemple instance label ) devrait également être ajoutée, et j'ai proposé cette portée :
architecture:top_entity.top_arch.entity_name.arch_name
A terme, ce périmètre pourrait être réduit aux éléments suivants :
architecture:top_entity.top_arch
car les noms d' étiquettes d'instance sont uniques au sein d'une architecture. Mais l'option 1 , bien que quelque peu redondante, donnerait plus d'informations sur la balise d' étiquette d'instance , et pourrait donc être hautement préférable lors de la navigation des balises.
Mais la chose manquante critique, que j'ai oubliée, serait une balise pour le composant instancié lui-même ( entity_name
dans l'extrait ci-dessus). Cette balise pourrait être appelée instance de composant (étant son étiquette, étiquette d'instance ) et sa portée devrait alors être :
instance label:top_entity.top_arch.instance_label
Ce serait vital pour la navigation des balises. Par exemple, à partir d'un tag donné d'une entité, il sera alors possible de retrouver :
instance_label
.Une dernière observation, pour le balisage instance label generic/port
dont j'ai parlé dans mon post précédent. Comme portée, j'ai suggéré:
instance label:top_entity.top_arch.entity_name.arch_name.instance_label
mais cela pourrait être réduit à:
instance label:top_entity.top_arch.instance_label
encore une fois parce que les noms d' étiquettes d'instance sont uniques au sein d'une architecture.
mais la variante 1 est la plus recommandée car elle fournit des informations sur le couple entité et architecture lié au label d'instance.
@pidgeon777 , pensez-vous que nous pouvons fusionner #2695 ?
Je pense avoir résolu les problèmes suivants que vous avez signalés :
La balise process
n'a pas de portée. Ça devrait être:
architecture:entity_name.arch_name
La portée de la balise variable
est actuellement :
process:proc_name
Ça devrait être:
process:entity_name.arch_name.proc_name
@pidgeon777 , pensez-vous que nous pouvons fusionner #2695 ?
Je fais plus de tests pour https://github.com/universal-ctags/ctags/pull/2695 avant confirmation.
Je pense avoir résolu les éléments suivants que vous avez soulignés
Sont-ils inclus dans le https://github.com/universal-ctags/ctags/pull/2695 susmentionné ?
Sont-ils inclus dans le # 2695 susmentionné ?
Oui. https://github.com/universal-ctags/ctags/pull/2695/commits/cf9a5d2eebc884e992aeaa2edcc4627452d12c78 dans # 2695 est le changement pour les éléments.
Sont-ils inclus dans le # 2695 susmentionné ?
Oui. cf9a5d2 dans #2695 est le changement pour les éléments.
Les nouveaux ajouts dans https://github.com/universal-ctags/ctags/pull/2695 semblent être OK.
J'ai fusionné #2695. Merci pour le test.
@pidgeon777 , puis-je vous demander de résumer les autres éléments ? (l'ouverture d'un nouveau problème est un moyen alternatif.)
J'ai une demande. Lors de l'affichage d'un exemple de champ d'étendue, pourriez-vous ajouter le préfixe scope:
?
ctags peut émettre le préfixe lorsque vous donnez l'option --fields=+Z
.
$ cat f.h
struct point {
int x, y;
};
$ ./ctags -o - --fields=+Z f.h
point f.h /^struct point {$/;" s
x f.h /^ int x, y;$/;" m scope:struct:point typeref:typename:int
y f.h /^ int x, y;$/;" m scope:struct:point typeref:typename:int
Je voudrais que vous montriez les exemples dans les formulaires ci-dessus.