Kintex-7にMicroblazeを載せる のバックアップ(No.4)

更新


公開メモ

概要

WebPack 版の Vivado を使って Kintex-7 に MicroBlaze を載せ、UART 経由で PC と通信したい。

最近は無償の WebPack 版でも MicroBlaze IP を使えるようになっているのだけれど、 実はソフト開発に使う SDK は WebPack 版では MicroBlaze をサポートしないことを後から知った。

以下の手順で自ら MicroBlaze 用のコンパイラを用意すれば、 ちょっと面倒ながらも MicroBlaze を使ったベアメタルシステムの開発が可能なことが分かったので まとめておく。

設計方針

FPGA ボードは以下を装備しているものとする。

  • Kintex-7 FPGA
  • LED が2つ
  • スイッチが2つ
  • USB-Serial 変換モジュール

MicroBlaze のプログラムから 自由に LED を光らせたり、スイッチの状態を読んだり、 USB 経由でホスト PC と通信をしたり、 を可能にしたい。

OS を走らせるようなたいそうなことを考えているわけではなく、 あくまでベアメタルのマイクロコントローラ的な使い方を想定している。

以下の方法でOSを走らせるのはたぶんかなり大変だと思われる。

Vivado での作業

プロジェクトの作成

new-project.png [File]-[Project]-[New]

project-name.png 適当に名前を付ける

project-type.png RTL プロジェクトを選ぶ

project-add-source.png Block Design をトップにするのでここでは何もしない

project-add-xdc.png 制約ファイルを1つ作っておく

project-select-kintex.png 対象とする FPGA を選択する

project-finish.png 以上でプロジェクト作成できた

ブロック図の作成

こちらが完成形:

block-diagram-final.png

  • 入力端子として
    • クロック(差動入力)
    • リセット(負論理)
    • スイッチ2つ
    • UART-RX (USB-Serial 変換器の TX 端子と繋ぐ)
  • 出力端子として
    • LED 2つ
    • UART-TX (USB-Serial 変換器の RX 端子と繋ぐ)

を持っており、それらが適切に IP に繋がっている。

以下が手順:

create-block-design.png Block Design を新規作成

block-design-name.png プロジェクトに1つしか作らないなら名前は適当でも

add-microblaze.png Add IP ボタンから MicroBlaze を追加する

add-uart.png 同様にシリアル通信用の UART モジュール を追加

add-gpio.png 同様に LED やスイッチの制御のための GPIO モジュール を追加

regenerate-layout.png Regenerate Layout ボタンで配置を調整

上部の Run Block Automation を押し、MicroBlaze についていろいろ設定する

block-automation-microblaze.png

OK すると以下が自動的に追加される。

  • クロックジェネレータ (Clocking Wizard)
  • リセットコントローラ (Processor System Reset)
  • ローカルメモリ (local memory)
  • AXI ハブ (AXI Interconnect)
  • 割り込みコントローラ (AXI Interrupt Controller)

block-automation-result.png

Clocking Wizard をダブルクリックして

adjust-clocking-wizard.png 入力周波数を 200MHz に変更

adjust-clocking-wizard2.png リセットを反転入力とする

GPIO をダブルクリックして

adjust-gpio.png 下位2ピンを出力にし、割り込みを有効にする

add-slice.png Slice を追加しダブルクリック

adjust-slice.png From を 1 にする

add-concat.png Concat を追加しダブルクリック

&ref(): File not found: "adjust-conscat.png" at page "電気回路/HDL/Kintex-7にMicroblazeを載せる"; 28bit, 1bit, 1bit, 2bit のポートを用意する

add-const.png Const を追加しダブルクリック

adjust-const.png 幅を 28bit, 値をゼロに設定

GPIO モジュールの GPIO バスをクリックして開き、slice, concat, const と結ぶ。
また、Slice の出力、Concat の2本の入力について、右クリックから Make External して外部端子を出す。

