FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス <a href="https://msyksphinz.github.io/github_pages/">

Googleの量子コンピュータNISQ向けオープンソースフレームワークCirqを試す (1. インストールとチュートリアル)

https://github.com/quantumlib/Cirq/raw/master/docs/Cirq_logo_color.svg?sanitize=true

Google量子コンピュータフレームワークだ!Q#も一応トライしたが、マスターする前にある程度動かした状態で投げ出してしまっていた。

GitHub

github.com

ドキュメント

Cirqのインストール

インストールは Ubuntu 18.04 LTS の上で行った。 "Installing Cirq"を参考にインストールする。

$ sudo apt-get install python3-tk texlive-latex-base latexmk
$ pip3 install --upgrade pip
$ pip install cirq

動作確認は以下で実行するらしい。なるほど、実行できた。でもこれは何だ?

$ python -c 'import cirq; print(cirq.google.Foxtail)'
(0, 0)───(0, 1)───(0, 2)───(0, 3)───(0, 4)───(0, 5)───(0, 6)───(0, 7)───(0, 8)───(0, 9)───(0, 10)
│        │        │        │        │        │        │        │        │        │        │
│        │        │        │        │        │        │        │        │        │        │
(1, 0)───(1, 1)───(1, 2)───(1, 3)───(1, 4)───(1, 5)───(1, 6)───(1, 7)───(1, 8)───(1, 9)───(1, 10)

チュートリアル

Tutorialを読んで、ソースコードをコピペしてみる。

Qubitの定義

以下のような記述でQubitを定義するらしい。そしてこれはすべてPythonで記述できる。

  • cirq_qubits.py
import cirq

# define the length of the grid.
length = 3
# define qubits on the grid.
qubits = [cirq.GridQubit(i, j) for i in range(length) for j in range(length)]
print(qubits)
$ python3 cirq_qubits.py
[GridQubit(0, 0), GridQubit(0, 1), GridQubit(0, 2), GridQubit(1, 0), GridQubit(1, 1), GridQubit(1, 2), GridQubit(2, 0), GridQubit(2, 1), GridQubit(2, 2)]

この「グリッド」が何者なのかはまだよくわからないが、まあとりあえずこの例では3×3の量子ビットを定義したと考えていいだろう。

これに対してHゲート(Hadamard)と、Xゲート(量子の回転)を定義する。量子ビットのグリッド(X, Y)X+Yが偶数ならばHゲート、奇数ならばXゲートを適用する。

$ python3 cirq_qubits.py
(0, 0): ───H───────

(0, 1): ───────X───

(0, 2): ───H───────

(1, 0): ───────X───

(1, 1): ───H───────

(1, 2): ───────X───

(2, 0): ───H───────

(2, 1): ───────X───

(2, 2): ───H───────

とりあえずチュートリアルをしっかり読まないと理解できそうにないが、コピペするとこんな格好いい量子回路を作ることができるらしい。面白いな!

$ ./qbit_one_step.py
(0, 0): ───X^0.1───X───────────@───────X───────────────────────────────────────────────────────@───────────────
                               │                                                               │
(0, 1): ───X^0.1───────────────┼───────X───@───────X───────────────────────────────────────────@^0.3───@───────
                               │           │                                                           │
(0, 2): ───X^0.1───Z^0.2───────┼───────────┼───────X───@───────X───────────────────────────────────────@^0.3───
                               │           │           │
(1, 0): ───X^0.1───Z^0.2───X───@^0.3───X───┼───────────┼───────X───@───────X───────────────────────────────────
                                           │           │           │
(1, 1): ───X^0.1───Z^0.2───────────────X───@^0.3───X───┼───────────┼───────────@───────────────────────────────
                                                       │           │           │
(1, 2): ───X^0.1───────────────────────────────────X───@^0.3───X───┼───────X───┼───────@───────X───────────────
                                                                   │           │       │
(2, 0): ───X^0.1───────────────────────────────────────────────X───@^0.3───X───┼───────┼───────────────@───────
                                                                               │       │               │
