AIのチップ(?)のまとめ

半導体回路の重要国際会議

から、チップレベルで実装されている深層学習アクセラレータの研究を抜粋した個人的なまとめ。 時折更新する。
産業的な要請 (?) から、多くはエッジデバイスにおける推論処理にフォーカスしている。
アプリケーションへの特化具合はものによりけり。

2018年におけるトレンド

  • 量子化
    重みや活性化関数のバイナリ化、3値化、対数近似 。
    専用ハードウェアの実装においては、特にメモリ使用量や演算器の削減効果が大きい。

  • Computing in-memory
    メモリと演算コアの間のデータ転送が性能のボトルネックになり易いため、 メモリ (主にSRAM) の内部や近傍で計算をおこなう構成が流行している。

  • アナログ演算
    差別化や演算効率化 (?) のためにアナログ的な演算手法を取り入れた研究が散見される。

関連分野、他に見ておくべき論文

  • アーキテクチャ
    ISCA, MICRO, HPCA, ASPLOSといった重要会議から演算コアやネットワークのアーキテクチャを引用した論文が多い。

  • コンピュータビジョン
    深層学習と親和性が高く、なおかつエッジデバイス向けのアプリケーションが多いため、 CVPR等で発表されたアプリケーションを引用して、専用ハードウェアによる低消費電力化・高速化を謳う論文が多々ある。

  • FPGA
    FPGA, FCCM, FPLといった重要会議でFPGA上への実装が報告されており、これらを参考に書かれた論文が多数ある。

汎用アクセラレータ

  • Eyeriss: A Spatial Architecture for Energy-Efficient Dataflow for Convolutional Neural Networks (MIT, NVIDIA, ISSCC 2016)
    • メッシュ型ネットワークで接続された積和演算コアとデータフローアーキテクチャで畳み込み演算を効率化。
  • EIE: Efficient Inference Engine on Compressed Deep Neural Network (Stanford University, Tsinghua University, ISSCC 2016)
    • スパース性を利用したチップ内SRAMへの効率的なデータ格納で性能改善。
  • A 1.42TOPS/W Deep Convolutional Neural Network Recognition Processor for Intelligent IoE Systems (KAIST, ISSCC 2016)
  • A 0.3‐2.6 TOPS/W Precision‐Scalable Processor for Real‐Time Large‐Scale ConvNets (KU Leuven, VLSI Cir. 2016)
  • A 1.40mm2 141mW 898GOPS Sparse Neuromorphic Processor in 40nm CMOS (University of Michigan, VLSI Cir. 2016)
  • Time-domain neural network: A 48.5 TSOp/s/W neuromorphic chip optimized for deep learning and CMOS technology (Toshiba, A-SSCC 2016)
    • 2信号間の時間的な遅延を利用してアナログ演算。遅延量は抵抗で調整。将来的な積層ReRAMの利用を想定。
  • DNPU: An 8.1TOPS/W Reconfigurable CNN-RNN Processor for GeneralPurpose Deep Neural Networks (KAIST, ISSCC 2017)
    • 畳み込み演算に特化したユニットと、全結合層+RNN演算に特化したユニットのハイブリッド型。
  • ENVISION: A 0.26-to-10TOPS/W Subword-Parallel Computational Accuracy-Voltage-Frequency-Scalable Convolutional Neural Network Processor in 28nm FDSOI (KU Leuven, ISSCC 2017)
  • A 3.43TOPS/W 48.9pJ/Pixel 50.1nJ/Classification 512 Analog Neuron Sparse Coding Neural Network with On-Chip Learning and Classification in 40nm CMOS (University of Michigan, Intel, VLSI Cir. 2017)
  • BRein Memory: A 13-Layer 4.2 K Neuron/0.8 M Synapse Binary/Ternary Reconfigurable In-Memory Deep Neural Network Accelerator in 65 nm CMOS (Hokkaido University, TiTech, Keio University, VLSI Cir. 2017)
    • 2値化・3値化が可能で、活性化関数もバイナリ。演算はSRAMの近くで効率よくおこなう。
  • A 1.06-To-5.09 TOPS/W Reconfigurable Hybrid-Neural-Network Processor for Deep Learning Applications (Tsinghua University, VLSI Cir. 2017)
  • A Shift Towards Edge Machine-Learning Processing (Google, ISSCC 2018)
  • QUEST: A 7.49TOPS Multi-Purpose Log-Quantized DNN Inference Engine Stacked on 96MB 3D SRAM Using Inductive-Coupling Technology in 40nm CMOS (Hokkaido University, Keio University, ISSCC 2018)
    • 対数量子化、三次元積層のSRAMチップで大容量化と転送速度向上を図っている。
  • UNPU: A 50.6TOPS/W Unified Deep Neural Network Accelerator with 1b-to-16b Fully-Variable Weight Bit-Precision (KAIST, ISSCC 2018)
    • 1bitから16bitまで自由に精度調整可能。ユニファイド型。ネットワーク構成も自由度が高い。
  • Conv-RAM: An Energy-Efficient SRAM with Embedded Convolution Computation for Low-Power CNN-Based Machine Learning Applications (MIT, ISSCC 2018)
    • バイナリ重みの畳み込み2層をインメモリ計算。
  • A 65nm 1Mb Nonvolatile Computing-in-Memory ReRAM Macro with Sub-16ns Multiply-and-Accumulate for Binary DNN AI Edge Processors (NTHU, ISSCC 2018)
  • A 65nm 4Kb Algorithm-Dependent Computing-in-Memory SRAM Unit Macro with 2.3ns and 55.8TOPS/W Fully Parallel Product-Sum Operation for Binary DNN Edge Processors (NTHU, TSMC, UESTC, ASU, ISSCC 2018)
  • STICKER: A 0.41‐62.1 TOPS/W 8bit Neural Network Processor with Multi‐Sparsity Compatible Convolution Arrays and Online Tuning Acceleration for Fully Connected Layers (THU, VLSI Cir. 2018)

