続いて、制御信号を自動生成してみよう。
基本的には、命令分類毎に必要な信号の種類がリストアップされているので、 命令分類毎に、各命令で制御信号が必要とされているかをチェックし、必要とされていれば信号線を生成、そうでなければ0とする。
## ##=== Making all of signals for each kinds of Instruction ## +ctrl_table = Hash.new() + inst_dec_type.each {|inst_type| ctrl_signals = Hash.new() @@ -324,4 +326,56 @@ inst_dec_type.each {|inst_type| } } printf("\n") + + # insert signals table into hash + ctrl_table[inst_type] = ctrl_signals; +} + + +## +## generate control signals +## + +inst_ctrl_fp.printf(" always @ (*) begin\n") + +inst_ctrl_fp.printf(" case (1'b1)\n") + +$arch_table.each_with_index {|target_inst, index| + target_signals = target_inst[ARCH::INST_CTRL]; + target_type = target_inst[ARCH::INST_TYPE]; + + mne = "`INST_%s"%([target_inst[ARCH::NAME].split(" ")[0].gsub(/\./,'_').upcase]) + + inst_ctrl_fp.printf(" %-15s : IF_INST_DEC <= {", mne) + + # traverse all of control signals in the inst-type + ctrl_table[target_type].each_with_index {|(key, ctrl_list), index| + if ctrl_list.size == 1 then + ctrl_bitwidth = 1 + else + ctrl_bitwidth = Math::log2(ctrl_list.size).to_i + end + + # traverse all of control signals in the inst-type + found = false + ctrl_list.each_with_index {|ctrl_pair, ctrl_index| + ctrl_name = ctrl_pair[0] + if target_signals.include?(ctrl_name) then + inst_ctrl_fp.printf("%s", ctrl_name) + found = true + end + } + if found == false then + inst_ctrl_fp.printf("%d'h0", ctrl_bitwidth) + end + if index != (ctrl_table[target_type].size-1) then + inst_ctrl_fp.print(", ") + end + } + inst_ctrl_fp.puts("};\n") } + +inst_ctrl_fp.printf(" endcase\n") +inst_ctrl_fp.printf(" end\n") +inst_ctrl_fp.printf("endmodule\n") +inst_ctrl_fp.close
作られた制御信号は以下のようになった。
/* CAUTION! THIS SOURCE CODE IS GENERATED AUTOMATICALLY. DON'T MODIFY BY HAND. */ `default_nettype none `include "./mips_dec.vh" module mips_dec ( input wire [31: 0] IF_INST, output wire [`INST_MAX-1: 0] IF_INST_DEC ); always @ (*) begin case (1'b1) `INST_ADD : IF_INST_DEC <= {DST_RD, R1_RS, R2_RT, ALU_SIGN_ADD, 1'h0, 1'h0, 3'h0}; `INST_ADDI : IF_INST_DEC <= {DST_RT, R1_RS, 1'h0, ALU_SIGN_ADD, IMM, 1'h0, 3'h0}; `INST_ADDIU : IF_INST_DEC <= {DST_RT, R1_RS, 1'h0, ALU_USIGN_ADD, IMM, 1'h0, 3'h0}; `INST_ADDU : IF_INST_DEC <= {DST_RD, R1_RS, R2_RT, ALU_USIGN_ADD, 1'h0, 1'h0, 3'h0}; `INST_CLO : IF_INST_DEC <= {DST_RD, R1_RS, 1'h0, ALU_COUNT_ONE, 1'h0, 1'h0, 3'h0}; `INST_CLZ : IF_INST_DEC <= {DST_RD, R1_RS, 1'h0, ALU_COUNT_ZERO, 1'h0, 1'h0, 3'h0}; `INST_DIV : IF_INST_DEC <= {DST_M, R1_RS, R2_RT, ALU_SIGN_DIV, 1'h0, SEPARATE, 3'h0}; `INST_DIVU : IF_INST_DEC <= {DST_M, R1_RS, R2_RT, ALU_USIGN_DIV, 1'h0, SEPARATE, 3'h0}; `INST_MADD : IF_INST_DEC <= {DST_M, R1_RS, R2_RT, ALU_SIGN_MADD, 1'h0, SEPARATE, 3'h0}; `INST_MADDU : IF_INST_DEC <= {DST_M, R1_RS, R2_RT, ALU_USIGN_MADD, 1'h0, SEPARATE, 3'h0}; `INST_MSUB : IF_INST_DEC <= {DST_M, R1_RS, R2_RT, ALU_SIGN_MSUB, 1'h0, SEPARATE, 3'h0}; `INST_MSUBU : IF_INST_DEC <= {DST_M, R1_RS, R2_RT, ALU_USIGN_MSUB, 1'h0, SEPARATE, 3'h0}; `INST_MUL : IF_INST_DEC <= {DST_RD, R1_RS, R2_RT, ALU_SIGN_MULT, 1'h0, 1'h0, 3'h0}; `INST_MULT : IF_INST_DEC <= {DST_M, R1_RS, R2_RT, ALU_SIGN_MULT, 1'h0, SEPARATE, 3'h0}; `INST_MULTU : IF_INST_DEC <= {DST_M, R1_RS, R2_RT, ALU_USIGN_MULT, 1'h0, SEPARATE, 3'h0}; `INST_SEB : IF_INST_DEC <= {DST_RD, R1_RS, R2_RT, ALU_SIGN_EXT_B, 1'h0, 1'h0, 3'h0}; `INST_SEH : IF_INST_DEC <= {DST_RD, R1_RS, R2_RT, ALU_SIGN_EXT_H, 1'h0, 1'h0, 3'h0}; `INST_SLT : IF_INST_DEC <= {DST_RD, R1_RS, R2_RT, ALU_SIGN_SLT, 1'h0, 1'h0, 3'h0}; `INST_SLTI : IF_INST_DEC <= {DST_RT, R1_RS, 1'h0, ALU_SIGN_SLT, IMM, 1'h0, 3'h0}; `INST_SLTIU : IF_INST_DEC <= {DST_RT, R1_RS, 1'h0, ALU_USIGN_SLT, IMM, 1'h0, 3'h0}; `INST_SLTU : IF_INST_DEC <= {DST_RD, R1_RS, R2_RT, ALU_USIGN_SLT, 1'h0, 1'h0, 3'h0}; `INST_SUB : IF_INST_DEC <= {DST_RD, R1_RS, R2_RT, ALU_SIGN_SUB, 1'h0, 1'h0, 3'h0}; `INST_SUBU : IF_INST_DEC <= {DST_RD, R1_RS, R2_RT, ALU_USIGN_SUB, 1'h0, 1'h0, 3'h0}; `INST_B : IF_INST_DEC <= {IMM, PC_REL, 1'h0, 1'h0, 1'h0, 3'h0, 1'h0}; `INST_BAL : IF_INST_DEC <= {IMM, PC_REL, DST_31, 1'h0, 1'h0, 3'h0, 1'h0}; ...
なんとなくうまく出来ている気がする。しかし、あとはレジスタインデックスの切り抜きなど、もうすこし気の効いた生成をしなければならない。見た目もインデントが揃っていなくて気持ちが悪い。 もうちょっと修正していこう。