Tag Archives: Verification

집중이 안되는 여름

연일 30도를 넘나드는 더위가 계속되고 있습니다.


이럴때 항상 문제가 되는 것이 집중력이 떨어진다는 건데요.. 저도 마찬가지 입니다.
(실은 개인적으로 좋은 일이 생겨서 그럴지도 모르겠습니다만 ^^;)


오늘만해도 gcc-MinGW에서 mti vpi 연결시키는 거 때문에 잠깐 modelsim userguide를 보다가, 딴짓을 하기 시작해서 대략한 5시간동안 딴짓을 했습니다.


뭐 딴짓이라고 해도 모레쯤이나 하려던 processor market forecasting자료 정리였는데, 어짜다보니 하고 있더군요. 이건 뭐, 원래 하려던 일은 까맣게 잊고 나중에 하려던 일을 한참하다가 “아.. 내가 오늘 하려던 일은 이게 아닌데.. ” 뭐 이런 시나리오라고나 할까요.


VPI 이야기가 나와서 그러는데요.. (또또.. 옆길로 빠집니다요) 회사 툴이 System Verilog-verification feature를 지원해주지 않아서, C/PLI나 만들어야 겠다는 이야기를 했었죠? 요즘 teal library를 분석하고 있는 중인데, 이거야 원.. 보면서 몇 번을 감탄한 것인지 모르겠습니다.


사실 뭐 PLI 연결하는 것이야 별 차이있겠습니까? 뭐 thread를 사용하는 것도 그렇다치구요.. 근데, PLI 연결 부분을 teal_synch.cpp라는 몰아두고, 이걸 class로 덮어씌우고 연산자 오버로딩을 해버리니 예술적인 경지에 이르르더군요. 사용하는 사람 입장에서는 이 부분이 verilog랑 붙기 때문에 어쩌구 저쩌구 생각할 필요가 거의 없도록 만들어졌더군요.


아쉽게도 저는 유연성 보다는 빠른 동작을 즐기기 때문에 teal을 그대로 이용하지는 않겠지만, (처음에는) 재미삼아 분석해 본 라이브러리인데 아주 많은 걸 배웠습니다. 천재성이 담긴 코드에요.. 저에겐 ‘이 정도쯤은 해야 verification engineer가 되는 건가.. 에효..’ 라는 상념에 빠지게 하더군요..


C++에 익숙하시고, PLI를 공부중인 분들은 상당히 도움을 받으실 수 있을 것 같습니다. 혹시라도 관심있으신분은 http://www.trusster.com/ 에서 다운 받아보실 수 있습니다. 이거 관련된 책도 있는데, 아직은 저도 본 상태가 아니라 뭐라 말씀드리기는 어렵습니다. (TRUSS도 아직 사용해보지 못했습니만, Teal만으로도 괜찮습니다 ^^;)


아.. 그러고보니 관련 기사도 있었군요.. EETimes Korea의 기사입니다.


위의 부분까지는 MS Writer에서 썼는데, 평소처럼 publish하려니 좀 허전하네요.. ^^;

혹시라도 PC환경에서 cygwin/modelsim하에서 사용하시는 분들을 위하여 몇 가지만

1) Makefile.Windows를 만듭니다. 이 파일은 Makefile.linux를 복사하시는 것이 편합니다.
2) 아래와 같이 고칩니다. (필요에 따라 더 고치셔도 됩니다.)


ARCH_LIB_OPT = -L/cygdrive/c/Modeltech_6.0/win32 -lmtipli
ARCH_SHARED_SUFFIX = dll
SYS_ARCH_CC = g++
              

3) Makefile을 수정합니다.


SIMULATOR_HOME = /cygdrive/c/Modeltech_6.0
ARCH    = Windows
SIM     = mti_2_0



대략적인 힌트만 드렸습니다만, 이 정도면 필요한 부분을 추가적으로 수정하셔서 verification_top()함수를 작성하신 다음에 linking하시는데 문제 없을듯 합니다.

PLI와 Simulator의 연결(I)

Automated Functional Verification 방법에는 여러 가지가 있지만, testvector 발생 유닛(보통 Directed Random방식을 사용하지요?)과 golden model을 이용한 checker model을 만들어서 DUV(Design Under Verification)의 결과와 비교하는 것이 가장 편한 방법 중에 하나임은 부정할 수 없습니다. (여담입니다만, 국내에서는 많은 경우 golden model없이 설계하는 경우가 많아서 검증을 위하여 작성한 golden model이 실제로 RTL보다도 정확성이 떨어지는 경우가 있다는 것이 문제가 종종 발생합니다. 여기서는 golden모델의 확보에 대한 이야기는 나중으로 미루죠.)보통 golden model은 C model을 이용하게 되는데, C 모델을 Verilog와 동시에 simulation하는 것은 그리 녹녹한 일이 아닙니다.