gpio-connection.png

interrupt-connection.png UART, GPIO からの割り込み線を INTC へ繋がる Concat へ接続

uart-make-external.png UART の UART 端子を右クリックして Make External

clock-make-external.png Clocking Wizard の入力端子を Make External

左上の Run Connection Automation をクリック

connection-automation.png

これで UART と GPIO が AXI ハブに繋がる。

Regenerate Layout して完成。

block-diagram-final.png

一カ所訂正

reset_rtl_0 と resetn_0 は被ってしまうので、reset_rtl_0 を削除して resetn_0 から ext_reset_in へ線を引いた。

アドレスを確認

Diagram のとなりのタブに Address Editor がある。

ここで、それぞれの IP のベースアドレスを確認できる。
必要に応じて変更することもできる。

address-editor.png

ブロック図から HDL を生成する

上図の左下で Generate Block Design を押すと以下のダイアログが現れる。

generate-block-design.png Global を選ぶ

design_1 上で右クリックして Create HDL Wrapper を選択。

create-hdl-wrapper.png

扱いは Vivado に任せる。

create-hdl-wrapper2.png

design_1_wrapper.v が自動生成され、以降、必要に応じて自動更新される。

generated-wrapper.png

Synthesis してみる

まだ制約をまったく与えていないものの、この時点で Synthesis が可能になっている。

&ref(): File not found: "synthesis-success.png" at page "電気回路/HDL/Kintex-7にMicroblazeを載せる"; &ref(): File not found: "post-synthesis-utilization.png" at page "電気回路/HDL/Kintex-7にMicroblazeを載せる";

Clocking Wizard に

&ref(): File not found: "post-synthesis-report-timing-summary.png" at page "電気回路/HDL/Kintex-7にMicroblazeを載せる";

制約を与える

module design_1_wrapper のインタフェースを見ると、

module design_1_wrapper(
  input wire CLK_IN1_D_0_clk_n,
  input wire CLK_IN1_D_0_clk_p,
  output wire [1:0] Dout_0,
  input wire [0:0] In1_0,
  input wire [0:0] In2_0,
  input wire UART_0_rxd,
  output wire UART_0_txd,
  input wire resetn_0
);

となっている。

Bit Stream を生成する

(未稿)

制約が満たされていることを確認

(未稿)

ハードウェアを SDK にエクスポート

以下に見るように、MicroBlaze 用のソフトウェアは WebPack 版の Xilinx SDK では開発できないので、 実はこの作業は無意味であった。

EDK を持っていて、SDK でソフト開発ができる場合にはこの手順で正しいはず。

(以下未稿)

SDK でエラーが出る

SDK でプロジェクトを作成しようとすると、bsp 生成部分で "Couldn't figure out compiler's library directory" というエラーが出てしまう。

ERROR	: (XSDB Server)ERROR: [Hsi 55-1545] Problem running tcl command ::sw_cpu_v2_7::generate : Couldn't figure out compiler's library directory
    while executing "error "Couldn't figure out compiler's library directory" "" "hsi_error""
   (procedure "::sw_cpu_v2_7::generate" line 139) invoked from within "::sw_cpu_v2_7::generate microblaze_0"
ERROR	: (XSDB Server)si 55-1442] Error(s) while running TCL procedure generate()
ERROR	: (XSDB Server)ERROR: [Hsi 55-1450] Error: run
ERROR	: (XSDB Server)ning generate_bsp.
ERROR	: Error generating bsp sources: Failed in generating sources

SDK を使って MicroBlaze 開発をするには EDK のライセンスが必要ということらしい。

クロスコンパイラの準備

そこで SDK を使わずにソフトウェアを開発する。

実は MicroBlaze 用のコードを出力する gcc を無償で利用することができるのだ。

ただし現状では、自分でビルドしなければならないみたい?

Windows 上の Vagrant で Ubuntu を立ち上げる