特定アプリ向けアクセラレータ

  • A 126.1mW Real-Time Natural UI/UX Processor with Embedded Deep Learning Core for Low-Power Smart Glasses Systems (KAIST, ISSCC 2016)
    • 音声と手形状認識によるマルチモーダルなUIを実現。スマートグラス向け。
  • A 502GOPS and 0.984mW Dual-Mode ADAS SoC with RNN-FIS Engine for Intention Prediction in Automotive Black-Box System (KAIST, ISSCC 2016)
  • A 0.55V 1.1mW Artificial-Intelligence Processor with PVT Compensation for Micro Robots (KAIST, ISSCC 2016)
  • A 0.62mW Ultra-Low-Power Convolutional-Neural-Network Face Recognition Processor and a CIS Integrated with Always-On Haar-Like Face Detector (KAIST, ISSCC 2017)
    • ウェアラブル常時稼動顔認識デバイス向け。Haar-Like顔検出器チップと、CNN顔分類プロセッサチップを混載。
  • A 9.02mW CNN-stereo-based real-time 3D hand-gesture recognition processor for smart mobile devices (Georgia Tech, ISSCC 2018)
    • HMD向け3Dハンドジェスチャ認識。ステレオマッチング。
  • A 55nm Time-Domain Mixed-Signal Neuromorphic Accelerator with Stochastic Synapses and Embedded Reinforcement Learning for Autonomous Micro-Robots (Georgia Tech, ISSCC 2018)
    • 自律動作のナノロボット向け。強化学習プロセッサ。
  • An Always-On 3.8μJ/86% CIFAR-10 Mixed-Signal Binary CNN Processor with All Memory on Chip in 28nm CMOS (Stanford, KU Leuven, ISSCC 2018)
  • A 1μW Voice Activity Detector Using Analog Feature Extraction and Digital Deep Neural Network (Columbia University, ISSCC 2018)
  • B‐Face: 0.2 mW CNN‐Based Face Recognition Processor with Face Alignment for Mobile User Identification (KAIST, VLSI Cir. 2018)
  • PhaseMAC: A 14 TOPS/W 8bit GRO based Phase Domain MAC Circuit for In‐Sensor‐Computed Deep Learning Accelerators (Toshiba, VLSI Cir. 2018)

幼女でもできる自作CPUチップ (16) CPUチップの測定

 前回の記事

ourfool.hatenablog.com