저는 프로세서를 대부분 다루기 때문에 C모델이라 함이 대부분 ISS simulator가 됩니다. 이후에 Simulator와 C모델은 그냥 섞어 쓸 가능성이 높은데, 보시는 분께서 편하신 대로 생각하시면 되겠습니다.


우선 Simulator를 만들 때 그 목적을 정확히 할 필요가 있습니다. 초기에 Simulator의 목적은 executable spec.의 의미가 가장 중요한 의미였을 것입니다. 그래서, 대부분 function level의 정확성을 가지지요. 프로세서의 경우 보통 이야기하는 ISS(Instruction Set Simulator)정도의 수준일 것입니다.


이때 고려하는 사항은 동작의 정확성, 빠른 동작 속도, 유연한 변경 가능성(design space exploration을 해야 하니까요)과 같은 것을 고려하게 됩니다.


그런데, 아시다시피 Verilog와 Simulation을 한다던지, Verilog Model대신 사용하려고 할 경우에는 ISS level뿐만 아니라, BFM 수준, 간혹은 Pin-level accuracy를 필요하게 됩니다. 통신이나 영상쪽의 모델은 뭐 Functional model이나 BFM이나 큰 어려움이 없습니다. Latency가 거의 정의되어 있기 때문이지요.


프로세서의 경우 약간 복잡해지는데, hazard의 발생, instruction issue rate의 변화, exception의 발생을 고려해야 하는데, 이 경우 bus function이 발생하는 Instruction Fetch와 Data Access stage의 동작을 모사하기 위해서는 대부분의 pipeline을 표현해내야 합니다. 예전에 pipeline 수준의 accuracy를 가지는 simulator를 만들고, pin-level interface를 붙여서 나름대로 쓸만한 PLI model을 만든 적이 있지요. 단지 문제는 pipeline수준의 accuracy를 가지다 보니, 너무 너무 느려져 버린거지요.


쉽게 쉽게 만들려면 functional model로 simulator를 만들고, Verilog Model(DUV)상에 하나의 명령이 retire되는 순간에 register들의 값을 비교하는 방법도 가능합니다. 하지만, 해당 model이 불필요한 hazard 발생은 없는지, Instruction Fetching에 불필요한 사항이 추가되지는 않았는지 확인 할 수는 없습니다. (당연하죠.. reference model이 functional model이니 timing spec.을 만족시켰는지는 알수 없는것이지요)


흠.. 많이 옆으로 샜는데요..


C Model과 Verilog와 붙이는 방법이 Verilog-PLI (Programming Language Interface)를 이용하는 겁니다. Simulator는 clock단위로 동작하므로, 느낌상 아래와 같이 동작시키면 될 것 같습니다. 이런 경우에 verilog에서 C function을 호출할 때 가장 많이 사용되는 건 calltf()를 이용하는 방법입니다.



always @(posedge clk or negedge rst_x) begin


  $run_sim_calltf(xxxx);


end


즉, run_sim()을 calltf()의 callback function으로 등록하는 겁니다. 그리고, 매 클럭 calltf()를 불러주는 것이지요.


근데, simualtor의 이전 상태를 계속적으로 보존해야 하는 경우에는 매 클럭 새롭게 호출되는 calltf()를 이용할 때 문제가 있을 수 있습니다. (사실 그리 어려운 일은 아닙니다만, 예를 들기 위하여 ^^ ) 그래서, 내용을 보존하고 싶을 때는 misctf()를 사용하는 것도 괜찮습니다. misctf()는 원래 verilog simulation의 이런 저런 정리 작업을 하는데 사용하는 목적으로 만드는 건데요. 아래와 같이도 사용할 수 있습니다.



initial begin


  $run_sim_misctf(data, reason, paramvc);


end


뭐 이런 느낌입니다. misctf()의 경우 시뮬레이터의 초기 시에 simulator에 연결된 이후에 simulator의 종료 시까지 계속 머무르면서 파라미터의 값이 변경 될 때 마다 제어권을 가집니다. 이 파라미터의 변화시마다 클럭이 변화되었는지 확인하고, 클럭이 변화하였을 때 값을 호출하면 되겠습니다.


아래는 한 4년 전에 만든 PLI 모델중의 misctf부분인데요.. 실제 구현은 없으니 공개해도 별 문제 없을 것입니다. ^^; 대략 이런 느낌으로 만드시면 됩니다. 🙂
다음 번에는 좀 더 재미난 PLI 함수를 다루어보죠.. (아.. VPI는 초반에 좀 다루지 않네요. ^^; Blog의 예제를 위해서라도 예전에 acc_와 tf_를 이용해서 만든 PLI 모델을 업그레이드해야겠군요. )