(2, 1): ───X^0.1───Z^0.2───────────────────────────────────────────────────────@^0.3───┼───────────────@^0.3───
                                                                                       │
(2, 2): ───X^0.1───Z^0.2───────────────────────────────────────────────────X───────────@^0.3───X───────────────
f:id:msyksphinz:20180725002739p:plain

RISC-V SpikeシミュレータでC/C++のprintfを実現する仕組み (6. ファイルシステムの呼び出し)

Hello Worldのプログラムを動かしながら、RISC-V Spikeシミュレータのログを追っていき、RISC-Vのブートシーケンスを追っていく、その3。

Spikeシミュレータはファイルの呼び出しもできる。これを実現しているのは、Spikeとは外部に接続されているpk(Proxy Kernel)だ。

試しにこんなプログラムを書いてRISC-VのGCCコンパイルしてみる。

#include <stdio.h>
#include <stdlib.h>

int main ()
{
  printf("Hello World\n");

  FILE *fp;
  if ((fp = fopen("sample_hello.txt", "w")) == NULL) {
    perror ("sample_hello.txt");
    exit(EXIT_FAILURE);
  }
  fprintf (fp, "Hello World\n");
  fclose (fp);

  if ((fp = fopen("sample_hello.txt", "r")) == NULL) {
    perror ("sample_hello.txt");
    exit(EXIT_FAILURE);
  }
  char cin[100];
  fscanf (fp, "%s", cin);
  printf ("%s\n", cin);

  char c[100];
  scanf("%s", c);
  printf("%s\n", c);

  return 0;
}
run: file_access_riscv file_access_x86
    spike pk $<

file_access_riscv: file_access.c
    riscv64-unknown-elf-gcc $^ -o $@

file_access_x86: file_access.c
    gcc $^ -o $@

これで実行してみると、通常のprintf/scanfはProxy Kernelの力で問題なく読み取りができる。一方で、ファイルシステムのほうは少し工夫が必要だった。 上記のプログラムでsample_hello.txtが存在しない場合、エラーとなって終了してしまう。

$ make run
spike pk file_access_riscv
Hello World
sample_hello.txt: No such file or directory
Makefile:2: recipe for target 'run' failed
make: *** [run] Error 1

ファイルをあらかじめ作っておくと、問題なく動作する。これはpkのバグか?仕様か?

$ make run

spike pk file_access_riscv
Hello World
Hello
hello
hello
$ cat sample_hello.txt
Hello World
f:id:msyksphinz:20180724020800p:plain

というわけで、動作の様子を観測したいので自作ISSで関数トレースを出してみたのだが、良くわからなくなった... もう少し解析だな。

...
          <Return: plic_prop>
          <FunctionCall 46805 plic_done(0x800035d4)>
          <Return: plic_done>
        <Return: fdt_scan_helper>
      <Return: fdt_scan_helper>
    <Return: fdt_scan>
  <Return: query_plic>
  <FunctionCall 46988 hart_plic_init(0x80002918)>
  <Return: hart_plic_init>
  <FunctionCall 47025 file_init(0x80000696)>
    <FunctionCall 47032 file_get_free(0x800005b0)>
    <Return: file_get_free>
    <FunctionCall 47053 file_dup(0x8000064a)>
      <FunctionCall 47068 file_incref(0x800005f0)>
      <Return: file_incref>
    <Return: file_dup>
    <FunctionCall 47082 file_get_free(0x800005b0)>
    <Return: file_get_free>
    <FunctionCall 47108 file_dup(0x8000064a)>
      <FunctionCall 47130 file_incref(0x800005f0)>
      <Return: file_incref>
    <Return: file_dup>
    <FunctionCall 47144 file_get_free(0x800005b0)>
    <Return: file_get_free>
    <FunctionCall 47175 file_dup(0x8000064a)>
      <FunctionCall 47204 file_incref(0x800005f0)>
      <Return: file_incref>
    <Return: file_dup>
  <Return: file_init>
  <FunctionCall 47223 pk_vm_init(0x80001732)>
    <FunctionCall 47257 __page_alloc(0x80000e34)>
      <FunctionCall 47278 memset(0x80007912)>
      <Return: memset>
    <Return: __page_alloc>
    <FunctionCall 48841 __map_kernel_range(0x8000163c)>
      <FunctionCall 48877 __walk_internal(0x80000e86)>
        <FunctionCall 48897 __page_alloc(0x80000e34)>
          <FunctionCall 48918 memset(0x80007912)>
          <Return: memset>
        <Return: __page_alloc>

