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