Decoder.scala 9.2 KB
Newer Older
1 2 3 4 5
package xiangshan.backend.decode

import chisel3._
import chisel3.util._
import xiangshan._
6
import utils._
7
import xiangshan.backend._
L
linjiawei 已提交
8
import xiangshan.backend.decode.isa.{RVCInstr, RV32I_ALUInstr, RVFInstr, RVDInstr}
9
import xiangshan.{CfCtrl, CtrlFlow}
10 11


12
class Decoder extends XSModule with HasInstrType {
13 14 15 16
  val io = IO(new Bundle() {
    val in = Input(new CtrlFlow)
    val out = Output(new CfCtrl)
  })
W
William Wang 已提交
17 18 19 20

  io.out := DontCare // FIXME: remove me!!!
  io.out.cf := io.in

21 22 23 24
  val instr: UInt = io.in.instr
  val decodeList = ListLookup(instr, Instructions.DecodeDefault, Instructions.DecodeTable)
  val instrType :: fuType :: fuOpType :: Nil = decodeList

25
  // todo: remove this when fetch stage can decide if an instr is br/jmp
26 27 28 29
  // io.out.cf.brUpdate.isBr := (instrType === InstrB ||
  //                   (fuOpType === JumpOpType.jal && instrType === InstrJ && fuType === FuType.jmp) ||
  //                   (fuOpType === JumpOpType.jalr && instrType === InstrI && fuType === FuType.jmp) ||
  //                   (fuOpType === CSROpType.jmp && instrType === InstrI && fuType === FuType.csr))
Z
zhanglinjuan 已提交
30 31 32
  val isRVC = instr(1, 0) =/= "b11".U
  val rvcImmType :: rvcSrc1Type :: rvcSrc2Type :: rvcDestType :: Nil =
    ListLookup(instr, CInstructions.DecodeDefault, CInstructions.CExtraDecodeTable)
33 34 35 36 37

  io.out.ctrl.fuOpType := fuOpType
  io.out.ctrl.fuType := fuType

  val SrcTypeTable = List(
38 39 40 41 42 43 44 45 46 47 48 49
    InstrI    -> (SrcType.reg, SrcType.imm),
    InstrFI   -> (SrcType.reg, SrcType.imm),
    InstrR    -> (SrcType.reg, SrcType.reg),
    InstrFR   -> (SrcType.fp,  SrcType.fp ),
    InstrS    -> (SrcType.reg, SrcType.reg),
    InstrFS   -> (SrcType.reg, SrcType.fp ),
    InstrSA   -> (SrcType.reg, SrcType.reg),
    InstrB    -> (SrcType.reg, SrcType.reg),
    InstrU    -> (SrcType.pc , SrcType.imm),
    InstrJ    -> (SrcType.pc , SrcType.imm),
    InstrN    -> (SrcType.pc , SrcType.imm),
    InstrGtoF -> (SrcType.reg, SrcType.imm),
L
linjiawei 已提交
50
    InstrFtoG -> (SrcType.fp , SrcType.fp)
51 52 53 54 55 56
  )
  val src1Type = LookupTree(instrType, SrcTypeTable.map(p => (p._1, p._2._1)))
  val src2Type = LookupTree(instrType, SrcTypeTable.map(p => (p._1, p._2._2)))

  val (rs, rt, rd) = (instr(19, 15), instr(24, 20), instr(11, 7))

Z
zhanglinjuan 已提交
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
  val rs1       = instr(11,7)
  val rs2       = instr(6,2)
  val rs1p      = LookupTree(instr(9,7), RVCInstr.RVCRegNumTable.map(p => (p._1, p._2)))
  val rs2p      = LookupTree(instr(4,2), RVCInstr.RVCRegNumTable.map(p => (p._1, p._2)))
  val rvc_shamt = Cat(instr(12),instr(6,2))

