FC2カウンター FPGAの部屋 無償ツールで実践する「ハード・ソフト協調検証」をやってみる7(DMAの割り込み機能)
FC2ブログ

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

FPGAの部屋

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

無償ツールで実践する「ハード・ソフト協調検証」をやってみる7(DMAの割り込み機能)

さて、最後の”無償ツールで実践する「ハード・ソフト協調検証」(7) ―― DMAの割り込み機能を確かめられるようにする”をやってみようと思う。

avalon_cpuのポートにirq(リスト12)を追加して、割り込みタスク(リスト13)も追加した。export宣言も追加した。最終的にavalon_cpu.sv は下のようになった。

module avalon_cpu (
    input  wire        clk,
    input  wire        reset,
    output wire [31:0] avm_address,
    output wire [2:0]  avm_burstcount,
    input  wire [31:0] avm_readdata,
    output wire [31:0] avm_writedata,
    input  wire        avm_waitrequest,
    output wire        avm_write,
    output wire        avm_read,
    output wire [3:0]  avm_byteenable,
    input  wire        avm_readdatavalid,

    input  wire    [31:0] irq
);
    altera_avalon_mm_master_bfm #(
        .AV_ADDRESS_W             (32),
        .AV_SYMBOL_W              (8),
        .AV_NUMSYMBOLS            (4),
        .AV_BURSTCOUNT_W          (3),
        .USE_READ                 (1),
        .USE_WRITE                (1),
        .USE_ADDRESS              (1),
        .USE_BYTE_ENABLE          (1),
        .USE_BURSTCOUNT           (1),
        .USE_READ_DATA            (1),
        .USE_READ_DATA_VALID      (1),
        .USE_WRITE_DATA           (1),
        .USE_BEGIN_TRANSFER       (0),
        .USE_BEGIN_BURST_TRANSFER (0),
        .USE_WAIT_REQUEST         (1),
        .AV_BURST_LINEWRAP        (1),
        .AV_BURST_BNDR_ONLY       (1),
        .AV_MAX_PENDING_READS     (1),
        .AV_FIX_READ_LATENCY      (1)
    )
    cpu (
        .clk                    (clk),
        .reset                  (reset),
        .avm_address                (avm_address),
        .avm_burstcount         (avm_burstcount),
        .avm_readdata           (avm_readdata),
        .avm_writedata          (avm_writedata),
        .avm_waitrequest        (avm_waitrequest),
        .avm_write              (avm_write),
        .avm_read               (avm_read),
        .avm_byteenable         (avm_byteenable), 
        .avm_readdatavalid      (avm_readdatavalid),
        .avm_begintransfer      (),
        .avm_beginbursttransfer () 
    );
    
    `define BFM cpu

    `ifdef DPI_C
        // =========================================================================
        // DPI-C
        // =========================================================================

        `ifndef TEST_BFM
        import "DPI-C" context task dpi_main();
        `endif // TEST_BFM

        export "DPI-C" task bfm_write32;
        export "DPI-C" task bfm_read32;
        export "DPI-C" task bfm_write16;
        export "DPI-C" task bfm_read16;
        export "DPI-C" task bfm_write8;
        export "DPI-C" task bfm_read8;
        export "DPI-C" task bfm_nop;
        export "DPI-C" task wait_for_interrupt;
        
        // =========================================================================
        // Main
        // =========================================================================

        initial begin

        `BFM.init();

        `ifdef TEST_BFM
        test_bfm;
        `else
        dpi_main();
        `endif // TEST_BFM

        #100;
        $finish(2);
        end

        // =========================================================================
        // Task
        // =========================================================================

        import avalon_mm_pkg::*;

        task wait_for_interrupt( output int unsigned status );
            status = 0;
            wait( irq != 0 );
            status = irq;
        endtask : wait_for_interrupt
        
        task automatic bfm_run( Request_t request, int addr, int byte_enable, inout int data );
.......................
end module;


ポートを追加したので、SOPC Builderの設定を”無償ツールで実践する「ハード・ソフト協調検証」(7)” 図27~図31の様にやり直した
”"interrupt_receiver"のParameters部のAssociated addressable interfaceを「none」から「avalon_master」に変更します(図31).”の所は、avalon_masterではなく、avalon_master_0だった。
図31まで終了した状態のSOPC Builderの様子を下に示す。
hard_soft_25_100306.png

右側のペインにIRQが追加された。

次にDMA Controllerを追加する。同様に”無償ツールで実践する「ハード・ソフト協調検証」(7) ”の図32, 図33 の様にDMA Controller を追加中の図を下に示す。
hard_soft_26_100306.png

無償ツールで実践する「ハード・ソフト協調検証」(7)の図35のようにDMA Controllerを接続した。下図が接続後。
hard_soft_27_100306.png

