FC2カウンター FPGAの部屋 MicroBlaze MCS

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

FPGAの部屋

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

MicroBlaze MCSをISE WebPACKから使用する6(割り込み)

今回は、また例によって、、”iso.enat.jp さんのブログ”の”MicroBlaze MCSで割り込みを使う”を参考にさせて頂いてやってみた。(microblaze_enable_interrupts とmicroblaze_disable_interrupts を引用させて頂いた)

結果は、うまく割り込みで動作した。mb-gcc のオプションが-O2 でも -O0 でも同様に割り込みで動作した。

Cソース (Atlys_LED_int.c) を下に貼っておく。

// 
// Atlys_LED_int.c
//
// AltysボードのLEDを1秒ごとに+1するソフトウェア
// FITの割り込みを使用する
//

#define    GPO1_ADDR            0x80000010
#define GPI1_ADDR            0x80000020

#define IRQ_ENABLE            0x80000038
#define IRQ_ACK                0x8000003C
#define    FIT1_INTERRUPT_BIT    0x80        // FIT1の割り込みビット位置

volatile int interrupt = 0;

//割り込み処理
void interrupt_handler()    __attribute__ ((interrupt_handler));
void interrupt_handler() {
    interrupt = 1;
    *(volatile unsigned int *)(IRQ_ACK) = FIT1_INTERRUPT_BIT;
}

//割り込み許可
void microblaze_enable_interrupts()

    __asm__(
    "mfs    r12, rmsr\n\t"        //Read the MSR register
    "ori    r12, r12, 2\n\t"    //Set the interrupt enable bit
    "mts    rmsr, r12\n\t"        //Save the MSR register
    );
}
//割り込み禁止
void microblaze_disable_interrupts()
{
    __asm__(
    "mfs    r12, rmsr\n\t"        //Read the MSR register
    "andi    r12, r12, ~2\n\t"    //Clear the interrupt enable bit
    "mts    rmsr, r12\n\t"        //Save the MSR register
    );
}

int main()
{
    unsigned int led = 0x55;
    
    *(volatile unsigned int *)(GPO1_ADDR) = led;
    
    microblaze_enable_interrupts();
    *(volatile unsigned int *)(IRQ_ENABLE) = FIT1_INTERRUPT_BIT;
    
    while(1){
        // FIT割り込み待ち
        interrupt = 0;
        while(interrupt==0);
        *(volatile unsigned int *)(GPO1_ADDR) = led++;
    }
}



Makefile を下に貼っておく。

TARGET=Atlys_LED_int.elf
TARGET_DEBUG=Atlys_LED_int_debug.elf
SRCDIR=./
OBJDIR=./

SRCS=            $(SRCDIR)Atlys_LED_int.c
OBJS=            $(OBJDIR)Atlys_LED_int.o
OBJS_DEBUG=        $(OBJDIR)Atlys_LED_int_debug.o

CC=mb-gcc
CFLAGS=-O2 -mlittle-endian -Wl,-Map=Atlys_LED_int.map
CFLAGS_DEBUG=-O0 -g -mlittle-endian -Wl,-Map=Atlys_LED_int_debug.map
LDFLAGS1=-Wl,-s

$(TARGET) : $(OBJS)
    $(CC) $(CFLAGS) $(LDFLAGS1) $(OBJS) -o $(OBJDIR)$(TARGET) $(LDFLAGS2)

$(OBJDIR)Atlys_LED_int.o: $(SRCDIR)Atlys_LED_int.c $(INCS)
    $(CC) $(CFLAGS) -c $< -o $@

clean:
    rm -f $(OBJDIR)*.elf $(OBJDIR)*.o $(OBJDIR)*.map 

debug: $(TARGET_DEBUG)

$(TARGET_DEBUG) : $(OBJS_DEBUG)
    $(CC) $(CFLAGS_DEBUG) $(OBJS_DEBUG) -o $(OBJDIR)$(TARGET_DEBUG) $(LDFLAGS2)

