FC2カウンター FPGAの部屋 Verilatorを試してみる8(SystemCモード4:CharDispCtrlerプロジェクト)
FC2ブログ

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

FPGAの部屋

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

Verilatorを試してみる8(SystemCモード4:CharDispCtrlerプロジェクト)

今度は、キャラクタ・ディスプレイ・コントローラ(CharDispCtrler.v) をVerilatorでシミュレーションしてみることにした。
"キャラクタ・ディスプレイ・コントローラ"、”キャラクタ・ディスプレイ・コントローラの構成”を参照のこと。

ここでの問題は、char_gen_rom.v でXilinxのプリミティブのRAMB16_S9とframe_buffer.v で同じくRAMB16_S2_S2を使用していることだ。果たしてXilinx社製のプリミティブがVerilatorでシミュレーション出来るかが問題だと思った。
Webで検索してみると、Verilatorのフォーラムの”Simulating Xilinx Projects”を発見して、この通りにやってみることにした。(結論としてはうまくいきませんでした)

まずは、Xilinx社のプリミティブのソースのうちのRAMB16_S9.v, RAMB16_S2_S2.v, glbl.v を現在のフォルダにコピーした。(もうすでにCharDispCtrler_tb_sc.cppを作成してある)
Verilator_24_110602.png

SystemCのテストベンチ、CharDispCtrler_tb_sc.cppを作成した。CharDispCtrler_tb_sc.cppを下に示す。

// CharDispCtrler_tb_sc.cpp

#include "VCharDispCtrler.h"
#include "verilated_vcd_sc.h"

int sc_main(int argc, char **argv) {

    Verilated::commandArgs(argc, argv);   // Remember args

    sc_clock clk ("clk"40, SC_NS);
    sc_signal<bool> reset;
    sc_signal<uint32_t> processor_addr;
    sc_signal<uint32_t> processor_din;
    sc_signal<bool> processor_we;
    sc_signal<bool> VGA_RED, VGA_GREEN, VGA_BLUE;
    sc_signal<bool> VGA_HSYNC, VGA_VSYNC;
    int clk_count;
    
    VCharDispCtrler *top;
    
    top = new VCharDispCtrler("top");
    
    top->clk(clk);
    top->reset(reset);
    top->processor_addr(processor_addr);
    top->processor_din(processor_din);
    top->processor_we(processor_we);
    top->VGA_RED(VGA_RED);
    top->VGA_GREEN(VGA_GREEN);
    top->VGA_BLUE(VGA_BLUE);
    top->VGA_HSYNC(VGA_HSYNC);
    top->VGA_VSYNC(VGA_VSYNC);
    
    Verilated::traceEverOn(true);
    VerilatedVcdC* tfp = new VerilatedVcdC;
    top->trace (tfp, 99);
    tfp->open ("simx_sc.vcd");
    
    processor_addr = 0;
    processor_din = 0;
    processor_we = 0;
    reset = 1;
    
    sc_start(45, SC_NS);
    reset = 0;
    
    sc_start(160, SC_NS);
    processor_din = 0x3B0;    // RGB=111(最上位), キャラクタ0
    
    sc_start(40, SC_NS);
    processor_we = 1;
    processor_addr = 80;    // 画面の2行1列目のキャラクタのアドレス
    
    sc_start(40, SC_NS);
    processor_we = 0;
    processor_din = 0x3C1;    // RGB=111(最上位), キャラクタA
    
    sc_start(40, SC_NS);
    processor_we = 1;
    processor_addr = 81;    // 画面の2行2列目のキャラクタのアドレス
    
    sc_start(40, SC_NS);
    processor_we = 0;
    
    sc_start(20000000, SC_NS);
    
    tfp->close();
    delete top;
    
    exit(0);        // シミュレーション終了
}    


最初に、とりあえずそのままの状態でコンパイルを試みた。コマンドを下に示す。

verilator -Wno-lint -sc --trace CharDispCtrler.v --exe CharDispCtrler_tb_sc.cpp


そうすると予想通りエラー。
Verilator_23_110601.png

Verilatorのフォーラムの”Simulating Xilinx Projects”に従って、RAMB16_S9.v, RAMB16_S2_S2.v, glbl.vを書き換えてみることにした。

