<개요>
Verilog RTL을 설계하고 검증하다 보면 어느시점까지 검증을 하고 마쳐야 하는지 궁금해지는 경우가 있다. 왠만한 테스트는 다 했지만 이 시점에서 검증을 마치자니 조금 불안한 경우가 많다.

이러한 궁금증을 해결하기 위해 자신이 수행하고자 하는 테스트 벡터가 설계한 모듈의 어느 정도나 검증을 할 수 있는지 나타내는 지표가 있다. 이 지표가 "Coverage"이다.

이러한 coverage에 대한 이슈를 위해 존재하는 tool이 coverage analysis tool이다.
Coverage analysis tool로는 여러가지가 있다.
그 중 가장 많이 쓰이는 tool로
Mentorgraphics사의 ModelSim
Cadence사의 ICC(ncverilog simulator와 연동해서 쓸 수 있다.)
등이 있다.

여기에서는 Cadence사의 ICC(Cadence Incisive Comprehensive Coverage)를 통해 coverage에 대한 이슈에 대해 알아보도록 한다.


Coverage는 크게 두 가지 type
1. Code Coverage: 말 그대로 설계한 코드를 얼마나 빼먹지 않고 잘 테스트 하는지에 대한 지표이다.
2. Functional Coverage: 이것은 유저가 중요하다고 생각하는 동작에 functional coverage point를 지정하고 이 point가 얼마나 수행되는지에 대한 지표이다.
으로 나누어진다.

ICC에서는 이 두 가지 type을 아래와 같이 더 세부적으로 나누어 정의하였다.
1. Code Coverage
   a. Code coverage

      i. Block coverage: Simulation이 수행하는 중에 코드의 각각의 line이 수행되었는지에 대한 지표
      ii. Branch coverage: Simulation이 수행되는 중에 각각의 branch가 얼마나 수행되었는지에 대한 지표 (block coverage보다 더 자세한 지표)
      iii. Expression coverage: Conditional statement에 어느 부분에 의해서 어떤 condition이 수행되었는지에 대한 지표
      iv. Toogle coverage: 각각의 signal과 port가 어떻게 변했는지에 대한 지표
   b. FSM coverage: FSM에서 어떤 state에 얼마나 있었는지 그리고 어떠한 state로 바뀌었는지에 대한 지표

2. Functional Coverage
   a. Control-oriented functional coverage
: Assertion-based 검증, 유저가 지정한 functional coverage point에 대한 내용에 대한 지표
   b. Data-oriented functional coverage: 어떠한 data가 assign되었는지를 tracking한다.

========================================================================================
<Coverage 데이터 수집 방법>
그럼 ICC를 사용하는 방법을 알아보도록 한다.

<ncverilog를 수행할 경우>
이 경우 ncvlog, ncelab, ncsim이 차례로 수행되게 된다.
ncverilog를 통해 coverage에 대한 데이터를 생성하고 싶은 경우에

ncverilog [-coverage <coverage_types> | -covfile <converage_configuration_file>] [-covdut <DUT_module>] [-covoverwrite] [-covtest <test>] [other options]

이와 같이 실행하면 ncverilog를 수행하는 도중 coverage에 대한 데이터를 생성하게 된다.

<ncvlog, ncelab, ncsim을 차례로 수행하는 경우>

실제로 coverage에 대한 데이터를 생성하는 step은 ncelab이다.
그러므로 ncvlog와 ncsim은 평소와 같이 사용하고
ncelab step에서만

ncelab [-coverage <coverage_types> | -covfile <coverage_configuration_file>] [-covdut <DUT_module>] [-covoverwrite] [-covtest <test>] [other options]

이와 같이 실행하면 ncelab을 하면서 coverage에 대한 데이터를 생성할 것을 명시하고
ncsim을 하면서 coverage에 대한 데이터를 생성하게 된다.

========================================================================================
<option에 대한 설명>
그럼 각각의 option에 대해서 알아보도록 하자
<-coverage <coverage_types>>
coverage_types
B (Block) - Block coverage를 켠다.
E (Expr) - Expression coverage를 켠다.
F (FSM) - FSM coverage를 켠다.
T (Toggle) - Toggle coverage를 켠다.
U (Functional) - Functional coverage를 켠다.
A (All) - 모든 coverage type을 켠다.

