-
Verilog : case문 사용 시, parallel_case 선언 이해하기Tech/Verilog 2012. 5. 21. 17:31
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한 상황이 보장될 때만 사용해야 한다.