コンピュータアーキテクチャにおいて、マイクロコードとは、プロセッサの命令セットアーキテクチャや内部制御シーケンスを実装するために使用される低レベルの制御データまたは命令の層である。[ 1 ]これは、多くのデジタルコンポーネントにおいて、より高レベルのマシンコード命令を実行したり、直接内部シーケンスを実行したりするハードウェアレベルの操作で構成されている。多くの最新のIntelおよびAMD汎用プロセッサでは、一般的な命令は内部マイクロ操作に直接デコードされるが、マイクロコードは主に、より複雑な命令、特殊なケース、およびプロセッサの更新に使用される。[ 2 ]
マイクロコードは、専用の高速メモリに格納され、機械語命令、ステートマシンデータ、またはその他の入力を、詳細な回路レベルの操作シーケンスに変換します。これにより、機械語命令と基盤となる電子回路が分離され、命令の設計と変更における柔軟性が向上します。さらに、複雑な多段階命令の構築を容易にすると同時に、コンピュータ回路の複雑さを軽減します。マイクロコードを記述する行為はマイクロプログラミングと呼ばれることが多く、特定のプロセッサ実装におけるマイクロコードはマイクロプログラムと呼ばれることもあります。
高度なマイクロプログラミングを用いることで、より小規模でシンプルなマイクロアーキテクチャが、より広いワード長、追加の実行ユニットなどを備えた堅牢なアーキテクチャをエミュレートすることが可能になります。このアプローチは、プロセッサファミリ内の異なる製品間におけるソフトウェアの互換性を確保するための比較的簡便な方法を提供します。
ハードウェアレベルでは、プロセッサはさまざまなタスクを実行する複数の独立した回路領域、つまり「ユニット」で構成されています。一般的に見られるユニットには、加算や2つの数値の比較などの命令を実行する算術論理演算ユニット(ALU)、外部メモリへのデータの読み書きを行う回路、および処理中にこれらの値を格納するためのオンボードメモリの小さな領域などがあります。ほとんどの設計では、レジスタファイルと呼ばれる追加の高性能メモリが、現在の命令に必要な値だけでなく、一時的な値を格納するために使用されます。[ 3 ]
命令を正しく実行するには、さまざまな回路を順番にアクティブ化する必要があります。たとえば、メモリからロードされていない2つの数値を加算することはできません。RISC設計では、これらの命令の適切な順序は、主にプログラマ、または少なくともプログラマが使用するプログラミング言語のコンパイラに依存します。たとえば、メモリ内の2つの数値を加算して結果をメモリに格納するには、コンパイラは、一方の値を1つのレジスタにロードし、もう1つの値を別のレジスタにロードし、ALUで加算関数を実行して結果をレジスタに格納し、そのレジスタをメモリに格納する命令を出力する場合があります。[ 3 ]
このより高レベルの概念である「メモリ内のこれら 2 つの数値を加算する」を実行するために必要な命令のシーケンスは、複数の命令を必要とする場合があり、これらの命令がメイン メモリに格納されている場合は、これがパフォーマンスのボトルネックとなる可能性があります。これらの命令を 1 つずつ読み込むには、実際のデータの読み書きに使用できる時間が費やされます。このため、RISC 以外の設計では、データの格納場所が大きく異なるさまざまな命令が多数あるのが一般的です。たとえば、MOS 6502には、加算命令 の 8 つのバリエーションがあり、ADCこれらは 2 つのオペランドを探す場所だけが異なります。[ 4 ]
最終的な操作に最も近い命令のバリエーション、つまり「オペコード」を使用することで、命令数を1つに減らすことができ、プログラムコードで使用されるメモリを節約し、データバスを他の操作のために空けておくことでパフォーマンスを向上させることができます。ただし、内部的には、これらの命令は個別の操作ではなく、ユニットが実際に実行する操作のシーケンスです。メモリから読み取った単一の命令を内部動作のシーケンスに変換するのは、プロセッサ内の別のユニットである制御ユニットの役割です。 [ 5 ]
マイクロコードの基本的な考え方は、命令シーケンスを実装するカスタムハードウェアロジックを、プロセッサ内の「マイクロコードエンジン」で実行される一連の単純な命令に置き換えることです。カスタムロジックシステムでは、さまざまな制御線に一連の電圧を出力するダイオードやゲートが複数あるのに対し、マイクロコードエンジンはこれらの線に接続され、エンジンがマイクロコード命令を順番に読み込むにつれて、これらの線がオン/オフされます。マイクロコード命令は、多くの場合、これらの線にビットエンコードされます。たとえば、ビット8が真であれば、ALUがデータ待ちで一時停止することを意味します。この点において、マイクロコードは、穴が押すべき鍵盤を表す自動演奏ピアノの紙ロールにいくらか似ています。
カスタムロジックとマイクロコードの違いは些細なものに見えるかもしれません。一方はダイオードとゲートのパターンを用いて命令をデコードし、一連の信号を生成するのに対し、もう一方は信号をマイクロ命令としてエンコードし、それを順番に読み取ることで同じ結果を得ます。決定的な違いは、カスタムロジック設計では個々のステップを変更するとハードウェアの再設計が必要になる点です。マイクロコードを使用する場合、変更されるのはマイクロコードを格納するメモリに格納されているコード、またはマイクロコードが制御ストアにロードされるストレージデバイスのみです。これにより、マイクロコードシステムの問題修正がはるかに容易になります。また、命令の複雑さに実質的な制限はなく、使用できるメモリ量によってのみ制限されることを意味します。
コンピュータのソフトウェアスタックの最下層は、従来はプロセッサ用の生の機械語命令でした。マイクロコードプロセッサでは、これらの命令のフェッチとデコード、および実行はマイクロコードによって行われる場合があります。混乱を避けるため、マイクロプログラムに関連する各要素は、マイクロ命令、マイクロアセンブラ、マイクロプログラマなど、マイクロ接頭辞によって区別されます。 [ 6 ]
複雑なデジタルプロセッサでは、本質的に非同期的に並列に実行する必要のあるサブタスクを委任するために、複数の(おそらくマイクロコードベースの)制御ユニットを使用することもあります。たとえば、 VAX 9000には、命令を取得してデコードするためのハードワイヤードの IBox ユニットがあり、それをマイクロコード化された EBox ユニットに渡して実行させます[ 7 ] 。また、 VAX 8800には、マイクロコード化された IBox とマイクロコード化された EBox の両方があります[ 8 ] 。
高水準プログラマー、あるいはアセンブリ言語プログラマーでさえ、通常はマイクロコードを見たり変更したりすることはありません。マシンコードは、同一ファミリー内の異なるプロセッサ間である程度の互換性を維持することが多いのに対し、マイクロコードは、特定のプロセッサ設計自体に内在する要素であるため、設計された電子回路上でのみ動作します。
エンジニアは通常、プロセッサの設計段階でマイクロコードを記述し、それを読み出し専用メモリ(ROM) またはプログラマブルロジックアレイ(PLA) [ 9 ]構造、あるいはその両方の組み合わせに格納します。[ 10 ]しかし、マイクロコードの一部または全部がスタティックランダムアクセスメモリ(SRAM) またはフラッシュメモリに格納されているマシンも存在します。これは、コンピュータの文脈では従来、書き込み可能な制御ストアと呼ばれ、読み出し専用メモリまたは読み書き可能なメモリのいずれかになります。後者の場合、CPU の初期化プロセスは、別の記憶媒体からマイクロコードを制御ストアにロードし、命令セットのバグを修正したり、新しいマシン命令を実装したりするためにマイクロコードを変更する可能性があります。
マイクロプログラムは、ハードウェア回路の非常に基本的なレベルでCPUを制御する一連のマイクロ命令で構成されています。例えば、典型的な水平方向のマイクロ命令1つは、次のような操作を同時に指定することができます。
プロセッサのすべての機能を1サイクルで同時に制御するために、マイクロ命令は50ビットよりも広いサイズになることがよくあります。例えば、エミュレータ機能を備えた360/85では128ビットです。マイクロプログラムは、可能な限り高速に実行できるように慎重に設計および最適化されています。マイクロプログラムの実行速度が遅いと、マシン命令の実行速度が遅くなり、そのような命令を使用する関連アプリケーションプログラムのパフォーマンスが低下するためです。
マイクロコードは、もともとコンピュータの制御ロジックをより簡単に開発する方法として開発されました。当初、CPUの命令セットはハードワイヤードでした。機械語命令のフェッチ、デコード、実行に必要な各ステップ(オペランドアドレスの計算、読み出し、書き込みを含む)は、組み合わせ論理回路と最小限のシーケンシャルステートマシン回路によって直接制御されていました。このようなハードワイヤードプロセッサは非常に効率的でしたが、多段階アドレッシングと複雑な演算(下記参照)を備えた強力な命令セットが必要だったため、設計とデバッグが困難でした。特に非常に不規則なエンコーディングが使用されている場合、高度にエンコードされた可変長の命令もこの問題の一因となります。
マイクロコードは、プロセッサの動作やプログラミングモデルの大部分を専用回路ではなくマイクロプログラムルーチンで定義できるようにすることで、設計作業を簡素化しました。設計プロセスの後半段階であっても、マイクロコードは容易に変更できるのに対し、ハードワイヤードのCPU設計は変更が非常に困難でした。このように、マイクロコードはCPU設計を大幅に容易にしました。
1940年代から1970年代後半にかけて、プログラミングの大部分はアセンブリ言語で行われていました。高水準命令はプログラマの生産性向上につながるため、マイクロコードの重要な利点は、強力な機械語命令を比較的容易に定義できることでした。この究極の形が「直接実行可能な高水準言語」設計であり、PL/Iなどの高水準言語の各ステートメントは、コンパイルなしでマイクロコードによって完全に直接実行されます。IBM Future SystemsプロジェクトやData General Fountainhead Processorは、その例です。1970年代には、CPU速度がメモリ速度よりも速く成長したため、メモリブロック転送、メモリプリフェッチ、マルチレベルキャッシュなどの多くの技術がこれを緩和するために使用されました。マイクロコードによって可能になった高水準機械語命令は、より複雑な機械語命令の数が少なく、必要なメモリ帯域幅が少なくなるため、さらに役立ちました。たとえば、文字列に対する操作は単一の機械語命令として実行できるため、複数の命令フェッチを回避できます。
複雑なマイクロプログラムによって実装された命令セットを持つアーキテクチャには、IBM System/360やDigital Equipment Corporation VAXなどがありました。ますます複雑化するマイクロコード実装命令セットのアプローチは、後に複雑命令セットコンピュータ(CISC) と呼ばれるようになりました。多くのマイクロプロセッサで使用されている別のアプローチは、主に命令デコードに 1 つ以上のプログラマブルロジックアレイ(PLA) または読み出し専用メモリ(ROM) (組み合わせ論理の代わりに) を使用し、シーケンスの大部分を (マイクロコードがほとんど、またはまったくない) 単純なステートマシンに行わせることです。MOS Technology 6502は、命令デコードとシーケンスに PLA を使用するマイクロプロセッサの例です。PLA はチップの顕微鏡写真で見ることができ、[ 11 ]その動作はトランジスタレベルのシミュレーションで見ることができます。
マイクロプログラミングは、現代のCPU設計においても依然として用いられています。場合によっては、シミュレーションでマイクロコードのデバッグを行った後、制御メモリの代わりに論理関数が使用されることがあります。論理関数は、同等のマイクロプログラムメモリよりも高速かつ低コストであることが多いのです。
プロセッサのマイクロプログラムは、通常のプログラマーが見るアセンブリ命令よりも、より原始的で、全く異なる、ハードウェア指向のアーキテクチャ上で動作します。マイクロコードはハードウェアと連携して、プログラマーが見るアーキテクチャを実装します。基盤となるハードウェアは、見えるアーキテクチャと固定的な関係を持つ必要はありません。これにより、特定の命令セットアーキテクチャを、多様な基盤となるハードウェアマイクロアーキテクチャ上で容易に実装できます。
IBM System/360 は 16 個の汎用レジスタを備えた 32 ビット アーキテクチャを採用していますが、System/360 の実装のほとんどは、より単純な基盤となるマイクロ アーキテクチャを実装するハードウェアを使用しています。たとえば、System/360 モデル 30 は、算術論理演算ユニット (ALU) とメイン メモリへの 8 ビット データ パスを持ち、汎用レジスタは高速コア メモリの専用ユニットに実装されています。System /360 モデル 40 は、ALU への 8 ビット データ パスとメイン メモリへの 16 ビット データ パスを持ち、汎用レジスタは高速コア メモリの専用ユニットに実装されています。モデル50 は完全な 32 ビット データ パスを持ち、汎用レジスタは高速コア メモリの専用ユニットに実装されています。[ 12 ]モデル 65 からモデル 195 までは、より大きなデータ パスを持ち、汎用レジスタはより高速なトランジスタ回路に実装されています。このように、マイクロプログラミングによってIBMは、ハードウェア構成が大きく異なり、コストと性能の幅も広いSystem/360モデルを多数設計することが可能になり、しかもそれらすべてにアーキテクチャ上の互換性を持たせることができました。これにより、各モデルごとに作成する必要のある固有のシステムソフトウェアプログラムの数を劇的に削減することができました。
デジタル・イクイップメント・コーポレーションのPDP-11は、8つの汎用レジスタを備えた16ビットアーキテクチャです。1970年に発表され、基本アーキテクチャは1990年代まで変更されませんでした。シリーズの最初のマシンだけがマイクロコード化されていませんでした。1972年から1976年にかけて、PDP-11の基盤となるマイクロプログラムの幅は22ビットから64ビットまで変化しました。マイクロプログラムの長さは256ワードから1,024ワードまで変化し、マイクロプログラムの長さが長いほど、一般的に幅は狭くなりました。[ 13 ]マイクロプログラムの幅が多様であることから、わずか4年間で少なくとも7つの異なるPDP-11の実装があったことがわかります。
デジタル・イクイップメント・コーポレーション(DEC)も、VAXシリーズのコンピュータで同様のアプローチを採用した。その結果、VAXプロセッサはそれぞれ異なるマイクロアーキテクチャを使用しているにもかかわらず、プログラマから見えるアーキテクチャは変わらない。
マイクロプログラミングは、プロセッサの欠陥(バグ)を修正するための現場変更コストも削減します。バグは、ハードウェアのロジックや配線を変更するのではなく、マイクロプログラムの一部を置き換えるだけで修正できる場合が多いからです。
1946年にアラン・チューリングによって設計されたACEコンピュータはマイクロプログラミングを使用していた。[ 14 ]
1947年、 MIT Whirlwindの設計では、コンピュータ設計を簡素化し、アドホックな方法から脱却する方法として、制御ストアの概念が導入されました。制御ストアはダイオードマトリックスです。これは2次元格子で、一方の次元はCPUの内部クロックからの「制御時間パルス」を受け取り、もう一方の次元はゲートやその他の回路の制御信号に接続されます。「パルス分配器」は、CPUクロックによって生成されたパルスを受け取り、それを8つの個別の時間パルスに分割します。それぞれのパルスは格子の異なる行をアクティブにします。行がアクティブになると、それに接続されている制御信号がアクティブになります。[ 15 ]
1951年、モーリス・ウィルクス[ 16 ]は、コンピュータソフトウェアの条件分岐に似た条件付き実行の概念を追加することで、この概念を拡張しました。彼の最初の実装は、一対のマトリックスで構成されていました。最初のマトリックスは、Whirlwind制御ストアの方式で信号を生成し、2番目のマトリックスは、次のサイクルでどの信号行(いわばマイクロプログラムの命令語)を呼び出すかを選択しました。条件分岐は、制御ストアの単一の行が2番目のマトリックスの選択肢から選択できるようにすることで実装されました。これにより、制御信号は検出された内部信号に条件付きになりました。ウィルクスは、この機能を説明し、単純な制御ストアと区別するために、マイクロプログラミングという用語を作り出しました。
マイクロコードは、コードを格納するために必要なROMのコストがカスタム制御ロジックのコストとそれほど変わらなかったため、コンピュータ設計では比較的まれなままでした。これは、1960年代初頭に大量生産されたコアメモリとコアロープの導入によって変化しました。これらは、ダイオードアレイや同様のソリューションに基づく専用ロジックよりもはるかに安価でした。これを実際に活用した最初の企業は、 1964年のSystem/360シリーズでIBMでした。これにより、マシンは非常に複雑な命令セットを持つことができ、バイナリ値を10進数文字列としてフォーマットするなど、高水準言語の構造に一致する操作や、このタスクに必要な複雑な一連の内部ステップを低コストのメモリにエンコードすることが可能になりました。[ 17 ]
しかし、360シリーズの真の価値は、内部構造が全く異なる一連のマシンを構築しながら、同じISAを実行できる点にあった。ローエンドのマシンでは、32ビットの加算を1回完了するのに複数サイクルを要する8ビットALUを使用するかもしれないが、ハイエンドのマシンでは、同じ加算を1サイクルで実行できる完全な32ビットALUを搭載するかもしれない。これらの違いは制御ロジックで実現できるが、マシンごとに全く異なるデコーダを実装するコストは法外なものになるだろう。マイクロコードを使用すれば、変更するのはROM内のコードだけとなる。例えば、あるマシンには浮動小数点演算ユニットが搭載されているため、2つの数値を乗算するマイクロコードはわずか数行で済むかもしれないが、同じマシンでFPUを搭載していない場合は、同じ演算を複数回の加算で行うプログラムとなり、変更するのはROMだけとなる。[ 17 ]
この設計の結果、顧客は低価格モデルを使ってソフトウェア開発を行うことができ、より高いパフォーマンスが必要になった場合は、より高速なバージョンに移行すれば、他の部分は何も変更する必要がないという安心感を得ることができた。これにより参入障壁が低くなり、360は爆発的な成功を収めた。1970年代末までには、マイクロコードの使用はメインフレーム業界全体で必須となった。
初期のミニコンピュータはマイクロコードを必要とするほど単純ではなく、命令セットやデコード方法の点では初期のメインフレームに似ていました。しかし、設計者がより複雑なISAを可能にするより強力な集積回路を使用し始めるまで、そう時間はかかりませんでした。1970年代半ばまでに、ほとんどの新しいミニコンピュータとスーパーミニコンピュータもマイクロコードを使用するようになり、PDP-11のほとんどのモデルや、特にVAXのほとんどのモデルには、360に見られるものとよく似た高レベル命令が含まれていました。[ 18 ]
マイクロプロセッサでも同様の基本的な進化が起こりました。初期の設計は非常にシンプルで、1970年代半ばのZilog Z80のようなより強力な8ビット設計でさえ、専用ロジックで実装できるほど単純な命令セットを持っていました。この頃には、制御ロジックをCPUと同じダイにパターン化できるようになり、ROMとロジックのコストの差はそれほど問題ではなくなりました。しかし、これらの企業は、より高性能な設計を導入しつつ、後方互換性も維持したいという問題にもすぐに直面しました。マイクロプロセッサ内のマイクロコードの初期の例としては、Intel 8086がありました。[ 5 ]
マイクロプロセッサにおけるマイクロコードの究極の実装例の一つが、Motorola 68000です。これは、高度に直交した命令セットと、マイクロコードで実装されたさまざまなアドレッシングモードを提供しました。初期の記事によると、これにはコストがかかり、チップの表面積(つまりコスト)の約 20% がマイクロコード システムでした[ 19 ] 。後の推定では、プロセッサの 68,000 個のトランジスタのうち約 23,000 個がマイクロコード システムの一部だったとされています。
企業が命令セットの複雑さで競争を続け、マイクロコードを使用してそれらを実装することに疑問が呈されなかった一方で、1970年代半ば、IBMの社内プロジェクトで、この概念全体に深刻な疑問が投げかけられました。高性能な全デジタル電話交換機を開発するプロジェクトの一環として、ジョン・コック率いるチームは、顧客の360(およびSystem/370)プログラムから膨大な量のパフォーマンスデータを調べ始めました。その結果、奇妙なパターンに気づきました。ISAが命令の複数のバージョンを提示する場合、コンパイラはコードを最も直接的に表す命令ではなく、ほぼ常に最も単純な命令を使用していたのです。その理由は、これらの命令は常にハードウェアで実装されており、したがって最も高速に実行されるためだと分かりました。他の命令を使用すると、一部のマシンではより高いパフォーマンスが得られる可能性がありますが、どのマシンで実行されているかを知る方法はありませんでした。これは、そもそもマイクロコードを使用する目的、つまりこれらの違いを隠すという目的を損なうものでした。[ 20 ]
チームは「コンピュータとユーザーの間にマイクロコードを押し付けると、最も頻繁に実行される命令を実行する際にコストのかかるオーバーヘッドが発生する」という根本的な結論に達した。[ 20 ]
この発見の結果生まれたのが、今日RISCコンセプトとして知られるものです。複雑なマイクロコードエンジンとその関連ROMは縮小または完全に排除され、それらの回路は代わりに、追加レジスタやより広いALUといった機能に割り当てられ、あらゆるプログラムのパフォーマンスが向上します。複雑な命令シーケンスが必要な場合は、コンパイラに任せることになり、それがそもそもコンパイラを使用する目的です。この基本コンセプトはすぐにカリフォルニアの大学研究者に採用され、シミュレーションによって、このような設計は従来の最速の設計でさえも容易に凌駕することが示唆されました。RISCという用語は、カリフォルニア大学バークレー校で行われたそのようなプロジェクトの一つから生まれたものです。
RISC の概念に対して業界は混乱と敵意の両方で反応し、Digital の VAX チームによる有名な否定的な記事もその一つだった。[ 21 ]主な論点は、命令をプロセッサの外部で実装すると、メモリからそれらの命令を読み込むのに多くの時間を費やすことになり、CPU 自体がどれだけ速く動作しても全体的なパフォーマンスが低下するということだった。[ 21 ]支持者は、特にコンパイルされたコードを考慮すると、シミュレーションによって命令の数がそれほど増えないことが明確に示されていると指摘した。[ 20 ]
議論は、1980年代後半に最初の商用RISC設計が登場するまで続き、その設計は他社の最も複雑な設計をはるかに凌駕した。1980年代後半には議論は終結し、DECでさえDEC Alpha設計でマイクロコードを放棄し、CISCプロセッサは多くの機能を実行するためにマイクロコードではなくハードワイヤード回路を使用するようになった。たとえば、Intel 80486は命令のフェッチとデコードにハードワイヤード回路を使用し、命令の実行にのみマイクロコードを使用する。レジスタ間移動命令と算術命令は1つのマイクロ命令しか必要としないため、1クロックサイクルで完了できる。[ 22 ] Pentium Proのフェッチおよびデコードハードウェアは命令をフェッチし、実行ユニットに渡される一連のマイクロ操作にデコードし、実行ユニットはマイクロ操作をスケジューリングして実行するが、場合によっては順不同で実行する。複雑な命令は、定義済みのマイクロ操作のシーケンスで構成されるマイクロコードによって実装される。[ 23 ]
一部のプロセッサ設計では、特別なモードで実行されるマシン コードを使用し、そのモードでのみ使用可能な、プロセッサ依存のハードウェアにアクセスできる特別な命令を使用して、命令セットのいくつかの低レベル機能を実装しています。純粋な RISC 設計である DEC Alpha は、PAL コードを使用して、変換ルックアサイド バッファ(TLB) ミス処理や割り込み処理などの機能を実装し、 [ 24 ]また、OpenVMSを実行する Alpha ベースのシステム向けに、 VAXアーキテクチャが提供する命令に似た、インターロック メモリ アクセスを必要とする命令を提供しました。[ 24 ] CMOS IBM System/390 CPU (G4 プロセッサ以降) およびz/Architecture CPU は、ミリ コードを使用して一部の命令を実装しています。[ 25 ]
マイクロプログラム内の各マイクロ命令は、CPUを内部的に構成する機能要素を制御するビットを提供します。ハードワイヤードCPUと比較した場合の利点は、CPU内部の制御がコンピュータプログラムの特殊な形式になることです。このように、マイクロコードは複雑な電子設計上の課題(CPUの制御)を、より単純なプログラミング上の課題へと変換します。この利点を活用するために、CPUはいくつかの部分に分割されています。
メインコンピュータのストレージにアクセスするために使用されるメモリ アドレス レジスタとメモリ データ レジスタも存在する場合があります。これらの要素が組み合わさって「実行ユニット」を形成します。ほとんどの最新のCPU には複数の実行ユニットがあります。単純なコンピュータでも、通常はメモリの読み書きを行うユニットと、ユーザー コードを実行するユニットが 1 つずつあります。これらの要素は、多くの場合、単一のチップとしてまとめられます。このチップは、実行ユニットを「スライス」する固定幅で提供されます。これらは「ビット スライス」チップとして知られています。AMD Am2900ファミリーは、ビット スライス要素の最もよく知られた例の 1 つです。[ 44 ]実行ユニットの各部分と実行ユニット全体は、バスと呼ばれるワイヤの束によって相互接続されています。
プログラマは、基本的なソフトウェアツールを使用してマイクロプログラムを開発します。マイクロアセンブラを使用すると、プログラマはビットテーブルを記号的に定義できます。マイクロコードは基盤となるアーキテクチャと密接な関係にあるため、「コンパイラを使用して生成するのが難しい特性がいくつかあります」[1]。シミュレータプログラムは、電子回路と同じようにビットを実行することを目的としており、マイクロプログラムのデバッグにより多くの自由度を与えます。マイクロプログラムが完成し、徹底的にテストされた後、同じデータを生成するロジックを構築するコンピュータプログラムへの入力として使用されることがあります。このプログラムは、プログラマブルロジックアレイを最適化するために使用されるプログラムに似ています。完全に最適化されたロジックがなくても、ヒューリスティックに最適化されたロジックは、読み出し専用メモリ(ROM)制御ストアに必要なトランジスタの数を大幅に削減できます。これにより、CPUの製造コストと消費電力が削減されます。
マイクロコードは、水平型または垂直型に分類できます。これは主に、各マイクロ命令がほとんどまたは全くデコードせずにCPU要素を制御するか(水平型マイクロコード)[ a ] 、あるいは制御する前に組み合わせ論理による広範なデコードを必要とするか(垂直型マイクロコード)によって決まります。したがって、水平型マイクロ命令は垂直型マイクロ命令よりも幅が広く(より多くのビットを含み)、より多くの記憶領域を占有します。
「水平マイクロコードには、複数の個別のマイクロ操作が1つのマイクロ命令にまとめられ、同時に実行されます。」[ 1 ]水平マイクロコードは通常、かなり広い制御ストアに格納されます。各ワードが108ビット以上であることも珍しくありません。シーケンサクロックの各ティックで、マイクロコードワードが読み取られ、デコードされ、CPUを構成する機能要素を制御するために使用されます。
一般的な実装では、水平方向のマイクロプログラムワードは、かなり厳密に定義されたビットのグループで構成されます。例えば、単純な構成としては次のようなものがあります。
このタイプのマイクロマシンがオペコードの次のアドレスを持つJUMP命令を実行するには、マイクロコードに2クロックティックが必要になる場合があります。設計者は、次のようなマイクロアセンブラのソースコードを作成します。
# 番号記号で始まる行はすべてコメントです。# これは単なるラベルで、アセンブラがメモリ アドレスをシンボルで表現する通常の方法です。 InstructionJUMP : # 次の命令に備えるため、命令デコード マイクロ コードはすでにプログラム カウンタをメモリ アドレス レジスタに移動しています。 この命令は、# ジャンプ オペ コードの後のメモリ ワードから、メモリ データ レジスタからメモリ アドレス レジスタにコピーすることで、ジャンプ命令のターゲット アドレスをフェッチします。 #これにより、メモリ システムは、次の命令をメモリ データ レジスタにフェッチして、命令デコードで使用できるようになります。# シーケンサ命令「next」は、制御ワード アドレスに 1 を加えることを意味します。 MDR 、 NONE 、 MAR 、 COPY 、 NEXT 、 NONE # これにより、次の命令のアドレスが PC に配置されます。# これにより、メモリ システムは、前のマイクロ命令で開始されたフェッチを完了するためにクロック ティックを受け取ります。# シーケンサ命令は、命令デコードの開始位置にジャンプします。 MAR 、1 、 PC 、 ADD 、 JMP 、 InstructionDecode # 命令デコードは通常、非常に複雑で、エミュレートされている特定のプロセッサに固有のものであるため、表示されません。この例でさえ簡略化されています。 # 多くのCPUは、オペコードの後のワードからアドレスをフェッチするだけでなく、アドレスを計算する複数の方法を持っています。 # そのため、これらのCPUは、1つのジャンプ命令ではなく、関連するジャンプ命令のファミリーを持っています。各ティックにおいて、CPUの一部のみが使用され、マイクロ命令内の残りのビット群は何もしない(no-op)状態となるのが一般的です。ハードウェアとマイクロコードを慎重に設計することで、この特性を利用して、CPUの異なる領域を使用する演算を並列化できます。例えば、上記の例では、最初のティックではALUは必要ないため、それ以前の算術演算命令を完了するために使用できる可能性があります。
垂直マイクロコードでは、各マイクロ命令は大幅にエンコードされます。つまり、ビットフィールドは一般的に中間組み合わせ論理回路を通過し、それがCPU内部要素(ALU、レジスタなど)の制御信号とシーケンス信号を生成します。これは、ビットフィールドが制御信号とシーケンス信号を直接生成するか、最小限にエンコードされる水平マイクロコードとは対照的です。したがって、垂直マイクロコードは命令長が短く、記憶容量も少なくて済みますが、デコードに時間がかかるため、CPUクロックが遅くなります。[ 45 ]
一部の垂直マイクロコードは、より複雑なコンピュータをエミュレートする単純な従来型コンピュータのアセンブリ言語にすぎません。DEC Alphaプロセッサや、後の IBM メインフレームSystem/390およびz/Architectureの CMOS マイクロプロセッサなどの一部のプロセッサは、通常のマシン コードでは利用できない特別な命令、特別なレジスタ、およびその他のハードウェア リソースにアクセスできる特別なモードで実行されるマシン コードを使用して、一部の命令やその他の機能を実装します[ 46 ] [ 47 ]、Alpha プロセッサではページ テーブル ウォークなどです[ 48 ] 。これは、Alpha プロセッサではPAL コード、IBM メインフレーム プロセッサではミリコードと 呼ばれます。
垂直マイクロコードの別の形式には、2つのフィールドがあります。
フィールド選択は、制御ストアのこのワードによってCPUのどの部分が制御されるかを選択します。フィールド値は、そのCPU部分を制御します。このタイプのマイクロコードでは、設計者は制御ストア内の未使用ビットを削減することでコストを削減するために、意図的にCPUの速度を遅くすることを選択します。ただし、複雑さが軽減されることでCPUのクロック周波数が上昇し、命令あたりのサイクル数の増加による影響が軽減される可能性があります。
トランジスタの価格が下がるにつれて、マイクロコードを用いたCPUの設計においては水平マイクロコードが主流となり、垂直マイクロコードの使用頻度は減少していった。
垂直マイクロコードと水平マイクロコードの両方が使用される場合、水平マイクロコードはナノコードまたはピココードと呼ばれることがある。[ 49 ]
書き込み可能なマイクロコードを使用して構築されたコンピュータがいくつかあります。この設計では、マイクロコードをROMやハードワイヤードロジックに格納するのではなく、書き込み可能な制御ストアまたはWCSと呼ばれるRAMにマイクロコードが格納されます。このようなコンピュータは、書き込み可能な命令セットコンピュータ(WISC)と呼ばれることもあります。[ 50 ]
多くの実験的なプロトタイプコンピュータは書き込み可能な制御ストアを使用しています。書き込み可能なマイクロコードを使用する商用マシンもあり、例えば、Burroughs Small Systems、初期のXeroxワークステーション、DEC VAX 8800 ( Nautilus ) ファミリー、Symbolics L および G マシン、多数の IBM System/360 およびSystem/370実装、一部の DEC PDP-10マシン[ 51 ] 、およびData General Eclipse MV/8000 [ 52 ]などがあります。
IBM System/370には、コンソールから、電源投入リセット(POR )の一部として、または密結合マルチプロセッサ複合体内の別のプロセッサから呼び出すことができる、初期マイクロプログラムロード(IMLまたはIMPL)[ 53 ]と呼ばれる機能が含まれています。
IBM 360/85などの一部の商用マシン[ 54 ] [ 55 ]は、マイクロコード用の読み取り専用ストレージと書き込み可能な制御ストアの両方を備えています。
WCSには、マイクロプログラムのパッチ適用が容易であることや、特定のハードウェア世代においてはROMよりも高速なアクセスが可能であることなど、いくつかの利点があります。ユーザーがプログラム可能なWCSを使用することで、ユーザーは特定の目的に合わせてマシンを最適化できます。
1995年のPentium Pro以降、いくつかのx86 CPUは書き込み可能なIntelマイクロコードを備えています。[ 56 ] [ 57 ]これにより、たとえば、Intel Core 2およびIntel Xeonマイクロコードのバグは、チップ全体を交換する必要なく、マイクロプログラムにパッチを適用することで修正できるようになりました。2番目の顕著な例は、2018年初頭に公表された設計上のセキュリティ脆弱性( SpectreとMeltdown )に対抗するために、Intelが最大10年前のプロセッサアーキテクチャの一部に提供した一連のマイクロコードパッチです。 [ 58 ] [ 59 ]マイクロコードのアップデートは、Linux [ 60 ] 、FreeBSD [ 61 ]、Microsoft Windows [ 62 ] 、またはマザーボードのBIOS [ 63 ]によってインストールできます。
HP 2100、DEC PDP-11/60、TI-990 /12 [ 64 ] [ 65 ] 、 Varian Data Machines V-70 シリーズのミニコンピュータなど、一部のマシンでは、オプションとしてユーザーがプログラム可能な書き込み可能な制御ストアが提供されています。WCS オプションはマイクロプロセッサにも拡張されています。DEC LSI-11には、内部の 8 ビット マイクロマシンをプログラムして、命令セットにアプリケーション固有の拡張機能を作成できるオプションがあります。[ 66 ]
マイクロコード周辺機器やアダプタの中には、書き込み可能なマイクロコードを備えているものがあり、通常はオペレーティングシステムのデバイスドライバによってロードされます。このようなマイクロコードは、デバイスのSRAMまたはDRAM(例えば、ビデオカードのGDDR SDRAM)にロードされます。
複雑な命令セットを持つマイクロコード化されたプロセッサへの設計傾向は、1960年代初頭に始まり、1980年代半ば頃まで続いた。その頃から、RISC設計思想がより顕著になってきた。
マイクロコードを使用するCPUは、一般的に1つの命令を実行するのに複数のクロックサイクルを要します。これは、その命令に対応するマイクロプログラムの各ステップに1クロックサイクルずつかかるためです。CISCプロセッサの中には、実行に非常に長い時間を要する命令が含まれているものもあります。このようなばらつきは、割り込みレイテンシだけでなく、現代のシステムにおいてより重要なパイプライン処理にも影響を与えます。
新しいプロセッサを設計する際、ハードワイヤード制御RISCは、マイクロコード制御CISCに比べて以下の利点があります。
反論もある。
多くのRISCプロセッサとVLIWプロセッサは、キャッシュにある命令はすべて1サイクルで実行するように設計されています。これは、マイクロコードを持つCPUが1サイクルあたり1つのマイクロ命令を実行するのと非常によく似ています。VLIWプロセッサの命令は、非常に広い水平マイクロコードと同様の動作をしますが、通常はマイクロコードが提供するようなハードウェアに対するきめ細かな制御はできません。RISC命令は、狭い垂直マイクロコードに似ている場合もあります。
NexGen Nx586、Intel Pentium Pro、AMD K5などのx86ファミリーといった最新のCISC実装では、 RISCや従来のマイクロコードに似た命令エンコーディングで、命令を動的にバッファリングされたマイクロオペレーションにデコードします。ハードワイヤードの命令デコードユニットは、一般的なx86命令のマイクロオペレーションを直接出力しますが、より複雑な命令や使用頻度の低い命令のマイクロオペレーションを含む、より従来型のマイクロコードROMにフォールバックします。[ 2 ]
例えば、x86 はマイクロコードからマイクロオペレーションを検索して、ループや文字列命令などの複雑な多段階操作、浮動小数点ユニットの超越関数、非正規化数などの特殊な値、 CPUIDなどの特殊目的命令を処理する場合があります。
PDP -8は、 1965年にデジタル・イクイップメント・コーポレーション(DEC)が発売した12ビットミニコンピュータのファミリーです。OPR (OPeRate)命令は「マイクロコード化」されていると言われていました。これは今日でいう「マイクロコード化」とは異なり、命令語の各ビットが特定のアクションを指定し、プログラマは複数のビットを設定することで1回の命令サイクルで複数のアクションを実行できるという意味でした。これらのアクションの例としては、アキュムレータのクリア、アキュムレータの補数化、右回転、2回右回転、バイトスワップなどがあります。
IBMやLenovoなどの一部のハードウェアベンダーは、マイクロコードという用語を組み込みファームウェアと互換的に使用しています。この文脈では、デバイス内のすべてのコードがマイクロコードかマシンコードかを問わず、マイクロコードと呼ばれます。たとえば、ハードディスクドライブのマイクロコードの更新には、マイクロコードとファームウェアの両方の更新が含まれる場合があります。[ 67 ]組み込みファームウェアは、ネットワークプロセッサ、デジタル信号プロセッサ、チャネルコントローラ、ディスクコントローラ、ネットワークインターフェイスコントローラ、フラッシュメモリコントローラ、グラフィックス処理ユニットなどのアプリケーション固有のプロセッサやその他のハードウェアで普及しています。
x 75ビットSRAM書き込み可能制御ストア:1パリティビット付き74ビットマイクロ命令(18フィールド)
{{cite book}}: CS1メンテナンス: 場所 (リンク)