FPGA開発日記

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

ハードウェア記述言語Chiselコンパイラの内部解析(2. Chiselコンパイルのフローを追いかける)

https://cdn-ak.f.st-hatena.com/images/fotolife/m/msyksphinz/20181105/20181105012126.png

ハードウェア記述言語ChiselはScalaのプラットフォームの上に構築されている。大きく分けて2つのリポジトリから構成されている。

chisel3のリポジトリは、ChiselのコードをFIRへ変換する。firrtlのリポジトリは、FIRのコードをVerilogに変換する。

以下のようなコードでsimple.scalaコンパイルすると、emitVerilogが呼び出される。

  • simple.scala
class simple extends Module {
...
}
object simple extends App {
  chisel3.Driver.emitVerilog(new simple())
}

printデバッグを行うと、chisel3リポジトリchisel3/src/main/scala/chisel3/Driver.scala内のemitVerilog()execute()が呼び出されることが分かる。

とりあえずはtargetsの変換を見てみることにした。

    val targets =
      Seq( classOf[DriverCompatibility.AddImplicitOutputFile],
           classOf[DriverCompatibility.AddImplicitOutputAnnotationFile],
           classOf[DriverCompatibility.DisableFirrtlStage],
           classOf[ChiselStage],
           classOf[DriverCompatibility.MutateOptionsManager],
           classOf[DriverCompatibility.ReEnableFirrtlStage],
           classOf[DriverCompatibility.FirrtlPreprocessing],
           classOf[chisel3.stage.phases.MaybeFirrtlStage] )

それぞれ以下に実装がある。それぞれのクラスのtransform()が呼ばれるらしい。

  • AddImplicitOutputFile : chisel3/src/main/scala/chisel3/stage/phases/AddImplicitOutputFile.scala
  • AddImplicitOutputAnnotationFile : chisel3/src/main/scala/chisel3/stage/phases/AddImplicitOutputAnnotationFile.scala
  • DisableFirrtlStage : chisel3/src/main/scala/chisel3/stage/phases/DriverCompatibility.scala
  • ChiselStage : chisel3/src/main/scala/chisel3/stage/ChiselStage.scala
  • MutateOptionsManager : chisel3/src/main/scala/chisel3/stage/phases/DriverCompatibility.scala
  • ReEnableFirrtlStage : chisel3/src/main/scala/chisel3/stage/phases/DriverCompatibility.scala
  • FirrtlPreprocessing : chisel3/src/main/scala/chisel3/stage/phases/DriverCompatibility.scala
  • MaybeFirrtlStage : chisel3/src/main/scala/chisel3/stage/phases/MaybeFirrtlStage.scala

最初のAnnotationのあたりはまだ理解できないので、ChiselStageのあたりを読んでみる。

  • chisel3/src/main/scala/chisel3/stage/ChiselStage.scala
class ChiselStage extends Stage with PreservesAll[Phase] {
  val shell: Shell = new Shell("chisel") with ChiselCli with FirrtlCli

