トップ:http://galaxy.u-aizu.ac.jp/note/wiki/CAEX2015 = マルチサイクルプロセッサの設計 = これまでの演習で設計してきたモジュールを組み合わせて、MIPS ISA互換のマルチサイクルプロセッサを設計します。 設計するプロセッサのブロック図全体図は以下のようになります。 = ブロック図 = [[Image(http://galaxy.u-aizu.ac.jp/note/raw-attachment/wiki/Ex07%E8%AA%B2%E9%A1%8C2015/datapath.png, 500)]] 詳細を見るためのPDF version -> http://galaxy.u-aizu.ac.jp/note/raw-attachment/wiki/Ex07%E8%AA%B2%E9%A1%8C2015/dp_ctl.pdf = 設計の指針 = * ブロック図を参照して、どのようなモジュールが必要かをリストアップする。 * それぞれのモジュールを設計する。 * モジュール間接続について考える。この時にモジュールごとに入力と出力の種類やbit幅を考慮する。 * "Datapath.v"を作成し、そこからモジュールのインスタンス化および接続をおこなう。 == モジュールのリストアップ == プロセッサを完成させるには、ブロック図を参照して、必要なモジュールをリストアップします。 これまでの演習で利用してきた、あるいは設計してきたモジュールは: * ALU (演習第4週) * ALU control (演習第5週) * Memory(メモリ)/Registers(レジスタファイル) (演習第6週) です。その他に必要なモジュールを列挙すると以下になります。 1. PCレジスタ 1. Aレジスタ 1. Bレジスタ 1. ALUOutレジスタ 1. Instruction register 1. Memory data register 1. 2 to 1 マルチプレクサ x 4 1. 3 to 1 マルチプレクサ x 1 1. 5 to 1 マルチプレクサ x 1 1. Sign extendモジュール 1. Zero extendモジュール 1. "Shift left 2"モジュール x 2 1. 制御部 == 各モジュールの設計 == === レジスタ === レジスタは全て32bitです。例えばAレジスタのHDL記述は以下のようになります。 {{{ module RegA(i, CK, CLR, o); input CK, CLR; input [31:0] i; output [31:0] o; reg [31:0] o; always @(posedge CK) begin if (CLR == 1'b1) o <= 32'h00000000; else o <= i; end endmodule }}} CLRが真の時にレジスタは0x0にクリアされます。 レジスタのうちPCレジスタ、Instruction registerは、制御信号で書き込みが制御されます。 例えば、PCレジスタはPCloadが真の時のみにレジスタの内容をアップデートします。記述例は以下のようになります。 {{{ module RegPC(i, PCload, CK, CLR, o); input CK, CLR, PCload; input [31:0] i; output [31:0] o; reg [31:0] o; always @(posedge CK) begin if (CLR == 1'b1) o <= 32'h00000000; else if (PCload == 1'b1) o <= i; end endmodule }}} === Instruction register === ブロック図を見るとわかるように、このレジスタはメモリモジュールから出力を保持する32bitレジスタですが、 出力は4種の信号線に分かれます。このレジスタが命令を保持するレジスタであるからです。 例えば今実行中の命令がR形式命令の場合、21-25ビットの部分はレジスタのアドレスを表すので、 その信号はレジスタファイルの読み出しアドレス(Read register 1)に接続されています。 同様に、26-31ビットの部分は制御部のOpに接続されます。 よって、この命令レジスタは以下の入出力となるように設計してください。 {{{ module RegInst(i, IRWrite, CK, CLR, o0_15, o16_20, o21_25, o26_31); input CK, CLR, IRWrite; input [31:0] i; output [15:0] o0_15; output [4:0] o16_20, o21_25; output [5:0] o26_31; endmodule }}} === マルチプレクサ === マルチプレクサは、制御信号に応じて、複数の入力から出力を選択します。 例えば、2入力から信号sに応じて、片方を選択する2 to 1マルチプレクサの記述は以下になります。 {{{ // 32bit : 2 to 1 multiplexer module mux2(i0, i1, s, o); input [31:0] i0, i1; input s; output [31:0] o; reg [31:0] o; // always分で代入する場合にはreg宣言も必要 always @(i0 or i1 or s) begin if (s == 1'b1) o <= i1; else o <= i0; end endmodule }}} 3入力以上のマルチプレクサはcase文で記述します。参考書の67ページを参照すること。 センシティビティリスト(「@()」の部分)に全ての入力信号を列挙する必要があることに注意すること。 === Sign extendモジュール === このモジュールは入力が16bitで出力が32bitになります。 === Zero extendモジュール === このモジュールも、入力が16bitで出力が32bitになります。 === "Shift left 2"モジュール === このモジュールは2回利用されていて、どちらも入力を左に2 bitシフトしたものが出力です。 ただし、Sign extendモジュールに接続されているものは入出力とも32bitですが、 命令の0-25ビットが入力されているものは、入力が26bitで出力が28bitです。 この28bitの出力信号は、PCレジスタの28-31ビットと合わせて32bit信号になり、 一番右にあるマルチプレクサの入力になります。 === 制御部 === 制御部は図の上部中心にあるオレンジ色の部分で、この部分については別途説明します。 = 課題1 データパスの理解 = 以下のPDFで示された黄色い箱の番号(1 - 8)のデータパスの信号幅を答えなさい。 http://galaxy.u-aizu.ac.jp/note/raw-attachment/wiki/Ex07%E8%AA%B2%E9%A1%8C2015/dp_bit_width.pdf = 課題2 モジュールの設計 = 制御部を除いて、リストアップされた必要なモジュールを設計してください。 そのうち、5 to 1マルチプレクサ、Sign extend、Zero extend、Shift left 2の各モジュールは、 テストベンチを書いて正しい動作をするかを確認してください。 = 状態遷移図の理解 = 制御部を設計するためには、このマルチサイクルプロセッサの状態遷移を理解する必要があります。 状態遷移図は、このファイル dp_ctl.pdf の2ページ目にあります。 講義ノート http://web-int.u-aizu.ac.jp/~miyazaki/comparch-15/lecture/comparch-9-multicycle.pdf も参照してください。 なお、ここで設計する状態遷移図は、講義ノートのものにイミディエイト命令が追加されていて、 全部の状態数は13個(0から12)になります。 アセンブラプログラム演習で用いたJALとJR命令は後の演習で追加するので、今は扱いません。 この状態遷移図は、各状態の○の中に記述された信号が変化することを示します。 例えば状態0の命令フェッチでは、!MemRead信号(1bit)が"1'b1"になり(アサート)、ALUSrcA(1bit)は"1'b0"になります(ネゲート)。 他の信号の意味も同様です。全ての信号の幅と意味については、上記講義ノートの11ページを参考にしてください。 == 命令実行時のデータパスの変化 == [[Image(http://galaxy.u-aizu.ac.jp/comparch2014/ori.png)]] この図で赤いで示された数字は、ORI命令を実行した時に、どのデータパスが利用されるかを示します。 ORI命令では、状態は0→1→12→11→0と遷移します。 例えば、状態1(命令デコード)の時には、ALUSrcAとALUSrcBとALUOpが変化します。 講義ノートの14ページにあるように、この時におこなわれる操作は、 レジスタファイルからレジスタA/Bへのデータ読み出しと、分岐アドレスの計算です。 よって、赤い数字1のついたデータパスが利用されます。 ただし、実行されるが使用されないパス(例えば状態0において、メモリからMemory Data registerへのデータ転送) および制御部からの信号には番号をつけていません。 ALUの入力は多くの状態で使用されるので番号を省略しています。 ただし、状態1においてPCからマルチプレクサ、ALUを経由してALUOutおよび命令レジスタから符号拡張、2bitシフト、 ALUを経由してALUOutまでのパスには1をつけています。 = 制御部の設計(1) = 制御部モジュールのテンプレートは以下のようになります。 {{{ module ControlUnit(PCWriteCond, PCWrite, IorD, MemRead, MemWrite, MemtoReg, IRWrite, PCSource, ALUOp, ALUSrcB, ALUSrcA, RegWrite, RegDST, Op, CK, CLR); // clock input CK; input CLR; // opcode (6 bit) input [5:0] Op; // 1 bit control signal output PCWriteCond; output PCWrite; output IorD; output MemRead; output MemWrite; output MemtoReg; output IRWrite; output RegWrite; output RegDST; output ALUSrcA; // 2 bit control signal output [1:0] PCSource; output [1:0] ALUOp; output [2:0] ALUSrcB; // register declaration reg PCWriteCond; reg PCWrite; reg IorD; reg MemRead; reg MemWrite; reg MemtoReg; reg IRWrite; reg [1:0] PCSource; reg [1:0] ALUOp; reg [2:0] ALUSrcB; reg ALUSrcA; reg RegWrite; reg RegDST; // state register reg [3:0] state; endmodule // ControlUnit }}} 入力信号はOpとCK(クロック信号)とCLR(リセット信号)で、その他は出力になります。 Op信号はMIPS命令コードの25-31ビットの部分です。各命令コードごとのOp信号を以下のテーブルに示します。 == 命令コード == || 命令の種類 || opcode(10進数) || || R形式 || 0 || || Load Word || 35 || || Store Word || 43 || || Branch on EQ|| 4 || || ADD imm || 8 || || SLT imm || 10 || || AND imm || 12 || || ORI imm || 13 || 注意:R形式命令では、命令コードの0-5ビットの部分で演算の種類を指定します。 == 例題 == 状態遷移図から、R形式命令の実行には4サイクル必要になります。 このことを、以下のファイルを使ってシミュレーションを行い確かめなさい。 状態遷移のみの制御回路 http://galaxy.u-aizu.ac.jp/note/raw-attachment/wiki/Ex07%E8%AA%B2%E9%A1%8C2015/ControlUnit_1.v.txt テストベンチファイル http://galaxy.u-aizu.ac.jp/note/raw-attachment/wiki/Ex07%E8%AA%B2%E9%A1%8C2015/CUbench_1.v.txt === 実行例 === それぞれのファイルをダウンロードまたは保存して、以下のコマンドを実行。 {{{ ncverilog CUbench_1.v }}} この状態遷移の回路では、always文の部分はCLKが上向きに変化する時に状態が遷移します。 また、CLR信号が真になったら状態0になります(リセット)。 そのため状態遷移を行う時にはCLR信号を適切に変化させる必要があります。 === 実行波形 === [[Image(http://galaxy.u-aizu.ac.jp/comparch2014/image/CUbench1.png)]] == 課題3 == LW命令とADDI命令の場合に、例題を参考にテストベンチファイルを作成して、 シミュレーションを行い、実行波形を確認してください。 それぞれの場合、実行までに何サイクル必要かを考えること。