gcc のビルドには Linux 環境が必要なので、お手軽な環境として Windows10 に VirtualBox を入れ、Vagrant から利用する。

ここではすでに VirtualBox と Vagrant は導入済みとして、 以下の手順で進める。

ただし、ビルドする開発ツール自体はローカルフォルダ (./work) にインストールすることになるため、必ずしもこれだけのために 仮想マシンが必要ではない。いくつかのパッケージを入れることをいとわなければ、 既存の Ubuntu 環境で作業しても問題ないはず。

https://qiita.com/watame/items/1c17aaf266f14abef13f を見ながら

LANG:console
$ cd \Users\osamu\Vagrant
$ mkdir microblaze-gcc
$ cd microblaze-gcc
$ vagrant init bento/ubuntu-16.04
$ vagrant up --provider virtualbox
$ vagrant ssh

これでコンソールが立ち上がる。

まずは日本語キーボードに変更し( https://blog.amedama.jp/entry/2017/03/10/210552 )、
タイムゾーンを日本にする( https://qiita.com/koara-local/items/32b004c0bf80fd70777c )。

LANG:console
$ sudo dpkg-reconfigure keyboard-configuration
 > Generic 105-key (Intel) PC
 > Japanese
 > Japanese
 > The default for the keyboard layout
 > No compose key
$ sudo timedatectl set-timezone Asia/Tokyo

共有フォルダの設定

一旦 exit で抜けて、

LANG:console
$ vagrant halt

で仮想マシンも止める。

\Users\osamu\Vagrant\microblaze-gcc\Vagrantfile に

config.vm.synced_folder "./shared", "/home/vagrant/shared"

という行を追加した。

これはホストマシンの

\Users\osamu\Vagrant\microblaze-gcc\shared

の内容を仮想マシンの

/home/vagrant/shared

に接続するおまじない。

必要なパッケージを追加する

もう一度、

LANG:console
$ vagrant up --provider virtualbox
$ vagrant ssh

としてシェルを立ち上げ、

LANG:console
$ sudo apt-get -y install build-essential m4 g++ texinfo

開発用ツールチェインのビルド

https://qiita.com/watame/items/1c17aaf266f14abef13f を参考にしつつ、 以下の内容を \Users\osamu\Vagrant\microblaze-gcc\shared\build-gcc.sh として保存した。

LANG:sh
export MB_WORK=~/work

export MB_LINUX_DEP=${MB_WORK}/mb-linux-dep
export MB_LINUX_PREFIX=${MB_WORK}/mb-elf-toolchain-linux

export MB_BUILD=x86_64-linux-gnu
export MB_TARGET=microblaze-elf
export MB_PREFIX=mb-

export PATH=${MB_LINUX_PREFIX}/bin:$PATH

# prepare --------------------------------------------------
mkdir -p ${MB_WORK}/build-linux
mkdir -p ${MB_WORK}/source

# download sources...
cd ${MB_WORK}/source
wget http://ftp.gnu.org/gnu/gmp/gmp-6.1.1.tar.xz
wget http://ftp.gnu.org/gnu/mpfr/mpfr-3.1.4.tar.xz
wget http://ftp.gnu.org/gnu/mpc/mpc-1.0.3.tar.gz
wget http://isl.gforge.inria.fr/isl-0.17.tar.xz
wget http://ftp.gnu.org/gnu/binutils/binutils-2.26.1.tar.bz2
wget http://ftp.gnu.org/gnu/gcc/gcc-5.4.0/gcc-5.4.0.tar.bz2
wget ftp://sources.redhat.com/pub/newlib/newlib-2.4.0.20160527.tar.gz
tar xzf gmp-6.1.1.tar.xz
tar xzf mpfr-3.1.4.tar.xz
tar xzf mpc-1.0.3.tar.gz
tar xzf isl-0.17.tar.xz
tar xzf binutils-2.26.1.tar.bz2
tar xzf gcc-5.4.0.tar.bz2
tar xzf newlib-2.4.0.20160527.tar.gz

# linux ----------------------------------------------------
# gmp
cd ${MB_WORK}/build-linux
mkdir build-gmp
cd build-gmp
../../source/gmp-6.1.1/configure --prefix=${MB_LINUX_DEP}
make && make install && make check

# mpfr
cd ${MB_WORK}/build-linux
mkdir build-mpfr
cd build-mpfr
../../source/mpfr-3.1.4/configure \
  --enable-static --disable-shared \
  --with-gmp=${MB_LINUX_DEP} \
  --prefix=${MB_LINUX_DEP}
make && make install

# mpc
cd ${MB_WORK}/build-linux
mkdir build-mpc
cd build-mpc
../../source/mpc-1.0.3/configure \
  --enable-static --disable-shared \
  --with-gmp=${MB_LINUX_DEP} \
  --with-mpfr=${MB_LINUX_DEP} \
  --prefix=${MB_LINUX_DEP}
make && make install

# isl
cd ${MB_WORK}/build-linux
mkdir build-isl
cd build-isl
../../source/isl-0.17/configure \
  --without-piplib \
  --enable-static --disable-shared \
  --with-gmp-prefix=${MB_LINUX_DEP} \
  --prefix=${MB_LINUX_DEP}
make && make install

# binutils
cd ${MB_WORK}/build-linux
mkdir build-binutils
cd build-binutils
../../source/binutils-2.26.1/configure --target=${MB_TARGET} \
  --prefix=${MB_LINUX_PREFIX} \
  --program-prefix=${MB_PREFIX}
make && make install

# bootstrap gcc
cd ${MB_WORK}/build-linux
mkdir build-gcc1
cd build-gcc1
../../source/gcc-5.4.0/configure \
  --target=${MB_TARGET} \
  --program-prefix=${MB_PREFIX} \
  --with-gnu-as --with-gnu-ld \
  --enable-static --disable-shared \
  --with-gmp=${MB_LINUX_DEP} \
  --with-mpfr=${MB_LINUX_DEP} \
  --with-mpc=${MB_LINUX_DEP} \
  --with-isl=${MB_LINUX_DEP} \
  --with-newlib \
  --without-headers \
  --enable-languages="c,c++" --enable-interwork --enable-multilib \
  --disable-decimal-float --disable-libffi \
  --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch \
  --disable-nls --disable-shared --disable-threads --disable-tls \
  --prefix=${MB_LINUX_PREFIX} \
  --with-system-zlib
make -j2 all-gcc
make install-gcc

# because newlib not support program-prefix, we need to create symbol link
cd ${MB_LINUX_PREFIX}/bin
ln -s mb-gcc mb-cc
ln -s mb-ar microblaze-elf-ar
ln -s mb-as microblaze-elf-as
ln -s mb-c++ microblaze-elf-c++
ln -s mb-gcc microblaze-elf-gcc
ln -s mb-gcc microblaze-elf-cc
ln -s mb-gcc-ar microblaze-elf-gcc-ar
ln -s mb-gcc-nm microblaze-elf-gcc-nm
ln -s mb-gcc-ranlib microblaze-elf-gcc-ranlib
ln -s mb-gcov microblaze-elf-gcov
ln -s mb-gcov-tool microblaze-elf-gcov-tool
ln -s mb-ld microblaze-elf-ld
ln -s mb-ld microblaze-elf-ld.bfd
ln -s mb-nm microblaze-elf-nm
ln -s mb-objcopy microblaze-elf-objcopy
ln -s mb-objdump microblaze-elf-objdump
ln -s mb-ranlib microblaze-elf-ranlib
ln -s mb-readelf microblaze-elf-readelf
ln -s mb-size microblaze-elf-size
ln -s mb-strings microblaze-elf-strings
ln -s mb-strip microblaze-elf-strip

# newlib
cd ${MB_WORK}/build-linux
mkdir build-newlib
cd build-newlib
../../source/newlib-2.4.0.20160527/configure \
  --target=${MB_TARGET} \
  --prefix=${MB_LINUX_PREFIX}
make && make install

# gcc
cd ${MB_WORK}/build-linux
mkdir build-gcc2
cd build-gcc2
../../source/gcc-5.4.0/configure \
  --target=${MB_TARGET} \
  --program-prefix=${MB_PREFIX} \
  --with-gnu-as --with-gnu-ld \
  --enable-static --disable-shared \
  --with-gmp=${MB_LINUX_DEP} \
  --with-mpfr=${MB_LINUX_DEP} \
  --with-mpc=${MB_LINUX_DEP} \
  --with-isl=${MB_LINUX_DEP} \
  --with-newlib \
  --enable-languages="c,c++" --enable-interwork --enable-multilib \
  --disable-decimal-float --disable-libffi \
  --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch \
  --disable-nls --disable-shared --disable-threads --disable-tls \
  --prefix=${MB_LINUX_PREFIX} \
  --with-system-zlib
make -j 2
make install

cd ${MB_LINUX_PREFIX}

リンク先のままだと make -j4 all-gcc で、

checking dynamic linker characteristics... configure: error: Link tests are not allowed after GCC_NO_EXECUTABLES.
Makefile:8349: recipe for target 'configure-zlib' failed
make: *** [configure-zlib] Error 1
make: *** Waiting for unfinished jobs....

というエラーが出たので、https://stackoverflow.com/questions/29481325/arm-gcc-build-error-under-fedora-21 に従って configure に --with-system-zlib を追加してある。

あとは、

LANG:console
$ cd
$ source shared/build-gcc.sh 2>1 | tee shared/build-gcc.log

とすれば、かな~り時間はかかるもののビルドに成功するはず。

LANG:console
$ cd
$ ls work/mb-elf-toolchain-linux/bin
 mb-addr2line  mb-gcc-ar      mb-ranlib           microblaze-elf-gcc-5.4.0   microblaze-elf-objdump
 mb-ar         mb-gcc-nm      mb-readelf          microblaze-elf-gcc-ar      microblaze-elf-ranlib
 mb-as         mb-gcc-ranlib  mb-size             microblaze-elf-gcc-nm      microblaze-elf-readelf
 mb-c++        mb-gcov        mb-strings          microblaze-elf-gcc-ranlib  microblaze-elf-size
 mb-cc         mb-gcov-tool   mb-strip            microblaze-elf-gcov        microblaze-elf-strings
 mb-c++filt    mb-ld          microblaze-elf-ar   microblaze-elf-gcov-tool   microblaze-elf-strip
 mb-cpp        mb-ld.bfd      microblaze-elf-as   microblaze-elf-ld
 mb-elfedit    mb-nm          microblaze-elf-c++  microblaze-elf-ld.bfd
 mb-g++        mb-objcopy     microblaze-elf-cc   microblaze-elf-nm
 mb-gcc        mb-objdump     microblaze-elf-gcc  microblaze-elf-objcopy
$ microblaze-elf-gcc --version
 microblaze-elf-gcc (GCC) 5.4.0
 Copyright (C) 2015 Free Software Foundation, Inc.
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

パスに追加

LANG:console
$ cat >> ~/.bashrc
 PATH=/home/vagrant/work/mb-elf-toolchain-linux/bin/:$PATH
 ^D

試しにコンパイルしてみる

LANG:console
$ cd shared
$ mkdir hello
$ cd hello
$ cat > hello.c
 int main()
 {
   return 0;
 }
$ mb-gcc -c hello.c
$ ls
 hello.c  hello.o
$ mb-gcc hello.c -o hello.elf
 /home/vagrant/work/mb-elf-toolchain-linux/lib/gcc/microblaze-elf/5.4.0/../../../../microblaze-elf/bin/ld: cannot find -lxil
 collect2: error: ld returned 1 exit status

コンパイルはできるけれど、リンクで libxil というライブラリが見つからないといって失敗する。

標準ライブラリなしでリンクするには -nostdlib を付けると良いらしいのだけれど、

LANG:console
$ mb-gcc hello.c -nostdlib -o hello.elf
/home/vagrant/work/mb-elf-toolchain-linux/lib/gcc/microblaze-elf/5.4.0/../../../../microblaze-elf/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000000050

今度は _start が見つからないと言われてしまう。

Wikipedia:フリースタンディング環境 などで解説されているとおり、-nostdlib を付けた場合には始めから main ではなく _start をエントリポイントとすれば良いらしい。

LANG:console
$ cat > hello.c
 void _start()
 {
 }
$ mb-gcc hello.c -nostdlib -o hello.elf
$ ls
 hello.c  hello.elf

めでたくコンパイルが通る。

コンパイルオプション

MicroBlaze を AXI バスと共に使う場合には

https://www.xilinx.com/support/documentation/sw_manuals/xilinx2018_1/ug984-vivado-microblaze-ref.pdf#page=11

にあるように Little Endian になるので、コンパイル時にもそうなるようにオプションを付ける必要がある。

LANG:console
$ mb-gcc -mlittle-endian -O2 hello.c -nostdlib -o hello.elf

UART ライブラリを作成

address.h

LANG:c
#define UART_BASE   0x40600000
#define GPIO        0x40000000
#define INTC_BASE   0x41200000

uart.h

LANG:c
#ifndef UART_LIB_INCLUDED
#define UART_LIB_INCLUDED
extern void uart_init(int enable_interrupt);
extern int  uart_status();
extern int  uart_readable();
extern int  uart_readc();
extern int  uart_writable();
extern void uart_writec(char c);
extern void uart_puts(const char *str);
extern void uart_write_hex1(int n);
extern void uart_write_hex2(int n);
extern void uart_write_hex4(int n);
extern void uart_write_hex8(int n);
#endif

uart.c

LANG:c
#include "address.h"

#define UART_RX       (UART_BASE+0)
#define UART_TX       (UART_BASE+4)
#define UART_STATUS   (UART_BASE+8)
#define UART_CTRL     (UART_BASE+12)

//////////////////////////////////////////////////

static void reg_set(int addr, int value)
{
    *(volatile int *)(addr) = value;
}

static int reg_get(int addr)
{
    return *(volatile int *)addr;
}

//////////////////////////////////////////////////

void uart_init(int enable_interrupt)
{
    reg_set(UART_CTRL, 3 + ((!!enable_interrupt) << 4));
}

int uart_status()
{
    return reg_get(UART_STATUS);
}

int uart_readable()
{
    return uart_status() & 1;
}

int uart_readc()
{
    while ( !uart_readable() )  // Empty
      ;
    return reg_get(UART_RX) & 0xff;
}

int uart_writable()
{
    return 0 == ( uart_status() & 8 );
}

void uart_writec(char c)
{
    while ( !uart_writable() )  // Full
      ;
    reg_set(UART_TX, c & 0xff);
}

void uart_puts(const char *str)
{
    while (*str) {
        uart_writec(*str);
        str++;
    }
}

void uart_write_hex1(int n)
{
    n = n & 0xf;
    uart_writec('0' + n + (n >= 10 ? 'a'-'0'-10 : 0));
}

void uart_write_hex2(int n)
{
    uart_write_hex1(n >> 4);
    uart_write_hex1(n);
}

void uart_write_hex4(int n)
{
    uart_write_hex2(n >> 8);
    uart_write_hex2(n);
}

void uart_write_hex8(int n)
{
    uart_write_hex4(n >> 8);
    uart_write_hex4(n);
}

hello.c

hello.c

LANG:c
#include "uart.h"
void _start()
{
  uart_puts("Hello World!!\n");
  while(1) {
    char c = uart_readc();
    uart_puts("detected key '");
    uart_writec(c);
    uart_puts("'\n");
  }
}

コンパイル

LANG:console
$ mb-gcc -mlittle-endian -O2 hello.c uart.c -nostdlib -o hello.elf

elf ファイルを bit ファイルへ埋め込む

updatemem と言うコマンドを使えばいいらしい。

LANG:tcl
exec updatemem -force \
-meminfo C:/Users/osamu/MicroBlazeHello/MicroBlazeHello.runs/impl_1/design_1_wrapper.mmi \
-bit C:/Users/osamu/MicroBlazeHello/MicroBlazeHello.runs/impl_1/design_1_wrapper.bit \
-data C:/Users/osamu/Vagrant/microblaze-gcc/data/hello/hello.elf \
-proc design_1_i/microblaze_0 \
-out C:/Users/osamu/MicroBlazeHello/MicroBlazeHello.runs/impl_1/download.bit

これで、design_1_wrapper.bit の中の design_1_i/microblaze_0 のメモリ内容を hello.elf で置き換えたものを download.bit として保存できる。

FPGA をプログラムする

あとは以下のようにして download.bit を FPGA へダウンロードできる。

LANG:tcl
set_property PROBES.FILE {} [get_hw_devices xc7k160t_0]
set_property FULL_PROBES.FILE {} [get_hw_devices xc7k160t_0]
set_property PROGRAM.FILE {C:/Users/osamu/MicroBlazeHello/MicroBlazeHello.runs/impl_1/download.bit} [get_hw_devices xc7k160t_0]
program_hw_devices [get_hw_devices xc7k160t_0]

ツールボタンに割り当てる

コンパイル → bit 置き換え → FPGAプログラム

を何度も繰り返すのはかなり面倒なので、「bit 置き換え → FPGAプログラム」をワンクリックで可能なツールボタンを作成する。

Vivado の [Tools]-[Custom Commands]-[Customize Commands...] に 上記のスクリプトを ; で区切りながら1行に繋げた手順を入れてボタンにしておく。

コンパイルしたらボタンを押すだけでプログラムができるようになる。

フラッシュメモリに書き込むには

普通なら Generate Bitstream のオプションで同時に bin ファイルを作成するようにしておけば良いのだけれど、elf を書き込んだ bit をフラッシュメモリに焼くにはどうしたらいいものか???

http://www3.hdl.co.jp/spc/xcm/466-q20160229.html

の手順で mcs ファイルを作れば良いらしい。

LANG:tcl
write_cfgmem -format MCS -interface SPIx1 -size 64 \
 -loadbit "up 0x0 C:/Users/osamu/MicroBlazeHello/MicroBlazeHello.runs/impl_1/download.bit" \
 "C:/Users/osamu/MicroBlazeHello/MicroBlazeHello.runs/impl_1/download.mcs"

スタートアップコードが足りないみたい???

上記の手順で一見動いているように見えたのだけれど、動作が不安定だ。

実は上で不足していると怒られた libxil のソースコードは Xilinx SDK に付いているので、

C:\Xilinx\SDK\2018.2\data\embeddedsw\lib\bsp\standalone_v6_7

不足するヘッダーファイル等を補うことでこれをそのまま上記環境でコンパイルして使えるっぽい。

ただ、そうしたときに完動するコードが、上記のように完全にベアな状態で走らせたときにうまく動かないケースがあった。

ここに付いてきたコードをそのままコンパイルして使っていいものかどうか、ライセンス的にちょっと心配なので、必要そうなコードを吟味して、独自のスタートアップルーチンを作るのがいいのかもしれない???

質問・コメント





Counter: 17578 (from 2010/06/03), today: 1, yesterday: 0