functional coverage: 두 개의 100% 뒤에 비어 있는 조합
깊이 4인 FIFO의 테스트 보고서에서 모든 점유율을 보았고 모든 요청 종류를 보았다고 나온다. 두 지표는 각각 100%다. 그런데 가득 찬 FIFO에서 push와 pop을 동시에 요청한 적은 없을 수 있다. 개별 항목을 한 번씩 본 사실과 그 항목들이 함께 발생한 사실은 같지 않다.
functional coverage는 명세에서 중요하다고 정한 상황이 실제로 관찰되었는지 기록한다. 어떤 상황을 세도록 정의했는지가 백분율보다 먼저다.
분모는 회로가 아니라 검증 계획에서 온다
UVM User’s Guide는 명시적으로 정한 기능 목표를 세는 coverage와 코드의 실행을 측정하는 지표를 구분한다. 기능 목표는 높은 수준의 동시 발생을 표현할 수 있지만, 적어 놓지 않은 요구는 그 보고서에 나타나지 않는다. 코드 지표 역시 명세 요구를 모두 대신하지 못한다. Accellera UVM User’s Guide 1.1, §4.11 Implementing Functional Coverage
FIFO 예에서 edge 직전의 점유율은 0~4다. 요청은 idle, push만, pop만, push와 pop 동시의 네 종류다. 이 가상 인터페이스는 빈 상태의 pop 요청이나 가득 찬 상태의 push 요청도 허용하되, 수락 여부와 응답을 명세대로 처리한다고 정한다. 요청 자체를 금지하는 인터페이스라면 이후의 분모가 달라진다.
점유율에 다섯 bin, 요청 종류에 네 bin을 만들자. 다음의 관측 기록은 서로 다른 시점에서 모았으며 중간의 상태 이동 과정은 표에서 생략했다.
| 관측한 점유율 | 그때의 요청 |
|---|---|
| 0 | idle |
| 1 | push만 |
| 2 | pop만 |
| 3 | 동시 요청 |
| 4 | idle |
점유율의 다섯 bin과 요청의 네 bin을 모두 보았으므로 각각의 지표는 100%다. 그러나 점유율 × 요청 종류의 cross를 만들면 가능한 조합은 5×4=20개이고, 표에서 본 조합은 5개다. cross coverage는 25%다.
가득 찬 상태의 동시 요청은 이 다섯 개에 없다. 두 개의 100%를 평균 내거나 곁에 표시해도 그 빠진 조합이 채워지지 않는다. 요구사항이 ‘full 상태에서 동시에 요청할 때도 정해진 수락 정책을 지킨다’라면, 그 조합을 별도 목표로 정의해야 한다.
많이 실행한 코드가 특정 동작을 보장하지 않는다
코드 coverage는 다른 질문에 답한다. 어떤 줄이나 분기가 실행되었는지, 어떤 신호가 바뀌었는지는 구현의 실행 흔적이다. 예를 들어 full 처리 분기는 push만 요청했을 때 실행되고, 동시 요청 처리 분기는 점유율 3일 때 실행될 수 있다. 두 분기를 각각 지나도 full과 동시 요청이 만나는 경계는 보지 않았을 수 있다.
Verilator의 공식 문서도 line coverage를 코드 제어 흐름 지점의 실행으로, toggle coverage를 신호 bit의 변화로 설명한다. 별도의 기능 coverage와 property coverage도 제공한다. 도구가 어떤 항목을 지원하는지와 그 항목이 어떤 요구를 표현하는지는 구분해야 한다. Verilator, Coverage Analysis
또한 coverage는 보통 ‘발생했다’를 센다. 해당 입력에서 출력이 옳았는지까지 자동으로 증명하지 않는다. full·동시 요청 bin을 채운 순간 FIFO가 잘못된 데이터를 내보내도, 그 오류를 잡을 별도 checker가 없으면 상황은 관측된 것으로 남을 수 있다. coverage를 수집하는 것과 정답을 검사하는 일을 함께 설계해야 한다.
불가능한 조합은 근거를 가지고 제외한다
cross를 늘리면 빈 bin이 많이 생긴다. 일부는 자극이 부족해서 비었고, 일부는 명세상 발생할 수 없어서 비었다. 이를 같은 방식으로 처리하면 보고서가 판단을 흐린다.
예를 들어 별도의 프로토콜이 full 상태의 push 요청을 아예 불법으로 정했다면 그 요청 조합은 일반적인 성공 목표에서 제외할 수 있다. 그러나 현재 예의 인터페이스처럼 요청은 허용하고 수락을 제한하는 계약이라면 full·push가 비었다고 ‘불가능’으로 제외할 근거가 없다. RTL에서 지금 관측되지 않는다는 사실만으로 명세상 불가능하다고 판단해서도 안 된다.
불법 상황을 표현할 때도 coverage만 믿지는 않는다. lowRISC 가이드는 illegal_bins를 유일한 checker로 사용하지 말고, coverage 수집 여부와 독립적으로 관련 검사를 두도록 권한다. 불법 bin의 처리를 모든 시뮬레이터에서 동일한 테스트 실패로 가정하지 않기 위해서다. lowRISC DV Coding Style, Functional Coverage
샘플링 기준도 목표와 맞아야 한다. 수락된 전송의 종류를 세는 목표라면 실제 handshake를 기준으로 하고, 거절된 요청에 대한 반응을 확인하려면 그 요청 자체를 관측한다. 점유율은 해당 edge에서 처리하기 전인지 후인지 명시한다. 정의가 섞이면 같은 bin 이름에 서로 다른 사건이 쌓인다.
functional coverage의 100%는 정의한 bin을 채웠다는 의미다. 정의에서 빠진 요구나 잘못된 결과까지 해결했다는 뜻은 아니다. 점유율과 요청을 각각 본 데서 멈추지 않고 중요한 조합을 목표로 만들고, 그 순간의 결과를 검사해야 한다. 보고서의 숫자를 검증 완료로 읽기 전에 그 숫자의 분모와 관측 기준을 읽어야 한다.