Category Archives: verification

Related on SoC & IP verification method.

검증 계획 작성하기

사실 검증이란 걸 처음 시작하면 정신이 아득해집니다. 도대체 뭘 어떻게 검증해야 하며, 언제 끝을 내야지만 하는가.. 이런 부분에 대한 교육이 부족했기 때문이겠지요


그래서, 이런걸 체계적으로 정리하자는 것이 “검증 계획(verification plan)”입니다. 설계 계획에 해당하는 spec. 작업이 설계에 있어서 가장 중요하듯, 검증에 있어서도 spec과 더불어 검증 계획이 중요합니다. 좀더 세분화된 검증 계획이 나중에 경험하게 될 인간 좀비가 될 시간을 줄여주는 거죠.


사실, 제가 처음 검증을 시작할 때, 단순히 “최대한 자동화해서 검증을 해야겠다. “라고 처음 생각을 가진지가 2002년이니 상당히 오랜 기간이 지났는데, 아직도 지지 부진합니다. 물론, 그 동안 설계니 뭐니 시간 문제로 띄엄 띄엄 손을 대었고, 회사내에서 본격적인 프로젝트로 launching은 아직도 못하고 있습니다만.. 제가 관리할 수 있는 입장이 되었으니, 이제야 비로소 verification쪽에 시간을 가질 수 있을 것이라 생각했습니다 (라고 이야기가 끝나면 얼마나 행복하겠습니까?) 만 설계가 부진한 부분을 보면 아직도 뛰어들어서 이것 저것 하느라고, 별로 진척이 없습니다. 여하튼.. 체계적인 계획 없이는 윗분들을 설득시키기도 저 자신을 노력하게 하기도 어렵지요. 검증이란 일이 저에게 있어서는 “맨땅에 헤딩”수준이라 잠시만 마음을 놓아버리면 바로~ 인간 좀비 모드로 변신해서 일을 하는 것도 아니고 아닌 것도 아닌 상황이 되죠.


여담으로 들어왔다가 엄청 돌았습니다.. 다시 본론으로 들어와서


검증계획이란 무엇이냐!


말 그대로, 스펙을 어떻게 분석할 것이며, 어떤 부분에 주의해야 할 것인가, 디렉토리 구조는 어떻게 가져갈 것이며, 스크립팅은 어떤 식으로 할 것인가에 대한 정의를 내리고, 각 부분에 대한 action item을 정의한 후, 해당 item을 어느 순간에 어떤 기준으로 완료할 것인가에 대하여 적어둠으로써, 이후의 검증을 어떻게 진행하고 어떤 기준으로 종결하고, 어떻게 마무리 할 것인가에 대하여 기술하는 문서입니다.


이러한 문서 기술은 우리나라 엔지니어들이 극히 싫어하는 일입니다만(저를 포함해서..^^;), 반드시 필요합니다.
체계적인 문서화는 반드시 작업 중에 발생할 수 많은 오류를 좀더 빨리 찾아내게 해주며, 좀더 쉽게 고칠 기회를 제공합니다. 좀더 좋은 엔지니어가 되시려면, 이 말을 항상 기억해야 한다고 생각합니다. 저도 물론 아직은 별로지만요..^^;


검증 계획 자체에 대하여 가장 체계화된 문서는 Peet James의 “the Five-Day verification plan” 입니다. 물론, 같은 제목의 책도 있습니다만, 저는 별 4개 이상은 주기 어려웠습니다. 첫 번째로 책의 내용이 이 on-line 문서를 좀더 체계화하고 예를 풍부하게 든것에 불과하기 때문에(전적으로 제 느낌입니다), 오히려 온라인 문서를 주욱 읽어보는 것이 더 도움이 되었습니다(미안해요 Peet! 책은 잘 읽었어요~ ). 책은 제 영어 실력의 한계 때문일지도 모르겠으나 상당한 가격을 주고 살만하진 않더군요.


이 문서의 내용은 각 날자별로 해야 하는 일과 빠지기 쉬운 오류(Gotchas)를 적어둔 문서입니다.