$(OBJDIR)Atlys_LED_int_debug.o: $(SRCDIR)Atlys_LED_int.c $(INCS)
    $(CC) $(CFLAGS_DEBUG) -c $< -o $@


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

MicroBlaze MCSをISE WebPACKから使用する5(gdb編)

MicroBlaze MCSをISE WebPACKから使用する4(XMD編)”の続き。

今回は、”iso.enat.jp さんのブログ”の”MicroBlaze MCS でgdbを使う”を参考にさせていただいて、ISE WebPACKでも使えるgdbでデバックしてみることにした。

最初に、デバック情報付きのELFファイルを作る必要がある。前回のMakefileでLDFLAGS1 の -Wl,-s は ld で全てのシンボル情報を出力ファイルから落すというオプションだった。これが付いているとmb-gcc で-g オプションを付けても、デバック情報が追加されない。ということで、Makefile を作りなおした。

TARGET=Atlys_LED_test.elf
TARGET_DEBUG=Atlys_LED_test_debug.elf
SRCDIR=./
OBJDIR=./

SRCS=            $(SRCDIR)Atlys_LED_test.c
OBJS=            $(OBJDIR)Atlys_LED_test.o
OBJS_DEBUG=        $(OBJDIR)Atlys_LED_test_debug.o

CC=mb-gcc
CFLAGS=-O2 -mlittle-endian -Wl,-Map=Atlys_LED_test.map
CFLAGS_DEBUG=-O0 -g -mlittle-endian -Wl,-Map=Atlys_LED_test_debug.map
LDFLAGS1=-Wl,-s

$(TARGET) : $(OBJS)
    $(CC) $(CFLAGS) $(LDFLAGS1) $(OBJS) -o $(OBJDIR)$(TARGET) $(LDFLAGS2)

$(OBJDIR)Atlys_LED_test.o: $(SRCDIR)Atlys_LED_test.c $(INCS)
    $(CC) $(CFLAGS) -c $< -o $@

clean:
    rm -f $(OBJDIR)*.elf $(OBJDIR)*.o $(OBJDIR)*.map 

debug: $(TARGET_DEBUG)

$(TARGET_DEBUG) : $(OBJS_DEBUG)
    $(CC) $(CFLAGS_DEBUG) $(OBJS_DEBUG) -o $(OBJDIR)$(TARGET_DEBUG) $(LDFLAGS2)

$(OBJDIR)Atlys_LED_test_debug.o: $(SRCDIR)Atlys_LED_test.c $(INCS)
    $(CC) $(CFLAGS_DEBUG) -c $< -o $@


(2012/02/10:修正)上のMakefileの CFLAGS_DEBUG=-O2 -g -mlittle-endian -Wl,-Map=Atlys_LED_test_debug.map から CFLAGS_DEBUG=-O0 -g -mlittle-endian -Wl,-Map=Atlys_LED_test_debug.map に修正しました。


これで、Cygwin を立ち上げて、make すると、今までと同じで、make debug するとAtlys_LED_test_debug.elf が出力される。
MB_MCS_90_120209.png


最初に、iMPACTでAtlys_LED_test.bit をダウンロードする。
(注)必ずその都度、できたELFファイルを、microblaze_mcs_data2mem TCLコマンドでビットファイルに入れておく。

次に、XMDを前回同様に立ち上げる。その手順をもう一度下に示す。

・コマンドプロンプトを立ち上げて、ISE13.4のインストール・フォルダに行って、setting32.bat (64ビットWindowsの方はsetting64.bat) を実行する。

・Atlys_LED_test.elf のあるフォルダに移動してXMDを起動する。
MB_MCS_84_120208.png

・MicroBlazeのMDMペリフェラルに、XilinxのUSBダウンロードケーブルで、USB2ポートで接続する。(connect mb mdm -cable type xilinx_platformusb port USB2) (追加:connect mb mdm のみでOKのようです)
MB_MCS_85_120208.png


次に、Cygwin上で、gdbを立ち上げる。