Spectre 1.1 (CVE-2018-3693) の論文を読む

Spectre 1.1/1.2の論文は早くから公開されており、Intel / Armも対策のためのWhitePaperを出している。 どいう問題なのか理解するために読んでみた。

この論文、概念的なところはしっかり説明してあるようなのだが、実際のベンチマーキングなどのところはカバーされていない。 実際にどのような攻撃手法があるのかよく分からなかったので、Intel / Armの文章も参照しながらどういうことなのか勉強することにした。

ただし、筆者自身もセキュリティに詳しいわけではないので理解が足りていない可能性がある。 っていうか、全体的に解説してくれているサイトが少なくて理解するのに時間がかかる...

Bounds Check Store Bypass とは

今回のSpectre 1.1の要点は、Spectre 1.0では「投機的なロード」であったものが、「投機的なストア」であるという点が異なる。

ストア命令は命令のコミットが確定するまで実行されない、ただし...

通常、投機的なストアというのは、コミットが確定するまで実行されない。 ストア命令自体を投機してしまうと、意図せずメモリデータを書き換えてしまう可能性があるため、ストア命令自体が本当に実行されることが確定するまでメモリに対して発行はされない。

一方で、高性能なアウトオブオーダプロセッサでは、ストアバッファを用いてストア命令を実行してしまうケースがある。これを"Speculative Store Execution"と呼ぶ。 いったん実行されたストア命令は、投機的にストアバッファに格納される。 ストアバッファに格納されたストア命令のうち、実際に実行した命令のみがストアバッファから取り出され、実行されない命令はストアバッファから破棄されるような方式になっている。

f:id:msyksphinz:20180721215114p:plain
図. ストアバッファの構成

さらに重要なキーワードとして、"Store to Load Forwarding" という技法がある。 例えば、以下のような命令列を考えると、Store命令が格納したアドレスのデータをLoad命令が使用している。

store rA, 100[sp]
load rB, 100[sp]

これを何も考えずに実現すると、アドレス依存が存在するためストア命令がメモリにデータを書き込んでからロード命令を実行しないと、Loadは1つ前のStore命令の結果を正しく読み込むことができない。 この問題を改善するために”Store to Load Forwarding"ではLoad命令がストアバッファを探索し、同じアドレスの命令を含んでいればその値を利用するという方式で、ストア命令が実際にメモリに書き込む前にロード命令が値を活用することができるという利点がある。

f:id:msyksphinz:20180721220213p:plain
図. Store to Load Forwardingの考え方

この手法を逆手に取ったのが、今回のSpectre 1.1の考え方だ。 以下のようなコードを考えたとき、攻撃者はyを変えて任意の場所にストアを任意の場所に発行させる。

このとき、本来であればlencのガードによって変なメモリに書き込まないようになっているが、ガードを超えるようなストア命令でもとりあえずストアバッファに格納される。

void f(u64 x, u64 y, u64 z) {
  if (y < lenc)
    c[y] = z;
}

ストアした場所(c[y])によって、以下の2パターンがある。

  • リターンアドレスを指している場合、関数から戻ってくるときに使用される。これはROP(Return Oriented Programming)に悪用される可能性がある。 また、Return Stack Pointerによる関数Returnに失敗するため、新たな値がキャッシュに割り当てられる危険性がある。
  • それ以外の値を場合は、任意の場所のデータを読み取ることができるようになる。

Return Stack Pointer とは

Return Stack Pointerは関数からのreturn命令を高速化するため仕組みで、関数の戻りアドレスを専用のスタックに格納しておく。 これは、関数の戻りアドレスが分かっていることが前提となっている。 したがって、関数によってはジャンプ元に戻らないような動作をする場合、このReturn Stack Pointerの内容は使用できず、新しい命令をフェッチしてくる必要がある。

