Verilog : case문 사용 시, parallel_case 선언 이해하기

case와 if는 연속된 조건문을 비교한다는 관점에서 보면 그 기능이 동일하다. 특히, Verilog에서는 C/C++의 switch-case문과 달리 break 등을 따로 기술하지 않으므로 기능이 완전히 동일하다고 볼 수 있다. 예를 들어보자. 아래의 두 module은 기능적으로 동일하다.

module interrupt_decode4 (output reg somthing, input [3:0] irq );
always @* begin
  if (irq[0]) do interrupt 0
  else if (irq[1]) do interrupt 1
  else if (irq[2]) do interrupt 2
  else if (irq[3]) do interrupt 3
  end
endmodule
module interrupt_decode4 (output reg somthing, input [3:0] irq );
always @* begin
case (irq)
  4'b???1: do interrupt 0
  4'b??1?: do interrupt 1
  4'b?1??: do interrupt 2
  4'b1???: do interrupt 3
endcase
end
endmodule

위 모듈들을 합성하게되면 어떻게 될까? if ... else if ... else 로 이어지는 비교문에서 else if 문은 이전 logic에 대한 비교가 사전에 가정된다. 예를 들어 위 예제에서는, else if (irq[1]) 문이 실행되는 조건은 ~irq[0] & irq[1] 이어야 한다는 것이 자동적으로 내포된다. 즉, else if ... else if ...로 이어지면서 계속해서 이전 조건에 대한 부정 logic이 추가되는 셈이다.

그런데, if문으로 구성하다보면 아래와 같이 독립적으로 비교하도록 작성할 수가 있다.

module interrupt_decode4 (output reg somthing, input [3:0] irq );
always @* begin
  if (irq[0]) do interrupt 0
  if (irq[1]) do interrupt 1
  if (irq[2]) do interrupt 2
  if (irq[3]) do interrupt 3
end
endmodule

위에서 간단히 else만 제거한 문장인데, 그렇다면 이렇게 설계된 module과 완벽히 일치하는 (합성을 해도 그 결과가 동일한!) case문을 만들려면 어떻게 해야할까? 앞서 소개한 case 예제는 if ... else if ... else 와 동일하다는 것을 이미 확인했다.

이런 상황에서는 case문에 parallel_case progma를 붙여주면 된다. Synopsys Design Compiler에서는 // synopsys 는 progma로 사용되므로 아래와 같이 case 문 옆에 // synopsys parallel_case로 선언해주면 된다.

module interrupt_decode4 (output reg somthing, input [3:0] irq );
always @* begin
casez (irq) // synopsys parallel_case
  4'b???1: do interrupt 0
  4'b??1?: do interrupt 1
  4'b?1??: do interrupt 2
  4'b1???: do interrupt 3
endcase
end
endmodule

이 경우, synthesis implementation에서는 irq각 bit에 대한 비교만으로 이루어져 있으며, 앞서 설명한 것과 같이 irq[1]을 비교할 때에는 irq[0]에 대한 비교가 포함되어 있지 않다. 즉, case에 선언된 모든 문장이 parallel하게 비교된다. 주의할 점은 case 문에서 비교되는 각 logic이 mutually exclusive 해야한다는 점이다.

2번째 case 경우를 보자. parallel_case가 선언되지 않았다면 이전의 비교문장인 (4’b???1) 을 비교한 후에 진행되므로 자동적으로 ~irq[0] && irq[1] 이 가정되지만, parallel_case가 선언된다면 ~irq[0] 를 가정하지 않으므로, irq[0]과 irq[1] 이 모두 1인 경우 어떠한 동작을 할지는 아무도 모른다. (synthesis 하기에 따라 다르다.) 따라서, parallel_case는 반드시 mutually exclusive한 상황이 보장될 때만 사용해야 한다.

  • 게스트 썸네일
    2012.06.28 09:51

    비밀댓글입니다

  • 게스트 썸네일
    수환
    2017.10.22 13:37 신고

    case 문 사용할때 조건을 나열하고 마지막에 endcase 전에 default: 라고 하는것도 있던데 그것을 안써도 무방한가요? 케이스 문 의 조건 변수가 가질수 있는 모든 경우를 나열했다면 default 를 굳이 사용하지 않아도 문제가 안되나요?

    • 게스트 썸네일
      2017.10.28 02:13 신고

      네 무관합니다. 다만 린트 툴에 따라 default: 를 무조건 강요하는 경우도 있습니다.