・”mb-gdb”コマンドを入力する。
MB_MCS_91_120209.png

・”load Atlys_LED_test_debug.elf"コマンドを入力したら、”You can't do that when your target is `None'”という表示が出た。

・”file Atlys_LED_test_debug.elf"コマンドを入力したら、elfファイルが読めたようだ。
MB_MCS_92_120209.png

・”list”コマンドを入力した。
MB_MCS_93_120209.png

・”b 22”コマンドを入力して、”*(volatile unsigned int *)(PIT1_PRELOAD_ADDR) = COUNT_VALUE; // 100MHzで1秒”でブレークする。(Cソースは、”MicroBlaze MCSをISE WebPACKから使用する3”の最後を参照のこと)
MB_MCS_94_120209.png

・”target remote localhost:1234 id 0”コマンドを入力して、XMDと接続した。id 0 を入れないとXMDとの接続ができなかった
MB_MCS_95_120209.png

・Cygwin側で”Ignoring packet error, continuing...”が出て、XMDで”Error: No Data on the Socket”のエラーが出たら、XMDでexit を入力して、XMDを終了する。
MB_MCS_96_120209.png
MB_MCS_97_120209.png

・XMDをもう一度立ち上げ、MicroBlazeのMDMペリフェラルに、XilinxのUSBダウンロードケーブルで、USB2ポートで接続する。(connect mb mdm -cable type xilinx_platformusb port USB2)

・もう一度、Cygwinで、”target remote localhost:1234 id 0”コマンドを入力して、XMDと接続する。

・Cygwin に”main () at Atlys_LED_test.c:28”と出て、正常にgdb が起動した。
MB_MCS_98_120209.png
MB_MCS_99_120209.png

GDBコマンドサイトを見ながらコマンドを入れていく。

・まずはp (print)コマンドで led 変数を見てみた。p/x にすると16進になる。(フリーランしてしまった時は、gdb側で止まらないので、XMDの方で stop コマンドを入力すると停止する)
MB_MCS_100_120209.png

・cont コマンドを入力して、次のブレークポイントまで進めた。次のブレークポイントは、現在の行なので、カウントが進んでいるはず。同様に、p (print)コマンドで led 変数を見てみたが、変化がなかった。もう一度、cont コマンドを入れて、led 変数を見てみたら変化している。ボードのLED表示も変化していた。
MB_MCS_101_120209.png

・ブレークポイントで止まるとXMDの方にも表示が出る。
MB_MCS_102_120209.png

・gdb で s や n を押すと1行進む。s はStep in で、n はStep overだ。
MB_MCS_103_120209.png

・最後に、Cygwin に q を、XMD に exit をいれると終了する。

エラーが出た時に、XMDを再起動すればうまくいくのを見つけるのが大変だった。半日、ブログを書くのが遅れてしまった。でも、無事にまとまってよかったと思う。
これで、ISE WebPACKのみでデバックも出来る。

(2010/02/10:追記)
mb-gcc で最初に -O2 オプションを入れないほうが良いとのご指摘を頂いた。確かにそうだと思うので、debug の方だけ、-O0 にしてやってみた。

オプティマイズされている弊害ではないか?という現象も見えていた。下の図で s コマンドで進んでいって30行から25行に戻るのはおかしい。28行に戻るべきだと思う。更に、”b_GPI1 = c_GPI1;”の行が抜けてしまった。これはコンパイラでオプティマイズされているからではないかと推測していた。
MB_MCS_103_120209.png

下にAtlys_LED_test.c のソースコードをもう一度貼っておく。

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

#define    GPO1_ADDR            0x80000010
#define GPI1_ADDR            0x80000020
#define PIT1_PRELOAD_ADDR    0x80000040
#define PIT1_COUNTER_ADDR    0x80000044
#define PIT1_CONTROL_ADDR    0x80000048

#define COUNT_VALUE            100

