ハードウェアの気になるあれこれ

技術的に興味のあることを調べて書いてくブログ。主にハードウェアがネタ。

Scalaの勉強 - Scalaの環境構築

最終的に扱えるようになりたいのはChiselなのだけれども、Chiselを勉強しようにもそもそもベースになってるScalaも書けないのでまずはそこから一通り見ていく。

Scalaって??

ドワンゴが公開してくれている資料から引用させていただく。

Introduction · Scala研修テキスト

Scalaとは
Scalaは2003年にスイス連邦工科大学ローザンヌ校(EPFL)のMartin Odersky教授によって開発されたプログラミング言語です。Scalaではオブジェクト指向関数型プログラミングの両方を行えるところに特徴があります。また、処理系はJVM上で動作するため1、Java言語のライブラリのほとんどをシームレスに利用することができます。
Scalaとは · Scala研修テキスト

ふむふむ。オブジェクト指向関数型プログラミングの両方を行える、、、と。 それプラスJVM上で動くのJavaのライブラリも使用可能!!とはいえ、Javaも書けないんですが。。
関数型プログラミングは触ってみたいとは思っていたのでちょうどいいかも。

Scala環境の構築

せっかく素晴らしい資料を公開してくださっているので、引き続きドワンゴの資料を元に環境を構築していく。

sbt

手順についてはこちら↓に従って進めていく。

sbtをインストールする · Scala研修テキスト

ということで、まずはsbt??のインストール。
sbtって何??って思っていたら、以下の記事を見つけた。

qiita.com

なるほど、scalaのビルドツールとな。scala言語を書いてても触れたことないと著者の方が書いているのでなくてもscala自体を使うことはできるみたい。

リファレンスマニュアルはこちら→sbt Reference Manual — sbt Reference Manual

Java環境の確認

前述の通り、JVM上で動作するものなのでScalaを動作させるにはJDKがインストールされている必要がある。
ということで環境の確認から。

$ apt search jdk
openjdk-8-jdk/xenial-updates,xenial-security,now 8u181-b13-0ubuntu0.16.04.1 amd64 [インストール済み]
  OpenJDK Development Kit (JDK)

openjdk-8-jdk-headless/xenial-updates,xenial-security,now 8u181-b13-0ubuntu0.16.04.1 amd64 [インストール済み、自動]
  OpenJDK Development Kit (JDK) (headless)

openjdk-8-jre/xenial-updates,xenial-security,now 8u181-b13-0ubuntu0.16.04.1 amd64 [インストール済み、自動]
  OpenJDK Java ランタイム - Hotspot JIT 版

openjdk-8-jre-dcevm/xenial 8u74-1 amd64
  Alternative VM for OpenJDK 8 with enhanced class redefinition

openjdk-8-jre-headless/xenial-updates,xenial-security,now 8u181-b13-0ubuntu0.16.04.1 amd64 [インストール済み、自動]
  OpenJDK Java ランタイム - Hotspot JIT 版 (ヘッドレス)

現在のPCには一通り入れていたっぽい。環境変数もついでに確認

$ env | grep JAVA_HOME
JAVA_HOME=/usr/lib/jvm/java-8-oracle

問題なさそうなので、改めてsbtのインストールへ。

sbtのインストール

Linuxの場合はsbtのサイトからデータ一式をダウンロードして、適当なパスに展開したのち、環境変数PATHの設定を行うだけよいとのこと。
sbtのサイト見るとaptコマンドでのインストールも可能みたいだけど、とりあえず今回は一式をダウンロードしてPATH設定を行う方法を採用
aptコマンド使ったインストールはこちら→https://www.scala-sbt.org/download

上記のsbtのダウンロードページの"All platfoprms"からデータをダウンロード。なおこの記事を書いている時の最新バージョンは1.2.1(2018年8月26日時点)

$ wget https://piccolo.link/sbt-1.2.1.tgz
$ tar xf sbt-1.2.1.tgz
$ cd sbt/bin
$ export PATH=$PWD:$PATH

動作確認

ドワンゴの資料では、REPL(Read Eval Print Loop)機能を使ってScalaプログラムの基本的なことを試していくが、その環境としていsbt consoleコマンドで起動できるターミナルを使用する。

