IT系メモ

興味のあったことや、勉強したことなどをメモしていきます。

LSI設計の流れ

はてな界隈ではコンピュータ関係の人が多いのだけど、はてブを見る限りプログラマーやWebデザイン関係ばかりで、LSI設計に関してのエントリーが少なくて寂しい。

なので自分で書いてみた。

LSI設計の流れはこんな感じ。実際にはRTLがある程度出来た時点でレイアウトを始めるとかあって、必ずしも上が完全に終わってから始めるということはない。

f:id:qpci32siekqd:20111228003339j:plain

背景が青い部分が、論理設計と言われるところ。仕様書に基づいてハードウェア記述言語などで論理を書いていく。ハードウェア記述言語と言われてもよくわからないと思うけど、やってることはvimemacsを使って、プログラミング書いてるのと見た目は変わらない。

RTL記述

ハードウェア記述言語には幾つか種類はあって、メジャーなのはverilogVHDLverilogで書くとこんな感じになる。

module alu (input [31:0] a,b,
		     output reg [31:0] alu_out,
		     input [3:0]	alu_func);

`include "paramlist_alu.h"
        reg [32:0] sum;

        always @* begin //Jan.20.2005 @(a , b ,alu_func,sum) begin
		`ifdef DISPLAY_MESSAGE
		   $display("ALUT Function called alu_func=%h",alu_func);
		`endif	
                case (alu_func)
                        ALU_NOTHING    : alu_out=32'h0000;
                        ALU_ADD        : alu_out=a+b;
                        ALU_SUBTRACT   : alu_out=a+~b+1'b1;//a-b;
                        ALU_OR         : alu_out=a | b;
                        ALU_AND        : alu_out=a & b;
                        ALU_XOR        : alu_out=a ^ b;
                        ALU_NOR        : alu_out=~(a | b);
                        ALU_LESS_THAN_UNSIGNED : alu_out=a < b;//Jun.29.2004
                        ALU_LESS_THAN_SIGNED: begin 
                                                 sum={a[31],a}+~{b[31],b}+1'b1;//a-b                                                                      $signed(a) > $signed(b);
                                                 alu_out={31'h0000_0000,sum[32]}; 
                                               end                      
                        default : alu_out=32'h0000_0000;


                endcase
        end
endmodule

詳細は省略するけど、端子や値を保存するためのレジスタや信号などを書いていく。レジスタの間の論理を記述していくからRTL(Register transfer level)って呼ばれてる。

こういうのを沢山、たくさーん書く。プログラムだと上から順番に動作していくけれども、ハードの場合は全部並列で動く。なので、プログラミングのようなデバッガーを使って、1ステップずつ動かして、変数の内部を見てといったことはしない。

検証

代わりに波形を作る。C言語アセンブラ、その他の言語ではこの信号がどのように動作させるかを制御していて、信号がどのように変化するかを時系列に出したもの。

f:id:qpci32siekqd:20111228000525j:plain

これを見ながらデバッグをする。たいていのLSIはクロックで動作するので、1クロックごとに信号が変化しているのを確認して、仕様書通りに動いているかなーってのを確かめる。

この信号が出すのをシミュレーションというのだけど、シミュレーションの前にコンパイルとエラボレートという処理が入る。

コンパイルはプログラミングと同じで構文間違いがないかをチェックすること、エラボレートというのは繋がっていない信号がないかチェックする接続確認みたいなもの。

数十GB単位のメモリを積んだ数コアのマシンでシミュレーションしても、なかなかシミュレーションなんて終わらない。28nmやら40nmのテクノロジーになると数ミリ秒シミュレーションするのに数時間かかったりする。

実機だと簡単なプログラムだと一瞬で終わるものが、シミュレーションだと全然終わらない。OSなんて動かせそうものなら数ヶ月経っても終わらない。

本当にすごく時間がかかる。バグがあったら泣きそうになる。それでも地道にシミュレーションで出てきた数GBの波形を見ながら修正していくわけです。

論理合成

そうやって確認したのを論理合成する。verilogだと論理は書いているけど、それではウェーハには回路を物理的に作ることは出来ないので、ウェーハに焼き込むことが出来るもっと低レベルな状態にする。

レイアウト

インテルなどのCPUの発表でよく見るダイってもの。こんな感じにどこに何を置くかを決める。基盤には何層かあって、何層目に何を置くかとか、3次元で考えていく。

f:id:qpci32siekqd:20111228003527j:plain

タイミング検証

この状態でタイミング検証をする。実際の電気信号だと信号がHighやLowに変動するのに時間がかかったり、ANDやORなどの論理によって信号が送れたり、配線がすごーく長い場合に決まった時間内に時間内に信号が届かなかったりする。

そういうのをシミュレーションしてキチンと決まった時間内に収まるようにする。


あとはTSMCとかそういった工場にデータを渡して実際のチップを作ってもらう。

こんな感じでLSIは作られます。

FPGAも高位合成もあるんだよ

とここまで一般的(?)なLSIの作り方を書いてきましたが、すごーく時間とお金がかかる。それだけ頑張ったのに性能が出ないんじゃ泣くに泣けない。

もっと効率上げる必要があるよねーということで、FPGAで仮に回路を作って動かしてみたり、高位合成で性能が出るか先に試してみたりする。(といっても28nmのチップなんてFPGAに全部入らないがな。)

最後に

Mac Book AirとiPhoneと参考書数冊買ってすぐに開発できるプログラミング環境が羨ましい。情報共有も盛ん。

今まではてブ人気エントリーLSI設計関係が入っただろうか。
(CPUやGPUの発表はあるだろうけど)

「スマフォアプリの作り方」を抜いて、「ヘテロジーニアスマルチコアの作成からマルチカーネルOSの動作方法まで」なんてエントリーが人気エントリーに入ればいいなぁと夢見る次第です。