Freedom E300 Arty DevKit でRISCVを試す

RISCVのArduino互換ボードであるHiFiveは日本国内ではすぐには入手できないので、DigilentのArtyをつかってRISCV(SiFiveのFreedom E300)を動かします。


![Arty.png](https://qiita-image-store.s3.amazonaws.com/0/157475/2fa21168-52a2-4e0f-cfca-d69e74b0ea60.png)
左がHiFive、右がArtyで動かしたFreedomE300。

## 1. 開発環境

- Host PC
    - Ubuntu 16.04 64bit
    - RHEL７の場合はFPGA開発日記の下記の記事を参照
        - http://msyksphinz.hatenablog.com/entry/2017/08/29/020000
        - YUMで必要なパッケージ導入
        - DTCはRPMを https://centos.pkgs.org/7/centos-extras-x86_64/dtc-1.4.6-1.el7.x86_64.rpm.html からDLしてでもOK 
- javac がない場合は入れておく
    - RHELの場合
        - yum install java-1.8.0-openjdk java-1.8.0-openjdk-devel
- Xilinx Vivado を Install しておく
    - SiFiveのガイドでは 2016.4
    - 2019.2 でも大丈夫でした
    - Installが済んだらvivadoへのパスを切っておく、例：
        - source /opt/Xilinx/Vivado/2019.2/settings64.sh 
- Digilent の ボード定義ファイルを追加しておく
    - 参照 https://reference.digilentinc.com/vivado/getting_started/start
- Arduino 1.8.0
- Digilent Arty (http://akizukidenshi.com/catalog/g/gM-10034/)
- Olimex JTAG ARM-USB-TINY-H (https://strawberry-linux.com/catalog/items?code=15045)

JTAGアダプターはFreedomで標準サポートのOlimex JTAG ARM-USB-TINY-Hを使っています。 Vivado WebPACKのインストールとセットアップは済んでいるものとします。

## 2. FPGAイメージの作成

### 2-1. FPGA用にFreedomをビルド

以下のように、Githubからコード一式をCloneして、MakeすればOK。Arty用のFreedom E300のMCSファイルが生成されます。

    git clone https://github.com/sifive/freedom.git
    cd freedom

Device Tree コンパイラをインストール

    sudo apt install device-tree-compiler

RISCVのToolchainをインストール

    wget https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-20170612-x86_64-linux-centos6.tar.gz
    tar xvfz riscv64-unknown-elf-gcc-20170612-x86_64-linux-centos6.tar.gz
    export RISCV=$PWD/riscv64-unknown-elf-gcc-20170612-x86_64-linux-centos6

submoduleを更新

    git submodule update --init
    cd rocket-chip/
    git submodule update --init
    cd ..

ChiselのソースコードからVerilog RTLを作成し、次にFPGAのイメージ（Bitfile）をビルドします。（この際vivadoにパスが通っていること）

    make -f Makefile.e300artydevkit verilog
    make -f Makefile.e300artydevkit mcs


### 2-2. ArtyのSPI FlashにMCSを書き込む

- PCとArtyをUSBケーブルで接続。
- Vivadoを起動し、hardware managerを起動。Open TargetからAuto connectで認識されます。
- FPGAを右クリックし、Add Configuration Memory device を選択、
    - Micron
    - 128
    - spi
    - 25q128-3.3v-spi-x1_x2_x4 を選択
- Configuration file で builds/e300artydevkit/sifive.freedom.everywhere.e300artydevkit.E300ArtyDevKitConfig.mcs を選択
- プログラム実行
- 書き込みが成功後、ボード上のPROGボタンを押せばFPGAイメージがFlashからFPGAにロードされ、Arty上のLED（LD4,5,6）が点灯します

## 3. アプリの実行

### 3-1. JTAGを接続をする

FreedomのJTAGはArtyの PMOD Dに割り当てられています。

|PIN # | Signal name |PIN # | Signal name
|-----:|:------------|-----:|:---------------
|    1 | TDO         |    7 | TDI
|    2 | TRST_n      |    8 | TMS
|    3 | TCK         |    9 | SRST_n
|    4 |             |   10 | 
|    5 | GBD         |   11 | GND
|    6 | VCC         |   12 | VCC


Olimex JTAG ARM-USB-TINY-H はARMの20PINのJTAGになります。

|PIN # | Signal name   |PIN # | Signal name
|-----:|:--------------|-----:|:---------------
|    1 | VREF          |    2 | VREF
|    3 | TTRST_N       |    4 | GND
|    5 | TTDI          |    6 | GND
|    7 | TTMS          |    8 | GND
|    9 | TTCK          |   10 | GND
|   11 | TRTCK         |   12 | GND
|   13 | TTDO          |   14 | GND
|   15 | TSRST_N       |   16 | GND
|   17 | NOT CONNECTED |   18 | GND
|   19 | TARGET SUPPLY |   20 | GND

信号の６PINとGNDを上記のPMOD Dに接続します。


### 3-2. Arduino IDEを使ってアプリを動かす

- Arduino IDEのセットアップはHiFiveの場合（http://qiita.com/mune10/items/2d62d48d92915d5105ba ）と同じです。
- Tools -> Board で Freedom E300 DevKit を選択
- Tools -> Programmer で SiFive OpenOCD を選択

#### 2017−1−17時点(最初のFPGAコード)

OpenOCDがうまく動かないので、＄HOME/.arduino15/packages/sifive/riscv/1.0.1/freedom-e-sdk/bsp/env/freedom-e300-arty/openocd.cfg を下記のように修正しておきます。

    adapter_khz     10000
    
    #source [find interface/ftdi/olimex-arm-usb-tiny-h.cfg]
    interface ftdi
    ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H"
    ftdi_vid_pid 0x15ba 0x002a
    ftdi_layout_init 0x0808 0x0a1b
    ftdi_layout_signal nSRST -oe 0x0200
    ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100
    ftdi_layout_signal LED -data 0x0800
    
    set _CHIPNAME riscv
    jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913
    
    set _TARGETNAME $_CHIPNAME.cpu
    target create $_TARGETNAME riscv -chain-position $_TARGETNAME
    $_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1
    
    flash bank my_first_flash fespi 0x20000000 0 0 0 $_TARGETNAME
    init
    #reset
    halt
    flash protect 0 64 last off


interface/ftdi/olimex-arm-usb-tiny-h.cfgがうまく見つけられないようなので、Olimexの設定を直接書き込んでおきます。あとFlashのProtectionを外すコマンドがコメントアウトされているので、元に戻しておきます。（この問題はForumでも指摘されているので、今後修正されると思います）

#### 2017−10−03時点(2017年8月更新のFPGAコード)

新しいFPFAイメージだと、上記の方法ではUploadがうまく動きません。Forumにこの問題と修正方法のスレッドが有ります（https://forums.sifive.com/t/freedom-e300-mcs-file-not-working/710）。＄HOME/.arduino15/packages/sifive/hardware/riscv/1.0.2/freedom-e-sdk/bsp/env/freedom-e300-arty/openocd.cfg を下記のように修正しておきます。

    adapter_khz     10000
    
    #source [find interface/ftdi/olimex-arm-usb-tiny-h.cfg]
    
    interface ftdi
    ftdi_device_desc "Olimex OpenOCD JTAG ARM-USB-TINY-H"
    ftdi_vid_pid 0x15ba 0x002a
    
    ftdi_layout_init 0x0808 0x0a1b
    ftdi_layout_signal nSRST -oe 0x0200
    ftdi_layout_signal nTRST -data 0x0100 -oe 0x0100
    ftdi_layout_signal LED -data 0x0800
    #
    
    set _CHIPNAME riscv
    #jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x10e31913
    jtag newtap $_CHIPNAME cpu -irlen 5
    
    set _TARGETNAME $_CHIPNAME.cpu
    target create $_TARGETNAME riscv -chain-position $_TARGETNAME
    $_TARGETNAME configure -work-area-phys 0x80000000 -work-area-size 10000 -work-area-backup 1
    
    #flash bank my_first_flash fespi 0x20000000 0 0 0 $_TARGETNAME
    flash bank my_first_flash fespi 0x20000000 0 0 0 $_TARGETNAME 0x10014000
    init
    #reset
    if {[ info exists pulse_srst]} {
      ftdi_set_signal nSRST 0
      ftdi_set_signal nSRST z
    }
    halt
    #flash protect 0 64 last off

あとOpenOCDも最新の物に差し替えておきます。

    ＄HOME/.arduino15/packages/sifive/tools
    wget https://static.dev.sifive.com/dev-tools/riscv-openocd-20170612-x86_64-linux-centos6.tar.gz
    tar xvfz riscv-openocd-20170612-x86_64-linux-centos6.tar.gz

＄HOME/.arduino15/packages/sifive/hardware/riscv/1.0.2/platform.txt ファイルを上記を使うようにパスを（無理やり）修正しておきます。 SDK周りは最新のRISCVにまだ更新されていないので騙し騙し使います。

### 3-3. アプリの実行

あとは、Arduino IDEで BlinkサンプルをCompile＆Uploadすれば、ArtyのLD1が赤く点滅します。

![Screenshot from 2017-01-17 06-01-52.png](https://qiita-image-store.s3.amazonaws.com/0/157475/a757cf4b-08e0-1539-f945-a682d1d4f87e.png)


### 3-4. コメント

JTAGアダプターはOlimex以外も使えると思いますが、OpenOCD周りで修正が必要になります。


## 4. 参照

- Freedom E300 Platform Brief
    - https://dev.sifive.com/documentation/freedom-e300-platform-brief/
- Freedom E300 Platform Reference Manual
    - https://dev.sifive.com/documentation/freedom-e300-platform-reference-manual/
- Forum
    - https://forums.sifive.com/c/freedomE300
- Github
    - https://github.com/sifive/freedom
- Digilent Arty A7 with Xilinx Artix-7 Implementing SiFive FE310 RISC-V
    - https://www.digikey.com/eewiki/display/LOGIC/Digilent+Arty+A7+with+Xilinx+Artix-7+Implementing+SiFive+FE310+RISC-V
    - Arty 100Tを使う手順の記載があります。通常は35Tで十分ですが、回路を追加するとギリギリになる場合は(少し高いですが)100Tを使ったほうがFPGAに余裕ができて作業は快適です。


## 5. 更新履歴
- 2017-01-17 初版 
- 2017-07-09 e300artydevkit-updateのブランチを使用してみる 
- 2017-10-03 8月に新しいRocket-CoreをベースにFreedomがアップデートされたので内容を更新
- 2019-05-11 DigikeyのWikiを参照に追加