1.glbl.vをWebサイトからダウンロードしたファイルに交換(これでglbl.vは終了)
2.module文の下に、// verilator tracing_offを挿入した
3.tri0 GSRを含むラインを消去した
4.GSRをglbl.GSRに置換した
5.initial文内の<= を= に置換した
6.遅延を表す#100 などを消去した
7.char_gen_rom.v, frame_buffer.v にglbl glbl;文を追加した


上記の対策を取ってみたが、やはりエラーが出る。可能なかぎり対策をとてみたがInternal Errorが出てしまった。
Verilator_25_110602.png

ここで諦めることにする。Verilatorのフォーラムの”Simulating Xilinx Projects”でもBlock RAMの変換は成功していないそうだ。残念。。。

Verilatorは、Verilogの論理合成記述のみが変換可能なのが残念だ。XilinxのIPは自分で書きなおさないと使用することが出来ないようだ。
  1. 2011年06月02日 05:26 |
  2. シミュレーション
  3. | トラックバック:0
  4. | コメント:4

コメント

verilator の高速化鍵は、サイクルベースにあります。(2値化は、数%程度の寄与でしょう。)スタティックなスケジューリング化で、イベント処理を省くやり方です。例えば、
always @(posedge clk) begin
couter<=counter+1;
end
等、合成可能なRTLモデルというのは、考えてみると時間の記述は不要で、次のようにクロックなしのスタッテック記述にモデルを単純化することが出来ます。NBAも記述順序で不要にします。
while(1){
時刻が進んだ
counter=counter+1
}
変換不能なのは、ダイナミックなスケジューリングを要する記述や、ダイナミックなバスファイト解決演算、マルチクロックドメインです。これらは、コンパイル時には、予測不能なのでイベントドリブンでなければ処理できません。

かってVTOCのように商用のサイクルベースシミュレータが喧伝された時期もありましが、現在のモダンなシミュレータ(NC/VCS等)では、内部にサイクルベースとイベントベースをミックスして最適化処理していますので、あまり意味がなくなったように思います。SystemC自体は、イベントドリブンシミュレータですので、頑張れば変換可能かもしれませんが..


  1. 2011/06/02(木) 06:34:47 |
  2. URL |
  3. たっく #-
  4. [ 編集 ]

たっくさん、こんにちは。解説ありがとうございます。
サイクルベースでも、回路の評価の順番で値が合わなくなった気がします。何度か評価するのかな?
サイクルベースだと、DCMの実装も難しいですね。計算精度チェック用にアルゴリズム実装部分だけを抜き出してVerilatorでやらせてみようか?と思っています。
今のところ仕事ではVHDLが多いですが、だんだんとVerilogに移行しようと思っています。今のところは混在なので、ISimでシミュレーションしています。
  1. 2011/06/02(木) 13:05:05 |
  2. URL |
  3. marsee #f1oWVgn2
  4. [ 編集 ]

>何度か評価するのかな
はい、コンパイル時にループがあると判定されたところは、(当然ながら、)スタティックスケジュールできません。なので適当にループをぶった切って、回路が安定するまでループします。結果その部分は、イベントドリブンに似た処理になります。ループの有無判定はグラフ理論を使っています。
>DCM
私自身は、Verilatorで動かしたことはないので断言はできないのですが、難しいと思います。 Verilatorが得意なのは、単一クロックの合成可能なRTLモデルだと思います。(CPUモデルとか) 
  1. 2011/06/02(木) 19:52:34 |
  2. URL |
  3. たっく #-
  4. [ 編集 ]

了解しました。解説ありがとうございました。
>ループの有無判定はグラフ理論を使っています。
そうなんですね。昔、Kue-Chip2のエミュレータを作ったときは、memcmpを使って全部比較して安定するまで繰り返していました。恥ずかしいですが、その時に書いたものです。
http://www.tulips.tsukuba.ac.jp/limedio/dlam/M36/M369221/3.pdf

やはり、DCMを実装するのは、難しいですね。やるとすれば、SC_NSだったら、例えば10ns でクロックが1周期だとします。
その時は、5クロックずらして変化させると180度位相がずれますね。そういうのを利用するしかないのかな?と思います。つまりテストベンチと一体になるような感じなのかな?と思います。
  1. 2011/06/02(木) 20:48:48 |
  2. URL |
  3. marsee #aouVx48I
  4. [ 編集 ]

コメントの投稿


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

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