  private val targets =
    Seq( classOf[chisel3.stage.phases.Checks],
         classOf[chisel3.stage.phases.Elaborate],
         classOf[chisel3.stage.phases.AddImplicitOutputFile],
         classOf[chisel3.stage.phases.AddImplicitOutputAnnotationFile],
         classOf[chisel3.stage.phases.MaybeAspectPhase],
         classOf[chisel3.stage.phases.Emitter],
         classOf[chisel3.stage.phases.Convert],
         classOf[chisel3.stage.phases.MaybeFirrtlStage] )
  • Checks : chisel3/src/main/scala/chisel3/stage/phases/Checks.scala.
    • Sanity checks an firrtl.AnnotationSeq before running the main firrtl.options.Phases of chisel3.stage.ChiselStage.
  • Elaborate : chisel3/src/main/scala/chisel3/stage/phases/Elaborate.scala.
    • Elaborate all chisel3.stage.ChiselGeneratorAnnotations into chisel3.stage.ChiselCircuitAnnotations.
  • AddImplicitOutputFile : chisel3/src/main/scala/chisel3/stage/phases/AddImplicitOutputFile.scala.
    • Add a output file for a Chisel circuit, derived from the top module in the circuit, if no ChiselOutputFileAnnotation already exists.
  • AddImplicitOutputAnnotationFile : chisel3/src/main/scala/chisel3/stage/phases/AddImplicitOutputAnnotationFile.scala.
    • Adds an firrtl.options.OutputAnnotationFileAnnotation if one does not exist. This replicates old behavior where an output annotation file was always written.
  • MaybeAspectPhase : chisel3/src/main/scala/chisel3/stage/phases/MaybeAspectPhase.scala.
    • Run AspectPhase if a chisel3.aop.Aspect is present.
  • Emiter : chisel3/src/main/scala/chisel3/stage/phases/Emitter.scala.
  • Convert : chisel3/src/main/scala/chisel3/stage/phases/Convert.scala.
  • MaybeFirrtlStage : chisel3/src/main/scala/chisel3/stage/phases/MaybeFirrtlStage.scala.
    • Run firrtl.stage.FirrtlStage if a chisel3.stage.NoRunFirrtlCompilerAnnotation is not present.
f:id:msyksphinz:20190826150622p:plain

ハードウェア記述言語Chiselコンパイラの内部解析(1. カスタマイズ用のローカル環境を作る)

https://cdn-ak.f.st-hatena.com/images/fotolife/m/msyksphinz/20181105/20181105012126.png

ハードウェア記述言語ChiselはScalaのプラットフォームの上に構築されている。大きく分けて2つのリポジトリから構成されている。

chisel3のリポジトリは、ChiselのコードをFIRへ変換する。firrtlのリポジトリは、FIRのコードをVerilogに変換する。

Chiselの開発・デバッグ用にChisel3のリポジトリをダウンロードしてみる。

git clone https://github.com/freechipsproject/chisel3.git

このときにいくつかのChisel3コンパイラの実装を変更してローカルでテストするためには、sbt publishLocalを使えば良いようだった。

sbt publishLocal

${HOME}/.ivyにローカル用のディレクトリが作られる。${HOME}/.ivy2/local/edu.berkeley.cs/chisel3_2.12/3.2-SNAPSHOTである。 このリポジトリの名前は、chisel3リポジトリのホームディレクトリに位置されているbuild.sbtで決定されている。