int misctf_proc(int data, int reason,int paramvc) {
 
 static int  reset_called = FALSE;
 int   POInt;
 
 
 
 switch (reason) {
  case reason_paramvc : { // 파라미터의 값 변화로 인한 호출의 경우
   if (tf_getp(PIN_RST_X) == 0) { // reset state
    // 아래의 형태는 초기 조건에서의 리셋 호출을 위하여 사용된다.
    if (reset_called == FALSE || paramvc == PIN_RST_X) {
     io_printf(“$AE32KB_RUN : CORE RESET CONDITION\n”);
     // 실제적인 reset을 수행한다.
     
     reset_called = TRUE;
     
     POInt = 0;
     
     if (tf_getp(PIN_OSIEN) == 1) {
      POInt = POInt | OSIEN;
      if (tf_getp(PIN_OSIROM) == 1) {
       POInt = POInt | OSIROM;
      }
     }
     ResetCore(POInt);
    }
   }
   else if ( paramvc == PIN_CLK ) {  
    if (is_posedge(PIN_CLK,paramvc) == TRUE) {
     // 변경된 모든 입력 값을 받아서 반영한다. 
     apply_input();
     io_printf(“%s : CLOCK POSEDGE\n”, tf_strgettime());
     
     EndClock();
     // end_clock함수
     
     StartClock();
     // start clock 함수
     
     // 변경된 데이터를 기반으로 핀과 레지스터를 변경시킨다.
    }
   }
   break;
  }
//  case
  default :
  break;
 }
 
 // apply outputs
 apply_output();
    return 0;
}


이제 EISC processor도 어느 정도 정비를 마치고, 빠른 미래에  좀 더 공격적인 마케팅을 시작할 예정입니다. ^^; 많이 기대를 해 주세요.. 특히 학생분들께 좋은 기회가 많이 돌아가도록 노력 중입니다.

Perl을 이용해서 검증할때 유용한 팁

뭐랄까요.. 요즘 이런 저런 일로 바쁘다보니, 사람이 좀 얇팍하게 글을 쓰게되네요. 🙂
(퇴고 없이 그냥 온라인에서 쓰는 글이라 앞뒤가 없을지도 모르겠습니다.)

오늘은 여러분들께서 perl을 이용해서 Verilog HDL을 위한 testbench를 작성할 때 간단히 명령어 해석기를 만들어 사용하는 방법을 알려드리죠.

이 방법은 제가 JTAG을 위한 protocol을 만들다가 생각해낸 방법인데요.. 아주 유용하게 쓰고 있습니다.
얼마전 AXI FileReader와 같은 간단한 명령어 해석기가 필요할 때도 쉽게 적용할 수 있구요.

예를들어, JTAG을 위한 몇몇 명령을 만들고, 이 명령을 이용해서 HDL model을 위한 신호 입력으로 변환시키는 과정을 생각해 봅시다.

1. 필요한 함수를 정합니다.
대충 다음과 같은 함수를 쓸 수 있겠지요?


rtnval = get_id();
do_intest(serin);
do_extest(serin);


2.
해당 함수를 perl에서 subroutine으로 만들어갑니다.
뭐, subroutine을 만드는 방법은 쉽죠?

3.
이 부분이 제일 중요한데요..


xxx.pl <filename.input>

이런식으로 처리하려면, 중간에 다음과 같은 루틴을 넣어줍니다.


do “$ARGV[0]”;

위의 한 행은 해당 파일($ARGV[0])에 지정된 “perl” 명령어들을 읽어와서 해석하는 부분입니다.
즉, 여러분께서 “filename.input” 이라는 입력 파일에 앞에서 작성한 subroutine을 “명령어 사용하듯” 적어두면, 이것이 perl script에서 읽혀서, “명령어를 해석하듯” 동작하게 됩니다.
이렇게 함으로써, 파싱하는 부분을 생략하고도, 그럴듯하게 명령어 해석기처럼 하나의 perl 스크립트를 만드는 것이 가능합니다.

이제 이러한 perl script에서 어떻게 HDL 테스트 벡터를 만들어내는지 생각해 봅시다.
간단히 생각할 수 있는 것은 두 가지 인데요.
첫번째는 ROM file형태로 만들어버리고, verification을 위한 testbench에서는 $readememh()를 써서 읽은 다음에 한 클럭에 하나의 신호 그룹을 뿌리는 방법이구요..
두번째는 각 subroutine에 printf FOUT 과 같은 file output을 사용해서, 간단한 verilog testvector를 만들어내고, 이를 verification을 위한 testbench에서 `include “xxx” 명령을 이용해서 읽어들이는 방법입니다.

둘 다 간단하죠?

한 마디로, perl을 이용하면 C로는 어렵게 해야 할 일이 아주 아주 편해지는 일이 많습니다. 그래서 verification engineer들에게 perl과 같은 scripting 언어가 사랑받는 것이겠죠.