f:id:msyksphinz:20180721230538p:plain
図. Return Stack Pointerの構成

RSP を使ったStore To Load Forwardingによってどのような攻撃ができるのか?

本文中からはあまりよく読み取れなかったが、たぶんReturn Stack Pointerに相当するアドレス(スタックフレームにおいてReturn Addressが配置されるアドレス)を書き換えることによってRSPの値が使用できなくなり、本来の値をキャッシュからロードする必要が生じる。これによるサイクル差により攻撃が可能となる?

また、上記の攻撃でメモリアクセスがスタックフレームを書き換えるようなアドレスだった場合、本来はそれが実行されないのだが投機的実行によりとりあえずストアバッファに入っている場合、Return命令がRSPをミスした影響によりストアバッファを参照し、誤った値をロードする可能性がある。これにより、Spectre 1.0に類似する攻撃が可能になる、ということか?

f:id:msyksphinz:20180721235910p:plain

AWS上で動作するRISC-VチップFireSimのチュートリアルを試す 7. FireSimのFPGAレベルシミュレーション

f:id:msyksphinz:20180617195844p:plain

FireSim v1.2でベンチマークプログラムを動かそうとしているのだが、どうもFPGAレベルでのシミュレーションでないと動かない?

FPGAレベルでのRTLシミュレーションは、Amazon AWS環境でないと動かない気がする。 F1インスタンスで使用しているVU9Pのデザインをコンパイルできる環境がないので、AWS上で作業を行った。

$ cd firesim_v12
$ ./build-setup.sh
$ make xsim
$ make xsim-dut &

これによりRTL側のサーバがOpenになる。opening driver_to_xsimでサーバが受け付けの状態になっていることが分かる。

Info: [Unisim HPIO_VREF-1] Fabric Tune Value changed to 0011101. Instance: tb.card.fpga.sh.DDR4_3.inst.u_ddr4_mem_intfc.u_mig_ddr4_phy.inst.u_ddr_iob.genByte[4].u_ddr_iob_byte.genblk1.genVref.u_hpio_vref
Info: [Unisim HPIO_VREF-1] Fabric Tune Value changed to 0011101. Instance: tb.card.fpga.sh.DDR4_3.inst.u_ddr4_mem_intfc.u_mig_ddr4_phy.inst.u_ddr_iob.genByte[5].u_ddr_iob_byte.genblk1.genVref.u_hpio_vref
Info: [Unisim HPIO_VREF-1] Fabric Tune Value changed to 0011101. Instance: tb.card.fpga.sh.DDR4_3.inst.u_ddr4_mem_intfc.u_mig_ddr4_phy.inst.u_ddr_iob.genByte[6].u_ddr_iob_byte.genblk1.genVref.u_hpio_vref
Info: [Unisim HPIO_VREF-1] Fabric Tune Value changed to 0011101. Instance: tb.card.fpga.sh.DDR4_3.inst.u_ddr4_mem_intfc.u_mig_ddr4_phy.inst.u_ddr_iob.genByte[7].u_ddr_iob_byte.genblk1.genVref.u_hpio_vref
Info: [Unisim HPIO_VREF-1] Fabric Tune Value changed to 0011101. Instance: tb.card.fpga.sh.DDR4_3.inst.u_ddr4_mem_intfc.u_mig_ddr4_phy.inst.u_ddr_iob.genByte[8].u_ddr_iob_byte.genblk1.genVref.u_hpio_vref
Info: [Unisim HPIO_VREF-1] Fabric Tune Value changed to 0011101. Instance: tb.card.fpga.sh.DDR4_3.inst.u_ddr4_mem_intfc.u_mig_ddr4_phy.inst.u_ddr_iob.genByte[9].u_ddr_iob_byte.genblk1.genVref.u_hpio_vref
Info: [Unisim HPIO_VREF-1] Fabric Tune Value changed to 0011101. Instance: tb.card.fpga.sh.DDR4_3.inst.u_ddr4_mem_intfc.u_mig_ddr4_phy.inst.u_ddr_iob.genByte[10].u_ddr_iob_byte.genblk1.genVref.u_hpio_vref
Info: [Unisim HPIO_VREF-1] Fabric Tune Value changed to 0011101. Instance: tb.card.fpga.sh.DDR4_3.inst.u_ddr4_mem_intfc.u_mig_ddr4_phy.inst.u_ddr_iob.genByte[11].u_ddr_iob_byte.genblk1.genVref.u_hpio_vref
opening driver_to_xsim

