オリジナル命令の追加検討


本内容を参考にして、各自オリジナル命令の追加を 検討してください。

オリジナル命令の追加例として、ここではNAND命令の追加を行ってみます。


命令仕様の定義:

NAND命令は2項演算ですから、OR、AND、EOR演算と同様に処理することができま す。
アドレッシングモードとして、即値アドレッシングとインデクス修飾アドレッシ ングを実現することにします。



命令コードの定義:

NAND命令の命令コード(オペレーションコード)を決定する必要があります。
KITE-1の命令セット表を眺めると、命令の上位ビットから、
“101110″
が使用されていないことがわかります。 ここを、命令コードとして使用することにします。
即値アドレッシングは“10111001″(0xB9)
インデクス修飾アドレッシングは“10111010″(0xBA)
になります。

opecode.v に命令を定義します。
  ...
`define IR_ROR    6'b101101
`define IR_NAND   6'b101110 // NAND命令追加
`define IR_SWP    6'b101111
  ...




ALUへの演算追加:

ALUへ新たなNAND演算を追加するわけですが、ALUは既に16演算が定義されており、 制御信号CBも4ビットであるため、新たな命令を追加するためには制御信号CBを5 ビットに拡張する必要があります。
また、演算処理を行う際、ALUの制御コードはそのまま演算命令の第13〜10ビッ トに対応するように命令は定義されていました。追加しようとしているNAND 命 令は命令の第13〜10ビットが“1110″になりますが、ALUの制御信号では既 にパス演算が定義されています。
これでは不都合ですから、NAND演算を“01110″として定義し、パス演算を “10000″として再定義することにします。

alu_op.v は以下のようになります。
//
// ALU operations
//

`define IADD  5'b00000
  ...
`define INAND 5'b01110 // NAND演算追加
  ...
`define IPAS  5'b10000 // PASS演算コードの再定義

alu.v は以下のようになります。
module alu (A, B, CB, S, F);
  ...
  input  [ 4:0] CB;	// 制御コード拡張
  ...

  always @( ...  )
  begin
    case ( ... )
    ...
    `INAND  : tmp <= { 1'b0, ~( A & B ) };  // NAND演算追加
    ...
    default : tmp <= { 1'b0, A };  // IPAS
    endcase
  end

  ...
endmodule




ALU制御信号配線の拡張

ALUの制御信号を4ビットから5ビットに拡張したため、ALUの制御信号に関連する 部分をすべて5ビットに拡張しておく必要があります。

kite.v 階層は、ALUとデコーダ・シーケンサとの間でALU制御信号を連結してい ます。
  ...
  wire   [ 4:0] ALU_C;		// for ALU Control (制御コード拡張)
  ...




デコーダ・シーケンサの拡張

最後にデコーダ・シーケンサ部(dec_seq.v)ですが、まずALUの制御信号を5ビッ トに拡張します。
  ...
	output [4:0] ALU; // 制御コード拡張
  ...
	reg    [4:0] ALU; // 制御コード拡張
  ...

命令のデコードを記述します。OR、AND、EOR命令と同じステートにより処理でき るので、同一の処理ステートへ遷移すればOKです。
  ...
          case ( `OP_6 )
          `IR_NAND : if( `OP_M==`IMM ) STATE<=`BIOP_IMM_1; else
                     if( `OP_M==`IDX ) STATE<=`BIOP_IDX_1; else
                                       STATE<=`F1;
  ...

即値アドレッシングの場合とインデクス修飾アドレッシングでは、命令レジスタ からの値の呼出し方が異なります。

論理演算の即値アドレッシングではアキュムレータの上位8ビットがそのまま残 るように演算していました。NAND命令でも同様にしますが、NANDの場合は結果が 反転しますので、アキュムレータの上位8ビットの反転した値が残るようにしま す。

インデクス修飾アドレッシングでは、命令の下位8ビットはインデクスレジスタ の加算値として使用しますが、その際、符号拡張します。
//------------------------------------------------------------------//
// BRANCH flag & SIGN flag are made from IR and FR
//------------------------------------------------------------------//
  always @( ...  )
    begin
    ...
      default :
        case ( `OP_6 )
        ...
	`IR_NAND : if ( `OP_M==`IMM ) SIGN<=1;    else SIGN<=IR[7];
        ...
        endcase
      endcase
    end

制御信号生成については、そのまま手を加える必要がありません。
理由は、OR、AND、EORの論理演算と共通の処理で実現できるようにALUの制御信 号および命令デコーダを再定義したからです。
以下のソースにおいて、
ALU<=`OP_A;
の記述が、同一のステートで個々の演算を実現できるようにしている部分です。
但し、ALU制御信号は5ビット、`OP_A は opecode.v では IR[13:10] と4ビット で定義されています。
代入の際に第4ビットが1ビット足りませんが、Verilog HDLでは1ビットの0が付加されるのでこのままで大丈夫です。
気になる人は、
ALU<= { 1'b0 , `OP_A };
のように記述するか、`OP_A の定義を、
`define OP_A	IR[14:10]	// ALU制御コードの拡張
にすればOKです。
  ...
    //
    // BIOP Index
    //  ADD, SUB, OR, EOR, AND, NAND
    `BIOP_IDX_1 :
       begin 
         IXR_R<=1; AR_W1<=1;
         IR_R8P2 <= !SIGN;
	 IR_R8M2 <=  SIGN;
         ALU <= `IADD;
      end
    `BIOP_IDX_2 :       MREQ<=1;
    `BIOP_IDX_3 : begin MREQ<=1; ACC_R<=1; ACC_W<=1; ALU<=`OP_A;
                        FR_W<=1; DBI2<=1;  ICS<=1; end
  ...

変更箇所は以上です。


次は、 シミュレーション により追加した NAND命令が正しく動作しているか確認します。


| CAD Home |