Chapter 5コンピュータアーキテクチャ-[最下位から作成されたコンピューティングシステム]

8936 ワード



5.1背景


5.1.1組み込みプログラムの概念


コンピュータは、一定のハードウェアプラットフォームに基づいて、所与の命令セットを実行する.また,コンピュータが実行する命令は基本ブロックとなり,無限に複雑なプログラムに組み合わされる.これらのプログラムはハードウェアに埋め込まれるのではなく、プログラムのコードをデータのようにコンピュータのメモリに直接格納して演算し、「ソフトウェア」と呼ばれます.

5.1.2フォンノイマン構造



フォンノイマン構造は、メモリ通信、入力装置からのデータ受信、出力装置へのデータ送信を担当する中央プロセッサ(CPU)に基づいている.

5.1.3メモリ


ポンノ万マシンのメモリには、データ、命令、および2つの情報が格納されます.この2つの情報は通常異なるものと見なされ、メモリデバイスを別々に格納するコンピュータもあります.
2つの情報の機能は異なるが、同じランダムアクセス構造にバイナリ形式で格納される点は同じである.
  • データメモリ
    高標準プログラムは、変数、配列、オブジェクトなどの抽象概念を処理します.これらの抽象データをマシン言語に翻訳すると、バイナリ数値列に変換され、データメモリに格納されます.
  • 命令メモリ
    ハイレベル命令を機械語に翻訳すると,バイナリ機械語命令を表す単語になる.これらの命令は命令メモリに格納される.
  • 5.1.4中央プロセッサー


    中央プロセッサは、プログラムをロードする命令を実行します.CPUは、これらの命令により各種計算(ALU)、メモリにおける値の読み書き(レジスタ)、条件に応じたジャンプ(コントローラ)を実行する.

  • 算術論理演算ユニット(ALU)
    これはコンピュータがサポートするすべての低レベル算術、論理演算を実行する装置である.通常、ALUは2つの値を追加し、どの数字が正数であるか、データ語を操作するビットなどを決定することができる.

  • n.レジスタ
    CPUは簡単な計算を迅速に実行するように設計されている.そのため、毎回メモリからデータをロードして格納するよりも、CPU付近に高速レジスタを配置します.

  • せいぎょそうち
    通常、16、32、64ビットのバイナリコードで表されるコンピュータ命令は、ALU、レジスタ、メモリが何をすべきかを説明する.また、どのコマンドを抽出し、次の実行を決定する役割も果たします.
  • これにより、CPU演算は、メモリから次の命令を抽出、解釈、実行、抽出するサイクルを繰り返しとして記述することができる.

    5.1.5レジスタ


    メモリアクセスは遅い作業です.CPUは、メモリアドレスjの取得を要求されると、以下の処理を行う.
  • jは、CPUからRAMに送信される.
  • RAMの直接アクセスロジックに従って、アドレスjのメモリレジスタを選択する.
  • RAM[j]の内容はCPUに再送される.

  • しかし、レジスタはCPUチップ内部で物理的な位置であり、メモリユニットはほぼ数百万個あるが、通常は少数のレジスタしかないため、データの転送やメモリの探索は必要ない.
    CPUには様々な用途があり、異なる数のレジスタを使用します.

  • データレジスタ
    CPUの短期記憶機能を備えています.例えば、(a-b)*c値を算出する場合、(a-b)の値をメモリに一時的に記憶することができるが、CPU内部に記憶する方が効率的であるため、「データレジスタ」をこの目的に用いる.

  • アドレッシングレジスタ
    CPUは、メモリにアクセスしてデータを読み書きする必要があります.次に、メモリにアクセスするメモリ単語(アドレス)を指定する必要があります.アドレスが現在のコマンドに含まれていない場合は、「アドレスレジスタ」に格納されている以前のコマンドの実行結果(アドレス)も使用できます.

  • プログラムカウンタレジスタ
    CPUは、次の命令メモリから抽出すべき命令のアドレスを記憶する.
    実行中のコマンドにgoto文がない場合は、PCがプログラム内の次のコマンドを指すように値を増やし、goto n文がある場合はPCにn値をロードします.
  • 5.1.6入力と出力


    私たちがよく使うディスプレイやキーボードのほか、I/Oデバイスもたくさんあります.各設定の作成にコストがかかりすぎるため、すべてのI/Oデバイスを同時に処理できる「メモリマッピングI/O」テクノロジーを作成しました.

  • メモリマッピングI/O
    I/Oデバイスがコンピュータに接続されている場合、そのデバイスのスペースは空きメモリに割り当てられます.I/Oデバイスをシミュレートすることで、CPUは通常のメモリセグメントのように見えます.

  • インプットデバイス
    入力デバイスのメモリマッピングは、デバイスの物理状態を反映し続けます.キーボードでキーを押すと、デバイスのメモリマッピングに特定の値が記録されます.

  • しゅつりょくそうち
    出力デバイスのメモリマッピングは、持続駆動デバイスの物理状態として作成されます.出力デバイス(画面表示、スピーカ再生)を操作する場合は、そのデバイスのメモリマッピングに特定の値を記録します.
  • ハードウェアの面では、I/Oデバイスはメモリデバイスと同様のインタフェースを有しなければならない.
    ソフトウェアの観点から,プログラムが正しくアクセスできるようにI/O機器ごとに通信規約を定義すべきである.

    5.2コアハードウェアプラットフォームの説明


    5.2.1概要


    5.2.2中央プロセッサー


    コアマシン言語で記述された16ビット命令を実行できるように設計されている.CPUは、命令メモリ、データ記憶モジュールに接続されている.

    5.2.3命令メモリ


    コア命令メモリは、読み取り専用メモリと呼ばれるチップ上で実現される.コアROMは32 K個のアドレス可能な16ビットレジスタからなる.

    5.2.4データメモリ


    コアのデータ記憶インタフェースは,第3章で実現したRAM装置と同様である.したがって、レジスタnの内容を読み取るには、メモリのアドレス入力にnを入れて出力をチェックするだけでよい.この演算は時計とは関係ない.
    レジスタnに値vを書き込むには、in入力にvを入れ、address入力にnを入れ、メモリのloadビットをアクティブにすればよい.これは、次のクロックサイクルでデータが変更される順序演算です.

  • メモリマッピング
    コアプラットフォームのI/Oデバイス、画面とキーボードはメモリマッピングバッファを通じてコンピュータプラットフォームと通信します.
    スクリーンイメージを表示または描画するには、スクリーンメモリマッピングと呼ばれる特定のメモリセグメントで単語を読み書きします.
    「キーボードメモリマッピング」と呼ばれる特定のメモリ単語を調べると、現在どのキーが押されているかがわかります.

  • すべてのメモリ
    RAM(標準データストレージ)、スクリーンマップ、キーボードマップが含まれます.

  • 5.2.5コンピュータ


    コンピュータチップは、CPU、データメモリ、命令メモリ、スクリーン、キーボード、および他のすべてのコンピュータを実行するために必要なハードウェアデバイスから構成される.このコンピュータ上でプログラムを実行するためには、プログラムコードをROMに予めロードしておく必要があります.

    5.3実施


    5.3.1中央プロセッサー


  • せいぎょそうちせっけい


  • HDL実装
  • CHIP CPU {
    
        IN  inM[16],         // M value input  (M = contents of RAM[A])
            instruction[16], // Instruction for execution
            reset;           // Signals whether to re-start the current
                             // program (reset==1) or continue executing
                             // the current program (reset==0).
    
        OUT outM[16],        // M value output
            writeM,          // Write to M? 
            addressM[15],    // Address in data memory (of M)
            pc[15];          // address of next instruction
    
        PARTS:
        // Put your code here:
        Mux16(a=instruction, b=ALUout, sel=instruction[15], out=AorC);      // 명령어의 종류(A or C)를 적용시킨다. 
        Not(in=instruction[15], out=A);
        Or(a=A, b=instruction[5], out=loadA);                               // i'+ d1
        ARegister(in=AorC, load=loadA, out=address, out[0..14]=addressM);   // A 명령어이거나 d1이 1인 경우에 A 레지스터에 새로운 값을 저장한다. 15비트 주소 값을 출력한다. 
    
        And(a=instruction[15], b=instruction[3], out=writeM);               // i * d3 -> C 명령어이고 d3가 1인 경우에 결과값을 확인하고 메모리에 저장한다. 
    
        Mux16(a=address, b=inM, sel=instruction[12], out=y);                // A 레지스터에 저장된 주소값을 사용할지, CPU의 입력값을 사용할지 a비트가 결정한다. 
    
        And(a=instruction[15], b=instruction[4], out=loadD);                // i * d2 -> C 명령어이고 d2가 1인 경우에 D 레지스터에 이전 결과값을 저장한다. 
        DRegister(in=ALUout, load=loadD, out=x);
    
        ALU(x=x, y=y, zx=instruction[11], nx=instruction[10],
            zy=instruction[9], ny=instruction[8], f=instruction[7], 
            no=instruction[6], out=outM, out=ALUout, zr=ALUzr, ng=ALUng);   // c1 ~ c6로 연산 종류를 결정한다. out=0 -> zr=1, out<0 -> ng=1
                                                                            
        Or(a=ALUzr, b=ALUng, out=outUpto0);                                 // out<=0   
        Not(in=outUpto0, out=outGThan0);                                    // out>0
        Not(in=ALUng, out=outDownto0);                                      // out>=0
        Not(in=ALUzr, out=outNot0);                                         // out!=0
    
        Mux(a=false, b=outGThan0, sel=instruction[0], out=muxAB);           
        Mux(a=ALUzr, b=outDownto0, sel=instruction[0], out=muxCD);
        Mux(a=muxAB, b=muxCD, sel=instruction[1], out=muxABCD);
    
        Mux(a=ALUng, b=outNot0, sel=instruction[0], out=muxEF);
        Mux(a=outUpto0, b=true, sel=instruction[0], out=muxGH);
        Mux(a=muxEF, b=muxGH, sel=instruction[1], out=muxEFGH);
    
        Mux(a=muxABCD, b=muxEFGH, sel=instruction[2], out=jmp);             // j1, j2, j3으로 가능한 점프 조건 결정
        
        And(a=instruction[15], b=jmp, out=PCload);                          // i * (해당하는 점프 조건) -> PC의 load비트
        Not(in=PCload, out=PCinc);                                          // PC의 load비트가 와 inc비트는 서로 반대다. 
        
        PC(in=address, load=PCload, inc=PCinc, reset=reset, out[0..14]=pc);     // A 레지스터에 저장된 주소값을 로드할지, 기존 명령어 주소를 increase할지 결정
    }

    5.3.2メモリチップ


  • デザイン


  • HDL実装
  • CHIP Memory {
        IN in[16], load, address[15];
        OUT out[16];
    
        PARTS:
        DMux4Way(in=load, sel=address[13..14], a=ramA, b=ramB, c=screen, d=keyboard);           // 최상위, 차상위 비트로 어떤 메모리에 접근할지 결정된다. 
        Or(a=ramA, b=ramB, out=ram);                                                            // ramA와 ramB는 같은 16K 메모리이므로 합연산으로 load를 통일한다. 
    
        RAM16K(in=in, load=ram, address=address[0..13], out=ramOut);                            // ram의 선택비트는 1bit로 통일했기 때문에 주소값으로 14bit를 넘긴다. 
        Screen(in=in, load=screen, address=address[0..12], out=screenOut);                      // screen의 용량은 8K이므로 주소값으로 13bit를 넘긴다. 
        Keyboard(out=keyOut);
        Mux4Way16(a=ramOut, b=ramOut, c=screenOut, d=keyOut, sel=address[13..14], out=out);     // 최초 선택 비트로 접근한 메모리의 출력값을 out으로 넘긴다. 
    }

    5.3.3コンピュータチップ

  • 設計
  • HDL実施
  • CHIP Computer {
    
        IN reset;
    
        PARTS:
        ROM32K(address=pc, out=instruction);      
        Memory(in=outM, load=writeM, address=addressM, out=inM);
        CPU(inM=inM, instruction=instruction, reset=reset, outM=outM, writeM=writeM, addressM=addressM, pc=pc);
    }