続き。とりあえずデコードテーブルを作ってみたところから。
## start of RISC-V instructions # ['BITFIELD' 31-26, 25-21, 20-16 15-11 10-06 05-00 ] # ['DECODE-KEY', 'OPCODE', 'RS' 'RT', 'RD', 'SHAMT', 'FUNCT' 'TYPE' 'KEY_TABLE' ] $arch_table[ 0] = Array['add d[15:11],d[25:21],d[20:16]', '000000', 'XXXXX', 'XXXXX', 'XXXXX', '00000', '100000', 'ALU', Array[ 'DST_RD', 'R1_RS', 'R2_RT', 'ALU_SIGN_ADD' ], Array['OPCODE', 'FUNCT', 'SHAMT'], ] $arch_table[ 1] = Array['addi d[20:16],d[25:21],h[15:0]', '001000', 'XXXXX', 'XXXXX', 'XXXXX', 'XXXXX', 'XXXXXX', 'ALU', Array[ 'DST_RT', 'R1_RS', 'IMM', 'ALU_SIGN_ADD' ], Array['OPCODE']] $arch_table[ 2] = Array['addiu d[20:16],d[25:21],h[15:0]', '001001', 'XXXXX', 'XXXXX', 'XXXXX', 'XXXXX', 'XXXXXX', 'ALU', Array[ 'DST_RT', 'R1_RS', 'IMM', 'ALU_USIGN_ADD' ], Array['OPCODE']] $arch_table[ 3] = Array['addu d[15:11],d[25:21],d[20:16]', '000000', 'XXXXX', 'XXXXX', 'XXXXX', '00000', '100001', 'ALU', Array[ 'DST_RD', 'R1_RS', 'R2_RT', 'ALU_USIGN_ADD' ], Array['OPCODE', 'FUNCT', 'SHAMT']] $arch_table[ 4] = Array['clo d[15:11],d[25:21]', '011100', 'XXXXX', 'XXXXX', 'XXXXX', '00000', '100001', 'ALU', Array[ 'DST_RD', 'R1_RS', 'ALU_COUNT_ONE' ], Array['OPCODE', 'FUNCT', 'SHAMT']] $arch_table[ 5] = Array['clz d[15:11],d[25:21]', '011100', 'XXXXX', 'XXXXX', 'XXXXX', '00000', '100000', 'ALU', Array[ 'DST_RD', 'R1_RS', 'ALU_COUNT_ZERO'], Array['OPCODE', 'FUNCT', 'SHAMT']] $arch_table[ 6] = Array['div d[25:21],d[20:16]', '000000', 'XXXXX', 'XXXXX', '00000', '00000', '011010', 'ALU', Array['SEPARATE', 'DST_M', 'R1_RS', 'R2_RT', 'ALU_SIGN_DIV' ], Array['OPCODE', 'FUNCT', 'RD', 'SHAMT']] $arch_table[ 7] = Array['divu d[25:21],d[20:16]', '000000', 'XXXXX', 'XXXXX', '00000', '00000', '011011', 'ALU', Array['SEPARATE', 'DST_M', 'R1_RS', 'R2_RT', 'ALU_USIGN_DIV' ], Array['OPCODE', 'FUNCT', 'RD', 'SHAMT']] $arch_table[ 8] = Array['madd d[25:21],d[20:16]', '011100', 'XXXXX', 'XXXXX', '00000', '00000', '000000', 'ALU', Array['SEPARATE', 'DST_M', 'R1_RS', 'R2_RT', 'ALU_SIGN_MADD' ], Array['OPCODE', 'FUNCT', 'RD', 'SHAMT']] $arch_table[ 9] = Array['maddu d[25:21],d[20:16]', '011100', 'XXXXX', 'XXXXX', '00000', '00000', '000001', 'ALU', Array['SEPARATE', 'DST_M', 'R1_RS', 'R2_RT', 'ALU_USIGN_MADD'], Array['OPCODE', 'FUNCT', 'RD', 'SHAMT']] $arch_table[ 10] = Array['msub d[25:21],d[20:16]', '011100', 'XXXXX', 'XXXXX', '00000', '00000', '000100', 'ALU', Array['SEPARATE', 'DST_M', 'R1_RS', 'R2_RT', 'ALU_SIGN_MSUB' ], Array['OPCODE', 'FUNCT', 'RD', 'SHAMT']] $arch_table[ 11] = Array['msubu d[25:21],d[20:16]', '011100', 'XXXXX', 'XXXXX', '00000', '00000', '000101', 'ALU', Array['SEPARATE', 'DST_M', 'R1_RS', 'R2_RT', 'ALU_USIGN_MSUB'], Array['OPCODE', 'FUNCT', 'RD', 'SHAMT']] $arch_table[ 12] = Array['mul d[25:21],d[20:16]', '011100', 'XXXXX', 'XXXXX', 'XXXXX', '00000', '000010', 'ALU', Array[ 'DST_RD', 'R1_RS', 'R2_RT', 'ALU_SIGN_MULT' ], Array['OPCODE', 'FUNCT', 'SHAMT']] $arch_table[ 13] = Array['mult d[25:21],d[20:16]', '000000', 'XXXXX', 'XXXXX', '00000', '00000', '011000', 'ALU', Array['SEPARATE', 'DST_M', 'R1_RS', 'R2_RT', 'ALU_SIGN_MULT' ], Array['OPCODE', 'FUNCT', 'RD', 'SHAMT']] $arch_table[ 14] = Array['multu d[25:21],d[20:16]', '000000', 'XXXXX', 'XXXXX', '00000', '00000', '011001', 'ALU', Array['SEPARATE', 'DST_M', 'R1_RS', 'R2_RT', 'ALU_USIGN_MULT'], Array['OPCODE', 'FUNCT', 'RD', 'SHAMT']] $arch_table[ 15] = Array['seb d[15:11],d[20:16]', '011111', '00000', 'XXXXX', 'XXXXX', '10000', '100000', 'ALU', Array[ 'DST_RD', 'R1_RS', 'R2_RT', 'ALU_SIGN_EXT_B'], Array['OPCODE', 'FUNCT', 'RS', 'SHAMT']] $arch_table[ 16] = Array['seh d[15:11],d[20:16]', '011111', '00000', 'XXXXX', 'XXXXX', '11000', '100000', 'ALU', Array[ 'DST_RD', 'R1_RS', 'R2_RT', 'ALU_SIGN_EXT_H'], Array['OPCODE', 'FUNCT', 'RS', 'SHAMT']] $arch_table[ 17] = Array['slt d[15:11],d[25:21],d[20:16]', '000000', 'XXXXX', 'XXXXX', 'XXXXX', '00000', '101010', 'ALU', Array[ 'DST_RD', 'R1_RS', 'R2_RT', 'ALU_SIGN_SLT' ], Array['OPCODE', 'FUNCT', 'SHAMT']] $arch_table[ 18] = Array['slti d[20:16],d[25:21],h[15:0]', '001010', 'XXXXX', 'XXXXX', 'XXXXX', 'XXXXX', 'XXXXXX', 'ALU', Array[ 'DST_RT', 'R1_RS', 'IMM', 'ALU_SIGN_SLT' ], Array['OPCODE']] $arch_table[ 19] = Array['sltiu d[20:16],d[25:21],h[15:0]', '001011', 'XXXXX', 'XXXXX', 'XXXXX', 'XXXXX', 'XXXXXX', 'ALU', Array[ 'DST_RT', 'R1_RS', 'IMM', 'ALU_USIGN_SLT' ], Array['OPCODE']] $arch_table[ 20] = Array['sltu d[15:11],d[25:21],d[20:16]', '000000', 'XXXXX', 'XXXXX', 'XXXXX', '00000', '101011', 'ALU', Array[ 'DST_RD', 'R1_RS', 'R2_RT', 'ALU_USIGN_SLT' ], Array['OPCODE', 'FUNCT', 'SHAMT']] $arch_table[ 21] = Array['sub d[15:11],d[25:21],d[20:16]', '000000', 'XXXXX', 'XXXXX', 'XXXXX', '00000', '100010', 'ALU', Array[ 'DST_RD', 'R1_RS', 'R2_RT', 'ALU_SIGN_SUB' ], Array['OPCODE', 'FUNCT', 'SHAMT']] $arch_table[ 22] = Array['subu d[15:11],d[25:21],d[20:16]', '000000', 'XXXXX', 'XXXXX', 'XXXXX', '00000', '100011', 'ALU', Array[ 'DST_RD', 'R1_RS', 'R2_RT', 'ALU_USIGN_SUB' ], Array['OPCODE', 'FUNCT', 'SHAMT']]
ここで、
'ALU'
とか書いてあるのが命令の種類に相当する。ここでは、'ALU', 'BRANCH', 'LOAD', 'STORE' の4つが存在する。 まずは、これらを区分するための制御信号を生成する。
inst_define_fp.printf("\n// declaration of instruction type\n") inst_dec_type.each_with_index {|type, index| inst_define_fp.printf("`define INST_TYPE_%s\t\t%d'b", type, inst_dec_type.size) bit_i = 0 while bit_i < inst_dec_type.size do if bit_i == index then inst_define_fp.printf("1") else inst_define_fp.printf("0") end bit_i = bit_i + 1 end inst_define_fp.puts("\n") }
これにより、以下のような信号定義が自動的に生成される。
// declaration of instruction type `define INST_TYPE_ALU 4'b1000 `define INST_TYPE_BRANCH 4'b0100 `define INST_TYPE_LOAD 4'b0010 `define INST_TYPE_STORE 4'b0001
続いて、制御信号の生成だ。