FC2カウンター FPGAの部屋 Verilatorを試してみる1(C++モード1)
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

Verilatorを試してみる1(C++モード1)

前回、”VerilatorでLint”でバージョン3.810のVerilatorをインストールして、Lintをここ見たがOVLがうまくコンパイル出来なかった。

今回は、バージョン3.812のVerilatorをインストールして、シミュレーションしてみた。環境としてはCygwinを使用した。
なぜVerilatorでシミュレーションしてみたかったか?というと
1.VerilogやSystemVerilogをコンパイルしてC++に落としてシミュレーションするということで、C++やSystemCのテストベンチが簡単に使用できるという利点がある。
2.値としては1と0のみで、ZやUやHやLなどの値を持たないが、その代わり高速にシミュレーションできるという結果が出ている。
3.VerilogやSystemVerilogがシミュレーションできるフリーのシミュレータである。
以上のような理由である。
SystemVerilog DPI-Cも魅力的だが、フリーのModelSimでやるには大きい規模のDUT(Device under test)をシミュレーションする予定なのだ。

武内さんの”電気回路/HDL/Verilator の導入(C++モード)”を全面的に参照させてもらいながら、Verilatorの試用をしていくことにする。武内さん、参照させていただきます。ありがとうございます。

・モジュールの入力信号、出力信号を見る
今回は自分で以前、電子サイコロをチュートリアル用に作ったときのdice_stat_machine.v単体をシミュレーションしてみる。下にdice_stat_machine.vを示す。

`default_nettype none
`timescale 1ns / 1ps

// 1から6までのサイコロの目を表すステートマシン,Direct Verilog2001

module dice_state_machine(
    input wire reset_sw,
    input wire clk,
    input wire roll,
    input wire roll_ena,
    output wire [2:0] spots
);

    parameter        st_one        = 6'b000001,
                    st_two        = 6'b000010,
                    st_three    = 6'b000100,
                    st_four        = 6'b001000,
                    st_five        = 6'b010000,
                    st_six        = 6'b100000;
    reg [5:0] current_state;
    reg [2:0]    spots_node;
    
    always @(posedge clk) begin
        if (reset_sw) begin
            spots_node <= 3'd1;
            current_state <= st_one;
        end else begin
            case (current_state)
                st_one : begin
                    spots_node <= 3'd1;
                    if (roll && roll_ena)
                        current_state <= st_two;
                end
                st_two : begin
                    spots_node <= 3'd2;
                    if (roll && roll_ena)
                        current_state <= st_three;
                end
                st_three : begin
                    spots_node <= 3'd3;
                    if (roll && roll_ena)
                        current_state <= st_four;
                end
                st_four : begin
                    spots_node <= 3'd4;
                    if (roll && roll_ena)
                        current_state <= st_five;
                end
                st_five : begin
                    spots_node <= 3'd5;
                    if (roll && roll_ena)
                        current_state <= st_six;
                end
                st_six : begin
                    spots_node <= 3'd6;
                    if (roll && roll_ena)
                        current_state <= st_one;
                end
            endcase
        end
    end
    assign spots = spots_node;
    
// synthesis translate_off
    reg [20*8:1] DICE_STATE; 
    
    always @(current_state) begin
        case (current_state)
            st_one    : DICE_STATE = "ST_ONE";
            st_two    : DICE_STATE = "ST_TWO";
            st_three: DICE_STATE = "ST_THREE";
            st_four    : DICE_STATE = "ST_FOUR";
            st_five    : DICE_STATE = "ST_FIVE";
            st_six    : DICE_STATE = "ST_SIX";
            default    : DICE_STATE = "ST_ONE";
        endcase
    end