  val RegLookUpTable = List(
    RVCInstr.DtCare   -> 0.U,
    RVCInstr.REGrs    -> rs,
    RVCInstr.REGrt    -> rt,
    RVCInstr.REGrd    -> rd,
    RVCInstr.REGrs1   -> rs1,
    RVCInstr.REGrs2   -> rs2,
    RVCInstr.REGrs1p  -> rs1p,
    RVCInstr.REGrs2p  -> rs2p,
    RVCInstr.REGx1    -> 1.U,
    RVCInstr.REGx2    -> 2.U
  )

  val rvc_src1 = LookupTree(rvcSrc1Type, RegLookUpTable.map(p => (p._1, p._2)))
  val rvc_src2 = LookupTree(rvcSrc2Type, RegLookUpTable.map(p => (p._1, p._2)))
  val rvc_dest = LookupTree(rvcDestType, RegLookUpTable.map(p => (p._1, p._2)))

  val rfSrc1 = Mux(isRVC, rvc_src1, rs)
  val rfSrc2 = Mux(isRVC, rvc_src2, rt)
L
linjiawei 已提交
82
  val rfSrc3 = instr(31, 27)
Z
zhanglinjuan 已提交
83 84
  val rfDest = Mux(isRVC, rvc_dest, rd)

85 86
  // TODO: refactor decode logic
  // make non-register addressing to zero, since isu.sb.isBusy(0) === false.B
87
  val rfWen = isrfWen(instrType) && fuType=/=FuType.fence // NOTE: fence instr use instrU but do not wb
L
LinJiawei 已提交
88
  val fpWen = isfpWen(instrType)
Z
zhanglinjuan 已提交
89 90
  io.out.ctrl.lsrc1 := Mux(src1Type === SrcType.pc, 0.U, rfSrc1)
  io.out.ctrl.lsrc2 := Mux(src2Type === SrcType.imm, 0.U, rfSrc2)
L
linjiawei 已提交
91
  io.out.ctrl.lsrc3 := rfSrc3
L
LinJiawei 已提交
92 93
  io.out.ctrl.rfWen := rfWen
  io.out.ctrl.fpWen := fpWen
Z
zhanglinjuan 已提交
94
  io.out.ctrl.ldest := Mux(fpWen || rfWen, rfDest, 0.U)
95 96 97