では、CPUチップの製造について書いた。

 今回は、製造されたCPUの測定について書いていく。CPUチップの入ったQFPパッケージをソケットに入れ、ArduinoをROM代わりに使って実際に動作するかを確認する。

 まず、CPUのQFPパッケージをクラムシェル型の測定ソケットに入れ、ブレッドボードを介して、ArduinoやLEDと接続した。ここで、ArduinoはROMとクロック・リセット回路の役割を、LEDは出力ポートを可視化する役割を果たしている。実際に繋いだようすは以下のような感じ。

f:id:ourfool:20180216155854j:plain

 

f:id:ourfool:20180216160017j:plain

写真からは何一つ情報が読み取れないかと思うので、各接続を図解すると、以下のような感じである。

 

f:id:ourfool:20180216162441p:plain

CPUからAddressを受取ったArduinoはそれに対応する命令をCPUへ返し、同時にCLK信号を一定周期でCPUへ向けて出力する。また、CPUの出力ポートにLEDアレイを接続することで、CPUからの出力が目で確認できるようになっている。 

 ArduinoにROMやクロック回路の役割を担当させるためのコードは、たとえば以下のような感じである。Arduinoの文法だけを使って幼女的に書いているので読めばわかるはずである。

CPUEval

CPUから受け取ったアドレス(analogRead(ADDR0)などの値)に応じて、指定した命令列をCPUへ出力している(digitalWrite(IM0, LOW), digitalWrite(INST0, HIGH)等)。また、クロックの生成も担当している。ここでクロックの周期は400~ms程度と設定しているので、CPUは2Hz程度で動作することになる。
 Arduinoに書き込んだプログラム内容で意図しているCPUの動作や、そのときの出力LEDの状態は以下の表のとおりである。これを確認できれば、ひとまず各種転送命令や演算命令が一通り実行できていることが確認できる。

f:id:ourfool:20180216162226p:plain

各種転送命令、演算命令に応じてLEDの状態が変わっていき、最後はジャンプ命令で最初のアドレスへと戻り、無限ループするプログラムとなっている。

 上記のプログラムを実行した結果は、以下のようになった。

表の意図する出力LEDの状態と比較すると、想定のとおりに動作していることがわかる。

 さて、今回までで実際にCPUチップを設計・製造し、その動作を確認することができた。CPUを作るという目標は半ば達成できたと言っていいのだが、肝心のCPUの脇でROM代わりに高級なマイコンを使っているところは何とも微妙な印象である。
 そこで、以前の記事(幼女でもできる自作CPUチップ (2) - saginomiya1.5)で示したとおり、製造したCPUとROM、クロック・リセット回路を基板に実装し、マイコン等を使わない独立のシステムとして組み上げることを目標としたい。次回は、その基板設計について書く予定である。

幼女でもできる自作CPUチップ (15) CPUチップの製造

 前回の記事

ourfool.hatenablog.com

では、CPUチップの製造に向けて、CPUのレイアウトをおこなった。ここまででチップ開発者としておこなう作業は全て終了したため、彼のデータを国内工場へと送付し、手薬煉いて製造完了の知らせを待つ状態であった。

 さて、去る本年1月、1年弱の月日を経て、ついに正常に製造されたCPUチップが到着した。

f:id:ourfool:20180214232251j:plain

ここまでの道のりも平坦ではなかった、というのも、実は昨年3月の時点でCPUチップは一度製造されていたのである。

 昨年3月に無事製造されたかに見えたチップは、全く動作をしなかった。話によると、製造側でトラブルがあり、回路の特性がかなり怪しいらしい。そうなると、せめて、不良モデル・原因だけでも正確に把握したいところである。幸い同一チップ上にCPU以外にも非常に簡単な回路が載っており、このデバイス特性を参考にすることができる、また同一のラインで複数チップが製造されたため、他のチップに載った回路に関しても参考にできるはずであった。しかし、そもそもトランジスタとしての特性を示していないように思われる回路が多く、どの回路もまともに動いてくれなかったため、デバッグの甲斐もなかった。したがって、ともかく今回は製造に失敗したが同じデータで再度製造すれば大丈夫なはず、という非常に曖昧な状態で次の機会へ臨むこととなった。

 そうした状況で、次の製造機会までにいったい何ができるか。ひとまず、前回駆け足で作ったため貧弱になっていたレイアウトの電源部分を強化することにした。プリント基板作成などの場合と同様、大きな電流が流れる電源配線は可能な限り太く、複数経路で配線するのが望ましい。加えて、重要な信号配線のいくつかについて、直接チップの外へとつなぎ、直接観測できるようにした。これによって万が一回路にミスがあった場合にも、容易にデバッグが可能になる。

 こうした気休め程度の修正を終えたのち、ある考えが頭をよぎった。これまで真面目に作ってきたチップにおいて、製造側で問題が発生したことは一度もなかった。そうしたチップと今回のCPUチップとの違いは何か。明白である。貴重なシリコン面積を犠牲にして、絵を描いているのだ。

