FC2カウンター FPGAの部屋 MicroBlaze MCSをテストする5(Project Navigatorでシミュレーション編)
FC2ブログ

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

FPGAの部屋

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

MicroBlaze MCSをテストする5(Project Navigatorでシミュレーション編)

”MicroBlaze MCSをテストする4(SDK編2)”の続き。

MicroBlaze MCSでは、正規の手順でSDKを使ってソフトウェアを作るという手順とWebPACKでも出来るように、独自にMicroBlaze のクロスコンパイラをビルドして独自にソフトウェアを作るという手順の2つを試している。今回はその内の前者だ。

今回はProject Navigatorでの手順を説明する。前回のMicroBlaze MCSの設定からPITの設定のDefine Prescaler の設定をNoneからExternalに変更した。

・Project Navigator で論理合成を行う。
MB_MCS_53_120128.png

・ViewメニューからPanels -> TCL Consoleを選択して、TCL Consoleを表示する。

・TCL CosoleのCommand> 行に以下のTCLコマンドを入力した。このTCLスクリプトはBMMファイルのマージとツールのアップデートを行う。

source ipcore_dir/microblaze_mcs_setup.tcl


MB_MCS_54_120128.png

・Project Navigator のProcessesウインドウでGenerate Programming Fies をダブルクリックして、ビットファイルの生成を行う。

・TCL CosoleのCommand> 行に以下のTCLコマンドを入力した。このTCLスクリプトは、SDKのELFバイナリをビットファイルに入れたり、シミュレーションのためにメモリイメージを生成する。

microblaze_mcs_data2mem SDK/Atlys_LED_Test/Debug/Atlys_LED_Test.elf


MB_MCS_55_120128.png

・シミュレーションのためのメモリイメージが生成された。(手動のISimシミュレーションについては、”SMMのシミュレーション(NetGenとData2MEMを使用する)”を参照)
MB_MCS_71_120202.png

・テストベンチファイルを生成して、ISimでシミュレーションを行った。その結果、2usec手前で、LED_outが55になったので、MicroBlaze MCSが動作していることが確認できた。
MB_MCS_72_120202.png

・今度はビットファイルを実機にダウンロードしてみたが、動作しなかった。

・良くUCFファイルを見なおしてみると、clkのピンアサインが違っていた(面目ない!)。これを修正したら、LEDが点灯した。動作したようだが、カウントダウンしない。
MB_MCS_73_120202.png

・PIT1のCounter Register、0x80000044番地の値が常に0のようだ。プリスケーラのせいか?一度プリスケーラを削除してみようか?その前にソフトウェアのカウント値を10程度にして、シミュレーションをしてみる。現在は100MHzで1秒間隔でカウントダウンして欲しいので、100000000にしてある。

・やはりカウントは変わらず0だった。

・今度は、+1カウントとPIT1のCounter Registerの値を交互にGPO1に表示した。やはり、PIT1のCounter Registerの値は0のようだ。なぜだろうか?
MB_MCS_74_120202.png

2010/02/07 追記:Counter Registerの値は0だけど、PIT自体は動いているようです。PIT_InterruptとPIT_Toggle は動作しています。”MicroBlaze MCSをISE WebPACKから使用する3”参照)

現在のソフトウェアを下に貼っておく。

// 
// Atlys_LED_test.c
//
// AltysボードのLEDを1秒ごとに+1するソフトウェア
// 初めは割り込みを使わないで実行する
//

#define    GPIO1_ADDR            0x80000010
#define PIT1_PRELOAD_ADDR    0x80000040
#define PIT1_COUNTER_ADDR    0x80000044
#define PIT1_CONTROL_ADDR    0x80000048

unsigned int read_counter(){
    return(*(volatile unsigned int *)(PIT1_COUNTER_ADDR));
}

int main()
{
    unsigned int b_count = 0;
    unsigned int c_count = 0;
    unsigned int led = 0x55;
    
    *(volatile unsigned int *)(PIT1_PRELOAD_ADDR) = 10// 100MHzで1秒
    *(volatile unsigned int *)(PIT1_CONTROL_ADDR) = 0x3// Timer Enable, Auto load
    
    *(volatile unsigned int *)(GPIO1_ADDR) = led;
    
    while(1){
        c_count = read_counter();
        *(volatile unsigned int *)(GPIO1_ADDR) = c_count;
        if (c_count > b_count){    // 現在の値のほうが大きいのでオートロードした
            *(volatile unsigned int *)(GPIO1_ADDR) = led++;
        }
        *(volatile unsigned int *)(GPIO1_ADDR) = led++;
        b_count = c_count;
    }
}


トップのVerilogファイル。

