Yosysというオープンソースの論理合成ツール(レジスタ転送レベルからゲートレベルに変換する一種のコンパイラ)があるので使ってみました。
インストール
公式のREADMEとだいたい同じです。Makefile
を書き換えてインストール場所を変更すれば、インストールに特権は必要ありません。
sudo apt update sudo apt-get install build-essential clang bison flex libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev mkdir git cd git git clone https://github.com/YosysHQ/yosys cd yosys/ vi Makefile make -j make install
ここで、Makefile
は、PREFIX ?= /home/lpha/yosys
のように書き換えました。
make -j
は、12th Gen Intel(R) Core(TM) i9-12900Kで2分くらいかかりました。
99%になったくらいが折り返し地点です。
使ってみる
チュートリアル
Yosys Open SYnthesis Suite :: Screenshots を見ながら試してみます。
まず、counter.v
とcmos_cells.lib
をダウンロードして実験用ディレクトリに置いておきます。
その後、以下のように入力します(各行について、先頭から空白文字まではプロンプトなので入力しません)。
$ ~/yosys/bin/yosys yosys> read_verilog counter.v yosys> hierarchy -check yosys> proc; opt; fsm; opt; memory; opt yosys> techmap; opt yosys> dfflibmap -liberty cmos_cells.lib yosys> abc -liberty cmos_cells_plus.lib
4bitの符号なし整数に1を足す回路は以下のように合成できるようです。
ABC RESULTS: NAND cells: 7 ABC RESULTS: NOT cells: 4 ABC RESULTS: NOR cells: 9
ライブラリを書き換えてみる
cmos_cells.lib
をコピーしたcmos_cells_2.lib
に、以下の記述を書き加えてみます。
cell(XOR) { area: 4; pin(A) { direction: input; } pin(B) { direction: input; } pin(Y) { direction: output; function: "(A*B+A'*B')"; } }
さきほどと同じ手順を踏むと、以下の結果を得ます。
ABC RESULTS: NOT cells: 3 ABC RESULTS: NAND cells: 3 ABC RESULTS: XOR cells: 3 ABC RESULTS: NOR cells: 6
NANDが4つ、NORが3つ、NOTが1つ、それぞれ減った代わりにXORが3つ増えたようです。 得したのかよくわかりません。
XORのコストを上げたら使われなくなるのかな、と思ってarea: 40;
などとしてみたら、以下のようになりました。
ABC RESULTS: NOT cells: 4 ABC RESULTS: NAND cells: 6 ABC RESULTS: XOR cells: 1 ABC RESULTS: NOR cells: 7
XORの使用がひかえめになりました。 でも、XORはNAND四つで作れるので、NANDの10倍のコストに設定したのに使われるのは変です。 面積を最小化しているわけではないのでしょうか。
ゲートカウント
yosys gate countとかでググると、以下のページが出てきます。
以下のように入力すれば、CMOSゲートに合成してくれるようです。
$ ~/yosys/bin/yosys yosys> read_verilog counter.v yosys> hierarchy -check yosys> proc; opt; fsm; opt; memory; opt yosys> techmap; opt yosys> abc -g cmos
出力は以下のようになりました。
ABC RESULTS: NOT cells: 2 ABC RESULTS: NAND cells: 1 ABC RESULTS: AOI3 cells: 1 ABC RESULTS: NOR cells: 2 ABC RESULTS: XOR cells: 2
AOI3のような、CMOSらしさあふれるものが使われていることがわかります(AOI3は複合ゲートの一種で、~((a&b)|c)
が6トランジスタで作れるというやつです)。
トランジスタカウント
yosys transistor countとかでググると、以下のページが出てきます。
以下のように入力すれば、トランジスタ数を算出してくれるようです。
$ ~/yosys/bin/yosys yosys> read_verilog counter.v yosys> hierarchy -check yosys> proc; opt; fsm; opt; memory; opt yosys> techmap; opt yosys> abc -g cmos yosys> stat -tech cmos
すると、以下の出力を得ます。
12. Printing statistics. === counter === Number of wires: 19 Number of wire bits: 31 Number of public wires: 4 Number of public wire bits: 7 Number of memories: 0 Number of memory bits: 0 Number of processes: 0 Number of cells: 12 $_AOI3_ 1 $_NAND_ 1 $_NOR_ 2 $_NOT_ 2 $_SDFFE_PP0P_ 4 $_XOR_ 2 Estimated number of transistors: 46+
+
がついてしまっているのは、フリップフロップのトランジスタ数がわからないことによるもののようです(stat.ccの215~218行目と261行目)。
トランジスタ数は、cost.hの53行目~68行目に定義されているものが使われていそうです。
XORゲートは10トランジスタで作れるはず(XORゲート - Wikipedia)ですが、それ以外はあっていそうです。
なお、ソースコードのどこで定義されているかは、GitHub上でcmosと検索することで発見しました。
面積
dffmap libraryとかでググると、以下のページが出てきます。
どうやらOklahoma State Universityが180nm用のスタンダードセルライブラリを公開しているようです。
osu018_stdcells.lib
(243KB)をダウンロードして、実験用ディレクトリに入れます。
これを、cmos_cells.lib
の代わりに使います。
$ ~/yosys/bin/yosys yosys> read_verilog counter.v yosys> hierarchy -check yosys> proc; opt; fsm; opt; memory; opt yosys> techmap; opt yosys> dfflibmap -liberty osu018_stdcells.lib yosys> abc -liberty osu018_stdcells.lib yosys> stat -liberty osu018_stdcells.lib
出力は以下のようになりました。
12. Printing statistics. === counter === Number of wires: 34 Number of wire bits: 46 Number of public wires: 4 Number of public wire bits: 7 Number of memories: 0 Number of memory bits: 0 Number of processes: 0 Number of cells: 17 AND2X1 1 AOI21X1 3 DFFPOSX1 4 INVX1 2 NAND3X1 1 NOR2X1 3 OAI21X1 2 XNOR2X1 1 Chip area for module '\counter': 754.000000
スタンダードセルの面積の確認
トランジスタを並べて回路を実現するとき、トランジスタを自由に配置できるとすると検証が大変です。 そこで、よくありそうな回路について検証されたトランジスタ配置を作っておき、それを並べて回路を実現することを考えます。 そのような検証されたトランジスタ配置がスタンダードセルです。 スタンダードセルは並べて使うことが前提なので、回路の外枠が長方形になっていて、かつ高さが固定値です。 高さが固定なので、トランジスタ数の多い回路は幅が広くなります。
- スタンダードセルに関する視覚的にわかりやすい資料:https://www.am.ics.keio.ac.jp/digital/layout.pdf
- 7nmの時代でも似たような感じらしい:ARMから見た7nm CMOS時代のCPU設計(5)〜スタンダードセルの「スタンダード」とは何か:福田昭のデバイス通信(16)(1/2 ページ) - EE Times Japan
osu018のスタンダードセルライブラリは、pMOSトランジスタとnMOSトランジスタのペア当たり、高さ8、幅1、となっていると思われます。
- NOTゲート:2トランジスタ必要で1列、隣とのスペースに1列、で2列なので面積は16
- NANDゲートやNORゲート:4トランジスタ必要で2列、隣とのスペースに1列、で3列なので面積は24
- ANDゲートやORゲート:6トランジスタ必要で3列、隣とのスペースに1列、で4列なので面積は32
- XORゲート:12トランジスタ必要で6列、隣とのスペースに1列、で7列なので面積は56(やっぱり12トランジスタで作るのが主流なのでしょうか)
- 半加算器:XORとANDなので18トランジスタ必要で9列、隣とのスペースに1列、で10列なので面積は80
- 全加算器:負論理で24トランジスタ必要※で12列、反転に4トランジスタ必要で2列、隣とのスペースに1列で15列なので面積は120
※参考文献:https://www.hindawi.com/journals/vlsi/2012/173079/(XORゲート - Wikipediaの参考文献として載っていました)
三入力NANDゲートは同様の推論で行くと32になりそうなところ36になっていて謎ですが、他は大体あっていそうです。
次に読む
さきほどのOklahoma State Universityのスタンダードセルライブラリを紹介していたブログの他の記事で、遅延の評価をやっているので、今度はこれをやってみたいと思います。