'wave'에 해당되는 글 1건

  1. 2010.11.13 맥에서 Verilog Simulation 하기 (3)
ASIC SoC2010. 11. 13. 11:22
이번에는 verilator로 실행하여서 vcd파일을 덤프하는 것을 만들어 보겠습니다.

일단 verilator로 c++ 소스 코드를 빌드할 때 이전과 차이점은  --trace 옵션이 붙습니다.

verilator --cc  --trace --exe dff_sync_reset_main.cpp  dff_sync_reset.v

위와 같이 실행하여서 Makefile과 c++ 코드를 만들어 냅니다.

testbench격인  dff_sync_reset_main.cpp 역시 수정해야 합니다.

#include <stdlib.h>
#include<iostream>

#include <verilated.h>          // Defines common routines
#include "verilated_vcd_c.h"
#include "Vdff_sync_reset.h"               // From Verilating "top.v"

......

int main(int argc, char** argv) {
            Verilated::commandArgs(argc, argv);   // Remember args

            Verilated::traceEverOn(true);
            VerilatedVcdC* tfp = new VerilatedVcdC;


            dff_sync_reset = new Vdff_sync_reset;             // Create instance

            dff_sync_reset->trace (tfp, 99);
            tfp->open ("./simx.vcd");

            dff_sync_reset->reset = 0;           // Set some inputs

            cout << "Start Simulation" << endl;

            while (!Verilated::gotFinish()) {
                if (main_time > 10) {
                    dff_sync_reset->reset = 1;   // Deassert reset
           .........
                main_time++;            // Time passes...

                tfp->dump (main_time);

            }
            dff_sync_reset->final();               // Done simulating
            //    // (Though this example doesn't get here)
            tfp->close();
            cout << "End Simulation" << endl;
}

추가되는 코드는 위와 같습니다.

먼저 헤더 파일로
#include "verilated_vcd_c.h"
을 읽어들이도록 합니다. 이것은 vcd 덤프를 위한 정보가 들어있습니다.

그리고 trace를 on하고
dump파일을 생성합니다.

            Verilated::traceEverOn(true);
            VerilatedVcdC* tfp = new VerilatedVcdC;
...
            dff_sync_reset->trace (tfp, 99);
            tfp->open ("./simx.vcd");

위에서 traceEverOn은 Trace를 항상 한다는 의미이고
dff_sync_reset->trace(tfp,99)는  최상위 모듈에서 밑으로 99개 depth까지 추적한다는 의미입니다.
거의 무한대겠군요

이후에

tfp->open(...)

을 호출하여 파일을 생성합니다.

            while (!Verilated::gotFinish()) {
                if (main_time > 10) {
                    dff_sync_reset->reset = 1;   // Deassert reset
           .........
                main_time++;            // Time passes...

                tfp->dump (main_time);

            }

무한 루프를 돌면서 한 턴이 끝나면 모두 save할 수 있도록 dump함수를 호출합니다.

이후에 시뮬레이션이 끝나면
            tfp->close();
으로 화일을 닫습니다.

이렇게 해서
simx.vcd
라는 파일을 얻어냅니다.
이것을 vcd 파일 볼 수 있는 프로그램인 gtkwave라던가 scansion에서 불러들이면 됩니다.

개인적으로는 맥스러운 GUI라면 Scansion인데 이 scansion에서 약간의 버그가 있습니다.
vcd파일에서 각 행의 시작열에 공백이 있으면 버그로 인식하게 됩니다.
이 프로그램은 잘 안팔려서 그런지 업데이트가 아주 느립니다.

요부분은 수작업으로 바꾸거나
스크립트로 바꾸면 됩니다.


=== Before ===
$version Generated by VerilatedVcd $end
$date Sat Nov 13 11:15:57 2010
 $end
$timescale 1ns $end

 $scope module TOP $end
  $var wire  1 $ clk $end
  $var wire  1 # data $end
  $var wire  1 & q $end
  $var wire  1 % reset $end
  $scope module v $end
   $var wire  1 $ clk $end
   $var wire  1 # data $end
   $var wire  1 & q $end
   $var wire  1 % reset $end
  $upscope $end
 $upscope $end
$enddefinitions $end


=== After ===
$version
   Generated by VerilatedVcd
$end
$date
    Sat Nov 13 10:51:15 2010
$end
$timescale
    1ns
$end

$scope module TOP $end
$var wire  1 $ clk $end
$var wire  1 # data $end
$var wire  1 & q $end
$var wire  1 % reset $end
$scope module v $end
$var wire  1 $ clk $end
$var wire  1 # data $end
$var wire  1 & q $end
$var wire  1 % reset $end
$upscope $end
$upscope $end
$enddefinitions $end
...

위와 같이 첫번째 열들부터 나타나는 공백을 모두 지우고 불러들이면 됩니다.

사용자 삽입 이미지

그리고 일일이 스크립트를 돌리기  귀찮으면verilator 소스 코드를 직접 수정하면 됩니다.
ident에 관한 일이므로 verilator 스타일로 보건데 한군데서 다 처리할 것 같아 뒤져보았습니다.

일단,
verilator source code가 있는 폴더에서 다음 파일을 찾아서 정리합니다.
.
...../verilator-3.804/include/verilated_vcd_c.cpp

이 파일에서 void VerilatedVcd::dumpHeader ()  함수가 헤더를 덤프해주는 함수입니다.
이 함수 내에 있는 printIdent(xxx) 함수 호출에서 xxx 부분을 몽땅 0으로 바꾸어 주면 됩니다.

=== before ===
354 행 :  printIndent(1);
=== after  ===
              printIndent(0);


382행
=== before ===
 printIndent(-1);
=== after ==
 printIndent(0);

392행
=== before ===
 printIndent(1);
=== after ==
 printIndent(0);


407행
=== before ==
printIndent(-1);
=== after ===
printIndent(0);

411행
=== before ====
printIndent(-1);
=== after ===
printIndent(0);

으로 변경합니다.
결론적으로 해당 함수의 printIdent는 모두 0으로 만들어버리면 ident가 VCD 파일에 들어가지 않습니다.
이제 새롭게 컴파일해서 설치하면 앞서의 scansion에서 파일 오픈할 때 일일이 헤더 부분을 수정할 수고를 덜어줍니다. 어차피 VCD파일 내부를 누가 보겠습니까 ?  IDENT가 없다고 상관없겠죠

이제 일일이 스크립트 돌릴 필요 없이 그냥 출력 파일을  scansion 에서 읽어들일 수 있습니다.







Posted by GUNDAM_IM