module MicroBlaze_MCS_Test(
    input     wire clk,
    input    wire reset,
    output    wire [7:0] LED_out
    );
    
    wire PIT1_Interrupt;
    wire PIT1_Toggle;
    wire INTC_IRQ;
    
    assign reset_n = ! reset;
    
    MB_MCS mcs_0 (
      .Clk(clk), // input Clk
      .Reset(reset), // input Reset
      .PIT1_Enable(1'b1), // input PIT1_Enable
      .PIT1_Interrupt(PIT1_Interrupt), // output PIT1_Interrupt
      .PIT1_Toggle(PIT1_Toggle), // output PIT1_Toggle
      .GPO1(LED_out), // output [7 : 0] GPO1
      .INTC_IRQ(INTC_IRQ) // output INTC_IRQ
    );
endmodule


シミュレーション用テストベンチ。

`timescale 1ns / 1ps

module MicroBlaze_MCS_Test_tb;

    // Inputs
    reg clk;
    reg reset;

    // Outputs
    wire [7:0] LED_out;

    // Instantiate the Unit Under Test (UUT)
    MicroBlaze_MCS_Test uut (
        .clk(clk), 
        .reset(reset), 
        .LED_out(LED_out)
    );
    
    parameter PERIOD = 10; // 100MHz clock
    parameter real DUTY_CYCLE = 0.5;
    parameter OFFSET = 0;

    initial    // Clock process for clk
    begin
      clk = 1'b0;
      #OFFSET;
      forever begin
            clk = 1'b0;
            #(PERIOD-(PERIOD*DUTY_CYCLE)) clk = 1'b1;
            #(PERIOD*DUTY_CYCLE);
      end
    end
    
    initial begin
        // Initialize Inputs
        reset = 1'b1;

        // Wait 100 ns for global reset to finish
        #100;
        
        // Add stimulus here
        reset = 1'b0;

    end
      
endmodule


UCFファイル。

NET "LED_out[0]" LOC = U18;
NET "LED_out[1]" LOC = M14;
NET "LED_out[2]" LOC = N14;
NET "LED_out[3]" LOC = L14;
NET "LED_out[4]" LOC = M13;
NET "LED_out[5]" LOC = D4;
NET "LED_out[6]" LOC = P16;
NET "LED_out[7]" LOC = N12;
NET "clk" LOC = L15;
NET "reset" LOC = P3;
NET "LED_out[0]" IOSTANDARD = LVCMOS33;
NET "LED_out[1]" IOSTANDARD = LVCMOS33;
NET "LED_out[2]" IOSTANDARD = LVCMOS33;
NET "LED_out[3]" IOSTANDARD = LVCMOS33;
NET "LED_out[4]" IOSTANDARD = LVCMOS33;
NET "LED_out[5]" IOSTANDARD = LVCMOS33;
NET "LED_out[6]" IOSTANDARD = LVCMOS33;
NET "clk" IOSTANDARD = LVCMOS33;
NET "reset" IOSTANDARD = LVCMOS18;

NET "clk" TNM_NET = "clk";
TIMESPEC TS_sysclk = PERIOD "clk" 10 ns HIGH 50 %;


  1. 2012年02月02日 05:59 |
  2. MicroBlaze MCS
  3. | トラックバック:0
  4. | コメント:3

コメント

TCLスクリプト

comment
初めまして、良く拝見しています。
microblaze_mcs_setup.tclの説明が誤解を招くのではないかと思います。
このスクリプトはコマンドラインオプションを追加するのみで、
bmmファイルが更新されるのは配置配線を実行した結果だと思います。
  1. 2012/02/03(金) 19:28:43 |
  2. URL |
  3. 磯村 剛 #-
  4. [ 編集 ]

磯村さん、こんにちは。
少し書き換えました。bmmファイルは、???_bd.bmmに変換されて、メモリBRAMの絶対位置が決まるのは、Placeの時だと思います。(未確認)
  1. 2012/02/03(金) 21:04:45 |
  2. URL |
  3. marsee #f1oWVgn2
  4. [ 編集 ]

comment
返答があってうれしいです。スクリプトはオプションを追加するだけなのでCoreGenで変更する毎の実行は
必要ないと思います。実際RAMサイズの変更やXMDの追加でもスクリプトを実行しなくても問題ないです。
スクリプトの実行しなくてもオプションをセットするだけで少なくとも単一のCPUなら問題ないです。
Translate PropertiesのOther Ngdbuild Command Line Optionsに-bm "ipcore_dir/mb.bmm"
を追加すれば良いです。mb.bmmはCoreGenで生成した名前です。
  1. 2012/02/03(金) 23:16:22 |
  2. URL |
  3. 磯村 剛 #-
  4. [ 編集 ]

コメントの投稿


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

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