FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-Vの連載をInterface誌に寄稿しました(2018年2月号から)

CQ出版のInterface誌2018年2月号から、RISC-Vについて連載を寄稿しました。タイトルは、「オープンソースCPU「RISC-V」の研究」です。

結構な文章と図を寄稿したのだけれども、紙面の都合上で連載になったらしい。何回続くのかはわかりませんが、ゆっくりとお付き合いいただければ。

ちなみに今月号は歴史と登場の背景なので、技術的にはあまり面白くない。本当はCPUと特許の歴史とかもっと調べて深堀したいんだけどなあ。 SuperHモトローラの話とか、すごく面白そうだ。

ちなみにストーリーとしては、大きく分けて

  1. RISC-Vについて
  2. RISC-Vの仕様について
  3. HiFive1を使ってみる
  4. Rocket-Chipを使ってみる

という感じで寄稿したはず。まあ、どのように編集されるかは、編集者さんにお任せしているので、良く分かりません。

f:id:msyksphinz:20171226225250p:plain

学生の頃、CQ出版に寄稿すると言えばかなりのレジェンドであると聞かされていたので、まさか自分がこのように原稿を書くことになるとは思っていなかった。 これで少しでもレジェンドに近づけるかなあ。

まだまだ自分はひよっこだし、文章力もいまいちなので、読みにくい部分はあると思いますがよろしくお願いします。

あと、何か月も連載しているとあらかじめ提出した原稿が古くなるので、その辺は随時更新していかなければならないし、このブログを通じて小話のようなものも書いていければ良いかなと思う。 特にこういうStep by Stepの話って、何か月も引っ張るような話でもないけど、まあ特集じゃないので文章を省略する必要もないしじっくり解説できる。 内容的に古くなったら更新していけばいいし、新しいネタがあればちょいちょい突っ込んでいけばいいかもしれない。

というわけで、みなさんバシバシ買ってください!

「半導体・ハードウェア開発 2017」Advent Calendarが終了しました

qiita.com

12/01から始めた「半導体・ハードウェア開発 2017」Advent Calendar、全ての日でエントリが埋まり、無事に終了しました。

まずはご協力頂いた皆様、どうもありがとうございました。皆様のご協力がなければ、25日全てを埋めることは不可能でした。改めて感謝致します。

25日の日程のうち、私は10日を担当しました。途中で仕事が忙しくなって結構苦しくなりましたが、何とか完走できてよかった。 ご協力してくださる方は非常にうれしかったですが、やはり去年のAdvent Calendarにも書いてくださった方が多いですね。 そういう意味では、私自身あまり進化していないかもしれない。。来年もやるかどうかは微妙ですね。

  • 終結果(2017/12/26 0:00時点)
    • カレンダー数 : 593
    • 25日完遂カレンダー数 : 230/ 593
    • 購読者数ランキング 114 / 230

ランキングで言うと非常に中途半端ですが、でも593カレンダーのうち完遂できたのはわずかに230カレンダーですので、その中で114位というのはかなり頑張った方だと思っています。

平日は夜中に頑張れますが、休日は別の用事もあったりして苦手で、他の方が支援して下さったのはありがたかったです。

今年はRISC-Vが徐々に知名度が上がってきたかなと思います。RISC-V関係のイベントで2件発表もさせてもらいました。 が、RISC-Vだけではネタもあまりないので、今年は少し範囲を広げた、という次第です。

やはり、去年と比べて機械学習や高位合成、などの話題が増えた、という印象ですね。

Google Voice Kitを使ってみる(3. 音声→文字を認識するアプリケーションの作成)

Google Voice Kitを使ってみる、続き。 前回、アプリケーションが動作するようになったので、自分で音声認識のプログラムなどを作ってみたい。

以下のサイトを参考にして、プログラムを作成した。ちなみ、Google Speech APIを使用するために課金の情報を入力する必要がある。 1年間の無料評価ライセンスがあるのでそれを使用しているが、1年間の間にちゃんとしっかり活用しないとなあ。。。

aiyprojects.withgoogle.com

  • /home/pi/src/motion.py
#!/usr/bin/env python3

import aiy.audio
import aiy.cloudspeech
import aiy.voicehat

def main():
    '''Start voice recognition when motion is detected.'''
    button = aiy.voicehat.get_button() 
    recognizer = aiy.cloudspeech.get_recognizer()
    recognizer.expect_phrase('repeat after me')
    aiy.audio.get_recorder().start()
    while True:
        print('Press the button and speak')
        button.wait_for_press() 
        print('Listening ...') 
        text = recognizer.recognize()  # 音声認識を実行する。
        print(text)
        aiy.audio.say('You said ')
        aiy.audio.say(text)

if __name__ == '__main__':
    main()