int main()
{
    unsigned int b_GPI1 = 0;
    unsigned int c_GPI1 = 0;
    unsigned int led = 0x55;
    
    *(volatile unsigned int *)(PIT1_PRELOAD_ADDR) = COUNT_VALUE; // 100MHzで1秒
    *(volatile unsigned int *)(PIT1_CONTROL_ADDR) = 0x3// Timer Enable, Auto Reload
    
    *(volatile unsigned int *)(GPO1_ADDR) = led;
    
    while(1){
        c_GPI1 = 0x2 & (*(volatile unsigned int *)(GPI1_ADDR));
        if (c_GPI1 != b_GPI1){
            *(volatile unsigned int *)(GPO1_ADDR) = led++;
        }
        b_GPI1 = c_GPI1;
    }
}



最初に、-O2 の場合と、-O0 の場合のAtlys_LED_test_debug.elf の大きさの差だが、どちらも9,357バイトで差がなかった。差分をとって見ると違っているようだ。

実際にmb-gdb を起動してステップ実行してみると、確実にCソースの行で停止した。下図に示す。
MB_MCS_104_120209.png

やはり、磯村さんが指摘されたように、mb-gcc の -O オプションは、少なくともデバック時は -O0 の方が良いようだ。上のMakefile を修正しました。
  1. 2012年02月09日 20:47 |
  2. MicroBlaze MCS
  3. | トラックバック:0
  4. | コメント:4

MicroBlaze MCSをISE WebPACKから使用する4(XMD編)

@Vengineerさんから教えていただいた”iso.enat.jp さんのブログ”の”MicroBlaze MCS でXMDを使う”でXMDの使い方が載っていた。許可を頂いたので、自分でもやってみることにした。なお、”iso.enat.jp さんのブログ”は、MicroBlaze MCSについて詳しく書いてあって、とてもためになるブログだと思う。ぜひ、ご一読されることをお勧めする。


XMDのコマンドについては、”Embedded System Tools Reference Manual UG111 (v13.4) January 18, 2012”の135ページからの”Xilinx Microprocessor Debugger (XMD)”を参照した。

(2011/02/09:追加)最初に、iMPACTで、ビットファイルをFPGAボードにダウンロードする必要があります。

・まずはコマンドプロンプトを立ち上げて、ISE13.4のインストール・フォルダに行って、setting32.bat (64ビットWindowsの方はsetting64.bat) を実行する。

・Atlys_LED_test.elf のあるフォルダに移動してXMDを起動する。
MB_MCS_84_120208.png

・MicroBlazeのMDMペリフェラルに、XilinxのUSBダウンロードケーブルで、USB2ポートで接続する。(connect mb mdm -cable type xilinx_platformusb port USB2) (追加:connect mb mdm のみでOKのようです)
MB_MCS_85_120208.png

・Atlys_LED_test.elf をダウンロードする。
MB_MCS_86_120208.png

・run するとAtlys_LED_test.elf が動作した。

・mrd 0x80000044 でPITのカウント・レジスタの値を確認しようとしたら、エラーだった。ラン状態ではみえないようだ。

・stop して、mrd 0x80000044 と0であるのが見えた。

・exit した。
MB_MCS_87_120208.png
  1. 2012年02月08日 05:23 |
  2. MicroBlaze MCS
  3. | トラックバック:0
  4. | コメント:0

MicroBlaze MCSをISE WebPACKから使用する3

今回は前回までと異なり、ISE12.4にインストールされてるmb-gcc を使ってMicroBlaze のソフトウェアをコンパイルする。cygwinからmb-gccを起動してMicroBlaze MCSを動作することができた。
ISEのgccソフトウェアをコピーして使っている。”カスタム設計の MicroBlaze”さんか”ISE WebPACKでも使用できるMicroBlazeコアとGCCコンパイラ”辺りを参照。

