... `define IR_ROR 6'b101101 `define IR_NAND 6'b101110 // NAND命令追加 `define IR_SWP 6'b101111 ...
// // ALU operations // `define IADD 5'b00000 ... `define INAND 5'b01110 // NAND演算追加 ... `define IPAS 5'b10000 // PASS演算コードの再定義
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
... wire [ 4:0] ALU_C; // for ALU Control (制御コード拡張) ...
... output [4:0] ALU; // 制御コード拡張 ... reg [4:0] ALU; // 制御コード拡張 ...
...
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;
...
//------------------------------------------------------------------//
// 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
ALU<=`OP_A;の記述が、同一のステートで個々の演算を実現できるようにしている部分です。
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命令が正しく動作しているか確認します。