  val imm = LookupTree(instrType, List(
    InstrI  -> SignExt(instr(31, 20), XLEN),
L
LinJiawei 已提交
98
    InstrFI -> SignExt(instr(31, 20), XLEN),
99
    InstrS  -> SignExt(Cat(instr(31, 25), instr(11, 7)), XLEN),
L
LinJiawei 已提交
100
    InstrFS -> SignExt(Cat(instr(31, 25), instr(11, 7)), XLEN),
101 102 103 104 105
    InstrSA -> SignExt(Cat(instr(31, 25), instr(11, 7)), XLEN),
    InstrB  -> SignExt(Cat(instr(31), instr(7), instr(30, 25), instr(11, 8), 0.U(1.W)), XLEN),
    InstrU  -> SignExt(Cat(instr(31, 12), 0.U(12.W)), XLEN),//fixed
    InstrJ  -> SignExt(Cat(instr(31), instr(19, 12), instr(20), instr(30, 21), 0.U(1.W)), XLEN)
  ))
106
  val immrvc = LookupTree(rvcImmType, List(
Z
zhanglinjuan 已提交
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
    RVCInstr.ImmNone  -> 0.U(XLEN.W),
    RVCInstr.ImmLWSP  -> ZeroExt(Cat(instr(3,2), instr(12), instr(6,4), 0.U(2.W)), XLEN),
    RVCInstr.ImmLDSP  -> ZeroExt(Cat(instr(4,2), instr(12), instr(6,5), 0.U(3.W)), XLEN),
    RVCInstr.ImmSWSP  -> ZeroExt(Cat(instr(8,7), instr(12,9), 0.U(2.W)), XLEN),
    RVCInstr.ImmSDSP  -> ZeroExt(Cat(instr(9,7), instr(12,10), 0.U(3.W)), XLEN),
    RVCInstr.ImmSW    -> ZeroExt(Cat(instr(5), instr(12,10), instr(6), 0.U(2.W)), XLEN),
    RVCInstr.ImmSD    -> ZeroExt(Cat(instr(6,5), instr(12,10), 0.U(3.W)), XLEN),
    RVCInstr.ImmLW    -> ZeroExt(Cat(instr(5), instr(12,10), instr(6), 0.U(2.W)), XLEN),
    RVCInstr.ImmLD    -> ZeroExt(Cat(instr(6,5), instr(12,10), 0.U(3.W)), XLEN),
    RVCInstr.ImmJ     -> SignExt(Cat(instr(12), instr(8), instr(10,9), instr(6), instr(7), instr(2), instr(11), instr(5,3), 0.U(1.W)), XLEN),
    RVCInstr.ImmB     -> SignExt(Cat(instr(12), instr(6,5), instr(2), instr(11,10), instr(4,3), 0.U(1.W)), XLEN),
    RVCInstr.ImmLI    -> SignExt(Cat(instr(12), instr(6,2)), XLEN),
    RVCInstr.ImmLUI   -> SignExt(Cat(instr(12), instr(6,2), 0.U(12.W)), XLEN),
    RVCInstr.ImmADDI  -> SignExt(Cat(instr(12), instr(6,2)), XLEN),
    RVCInstr.ImmADDI16SP-> SignExt(Cat(instr(12), instr(4,3), instr(5), instr(2), instr(6), 0.U(4.W)), XLEN),
    RVCInstr.ImmADD4SPN-> ZeroExt(Cat(instr(10,7), instr(12,11), instr(5), instr(6), 0.U(2.W)), XLEN)
  ))
  io.out.ctrl.imm := Mux(isRVC, immrvc, imm)
125

126 127
 when (fuType === FuType.jmp) {
   def isLink(reg: UInt) = (reg === 1.U || reg === 5.U)
Z
zhanglinjuan 已提交
128
   when (isLink(rfDest) && fuOpType === JumpOpType.jal) { io.out.ctrl.fuOpType := JumpOpType.call }
G
GouLingrui 已提交
129
   when (fuOpType === JumpOpType.jalr) {
Z
zhanglinjuan 已提交
130 131
     when (isLink(rfSrc1)) { io.out.ctrl.fuOpType := JumpOpType.ret }
     when (isLink(rfDest)) { io.out.ctrl.fuOpType := JumpOpType.call }
132 133
   }
 }
134

L
linjiawei 已提交
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174



  def bitPatLookup(key: UInt, default: UInt, mapping: Seq[(BitPat, UInt)]) = {
    mapping.foldLeft(default){case (d, (k, v)) => Mux(k === key, v, d)}
  }

  io.out.ctrl.src1Type := bitPatLookup(instr, src1Type, Seq(
    RV32I_ALUInstr.LUI -> SrcType.reg // FIX LUI
  ))
  io.out.ctrl.src2Type := bitPatLookup(instr, src2Type, Seq(
    RVFInstr.FSQRT_S -> SrcType.imm,
    RVFInstr.FCLASS_S -> SrcType.imm,
    RVFInstr.FMV_X_W -> SrcType.imm,
    RVFInstr.FCVT_W_S -> SrcType.imm,
    RVFInstr.FCVT_WU_S -> SrcType.imm,
    RVFInstr.FCVT_L_S -> SrcType.imm,
    RVFInstr.FCVT_LU_S -> SrcType.imm,

    RVDInstr.FSQRT_D -> SrcType.imm,
    RVDInstr.FCVT_S_D -> SrcType.imm,
    RVDInstr.FCVT_D_S -> SrcType.imm,
    RVDInstr.FCLASS_D -> SrcType.imm,
    RVDInstr.FMV_X_D -> SrcType.imm,
    RVDInstr.FCVT_W_D -> SrcType.imm,
    RVDInstr.FCVT_WU_D -> SrcType.imm,
    RVDInstr.FCVT_L_D -> SrcType.imm,
    RVDInstr.FCVT_LU_D -> SrcType.imm
  ))
  io.out.ctrl.src3Type := bitPatLookup(instr, SrcType.imm, Seq(
    RVFInstr.FMADD_S -> SrcType.fp,
    RVFInstr.FNMADD_S -> SrcType.fp,
    RVFInstr.FMSUB_S -> SrcType.fp,
    RVFInstr.FNMSUB_S -> SrcType.fp,

    RVDInstr.FMADD_D -> SrcType.fp,
    RVDInstr.FNMADD_D -> SrcType.fp,
    RVDInstr.FMSUB_D -> SrcType.fp,
    RVDInstr.FNMSUB_D -> SrcType.fp,
  ))
175 176