ポイントは mb-gcc のオプションに -mlittle-endian を付けることだった。ビッグエンディアンだと思っていたのだが、リトルエンディアンだったのかな?AXI4はリトルエンディアンと教えてもらった。Spartan-6なので、AXI4バスでリトルエンディアンなのか?
LogiCORE IP MicroBlaze Micro Controller System (v1.0) の21ページ Table 6: Internal MicroBlaze Parameters Settings によると、C_ENDIANNESSパラメータはデフォルト1で、Select endianness (1 = Little endian)だそうだ。ビッグエンディアンにも出来るということだろう。C_I_AXIはデフォルト0でPLBバスのようだ)

・Cygwinでの実行例。Makefile は、”ひでみのアイデア帳”のMakefileを参考にさせていただいた。
MB_MCS_79_120206.png

(追加)Makefile を貼っておきます。

# PROJECT: Build New MicroBlaze
# ----------------------------------------------------------------------
#
# Copyright (C) 2011-2012 H.Ishihara, http://www.aquaxis.com/
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# For further information please contact.
#   http://www.aquaxis.com/
#   info(at)aquaxis.com or hidemi(at)sweetcafe.jp

TARGET=Atlys_LED_test.elf
SRCDIR=./
OBJDIR=./

SRCS=    $(SRCDIR)Atlys_LED_test.c
OBJS=    $(OBJDIR)Atlys_LED_test.o

CC=mb-gcc
CFLAGS=-O2 -mlittle-endian -Wl,-Map=Atlys_LED_test.map
LDFLAGS1=-Wl,-s

$(TARGET) : $(OBJS)
    $(CC) $(CFLAGS) $(LDFLAGS1) $(OBJS) -o $(OBJDIR)$(TARGET) $(LDFLAGS2)

$(OBJDIR)Atlys_LED_test.o: $(SRCDIR)Atlys_LED_test.c $(INCS)
    $(CC) $(CFLAGS) -c $< -o $@

clean:
    rm -f Atlys_LED_test.elf $(OBJDIR)*.o Atlys_LED_test.map


・Atlys_LED_test.elf が出来ていた。
MB_MCS_80_120206.png

・Atlys_LED_test.elf を MB_MCS_led_test2フォルダの下にコピーして、Project Navigator のTCL ConsoleタブのCommand> で”microblaze_mcs_data2mem Atlys_LED_Test.elf”を実行する。
MB_MCS_82_120206.png

・これでISimを起動して、シミュレーションを行うとLED_out[7:0] の途中で 55 に変化したので、動作している。前回のシミュレーション結果と異なるのは、FITのカウント値に100000000をセットしてあるからだ。
MB_MCS_81_120206.png

・ビットファイルをAtlysにダウンロードしたら、LED+1が表示された。。。成功。。。

(2012/02/07:追加)
PITのPIT_InterruptとPIT_Toggleも動いていました。カウンタの値は読めないようです。
MB_MCS_83_120207.png

この時のソフトウェアのAltys_LED_Test.cを下に貼っておきます。

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

#define    GPO1_ADDR            0x80000010
#define GPI1_ADDR            0x80000020
#define PIT1_PRELOAD_ADDR    0x80000040
#define PIT1_COUNTER_ADDR    0x80000044
#define PIT1_CONTROL_ADDR    0x80000048

#define COUNT_VALUE            100

int main()
{
    unsigned int b_GPI1 = 0;
    unsigned int c_GPI1 = 0;
    unsigned int led = 0x55;
    
    *(volatile unsigned int *)(PIT1_PRELOAD_ADDR) = COUNT_VALUE; // 100MHzで1秒
    *(volatile unsigned int *)(PIT1_CONTROL_ADDR) = 0x3// Timer Enable, Auto Reload
    
    *(volatile unsigned int *)(GPO1_ADDR) = led;
    
    while(1){
        c_GPI1 = 0x2 & (*(volatile unsigned int *)(GPI1_ADDR));
        if (c_GPI1 != b_GPI1){
            *(volatile unsigned int *)(GPO1_ADDR) = led++;
        }
        b_GPI1 = c_GPI1;
    }
}


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

MicroBlaze MCSをテストする6(FITを使用する)

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