f:id:ourfool:20180214233648p:plain

そこで、ついに大きな決断を下した。絵を削除し、そのスペースを使った電源配線の強化、デバッグ用の信号配線に踏み切ったのである。これは疑心暗鬼というべきものだろうし、絵のひとつも載っていないCPUなど無用、学術的な裏付けなしにこの削除をおこなったのは理性の敗北というものかもしれない。しかし、絵を載せたところでCPUの特性に全く変化はなく、無駄に配線し辛くなるということだけは違いなく事実であるからして、今回は絵を全て削除して右のような新レイアウトを得た。

 そうした苦難の末に、ついに、正常に製造されたCPUチップは到着したのである。これを測定用のソケットに入れ、信号生成用のArduinoと接続したのが以下の図。せっかく1チップのCPUを作ったにも関わらず滅茶苦茶な配線である。

f:id:ourfool:20180215001243j:plain

 次回はこのチップの測定とその結果について書いていく。何気に3年ほど続いて来たCPUチップの製造開発にも、終わりが近づいて来たようだ。 

幼女でもできる自作CPUチップ (14) CPUチップのレイアウト

 前回の記事

ourfool.hatenablog.com

では、CPUチップの製造に向けて、CPUの各回路ブロックのレイアウトをおこなった。

 ここまでの作業で、CPUに搭載する回路ブロックのレイアウトを全て終えることができた。あとは各ブロックの電源・GND線や、対応する信号線を接続したのち、チップ外部と接続される線を、外周に設けられたボンディングPADと接続すれば、ついに自作CPU、LO5をワンチップ化したものが完成する。

 さて、まずは、各ブロックを適当に配置しよう——としたところで、ふと冷静になってみると、どうもおかしなことに気が付いた。今回試作を想定しているチップの面積はおよそ3mm角だが、PADや外周の電源リングを除くと内部回路に使える面積は高々2.5mm角である。一方、各ブロックの大きさは大きなもので1辺1mmを超える。なんだこのクソデカ回路。終わった。

 そんなわけで、真面目に面積をよくよく鑑みて設計する必要があるとわかり、それぞれの配置は以下のようになった。

f:id:ourfool:20170322000325j:plain

特にプログラムカウンタとALU、出力ポートなどは、事前に配線経路を検討して、最小線幅・線間隔のぎりぎりを攻めて配置した。当たり前だが、ドチャクソ大変だった。

 今回使う2umCMOSプロセスでは、メタル配線がなんと2層しかない。そのため、配線同士が干渉しないよう事前に考え考えして、慎重に配線をおこなわなければならない。LSIにおける配線のごく基本的な戦略として、縦と横で使うメタル配線を分けるというものがある。縦は2層目、4層目、6層目、といった偶数層のメタル、横は3層目、5層目、7層目といった奇数層のメタル、といった風にである。アナログ回路(専ら手配線する)にしろ、ディジタル回路(専ら自動配線するため、使用するメタル層は設定で決める)にしろこれが基本戦術である。なお、今回はそもそも2層しかメタルがないので、まあブロック間のグローバルな配線はどちらかが横でどちらかが縦でいこ、詰まったらそんとき考えよ、といった適当な感じで配線していった。

 まず、レジスタセレクタ、ALUの配線をおこなった。ここはスペース的に余裕があるので、間違いのないよう、兎角、空いた空間を等分割しそれぞれの配線を割り当てる、と意識して引いた。