make run-xsimでパタンを流すらしい?マニュアルではmake xsimとあるが、これはビルドにしか使えなさそう。

rv64ui-p-addを流してみたが、うまく動かない...

$ make run-xsim SIM_BINARY=../riscv-tools-install/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add.out
cd /home/centos/firesim_v12/sim/generated-src/f1/FireSim-FireSimRocketChipConfig-FireSimConfig/ && ./FireSim-f1  +permissive +mm_relaxFunctionalModel=0 +mm_writeMaxReqs=16 +mm_readMaxReqs=16 +mm_writeLatency=30 +mm_readLatency=30 \
+sample=rv64ui-p-add.out.sample  +permissive-off /home/centos/firesim_v12/riscv-tools-install/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add.out
opening driver to xsim
opening xsim to driver
using link latency: 0 cycles
using netbw: 200
using netburst: 8
random min: 0x0, random max: 0xffffffffffffffff
C0:          0 [0] pc=[0000000000] W[r 0=0000000000000000][0] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[00000000] DASM(00000000)
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[0].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @25959376
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[1].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @25959376
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[2].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @25959376
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[3].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @25959376
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[4].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @25959376
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[5].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @25959376
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[6].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @25959376
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[7].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @25959376
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[8].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @25959376
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[9].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @26079328
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[10].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @26079328
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[11].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @26079328
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[12].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @26079328
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[13].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @26079328
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[14].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @26079328
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[15].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @26079328
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[16].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @26079328
tb.card.u_ddr4_rdimm_C.rcd_enabled.genblk1.u_ddr4_dimm.rank_instances[0].even_ranks.u_ddr4_rank.Micron_model.instance_of_sdram_devices[17].micron_mem_model.u_ddr4_model.always_diff_ck.if_diff_ck:Initialization complete @26079328

AWS上で動作するRISC-VチップFireSimのチュートリアルを試す 6. FireSimのシミュレーション環境解析

f:id:msyksphinz:20180617195844p:plain

FireSim v1.2でベンチマークプログラムを動かそうとしているのだが、なかなかうまく動かない。

NoNIC環境 (FireSim Rocket-Chip Standalone環境)の場合

これは簡単だ。riscv-testsの環境でテストパタンをビルドして、それを持ってくれば簡単なC言語のプログラムなら動作させることができる。

$ cd ${HOME}/work/firesim_v12/target-design/firechip/rocket-chip/riscv-tools/riscv-tests/benchmarks/
$ mkdir printf_sample
$ # printf_sample/printf_sample.c を作成する
$ cat printf_sample/printf_sample.c 
#include <stdio.h>

int main ()
{
  printf ("Hello, World\n");

  int sum = 0;
  for (int i = 1; i <= 10; i++) {
    sum += i;
  }

  printf ("1 + ... + 10 = %d\n", sum);

  return 0;
}
$ make

これをFireSimのoutputディレクトリにリンクする。 - firesim/simにて

