FC2カウンター FPGAの部屋 2009年04月16日
FC2ブログ

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

FPGAの部屋

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

QUCSを使ってみた

検索していたらQUCS(Quite Universal Circuit Simulator)が見つかった。日本語も対応しているし、GPLライセンスだし、回路シミュレータとしてなかなかよさそうだったので使ってみた。今回はWindowsをインストールしたが、Ubuntuでもパッケージマネージャーから探して、インストールすることができた。
まずはQucs projectのページ。VHDLシミュレータもVerilogシミュレータも統合して論理シミュレーションもできる感じ。スクリーンショットを見るといろんなことができそう。
日本のサイトでは山梨大学のQUCS入門ぐうたらの部屋 電子回路部Qucs(電子回路シュミレータ)によく書いてあった。
鳥取大学の電気電子工学実験Ⅰでは実験に使っているようだ。電気回路シミュレータQucs説明書としてPDFの詳細なマニュアルもある。
とりあえず、ぐうたらの部屋 電子回路部、Qucs(電子回路シュミレータ)のページに載っていたサンプルを入力してみた。サンプル回路はダウンロード出来たが、ツールになれるために自分で下のように積分回路(ローパスフィルタ)を入力してみた。
qucs_1_080415.png

しかし、載っていた波形のようにはならずに、下の様な波形になってしまった。
qucs_2_080415.png

ぐうたらの部屋 電子回路部、Qucs(電子回路シュミレータ)のページからサンプルファイルをダウンロードしてどこが違うか確かめてみると、自分で回路図を入力したものは、トランジット解析のプロパティのステップ数が11しかなかった。
qucs_3_080415.png

これを300に変えるとちゃんと波形が出てきた。
qucs_4_080415.png

ソース元部品を2kHzのAC電圧源に変更した時の、トランジェント解析とACシミュレーションの結果を下に示す。
qucs_5_080415.png

qucs_6_080415.png

なかなか面白そう。。。VHDLファイルやVerilogファイルを読ませるとポートを判別してシンボルを作ってくれる。

  1. 2009年04月16日 21:50 |
  2. EDAツールについて
  3. | トラックバック:0
  4. | コメント:4

Spartan3A Starter KitのDDR2 SDRAMコントローラIOテストモジュールのシミュレーション2

”Spartan3A Starter KitのDDR2 SDRAMコントローラIOテストモジュールのシミュレーション1”で、ddr2_dqが最初から0000を出力してしまっているが、これはZZZZのはずという不具合があったが、これはIOBUFのトライステート条件を入力するT入力の論理を間違えていたからだった。Tは0で出力、1でハイインピーダンスだった。したがってT入力に入力する信号を反転した。

    IOBUF IOBUF_DQ(
        .O(dq_data_to_io),
        .IO(io_pad),
        .I(to_io_pad),
        .T(~tri_out)
    );


ちなみにシミュレーション用のテストベンチの概略は下のように書いてある。

    task READ_DATA_SIG; // DDR2のリード信号を生成
        input [63:0] read_data;
        
        begin
            #1;
            read_timing = 1'b0;
            @(posedge clk);
            #1; // 明確にクロックの立ち上がりの後を宣言
            ddr2_dqs_node = 1'b0;
            @(posedge clk);
            #1;
            read_timing = 1'b1;
            ddr2_dqs_node = 1'b1;
            ddr2_dq_node = read_data[63:48];
            @(negedge clk);
            #1;
            ddr2_dqs_node = 1'b0;
            ddr2_dq_node = read_data[47:32];
            @(posedge clk);
            #1;
            ddr2_dqs_node = 1'b1;
            ddr2_dq_node = read_data[31:16];
            @(negedge clk);
            #1;
            ddr2_dqs_node = 1'b0;
            ddr2_dq_node = read_data[15:0];
            @(posedge clk);
            #1;
            read_timing = 1'b0;
            ddr2_dqs_node = 1'bz;
            ddr2_dq_node = {DDR2_DATA_WIDTH{1'bz}};
        end
    endtask
    
    assign ddr2_dqs = ddr2_dqs_node;
    assign ddr2_dq = ddr2_dq_node;    
    
    always @* begin // rdd_afifo_emptyのときに読みだす
        if (~rdd_afifo_empty)
            #100    rdd_afifo_rd_en <= 1'b1;
        else
            #100    rdd_afifo_rd_en <= 1'b0;
    end
        
    always begin // クロックの生成
       #(CLK_PERIOD/2)    clk = 1'b1 ;
       #(CLK_PERIOD/2)    clk = 1'b0 ;
    end
    
    initial begin // resetの動作
                reset = 1'b0;
        #1000    reset = 1'b1;
        #20000    reset = 1'b0;
    end
    
    initial begin
        ddr2_dq_node = {DDR2_DATA_WIDTH{1'bz}};
        ddr2_dqs_node = {DDR2_DQS_DM_WIDTH{1'bz}};
        read_timing = 1'b0;
        #1;
        @(posedge reset);
        #1;
        @(negedge reset); // リセット終了
        #1;
        @(posedge ddr2_sdram_cont_test_inst.dcm_locked); // DCMがロックするのを待つ
        #10000;
        READ_DATA_SIG(64'h123456789ABCDEF0);
        #10000;
        READ_DATA_SIG(64'h1122334455667788);
        #100000;
        $stop;
    end


DDR2 SDRAMのリード信号を生成するREAD_DATA_SIGというtaskを作って、一番下のinital文でリセットが終了して、DCMがロックするのを待って、READ_DATA_SIGを2度呼びだしている。こういうときにVerilog-HDLは下のインスタンスの信号を簡単に参照できるので便利だ。VHDLだと面倒なことをする必要がある。
これで再度、シミュレーションをしてみた。それを下の図に示す。今度はddr2_dqもZZZZとなって正常になった。しかし、FIFOの動作がおかしい。
spa3A_skit_io_sim_2_090415.png

まずは非同期FIFOのタイミングに問題がある。reset_dcmが下がってリセットが解除されているところまでに(ピンクの矢印部分)、rdd_afifo_fullが0になっていない。非同期リセットならばすぐに0にさがるはずなのだが。。。rdd_afifo_fullが0になるのは2回目のリードデータが来る時だ(緑の矢印)。その後、rdd_afifo_emptyが0になって、リードデータが来ていることがわかるが、データは1個だけしか読めない。上のテストベンチを読むとわかるが、rdd_afifo_emptyが0になったら即、rdd_afifo_rd_enを1にして非同期FIFOのデータを読み出すことになっている。
やはり、非同期FIFOのwr_clkにフリーランではない、DQSを入れているのがまずいのだろうか?ためしに内部使用クロックを入れてみることにする。そうしてみてシミュレーションしてみたのが、下の図。
spa3A_skit_io_sim_3_090415.png

緑色の矢印の位置で、rdd_afifo_fullが0になってリセットされている。やはり同期リセットのような気がする。rdd_afifo_doutを見るとデータが正常に出力されている。やはりフリーランクロックでないとダメ?
もう一度Core Generatorの設定を見てみると、非同期リセット固定のように見える。なぜだろうか?
spa3A_skit_io_sim_4_090415.png

次は、XilinxのVerilogコードを見てこの謎を解明してみようと思う。
  1. 2009年04月16日 05:52 |
  2. Spartan3A Starter Kit
  3. | トラックバック:0
  4. | コメント:0