예를들면 첫째날은



  • 주요 인터페이스를 살펴보고, 누가 쓸것인지, 중요한 기능이 뭔지, 가장 많이 사용되는 모드가 뭔지 살펴볼 것

  • 각 인터페이스에 대하여 살펴보고, 어떤 BFM을 적용해야 하는지 볼 것

  • 사용 가능한 검증 인프라가 있나?

  • Behavioral model에 대해서 살펴보고 golden모델에 대하여 생각하고, 어떻게 비교할지 생각할 것

  • 어떤 검증 언어를 쓸껀가요?

  • 어떤 장비를 쓸건가?

  • 어떤 방식의 random 기반 검증이 가능한지 생각할 것

뭐 이런 식인거죠. 그리고, 이에 대한 예를 주욱~ 적어두고.. 이런 생각할 때 주의해야 할 사항들을 적어두고.. 이런식으로 풀어둔 책입니다. 뭐 자세히 설명할 필요 없이 위의 문서를 읽어보는 것이 좋겠죠.


그리 어렵지도, 그리 획기적이지도 않습니다만, 생각보다 처음 검증을 시작하시는 분들에게는 도움이 될 거라고 생각합니다. 저도 생각보다 많이 도움을 받은 문서이면서 책이거든요.^^; 자! 검증 엔지니어 지망하시는 분들 혹은 검증의 중요성을 느끼시는 분들이라면, 검증 계획을 한번 적어봅시다. (참고적으로.. 이 검증 계획 적는 일을 해보시면, 생각보다 쉽지 않다는 걸 깨닿는데 1시간이 채 걸리지 않습니다. 그런데, 꾸욱~ 참고 몇 프로젝트에 대해서 적어보면 점점 나아지니까 처음엔 적응기라 생각하고 버티세요..)

Coverage와 Assertion

검증에 있어서 고려되어야 하는 사항중에 하나는 “언제 검증을 그만 둘 것인가”입니다.


너무나도 쉬운 질문이지요? 뭐, 검증할 부분을 다하면 검증을 그만 두면 되죠. 그럼 질문을 바꿔보겠습니다. “검증할 부분에 대하여 모두 검증했는지는 어떻게 알지요?”


그것이 오늘 말씀드릴 coverage에 대한 부분입니다.


사실 이쪽 계통에서 coverage라는 이름으로 검색하면 처음에 나오는 것은 아마도 falut coverage/test coverage일 것입니다. [wp]DFT[/wp]/Testing 부분에서 사용하는 용어인데, 만들어진 test vector가 얼마나 많은 tr. 을 천이시켜 볼 수 있느냐를 나타내는 말이죠(값을 천이시킬 수 있어야지만, stuck-at-0/stuck-at-1 fault를 잡아낼 수 있으니까요). 여하튼.. 이때 test coverage는 입력된 테스트 벡터에 의하여 천이 시킬 수 있는 transistor의 비율을 나타냅니다.


검증에 있어서 coverage도 마찬가지 입니다.


기본적으로 두 가지 coverage는 충족해야 하는데, 아주 기초적인 값이 code coverage, 약간 더 복잡하지만 반드시 체크해야 하는 부분이 functional coverage입니다.


이 중 code coverage는 주어진 RTL 코드 중에 검증 벡터에 의하여 활성화 되는 코드의 비율 정도로, functional coverage는 “점검해야 할 기능 요소 대비 주어진 벡터로 잡아낼 수 있는 기능 요소의 수” 정도로 요약 될 수 있습니다. Code coverage는 그나마 좀 자동화하기 쉽습니다.


이미 존재하는 RTL 코드가 시뮬레이션 도중에 사용되는지를 확인하면 되는 문제니까 말입니다. 물론, 여기서 말한 [wp]code coverage[/wp]는 가장 기초적인 line coverage를 의미합니다만… ^^;
여하튼, 이 code coverage는 검증에 있어서 가장 기본적인 요소가 됩니다. 적어도 자기가 만든 RTL 코드가 검증 벡터에 의하여 모두 확인되었는지는 알고 지나가야 할 문제니까요.  


다시 처음 질문으로 돌아가서 “점검해야 할 기능 요소의 수”는 어떻게 알수 있겠습니까???  물론, 설계자의 spec안에 있습니다. RTL 코드란 궁극적으로 spec안에 제시된 기능을 구현한 것이니까요. 그런데, 이걸 검증 과정에서 빼놓지 않고 검증 했는지를 알기란 상당히 어렵고, 자동화 대상이 되기 어렵습니다. 그래서 assertion이 등장합니다.