sbtをインストールする · Scala研修テキスト

起動時には”仮のディレクトリを作成しておくことをお勧めする”とのことなので、ディレクトリを作ってからsbt consoleで起動

$ mkdir 000_sbt_trial
$ cd 000_sbt_trial
$ sbt console

初回起動時はなんかいろいろとダウンロードが行われた後に以下のようにscala consoleが起動して、コマンドを受け付ける状態になる。
起動時のログはこちら→initial running log of scala console · GitHub

scala>

sbt consoleを終了する場合は以下のようにする。

scala> :quit

上で初回起動時に”いろいろとダウンロードされて”と書いたが、その中にScala本体も含まれているので、Scalaのインストールはこれで完了!!

RISC-Vの実装の1つ - SCR1の解析 - riscv-toolsのビルド

基本的にはRISC-Vのページに記載の手順でビルドしていくだけ。

github.com

とりあえず今回は、SCR1向けのビルド環境を立ち上げたいので、それ向けに構築していく

$ git clone https://github.com/riscv/riscv-tools.git
$ cd riscv-tools
$ git submodule update --init --recursive

SCR1はRV32I or RV32Eをベースに以下のオプションをつけることができる。

  • M : 整数の乗除算
  • C : 圧縮命令(16bit命令/ARMのthumb命令みたいなの)

このriscv-toolsリポジトリは、ソフト開発に必要な各種RISV-Vのツールをひとまとめにしたリポジトリになっており、サブモジュールをcloneした後に、build.shを実行すると

  • riscv-openocd : OpenOCD をRISC-V向けにforkしたもの
  • riscv-fesvr : front-end server
  • riscv-isa-sim : ISAシミュレータ
  • riscv-gnu-toolchain : GNUコンパイラツール
  • riscv-pk : proxy kernel
  • riscv-tests : RISC-VのISAのテスト一式

がビルドされる(エラーがなければ)

$ git submodule update --init --recursive
$ export RISCV=/path/to/install/riscv/toolchain
$ export PATH=$PATH:$RISCV/bin

関連パッケージをインストール

$ sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev libusb-1.0-0-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev device-tree-compiler pkg-config libexpat-dev

RISC-Vのページの手順に従うと、上記設定の後に build.sh を実行することになるがこのファイルの中身は64bitCPU向けの物になっているので代わりにbuild-rv32ima.shを実行する

$ build-rv32ima.sh

と、エラー発生。。。

/bin/sh: 1: test: false: unexpected operator
*** This configuration is not supported in the following subdirectories:
     zlib target-libquadmath target-libatomic target-libcilkrts target-libitm target-libsanitizer target-libvtv target-libmpx gnattools gotools target-libada target-libhsail-rt target-libgfortran target-libbacktrace target-libgo target-libffi target-libobjc target-libgomp target-liboffloadmic target-libssp
    (Any other directories should still work fine.)