$ cd output/f1/FireSimNoNIC-FireSimRocketChipConfig-FireSimConfig/
$ ln -s ${HOME}/work/firesim_v12/target-design/firechip/rocket-chip/riscv-tools/riscv-tests/benchmarks/printf_sample.riscv
$ cd -
$ make DESIGN=FireSimNoNIC ${PWD}/output/f1/FireSimNoNIC-FireSimRocketChipConfig-FireSimConfig/printf_sample.riscv.out
cd /home/msyksphinz/work/firesim_v12/sim/generated-src/f1/FireSimNoNIC-FireSimRocketChipConfig-FireSimConfig/ && \
./VFireSimNoNIC /home/msyksphinz/work/firesim_v12/sim/output/f1/FireSimNoNIC-FireSimRocketChipConfig-FireSimConfig/printf_sample.riscv +sample=/home/msyksphinz/work/firesim_v12/sim/output/f1/FireSimNoNIC-FireSimRocketChipConfig-FireSimConfig/printf_sample.riscv.sample +max-cycles=100000000 +mm_relaxFunctionalModel=0 +mm_writeMaxReqs=16 +mm_readMaxReqs=16 +mm_writeLatency=30 +mm_readLatency=30 +dramsim \
2> /home/msyksphinz/work/firesim_v12/sim/output/f1/FireSimNoNIC-FireSimRocketChipConfig-FireSimConfig/printf_sample.riscv.out && [ $PIPESTATUS -eq 0 ]
Hello, World
1 + ... + 10 = 55

簡単なプログラム程度は動いた。

WindowsでX-Server越しにEmacsを立ち上げると初期画面がおかしくなる件

Emacsが大好きである。好きすぎてありとあらゆる環境でEmacsを使っているのだが、どうも最近様子がおかしい。 最新のEmacsを使うと、初期画面の大きさがおかしくなる。

いろいろと環境を変えながら調査していると、Virtual BoxからXクライアントを通じてEmacsGUIを立ち上げると辺になるらしい。 Emacsのビルド時にXのツールキットを変えると症状も変わる、ということでどの構成がベストなのか調査してみた。

ちなみに、どのようなビルドオプションがあるのかについては、以下のウェブサイトを参考にした。とても分かりやすい!!

kaniza.hatenablog.com

環境

まとめると、だいたいこんな感じである。ってかGTK-3ひどいな!!!!

f:id:msyksphinz:20180719003124p:plain

GTK2 (--with-x-toolkit=gtk2)

まともである。

f:id:msyksphinz:20180719003540p:plain

GTK3 (--with-x-toolkit=gtk3)

これはひどい

f:id:msyksphinz:20180719003640p:plain

Motif (--with-x-toolkit=motif)

これはまともな方なんじゃないか。

f:id:msyksphinz:20180719003726p:plain

Lucid (--with-x-toolkit=lucid)

これも使い物になる。

f:id:msyksphinz:20180719003810p:plain

Athena (--with-x-toolkit=athena)

Luciaとほぼ一緒。

f:id:msyksphinz:20180719003854p:plain

No (--with-x-toolkit=no)

f:id:msyksphinz:20180719003939p:plain

というわけで、デフォルトでGTK-3が使われていることが分かったので、Motifあたりでビルドしなおして使おうっと。

AWS上で動作するRISC-VチップFireSimのチュートリアルを試す 5. FireSim v1.2 を試行する

f:id:msyksphinz:20180617195844p:plain

FireSim v1.2が公開された。主な変更点としては、Rocket-ChipだけでなくBOOMにも対応したとのことなので試行してみよう。

github.com

FireSim v1.2環境をCloneする

FireSimのリポジトリを、Tag付きでCloneする。さすがにriscv-toolsは取ってこなくても良いと思うけれども...

git clone -b 1.2 https://github.com/firesim/firesim.git firesim_v12

Rocket-ChipでのDhrystoneの実行

まずはRocket-Chipでの試行だ。sim/に移動して実行する。VCSとVerilatorをサポートしているが、今回はVerilatorを使用する。

$ make DESIGN=FireSimNoNIC
...
$ make DESIGN=FireSimNoNIC ${PWD}/output/f1/FireSimNoNIC-FireSimRocketChipConfig-FireSimConfig/dhrystone.riscv.out
...
./VFireSimNoNIC /home/masayuki/work/firesim_v12/sim/output/f1/FireSimNoNIC-FireSimRocketChipConfig-FireSimConfig/dhrystone.riscv +sample=/home/masayuki/work/firesim_v12/sim/output/f1/FireSimNoNIC-FireSimRocketChipConfig-FireSimConfig/dhr
ystone.riscv.sample +max-cycles=100000000 +mm_relaxFunctionalModel=0 +mm_writeMaxReqs=16 +mm_readMaxReqs=16 +mm_writeLatency=30 +mm_readLatency=30 +dramsim \
3>&1 1>&2 2>&3 | /home/masayuki/riscv64/bin/spike-dasm  > /home/masayuki/work/firesim_v12/sim/output/f1/FireSimNoNIC-FireSimRocketChipConfig-FireSimConfig/dhrystone.riscv.out && [ $PIPESTATUS -eq 0 ]
Microseconds for one run through Dhrystone: 469
Dhrystones per Second:                      2132
mcycle = 234636
minstret = 196530