[wp]assertion[/wp]은 software부분에서는 이미 폭넓게 사용되던 개념입니다. 코딩에 있어서는 어떤 가정(이 조건은 절대 들어오지 않는다던지.. 어떤 변수는 어느 구간안에서는 절대 어떤 값을 지니지 않는다던지..)을 하는 경우가 있는데, 이런 가정하지 않은 경우가 온다면 구현된 코드가 “절대” 안전 할 수 없으며, 정의되지 않은 동작을 시도하면서 프로그램이 오동작하게 됩니다. 이런 경우를 확실히(assert)  하기 위해서 assertion이라는 것을 사용합니다. 즉, 가정하지 않은 경우가 발생하면 동작 과정에서 “조용히 버그를 발생시키기보다는 경고 메시지와 함께 끝나자”는 것입니다. (여기에 대한 주요한 내용은 이 분야의 선구자(?)인 Foster의 “Assertion-based Design”이라는 책을 보면 잘 나와 있습니다.) 이 책의 내용을 기반으로 OVA라는 라이브러리도 있고, 실무에서 많이 사용된다고 합니다. [wp]PSL[/wp]/Sugar라는 표준 언어가 제정되기도 했지요. (systemverilog에서는 언어수준에서 assertion이 제공됩니다.)


이 assertion 기능을 좀 더 전향적으로 사용하면, spec을 정의할 수도 있습니다. 즉, 어떤 기능에 대하여 assetion으로 지정해 두는 것이지요. 이런 assertion은 테스트 벡터에 의하여 지정된 기능 요소가 검증되었는지 나타내는 기능으로 사용되는 것입니다. 이걸 바꿔 말하면, 주어진 assertion의 수 대비 테스트 벡터에 의하여 점검된 assertion의 수로써 우리가 원하던 “spec에 정의된 기능을 테스트 벡터가 얼마나 수행하였는지”를 나타내게 되며, 이는 달리 말하면 functional coverage를 나타내게 됩니다. !!!


드디어 전혀 관계 없어 보였던 두 개의 기능이 만나 하나의 art가 되는 순간이죠. ^^;


몇 번 적었습니다만, Lint, code coverage, assertion의 개념은 모두 소프트웨어 공학쪽의 개념이었는데, 이제는 하드웨어 설계로 넘어오고 있습니다(사실 다 넘어왔죠..) 참 재미있습니다.

Level of abstraction

“추상화 수준”, “추상화 단계”라 불리는 용어이지요. 아마도 C++를 다루실 때 많이 접하셨을 것이라 생각합니다. ^^; 추상화 수준이라는 것은 말 그대로 추상화의 정도입니다. 추상화의 반대가 구체화라는 것은 아실 것이고, 추상화는 생각에, 구체화는 사물에 가깝다는 것도 아실 것이라 생각합니다.


모든 작품(?)이 다들 그렇지만, 머리 속의 관념이(ASIC에서는 알고리즘) 표현 도구를 통하여 구체화되는 과정을 거쳐서 하나의 작품이 됩니다. 이때 머리속의 관념은 추상화 단계에서 점차 구체화되는데요.. 칩쟁이들이 잘 하는 말로 algorithm level, architecture level, register transfer level, gate level, physical implement level 뭐 이 정도 표현할 수 있겠습니다.


ASIC에 있어서 보통 RTL이라고 하는 register transfer level에서부터 physical impelmentation level(즉, GDSII라는 완성된 그림이 나오는 단계)까지는 EDA툴이라 부르는 CAD툴에 거의 전적으로 의존하게 됩니다. (아날로그 하시는 분들이 빼고요.. 그 분들은 직접 그림을 그리시는 artist잖아요~ ^^;)