f:id:ourfool:20170322001818j:plain

 下図は出力ポートとALU、プログラムカウンタの間で、ここが最も難しかった。データバスをそれぞれに接続する上、各々の選択信号を引き出す必要もある。しかしながら、上で示したブロックの配置からわかるとおり、全体の面積削減はここの空間をどれだけ小さく出来るかにかかっている。そのため、最小面積を目指して細かな調整を加えつつ配線した。

f:id:ourfool:20170322002218j:plain

 その後、各々の回路ブロックの電源・GNDを接続し、PADへと接続する配線に名前をテキストで貼り付け、と色々面倒な作業をした末、最終的なレイアウトは以下のようになった。割と感無量である。

f:id:ourfool:20170322002434j:plain

PADへの接続配線の最終的な接続は、チップ試作の都合上、大先生にお願いした。ここで深く感謝いたします。

 さて、そんなわけでなんとか一通りレイアウトを終えた————とかなんか割と順調に終わったように書いてしまったが、実際には相当に過酷、というか無謀な作業であった。予想の10倍の時間がかかったうえ、最終的には締切当日の朝に意識朦朧の中なんとか終えた、ってか終わったのか?これ終わったの?といった有様であった。

 冷静に考えると、ブロック内より遥かに配線量が多い上、・2層しかメタルがなく、・面積にも余裕がない、のだから時間がかかるのは当たり前なのだが、通常手描きしているようなアナログLSI設計では双方ともあり得ない条件だったため、全く見込み違いとなってしまった。結論、ディジタル回路は手描きするべきではない。

 とにもかくにも回路のレイアウトは終えられたが、このままではブロック間に空白が目立ち、そこで密度エラーが生じてしまう恐れがあると、最後の最後に思い至った*1。これを何とか回避するため、最後の力を振り絞って空白にダミーのパターンを挿入し、最終的なチップレイアウトを以下のように得た。

f:id:ourfool:20170322004849j:plain

 さて、そんなわけで、ついに自作CPUであるLO5(Laconic Original 5-bit processor)のチップレイアウト≒製造用マスクデータが完成した。あとは製造を待つばかりである。いよいよ、幼女でもCPUチップが自作できることが証明されるのだ。

 次回はこのチップの測定とその結果について書くことになるはずである。あるいはその前段階で、測定基板の設計や、アセンブラの開発について書くかもしれない。

*1:比較的新しいプロセスだと、製造工程での表面平坦性を確保するために、メタル層の密度をチップ全体で均一にしなければならない、という厳しい設計ルールが存在する。なお本試作は全く遅れたプロセスなので、そんな設計ルールは存在しない。

幼女でもできる自作CPUチップ (13) レジスタ・プログラムカウンタのLSI向けレイアウト

 前回の記事

ourfool.hatenablog.com

では、CPUチップの製造に向けて、命令デコーダとデータセレクタのレイアウトをおこなった。

 今回は、残された回路ブロックである、レジスタとプログラムカウンタのレイアウトについて書いていく。

 最初におさらいしておくと、外部メモリやクロック回路、命令デコーダも含めたCPU全体のブロック図と、演算コア内部のブロック図とは、それぞれ以下のようになっていたのであった。

f:id:ourfool:20170227001555j:plain

 

f:id:ourfool:20170303192320j:plain

  前回までに、ALU、命令デコーダ、データセレクタのレイアウトを終えたため、残ったのは、レジスタA, Bとプログラムカウンタ、出力ポートとなる。このうち、レジスタA, Bと出力ポートは、回路としては同一のものである。したがって、レジスタとプログラムカウンタのレイアウトを完了すれば、一通りの要素ブロックレイアウトが完了することとなる。

 これまで書いてきたALU、命令デコーダ、データセレクタが全て組み合わせ回路—現在の入力信号に応じて出力信号が一意に定まる—だったのに対して、今回書いていくレジスタやプログラムカウンタは順序回路—クロック信号の立ち上がりに応じてデータを変化させる、つまり過去のデータを保持することができる—である。クロックが出てくるといよいよディジタル回路という感じがしてよさを感じる*1

 まず、レジスタについて書く。レジスタはDフリップフロップと2入力のマルチプレクサから構成されている。