サンプルプログラムにはaiy.audio.say('You said ', text)と書いてあるが、実行中にエラーメッセージが出てしまうので修正しなければならなかった。

Press the button and speak
Listening ...
repeat after me
Unknown language: repeat after me
Valid languages:
en-US
en-GB
de-DE
es-ES
fr-FR
it-IT

Usage: pico2wave <words>
  -w, --wave=filename.wav     Write output to this WAV file (extension SHOULD be .wav)
  -l, --lang=lang             Language (default: "en-US")

Help options:
  -?, --help                  Show this help message
      --usage                 Display brief usage message
Traceback (most recent call last):
  File "./src/motion.py", line 22, in <module>
    main()
  File "./src/motion.py", line 19, in main
    aiy.audio.say('You said ', text)

これを実行して、音声認識を実行する。

$ ./src/motion.py 
Press the button and speak
Listening ...
what time is it now     # 認識結果
Press the button and speak
Listening ...

ある程度きちんと認識できる。ただし、"Turn on the light", "Turn off the light" の「ターン」の発音が下手くそすぎて認識されない。 スマートフォンGoogleに喋らせるとうまく認識するので、これは日本人の発音の問題かなあ。 日本語のAPIがきちんと使えるようになればいいのだが。

f:id:msyksphinz:20171224232547p:plain

アプリケーション実行中はボタンのLEDが点灯する。格好いい。

関連記事

Google Voice Kitを使ってみる(2. サンプルプログラムの実行)

Google Voice Kitを使ってみる、続き。 前回、組み立てが完了したので次にソフトウェアをダウンロードして実行する。

まず、MagPiのウェブサイトからISOファイルをダウンロードする。 MicroSDカード(4GB以上?)を用意し、EtcherでISOファイルを書き込む。

aiyprojects.withgoogle.com

f:id:msyksphinz:20171223223403p:plain

SDカードをRaspberry-Pi3に差し込み、ブートすると、ディスプレイにデスクトップ画面が現れる。

f:id:msyksphinz:20171223230907p:plain

ワイヤレスLANを接続する。

f:id:msyksphinz:20171223235114p:plain

Voice / Microphone テストを実行しよう。"Check Audio"プログラムをクリックする。

f:id:msyksphinz:20171223235428p:plain

マイクから、"Front, Centre"と聞こえる。次に、"Testing 1,2,3..." とスピーカーに喋りかけると、その声がリピートされる。

成功だ!ちゃんと動作していることを確認できた。

関連記事

Google Voice Kitを使ってみる(1. 組み立て)

Google Voice Kit、前から欲しかったのだが、ついにAIY Projectsから発送され、自宅に到着した。 実際には先週には到着していたのだが、RISC-V Dayなど忙しさが重なり、試行できなかった。 土日でようやくトライできるようになったので、早速やってみよう。

ホーム - Raspberry Pi Shop by KSY

これが内容物一覧。

f:id:msyksphinz:20171223223702p:plain

Raspberry-Pi3が必要。

f:id:msyksphinz:20171223223815p:plain

Raspberry-Pi3に接続することでくみ上げる。

f:id:msyksphinz:20171223223857p:plain

ちなみに、組み立てるためには、マニュアルには書かれていない細目のスクリュードライバーが必要なので注意。

f:id:msyksphinz:20171223224833p:plain

あと、マイクの接続には両面テープが必要と書いてある。別に両面テープでなくてもいいのだが、普通のテープだと少し格好悪い。 はんだ付けの角が出っ張ってしまい、マイクが浮いているのが少し残念。

f:id:msyksphinz:20171223232114p:plain

完成形は以下のようになる。

f:id:msyksphinz:20171223224027p:plain

関連記事

「スターウォーズ エピソード8 最後のジェダイ」を見てきた

スターウォーズ大好きなんです。。。

starwars.disney.co.jp

本当は公開当日に行きたかったけど、忙しかったので一週間遅れ。レイトショーで見てきた。2時間30分って長いよ!

ストーリーはエピソード7ほど大きくは動かなかったような気がする。いろんな人が死んだけど。 事前情報は相変わらず何もないので、結構ドキドキハラハラしながら見ていた。 なんか旧三部作よりも、ファースト・オーダーとレジスタンスの戦力差が大きく見えて、ファースト・オーダー強すぎ!って感じがするね。

そんな中、どうやってエピソード9につなげていくのか、気になるところ。 今回はそんな、繋ぎの回って感じだった。

サントラ出たら買おうかなあ。DVDもまた買おうかな。エピソード7、ローグワン両方買っちゃったんだよね。

7th RISC-V Workshop の Vector Extension Proposal 概要

RISC-V 7th Workshopでは、Vector Extensionの説明がなされている。

https://content.riscv.org/wp-content/uploads/2017/12/Wed-1330-RISCVRogerEspasaVEXT-v4.pdf

f:id:msyksphinz:20171222012224p:plain