実行できた。次はBOOMの構成を作成してみる。

$ make DESIGN=FireBoomNoNIC TARGET_CONFIG=FireSimBoomConfig
$ make DESIGN=FireBoomNoNIC TARGET_CONFIG=FireSimBoomConfig ${PWD}/output/f1/FireBoomNoNIC-FireSimBoomConfig-FireSimConfig/dhrystone.riscv.out
...
./VFireBoomNoNIC /home/masayuki/work/firesim_v12/sim/output/f1/FireBoomNoNIC-FireSimBoomConfig-FireSimConfig/dhrystone.riscv +sample=/home/masayuki/work/firesim_v12/sim/output/f1/FireBoomNoNIC-FireSimBoomConfig-FireSimConfig/dhrystone.ri
scv.sample +max-cycles=100000000 +mm_relaxFunctionalModel=0 +mm_writeMaxReqs=16 +mm_readMaxReqs=16 +mm_writeLatency=30 +mm_readLatency=30 +dramsim \
3>&1 1>&2 2>&3 | /home/masayuki/riscv64/bin/spike-dasm  > /home/masayuki/work/firesim_v12/sim/output/f1/FireBoomNoNIC-FireSimBoomConfig-FireSimConfig/dhrystone.riscv.out && [ $PIPESTATUS -eq 0 ]

このあと固まってしまった。まだサポートされていないのかな?

2018/07/20 追記。簡単なテストパタン(ISAチェック用のテスト)なら動作するようだ。何かエラーが出るけど。 Dhrystoneなどは設定の変更が必要なんだろうか?

$ make DESIGN=FireBoomNoNIC TARGET_CONFIG=FireSimBoomConfig ${PWD}/output/f1/FireBoomNoNIC-FireSimBoomConfig-FireSimConfig/rv64ui-p-add.out
...
./VFireBoomNoNIC /home/msyksphinz/work/firesim_v12/sim/output/f1/FireBoomNoNIC-FireSimBoomConfig-FireSimConfig/rv64ui-p-add +sample=/home/msyksphinz/work/firesim_v12/sim/output/f1/FireBoomNoNIC-FireSimBoomConfig-FireSimConfig/rv64ui-p-add.sample +max-cycles=100000000 +mm_relaxFunctionalModel=0 +mm_writeMaxReqs=16 +mm_readMaxReqs=16 +mm_writeLatency=30 +mm_readLatency=30 +dramsim \
2> /home/msyksphinz/work/firesim_v12/sim/output/f1/FireBoomNoNIC-FireSimBoomConfig-FireSimConfig/rv64ui-p-add.out && [ $PIPESTATUS -eq 0 ]
/bin/sh: 3: [: -eq: unexpected operator
Makefile:176: recipe for target '/home/msyksphinz/work/firesim_v12/sim/output/f1/FireBoomNoNIC-FireSimBoomConfig-FireSimConfig/rv64ui-p-add.out' failed
make: *** [/home/msyksphinz/work/firesim_v12/sim/output/f1/FireBoomNoNIC-FireSimBoomConfig-FireSimConfig/rv64ui-p-add.out] Error 2

$ cat ${PWD}/output/f1/FireBoomNoNIC-FireSimBoomConfig-FireSimConfig/rv64ui-p-add.out
random min: 0x0, random max: 0xffffffffffffffff
time elapsed: 1.8 s, simulation speed = 1.60 KHz
*** PASSED *** after 2912 cycles
Runs 2912 cycles
[PASS] FireBoomNoNIC Test
SEED: 1532017147
````