f:id:ourfool:20170303222713j:plain

 Dフリップフロップはクロックの立ち上がりでDの値を取り込み、Qへ出力する機能を持っている。次にクロックがもう一度立ち上がるまでは、その値を保持し続ける*2。ここでは、マルチプレクサの出力がDと繋がっている。仮にLoadの値が0だと、Dフリップフロップの出力Qは入力Dへと短絡され、クロックが何度立ち上がってもDとQは同じ値を保持し続けることになる。一方、Loadが1になると、Dフリップフロップには外部から来たDataが入力される。これによって、Dフリップの入出力はDataへと変更される。

 以上に示したように、この回路が、Loadが0→同じ値を保持し続ける、Loadが1→Dataを取り込む、という機能を持った記憶回路として働くことがわかる。これを5つ並列にすると、5bitレジスタの完成である。

f:id:ourfool:20170303234655j:plain

  次に、プログラムカウンタについて書く。カウンタの機能はクロックの立ち上がり毎に2進数の00000から11111まで出力値を変えていくというものである。基本的な構成はレジスタと似ているが、ちょっと面倒な回路なので細かな説明は省略する。ネット上の記事だとこちら

qiita.com

が詳しいしわかりやすいので、是非ご参照いただきたい。
 そんなこんなで、プログラムカウンタのレイアウトについては、以下のようになった。

f:id:ourfool:20170303235736j:plain

 

  さて、レイアウト後に、それぞれについて前回の記事同様SPICEファイルを生成し、その挙動を検証した。

 以下はレジスタについてのシミュレーション結果である。rst(リセット信号)がHIGHのときにクロックの立ち上がりに応じてout0(出力信号)がLOWへリセットされ、load(読み込み信号)がHIGHのときにはクロックの立ち上がりに応じてin0(入力信号)をout0へ反映し、LOWのときには以前の値を保持し続けていることがわかる。

f:id:ourfool:20170303235905j:plain

 次に、プログラムカウンタのシミュレーション結果を同様に示す。クロック信号の立ち上がりに応じて、rst(リセット信号)がHIGHのときリセット、以降は出力信号の各bit (out4, out3, out2, out1, out0)が、(0, 0, 0, 0, 0)から(1, 1, 1, 1, 1)まで、つまり10進数で示すと0から31まで、クロックに応じて順々に増えていっていることがわかるはずである。LOWとかHIGHとか0とか1とか混在して無茶苦茶な説明だが、とにかく動作は合ってるので感じ取っていただきたい。

f:id:ourfool:20170304000239j:plain

 さて、そんなわけで、全ブロックのレイアウトを終えた。命令デコーダ以外を適当に並べたレイアウトが以下のツイートの添付画像である。

 今回までで、CPUチップに搭載する各ブロックのレイアウトを全て終えることができた。あとは、これらの入出力を適当に配線でつなぐだけである。こんな楽勝な作業はない、優勝確定—なんてことはあるわけがなく、地獄を見た。がそれについては次の記事で書くこととする。

*1:現在のディジタル回路のほとんどはクロック信号を元にした同期設計である。しかし、非同期設計にも長所があり、むしろ研究ネタとしてはこっちが盛り上がっていく気配もある

*2:Dフリップフロップの詳細動作についてはめんどいので省略する。一応内部回路構成について述べておくと、マスタースレーブ方式(Dラッチ2つを接続した構造)で、スイッチ+インバータではなく、クロックドインバータを用いている

幼女でもできる自作CPUチップ (12) 命令デコーダ・データセレクタのLSI向けレイアウト

 前回の記事

ourfool.hatenablog.com