즉, 설계라는 분야란 기계적으로 말하자면 algorithm을 RTL로 변환하는 과정을 의미합니다. “기계적”이란 용어를 사용한 건 말이 그렇다는 것을 알려드리고 싶어서입니다. ^^;
실무에서 보면, algorithm을 전공하신 분과 computer architecture/ASIC을 전공하신 분이 실무에서 어느 정도 일하다가 동일한 작업을 수행하기 위하여 RTL을 만들때 보면 전혀 다른 RTL을 만들어낼때가 있는데, 가장 큰 이유는 어느 추상화 수준에 초점을 맞추었느냐에 차이가 있고, 두 번째는 ASIC 전공자들은 알고리즘 자체를 볼때 하드웨어 구현을 고려하여 하드웨어에 최적화된 알고리즘을 생각하는 반면, 많은 알고리즘 전공자 분들께서는 software적인 최적화 알고리즘을 많이 생각해 내십니다. (에고.. 그냥 이야기하다가 너무 벗어났네요..여하튼.. 저는 각 전공분야에서 보는 관점이 다르다..라는 이야길 하고 싶었는데.. 쩝. ^^;)


검증에서는 약간 더 많은 추상화 단계를 지닙니다. 사실 검증이라기 보다는 modeling이라는 표현이 맞겠습니다. 이건 model의 정확성과 수행 시간간의 상관관계 때문에 아주 정확하지 않아도 되는 부분은 추상적으로 표현해서 속도를 빠르게 할 수 있기 때문이지요.


예를 들어, gate 수준으로 구현된 netlist simulation보다 RTL simulation이 훨씬 빠른 것이 당연하고, RTL simulation보다 대략적인 functional model을 이용하는 것이 더 빠르니까요.


이 functional model은 약간 더 세분하면



  • Transaction level model; 사실 각 모듈 간의 동작만을 정의하는 것이지요. 내부 동작 자체를 구현할 수도 안할 수도 있는데, 일반적으로 ‘추상화 수준이 높다’고 이야기 할때는 내부 동작은 구현하지 않고 모듈의 transaction만을 나타낼 때입니다.

  • Untimed functional model; transaction level도 untimed와 timed로 나뉘는데 시간에 대한 정보 포함 여부에 따라 나눕니다. 그냥 읽고/쓰고.. 이런식으로 하면 untimed이고, 가장 추상화 수준이 높다고 봅니다.

  • Timed functional model; timed는 transaction의 time정보가 있으므로, 약간은 더 구체화 된 수준입니다.

대략 이런식으로 나눕니다. 물론, 이것 이외에도 behavior level을 나누는 형태로



  • bus functional model(BFM) – bus functional model은 사실 transaction level model과 별 차이 없다고 생각되는데 많은 경우 pin accuracy가 있느냐를 가지고 나눕니다. 말 그대로 모듈의 출력/버스 수준에서의 동작만을 기술한 것입니다. 알고리즘이 들어간 블럭의 경우 이런거 만들기 쉽습니다. 

  • bus cycle accurate model – timed functional model과 유사하죠.

  • cycle accurate model – 시스템 클럭 수준에서의 동작을 맞추어 주는 수준입니다.

둘 사이에 많은 유사점이 있는데, 큰 사항은 transaction을 추상화 할 것이냐 차이겠습니다.


사실 pipelined processor와 같은 control 위주의 모델에서는 transaction model이 크게 편하지 않습니다. 어짜피 명령어 fetching 이후에 몇번째 사이클에서 data bus에 어떤 종류의 transaction이 발생할지를 알아내기 위해서는 어느 정도 구체화를 해야하니까요. 하지만, 통신 모델이라던지 연산 모델에서는 이게 상당히 쉽습니다. latency정도만 알면 연산하고 latency이후에 결과를 내놓는 형태로 구현되니까요. 그래서 알고리즘, 통신 쪽에서 transaction model이 각광받고 있고, ASIC에서 이쪽 분야가 차지하는 비중을 생각할때 이 모델들이 중요시 되는 것이겠지요. ^^;


추가적으로 검증에서는 어떤 수를 써서라도 추상화 레벨을 높여주는 것이 필요합니다. 왜냐하면, 더 정확한 검증이란 더 많은 검증 벡터를 기존 벡터가 cover하지 못한 부분에 generation해 주어야 하고, 많은 검증 벡터를 주어진 시간안에 수행하여 coverage를 높이기 위해서는 모델이 더 빨라져야 하며, 이를 가장 보장해주는 방법이 추상화 수준을 높이는 것이기 때문입니다.  ^^;



p.s. system verilog의 verification feature(class나 dynamic array, queue같은..)가 지원되는 “저가” simualtor 좋은 거 없나요? ㅎㅎ