ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Verilog] Latch를 피하는 방법 (combinational logic 기술 시 유의할 점)
    Tech/Verilog 2013. 2. 28. 15:03

     Verilog를 이용해서 디지털 회로를 디자인할 때, always@ 기술 시 의도하지 않은 Latch 생성에 유의해야 한다. 처음 Verilog를 이용해서 만들 때에 매번 synthesis report를 확인하면서 latch가 생기지 않았나 검색하던 기억이 난다.

     의도치 않은 Latch는 always 구문을 이용해서 combinational logic을 기술할 때 가장 많이 발생한다. Verilog에서는 always 로 작성된 구문은 합성 시에, 모든 입력 조건에 대해 동작하도록 closed logic을 자동으로 형성하는데, **기술되지 않은 조건에 해당할 때에는 이전 값을 유지하도록 만든다. 따라서, 입력값에 의해서만 바뀌는 combinational logic을 만들었더라도 모든 조건에 대한 값이 지시되어 있지 않으면 (혹은 자기 자신 값을 대입하도록 설계하였다면) 이전 값을 유지하기위해서 Latch가 생성되고 만다.

     예를 들어 아래의 코드가 있다고 하자.

    module A (
     input wire In0,
     input wire Enable,
     output reg Out0,
     output reg Out1
    );
    
     always @(*)
     begin
      Out1 = 0;
      if (Enable)
      begin
        Out0 = In0;
        Out1 = In0;
      end
     end
    endmodule
    

     위 모듈을 보면, Out1은 Enable이 1이면 In0의 값을, Enable이 0이면 0을 출력하도록 되어 있다.

     하지만 Out0의 경우를 보면, Enable == 1 일 때에는 값이 설정되어 있지만, 반대의 경우에는 어떠한 값도 설정되어있지 않다. 이 경우, design compiler에서는 Out0의 이전 값을 유지하려고 할 것이다. 하지만 Out0과 Out1은 edge-sensitive하게 동작하는 sequential logic이 아니다. (always @(posedge clk)등으로 선언되어 있지 않음.) 따라서 Latch를 생성해서 이전값을 유지할 수 밖에 없는데, 결과적으로는 아래와 같다.

     이러한 래치 생성을 막으려면, 모든 경우에 대해서 값을 가지도록 기술하면 된다.

     module A_rev (
     input wire In0,
     input wire Enable,
     output reg Out0,
     output reg Out1
    );
    
    always @(*)
     begin
     Out0 = 1;
     Out1 = 0;
     if (Enable)
     begin
     Out0 = In0;
     Out1 = In0;
     end
     end
    endmodule
    

    A_rev 모듈은 래치가 생성되지 않는다. Out0, Out1의 모든 경우에 대해서 값이 결정되어 있기 때문이다.

    이렇듯 Verilog에서 always @() 등을 이용한 combinational logic을 기술할 때에는 꼭 모든 조건들에 대해 기술되어있는지 확인하자!

    댓글

Copyright 2022 JY