디지털 회로 설계를 공부하다 보면 unate / non-unate cell이 나오는데, 처음엔 “이게 뭐가 중요하지?” 싶다.
Unateness는 STA가 ‘단순 규칙으로 안전하게 최악의 경우를 단조롭게 정의 할 수 있는가’를 가르는 기준이다. 성능(runtime) 과 Pessimism을 줄이기 위함이다.
1) Unate / Non-unate: 한 줄 정의
- Unate cell: 특정 입력 핀 기준으로 입력 전이(rise/fall)가 출력 전이 방향을 단조롭게 결정 가능하다.
→ STA가 전이 방향을 고정하고 worst를 계산할 수 있다. 그러므로, 계산해야 할 경우의 수가 작다.

- 예를들어 AND Gate는 input pin 전이가 발생하면, output pin은 같은 방향으로 시그널 전이가 발생하거나, 이전 시그널을 유지한다.
- 이것을 Positive unate 라고 합니다.
- 반대로, input pin 의 반대 방향으로 output pin 시그널이 움직이면, 이를 Negative unate 라고합니다.
- Non-unate cell: 상황(다른 입력 상태/조건)에 따라 출력 전이 방향이 달라질 수 있다.
→ STA가 전이 방향을 고정할 수 없어서 Case split 필요하다.

즉, “non-unate는 타이밍 arc/전이 case를 분기해서 여러가지 경우의 수로 열거해서 본다. (부분 열거).”
2) Liberty의 timing_sense가 왜 중요한가
라이브러리(.lib)에는 보통 다음이 들어간다.
timing_sense: positive_unatetiming_sense: negative_unatetiming_sense: non_unate
이 한 줄이 하는 일은 간단하다.
PrimeTime 같은 STA 엔진이 어떤 timing arc를 ‘Monotonicity 기반으로 pruning 가능한지’ 결정한다.
Unate면:
- 해당 핀의 전이 방향이 고정되므로
- 후보 arc/케이스가 줄어든다.
Non-unate면:
- 가능한 arc/케이스를 더 넓게 본다.
- runtime↑ + pessimism↑ 가능성이 커진다.
3) 왜 “퍼포먼스 때문만”은 아닌가
맞다, non-unate는 분기 때문에 STA가 느려질 수 있다.
하지만 더 중요한 건 이거다:
Unate는 STA가 단조 가정을 통해 ‘안전한 upper bound’(최악을 안 놓치는 보수성)를 만들기 쉽다.
Non-unate는 그 가정이 깨져서, 엔진이 더 보수적으로(=pessimistic) 갈 수밖에 없다.
즉, unate/non-unate는 “엔진 최적화 트릭”이 아니라 STA 수학 모델의 가정 조건이다.
4) non-unate cell이 Timing 계산에서 골칫덩이인 이유
(1) XOR: 대표적인 non-unate
XOR는 입력 변화가 출력에 미치는 “방향”이 고정되지 않는다.
그래서 STA는 rise/fall 조합을 더 많이 분기해서 봐야 한다.
결과:
- timing arc/case 증가
- pruning 어려움
- 실제 회로의 동작보다 더 pessimism 한 동작이 STA에서 검증 될 수도 있다.