// synthesis translate_on
endmodule
`default_nettype wire 


(2010/05/23 dice_state_machine.vを修正しました)

次に、武内さんの”電気回路/HDL/Verilator の導入(C++モード)”のbin2bcd_test.cppを参照させていただいて作ったC++のテストベンチのdsm_test.cppを下に示す。

#include <iostream>
#include <verilated.h>    // Defines common routines
#include "Vdice_state_machine.h"

unsigned int main_time = 0;     // Current simulation time

double sc_time_stamp () {       // Called by $time in Verilog
    return main_time;
}

int main(int argc, char** argv) {
    Verilated::commandArgs(argc, argv);   // Remember args
    
    Vdice_state_machine *top = new Vdice_state_machine();
    
    top->reset_sw = 1;        // Set some inputs
    top->clk = 0;
    top->roll = 0;
    top->roll_ena = 0;
    
    while (!Verilated::gotFinish()) {
        if (main_time > 10) 
            top->reset_sw = 0;    // リセットを解除する
        
        if ((main_time % 5) == 0)    // クロックを生成する
            top->clk = !top->clk;
            
        if (main_time > 20)    // roll を1にする
            top->roll = 1;
            
        if (!top->reset_sw) {    // リセットが解除された後で
            if ((main_time % 10) == 1) // クロックが立ち上がった1デルタ時間後
                top->roll_ena = !top->roll_ena;
        }
        
        top->eval();    // 評価
        
        printf("Time %d : clk = %d roll_ena = %d spots = %d\n", main_time, top->clk, top->roll_ena, top->spots);
            
        if (main_time>200)
            break;         // 終了
        
        main_time++;
    }
    
    top->final();        // シミュレーション終了
}


この2つのファイルをフォルダに置いて、Verilatorでコンパイルを行った。その時のコマンドを下に示す。

verilator --cc -Wno-lint dice_state_machine.v --exe dsm_test.cpp


現在のフォルダ上にobj_dirフォルダができる。cdコマンドを使用して、obj_dirフォルダに移る。

cd obj_dir/


makeを行って、実行ファイルを作成する。

make -j -f Vdice_state_machine.mk Vdice_state_machine


実行ファイルを実行する。

./Vdice_state_machine.exe


下に、実行ファイルを実行する前のCygwinの画面を示す。
Verilator_6_110523.png

実行後のCygwinの画面を下に示す。
Verilator_7_110523.png

シミュレーション結果のprintfの出力を下に示す。

Time 0 : clk = 1 roll_ena = 0 spots = 1
Time 1 : clk = 1 roll_ena = 0 spots = 1
Time 2 : clk = 1 roll_ena = 0 spots = 1
Time 3 : clk = 1 roll_ena = 0 spots = 1
Time 4 : clk = 1 roll_ena = 0 spots = 1
Time 5 : clk = 0 roll_ena = 0 spots = 1
Time 6 : clk = 0 roll_ena = 0 spots = 1
Time 7 : clk = 0 roll_ena = 0 spots = 1
Time 8 : clk = 0 roll_ena = 0 spots = 1
Time 9 : clk = 0 roll_ena = 0 spots = 1
Time 10 : clk = 1 roll_ena = 0 spots = 1
Time 11 : clk = 1 roll_ena = 1 spots = 1
Time 12 : clk = 1 roll_ena = 1 spots = 1
Time 13 : clk = 1 roll_ena = 1 spots = 1
Time 14 : clk = 1 roll_ena = 1 spots = 1
Time 15 : clk = 0 roll_ena = 1 spots = 1
Time 16 : clk = 0 roll_ena = 1 spots = 1
Time 17 : clk = 0 roll_ena = 1 spots = 1
Time 18 : clk = 0 roll_ena = 1 spots = 1
Time 19 : clk = 0 roll_ena = 1 spots = 1
Time 20 : clk = 1 roll_ena = 1 spots = 1
Time 21 : clk = 1 roll_ena = 0 spots = 1
Time 22 : clk = 1 roll_ena = 0 spots = 1
Time 23 : clk = 1 roll_ena = 0 spots = 1
Time 24 : clk = 1 roll_ena = 0 spots = 1
Time 25 : clk = 0 roll_ena = 0 spots = 1
Time 26 : clk = 0 roll_ena = 0 spots = 1
Time 27 : clk = 0 roll_ena = 0 spots = 1
Time 28 : clk = 0 roll_ena = 0 spots = 1
Time 29 : clk = 0 roll_ena = 0 spots = 1
Time 30 : clk = 1 roll_ena = 0 spots = 1
Time 31 : clk = 1 roll_ena = 1 spots = 1
Time 32 : clk = 1 roll_ena = 1 spots = 1
Time 33 : clk = 1 roll_ena = 1 spots = 1
Time 34 : clk = 1 roll_ena = 1 spots = 1
Time 35 : clk = 0 roll_ena = 1 spots = 1
Time 36 : clk = 0 roll_ena = 1 spots = 1
Time 37 : clk = 0 roll_ena = 1 spots = 1
Time 38 : clk = 0 roll_ena = 1 spots = 1
Time 39 : clk = 0 roll_ena = 1 spots = 1
Time 40 : clk = 1 roll_ena = 1 spots = 1
Time 41 : clk = 1 roll_ena = 0 spots = 1
Time 42 : clk = 1 roll_ena = 0 spots = 1
Time 43 : clk = 1 roll_ena = 0 spots = 1
Time 44 : clk = 1 roll_ena = 0 spots = 1
Time 45 : clk = 0 roll_ena = 0 spots = 1
Time 46 : clk = 0 roll_ena = 0 spots = 1
Time 47 : clk = 0 roll_ena = 0 spots = 1
Time 48 : clk = 0 roll_ena = 0 spots = 1
Time 49 : clk = 0 roll_ena = 0 spots = 1
Time 50 : clk = 1 roll_ena = 0 spots = 2
Time 51 : clk = 1 roll_ena = 1 spots = 2
Time 52 : clk = 1 roll_ena = 1 spots = 2
Time 53 : clk = 1 roll_ena = 1 spots = 2
Time 54 : clk = 1 roll_ena = 1 spots = 2
Time 55 : clk = 0 roll_ena = 1 spots = 2
Time 56 : clk = 0 roll_ena = 1 spots = 2
Time 57 : clk = 0 roll_ena = 1 spots = 2
Time 58 : clk = 0 roll_ena = 1 spots = 2
Time 59 : clk = 0 roll_ena = 1 spots = 2
Time 60 : clk = 1 roll_ena = 1 spots = 2
Time 61 : clk = 1 roll_ena = 0 spots = 2
Time 62 : clk = 1 roll_ena = 0 spots = 2
Time 63 : clk = 1 roll_ena = 0 spots = 2
Time 64 : clk = 1 roll_ena = 0 spots = 2
Time 65 : clk = 0 roll_ena = 0 spots = 2
Time 66 : clk = 0 roll_ena = 0 spots = 2
Time 67 : clk = 0 roll_ena = 0 spots = 2
Time 68 : clk = 0 roll_ena = 0 spots = 2
Time 69 : clk = 0 roll_ena = 0 spots = 2
Time 70 : clk = 1 roll_ena = 0 spots = 3
Time 71 : clk = 1 roll_ena = 1 spots = 3
Time 72 : clk = 1 roll_ena = 1 spots = 3
Time 73 : clk = 1 roll_ena = 1 spots = 3
Time 74 : clk = 1 roll_ena = 1 spots = 3
Time 75 : clk = 0 roll_ena = 1 spots = 3
Time 76 : clk = 0 roll_ena = 1 spots = 3
Time 77 : clk = 0 roll_ena = 1 spots = 3
Time 78 : clk = 0 roll_ena = 1 spots = 3
Time 79 : clk = 0 roll_ena = 1 spots = 3
Time 80 : clk = 1 roll_ena = 1 spots = 3
Time 81 : clk = 1 roll_ena = 0 spots = 3
Time 82 : clk = 1 roll_ena = 0 spots = 3
Time 83 : clk = 1 roll_ena = 0 spots = 3
Time 84 : clk = 1 roll_ena = 0 spots = 3
Time 85 : clk = 0 roll_ena = 0 spots = 3
Time 86 : clk = 0 roll_ena = 0 spots = 3
Time 87 : clk = 0 roll_ena = 0 spots = 3
Time 88 : clk = 0 roll_ena = 0 spots = 3
Time 89 : clk = 0 roll_ena = 0 spots = 3
Time 90 : clk = 1 roll_ena = 0 spots = 4
Time 91 : clk = 1 roll_ena = 1 spots = 4
Time 92 : clk = 1 roll_ena = 1 spots = 4
Time 93 : clk = 1 roll_ena = 1 spots = 4
Time 94 : clk = 1 roll_ena = 1 spots = 4
Time 95 : clk = 0 roll_ena = 1 spots = 4
Time 96 : clk = 0 roll_ena = 1 spots = 4
Time 97 : clk = 0 roll_ena = 1 spots = 4
Time 98 : clk = 0 roll_ena = 1 spots = 4
Time 99 : clk = 0 roll_ena = 1 spots = 4
Time 100 : clk = 1 roll_ena = 1 spots = 4
Time 101 : clk = 1 roll_ena = 0 spots = 4
Time 102 : clk = 1 roll_ena = 0 spots = 4
Time 103 : clk = 1 roll_ena = 0 spots = 4
Time 104 : clk = 1 roll_ena = 0 spots = 4
Time 105 : clk = 0 roll_ena = 0 spots = 4
Time 106 : clk = 0 roll_ena = 0 spots = 4
Time 107 : clk = 0 roll_ena = 0 spots = 4
Time 108 : clk = 0 roll_ena = 0 spots = 4
Time 109 : clk = 0 roll_ena = 0 spots = 4
Time 110 : clk = 1 roll_ena = 0 spots = 5
Time 111 : clk = 1 roll_ena = 1 spots = 5
Time 112 : clk = 1 roll_ena = 1 spots = 5
Time 113 : clk = 1 roll_ena = 1 spots = 5
Time 114 : clk = 1 roll_ena = 1 spots = 5
Time 115 : clk = 0 roll_ena = 1 spots = 5
Time 116 : clk = 0 roll_ena = 1 spots = 5
Time 117 : clk = 0 roll_ena = 1 spots = 5
Time 118 : clk = 0 roll_ena = 1 spots = 5
Time 119 : clk = 0 roll_ena = 1 spots = 5
Time 120 : clk = 1 roll_ena = 1 spots = 5
Time 121 : clk = 1 roll_ena = 0 spots = 5
Time 122 : clk = 1 roll_ena = 0 spots = 5
Time 123 : clk = 1 roll_ena = 0 spots = 5
Time 124 : clk = 1 roll_ena = 0 spots = 5
Time 125 : clk = 0 roll_ena = 0 spots = 5
Time 126 : clk = 0 roll_ena = 0 spots = 5
Time 127 : clk = 0 roll_ena = 0 spots = 5
Time 128 : clk = 0 roll_ena = 0 spots = 5
Time 129 : clk = 0 roll_ena = 0 spots = 5
Time 130 : clk = 1 roll_ena = 0 spots = 6
Time 131 : clk = 1 roll_ena = 1 spots = 6
Time 132 : clk = 1 roll_ena = 1 spots = 6
Time 133 : clk = 1 roll_ena = 1 spots = 6
Time 134 : clk = 1 roll_ena = 1 spots = 6
Time 135 : clk = 0 roll_ena = 1 spots = 6
Time 136 : clk = 0 roll_ena = 1 spots = 6
Time 137 : clk = 0 roll_ena = 1 spots = 6
Time 138 : clk = 0 roll_ena = 1 spots = 6
Time 139 : clk = 0 roll_ena = 1 spots = 6
Time 140 : clk = 1 roll_ena = 1 spots = 6
Time 141 : clk = 1 roll_ena = 0 spots = 6
Time 142 : clk = 1 roll_ena = 0 spots = 6
Time 143 : clk = 1 roll_ena = 0 spots = 6
Time 144 : clk = 1 roll_ena = 0 spots = 6
Time 145 : clk = 0 roll_ena = 0 spots = 6
Time 146 : clk = 0 roll_ena = 0 spots = 6
Time 147 : clk = 0 roll_ena = 0 spots = 6
Time 148 : clk = 0 roll_ena = 0 spots = 6
Time 149 : clk = 0 roll_ena = 0 spots = 6
Time 150 : clk = 1 roll_ena = 0 spots = 1
Time 151 : clk = 1 roll_ena = 1 spots = 1
Time 152 : clk = 1 roll_ena = 1 spots = 1
Time 153 : clk = 1 roll_ena = 1 spots = 1
Time 154 : clk = 1 roll_ena = 1 spots = 1
Time 155 : clk = 0 roll_ena = 1 spots = 1
Time 156 : clk = 0 roll_ena = 1 spots = 1
Time 157 : clk = 0 roll_ena = 1 spots = 1
Time 158 : clk = 0 roll_ena = 1 spots = 1
Time 159 : clk = 0 roll_ena = 1 spots = 1
Time 160 : clk = 1 roll_ena = 1 spots = 1
Time 161 : clk = 1 roll_ena = 0 spots = 1
Time 162 : clk = 1 roll_ena = 0 spots = 1
Time 163 : clk = 1 roll_ena = 0 spots = 1
Time 164 : clk = 1 roll_ena = 0 spots = 1
Time 165 : clk = 0 roll_ena = 0 spots = 1
Time 166 : clk = 0 roll_ena = 0 spots = 1
Time 167 : clk = 0 roll_ena = 0 spots = 1
Time 168 : clk = 0 roll_ena = 0 spots = 1
Time 169 : clk = 0 roll_ena = 0 spots = 1
Time 170 : clk = 1 roll_ena = 0 spots = 2
Time 171 : clk = 1 roll_ena = 1 spots = 2
Time 172 : clk = 1 roll_ena = 1 spots = 2
Time 173 : clk = 1 roll_ena = 1 spots = 2
Time 174 : clk = 1 roll_ena = 1 spots = 2
Time 175 : clk = 0 roll_ena = 1 spots = 2
Time 176 : clk = 0 roll_ena = 1 spots = 2
Time 177 : clk = 0 roll_ena = 1 spots = 2
Time 178 : clk = 0 roll_ena = 1 spots = 2
Time 179 : clk = 0 roll_ena = 1 spots = 2
Time 180 : clk = 1 roll_ena = 1 spots = 2
Time 181 : clk = 1 roll_ena = 0 spots = 2
Time 182 : clk = 1 roll_ena = 0 spots = 2
Time 183 : clk = 1 roll_ena = 0 spots = 2
Time 184 : clk = 1 roll_ena = 0 spots = 2
Time 185 : clk = 0 roll_ena = 0 spots = 2
Time 186 : clk = 0 roll_ena = 0 spots = 2
Time 187 : clk = 0 roll_ena = 0 spots = 2
Time 188 : clk = 0 roll_ena = 0 spots = 2
Time 189 : clk = 0 roll_ena = 0 spots = 2
Time 190 : clk = 1 roll_ena = 0 spots = 3
Time 191 : clk = 1 roll_ena = 1 spots = 3
Time 192 : clk = 1 roll_ena = 1 spots = 3
Time 193 : clk = 1 roll_ena = 1 spots = 3
Time 194 : clk = 1 roll_ena = 1 spots = 3
Time 195 : clk = 0 roll_ena = 1 spots = 3
Time 196 : clk = 0 roll_ena = 1 spots = 3
Time 197 : clk = 0 roll_ena = 1 spots = 3
Time 198 : clk = 0 roll_ena = 1 spots = 3
Time 199 : clk = 0 roll_ena = 1 spots = 3
Time 200 : clk = 1 roll_ena = 1 spots = 3
Time 201 : clk = 1 roll_ena = 0 spots = 3


(2011/05/23 dice_state_machine.v を修正したので、シミュレーション結果も修正しました)

シミュレーションができた。次は、obj_dirのファイルとモジュール内部の信号を見る方法を書いておこうと思う。

#C言語で勉強したので、coutよりもprintfの方が使いやすいので使用した。

Verilatorを試してみる2(C++モード2:モジュール内部信号の観測)”に続く。
  1. 2011年05月23日 05:15 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
http://marsee101.blog.fc2.com/tb.php/1807-851c5b89
この記事にトラックバックする(FC2ブログユーザー)