  io.out.cf.exceptionVec.map(_ := false.B)
Y
Yinan Xu 已提交
177
  io.out.cf.exceptionVec(illegalInstr) := instrType === InstrN
178
  io.out.cf.exceptionVec(instrPageFault) := io.in.exceptionVec(instrPageFault)
Z
ZhangZifei 已提交
179
  // io.out.cf.exceptionVec(instrAccessFault) := io.in.pc(VAddrBits - 1, PAddrBits).orR && !vmEnable // NOTE: PAddrBits is larger than VAddrBits, so comment it
180

181 182 183 184
  io.out.ctrl.isXSTrap := (instr === XSTrap.TRAP)
  when(io.out.ctrl.isXSTrap){
    io.out.ctrl.lsrc1 := 10.U // a0
  }
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199

  /*noSpecExec make it sent to alu0,for roq is empty*/
  io.out.ctrl.noSpecExec := io.out.ctrl.isXSTrap ||
    io.out.ctrl.fuType===FuType.csr ||
    io.out.ctrl.fuType===FuType.mou ||
    io.out.ctrl.fuType===FuType.fence

  //                           fflags    zero csrrs rd    csr
  val isFrflags = BitPat("b000000000001_00000_010_?????_1110011") === io.in.instr

  io.out.ctrl.blockBackward := io.out.ctrl.isXSTrap ||
    (io.out.ctrl.fuType===FuType.csr && !isFrflags) ||
    io.out.ctrl.fuType===FuType.mou ||
    io.out.ctrl.fuType===FuType.fence

200
  io.out.ctrl.flushPipe := io.out.ctrl.fuType===FuType.fence
L
LinJiawei 已提交
201

L
linjiawei 已提交
202 203
  io.out.ctrl.isRVF := instr(26, 25) === 0.U

204 205 206 207 208

  XSDebug("in:  instr=%x pc=%x excepVec=%b intrVec=%b crossPageIPFFix=%d\n",
    io.in.instr, io.in.pc, io.in.exceptionVec.asUInt, io.in.intrVec.asUInt, io.in.crossPageIPFFix)
  XSDebug("out: src1Type=%b src2Type=%b src3Type=%b lsrc1=%d lsrc2=%d lsrc3=%d ldest=%d fuType=%b fuOpType=%b\n",
    io.out.ctrl.src1Type, io.out.ctrl.src2Type, io.out.ctrl.src3Type, io.out.ctrl.lsrc1, io.out.ctrl.lsrc2, io.out.ctrl.lsrc3, io.out.ctrl.ldest, io.out.ctrl.fuType, io.out.ctrl.fuOpType)
209
  XSDebug("out: rfWen=%d fpWen=%d isXSTrap=%d noSpecExec=%d isBlocked=%d flushPipe=%d isRVF=%d imm=%x\n",
210
    io.out.ctrl.rfWen, io.out.ctrl.fpWen, io.out.ctrl.isXSTrap, io.out.ctrl.noSpecExec, io.out.ctrl.blockBackward, io.out.ctrl.flushPipe, io.out.ctrl.isRVF, io.out.ctrl.imm)
211
}