前回、GPOは動いているということがわかった。PITはその後のシミュレーションでも動作させることができなかった。
そこで、FITを使用することにした。今回もProject Navigator 13.4 でテストを行った。

・MicroBlaze MCSのIPをダブルクリックして、設定用のダイアログを出して、FITタブをクリックする。Use Timerをチェックして、Number of Clocks Between Strobes をシミュレーションのために100をセットする。Generate Interruptにチェックを入れた。
MB_MCS_76_120204.png

・これでもう一度、MicroBlaze MCSを生成した。結構長い時間が掛かる。30分くらいかかる感じ?

・FITが入っていたので、トップのVerilogファイル (MicroBlaze_MCS_Test.v) を書き換えた。下にソースを示す。

module MicroBlaze_MCS_Test(
    input     wire clk,
    input    wire reset,
//     input    wire UART_Rx,
//     output    wire UART_Tx,
    output    wire [7:0] LED_out
    );
    
    wire PIT1_Interrupt;
    wire PIT1_Toggle;
    wire INTC_IRQ;
     wire [7:0]    GPI1;
     wire FIT1_Interrupt;
     wire FIT1_Toggle;
    
    assign GPI1 = {6'd0, FIT1_Toggle, PIT1_Toggle};
    
    MB_MCS mcs_0 (
      .Clk(clk), // input Clk
      .Reset(reset), // input Reset
//        .UART_Rx(UART_Rx), // input UART_Rx
//        .UART_Tx(UART_Tx), // output UART_Tx
      .FIT1_Interrupt(FIT1_Interrupt), // output FIT1_Interrupt
      .FIT1_Toggle(FIT1_Toggle), // output FIT1_Toggle
      .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
        .GPI1(GPI1), // input [7 : 0] GPI1
      .INTC_IRQ(INTC_IRQ) // output INTC_IRQ
    );
endmodule


・これで、インプリメントを行った。なお、”source ipcore_dir/microblaze_mcs_setup.tcl”は、BMMファイルのマージとngdbuild "-bm" option の付加を行うようだ。今回のBMMファイルは1つだけなので、最初に一回やれば良いようだ。(コメントで教えて頂きました)ただ、MicroBlaze MCS IPを2つ入れていて、少なくともその内の1つの内蔵のRAM領域を変更した場合には(8Kバイトから16Kバイトとか)、BMMファイルを再度マージするために、もう一度、実行する必要があると思う。

#インプリメント後のFF使用数は728 out of 54,576、LUT使用数は944 out of 27,288、RAMB16BWERs使用数は4 out of 116だった。

・”microblaze_mcs_data2mem SDK/Atlys_LED_Test/Debug/Atlys_LED_Test.elf”を実行して、ソフトウェアをビットファイルやシミュレーション用の記述に入れた。

・ISimでシミュレーションを行った。その際のソフトウェアを下に示す。GPI1の2ビット目の反転を見てLED+1するソフトウェアだ。GPI1の2ビット目はFIT1_Toggle だ。

#define    GPO1_ADDR            0x80000010
#define GPI1_ADDR            0x80000020
#define COUNT_VALUE            100

int main()
{
    unsigned int b_GPI1 = 0;
    unsigned int c_GPI1 = 0;
    unsigned int led = 0x55;
    
    *(volatile unsigned int *)(GPO1_ADDR) = led;
    
    while(1){
        c_GPI1 = 0x2 & (*(volatile unsigned int *)(GPI1_ADDR));
        if (c_GPI1 != b_GPI1){
            *(volatile unsigned int *)(GPO1_ADDR) = led++;
        }
        b_GPI1 = c_GPI1;
    }
}


・ISimのシミュレーション結果を下に示す。FITは動作している。
MB_MCS_78_120205.png

・今度は実機でLEDの動作を見るために、正規の状態にMicroBlaze MCSの設定を戻した。MicroBlaze MCSのIPをダブルクリックして、設定用のダイアログを出して、FITタブをクリックする。Number of Clocks Between Strobesに100000000をセットした。
MB_MCS_77_120204.png

すると、LEDが1秒ごとに+1されて動作した。やっと動いた。。。それにしてもPITは動かないのだろうか?どなたかPITが動いた方がいらしたらお知らせ下さい。よろしくお願いします。

(2011/02/05:追記)どうやら、カウンタの値はリードできないけれど、トグル出力と割り込み出力は皆さん、出ているようです。もう一度確かめてみます。。
  1. 2012年02月05日 05:20 |
  2. MicroBlaze MCS
  3. | トラックバック:0
  4. | コメント:4

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

MicroBlaze MCSをISE WebPACKから使用する2

MicroBlaze MCSをISE WebPACKから使用する1”の続き。

ひでみのアイデア帳(SweetCafe)さんの”MicroBlaze MCSで遊ぶ手順”の記事の通りにMicroBlaze MCSを試してみようと思う。

・まずは、生成してあったMicroBlaze MCS IPを記事の指定通りに変更する。
MB_MCS_64_120201.png

・”mb_mcsのスクリプトをgithubにアップ”の記事のgithubからaquaxis-aquaxis-58dbd58.zip をダウンロードした。

・適当なところに解凍した。

・ipcore_dirフォルダの下からMB_MCS.v をコピーして、aquaxis-aquaxis-58dbd58\MicroBlaze\MicroBlazeMCS フォルダにコピーした。

・MB_MCS.v を小文字のmb_mcs.v に変更した。
MB_MCS_65_120201.png

・私のWindows XPにはActivePerlが入っているので、make_mb_mcs.plをダブルクリックした。

・mb_mcs_new.v, mb_mcs_ram.bmm, mb_mcs_ram.v が生成された。
MB_MCS_66_120201.png

・”MicroBlaze MCSをISE WebPACKから使用する1”で生成したHelloWorld をHelloWorld.elf と名前を変更してコピーした。

・cygwin を起動して、make を実行したが、glbl.v がないと言われてエラーだった。ここは変更する必要がある。
MB_MCS_67_120201.png

・glbl.v をコピーしてきて、tb_mb_mcs.prj のglbl.v のパスをカレントフォルダに変更した。

・もういちどmake した。mb_mcsがUNKNOWN moduleになってしまった。
MB_MCS_68_120201.png

・今度は、コマンドプロンプトでやってみる。コマンドプロンプトを立ち上げて、Xilinx\13.4\ISE_DSフォルダのsettings32.bat を実行する。

・aquaxis-aquaxis-58dbd58\MicroBlaze\MicroBlazeMCS フォルダに移動して、”fuse -incremental -lib unisims_ver -lib unimacro_ver -lib xilinxcorelib_ver -o tb_mb_mcs -prj tb_mb_mcs.prj work.tb_mb_mcs work.glbl”を実行したが、同様のエラーだった。

・そういえば、MB_MCB.v からmb_mcb.v に変更した時に、ファイル内のmodule名などのMB_MCS をmb_mcs に変更した。

・もう一度、make_mb_mcs.pl を実行した。これで、mb_mcs_new.v に正しく、mb_mcs.vのコードが反映されたようだ。

・Cygwinでmake を実行した。成功したようだ。
MB_MCS_69_120201.png

・tb_mb_mcs.exe ができたので、これをCygwinで実行したがISimのバージョンが古かった。setting32.bat を実行してあるコマンドプロンプトで -gui オプション付きで実行した。

・ISimが起動した。mb_mcsの信号線をWaveウインドウに追加して、100 msecシミュレーションすると、動いているようです。
MB_MCS_70_120201.png

HelloWorldのHだけConsole に表示されている。

今度は、MicroBlaze MCSのSDKを使う手順をシミュレーションしてなかったので、シミュレーションを試みようと思う。
  1. 2012年02月01日 05:46 |
  2. MicroBlaze MCS
  3. | トラックバック:0
  4. | コメント:0
»