では、CPUチップ製造前のテストとして、自作ALUチップの実装と評価をおこなった。

 ここから本記事まで半年弱と、だいぶ間が空いてしまったが、「ALUチップ作ってなんか一仕事終えた感がでてきたし放置気味でいいか・・・」などと不遜なことを思っていたわけでは全くなく、次の試作へ向けて存分に力を蓄えていたのである。

 さて、今回はいよいよCPU全体を載せたチップの製造に向けて、各ブロックのレイアウトと検証を進めていく―というか、実のところ既にレイアウト+検証済みなので、それについて後追いで書いておく。

 まず、命令デコーダについて。「(4) 命令デコーダ設計」で書いたとおり、機械語命令をCPU内の各回路ブロックの選択信号へと変換するデコーダ回路を設計する必要がある。ゲートレベルの表現は既に完了しているので、あとはこれをLSI上の実レイアウトにすればよい。今回に関しても、配置配線などという高級な手段は使わず、人力でゲートを配置し手配線する。レイアウトツールには、フリーのレイアウトツールであるGladeを用いる。フリーソフトの割にかなりつよい。というかこれがフリーソフトって何がどうなっちゃってるのというレベルである。しかも質問フォーラムでの対応が非常に丁寧で、日本時間のいつ質問しても速攻で返事が返ってくる。謎。しかしこれからLSIを作る幼女の方にはとてもおススメである。

f:id:ourfool:20170226230735j:plain

 さて、そんなわけで命令デコーダのレイアウトをおこなった。全体図は以下のようになった。

f:id:ourfool:20170226231252j:plain

左端の出っ張った部分にはインバータが5個配置されており、各入力信号の反転信号を生成している。IN0~4と、IN0~4の反転信号の計10信号がそこから引き出され、ずらっと並んだ各ゲートに入力されている。「(4) 命令デコーダ設計」の記事に書いた回路図まんまである。

f:id:ourfool:20170226231606j:plain

 

 続いて、データセレクタについて書く。データセレクタの役割は、3種類のデータ (レジスタA, レジスタB, 外部入力) or 全て0 (つまりGND電位) の計4種類のデータから1種類を選んで出力することであった。

f:id:ourfool:20170226233034j:plain

というわけで単に1bitのマルチプレクサをちょいと工夫して配置してやればよい。まず、単純な2データ1選択信号のマルチプレクサは以下のようになる。

f:id:ourfool:20170226233246j:plain

NMOSとPMOSの相補スイッチを使った形である。で、これを2つ並べ、それぞれの出力をさらにもう一つのマルチプレクサへ入力してやると、4データ入力、2選択信号のマルチプレクサができる。1つ目の選択信号で4データのうち2データが勝者として選ばれ、2つ目の選択信号で優勝者が決まるトーナメント方式、と考えるとわかりやすいかもしれない。

f:id:ourfool:20170226233615j:plain

ここで、SA, SBは選択信号、INA, INB, INIが入力信号、GNDがGND電位を入力する部分である。これで1bitのセレクタができた。なお、3つのマルチプレクサの他に2つのインバータを最終段に加えている。これは、マルチプレクサの非フルスイングな出力をGNDから電源電圧までのフルスイング出力に直してやるためである。トランジスタのON抵抗とかが関係ある(適当)。

 あとはこの1bitセレクタをシンプルに並列に並べてやればよい。とても簡単。

f:id:ourfool:20170226234059j:plain

 デコーダセレクタの検証については、Gladeのノード抽出機能によりCDLファイル (cadence社のソフトに使われているSpiceもどきの回路記述形式) を吐き出したあと、それをSpice形式へ書き直した上でもって、LTSpice (ADSpice) でおこなった。使い慣れないLSI用フリーEDAツールを離れ、Spiceでの検証を始めると、実家のような安心感を覚える。

 以下がそのSpiceファイル。普段Spiceで検証するようなアナログ回路ではあんま見ないクソ長かつクソフラット(階層化されておらず全部MOS)記述である。

f:id:ourfool:20170226234509j:plain

 下はシミュレーション結果。入力電圧を0V or 5Vにして各出力を確認した。

f:id:ourfool:20170226234700j:plain

 さて、今回は命令デコーダとデータセレクタの記述を終えることができた。結果として、下図の青く塗りつぶした部分の設計が完了したことになる。

f:id:ourfool:20170227001555j:plain

チップ内部はあとレジスタとプログラムカウンタを残すのみである*1。ちなみに、諸般の都合でLO10は5bitのCPU (LO5) にまた戻ったが、まあその辺は気にしないで進んでいきたい。やはり、5bit=命令32ステップで優勝できるアプリケーションを考えてこそのエンジニア、だったのだ。そういうことにする。

 

*1:てか、これも実は既に終わってる

幼女でもできる自作CPUチップ (11) 自作LSI(4bit ALU)の実装・評価

 前回の記事