ここでGenerateボタンでGenerateする。Generateは成功した。

●シミュレーションの準備を行う
ここでvlog の+defineオプションがでてきた。DPC_Cの他にDEBUGもdefineするみたいだ。私は、ライブラリ化の時に使ったsetup_sim_lib.do をsetup_sim_dma.do に名前を変更して、DEBUGのdefine を追加した。
setup_sim_dma.do の_vsim を下のように変更した。

alias _vsim {vsim -t ps +nowarnTFMPC -sv_root prog -sv_lib dpi_main_dma -L lpm_ver -L sgate_ver -L altera_mf_ver -L altgxb_ver -L stratixiigx_hssi_ver -L stratixgx_ver -L stratixgx_gxb_ver -L stratixiigx -L altera_ver -L stratixiii_ver -L stratixii_ver -L cycloneii_ver -L cycloneiii_ver -L stratixiv_hssi_ver -L arriaii_ver -L arriaii_pcie_hip_ver -L arriaii_hssi_ver -L stratixiv_pcie_hip_ver -L cycloneiv_pcie_hip_ver -L cycloneiv_hssi_ver -L hardcopyiv_pcie_hip_ver -L hardcopyiv_hssi_ver test_bench} } else {
alias _vsim {vsim -t ps +nowarnTFMPC -sv_root prog -sv_lib dpi_main_dma test_bench } }



●テスト・プログラムを用意する
リスト14に示されたテストプログラムをdpi_main_dma.c としてセーブした。たぶん、リスト14の前に #include "dpi_func.h" を付ける必要があるはずなので、それを1行目に追加した。

MSYSを立ち上げて、avalon_bfm/avalon_bfm_sim/prog にcd して、dpi_main_dma.c をコンパイルする。

gcc -c dpi_main_dma.c


そうしたら、DMA_READ_REGなどが定義されていないとしてエラー発生。当然そうなりますね?
hard_soft_28_100307.png

どうしようと思ったが、考えてみれば、図37にログがあるので、そこから推測できるはず。。。しかし、DMA Controller のマニュアルはどこにあるんだろう?HelpやAlteraのサイトを探してみたが良くわからなかったが、SOPC Builder のDMA Controller をクリックし、Editボタンをクリックすると出てくる設定ダイアログにDocumentaion ボタンが有った。これをクリックすると、データシートが出てきた。DMA Controllerのデータシートはこれ。7ページのTable 24–3. DMA Controller Register Mapを見るとレジスタのマップがわかる。それを下に転載する。
hard_soft_29_100307.png

これを元に定義値を推測して、dma_define.h を書いている。dma_define.h を下に示す。

// dma_define.h

#define    DMA_STATUS_REG    0x10000000
#define DMA_READ_REG    0x10000004
#define DMA_WRITE_REG    0x10000008
#define    DMA_LENGTH_REG    0x1000000c
#define    DMA_CONTROL_REG    0x10000018

// DMA_CONTROL_REGの値の定義
#define DMA_CONTROL_SOFTWARERESET    0x1000
#define DMA_CONTROL_QUADWORD         0x800    
#define DMA_CONTROL_DOUBLEWORD         0x400
#define DMA_CONTROL_WCON             0x200
#define DMA_CONTROL_RCON             0x100
#define    DMA_CONTROL_LEEN              0x80
#define DMA_CONTROL_WEEN              0x40
#define DMA_CONTROL_REEN              0x20
#define    DMA_CONTROL_I_EN              0x10
#define DMA_CONTROL_GO                   0x8
#define DMA_CONTROL_WORD               0x4
#define DMA_CONTROL_HW                   0x2
#define DMA_CONTROL_BYTE               0x1

// DMA_STATUS_REGの値の定義
#define DMA_STATUS_LEN    0x10
#define DMA_STATUS_WEOP     0x8
#define DMA_STATUS_REOP     0x4
#define DMA_STATUS_BUSY     0x2
#define DMA_STATUS_DONE     0x1


dpi_main_dma.c の最初に、

#include "dma_define.h"


を追加した。
gccでコンパイルすると成功した。dpi_main_dma.o が生成できた。

しまった。SystemVerilogコードをコンパイルするのを忘れてしまった。
ModelSim AE 6.5bを立ち上げて、avalon_bfm_sim.mpf をロードして、

do setup_sim_dma.do


を実行する。
hard_soft_30_100307.png

s


コマンドを実行する。

vsim -c -dpiexportobj prog/exportobj.obj test_bench


コマンドを実行する。

これでまたMSYSに戻って、

gcc -shared -o dpi_main_dma.dll dpi_mai_dma.o exportobj.obj \/c/altera/91/modelsim_ase/win32aloem/mtipli.dll


で、dpi_main_dma.dll を作る。