<-covfile <coverage_configuration_file>>
이 option을 사용하면 coverage configuration file을 넘겨주고 coverage configuration file에 명시되어 있는 command를 실행하게 되는데
그 중 많이 쓰이게 되는 command는 deselect_coverage, set_explicit_block_scoring이다.

deselect_coverage [-<coverage_type>] [[-module] <list> | -instance <list>]
예)
deselect_coverage -bet -module memctl
memctl module을 사용하는 모든 instance들의 block, expression, toggle coverage 데이터를 수집하지 않는다.
deselect_coverage -be -instance top:vhdltest:mctl
top:vhdltest:mctl와 그 하위 모듈의 block, expression coverage 데이터를 수집하지 않는다.

이 command를 사용하면 이미 검증이 완료되었거나 자신이 작성하지 않은 module의 경우 coverage test항목에서 제외시킬 수 있다.

set_explicit_block_scoring -off
이 command를 사용하면 Verilog의 case문 default를 block coverage 데이터 수집에서 제외한다.


이외에도 많은 command들이 있지만 자세한것은 manual을 참고하자.

<-covdut <DUT_module>>
coverage 데이터를 수집할 module을 제한한다. 위의 option을 사용하면 DUT_module과 그 하위 module에 한에서 coverage 데이터를 수집하게 된다.
만약 이 option이 명시되지 않는다면 top-level module부터 데이터를 수집하게 된다.
cf) RTL 코드의 일부분을 coverage 데이터 수집 범위에서 제외하고 싶다면
pragma를 사용해주면 된다.
예)
always @(...)
begin
    A
end

// pragma coverage off
always @(...)
begin
    B
end
// pragma coverage on

always @(...)
begin
    C
end
이렇게 pragma를 사용해주면 B가 포함된 always문은 coverage 데이터 수집 범위에서 제외된다.

<-covoverwrite>
기존에 작성된 coverage 데이터 파일을 overwrite한다.

<-covtest <test>>
Coverage 데이터가 수집될 test의 명칭을 지정해 준다.

========================================================================================
<수집된 coverage데이터 분석 방법>
이렇게 해서 수집된 데이터는 다음과 같은 방법으로 확인할 수 있다.
먼저 coverage 데이터 파일을 분석해 주는 tool인 iccr을 실행한다.

$ iccr -gui &

그 다음 자동으로 생성된 cov_work 디렉토리 안의 coverage 데이터 파일을 열면,
그럼 다음과 같은 창이 뜬다.

이는 전체적인 coverage summary이다.
맨 위칸이 module과 instance의 coverage, 두 번째 칸이 FSM의 coverage, 마지막 칸이 functional coverage의 summary를 나타낸다.
----------------------------------------------------------------------------------------

여기에서 Code/Data tab을 들어가면
아래와 같은 화면이 나오는데
각각의 instace별로 b(block), e(expression), t(toggle) coverage를 확인할 수 있다.
----------------------------------------------------------------------------------------

또 각각의 instance에 우클릭하여 show detail을 보면,
아래의 그림과 같이 해당 module의 RTL에서 어느 부분이 uncovered되어 있는지, 알 수 있다.
아래의 그림은 각각 uncovered (coverage report 부분)되어 있는 block, expression code (coverage statistics 부분)가 무었인지 보여주는 그림이다.
----------------------------------------------------------------------------------------

또한 FSM tab에 들어가면 다음과 같은 그림이 나오는데,

보는바와 같이 각각의 state를 몇 번이나 방문했는지, 방문하지 않는 state는 어떤 state인지 알 수 있다.


그리고 아래 그림과 같이 coverage statistics를 arc로 설정하면, 하나의 state에서 다른 state로 몇번이나 transition이 일어났는지, 또 transition이 일어나지 않는 path는 어떤 path인지를 확인할 수 있다.
----------------------------------------------------------------------------------------

다음으로 Functional tab에 들어가면
다음 그림과 같이 control-oriented coverage, data-oriented coverage에 대해 각각 살펴 볼 수 있다.

각각을 펼쳐보면 다음과 같아.
일단 control-oriented coverage의 내용을 펴보면,
아래 그림과 같이 assert로 명시해 놓은 지점을 몇 번이나 통과했는지를 알 수 있다.

data-oriented coverage의 내용을 펴보면,
RTL에서 명시한 데이터의 coverage를 한눈에 알 수 있다.

========================================================================================
더욱 자세한 것은
ICC Tutorial, ICC User Guide을 참조.

Posted by sunshowers
,