산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> verilog

Verilog 계층적 참조 범위 마스터하기: 모듈과 블록 간 이름 충돌 방지

대부분의 프로그래밍 언어에는 범위(scope)라는 특성이 있어, 코드의 특정 섹션이 변수와 메서드에 대해 가시성을 정의합니다. 범위는 같은 네임스페이스 내 다른 객체 이름 간의 충돌을 피하기 위한 네임스페이스를 정의합니다.

Verilog는 모듈, 함수, 태스크, 명명된 블록, generate 블록에 대해 새로운 범위를 정의합니다.

module tb;
  reg signal;
  // 같은 범위에서 이미 존재하는 이름으로 다른 변수 선언 불가
  reg signal; // 에러
  // 하지만 'signal' 이름은 태스크 안에서 재사용 가능 (다른 범위이므로)
  task display();
    reg signal = 1;
    $display("signal = %0b", signal);
  endtask
endmodule

식별자(신호 이름 등)는 주어진 범위에서 한 종류의 항목만 선언하는 데 사용될 수 있습니다. 즉, 같은 범위에서 다른 데이터 타입의 두 변수가 같은 이름을 가질 수 없으며, 태스크와 변수가 같은 이름을 가질 수 없고, 넷과 게이트 인스턴스도 같은 이름을 가질 수 없습니다.

Verilog의 모든 식별자는 고유한 계층적 경로 이름을 가지며, 각 모듈 인스턴스, 태스크, 함수, 명명된 begin end 또는 fork join 블록이 새로운 레벨 또는 범위를 정의합니다.

계층적 참조 예제

module tb;
  // 서로 다른 두 모듈의 인스턴스 생성
  A uA();
  B uB();
  // 신호를 선언하고 시뮬레이션 시작 10ns에 값 출력하는 명명된 블록
  initial begin : TB_INITIAL
    reg signal;
    #10 $display("signal=%0d", signal);
  end
  // 이 initial 블록에서 계층적 참조를 사용하여 다른 범위에 접근 시도
  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

시뮬레이션 로그

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

상향 이름 참조 (Upwards Name Referencing)

하위 레벨 모듈은 계층 구조에서 그 위의 모듈에 있는 항목을 참조할 수 있습니다. 예를 들어, TB_INITIAL 블록의 signal이 모듈 A의 display 태스크에서 보일 수 있습니다.

module A;
  task display();
    $display("Hello, this is A");
    // 상향 참조, TB_INITIAL이 이 모듈에서 보임
    #5 TB_INITIAL.signal = 1;
  endtask
endmodule

모듈 A에 의한 상향 참조 변경으로 TB signal이 0 대신 1이 됨을 알 수 있습니다.

시뮬레이션 로그

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

여러 중첩 모듈이 있는 또 다른 예제로, 리프 노드가 상향 계층적 참조를 통해 상위 노드의 멤버에 직접 접근할 수 있습니다.

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(); // 또는 A.display()
    b.display(); // 또는 B.display()
    c.display(); // 또는 C.display()
    a.b.c.display();
  end
endmodule

시뮬레이션 로그

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

컴파일러가 b.display()를 찾으면,

  1. 현재 범위(모듈 D 내부)에서 b가 정의되어 있는지 확인. 없으면 둘러싼 범위에서 이름을 찾고 모듈 범위까지 위로 이동. 여전히 없으면 다음 단계로.
  2. 부모 모듈의 최외곽 범위에서 찾고, 없으면 계층을 계속 위로 올라감.

verilog

  1. 버릴로그(Verilog) 입문: 디지털 회로 설계를 위한 하드웨어 기술 언어
  2. Verilog 결합(Concatenation) & 복제(Replication) 연산자 실전 가이드
  3. Verilog 핵심 요약: 모듈, 데이터 타입, 할당문 3분 만에 익히기
  4. Verilog 할당문 이해: 유형, 문법, 모범 사례
  5. Verilog 차단 vs 비차단 할당: 핵심 차이점 완벽 이해
  6. Verilog 함수 마스터하기: 효율적인 RTL 설계를 위한 활용법
  7. Verilog 태스크 이해: 함수와의 차이점, 문법, 활용법
  8. Verilog 계층적 참조 범위 마스터하기: 모듈과 블록 간 이름 충돌 방지
  9. Verilog 클럭 생성기: 설계 및 구현 가이드
  10. Verilog 디스플레이 태스크 마스터하기: 효율적인 디버깅 및 로깅