資料を読みながらまとめてみる。追記の可能性あり。


RISC-V Vector Extensionの特徴としては、

  • なるべくコンパクトにすること。
  • ベクトルレジスタの処理にマスクを加え、任意の要素のみ演算が適用されるようにする。
  • スカラー、ベクトル、行列の形式などをサポートする(ただし行列形式はオプションであり、ベースの仕様には追加されない)。
  • 型を混在させることが出来る。
  • (自称)これまでのベクトル命令の中で最高の出来である。

ベクトルレジスタ

ベクトルレジスタはV0からV31までの32本が定義されている。

  • 各ベクトルレジスタには"Type"とよばれるレジスタが付与される。これは16bit長のベクトルレジスタである。
  • 各ベクトルレジスタには"Type"が付けられ、ベクトルレジスタ毎に異なる"Type"を設定することが出来る。
  • "Type"はvdcfgレジスタにより設定することが出来る。16bit×32本で512bitあるのだが、これをどのように設定することが出来るのかは詳細が語られていない。
  • おそらくvdcfgレジスタが複数作られ、csrrw命令により設定されていくものと思われる。

ベクトル算術演算の実行

  • 実装されているベクトルレジスタの長さはMVLで定義する。一方で実行中の演算が適用されるベクトルの要素の長さはVLで定義する。
  • MVLの長さは全てのベクトルレジスタにおいて同一である。
  • ベクトルレジスタの長さと、演算のレイテンシは別物として考える。vadd命令を実行した場合その命令を1サイクルで実行する必要はない。何サイクル化に分けて実行して構わない。

f:id:msyksphinz:20171221011520p:plain

  • 4サイクルで実行する場合

f:id:msyksphinz:20171221011615p:plain

  • 2サイクルで実行する場合

f:id:msyksphinz:20171221011634p:plain

マスク付きの実行

ベクトル命令は、マスクを使ってエレメント毎に演算の有効無効を指定できる。例えば、vadd v5, v3, v4, v1.tとする場合、以下のようにv1.tで指定されるレジスタの値に依存してマスクがかけられる。

f:id:msyksphinz:20171221012156p:plain

メモリアクセス

ロード命令・ストライド付きロード命令

ロード命令は非常にシンプルなロード命令。Unalignedも許可するが、非常に低速なことが前提。

ストライド付きロード命令は、いわゆるGather命令。RISC-Vの仕様であるGather命令はさらにえげつない。 f:id:msyksphinz:20171221013344p:plain

Gather命令

Gather命令は、各ベクトルエレメントで、ロードするメモリアドレスのオフセットを自由に設定できる。 結構実装が大変になる気がするが。。。

f:id:msyksphinz:20171221014131p:plain

ベクトルレジスタの型、型変換

  • 異なる"Type"が設定されたレジスタ同士の演算でも、ある程度ルールの中ならば演算を適用させることが出来る。
vcvt v1(F32) --> v0(F16)
vcvt v1(u8) --> v0(F32)
vcvct v1(F32) --> v0(I32)

この場合のベクトルレジスタのサイズが非常にややこしいことになる。 各ベクトルレジスタは異なる型を持つことが出来るが、MVL(ベクトルレジスタ当たりのエレメントの数)は常に同一である。 したがって、以下のようなことが出来るようになる。

  • プログラムコードが2つのF16ベクトルレジスタおよび2つのF32ベクトルレジスタを必要としている場合、
    • F16(=2byte)×2 + F32(=4byte)×2 = 12byteが必要となる。

このとき、ベクトルレジスタのハードウェアとしては  4\text{byte}\times 4\text{element}\times 32\text{本}=512\text{byte} 保持しているとすると、 \text{MVL}=512\text{byte} / (12\text{byte} + 4\text{byte(使用しないレジスタ)}) = 32となり、1ベクトルレジスタ当たり32エレメントを持つことが出来るようになる。

これをどのようにベクトルレジスタに当てはめるかは実装に任されている。例えば、以下のような構成が可能となる。

上位の 4\text{byte}\times 4\text{element}\times 4\text{本}\times 2\text{レジスタ}(=128\text{byte}) をF16のベクトルレジスタとして使い、 次の4\text{byte}\times 4\text{element}\times 8\text{本}\times 2\text{レジスタ}(=256\text{byte}) をF32のベクトルレジスタとして使う。

f:id:msyksphinz:20171222012123p:plain

以上のように、ベクトルレジスタのハードウェアを実際のアーキテクチャ的などのレジスタに割り当てるかは非常に柔軟に持つことが出来るようになる。 その分、かなり制限を加えないと実装が大変そうだが... (検証も大変そうだ)。

と思ったら、命令コード表には入っていた。師匠に指摘していただきました。ありがとうございます。

f:id:msyksphinz:20171226010836p:plain