もう一度、ModelSim AE 6.5bに戻って、_vsim を実行する。
hard_soft_31_100307.png

シミュレーションがスタートするので、InstanceウインドウのsimタブでDUT -> avalon_cpu を選択すると、Objectウインドウに信号が表示されるので、waveウインドウのドラックアンドドロップして、RadixをHexadecimal とする。
hard_soft_32_100307.png

run -all


コマンドを実行した。うまく行ったみたいです。
hard_soft_33_100307.png

ログを下に示す。

#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: - Hello from altera_avalon_mm_master_bfm
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   $Revision: #2 $
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   $Date: 2009/08/28 $
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   AV_ADDRESS_W             = 32
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   AV_SYMBOL_W              = 8
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   AV_NUMSYMBOLS            = 4
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   AV_BURSTCOUNT_W          = 3
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   USE_READ                 = 1
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   USE_WRITE                = 1
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   USE_ADDRESS              = 1
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   USE_BYTE_ENABLE          = 1
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   USE_BURSTCOUNT           = 1
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   USE_READ_DATA            = 1
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   USE_READ_DATA_VALID      = 1
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   USE_WRITE_DATA           = 1
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   USE_BEGIN_TRANSFER       = 0
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   USE_BEGIN_BURST_TRANSFER = 0
#                    0: INFO: test_bench.DUT.the_avalon_cpu_0.avalon_cpu_0.cpu.hello: -   USE_WAIT_REQUEST         = 1
#                    0: INFO: ------------------------------------------------------------
# bfm_write32 : addr = 0x00000000, data = 0x12345678
# bfm_write32 : addr = 0x00000004, data = 0x12345678
# bfm_write32 : addr = 0x00000008, data = 0x12345678
# bfm_write32 : addr = 0x0000000c, data = 0x12345678
# bfm_write32 : addr = 0x00000010, data = 0x12345678
# bfm_write32 : addr = 0x00000014, data = 0x12345678
# bfm_write32 : addr = 0x00000018, data = 0x12345678
# bfm_write32 : addr = 0x0000001c, data = 0x12345678
# bfm_write32 : addr = 0x00000020, data = 0x12345678
# bfm_write32 : addr = 0x00000024, data = 0x12345678
# bfm_write32 : addr = 0x00000028, data = 0x12345678
# bfm_write32 : addr = 0x0000002c, data = 0x12345678
# bfm_write32 : addr = 0x00000030, data = 0x12345678
# bfm_write32 : addr = 0x00000034, data = 0x12345678
# bfm_write32 : addr = 0x00000038, data = 0x12345678
# bfm_write32 : addr = 0x0000003c, data = 0x12345678
# bfm_write32 : addr = 0x10000004, data = 0x00000000
# bfm_write32 : addr = 0x10000008, data = 0x00000800
# bfm_write32 : addr = 0x1000000c, data = 0x00000040
# bfm_write32 : addr = 0x10000018, data = 0x0000009c
# Interrput = 0x1
# bfm_read32  : addr = 0x10000000, data = 0x00000011
# bfm_write32 : addr = 0x10000000, data = 0x00000011
# bfm_read32  : addr = 0x00001000, data = 0x12345678
# bfm_read32  : addr = 0x00001004, data = 0x12345678
# bfm_read32  : addr = 0x00001008, data = 0x12345678
# bfm_read32  : addr = 0x0000100c, data = 0x12345678
# bfm_read32  : addr = 0x00001010, data = 0x12345678
# bfm_read32  : addr = 0x00001014, data = 0x12345678
# bfm_read32  : addr = 0x00001018, data = 0x12345678
# bfm_read32  : addr = 0x0000101c, data = 0x12345678
# bfm_read32  : addr = 0x00001020, data = 0x12345678
# bfm_read32  : addr = 0x00001024, data = 0x12345678
# bfm_read32  : addr = 0x00001028, data = 0x12345678
# bfm_read32  : addr = 0x0000102c, data = 0x12345678
# bfm_read32  : addr = 0x00001030, data = 0x12345678
# bfm_read32  : addr = 0x00001034, data = 0x12345678
# bfm_read32  : addr = 0x00001038, data = 0x12345678
# bfm_read32  : addr = 0x0000103c, data = 0x12345678
# ** Note: Data structure takes 7471320 bytes of memory
#          Process time 0.12 seconds
#          $finish    : ../avalon_bfm_sim/avalon_cpu.sv(88)
#    Time: 3490100 ps  Iteration: 0  Instance: /test_bench/DUT/the_avalon_cpu_0/avalon_cpu_0
# 1
# Break in Module avalon_cpu at ../avalon_bfm_sim/avalon_cpu.sv line 88


これで終了とする。
  1. 2010年03月07日 05:31 |
  2. SystemVerilog
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


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

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