ourfool.hatenablog.com

では、自作ALUの搭載されたLSIチップ用に、プリント基板を設計し、製造をおこなった。

 今回はいよいよこの基板に自作LSIチップを搭載し、所望の機能が実現できるかArduinoを使って検証する。

 まず、QFPを基板に手半田した。64pin、0.5mmピッチということでそれなりに細かい作業にはなるが、フラックスを塗りたくって適当に半田を流しておけばなんとかなる。重要なのはとにかく半田を流し過ぎないことのように感じる。基板のフィニッシュをHASL(有鉛半田レベラー)にしておけば、元々基板側にコーティングされた半田が存在するので、外から流す半田はおまけ程度でよいように思う。

なお、QFPの半田付け時には上図のような基板を固定する器具があると非常に助かる。

 今回作る基板はQFP以外とにかくピンヘッダとピンソケットをつけまくるだけなので、QFPさえ乗り越えればあとはサクサクであった。なお、Arduinoとの接続用ピンソケットについては、ピンソケット 1x8 (8P) リード長15mm: パーツ一般 秋月電子通商 電子部品 ネット通販のような15mmリード長のものを採用した。Arduino上に乗った部品とシールドとの干渉を防ぐためには、深くまで挿入してもシールドと部品類間にある程度隙間の残る、15mmリード長の採用が一番簡便である。

 そんなこんなでついに一通り実装を終えた。実装後の基板は以下のような見た目。

 さて、実装を終えたところで今度はArduinoでの評価用プログラム作成をおこなった。具体的に流した最も簡単なプログラムは以下のようなものである。

gistd484ec560e80761b7191bdceff30e6b7

 ここでピン名のID1-4は4bitの入力データ1、IM1-4は4bitの入力データ2、IS0-2は3bitのALU選択信号、O1-4は4bitの出力データをそれぞれ表している。パソコン上のコンソールにA-Eの文字を打ち込むと、それぞれに対応する、ADD(加算)、SUB(減算)、AND、OR、NOT演算がおこなえるよう、ALU選択信号に相当するピン電圧が決定される。その後、入力4bit+4bitの全パターンをぶん回す。入力データの値と出力データの値は 毎回コンソールに表示される。このあたり、マジで幼女レベルのテストコードなので読めばわかるはずである。

 このプログラムに合うよう、QFPからの出力とArduinoピンを接続した。先ほどの小綺麗な実装から嘘みたいに汚い配線状況となった。

f:id:ourfool:20160922004946j:plain

 その配線チェックを終え、祈るような気持ちでプログラムを動かしたところ・・・・・・・・・・・何か挙動がおかしい。しかも規則性がよくわからない、ヤバい。

 この時点で割と死にそうな心持ちになり一旦きんいろモザイクを読んだ。すると数時間後、電源系のそれらしい接続ミスを発見した。やはりきんモザは神。

 5V電源を与えるべきQFPのピンが複数あると気付いたため、ソケットを増設、ジャンパワイヤでつなぎ直した後、息を呑んでプログラムを動かすと・・・

 

 めっちゃ動作した(勝利)

 

 測定系の全景は以下のとおり、ノートパソコンとArduino、今回自作したシールドさえあれば動作する。もちろん、ALUをコンソールから操作する必要がなければ、5Vの外部電源さえあればOK。流石に動いているのを見ると感無量である。

f:id:ourfool:20160922010245j:plain

 さて、そんなわけで、自作LSIチップを自作基板に実装し、幼女でもわかるプログラムでその機能を検証することができた。自作CPUの作成に向けて、大きな一歩を無事踏み出せた。次回はおそらく実際のCPUレイアウトに向かっていくことになるだろう。今回ALUについて、論理としては問題なく動くことが確認できたので、今後動作周波数や各モード毎のタイミングについて探っていき問題がないことを確認した上で、レジスタ周りやクロック分配回路の設計に入っていくことになる。

 まあ何はともあれ、本記事もひとまずこれにてひと段落ということで、次回のチップ試作へ向けて力を蓄えていきたい。その間、本記事の内容を別の媒体としてまとめることを考えているので、そちらについても興味を持って見ていていただければ幸いである。