Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Industrial programming >> Verilog

Portée de référence hiérarchique Verilog

La plupart des langages de programmation ont une caractéristique appelée portée qui définit la visibilité de certaines sections de code aux variables et aux méthodes. La portée définit un espace de noms pour éviter les collisions entre différents noms d'objets dans le même espace de noms.

Verilog définit une nouvelle portée pour les modules, les fonctions, les tâches, les blocs nommés et les blocs de génération.

  
  
module tb;
	reg signal;
	
	// Another variable cannot be declared with
	// an already existing name in the same scope
	reg signal;
	
	// However, the name 'signal' can be reused inside
	// a task because it belongs to a different scope.
	task display();
		reg signal = 1;
		$display("signal = %0b", signal);
	endtask
	
endmodule

  

Un identifiant, comme un nom de signal, peut être utilisé pour déclarer un seul type d'élément dans une portée donnée. Cela signifie que deux variables de types de données différents ou identiques ne peuvent pas avoir le même nom, ou une tâche et une variable du même nom, ou même une instance net et gate avec le même nom dans la même portée.

Chaque identifiant dans Verilog a un nom de chemin hiérarchique unique, où chaque instance de module, tâche, fonction ou nommé begin end ou fork join bloc définit un nouveau niveau ou une nouvelle portée.

Exemple de référence hiérarchique

  
  
module tb;

	// Create two instances of different modules
	A uA();
	B uB();
	
	// Create a named block that declares a signal and 
	// prints the value at 10ns from simulation start
	initial begin : TB_INITIAL
		reg signal;
      #10 $display("signal=%0d", signal);      
	end
  
  	// We'll try to access other scopes using hierarchical
  	// references from this initial block
  	initial begin
  	  TB_INITIAL.signal = 0;
      uA.display();
      
      uB.B_INITIAL.B_INITIAL_BLOCK1.b_signal_1 = 1;
      uB.B_INITIAL.B_INITIAL_BLOCK2.b_signal_2 = 0;
    end
endmodule

  
  
  
module A;
	task display();
		$display("Hello, this is A");
	endtask
endmodule

module B;
	initial begin : B_INITIAL
		#50;
		begin : B_INITIAL_BLOCK1
			reg b_signal_1;
          #10 $display("signal_1=%0d", b_signal_1);
          
          
		end
		
		#50;
		begin : B_INITIAL_BLOCK2
			reg b_signal_2;
          #10 $display("signal_2=%0d", b_signal_2);
		end
	end
endmodule

  
Journal de simulation
xcelium> run
Hello, this is A
TB signal=0
signal_1=1
signal_2=0
xmsim: *W,RNQUIE: Simulation is complete.

Référencement du nom vers le haut

Un module de niveau inférieur peut référencer des éléments dans un module au-dessus de lui dans la hiérarchie. Par exemple, le signal dans le bloc TB_INITIAL serait visible depuis la tâche d'affichage dans A.

  
  
module A;	
	task display();
		$display("Hello, this is A");
      
        // Upward referencing, TB_INITIAL is visible in this module
      	#5 TB_INITIAL.signal = 1;
	endtask
endmodule

  

Notez que le signal TB est maintenant 1 au lieu de 0, en raison du changement de référencement vers le haut apporté au signal par le module A.

Journal de simulation
xcelium> run
Hello, this is A
TB signal=1
signal_1=1
signal_2=0
xmsim: *W,RNQUIE: Simulation is complete.

Voici un autre exemple avec plusieurs modules imbriqués et le nœud feuille peut accéder directement aux membres des nœuds ci-dessus via une référence hiérarchique ascendante.

  
  
module tb;
  A a();
  
  function display();
    $display("Hello, this is TB");
  endfunction
endmodule

module A;
  B b();
  function display();
    $display("Hello, this is A");
  endfunction
endmodule

module B;
  C c();  
  function display();
    $display("Hello, this is B");
  endfunction
endmodule

module C;
  D d();
  
  function display();
    $display("Hello, this is C");
  endfunction
endmodule

module D;
  initial begin
    a.display();  // or A.display()
    b.display();  // or B.display()
    c.display();  // or C.display()
    
    a.b.c.display();
  end
endmodule

  
Journal de simulation
xcelium> run
Hello, this is A
Hello, this is B
Hello, this is C
Hello, this is C
xmsim: *W,RNQUIE: Simulation is complete.

Lorsque le compilateur trouve b.display(),

  1. Il regarde dans la portée actuelle du module D pour voir si b est défini. S'il n'existe pas, il recherche le nom dans la portée englobante et se déplace vers le haut jusqu'à ce que la portée du module soit atteinte. Si le nom n'est toujours pas trouvé, il passe à l'étape suivante.
  2. Il recherche dans la portée la plus externe du module parent et s'il n'est pas trouvé, il continue de remonter dans la hiérarchie.

Verilog

  1. Tutoriel Verilog
  2. Concaténation Verilog
  3. Verilog - Dans une coquille de noix
  4. Affectations Verilog
  5. Verilog bloquant et non bloquant
  6. Fonctions Verilog
  7. Tâche Verilog
  8. Portée de référence hiérarchique Verilog
  9. Générateur d'horloge Verilog