이번에는 코드를 작성 시 많이 사용되는 조건문인 if~else, case 문에 대해서 정리해보겠습니다.

if~else나 case는 c언어를 공부했다면 이미 알고 있을테고 크게 다른 점이 없기 때문에 이번 포스트는 간단하게만 정리하고 넘어가도록 할게요.


- if ~ else 문

if(condition 1)
  code to execute;
else if(condition 2)
  code to execute;
...
else if(condition n)
  code to execute;
else
  code to execute;

if ~ else문은 잘 알고있다시피 조건이 맞다면 그 문장을 실행하고 아니라면 else if로 가서 다른 조건을 검사하거나

else로 가서 문장을 실행하게 됩니다.

 

그런데 Verilog에서 이런 if~else문을 사용할 때 주의해야할 것이 세가지가 있는데요.

첫번째로는 어떤 condition을 만족했을 때, 동작해야할 문장이 여러개가 존재한다면 아래와 같이 begin ~ end로 묶어줘야 한다는 것입니다.

if, else if, else 하위에 하나의 실행문장만 넣을거면 굳이 넣어주지 않아도 되지만 실행문장이 여러개라면 begin ~ end를 넣어야 함을 기억하고 넘어갑시다.

if(condition 1) begin
  code to execute 1;
  code to execute 2;
end
else if(condition 2) begin
  code to execute 3;
  code to execute 4;
end
else begin
  code to execute 5;
  code to execute 6;
end

 

두번째로는 if ~ else if로 작성을 하고 마지막에 else를 꼭 넣어주어야 한다는 것입니다.

코드를 작성하다보면 아래와 같이 고려했던 Condition이 모두 Cover됐다고 판단해 else 없이 else if로 끝내는 경우가 있습니다.

물론 이렇게 한다고 해서 컴파일 오류나 동작에 이상이 없을 수 있지만 원치 않는 latch가 발생할 수 있기 때문에
만에 하나를 방지하기 위해 if ~ else 문을 사용할 때 마지막에 else문을 넣는 것이 권장된다고 합니다.

if(condition 1)
  code to execute;
else if(condition 2)
  code to execute;
else if (condition 3)
  code to execute;

 

 

마지막으로는 if ~ else if ~ else를 너무 남발하면 안된다는 점입니다.

Verilog는 하드웨어 설계 언어이기에 이를 더욱 명심해야하는데요.

if ~ else 구문은 (조건1)이 맞으면 (a)를 실행하고 (조건1)이 아니라면 (b)를 실행하는 구문입니다.

즉, 조건1을 검사해서 출력을 a, b 중에서 선택을 하는 코드라고 할 수 있는데 이는 회로적으로 봤을 때 2X1 Mux가 됩니다.

if~else 구문의 HW

그러면 만약 if ~ else if ~ else if ~ else if ~ ... ~ else 문으로 엄청 길게 작성한다면 어떻게 될까요?

위에서 봤던 2X1 Mux가 줄줄이로 생겨서 회로의 Size가 매우 커지고 Hardware적으로 좋다고 할 수 없겠죠.

따라서 꼭 필요한 경우는 어쩔 수 없겠지만 꼭 필요하지 않다면 if~else if~else를 과도하게 길게 가져가는 것은 좋지 않기에 이도 고려하면서 코드를 작성해야 합니다.


- Case 문

case (variable)
  value 1 : code to execute;
  value 2 : code to execute;
  ...
  value n : code to execute;
  default : code to execute;
endcase

case 문은 variable의 값을 병렬적으로 고려해서 해당하는 실행문을 실행시켜 주는 구문으로 위와 같이 작성하게 됩니다.

if~else에서 살펴봤던 흐름대로 한번 살펴볼까요?

 

if~else 문에서 한 condition이 만족했을 때 여러개의 실행문을 담으려면 begin ~ end를 사용해야 한다고 했죠.

if~else 문에서 설명한 것처럼 case문에서도 value당 여러개의 실행문을 담을 것이면 begin ~ end로 묶어주어야 합니다.

case (variable)
  value 1 : begin
  code to execute 1;
  code to execute 2;
  end
  value 2 : begin
  code to execute 3;
  code to execute 4;
  end
  default : begin
  code to execute 4;
  code to execute 5;
  end
endcase

 

그럼 case문 같은 경우에는 Hardware적으로 어떻게 구현될까요?

case는 어떤 variable을 병렬적으로 고려해서 어떤 실행문이 실행될 지를 선택하는 것이죠.

따라서 2X1 Mux인 if~else와 달리 case는 nX1 Mux로 구현되게 됩니다. 

 

예를 들어 case문으로 value 8개에 해당하는 실행문을 만들어 놨다면 Hardware적으로는 8X1 Mux가 아래처럼 나오게 될 겁니다.

만약 조건들이 우선순위 없이 병렬적으로 처리되도 되는 코드를 작성한다면 if~else를 8개 작성하는 것보다 위와 같이 case를 사용하는 것이 Hardware적으로 더 좋은 설계라고 할 수 있겠습니다.

 

또 하나 추가적으로 if~else에서 latch방지를 위해 else 사용을 권장했듯이
case문에서도 latch방지를 위해 default 사용을 권장한다고 합니다. 

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기