Verilogをはじめよう! その2
前回は演算子が、○○器を作るという話まででした。加算器について、どのような加算器が作られるのか、いけるところまで作ってみましょう。
今日も嘘が多めです。
まずは、加算器の片方を定数にしてみましょう。これで、(define plus5 (lambda (x) (+ x 5))みたいな、わかりやすい変換を期待しています。
always @(posedge clk) begin
if(a == b) begin
a <= b + 5;
end else begin
a <= a + 10;
end
end
コンパイルすると、5を足す加算器と、10を足す加算器がそれぞれできるはずです。
ちくしょう
なんということでしょう。最適化されて、加算器が一つになってしまいました。
つまりこういう事です。
if(a == b) begin
a <= b + 5;
end else begin
a <= a + 10;
end
がC言語っぽい疑似コードで書くとこう最適化されました。
cond = (a == b);
tmp_a = cond ? b : a;
tmp_b = cond ? 5 : 10;
a <= tmp_a + tmp_b;
<=はレジスタへの代入、=はただの配線です。?はif文のシンタックスシュガーなので、○○器を作る演算子ではありません。結果的に、もとのコードに比べると+の演算子が一つ減っていることになります。その結果、等価な回路でも少ない加算器で実現できました。
教科書的にはリソースシェアリングという最適化です。この場合、加算器を b + 5、a + 10という2つの式でシェアしています。不意打ちだったのでびっくりしましたが、次からネタに使えるので良しとしましょう。
今日の発見
・ISEはデフォでリソースシェアリングをする。
ちなみにSynplifyはデフォでOFFです。多分。
ISEのresource sharingのオプションをoffにして、あらためてコンパイルするとこうなりました。
もう満足です。よく見ると加算器の片方の入力が、101や1010になっているのがわかります。当然、ソースの中に現れる定数、5と10の事です。+を書けば、書く度に加算器が作られます。足せば足すほど加算器です。
話は変わりますが、ifの話。
前回は四角いのがifとあっさり説明しましたが、四角の中身はこうなっています。
理系の方であれば1回くらい見たことがある図だと思います。マルチプレクサとかセレクタとか呼ばれる論理回路です。真面目な説明は例によって、http://ja.wikipedia.org/wiki/マルチプレクサへ。京大の中のページにはちゃんと2入力のマルチプレクサがあります。不真面目に説明すると、魔法使い?という信号が1ならばタバサが、0ならば長門がでてくるような回路です。一気にきもくなりました。
よくみるとマルチプレクサの入力が上から、a_addsub0001(7)、a_cmp_eq0000、a_addsub0000(7)、出力がa_mux000(7)です。セレクタのSにあたる部分に比較器の出力(a_cmp_eq0000)が接続されていています。比較器の出力とは、ソース内の(a == b)の判定結果です。A、Bにあたる部分がa_addsub0001(7)と、a_addsub0000(7)です。2つある加算器の出力から一つを選んで、a_mux000(7)を作っています。末尾の(7)はおそらく7bit目という意味ですが、コンパイラが勝手につけた中間ノードなので断言はできません。ソースははしょってますが、実は変数aは8bitです。最適化がかかっている図でも、そうでない図でもどちらでも良いのですが、もう一度図をよく見てください。マルチプレクサ(四角)が8つあるのがわかります。最終のa(8bit)を作るのに、各bitそれぞれにマルチプレクサが入っているというわけです。
if文は、C言語では条件付きジャンプ命令になりますが、HDLではマルチプレクサを生成します。C言語でif文書いても条件付きジャンプにならないことがあるように、常にマルチプレクサになるかといわれると困りますが、やっぱり困るのでこの説明で勘弁してください。こんな風に教えてくれたら、論理回路の授業ももっと楽しめたに違いありませんが、僕はそもそも論理回路or電気回路は履修していない気がします。
マルチプレクサが、andとorとnotで出来ているのも面白いです。全ての論理回路はandとorとnotで表現できます。Schemeが5つの構文(define、quote、if、set!、lambda)に還元できるように、全ての論理回路はandとorとnotに還元できます。携帯も、PS3も、パソコンも中に入っている半導体をばらしていくと、大半はandとorとnotの集まりになります。ちょっとすごい。Shiroさんお勧めの思考する機械コンピュータの前半もそういうお話でした。
andとorとnotにコンパイルされたHDLが、どのようにFPGAの中で動くのかはとても面白いのですが、今日はここまで。
The comments to this entry are closed.
Comments
こんにちは。
論理回路の話ですが、NANDかNORのいずれかがあればすべてはそれから作ることが
できるというのを大学時代に習ったような記憶があるのですが違うのでしょうか?
工学部じゃなくてちょこっとやっただけでなので間違った記憶かも(^^;
Posted by: きむら(K) | 2007.09.15 01:19 AM
シェーファーの魔法の棒
http://alohakun.blog7.fc2.com/blog-entry-58.html
ってやつですねぇ (2 年半も前の記事を読みかえすと,いろいろ恥ずかしい).
# 僕は昔からダニエル・ヒリス燃えなので,昔の記事ではシンキングマシンズ社 (コネクションマシン) とか,思考する機械コンピュータについていろいろ書いていたりも.あと第五世代コンピュータ計画とか GHC/KL1 とか.
not A は A nand A で,
A and B は, not が既にできているので not (A nand B) で,
A or B は, and と not が既にできているので not (not A and not B) で表現できます.
Posted by: あろは | 2007.09.15 04:18 AM
ああ、確かにそうだ。
NANDから、NOTを作る。
NANDの出力にNOTを入れるとAND。
NANDの入力2つにNOTを入れると、ドモルガンでORですね。
というか、トランジスタの基本動作がNANDだから、NAND一つでOKです。orz
嘘を書いてしまったことよりも、反応があったことの方が嬉しい。
突っ込みありがとうございました。
Posted by: なつたん | 2007.09.15 04:19 AM
こんな時間に、あろはさんと一分ちがいだ。
おはようございます。
フォローありがとうございます。
とりえあず、読者が2人いることはわかったので、次はもう少しまじめに書こう。
Posted by: なつたん | 2007.09.15 04:28 AM
おはようございます。
私も楽しみに読んでいます。
もう1つNORの場合を。
NOTは A NOR A、ANDは (NOT A) NOR (NOT A)、ORは NOT (A NOR A)ですね。
これからの展開を楽しみにしています。
Posted by: marsee | 2007.09.15 05:00 AM
marseeさん、こんにちは。
FPGAの基本動作にいくまでに、あとCLKと、レジスタの概念が必要ですね。
ステートマシーンは、不真面目に説明するだけの国語力がないので、悩ましいところです。
最後に、CPUの創りかたの4bitCPUができるところまで行けば十分かなと。
HDLを知らない人が一人でも興味を持ってくれれば、私としては大成功なのですが、
まじめに勉強している人には有害かもしれません。
Posted by: なつたん | 2007.09.15 02:56 PM
こんにちは。
うちのFPGAの実験では、組み合わせ回路、順序回路、ステートマシンと進んでいきます。
>まじめに勉強している人には有害かもしれません。
そんなことないと思います。少なくとも私は、興味深く拝見させていただいています。
NORの回路、起床したときに書いたので間違いました。すみませんが修正させてください。
>NOTは A NOR A、ANDは (NOT A) NOR (NOT A)、ORは NOT (A NOR A)
正しくは、NOT Aは A NOR A
A AND B は (NOT A) NOR (NOT B)
A OR B は NOT(A NOR B)
Posted by: marsee | 2007.09.15 07:25 PM
marseeさん、こんにちは。
やはり、順番としては、順序回路(CLK、レジスタ)→ステートマシーンですね。
有害かなと思うところは、いくつかあって
・今回の間違いもそうですが、いろんな所で裏を取っていない。
・実際のFPGAなりASICで、*を使って乗算器を作ることはまずない。組み込みの乗算器であったり、デザインコンパイラのライブラリでラップされていたり。
等々、誤字脱字も多いですし。
ぼちぼちと書いていきますので、突っ込みがありましたらよろしくお願いいたします。
Posted by: なつたん | 2007.09.16 02:20 PM
こんにちは
話がずれるかもしれないですが、気になったので。
LSIのレイアウト(CMOS)ではNOT はNOTであってNANDでは作らないです。
参考URL
http://www.moge.org/okabe/temp/circuit/node22.html
ちなみにゲート規模で言うと
NOR:1ゲート, NOR:2ゲート,NAND:2ゲート
で、単純にPMOSとNMOSをペアとして
CMOSトランジスタの数です。
Posted by: mayarero | 2007.09.18 07:06 AM
mayareroさん、こんにちは。
トランジスタがNANDが基本というのは、TTLを想定して書いたのですが、
HDLの話をしていてるときに、TTL前提の話はおかしいですね。
指摘が無ければ気がつきませんでした。
HDLにおける、マシン語とか命令セットというのは実はここなんですよね。
まだまだ勉強が足りない。
コメントありがとうございました。
Posted by: なつたん | 2007.09.19 04:46 AM