xref: /XiangShan/src/main/scala/xiangshan/backend/decode/DecodeUnit.scala (revision 4d24c305ffe6afbc18f58fbbb7e92f28aaef1365)
1package xiangshan.backend.decode
2
3import chisel3._
4import chisel3.util._
5
6import freechips.rocketchip.config.Parameters
7import freechips.rocketchip.rocket.{RVCDecoder, ExpandedInstruction}
8import freechips.rocketchip.rocket.{CSR,Causes}
9import freechips.rocketchip.util.{uintToBitPat,UIntIsOneOf}
10
11import xiangshan._
12import utils._
13import xiangshan.backend._
14import xiangshan.backend.decode.AltInstructions._
15import xiangshan.backend.fu.fpu.FPUOpType
16import freechips.rocketchip.tile.RocketTile
17
18/**
19 * Abstract trait giving defaults and other relevant values to different Decode constants/
20 */
21abstract trait DecodeConstants {
22  // TODO move these constants to somewhere else?
23  def X = BitPat("b?")
24  def N = BitPat("b0")
25  def Y = BitPat("b1")
26
27  def decodeDefault: List[BitPat] =
28    //   src1Type     src2Type     src3Type     fuType      fuOpType       rfWen
29    //   |            |            |            |           |              |  fpWen
30    //   |            |            |            |           |              |  |  isXSTrap
31    //   |            |            |            |           |              |  |  |  noSpecExec
32    //   |            |            |            |           |              |  |  |  |  blockBackward
33    //   |            |            |            |           |              |  |  |  |  |  flushPipe
34    //   |            |            |            |           |              |  |  |  |  |  |  isRVF
35    //   |            |            |            |           |              |  |  |  |  |  |  |
36    List(SrcType.reg, SrcType.reg, SrcType.reg, FuType.alu, ALUOpType.sll, N, N, N, N, N, N, N)
37
38    val table: Array[(BitPat, List[BitPat])]
39}
40
41trait RISCVConstants
42{
43  // abstract out instruction decode magic numbers
44  val RD_MSB  = 11
45  val RD_LSB  = 7
46  val RS1_MSB = 19
47  val RS1_LSB = 15
48  val RS2_MSB = 24
49  val RS2_LSB = 20
50  val RS3_MSB = 31
51  val RS3_LSB = 27
52
53  // TODO move constants above to somewhere better and remove useless constants below
54
55  val CSR_ADDR_MSB = 31
56  val CSR_ADDR_LSB = 20
57  val CSR_ADDR_SZ = 12
58
59  // location of the fifth bit in the shamt (for checking for illegal ops for SRAIW,etc.)
60  val SHAMT_5_BIT = 25
61  val LONGEST_IMM_SZ = 20
62  val X0 = 0.U
63  val RA = 1.U // return address register
64
65  // memory consistency model
66  // The C/C++ atomics MCM requires that two loads to the same address maintain program order.
67  // The Cortex A9 does NOT enforce load/load ordering (which leads to buggy behavior).
68  val MCM_ORDER_DEPENDENT_LOADS = true
69
70  val jal_opc = (0x6f).U
71  val jalr_opc = (0x67).U
72
73  def GetUop(inst: UInt): UInt = inst(6,0)
74  def GetRd (inst: UInt): UInt = inst(RD_MSB,RD_LSB)
75  def GetRs1(inst: UInt): UInt = inst(RS1_MSB,RS1_LSB)
76
77  // Note: Accepts only EXPANDED rvc instructions
78  def ComputeBranchTarget(pc: UInt, inst: UInt, xlen: Int)(implicit p: Parameters): UInt = {
79    val b_imm32 = Cat(Fill(20,inst(31)), inst(7), inst(30,25), inst(11,8), 0.U(1.W))
80    ((pc.asSInt + b_imm32.asSInt).asSInt & (-2).S).asUInt
81  }
82
83  // Note: Accepts only EXPANDED rvc instructions
84  def ComputeJALTarget(pc: UInt, inst: UInt, xlen: Int)(implicit p: Parameters): UInt = {
85    val j_imm32 = Cat(Fill(12,inst(31)), inst(19,12), inst(20), inst(30,25), inst(24,21), 0.U(1.W))
86    ((pc.asSInt + j_imm32.asSInt).asSInt & (-2).S).asUInt
87  }
88}
89
90/**
91 * Decoded control signals
92 * See xiangshan/package.scala, xiangshan/backend/package.scala, Bundle.scala
93 */
94// FIXME Check sig from isXSTrap to isRVF
95/**
96 * Decode constants for RV64
97 */
98object X64Decode extends DecodeConstants {
99  val table: Array[(BitPat, List[BitPat])] = Array(
100    LD      -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.ldu, LSUOpType.ld, Y, N, N, N, N, N, N),
101    LWU     -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.ldu, LSUOpType.lwu, Y, N, N, N, N, N, N),
102    SD      -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.stu, LSUOpType.sd, N, N, N, N, N, N, N),
103
104    SLLI    -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.sll, Y, N, N, N, N, N, N),
105    SRLI    -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.srl, Y, N, N, N, N, N, N),
106    SRAI    -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.sra, Y, N, N, N, N, N, N),
107
108    ADDIW   -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.addw, Y, N, N, N, N, N, N),
109    SLLIW   -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.sllw, Y, N, N, N, N, N, N),
110    SRAIW   -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.sraw, Y, N, N, N, N, N, N),
111    SRLIW   -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.srlw, Y, N, N, N, N, N, N),
112
113    ADDW    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.addw, Y, N, N, N, N, N, N),
114    SUBW    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.subw, Y, N, N, N, N, N, N),
115    SLLW    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.sllw, Y, N, N, N, N, N, N),
116    SRAW    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.sraw, Y, N, N, N, N, N, N),
117    SRLW    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.srlw, Y, N, N, N, N, N, N)
118  )
119}
120
121/**
122 * Overall Decode constants
123 */
124object XDecode extends DecodeConstants {
125  val table: Array[(BitPat, List[BitPat])] = Array(
126    LW      -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.ldu, LSUOpType.lw, Y, N, N, N, N, N, N),
127    LH      -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.ldu, LSUOpType.lh, Y, N, N, N, N, N, N),
128    LHU     -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.ldu, LSUOpType.lhu, Y, N, N, N, N, N, N),
129    LB      -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.ldu, LSUOpType.lb, Y, N, N, N, N, N, N),
130    LBU     -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.ldu, LSUOpType.lbu, Y, N, N, N, N, N, N),
131
132    SW      -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.stu, LSUOpType.sw, N, N, N, N, N, N, N),
133    SH      -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.stu, LSUOpType.sh, N, N, N, N, N, N, N),
134    SB      -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.stu, LSUOpType.sb, N, N, N, N, N, N, N),
135
136    LUI     -> List(SrcType.pc, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.add, Y, N, N, N, N, N, N),
137
138    ADDI    -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.add, Y, N, N, N, N, N, N),
139    ANDI    -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.and, Y, N, N, N, N, N, N),
140    ORI     -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.or, Y, N, N, N, N, N, N),
141    XORI    -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.xor, Y, N, N, N, N, N, N),
142    SLTI    -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.slt, Y, N, N, N, N, N, N),
143    SLTIU   -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.sltu, Y, N, N, N, N, N, N),
144
145    SLL     -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.sll, Y, N, N, N, N, N, N),
146    ADD     -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.add, Y, N, N, N, N, N, N),
147    SUB     -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.sub, Y, N, N, N, N, N, N),
148    SLT     -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.slt, Y, N, N, N, N, N, N),
149    SLTU    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.sltu, Y, N, N, N, N, N, N),
150    AND     -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.and, Y, N, N, N, N, N, N),
151    OR      -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.or, Y, N, N, N, N, N, N),
152    XOR     -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.xor, Y, N, N, N, N, N, N),
153    SRA     -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.sra, Y, N, N, N, N, N, N),
154    SRL     -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.srl, Y, N, N, N, N, N, N),
155
156    MUL     -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mul, MDUOpType.mul, Y, N, N, N, N, N, N),
157    MULH    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mul, MDUOpType.mulh, Y, N, N, N, N, N, N),
158    MULHU   -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mul, MDUOpType.mulhu, Y, N, N, N, N, N, N),
159    MULHSU  -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mul, MDUOpType.mulhsu, Y, N, N, N, N, N, N),
160    MULW    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mul, MDUOpType.mulw, Y, N, N, N, N, N, N),
161
162    DIV     -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.div, MDUOpType.div, Y, N, N, N, N, N, N),
163    DIVU    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.div, MDUOpType.divu, Y, N, N, N, N, N, N),
164    REM     -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.div, MDUOpType.rem, Y, N, N, N, N, N, N),
165    REMU    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.div, MDUOpType.remu, Y, N, N, N, N, N, N),
166    DIVW    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.div, MDUOpType.divw, Y, N, N, N, N, N, N),
167    DIVUW   -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.div, MDUOpType.divuw, Y, N, N, N, N, N, N),
168    REMW    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.div, MDUOpType.remw, Y, N, N, N, N, N, N),
169    REMUW   -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.div, MDUOpType.remuw, Y, N, N, N, N, N, N),
170
171    AUIPC   -> List(SrcType.pc, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.add, Y, N, N, N, N, N, N),
172    JAL     -> List(SrcType.pc , SrcType.imm, SrcType.DC, FuType.jmp, JumpOpType.jal, Y, N, N, N, N, N, N),
173    JALR    -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.jmp, JumpOpType.jalr, Y, N, N, N, N, N, N),
174    BEQ     -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.beq, N, N, N, N, N, N, N),
175    BNE     -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.bne, N, N, N, N, N, N, N),
176    BGE     -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.bge, N, N, N, N, N, N, N),
177    BGEU    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.bgeu, N, N, N, N, N, N, N),
178    BLT     -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.blt, N, N, N, N, N, N, N),
179    BLTU    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.alu, ALUOpType.bltu, N, N, N, N, N, N, N),
180
181    // I-type, the immediate12 holds the CSR register.
182    CSRRW   -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.wrt, N, N, N, N, N, N, N),
183    CSRRS   -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.set, N, N, N, N, N, N, N),
184    CSRRC   -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.clr, N, N, N, N, N, N, N),
185
186    CSRRWI  -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.wrti, N, N, N, N, N, N, N),
187    CSRRSI  -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.seti, N, N, N, N, N, N, N),
188    CSRRCI  -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.clri, N, N, N, N, N, N, N),
189
190    SFENCE_VMA->List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.fence, FenceOpType.sfence, N, N, N, N, N, N, N),
191    SCALL   -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.jmp, N, N, N, N, N, N, N), // same as ECALL
192    SRET    -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.jmp, N, N, N, N, N, N, N),
193    MRET    -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.csr, CSROpType.jmp, N, N, N, N, N, N, N),
194
195    WFI     -> List(SrcType.pc, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.sll, N, N, N, N, N, N, N),
196
197    FENCE_I -> List(SrcType.pc, SrcType.imm, SrcType.DC, FuType.fence, FenceOpType.fencei, N, N, N, N, N, N, N),
198    FENCE   -> List(SrcType.pc, SrcType.imm, SrcType.DC, FuType.fence, FenceOpType.fence, N, N, N, N, N, N, N),
199
200    // A-type
201    AMOADD_W-> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amoadd_w, N, N, N, N, N, N, N),
202    AMOXOR_W-> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amoxor_w, N, N, N, N, N, N, N),
203    AMOSWAP_W->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amoswap_w, N, N, N, N, N, N, N),
204    AMOAND_W-> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amoand_w, N, N, N, N, N, N, N),
205    AMOOR_W -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amoor_w, N, N, N, N, N, N, N),
206    AMOMIN_W-> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amomin_w, N, N, N, N, N, N, N),
207    AMOMINU_W->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amominu_w, N, N, N, N, N, N, N),
208    AMOMAX_W-> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amomax_w, N, N, N, N, N, N, N),
209    AMOMAXU_W->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amomaxu_w, N, N, N, N, N, N, N),
210
211    AMOADD_D-> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amoadd_d, N, N, N, N, N, N, N),
212    AMOXOR_D-> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amoxor_d, N, N, N, N, N, N, N),
213    AMOSWAP_D->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amoswap_d, N, N, N, N, N, N, N),
214    AMOAND_D-> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amoand_d, N, N, N, N, N, N, N),
215    AMOOR_D -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amoor_d, N, N, N, N, N, N, N),
216    AMOMIN_D-> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amomin_d, N, N, N, N, N, N, N),
217    AMOMINU_D->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amominu_d, N, N, N, N, N, N, N),
218    AMOMAX_D-> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amomax_d, N, N, N, N, N, N, N),
219    AMOMAXU_D->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.amomaxu_d, N, N, N, N, N, N, N),
220
221    LR_W    -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.mou, LSUOpType.lr_w, N, N, N, N, N, N, N),
222    LR_D    -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.mou, LSUOpType.lr_d, N, N, N, N, N, N, N),
223    SC_W    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.sc_w, N, N, N, N, N, N, N),
224    SC_D    -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.mou, LSUOpType.sc_d, N, N, N, N, N, N, N)
225  )
226}
227
228/**
229 * FP Decode constants
230 */
231object FDecode extends DecodeConstants{
232  val table: Array[(BitPat, List[BitPat])] = Array(
233    // FIXME check Src3type below
234  FLW     -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.ldu, LSUOpType.flw, N, N, N, N, N, N, N),
235  FLD     -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.ldu, LSUOpType.ld, N, N, N, N, N, N, N),
236  FSW     -> List(SrcType.reg, SrcType.fp, SrcType.DC, FuType.stu, LSUOpType.sw, N, N, N, N, N, N, N), // sort of a lie; broken into two micro-ops
237  FSD     -> List(SrcType.reg, SrcType.fp, SrcType.DC, FuType.stu, LSUOpType.sd, N, N, N, N, N, N, N),
238
239  FCLASS_S-> List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.fclass, N, N, N, N, N, N, N),
240  FCLASS_D-> List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.fclass, N, N, N, N, N, N, N),
241
242  FMV_D_X -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.i2f, FPUOpType.fmv_i2f, N, N, N, N, N, N, N),
243  FMV_X_D -> List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.fmv_f2i, N, N, N, N, N, N, N),
244  FMV_X_W -> List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.fmv_f2i, N, N, N, N, N, N, N),
245  FMV_W_X -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.i2f, FPUOpType.fmv_i2f, N, N, N, N, N, N, N),
246
247  FSGNJ_S -> List(SrcType.fp,  SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.fsgnj, N, N, N, N, N, N, N),
248  FSGNJ_D -> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmisc, FPUOpType.fsgnj, N, N, N, N, N, N, N),
249  FSGNJX_S-> List(SrcType.fp,  SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.fsgnjx, N, N, N, N, N, N, N),
250  FSGNJX_D-> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmisc, FPUOpType.fsgnjx, N, N, N, N, N, N, N),
251  FSGNJN_S-> List(SrcType.fp,  SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.fsgnjn, N, N, N, N, N, N, N),
252  FSGNJN_D-> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmisc, FPUOpType.fsgnjn, N, N, N, N, N, N, N),
253
254  // FP to FP
255  FCVT_S_D-> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmisc, FPUOpType.d2s, N, N, N, N, N, N, N),
256  FCVT_D_S-> List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmisc, FPUOpType.s2d, N, N, N, N, N, N, N),
257
258  // Int to FP
259  FCVT_S_W-> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.i2f, FPUOpType.w2f, N, N, N, N, N, N, N),
260  FCVT_S_WU->List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.i2f, FPUOpType.wu2f, N, N, N, N, N, N, N),
261  FCVT_S_L-> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.i2f, FPUOpType.l2f, N, N, N, N, N, N, N),
262  FCVT_S_LU->List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.i2f, FPUOpType.lu2f, N, N, N, N, N, N, N),
263
264  FCVT_D_W-> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.i2f, FPUOpType.w2f, N, N, N, N, N, N, N),
265  FCVT_D_WU->List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.i2f, FPUOpType.wu2f, N, N, N, N, N, N, N),
266  FCVT_D_L-> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.i2f, FPUOpType.l2f, N, N, N, N, N, N, N),
267  FCVT_D_LU->List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.i2f, FPUOpType.lu2f, N, N, N, N, N, N, N),
268
269  // FP to Int
270  FCVT_W_S-> List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.f2w, N, N, N, N, N, N, N),
271  FCVT_WU_S->List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.f2wu, N, N, N, N, N, N, N),
272  FCVT_L_S-> List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.f2l, N, N, N, N, N, N, N),
273  FCVT_LU_S->List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.f2lu, N, N, N, N, N, N, N),
274
275  FCVT_W_D-> List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.f2w, N, N, N, N, N, N, N),
276  FCVT_WU_D->List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.f2wu, N, N, N, N, N, N, N),
277  FCVT_L_D-> List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.f2l, N, N, N, N, N, N, N),
278  FCVT_LU_D->List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.f2lu, N, N, N, N, N, N, N),
279
280  // "fp_single" is used for wb_data formatting (and debugging)
281  FEQ_S    ->List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.feq, N, N, N, N, N, N, N),
282  FLT_S    ->List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.flt, N, N, N, N, N, N, N),
283  FLE_S    ->List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.fle, N, N, N, N, N, N, N),
284
285  FEQ_D    ->List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.feq, N, N, N, N, N, N, N),
286  FLT_D    ->List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.flt, N, N, N, N, N, N, N),
287  FLE_D    ->List(SrcType.fp , SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.fle, N, N, N, N, N, N, N),
288
289  FMIN_S   ->List(SrcType.fp,  SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.fmin, N, N, N, N, N, N, N),
290  FMAX_S   ->List(SrcType.fp,  SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.fmax, N, N, N, N, N, N, N),
291  FMIN_D   ->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmisc, FPUOpType.fmin, N, N, N, N, N, N, N),
292  FMAX_D   ->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmisc, FPUOpType.fmax, N, N, N, N, N, N, N),
293
294  FADD_S   ->List(SrcType.fp,  SrcType.fp, SrcType.DC, FuType.fmac, FPUOpType.fadd, N, N, N, N, N, N, N),
295  FSUB_S   ->List(SrcType.fp,  SrcType.fp, SrcType.DC, FuType.fmac, FPUOpType.fsub, N, N, N, N, N, N, N),
296  FMUL_S   ->List(SrcType.fp,  SrcType.fp, SrcType.DC, FuType.fmac, FPUOpType.fmul, N, N, N, N, N, N, N),
297  FADD_D   ->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmac, FPUOpType.fadd, N, N, N, N, N, N, N),
298  FSUB_D   ->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmac, FPUOpType.fsub, N, N, N, N, N, N, N),
299  FMUL_D   ->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmac, FPUOpType.fmul, N, N, N, N, N, N, N),
300
301  FMADD_S  ->List(SrcType.fp,  SrcType.fp, SrcType.DC, FuType.fmac, FPUOpType.fmadd, N, N, N, N, N, N, N),
302  FMSUB_S  ->List(SrcType.fp,  SrcType.fp, SrcType.DC, FuType.fmac, FPUOpType.fmsub, N, N, N, N, N, N, N),
303  FNMADD_S ->List(SrcType.fp,  SrcType.fp, SrcType.DC, FuType.fmac, FPUOpType.fnmadd, N, N, N, N, N, N, N),
304  FNMSUB_S ->List(SrcType.fp,  SrcType.fp, SrcType.DC, FuType.fmac, FPUOpType.fnmsub, N, N, N, N, N, N, N),
305  FMADD_D  ->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmac, FPUOpType.fmadd, N, N, N, N, N, N, N),
306  FMSUB_D  ->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmac, FPUOpType.fmsub, N, N, N, N, N, N, N),
307  FNMADD_D ->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmac, FPUOpType.fnmadd, N, N, N, N, N, N, N),
308  FNMSUB_D ->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmac, FPUOpType.fnmsub, N, N, N, N, N, N, N)
309
310  )
311}
312
313/**
314 * FP Divide SquareRoot Constants
315 */
316object FDivSqrtDecode extends DecodeConstants {
317  val table: Array[(BitPat, List[BitPat])] = Array(
318  FDIV_S    ->List(SrcType.fp,  SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.fdiv, N, N, N, N, N, N, N),
319  FDIV_D    ->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmisc, FPUOpType.fdiv, N, N, N, N, N, N, N),
320  FSQRT_S   ->List(SrcType.fp,  SrcType.fp, SrcType.DC, FuType.fmisc, FPUOpType.fsqrt, N, N, N, N, N, N, N),
321  FSQRT_D   ->List(SrcType.reg, SrcType.reg, SrcType.DC, FuType.fmisc, FPUOpType.fsqrt, N, N, N, N, N, N, N)
322
323  )
324}
325
326/**
327 * XiangShan Trap Decode constants
328 */
329object XSTrapDecode extends DecodeConstants {
330  // calculate as ADDI => addi zero, a0, 0
331  // replace rs '?????' with '01010'(a0) in decode stage
332  def lsrc1 = "b01010".U // $a0
333  val table: Array[(BitPat, List[BitPat])] = Array(
334    TRAP    -> List(SrcType.reg, SrcType.imm, SrcType.DC, FuType.alu, ALUOpType.add, N, N, N, N, N, N, N)
335  )
336}
337
338class RVCExpander extends XSModule {
339  val io = IO(new Bundle {
340    val in = Input(UInt(32.W))
341    val out = Output(new ExpandedInstruction)
342    val rvc = Output(Bool())
343  })
344
345  if (HasCExtension) {
346    io.rvc := io.in(1,0) =/= 3.U
347    io.out := new RVCDecoder(io.in, XLEN).decode
348  } else {
349    io.rvc := false.B
350    io.out := new RVCDecoder(io.in, XLEN).passthrough
351  }
352}
353
354/**
355 * IO bundle for the Decode unit
356 */
357class DecodeUnitIO extends XSBundle {
358  val enq = new Bundle { val ctrl_flow = Input(new CtrlFlow) }
359  val deq = new Bundle { val cf_ctrl = Output(new CfCtrl) }
360}
361
362/**
363 * Decode unit that takes in a single CtrlFlow and generates a CfCtrl.
364 */
365class DecodeUnit extends XSModule with RISCVConstants {
366  val io = IO(new DecodeUnitIO)
367
368  val ctrl_flow = Wire(new CtrlFlow) // input with RVC Expanded
369  val cf_ctrl = Wire(new CfCtrl)
370
371  // FIXME add expander
372  val exp = Module(new RVCExpander()) // FIXME Is empty really worked here?
373  exp.io.in := io.enq.ctrl_flow.instr
374  ctrl_flow := io.enq.ctrl_flow
375  when (exp.io.rvc) {
376    ctrl_flow.instr := exp.io.out.bits
377  }
378
379  // save rvc decode info
380  val rvc_info = Wire(new ExpandedInstruction())
381  val is_rvc = Wire(Bool())
382  rvc_info := exp.io.out
383  is_rvc := exp.io.rvc
384
385  var decode_table = XDecode.table ++ FDecode.table ++ FDivSqrtDecode.table ++ X64Decode.table ++ XSTrapDecode.table
386
387  // output
388  cf_ctrl.cf := ctrl_flow
389  cf_ctrl.brTag := DontCare
390  val cs = Wire(new CtrlSignals()).decode(ctrl_flow.instr, decode_table)
391
392  when (is_rvc) {
393    cs.lsrc1 := rvc_info.rs1
394    cs.lsrc2 := rvc_info.rs2
395    cs.lsrc3 := rvc_info.rs3
396
397    cs.ldest := rvc_info.rd
398
399  } .otherwise {
400    cs.lsrc1 := ctrl_flow.instr(RS1_MSB,RS1_LSB)
401    cs.lsrc2 := ctrl_flow.instr(RS2_MSB,RS2_LSB)
402    cs.lsrc3 := ctrl_flow.instr(RS3_MSB,RS3_LSB)
403
404    cs.ldest := ctrl_flow.instr(RD_MSB,RD_LSB)
405  }
406
407  // TODO fill exp, intr Vec in CtrlFlow
408  io.deq.cf_ctrl.cf.exceptionVec := io.enq.ctrl_flow.exceptionVec
409  io.deq.cf_ctrl.cf.intrVec := io.enq.ctrl_flow.intrVec
410
411  // TODO fill imm
412  cs.imm := DontCare
413
414  cf_ctrl.ctrl := cs
415  io.deq.cf_ctrl := cf_ctrl
416
417  //-------------------------------------------------------------
418  // Debug Info
419  XSDebug("in:  instr=%x pc=%x excepVec=%b intrVec=%b crossPageIPFFix=%d\n",
420    io.enq.ctrl_flow.instr, io.enq.ctrl_flow.pc, io.enq.ctrl_flow.exceptionVec.asUInt,
421    io.enq.ctrl_flow.intrVec.asUInt, io.enq.ctrl_flow.crossPageIPFFix)
422  XSDebug("out: src1Type=%b src2Type=%b src3Type=%b lsrc1=%d lsrc2=%d lsrc3=%d ldest=%d fuType=%b fuOpType=%b\n",
423    io.deq.cf_ctrl.ctrl.src1Type, io.deq.cf_ctrl.ctrl.src2Type, io.deq.cf_ctrl.ctrl.src3Type,
424    io.deq.cf_ctrl.ctrl.lsrc1, io.deq.cf_ctrl.ctrl.lsrc2, io.deq.cf_ctrl.ctrl.lsrc3,
425    io.deq.cf_ctrl.ctrl.ldest, io.deq.cf_ctrl.ctrl.fuType, io.deq.cf_ctrl.ctrl.fuOpType)
426  XSDebug("out: rfWen=%d fpWen=%d isXSTrap=%d noSpecExec=%d isBlocked=%d flushPipe=%d isRVF=%d imm=%x\n",
427    io.deq.cf_ctrl.ctrl.rfWen, io.deq.cf_ctrl.ctrl.fpWen, io.deq.cf_ctrl.ctrl.isXSTrap,
428    io.deq.cf_ctrl.ctrl.noSpecExec, io.deq.cf_ctrl.ctrl.blockBackward, io.deq.cf_ctrl.ctrl.flushPipe,
429    io.deq.cf_ctrl.ctrl.isRVF, io.deq.cf_ctrl.ctrl.imm)
430}
431