Chiselで始める爆速LSI設計
この記事は HDL Advent Calendar 2021 5日目の記事です。 qiita.com
はい、Cra2yPierr0tです。
皆さん、来週の月曜に会社や研究室に顔を出すと、ボスがニコニコしながら近づいてきて「〇〇さん、一ヶ月くらいでこんな感じのLSI作ってくれない?ツールはフリーな物を自分で探してね!」と言ってきたらどうしますか?こんな無茶振りをされるという事は、妻子を人質に取られているか拳銃を突き付けられている可能性がありますね。今この文章を読んでいる皆さん、幸運です。この記事を読めば、ボスとの交渉に使えるギリギリ成果物っぽいサムシングをこしらえる事が可能です。
ではやっていきましょう。
概要
RTLをChiselで生やしてGDSII*1をOpenLANEを使って生成しましょう。Chiselの詳しい説明はインターネットに先達が書いた記事が存在しているのでそちらを参照してください。
1. Chiselのインストール
始めにscalaのビルドツールであるsbtをインストールしましょう。インストール方法は各自OSに応じて調べてください。
$ sudo pacman -S sbt
次にChiselのプロジェクトテンプレートをダウンロード、このディレクトリ下でChiselが使えます。
$ git clone https://github.com/ucb-bar/chisel-template.git
2. Chiselを書く
今回はボスに5つの8bitの入力の分散を計算するハードウェアを要求されたと仮定しましょう。
ダウンロードしたchisel-templateのsrc/main/scala以下にvarianceディレクトリを作成し、variance.scalaにChiselを書いていきます。
. └── chisel-template └── src └── main └── scala └── variance └── variance.scala
以下が分散を計算するvariance.scalaの内容です。Chiselを初めて書いたので正しく動くか分かりませんが多分動きます。
import chisel3._ class variance extends Module { val io = IO(new Bundle { val in = Input(Vec(5, UInt(8.W))) val out = Output(UInt((8.W))) }) var r_sum = Reg(UInt(16.W)) // 総和 var r_sum2 = Reg(UInt(16.W)) // 2乗の総和 val r_average_2 = Reg(UInt(16.W)) // 平均の2乗 val r_average2 = Reg(UInt(16.W)) // 2乗の平均 r_sum = 0.U r_sum2 = 0.U for (i <- 0 to 4) { r_sum = r_sum + io.in(i) r_sum2 = r_sum2 + io.in(i) * io.in(i) } r_average_2 := (r_sum / 5.U) * (r_sum / 5.U) r_average2 := r_sum2 / 5.U io.out := r_average2 - r_average_2 } object Elaborate extends App { chisel3.Driver.execute(args, () => new variance) }
そしたらchisel-template直下でsbt "run"
を実行すればvariance.vが生成されます。
$ sbt "run"
variance.vは一旦置いておき、次はOpenLANEの準備に入ります。
3. OpenLANEのインストール
先程生成したTop.vをGDSIIにするために、OpenLANEをインストールしましょう。 OpenLANEは約20個のOSSを組み合わせて作成されたRTL-to-GDSIIコンパイラです。すごいね。
まずはOpenLANEリポジトリをクローン
$ git clone git@github.com:The-OpenROAD-Project/OpenLane.git $ cd OpenLane
次にOpenLANEのDockerコンテナをダウンロード。事前にDockerデーモンを起動しておきましょう。
$ make pull-openlane
最後にskywater PDKをビルド、20分くらい掛かります。
$ make pdk
次は遂にGDSIIの生成です。
4. OpenLANEでGDSIIを生成
OpenLaneディレクトリ直下で以下のコマンドを実行し、designs以下に自分のデザインのディレクトリとコンフィグを追加しましょう。
$ make mount
bash-4.2$ ./flow.tcl -design variance -init_design_config
するとOpenLane/designs以下にvarianceディレクトリが生成されます。そしたらvariance/srcに先程生成したvariance.vを追加しましょう。
$ cp ../chisel-template/variance.v designs/variance/src
次にvarianceディレクトリにあるconfig.tclを編集します。CLOCK_PERIODとCLOCK_PORTの値を編集するだけで大丈夫です。
# User config set ::env(DESIGN_NAME) variance # Change if needed set ::env(VERILOG_FILES) [glob $::env(DESIGN_DIR)/src/*.v] # Fill this # 10MHz set ::env(CLOCK_PERIOD) "100.0" set ::env(CLOCK_PORT) "clock" set filename $::env(DESIGN_DIR)/$::env(PDK)_$::env(STD_CELL_LIBRARY)_config.tcl if { [file exists $filename] == 1} { source $filename }
各変数の説明はここに書いてあります Variables information - OpenLane Documentation
config.tclの編集が終わったら、OpenLaneディレクトリ直下で以下のコマンドを実行してビルドを開始します。祈りましょう。
$ make mount $ ./flow.tcl -design variance
ビルドが完了したらOpenLane/designs/variance/runs/RUN_<実行時刻>/result/finishing
にvariance.gdsが生成されています。
klayoutでレイアウトを見ることが出来ます、これをボスに見せて猶予を貰いましょう。
おわりに
という訳でChiselからGDSIIを生成しました。実際にChisekを書き始めてからGDSIIファイルが生成されるまで大体3時間です。早いですね。 もし実際にOpenLANEを用いてオレオレLSIを焼きたいなら、OpenMPW Shuttle Programがオススメです。
GoogleがEfablessに出資したおかげで、デザインをオープンにする代わりに無料でLSIを焼くことが出来ます。送料も無料で5個の評価ボードと50個のチップがあなたの家に届きます!
流石にこの記事よりは時間も必要になりますしconfig.tcl
もそこそこ書くことになりますが、自分でチップを焼くことは他の現代人に対し圧倒的なアドバンテージになります。そんな事を言っていいのか、俺は130nmプロセスを焼いた漢だぞ。
もし興味が湧いたり質問がありましたらVLSI.jpを参照するかMake:LSIを覗いてみるか筆者に聞いてみてください。良き半導体ライフを。