  • build.sbt
lazy val commonSettings = Seq (
  resolvers ++= Seq(
    Resolver.sonatypeRepo("snapshots"),
    Resolver.sonatypeRepo("releases")
  ),
  organization := "edu.berkeley.cs",
  version := "3.2-SNAPSHOT",
  autoAPIMappings := true,
  scalaVersion := "2.12.6",
  crossScalaVersions := Seq("2.12.6", "2.11.12"),

改造を加えたchiselを別ディレクトリとしてコンパイルしたい場合、上記の設定情報を書き換える。

diff --git a/build.sbt b/build.sbt
index 2cffb8b7..4b5fb36f 100644
--- a/build.sbt
+++ b/build.sbt
@@ -35,8 +35,8 @@ lazy val commonSettings = Seq (
     Resolver.sonatypeRepo("snapshots"),
     Resolver.sonatypeRepo("releases")
   ),
-  organization := "edu.berkeley.cs",
-  version := "3.2-SNAPSHOT",
+  organization := "local.berkeley.cs",
+  version := "msyksphinz-SNAPSHOT",
   autoAPIMappings := true,
   scalaVersion := "2.12.6",
   crossScalaVersions := Seq("2.12.6", "2.11.12"),

これでsbt publishLocalを実行すると、以下のようにローカルディレクトリに独自のディレクトリが出来上がる。

local
└── local.berkeley.cs
    └── chisel3_2.12
        └── msyksphinz-SNAPSHOT
            ├── docs
            │   ├── chisel3_2.12-javadoc.jar
            │   ├── chisel3_2.12-javadoc.jar.md5
            │   └── chisel3_2.12-javadoc.jar.sha1
            ├── ivys
            │   ├── ivy.xml
            │   ├── ivy.xml.md5
            │   └── ivy.xml.sha1
            ├── jars
            │   ├── chisel3_2.12.jar
            │   ├── chisel3_2.12.jar.md5
            │   └── chisel3_2.12.jar.sha1
            ├── poms
            │   ├── chisel3_2.12.pom
            │   ├── chisel3_2.12.pom.md5
            │   └── chisel3_2.12.pom.sha1
            └── srcs
                ├── chisel3_2.12-sources.jar
                ├── chisel3_2.12-sources.jar.md5
                └── chisel3_2.12-sources.jar.sha1

8 directories, 15 files

例えば以下のようにChisel3のリポジトリに改造を加えてみる。emitVerilog()を実行時にprintf()を実行する。

diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala
index a78cc92f..3629affd 100644
--- a/src/main/scala/chisel3/Driver.scala
+++ b/src/main/scala/chisel3/Driver.scala
@@ -122,6 +122,7 @@ object Driver extends BackendCompilationUtilities {
     * @return A String containing the design in Verilog.
     */
   def emitVerilog[T <: RawModule](gen: => T): String = {
+    print("MYSKSPHINZ : emitVerilog is called\n")
     execute(Array[String](), { () => gen }) match {
       case ChiselExecutionSuccess(_, _, Some(firrtl.FirrtlExecutionSuccess(_, verilog))) => verilog
       case _ => sys.error("Cannot get Verilog!")

Chisel3のリポジトリ内で再度sbt publishLocalを実行してローカルディレクトリにデプロイする。 今度は、Chiselのハードウェアを設計しているディレクトリのbuild.sbtを変更する。

  • build.sbt
libraryDependencies ++= (Seq("local.berkeley.cs" %% "chisel3" % "msyksphinz-SNAPSHOT"))
[info] Done packaging.
[info] Running map_test.map_test 
MYSKSPHINZ : emitVerilog is called
[info] [0.002] Elaborating design...
[info] [8.166] Done elaborating.
Total FIRRTL Compile Time: 1019.6 ms
[success] Total time: 48 s, completed 2019/08/25 14:04:55

Chiselで再帰を使ってPopCountモジュールを実装する

https://cdn-ak.f.st-hatena.com/images/fotolife/m/msyksphinz/20170830/20170830023047.png

Arianeの実装を見ていると、PopCountの実装がSystem Verilog再帰を使って実装してあった。

github.com

f:id:msyksphinz:20190820225744p:plain
Popcountの実装
module popcount #(
    parameter int unsigned INPUT_WIDTH = 256,
    localparam POPCOUNT_WIDTH          = $clog2(INPUT_WIDTH)+1
) (
    input logic [INPUT_WIDTH-1:0]     data_i,
    output logic [POPCOUNT_WIDTH-1:0] popcount_o
);

...
   //Recursive instantiation to build binary adder tree
   if (INPUT_WIDTH == 2) begin : leaf_node
     assign left_child_result  = padded_input[1];
     assign right_child_result = padded_input[0];
   end else begin : non_leaf_node
     popcount #(.INPUT_WIDTH(PADDED_WIDTH / 2))
         left_child(
                    .data_i(padded_input[PADDED_WIDTH-1:PADDED_WIDTH/2]),
                    .popcount_o(left_child_result));

     popcount #(.INPUT_WIDTH(PADDED_WIDTH / 2))
         right_child(
                     .data_i(padded_input[PADDED_WIDTH/2-1:0]),
                     .popcount_o(right_child_result));
   end
...
endmodule

これはそのままChiselで実装できる。生成できるVerilogは階層化されて出力される。

import chisel3._
import chisel3.util._
import chisel3.Bool

class popcount(INPUT_WIDTH:Int = 256) extends Module
{
  val POPCOUNT_WIDTH:Int = log2Ceil(INPUT_WIDTH) + 1

  val io = IO(new Bundle {
    val data_i     = Input(UInt(INPUT_WIDTH.W))
    val popcount_o = Output(UInt(POPCOUNT_WIDTH.W))
  })

  val PADDED_WIDTH  :Int = 1 << log2Ceil(INPUT_WIDTH)

  val padded_input = Wire(UInt(PADDED_WIDTH.W))
  val left_child_result  = Wire(UInt((POPCOUNT_WIDTH-1).W))
  val right_child_result = Wire(UInt((POPCOUNT_WIDTH-1).W))

  //Zero pad the input to next power of two
  padded_input := io.data_i

  //Recursive instantiation to build binary adder tree
  if (INPUT_WIDTH == 2) { // leaf_node
    left_child_result  := padded_input(1)
    right_child_result := padded_input(0)
  } else { // : non_leaf_node
    val left_child = Module(new popcount (PADDED_WIDTH / 2))
    left_child.io.data_i := padded_input(PADDED_WIDTH-1, PADDED_WIDTH/2)
    left_child_result    := left_child.io.popcount_o

    val right_child = Module(new popcount (PADDED_WIDTH / 2))
    right_child.io.data_i := padded_input(PADDED_WIDTH/2-1, 0)
    right_child_result    := right_child.io.popcount_o
  }

  //Output assignment
  io.popcount_o := left_child_result + right_child_result
}

Parameterの依存関係を記述するための手法

Verilogでは、以下のような記述によってパラメータの依存関係を記述できる。

module test #(
  parameter A = 2,
  parameter B = A * 2
) (
  input logic [A-1:0] in_a,
  output logic[B-1:0] out_b
);

ところが、ChiselではParameterを上記のように依存関係を持って記述するとエラーになる。

class test(A:Int = 2, B:Int = A*2) extends Module
{
  val io = IO(new Bundle {
    val in_a  = Input(UInt(A.W))
    val out_b = Output(UInt(B.W))
  })
  io.out_b := Cat(io.in_a, io.in_b)
}
popcount.scala:62:31: not found: value A
[error] class test(A:Int = 2, B:Int = A*2) extends Module
[error]                               ^

そこでどうしようか迷ったのだが、冷静に考えるとクラスの宣言とioの宣言の間に入れればよいのだった。

class test(A:Int = 2) extends Module
{
  val B:Int = A*2
  val io = IO(new Bundle {
    val in_a  = Input(UInt(A.W))
    val out_b = Output(UInt(B.W))
  })
  io.out_b := Cat(io.in_a, io.in_a)
}

ChiselでMapやReduceを使ったいくつかのハードウェア記述Tips

https://cdn-ak.f.st-hatena.com/images/fotolife/m/msyksphinz/20170830/20170830023047.png

ChiselはScalaをベースとしたハードウェア記述言語なので、Verilog-HDLではあまり見かけることのない記述ができる。

最近使っているChiselの便利な技法のいくつかをまとめてみる。

  • Vecの中身を.reducを使ってリダクションする

Vecにはreductionなどの記法が用意されている。具体的には、あまり説明のないAPI一覧の資料を見てほしいのだが、

https://chisel.eecs.berkeley.edu/api/3.1.0/chisel3/core/Vec.htmlchisel.eecs.berkeley.edu

例えば、こんな感じで書く。

class map_test(WIDTH: Int = 32) extends Module {
  val io = IO(new Bundle {
    val in_val  = Input (Vec(WIDTH, UInt(16.W)))
    val reduc   = Output(UInt(16.W))
  })

  io.reduc   := io.in_val.reduce(_ +& _)
}

入力信号の16bit×WIDTHのベクトル形式の信号を受け取り、それらのすべての要素を加算(+&はビット拡張を行いながら加算する)してその結果を返す。 これは+&以外でも、論理演算などでも使える。 reduce(_ | _)など。

  • Vecの内容すべてに処理を適用するための.map

Mapを使うと、すべての要素に処理を適用できる。例えば、以下はWIDTH長のベクトル入力に対してすべてNOT演算を適用する。

class map_test(WIDTH: Int = 32) extends Module {
  val io = IO(new Bundle {
    val in_bool = Input (Vec(WIDTH, Bool()))
    val not_out = Output(Vec(WIDTH, Bool()))
  })
  io.not_out := io.in_bool.map(x => ~x)
}

in_boolのすべてのベクトルに対して、NOT演算を適用してその結果をio.not_outに渡している。

  • Mapでベクトルの要素を取り出して、さらにReducする

.mapは上記のような処理の適用だけでなく、ベクトル内の要素の取り出しにも使える。例えば、以下はValidIO信号の中のbits要素(ValidIOvalidbitsの2種類から構成されているデータ型である)を取り出して、それらをすべてのベクトルに対してreducする。

class map_test(WIDTH: Int = 32) extends Module {
  val io = IO(new Bundle {
    val in_validio  = Input(Vec(WIDTH, ValidIO(UInt(16.W))))
    val out_validio = Output(UInt(16.W))
  })
  io.out_validio := io.in_validio.map(x => x.bits).reduce(_ +& _)
}

mapにより要素の取り出しを行い、その結果に対してreducを適用した。

このように、簡単な処理であればVerilog-HDLのようにfor文を使わずに処理を実現できる。

SystemVerilogで記述されたRISC-VプロセッサArianeのフロントエンドの構成

SystemVerilogで記述されたRISC-VプロセッサArianeについて解析を進めている。 まずはフロントエンドから。フロントエンドは命令をフェッチするところだが、以下のようなサブモジュールで構成される。

  • instr_realign : 命令アライナ。命令フェッチ時に命令のプリデコードを行い、命令サイズから次のフェッチラインを判定する。
  • instr_scan : 命令内で分岐命令を特定し、分岐予測命令の判定に使用する。
  • ras : Return Address Stack
  • btb : Branch Target Buffer
  • bht : Branch History Table
  • instr_queue : 命令キュー
f:id:msyksphinz:20190824164124p:plain
Arianeのフロントエンドの構成。

となっている。命令アライナは命令を取り込んできてからプリデコードを行う。これは最大2命令フェッチ(32ビット幅バス)と最大4命令フェッチ(64ビット幅バス)で実装が切り分けられており、2命令フェッチのときを解説すると、

  • 過去にUnalignedな状態(32ビットのうち上位16ビットが残り、次の16ビットが必要)な状態になって次の命令がフェッチされると、
    • 下位16ビットを接続して32ビットの命令を作成
    • 上位16ビットはRVC命令として判定できる場合はそのまま命令を生成、そうでない場合は再びUnalignedな状態を維持
  • Unalignedではない状態から次の命令がフェッチされると、
    • 下位16ビットがRVC命令として判定できるのならばRVC命令として生成する。そうでないならば32ビット命令として生成
    • 下位16ビットがRVC命令として判定できる場合で
      • 上位16ビットがRVC命令として判定できる場合は上位16ビットをRVC命令として判定。
      • 上位16ビットがRVC命令として判定できない場合はUnalignedな状態に移行。

という構成になっている。

instr_scanは命令の簡易スキャンを行う。ジャンプ命令などを命令デコードよりも前にデコードし、後続の分岐予測器などに活用する仕組みである。

SystemVerilogで記述されたRISC-VプロセッサArianeの回路面積解析

SystemVerilogで記述されたRISC-VプロセッサArianeについて解析を進めている。回路面積が大きいという話で、実際にどれくらいのサイズなのか見てみることにした。

github.com

上記を使用している。FPGAの合成には、リポジトリをダウンロードした上でmake fpgaとしてVivadoを実行する。

ちなみに、Genesys2のボードパッケージを持っていなかったので以下のように構成を若干変更して合成した。

diff --git a/Makefile b/Makefile
index f83eaff..cc46c6d 100644
--- a/Makefile
+++ b/Makefile
@@ -503,7 +503,8 @@ fpga: $(ariane_pkg) $(util) $(src) $(fpga_src) $(uart_src)
        @echo read_verilog -sv {$(filter-out $(fpga_filter), $(src))}      >> fpga/scripts/add_sources.tcl
        @echo read_verilog -sv {$(fpga_src)}   >> fpga/scripts/add_sources.tcl
        @echo "[FPGA] Generate Bitstream"
-       cd fpga && make BOARD="genesys2" XILINX_PART="xc7k325tffg900-2" XILINX_BOARD="digilentinc.com:genesys2:part0:1.1" CLK_PERIOD_NS="20"
+       cd fpga && make CLK_PERIOD_NS="20"
+#      cd fpga && make BOARD="genesys2" XILINX_PART="xc7k325tffg900-2" XILINX_BOARD="digilentinc.com:genesys2:part0:1.1" CLK_PERIOD_NS="20"

 .PHONY: fpga

@@ -522,4 +523,3 @@ clean:
        check-benchmarks check-asm-tests                                          \
        torture-gen torture-itest torture-rtest                                   \
        run-torture run-torture-verilator check-torture check-torture-verilator
-
diff --git a/fpga/sourceme.sh b/fpga/sourceme.sh
index 5a6d156..26faf96 100644
--- a/fpga/sourceme.sh
+++ b/fpga/sourceme.sh
@@ -9,6 +9,7 @@ if [ "$BOARD" = "genesys2" ]; then
   echo -n "Configuring for "
   echo "Genesys II"
   export XILINX_PART="xc7k325tffg900-2"
-  export XILINX_BOARD="digilentinc.com:genesys2:part0:1.1"
+  export XILINX_BOARD="xilinx.com:kc705:part0:1.4"
+  # "digilentinc.com:genesys2:part0:1.1"
   export CLK_PERIOD_NS="20"
 fi

合成が終了すると以下のようなレポートが出力された(一部下位の階層は省略している)。

やはり一番大きいのはコアだが、DDRコントローラなども結構大きい。コアの中で最も大きいのは演算器のようだ(ex_stage_i)。 ArianeはFPUを載せているのか。それでここまで大きくなっているのかな。

+------------------------------------+---------------------------+------------+------------+---------+------+-------+--------+--------+--------------+
|             Instances              |           Modules         | Total LUTs | Logic LUTs | LUTRAMs | SRLs |  FFs  | RAMB36 | RAMB18 | DSP48 Blocks |
+------------------------------------+---------------------------+------------+------------+---------+------+-------+--------+--------+--------------+
| ariane_xilinx                      |                     (top) |      63150 |      61558 |    1224 |  368 | 48346 |     49 |      2 |           27 |
|   (ariane_xilinx)                  |                     (top) |          5 |          5 |       0 |    0 |     1 |      0 |      0 |            0 |
|   i_ariane                         |                    ariane |      37633 |      37633 |       0 |    0 | 23263 |     36 |      0 |           27 |
|     (i_ariane)                     |                    ariane |        103 |        103 |       0 |    0 |     0 |      0 |      0 |            0 |
|     csr_regfile_i                  |               csr_regfile |        298 |        298 |       0 |    0 |  1136 |      0 |      0 |            0 |
|     ex_stage_i                     |                  ex_stage |      14886 |      14886 |       0 |    0 |  7069 |      0 |      0 |           27 |
|     i_cache_subsystem              |        wt_cache_subsystem |       6136 |       6136 |       0 |    0 |  2510 |     36 |      0 |            0 |
|     i_frontend                     |                  frontend |       2684 |       2684 |       0 |    0 |  3614 |      0 |      0 |            0 |
|     i_perf_counters                |             perf_counters |        283 |        283 |       0 |    0 |   896 |      0 |      0 |            0 |
|     id_stage_i                     |                  id_stage |        494 |        494 |       0 |    0 |   290 |      0 |      0 |            0 |
|     issue_stage_i                  |               issue_stage |      12752 |      12752 |       0 |    0 |  7748 |      0 |      0 |            0 |
|   i_ariane_peripherals             |        ariane_peripherals |       3801 |       3690 |     104 |    7 |  4663 |     10 |      2 |            0 |
|   i_axi2rom                        |                   axi2mem |         68 |         68 |       0 |    0 |    36 |      0 |      0 |            0 |
|   i_axi_riscv_atomics              |    axi_riscv_atomics_wrap |       1765 |       1765 |       0 |    0 |   888 |      0 |      0 |            0 |
|   i_axi_xbar                       | axi_node_wrap_with_slices |       7364 |       7364 |       0 |    0 |  8636 |      0 |      0 |            0 |
|   i_bootrom                        |                   bootrom |         65 |         65 |       0 |    0 |     9 |      2 |      0 |            0 |
|   i_clint                          |                     clint |        180 |        180 |       0 |    0 |   152 |      0 |      0 |            0 |
|   i_ddr                            |           xlnx_mig_7_ddr3 |      10560 |       9283 |     916 |  361 |  8548 |      1 |      0 |            0 |
|   i_dm_axi2mem                     |                 axi2mem_0 |        350 |        350 |       0 |    0 |    41 |      0 |      0 |            0 |
|   i_dm_axi_master                  |               axi_adapter |         54 |         54 |       0 |    0 |    69 |      0 |      0 |            0 |
|   i_dm_top                         |                    dm_top |        562 |        562 |       0 |    0 |   675 |      0 |      0 |            0 |
|   i_dmi_jtag                       |                  dmi_jtag |        327 |        327 |       0 |    0 |   339 |      0 |      0 |            0 |
|   i_fan_ctrl                       |                  fan_ctrl |         20 |         20 |       0 |    0 |    24 |      0 |      0 |            0 |
|   i_rstgen_main                    |                    rstgen |          1 |          1 |       0 |    0 |     4 |      0 |      0 |            0 |
|   i_xlnx_axi_clock_converter_ddr   |  xlnx_axi_clock_converter |        398 |        194 |     204 |    0 |   998 |      0 |      0 |            0 |
|   i_xlnx_clk_gen                   |              xlnx_clk_gen |          0 |          0 |       0 |    0 |     0 |      0 |      0 |            0 |
+------------------------------------+---------------------------+------------+------------+---------+------+-------+--------+--------+--------------+
f:id:msyksphinz:20190823191127p:plain

RISC-V Vector Extension 0.7.2の仕様書の日本語化を始めた (第3章まで)

https://content.riscv.org/wp-content/uploads/2018/03/RISC-V-Logo.jpg

RISC-V Vector Extensionは仕様が徐々に固まってきており、実装はまだ分からないがツールセットやアセンブラが徐々に公開されている。

Vector Extensionは現在でも使用がアップデートされており、特にこれまでの0.6から0.7へのアップデートはかなりの修正が加えられており、追いかけるのが非常に難しい。またネット上に情報もあまり存在せず、仕様書を一から読んでいかないと理解できない部分が多い。

そこで、RISC-V Vector Extensionの仕様書を読みながら日本語に翻訳することで、理解を深めていくことにした。 せっかくなので翻訳した結果はGitHub Pagesで公開することにした。

こうやってRISC-Vの仕様について正しい理解が進んでいけばよいと思っている。

ベースにしているRISC-V Vector Extensionの版はVersion 0.7.2-draft-20190616である。

参考にしているのは以下のサイト: github.com

まずは第1章、第2章、第3章まで。

    1. イントロダクション
    1. 実装により決定される定数パラメータ
    1. ベクトル拡張のプログラミングモデル
    2. 3.1 ベクトルレジスタ
    3. 3.2 ベクトル型レジスタ, vtype
    4. 3.3. ベクトル長レジスタvl
    5. 3.4. ベクトルスタートインデックスCSRvstart
    6. 3.5. ベクトル固定小数点丸目モードレジスタvxrm
    7. 3.6. ベクトル固定小数点飽和フラグvxsat
    8. 3.7. fcsrのベクトル固定小数点フィールド
    9. 3.8. ベクトル拡張のリセット状態について

第4章以降の翻訳を続けていく。