Begin Again

Begin Again

technology

Hardware Programming with Chisel #1 Hello, Scala!

f:id:Orihasam810:20201213163215j:plain
https://www.chisel-lang.org/

1. What is Hardware Programming?

 ハードウェアプログラミングは、ロジック回路をハードウェア記述言語(以下HDL:Hardware Description Language)によって実現する方法である。HDLは、電子回路の経時的振舞いと空間的構造を表現することで、ハードウェアの動作仕様を記述するための言語であり、半導体メーカーにおいて、ASIC(Application-Specific Integrated Circuit)やFPGA(Field-Programmable Gate Array)と呼ばれるLSI(Large Scale Integrated circuit)で所望の回路を実現するために用いられている。
 最近では、Deep learningにおける並列計算を行うための専用回路を実装することで、消費電力を抑えつつ、学習や推論に掛かる時間を短縮するための専用回路(google社のTPUなど)開発のニーズが高まっていることもあり、Deep Learning技術に精通したソフトウェアエンジニアが、HDLを用いたハードウェアプログラミングを習得する必要に迫られることもあるのではないだろうか。

2. Species of HDL.

 現在HDLで主流となっている言語には、Verilog HDLと、VHDLの2つがある。Verilog HDL、VHDLの双方とも1980年代に登場した言語であり、IEEEによって標準化されている。しかし、これらの言語は元々回路の動作使用の記述や回路シミュレーションを主目的として開発された言語のため、回路設計を主目的とするには若干不向きであることや、ソフトウェア開発用の言語(CやPythonなど)とは使い勝手が違うためソフトウェア開発者が学ぶにはハードルが高いといった欠点がある。
 また高位合成と呼ばれる方法で、C言語等のソフトウェアプログラミング用ソースコードからハードウェアプログラミングを行うツールがxilinx社等により提供されているが、ソフトウェアプログラミング言語はあくまでも処理のフローを記述する言語であるため、効率的な回路を記述するためには結局、HDLにより設計する必要がある。
 私自身ソフトウェアプログラミングの経験しかないため、このブログでは、回路設計を主目的とした言語かつ、ソフトウェアプログラミング言語ScalaDSL(Domain-Specific Language)ライブラリであるChiselを用いてハードウェアプログラミングをしていきたいと思う。

3. About Chisel.

 Chiselは2つのグループの開発者をターゲットにしている。
 一つ目が、VHDLVerilogに使い慣れており、ハードウェア生成のためにPythonJavaを使用しているハードウェア設計者、もう一つが、プログラムの高速化等の目的で、ハードウェア設計に興味があるソフトウェアプログラマである。
 Chiselは、オブジェクト指向関数型言語といったデジタル設計におけるソフトウェアプログラミング言語のメリットを備えている。
 なお、Chiselにおけるハードウェア設計では、テストや合成の中間言語としてVerilogが用いられているが、Chiselを使用する上で、Verilogの深い知識や理解は不要である。

4. Install Scala.

Chiselを使用するためにまずは、Scalaのインストール方法について紹介していく。WindowsMacでのインストール方法については、各自Scalaの公式サイト等を参照して欲しい。
なお、この記事では、特に明示しない限りUbuntu 18.04.5上で作業している。 OpenJDKのインストール scalaのプログラムやscala用のビルドツールは、JVM上で動作するため、JDKのインストールが必要である。

$ sudo apt install openjdk-8-jdk

sbt(scala build tool)のインストール
sbtはscalaのビルドや仮想環境・外部ライブラリの管理が行える便利なツールである。

$ echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list
$ curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo apt-key add
$ sudo apt update
$ sudo apt install sbt

これでScalaの開発環境が整った。

5. Hello, World! with Scala.

Scalaプログラミングの基本について書いていこうと思う。 まずはhello worldする。最初に作業用ディレクトリを作成する。

$ mkdir scala_tutorial
$ cd scala_tutorial

次にプロジェクトのテンプレートを作成する。

$ sbt new scala/hello-world.g8

プロジェクトの名前を聞かれたら任意の名前をつける。今回は"hello-world"とした。

name [Hello World template]: hello-world

作成されたテンプレートは以下のような構成となっている。

.
├── hello-world
│   ├── build.sbt
│   ├── project
│   │   └── build.properties
│   └── src
│       └── main
│           └── scala
│               └── Main.scala
├── project
│   └── target
└── target
    ├── global-logging
    └── task-temp-directory

10 directories, 3 files

作成されたテンプレートには最初からhello world!を表示するためのプログラムが作成されている(hello-world/src/main/scala/Main.scala)。 Hello Worldを表示するプログラムの中身は以下のようになっている。

object Main extends App {
   println("Hello, World!")
 }

 1行目では、objectをMainと定義している。またextendsは、Appを継承していることを示している。この記述とすることにより、object内にmainメソッドを記述することなく、objectに記述されているコードを実行できる。printlnは末尾改行付き標準出力。  プロジェクトを実行するには以下のコマンドを入力する。なお初回実行時はコンパイルに多少の時間が掛かる。

$ sbt
sbt:hello-world> run

実行結果

Hello, World!

 次に簡単な数値計算を行ってみる。

object Main extends App {
   val x = 2
   val y = 3
   var z = 0
   println("z:"+z)
   z = x + y
   println("z:"+z)
 }

 Pythonは型推定の機能があるため、変数に型の宣言は必要ないが、scalaでは変数の型を明示的に宣言する必要がある。valは再代入することができない変数の宣言、varは再代入することが可能な変数の宣言である。
 上記のプログラムの実行結果は以下の通り。

z:0
z:5

 最初に出力されたzは代入前の初期値である0の値を保持しており、2回目に出力されたzは、x+yの計算結果を保持していることが分かる。
 次にif式とfor式を試してみる。プログラミングにおいて式は計算結果の値を返すモノ、文は評価は行うが値を返さないモノを意味している。つまりifやforは値を返すことができる。ただしこの記事では、式であることが重要であるようなプログラムは作成しない。
 if式とfor式を試すために、1から15まで順に変数iに代入し、iの値が3の倍数であればfizzと表示し、5の倍数であればfuzzと表示、15の倍数であればfizzbuzzと表示、いずれの倍数でもなければiの値を表示するプログラムを作成する。

object Main extends App {
  var n = 15
  for{i <- 1 to n}{
    if(i%15==0){
      println("FizzBuzz")
    } else if(i%3==0){
      println("Fizz")
    } else if(i%5==0){
      println("Buzz")
    }else{
      println(i)
    }
  }
}

 3行目は、iが1からnまで1つずつインクリメントして{}内のプログラムを繰り返し実行する。※インクリメント数を変更する場合は、 for{i <- (1 to n by 2)}のように「by 値」を追加する。
 if式では()無いの式がTrueであるとき、{}内のプログラムを実行する。else ifには複数条件式を設定する場合、elseにはいずれの条件にも合致しなかった場合の処理を記述する。
 実行結果

1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz

 以上でscalaの基本的な文法紹介は終わりにして、次回以降はChiselの環境構築及びプログラミングについて書きたいと思う。

orihasam.hatenadiary.com

【送料無料】 Scalaスケーラブルプログラミング 第3版 / マーティン・オダースキー 【本】

価格:5,060円
(2021/1/23 14:38時点)

【POD】Chiselを始めたい人に読んで欲しい本 (技術の泉シリーズ(NextPublishing)) [ 七夕 雅俊 ]

価格:2,750円
(2021/1/23 14:38時点)