FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

ISSからハードウェアデコーダを自動生成してみる(4)

続いて、制御信号を自動生成に挑戦する。

  • ALU_ADD / ALU_SUB など、接頭語が同一ならば、同じビットフィールドとして宣言する。
  • それ以外の単発の名前であれば、固有に1ビットを割り当てる。

  • 例: ALU_ADD/ALU_SUB/ALU_MUL/ALU_DIV/DST_EN/R1_EN/R2_EN の信号を使う場合、デコードフィールドは、

ctrl[1:0] : ALU_xxx
ctrl[2] : DST_EN
ctrl[3] : R1_EN
ctrl[4] : R2_EN

の信号が生成される。テーブルからこのようなフィールドを生成するrubyスクリプトを頑張って書いてみた(ハッシュとかを使うのは始めてだ...)

github.com

##
##=== Making all of signals for each kinds of Instruction
##
inst_dec_type.each {|inst_type|

  ctrl_signals = Hash.new()

  $arch_table.each_with_index {|inst_info, index|
    if inst_type != inst_info[ARCH::INST_TYPE] then
      next
    end

    inst_ctrls = inst_info[ARCH::INST_CTRL];
    inst_ctrls.each {|each_inst_ctrl|
      key = 0
      found = false
      head = each_inst_ctrl.split("_")[0]
      if ctrl_signals.key?(head) then
        ctrl_signals[head].each {|each_signal|
          each_signal_name = each_signal[0]
          each_signal_key  = each_signal[1]
          if each_signal_name.split("_")[0] == each_inst_ctrl.split("_")[0] then
            if each_signal_name != each_inst_ctrl then
              key = key + 1
            else
              found = true
              break
            end
          end
        }
        if found == false then
          new_pair = Array[]
          new_pair[0] = each_inst_ctrl
          new_pair[1] = key
          ctrl_signals[head].push(new_pair)
        end
      else
        new_pair = Array[]
        new_pair[0] = each_inst_ctrl
        new_pair[1] = key
        ctrl_signals[head] = Array[]
        ctrl_signals[head][0] = new_pair
      end
    }
  }


  printf("Ctrl_signals of inst_type = %s :\n", inst_type)
  ctrl_signals.each {|key, signals|
    printf("    %s\n", key)
    signals.each {|pair|
      printf("        %s=%d\n", pair[0], pair[1])
    }
  }
  printf("\n")
}

生成される情報は以下のようなものである。これから、今度こそ本当に制御信号を作成していこう。

Ctrl_signals of inst_type = ALU :
    DST
        DST_RD=0
        DST_RT=1
        DST_M=2
        DST_HI=3
        DST_LO=4
    R1
        R1_RS=0
        R1_HI=1
        R1_LO=2
        R1_SYS=3
    R2
        R2_RT=0
    ALU
        ALU_SIGN_ADD=0
        ALU_USIGN_ADD=1
        ALU_COUNT_ONE=2
        ALU_COUNT_ZERO=3
        ALU_SIGN_DIV=4
        ALU_USIGN_DIV=5
        ALU_SIGN_MADD=6
        ALU_USIGN_MADD=7
        ALU_SIGN_MSUB=8
        ALU_USIGN_MSUB=9
        ALU_SIGN_MULT=10
        ALU_USIGN_MULT=11
        ALU_SIGN_EXT_B=12
        ALU_SIGN_EXT_H=13
        ALU_SIGN_SLT=14
        ALU_USIGN_SLT=15
        ALU_SIGN_SUB=16
        ALU_USIGN_SUB=17
    IMM
        IMM=0
    SEPARATE
        SEPARATE=0
    LOGIC
        LOGIC_AND=0
        LOGIC_LUI=1
        LOGIC_NOR=2
        LOGIC_OR=3
        LOGIC_XOR=4
        LOGIC_EXT=5
        LOGIC_INS=6
        LOGIC_WBSH=7
        LOGIC_THROUGH=8
        LOGIC_MOVN=9
        LOGIC_MOVZ=10
        LOGIC_ROTR=11
        LOGIC_SLL=12
        LOGIC_SRA=13
        LOGIC_SRL=14

Ctrl_signals of inst_type = BRANCH :
    IMM
        IMM=0
    PC
        PC_REL=0
    DST
        DST_31=0
    R1
        R1_RS=0
    R2
        R2_RT=0
        R2_ZERO=1
    ALU
        ALU_SIGN_EQ=0
        ALU_SIGN_GE=1
        ALU_SIGN_GT=2
        ALU_SIGN_LE=3
        ALU_SIGN_LT=4
        ALU_SIGN_NE=5
        ALU_UNSIGN_GE=6
        ALU_UNSIGN_LT=7
        ALU_zSIGN_GT=8
    LIKELY
        LIKELY=0

Ctrl_signals of inst_type = LOAD :
    DST
        DST_RT=0
    R1
        R1_RS=0
    BYTE
        BYTE=0
    SIGNED
        SIGNED=0
    IMM
        IMM=0
    UNSIGNED
        UNSIGNED=0
    HWORD
        HWORD=0
    WORD
        WORD=0
    UNALIGN
        UNALIGN_LEFT=0
        UNALIGN_RIGHT=1

Ctrl_signals of inst_type = STORE :
    R1
        R1_RS=0
    R2
        R2_RT=0
    BYTE
        BYTE=0
    IMM
        IMM=0
    WORD
        WORD=0
    HWORD
        HWORD=0
    UNALIGN
        UNALIGN_LEFT=0
        UNALIGN_RIGHT=1