libtool: install: warning: remember to run `libtool --finish /home/dnn-admin/workspace/hw/study/1001_riscv-tools/libexec/gcc/riscv32-unknown-elf/7.2.0'
configure: error: 
*** LIBRARY_PATH shouldn't contain the current directory when
*** building gcc. Please change the environment variable
*** and run configure again.
make[1]: *** [configure-gcc] エラー 1
make: *** [stamps/build-gcc-newlib-stage1] エラー 2

最初、よく見ずにLD_LIBRARY_PATHかと思ったので、現在のパスなんか設定してないし!!って思ったらLIBRARY_PATHだったのね。。
エラーメッセージで検索してみると、以下が見つかった。

github.com

この記事の最後の方の回答に以下のものがあった。

philippbayer commented on 9 Jun 2017
A year later and a blog post reminded me of this issue - https://joshumax.github.io/general/2017/06/08/how-torch-broke-ls.html
It turns out that an empty entry in LD_LIBRARY_PATH is converted into the current directory. Good to know!

It turns out that an empty entry in LD_LIBRARY_PATH is converted into the current directory. Good to know!

ですって!!

これはLD_LIBRARY_PATHの話だが、まさか、、、と思いLIBRARY_PATHに適当な値を設定して再度ビルド。

$ export LIBRARY_PATH=~/.
$ build-rv32ima.sh
Installing project riscv-openocd
Makefile:4431: 警告: ターゲット 'check-recursive' のためのレシピを置き換えます
Makefile:3842: 警告: ターゲット 'check-recursive' のための古いレシピは無視されます
Makefile:4431: 警告: ターゲット 'check-recursive' のためのレシピを置き換えます
Makefile:3842: 警告: ターゲット 'check-recursive' のための古いレシピは無視されます
Makefile:4431: 警告: ターゲット 'check-recursive' のためのレシピを置き換えます
Makefile:3842: 警告: ターゲット 'check-recursive' のための古いレシピは無視されます
Makefile:4431: 警告: ターゲット 'check-recursive' のためのレシピを置き換えます
Makefile:3842: 警告: ターゲット 'check-recursive' のための古いレシピは無視されます
Makefile:4431: 警告: ターゲット 'check-recursive' のためのレシピを置き換えます
Makefile:3842: 警告: ターゲット 'check-recursive' のための古いレシピは無視されます

RISC-V Toolchain installation completed!

通った!!! ビルドしたツールを使用して、動作確認をしてみる

$ echo -e '#include <stdio.h>\n int main(void) { printf("Hello world!\\n"); return 0; }' > hello.c
$ riscv32-unknown-elf-gcc -o hello hello.c
$ spike pk hello
Hello World!!

無事Hello World!が表示されて、動作確認も完了。 ビルドしたツールを使って生成したバイナリを使ってSCR1のシミュレーションを実行していく

RISC-Vの実装の1つ - SCR1の解析 - Vivadoプロジェクト準備(3)

前回はSCR1のシミュレーション環境でシミュレーション実行時にモジュールが足りないというエラーが出たためその解析を行った。

tech-diningyo.hatenablog.com

最初のエラーは解決したが、その後Vivadoのシミュレータがセグメンテーション違反で強制終了したため今回はそのエラーの解析を行っていく。

SIGSEGVの解析

Vivadoのバージョンの変更

現在使用しているVivadoは2017.4。Vivadoは1年に4回リリースが行われるので、この記事の執筆時の最新バージョンは2018.2となっている。 まずは、2017.4以降のリリースで改善されているかもしれないことに一縷の望みをかけて新しいバージョンで実行してみる。

Vivado バージョン 結果
2018.1 変わらずSIGSEGVで落ちる
2018.2 変わらずSIGSEGVで落ちる

ダメかぁ。。

ちゃんと原因を調査する

原因を確定させるために、もう一度ログを眺めてみる。

Compiling module xil_defaultlib.scr1_core_top
Compiling module xil_defaultlib.scr1_dp_memory_default
Compiling module xil_defaultlib.scr1_tcm
Compiling module xil_defaultlib.scr1_timer
Compiling module xil_defaultlib.scr1_imem_router(SCR1_ADDR_PATTE...
Compiling module xil_defaultlib.scr1_dmem_router(SCR1_PORT1_ADDR...
Compiling module xil_defaultlib.scr1_mem_axi_default
Compiling module xil_defaultlib.scr1_top_axi
Compiling module xil_defaultlib.scr1_memory_tb_axi_default
ERROR: [XSIM 43-3316] Signal SIGSEGV received.

xil_defaultlib.scr1_memory_tb_axi_defaultコンパイル中にSIGSEGVが発生しているので、このファイルの中に原因となる記述が入っているということになる。 とりあえず、このファイルが原因かを判断するためにテストベンチ上からモジュールscr1_memory_tb_axiインスタンス記述を削除する。 具体的には、scr1/src/tb/scr1_top_tb_axi.svの中の以下の部分をコメントアウト

  • L.168 - L.214 : シミュレーション制御用のinitial ~ endブロック
  • L.338 - L.390 : scr1_memory_tb_axiのインスタンス記述

コメントアウト後に再度シミュレーションを実行。

f:id:diningyo-kpuku-jougeki:20180819222209p:plain

あ、動いた。。。
ということで原因はscr1_memory_tb_axiの中の記述の何か、、ということで確定。

scr1_memory_tb_axiの解析

原因となっている、scr1_memory_tb_axiの中身を見ていく。

github.com

大まかに書くと以下の4つの構成。

  • L.8 - L.60 : モジュール宣言
module scr1_memory_tb_axi #(
    parameter SIZE   = 1*1024*1024,
    parameter N_IF   = 2,
    parameter W_ID   = 4,
    parameter W_ADR  = 32,
    parameter W_DATA = 32
)
(
    // System
    input   logic                          rst_n,
    input   logic                          clk,

~~
);
  • L.65 - L141 : パラメータと基本タスク(read/write)の実装
//-------------------------------------------------------------------------------
// Local parameters
//-------------------------------------------------------------------------------
localparam [W_ADR-1:0]                      PRINT_ADDR     = 32'hF000_0000;
localparam [W_ADR-1:0]                      IRQ_ADDR       = 32'hF000_0100;

~~

//-------------------------------------------------------------------------------
// Local functions
//-------------------------------------------------------------------------------

function automatic logic [W_DATA-1:0] mem_read (
    logic [W_ADR:0] adr,
    int             bytes_num,
    int             bytes_max
    );
~~
endfunction : mem_read

function automatic void mem_write (
    logic [W_ADR-1:0]      adr,
    logic [W_DATA-1:0]     data,
    logic [(W_DATA/8)-1:0] bytes_en,
    int                    bytes_num,
    int                    bytes_max
    );
~~
endfunction : mem_write
  • L.146 - L.149 : 実行バイナリの読み込み
//-------------------------------------------------------------------------------
// Load file to mem
//-------------------------------------------------------------------------------
always @(negedge rst_n) begin
    memory = '{SIZE{'0}};
    if(stuff_file.len()>0) $readmemh(stuff_file,memory);
end
  • L.151以降 : AXI I/Fの実装
enerate for(gi=0; gi<N_IF; ++gi) begin : rw_if

//-------------------------------------------------------------------------------
// Read operation
//-------------------------------------------------------------------------------
always @(posedge clk, negedge rst_n) begin

~~

end endgenerate

うーーむ、特に気になる記述も無い。。。
アサーションか?と思って、コメントアウトしてみたけど、それでもエラーは変わらず。ってそりゃそうか、パースは通ってるっぽいんだし。 まさかと思って、メモリのサイズを変更してみた。

f:id:diningyo-kpuku-jougeki:20180819224908p:plain

動いた!!
画像のscopeのとこのテストベンチ階層構造にscr1_memory_tb_axiが入った状態でシミュレーションが出来ている。 初期サイズは1 * 1024 * 1024で1MBの領域をメモリとして確保しているが、それだと大きすぎる様子。
サイズを振って調べてみたところ32KBなら動くみたい。
シミュレーションでは、riscv-testが動けばいいので32KBくらいなら大丈夫かな、たぶん。。
とりあえず、Vivadoシミュレータでのシミュレーションも可能になったので、次はRISCVのビルド環境の構築に取り掛かる。

RISC-Vの実装の1つ - SCR1の解析 - Vivadoプロジェクト準備(2)

前回の記事では、Vivadoプロジェクトを立ち上げて、SCR1の合成環境を整えた。

tech-diningyo.hatenablog.com

そのあと、シミュレーションを実行したら、エラーが出たので要解析、、という状況であったので、その続き。

エラーの解析

というわけでエラーメッセージを再度チェック。

ERROR: [VRFC 10-2063] Module not found while processing module instance [/home/dnn-admin/workspace/hw/study/fpga-scr1/scr1/src/pipeline/scr1_pipe_brkm.sv:794]
ERROR: [VRFC 10-1040] module scr1_pipe_dbga_default ignored due to previous errors [/home/dnn-admin/workspace/hw/study/fpga-scr1/scr1/src/pipeline/scr1_pipe_dbga.sv:11]
ERROR: [VRFC 10-1040] module scr1_tapc_shift_reg(SCR1_WIDTH=32'b01,SCR1_RESET_VALUE=1'b0) ignored due to previous errors [/home/dnn-admin/workspace/hw/study/fpga-scr1/scr1/src/core/scr1_tapc_shift_reg.sv:9]
ERROR: [VRFC 10-1040] module scr1_tapc_data_reg(SCR1_WIDTH=32'b01,SCR1_RESET_VALUE=1'b0) ignored due to previous errors [/home/dnn-admin/workspace/hw/study/fpga-scr1/scr1/src/core/scr1_tapc_data_reg.sv:9]
ERROR: [XSIM 43-3322] Static elaboration of top level Verilog design unit(s) in library work failed.

エラーとしては5つ出ているけど、頭の1つが原因で後続の4つが出ている状況の模様。
ただ、モジュールが見つからないとのことだが、合成は通っているのでファイルの不足ではない。
ということで、コンパイルの順番を疑って見ていく。

f:id:diningyo-kpuku-jougeki:20180818182536p:plain

SCR1は、上記画像中の"scr1_arch_description.svh"というファイルでSCR1のコンフィグレーションを変更できるようになっている。
上記でエラーと”scr1_pipe_brkm.sv”や"scr1_brkm_matcher"はarch_descriptionから判断するにbreakpoint module。
ブレークポイントに関するモジュールを使用するかどうかもdefineで切り替えることができる。
bkrmが入っている2つのファイルの間にarch_descriptionが入っているのがどうも怪しいので、コンパイル順を変更する。
arch_descriptionはdefineでコアの構成を決めているので最初に読み込まれるべきなのでそのように変更。
#もともと、ヘッダとして扱われるべきファイルをsystem verilogとして登録したので、明確にコンパイル対象となったのがそもそもの原因の様子。

f:id:diningyo-kpuku-jougeki:20180818183348p:plain

再度シミュレーションを実行、、、と今度はelaborationは通過した。

Vivado Simulator 2017.4
Copyright 1986-1999, 2001-2016 Xilinx, Inc. All Rights Reserved.
Running: /opt/Xilinx/Vivado/2017.4/bin/unwrapped/lnx64.o/xelab -wto 0e6fead3633f402a8a5bfc48c6ea3f43 --incr --debug typical --relax --mt 8 -d SCR1_SIM_ENV= -L xil_defaultlib -L unisims_ver -L unimacro_ver -L secureip --snapshot scr1_top_tb_axi_behav xil_defaultlib.scr1_top_tb_axi xil_defaultlib.glbl -log elaborate.log
Using 8 slave threads.
WARNING: [XSIM 43-3431] One or more environment variables have been detected which affect the operation of the C compiler. These are typically not set in standard installations and are not tested by Xilinx, however they may be appropriate for your system, so the flow will attempt to continue. If errors occur, try running fuse with the "-mt off -v 1" switches to see more information from the C compiler. The following environment variables have been detected:
Starting static elaboration
Completed static elaboration

、、、が、その先でエラーが。。。

Compiling module xil_defaultlib.scr1_tapc_shift_reg(SCR1_WIDTH=3...
Compiling module xil_defaultlib.scr1_dbgc
Compiling module xil_defaultlib.scr1_core_top
Compiling module xil_defaultlib.scr1_dp_memory_default
Compiling module xil_defaultlib.scr1_tcm
Compiling module xil_defaultlib.scr1_timer
Compiling module xil_defaultlib.scr1_imem_router(SCR1_ADDR_PATTE...
Compiling module xil_defaultlib.scr1_dmem_router(SCR1_PORT1_ADDR...
Compiling module xil_defaultlib.scr1_mem_axi_default
Compiling module xil_defaultlib.scr1_top_axi
Compiling module xil_defaultlib.scr1_memory_tb_axi_default
ERROR: [XSIM 43-3316] Signal SIGSEGV received.

いや、SIGSEGVて。。。
未だ実行できず、次回に続く。。

RISC-Vの実装の1つ - SCR1の解析 - Vivadoプロジェクト準備(1)

RISC-Vの中身を勉強するために手頃な環境を用意したい。
ということで、RISC-Vのサイトに紹介されているコアから良さそうな物を1つ選んでそれをベースに環境を立ち上げていきたいと思う。

RISC-V

RISC-Vの説明をWikipediaで調べると、以下のように書いてある。

RISC-V(リスク ファイブ)は、オープン標準のRISCマイクロプロセッサの命令セット・アーキテクチャ (ISA) である。

ほとんど全てのISAと異なり、RISC-V ISAはいかなる用途にも自由に利用でき、誰もがRISC-Vチップおよびソフトウェアを設計、製造、販売可能である。最初のオープンアーキテクチャのISA[1]ではないが、幅広いデバイスに有用であるように設計されている点が重要である。命令セットは、ソフトウェアがサポートするのに十分な量があり、新しい命令セットの弱点を回避している。

プロジェクトは、2010年にカリフォルニア大学バークレイ校で開始されたが、現在は、多くのコントリビューターが、ボランティアもしくは企業の従業員として、大学外から参加している。[2] 例えば、グーグル、オラクル、ヒューレット・パッカードエンタープライズ(HPE)などが開発に参加している[3]。

RISC-V ISAは、小さく、速く、省電力で、実用性を重視して設計されてきているが、[4][5] 特定のマイクロアーキテクチャに過適合しないようにしている。[5][6][7][8]

2017年5月に、ユーザーレベルのISAのバージョン2.2が決定され、特権レベルISAが、ドラフト・バージョン1.10として提供されている。
RISC-V - Wikipedia

やっぱり魅力はいかなる用途にも自由に利用できるISAってところですね。
言及されているISAはRISC-Vのサイトに行くと見ることができる。

トップページ↓
riscv.org

ISA↓
riscv.org

RISC-Vコア

下記を見るといろいろなコアが紹介されている。

RISC-V Cores - RISC-V Foundation

- Rocket
- ORCA
- PULPino
- OPenV/mriscv
- VexRiscv
- Roa Logic RV12
- SCR1
- Hummingbird E200
- Shakti

SCR1

上記の中からSCR1という実装を解析をしていく。

github.com

選んだ理由は

  1. 実装言語がsystem verilog
  2. サポートしているRISC-V ISAが最新のもの(Previleged 1.10 / User 2.2)
  3. 比較的シンプルな実装(Rocketみたいなのと比べると、、の話)
  4. ドキュメントが整備されていて、とっつきやすそう(これ大事!!)
  5. いろいろカスタマイズ可能
  6. SDKも公開されてる(GitHub - syntacore/scr1-sdk: open-source SDK for SCR1 core)

FPGAプロジェクトの準備

お試しがてらSCR1のデータをgithubから持ってきてVivadoで合成を実行できるように環境を整えていく。

作業用ディレクトリの準備
$ mkdir fpga-scr1
$ cd fpga-scr1
$ mkdir vivado
$ git clone https://github.com/syntacore/scr1.git
Vivadoプロジェクト作成

Vivadoシミュレータの動作確認 - ハードウェアの気になるあれこれの要領でプロジェクトを作成。
その後、cloneしておいたSCR1のデータを取り込んでいく。
"Add Sources"を選んでdesign sourcesでデータを取り込む。
まとめてデータを取り込むの"Add Directories"でcloneしたSCR1のディレクトリごとインポート

f:id:diningyo-kpuku-jougeki:20180812220147p:plain

SCR1はトップ改装をAXI or AHBのいずれを使用するかをdefineで選択可能になっている。
今回はAXIを使用するので、scr1_top_axiをトップモジュールに指定しておく。
またscr1/src/includesの下はインポートしたままだとverilogとして解析されるので"Source File Properties"から"Type"をsytem verilogに変更しておく。
ここまでの作業後に、"Run Synthesis"を実行するととりあえず合成が通ることは確認できた。

シミュレーション環境の準備

前項と同じく"Add Sources"で"simulation sources"にscr1/src/tb以下のデータを取り込む。
本当はRISC-Vのコンパイラでテスト用のプログラムデータを生成する必要があるのだが、とりあえずこの状態でコンパイルが通るかを確認するため"Run Simulation"を実行。

したんだけど、、、なんかエラー出た。。。

f:id:diningyo-kpuku-jougeki:20180812221652p:plain

詳細は"elaborate.log"を見ろ、とのこと↓

Vivado Simulator 2017.4
Copyright 1986-1999, 2001-2016 Xilinx, Inc. All Rights Reserved.
Running: /opt/Xilinx/Vivado/2017.4/bin/unwrapped/lnx64.o/xelab -wto 0e6fead3633f402a8a5bfc48c6ea3f43 --incr --debug typical --relax --mt 8 -d SCR1_SIM_ENV= -L xil_defaultlib -L unisims_ver -L unimacro_ver -L secureip --snapshot scr1_top_tb_axi_behav xil_defaultlib.scr1_top_tb_axi xil_defaultlib.glbl -log elaborate.log
Using 8 slave threads.
WARNING: [XSIM 43-3431] One or more environment variables have been detected which affect the operation of the C compiler. These are typically not set in standard installations and are not tested by Xilinx, however they may be appropriate for your system, so the flow will attempt to continue. If errors occur, try running fuse with the "-mt off -v 1" switches to see more information from the C compiler. The following environment variables have been detected:
Starting static elaboration
ERROR: [VRFC 10-2063] Module not found while processing module instance [/home/dnn-admin/workspace/hw/study/fpga-scr1/scr1/src/pipeline/scr1_pipe_brkm.sv:794]
ERROR: [VRFC 10-1040] module scr1_pipe_dbga_default ignored due to previous errors [/home/dnn-admin/workspace/hw/study/fpga-scr1/scr1/src/pipeline/scr1_pipe_dbga.sv:11]
ERROR: [VRFC 10-1040] module scr1_tapc_shift_reg(SCR1_WIDTH=32'b01,SCR1_RESET_VALUE=1'b0) ignored due to previous errors [/home/dnn-admin/workspace/hw/study/fpga-scr1/scr1/src/core/scr1_tapc_shift_reg.sv:9]
ERROR: [VRFC 10-1040] module scr1_tapc_data_reg(SCR1_WIDTH=32'b01,SCR1_RESET_VALUE=1'b0) ignored due to previous errors [/home/dnn-admin/workspace/hw/study/fpga-scr1/scr1/src/core/scr1_tapc_data_reg.sv:9]
ERROR: [XSIM 43-3322] Static elaboration of top level Verilog design unit(s) in library work failed.

モジュールが無いって言われてる。何か設定が足りてないのか。。。
後日確認することにしよう。

Vivadoシミュレータの動作確認

去年辺りから日本でもよく聞くようになったRISC-Vを触ってみたくなったので、Chiselを勉強してみようと思いたった。
RISC-Vもだし、Chiselについてもあんまり日本語の記事見当たらなかったので備忘の意味も兼ねてブログに書いて公開してみる。

Chiselは、デジタル回路設計用の、オープンソースのハードウェア記述言語(HDL: Hardware Description Language)の一種である。カリフォルニア大学バークレー校で開発が行われている。Chiselは、Scalaの内部DSLとして実装されている。
Chisel - Wikipediahttps://ja.wikipedia.org/wiki/Chiselja.wikipedia.org

いや、RISC-Vはむちゃくちゃ詳しく書いてくださってる方が何人かいらっしゃるんですがね、、msyksphinzさんとか↓

msyksphinz.hatenablog.com

まずは各種Chiselの環境を入れる前にいくつかやっておきたいがある(下記参照)のでまずはそこから。

やっておきたいこと
  1. scalaの勉強
  2. シミュレータの準備

1. は上記Wikiの引用にもあるとおり、ChiselはScalaの内部DSLだから。Scala、、書けないですし。。。
2.はやっぱりシミュレーションで動かしたいよね!!という単純な理由。

環境の準備

最終的には、Chisel→RTL→FPGA実装で何か動かしたい!!なのでVivado入れて合成環境&シミュレーション環境を構築する。
これをやるにあたって、Vivadoシミュレータって制限あったりしないかしら、と思ったのだけど特に制限もない模様。
まあ、そんな大規模デザインをシミュレーションすることもないだろうから、なんか起きた時に考えよう。

Vivado® シミュレータは、豊富な機能を備えた Verilog、SystemVerilog および VHDL 言語に対応する混合言語シミュレータです。すべての Vivado HLx Edition に含まれ、追加料金は不要です。デザイン サイズ、インスタンス、または行数の制限がないため、1 つの Vivado ライセンスで無制限のインスタンスの混合言語シミュレーションを実行できます。
Vivado シミュレータ

Vivadoのインストール

先に、これ以降の自分の作業環境を記載

CPU AMD Ryzen 7 1700
Memory 16GB
OS Ubuntu 16.04
Kernel Version 4.13.0-45

Vivadoは以下のページからLinux版のウェブインストーラーをダウンロード

japan.xilinx.com

インストールについては、特に変更もせずにインストール。
途中で聞かれるどのバージョンを使うかの選択肢は、"Web" Pack"を選択。
Webインストールでそこそこのデータをダウンロードするのでしばし待機。。。

Vivadoの起動

インストール終わるとデフォルト設定なら/optの下にVivadoがインストールされる。
その中に以下の設定があるので、こいつをsourceすると各種設定やってくれるので楽。。

- /opt/Xilinx/Vivado/2017.4/settings64.sh

source /opt/Xilinx/Vivado/2017.4/settings64.sh 

設定ファイル読みこみの後、Vivadoを起動
以下の手順で適当にテストプロジェクトを作成する

  1. [FIle] -> [New Proect]を選択でプロジェクト作成画面が立ち上がる
  2. [Next]押して、"Project Name"画面で適当にプロジェクト名と場所を指定
  3. 次の画面で"RTL Project"のボタンにチェック
  4. "Add Sources"は何もないのでそのまま[Next]を選択
  5. "Add Constraints"も同様[Next]を選択
  6. "Default Parts"は適当にSpartan-7のデバイスから選択
  7. 次の画面で[Finish]押して作成完了

テスト用RTLの作成

めちゃ適当に32bitのFFを作成する。

1. 画面左の"PROJECT MANAGER"から[Add Sources]を選択

f:id:diningyo-kpuku-jougeki:20180811183547p:plain

2. 開いた画面で"Add or create degisn sources"を選択して[Next]

f:id:diningyo-kpuku-jougeki:20180811183717p:plain

3.[Create File]を選択して、開いた画面でFile Nameを適当に埋めてファイル作成

f:id:diningyo-kpuku-jougeki:20180811183853p:plain

4. 作成したファイルにFFを実装。

module test_ff(
     input wire        clk
    ,input wire        rst_n
    ,input wire [31:0] i_data
    ,input wire        wren
    ,output reg [31:0] o_data
    );

   always @(posedge clk or negedge rst_n) begin
      if (!rst_n) begin
         o_data <= #1 {32{1'b0}};
      end
      else if (wren) begin
         o_data <= #1 i_data;
      end
   end
   
endmodule // test_ff

5. シミュレーション用のテストベンチファイルの作成
1-4と同じ手順で作るが、2.の時に"Add or create simulation sources"を選択。これを選択することで"PROJECT MANAGER"上の"Sources"の"Simulation Sources"の下にベンチファイルが生成される。

f:id:diningyo-kpuku-jougeki:20180811184209p:plain

6. 適当にベンチ記述を実装。今回はリセット解除後にFFにライトして値チェックしておしまいな感じ。

module topsim();

   // clock
   reg clk;
   
   initial begin
      clk = 1'b0;

      forever begin
         clk = #50 !clk;
      end
   end

   // reset
   reg rst_n;
   
   initial begin
      rst_n = 1'b1;

      #100;

      rst_n = 1'b0;

      #100;

      rst_n = 1'b1;
   end // initial begin

   // ff access
   reg r_wren;
   reg [31:0] r_wdata;

   wire [31:0] w_o_data;

   task idle();
      #1
      r_wren = 1'b0;
      @(posedge clk);
   endtask // idle
   
   task wr(input [31:0] wdata);
      #1
      r_wren = 1'b1;
      r_wdata = wdata;
      @(posedge clk);
   endtask // wr

   // write ff
   initial begin
      idle();
      @(posedge rst_n);

      idle();
      
      wr(32'hdead_beaf);
      idle();

      if (w_o_data == 32'hdead_beaf) begin
        $display("OK");
      end
      else begin
        $display("NG");
      end

      $finish(1);
      
   end // initial begin
   
   test_ff DUT
     (
       .clk     (clk            )
      ,.rst_n   (rst_n          )
      ,.i_data  (r_wdata        )
      ,.wren    (r_wren         )
      ,.o_data  (w_o_data       )
      );
      
endmodule

7. シミュレーションの実行
"Run Simulation"をクリック!!

f:id:diningyo-kpuku-jougeki:20180811184721p:plain

8. 文法エラーがなければシミュレーションが実行される

f:id:diningyo-kpuku-jougeki:20180811184956p:plain

と、これでとりあえず動作確認はできた。