文件结构调整
This commit is contained in:
parent
f229789a12
commit
61930afee6
|
@ -3,7 +3,7 @@ import circt.stage._
|
|||
|
||||
object Elaborate extends App {
|
||||
implicit val config = new CpuConfig()
|
||||
def top = new PuaMips()
|
||||
def top = new PuaCpu()
|
||||
val useMFC = false // use MLIR-based firrtl compiler
|
||||
val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top))
|
||||
if (useMFC) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import cache._
|
|||
import cpu._
|
||||
import cpu.defines._
|
||||
|
||||
class PuaMips extends Module {
|
||||
class PuaCpu extends Module {
|
||||
implicit val config = new CpuConfig()
|
||||
val io = IO(new Bundle {
|
||||
val ext_int = Input(UInt(6.W))
|
|
@ -1,194 +1,194 @@
|
|||
package cpu.pipeline.decoder
|
||||
// package cpu.pipeline.decoder
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
// import chisel3._
|
||||
// import chisel3.util._
|
||||
// import cpu.defines._
|
||||
// import cpu.defines.Const._
|
||||
|
||||
class Decoder extends Module {
|
||||
val io = IO(new Bundle {
|
||||
// inputs
|
||||
val in = Input(new Bundle {
|
||||
val inst = UInt(INST_WID.W)
|
||||
})
|
||||
// outputs
|
||||
val out = Output(new InstInfo())
|
||||
})
|
||||
val inst = io.in.inst
|
||||
// class Decoder extends Module {
|
||||
// val io = IO(new Bundle {
|
||||
// // inputs
|
||||
// val in = Input(new Bundle {
|
||||
// val inst = UInt(INST_WID.W)
|
||||
// })
|
||||
// // outputs
|
||||
// val out = Output(new InstInfo())
|
||||
// })
|
||||
// val inst = io.in.inst
|
||||
|
||||
val signals: List[UInt] = ListLookup(
|
||||
//@formatter:off
|
||||
inst,
|
||||
List(INST_INVALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_NOP, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
Array( /* inst_valid | reg1_ren | reg2_ren | fusel | op | reg_wen | reg_waddr | imm_type | dual_issue */
|
||||
// NOP
|
||||
NOP -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_NOP, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// 位操作
|
||||
OR -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_OR, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
AND -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_AND, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
XOR -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_XOR, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
NOR -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_NOR, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// 移位
|
||||
SLLV -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_SLL, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
SRLV -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_SRL, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
SRAV -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_SRA, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
SLL -> List(INST_VALID, READ_DISABLE, READ_ENABLE, FU_ALU, EXE_SLL, WRITE_ENABLE, WRA_T1, IMM_SHT, DUAL_ISSUE),
|
||||
SRL -> List(INST_VALID, READ_DISABLE, READ_ENABLE, FU_ALU, EXE_SRL, WRITE_ENABLE, WRA_T1, IMM_SHT, DUAL_ISSUE),
|
||||
SRA -> List(INST_VALID, READ_DISABLE, READ_ENABLE, FU_ALU, EXE_SRA, WRITE_ENABLE, WRA_T1, IMM_SHT, DUAL_ISSUE),
|
||||
// 立即数
|
||||
ORI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_OR, WRITE_ENABLE, WRA_T2, IMM_LZE, DUAL_ISSUE),
|
||||
ANDI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_AND, WRITE_ENABLE, WRA_T2, IMM_LZE, DUAL_ISSUE),
|
||||
XORI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_XOR, WRITE_ENABLE, WRA_T2, IMM_LZE, DUAL_ISSUE),
|
||||
LUI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_OR, WRITE_ENABLE, WRA_T2, IMM_HZE, DUAL_ISSUE),
|
||||
// val signals: List[UInt] = ListLookup(
|
||||
// //@formatter:off
|
||||
// inst,
|
||||
// List(INST_INVALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_NOP, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// Array( /* inst_valid | reg1_ren | reg2_ren | fusel | op | reg_wen | reg_waddr | imm_type | dual_issue */
|
||||
// // NOP
|
||||
// NOP -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_NOP, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// // 位操作
|
||||
// OR -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_OR, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// AND -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_AND, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// XOR -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_XOR, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// NOR -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_NOR, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// // 移位
|
||||
// SLLV -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_SLL, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// SRLV -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_SRL, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// SRAV -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_SRA, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// SLL -> List(INST_VALID, READ_DISABLE, READ_ENABLE, FU_ALU, EXE_SLL, WRITE_ENABLE, WRA_T1, IMM_SHT, DUAL_ISSUE),
|
||||
// SRL -> List(INST_VALID, READ_DISABLE, READ_ENABLE, FU_ALU, EXE_SRL, WRITE_ENABLE, WRA_T1, IMM_SHT, DUAL_ISSUE),
|
||||
// SRA -> List(INST_VALID, READ_DISABLE, READ_ENABLE, FU_ALU, EXE_SRA, WRITE_ENABLE, WRA_T1, IMM_SHT, DUAL_ISSUE),
|
||||
// // 立即数
|
||||
// ORI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_OR, WRITE_ENABLE, WRA_T2, IMM_LZE, DUAL_ISSUE),
|
||||
// ANDI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_AND, WRITE_ENABLE, WRA_T2, IMM_LZE, DUAL_ISSUE),
|
||||
// XORI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_XOR, WRITE_ENABLE, WRA_T2, IMM_LZE, DUAL_ISSUE),
|
||||
// LUI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_OR, WRITE_ENABLE, WRA_T2, IMM_HZE, DUAL_ISSUE),
|
||||
|
||||
// Move
|
||||
MOVN -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_MOVN, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
MOVZ -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_MOVZ, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// // Move
|
||||
// MOVN -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_MOVN, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// MOVZ -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_MOVZ, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
|
||||
// HI,LO的Move指令
|
||||
MFHI -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_MFHILO, EXE_MFHI, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
MFLO -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_MFHILO, EXE_MFLO, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
MTHI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MTHILO, EXE_MTHI, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
MTLO -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MTHILO, EXE_MTLO, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// // HI,LO的Move指令
|
||||
// MFHI -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_MFHILO, EXE_MFHI, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// MFLO -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_MFHILO, EXE_MFLO, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// MTHI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MTHILO, EXE_MTHI, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// MTLO -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MTHILO, EXE_MTLO, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
|
||||
// C0的Move指令
|
||||
MFC0 -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_MFC0, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
MTC0 -> List(INST_VALID, READ_DISABLE, READ_ENABLE, FU_ALU, EXE_MTC0, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
// // C0的Move指令
|
||||
// MFC0 -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_MFC0, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
// MTC0 -> List(INST_VALID, READ_DISABLE, READ_ENABLE, FU_ALU, EXE_MTC0, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
|
||||
// 比较指令
|
||||
SLT -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_SLT, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
SLTU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_SLTU, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// 立即数
|
||||
SLTI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_SLT, WRITE_ENABLE, WRA_T2, IMM_LSE, DUAL_ISSUE),
|
||||
SLTIU -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_SLTU, WRITE_ENABLE, WRA_T2, IMM_LSE, DUAL_ISSUE),
|
||||
// // 比较指令
|
||||
// SLT -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_SLT, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// SLTU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_SLTU, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// // 立即数
|
||||
// SLTI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_SLT, WRITE_ENABLE, WRA_T2, IMM_LSE, DUAL_ISSUE),
|
||||
// SLTIU -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_SLTU, WRITE_ENABLE, WRA_T2, IMM_LSE, DUAL_ISSUE),
|
||||
|
||||
// Trap
|
||||
TEQ -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_EX, EXE_TEQ, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
TEQI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_EX, EXE_TEQ, WRITE_DISABLE, WRA_X, IMM_LSE, DUAL_ISSUE),
|
||||
TGE -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_EX, EXE_TGE, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
TGEI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_EX, EXE_TGE, WRITE_DISABLE, WRA_X, IMM_LSE, DUAL_ISSUE),
|
||||
TGEIU -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_EX, EXE_TGEU, WRITE_DISABLE, WRA_X, IMM_LSE, DUAL_ISSUE),
|
||||
TGEU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_EX, EXE_TGEU, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
TLT -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_EX, EXE_TLT, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
TLTI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_EX, EXE_TLT, WRITE_DISABLE, WRA_X, IMM_LSE, DUAL_ISSUE),
|
||||
TLTU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_EX, EXE_TLTU, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
TLTIU -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_EX, EXE_TLTU, WRITE_DISABLE, WRA_X, IMM_LSE, DUAL_ISSUE),
|
||||
TNE -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_EX, EXE_TNE, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
TNEI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_EX, EXE_TNE, WRITE_DISABLE, WRA_X, IMM_LSE, DUAL_ISSUE),
|
||||
// // Trap
|
||||
// TEQ -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_EX, EXE_TEQ, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// TEQI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_EX, EXE_TEQ, WRITE_DISABLE, WRA_X, IMM_LSE, DUAL_ISSUE),
|
||||
// TGE -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_EX, EXE_TGE, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// TGEI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_EX, EXE_TGE, WRITE_DISABLE, WRA_X, IMM_LSE, DUAL_ISSUE),
|
||||
// TGEIU -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_EX, EXE_TGEU, WRITE_DISABLE, WRA_X, IMM_LSE, DUAL_ISSUE),
|
||||
// TGEU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_EX, EXE_TGEU, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// TLT -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_EX, EXE_TLT, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// TLTI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_EX, EXE_TLT, WRITE_DISABLE, WRA_X, IMM_LSE, DUAL_ISSUE),
|
||||
// TLTU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_EX, EXE_TLTU, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// TLTIU -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_EX, EXE_TLTU, WRITE_DISABLE, WRA_X, IMM_LSE, DUAL_ISSUE),
|
||||
// TNE -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_EX, EXE_TNE, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// TNEI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_EX, EXE_TNE, WRITE_DISABLE, WRA_X, IMM_LSE, DUAL_ISSUE),
|
||||
|
||||
// 算术指令
|
||||
ADD -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_ADD, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
ADDU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_ADDU, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
SUB -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_SUB, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
SUBU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_SUBU, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
MUL -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MUL, EXE_MUL, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
MULT -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MUL, EXE_MULT, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
MULTU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MUL, EXE_MULTU, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
MADD -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MUL, EXE_MADD, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
MADDU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MUL, EXE_MADDU, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
MSUB -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MUL, EXE_MSUB, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
MSUBU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MUL, EXE_MSUBU, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
DIV -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_DIV, EXE_DIV, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
DIVU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_DIV, EXE_DIVU, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
CLO -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_CLO, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
CLZ -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_CLZ, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// 立即数
|
||||
ADDI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_ADD, WRITE_ENABLE, WRA_T2, IMM_LSE, DUAL_ISSUE),
|
||||
ADDIU -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_ADDU, WRITE_ENABLE, WRA_T2, IMM_LSE, DUAL_ISSUE),
|
||||
// 跳转指令
|
||||
J -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_BR, EXE_J, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
JAL -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_BR, EXE_JAL, WRITE_ENABLE, WRA_T3, IMM_N, DUAL_ISSUE),
|
||||
JR -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_JR, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
JALR -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_JALR, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
BEQ -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_BR, EXE_BEQ, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
BNE -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_BR, EXE_BNE, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
BGTZ -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_BGTZ, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
BLEZ -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_BLEZ, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
BGEZ -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_BGEZ, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
BGEZAL -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_BGEZAL, WRITE_ENABLE, WRA_T3, IMM_N, DUAL_ISSUE),
|
||||
BLTZ -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_BLTZ, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
BLTZAL -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_BLTZAL, WRITE_ENABLE, WRA_T3, IMM_N, DUAL_ISSUE),
|
||||
// // 算术指令
|
||||
// ADD -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_ADD, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// ADDU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_ADDU, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// SUB -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_SUB, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// SUBU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_SUBU, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// MUL -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MUL, EXE_MUL, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// MULT -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MUL, EXE_MULT, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// MULTU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MUL, EXE_MULTU, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// MADD -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MUL, EXE_MADD, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// MADDU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MUL, EXE_MADDU, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// MSUB -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MUL, EXE_MSUB, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// MSUBU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MUL, EXE_MSUBU, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// DIV -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_DIV, EXE_DIV, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// DIVU -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_DIV, EXE_DIVU, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// CLO -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_CLO, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// CLZ -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_CLZ, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// // 立即数
|
||||
// ADDI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_ADD, WRITE_ENABLE, WRA_T2, IMM_LSE, DUAL_ISSUE),
|
||||
// ADDIU -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_ADDU, WRITE_ENABLE, WRA_T2, IMM_LSE, DUAL_ISSUE),
|
||||
// // 跳转指令
|
||||
// J -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_BR, EXE_J, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// JAL -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_BR, EXE_JAL, WRITE_ENABLE, WRA_T3, IMM_N, DUAL_ISSUE),
|
||||
// JR -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_JR, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// JALR -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_JALR, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
|
||||
// BEQ -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_BR, EXE_BEQ, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// BNE -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_BR, EXE_BNE, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// BGTZ -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_BGTZ, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// BLEZ -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_BLEZ, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// BGEZ -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_BGEZ, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// BGEZAL -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_BGEZAL, WRITE_ENABLE, WRA_T3, IMM_N, DUAL_ISSUE),
|
||||
// BLTZ -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_BLTZ, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// BLTZAL -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_BLTZAL, WRITE_ENABLE, WRA_T3, IMM_N, DUAL_ISSUE),
|
||||
|
||||
// TLB
|
||||
TLBP -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_TLBP, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
TLBR -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_TLBR, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
TLBWI -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_TLBWI, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
TLBWR -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_TLBWR, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
// // TLB
|
||||
// TLBP -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_TLBP, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
// TLBR -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_TLBR, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
// TLBWI -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_TLBWI, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
// TLBWR -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_TLBWR, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
|
||||
// 例外指令
|
||||
SYSCALL -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_EX, EXE_SYSCALL, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
BREAK -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_EX, EXE_BREAK, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
ERET -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_EX, EXE_ERET, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
WAIT -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_NOP, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
// // 例外指令
|
||||
// SYSCALL -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_EX, EXE_SYSCALL, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
// BREAK -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_EX, EXE_BREAK, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
// ERET -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_EX, EXE_ERET, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
// WAIT -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_NOP, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
|
||||
// 访存指令
|
||||
LB -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MEM, EXE_LB, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
LBU -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MEM, EXE_LBU, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
LH -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MEM, EXE_LH, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
LHU -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MEM, EXE_LHU, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
LW -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MEM, EXE_LW, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
SB -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_SB, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
SH -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_SH, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
SW -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_SW, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
LWL -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_LWL, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
LWR -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_LWR, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
SWL -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_SWL, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
SWR -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_SWR, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// // 访存指令
|
||||
// LB -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MEM, EXE_LB, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
// LBU -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MEM, EXE_LBU, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
// LH -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MEM, EXE_LH, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
// LHU -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MEM, EXE_LHU, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
// LW -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MEM, EXE_LW, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
// SB -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_SB, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// SH -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_SH, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// SW -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_SW, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// LWL -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_LWL, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
// LWR -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_LWR, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
// SWL -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_SWL, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// SWR -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_SWR, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
|
||||
LL -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MEM, EXE_LL, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
SC -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_SC, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
// LL -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MEM, EXE_LL, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
// SC -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_MEM, EXE_SC, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE),
|
||||
|
||||
SYNC -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_EX, EXE_NOP, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
PREF -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_NOP, WRITE_ENABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
PREFX -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_NOP, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// SYNC -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_EX, EXE_NOP, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// PREF -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_NOP, WRITE_ENABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
// PREFX -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_NOP, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
|
||||
|
||||
// Cache
|
||||
CACHE -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_CACHE, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
),
|
||||
// @formatter:on
|
||||
)
|
||||
val inst_valid :: reg1_ren :: reg2_ren :: fusel :: op :: reg_wen :: reg_waddr_type :: imm_type :: dual_issue :: Nil =
|
||||
signals
|
||||
// // Cache
|
||||
// CACHE -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_CACHE, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
|
||||
// ),
|
||||
// // @formatter:on
|
||||
// )
|
||||
// val inst_valid :: reg1_ren :: reg2_ren :: fusel :: op :: reg_wen :: reg_waddr_type :: imm_type :: dual_issue :: Nil =
|
||||
// signals
|
||||
|
||||
val rt = inst(20, 16)
|
||||
val rd = inst(15, 11)
|
||||
val sa = inst(10, 6)
|
||||
val rs = inst(25, 21)
|
||||
val imm16 = inst(15, 0)
|
||||
// val rt = inst(20, 16)
|
||||
// val rd = inst(15, 11)
|
||||
// val sa = inst(10, 6)
|
||||
// val rs = inst(25, 21)
|
||||
// val imm16 = inst(15, 0)
|
||||
|
||||
io.out.inst_valid := inst_valid
|
||||
io.out.reg1_ren := reg1_ren
|
||||
io.out.reg1_raddr := rs
|
||||
io.out.reg2_ren := reg2_ren
|
||||
io.out.reg2_raddr := rt
|
||||
io.out.fusel := fusel
|
||||
io.out.op := op
|
||||
io.out.reg_wen := reg_wen
|
||||
io.out.reg_waddr := MuxLookup(reg_waddr_type, AREG_31)( // 取"b11111", 即31号寄存器
|
||||
Seq(
|
||||
WRA_T1 -> rd, // 取inst(15,11)
|
||||
WRA_T2 -> rt // 取inst(20,16)
|
||||
)
|
||||
)
|
||||
io.out.imm32 := MuxLookup(imm_type, Util.zeroExtend(sa))( // default IMM_SHT
|
||||
Seq(
|
||||
IMM_LSE -> Util.signedExtend(imm16),
|
||||
IMM_LZE -> Util.zeroExtend(imm16),
|
||||
IMM_HZE -> Cat(imm16, Fill(16, 0.U))
|
||||
)
|
||||
)
|
||||
io.out.cp0_addr := Cat(inst(15, 11), inst(2, 0))
|
||||
io.out.dual_issue := dual_issue
|
||||
io.out.whilo := VecInit(FU_MUL, FU_DIV, FU_MTHILO).contains(fusel) && op =/= EXE_MUL // MUL不写HILO
|
||||
io.out.inst := inst
|
||||
io.out.wmem := fusel === FU_MEM && (!reg_wen.orR || op === EXE_SC)
|
||||
io.out.rmem := fusel === FU_MEM && reg_wen.orR
|
||||
io.out.mul := fusel === FU_MUL
|
||||
io.out.div := fusel === FU_DIV
|
||||
io.out.ifence := inst(16) === 0.U && op === EXE_CACHE
|
||||
io.out.dfence := inst(16) === 1.U && op === EXE_CACHE
|
||||
io.out.tlbfence := VecInit(EXE_MTC0, EXE_TLBWI, EXE_TLBWR).contains(op)
|
||||
io.out.branch_link := VecInit(EXE_JAL, EXE_JALR, EXE_BGEZAL, EXE_BLTZAL).contains(op)
|
||||
io.out.mem_addr := DontCare
|
||||
io.out.mem_wreg := VecInit(EXE_LB, EXE_LBU, EXE_LH, EXE_LHU, EXE_LW, EXE_LL, EXE_LWL, EXE_LWR).contains(op)
|
||||
}
|
||||
// io.out.inst_valid := inst_valid
|
||||
// io.out.reg1_ren := reg1_ren
|
||||
// io.out.reg1_raddr := rs
|
||||
// io.out.reg2_ren := reg2_ren
|
||||
// io.out.reg2_raddr := rt
|
||||
// io.out.fusel := fusel
|
||||
// io.out.op := op
|
||||
// io.out.reg_wen := reg_wen
|
||||
// io.out.reg_waddr := MuxLookup(reg_waddr_type, AREG_31)( // 取"b11111", 即31号寄存器
|
||||
// Seq(
|
||||
// WRA_T1 -> rd, // 取inst(15,11)
|
||||
// WRA_T2 -> rt // 取inst(20,16)
|
||||
// )
|
||||
// )
|
||||
// io.out.imm32 := MuxLookup(imm_type, Util.zeroExtend(sa))( // default IMM_SHT
|
||||
// Seq(
|
||||
// IMM_LSE -> Util.signedExtend(imm16),
|
||||
// IMM_LZE -> Util.zeroExtend(imm16),
|
||||
// IMM_HZE -> Cat(imm16, Fill(16, 0.U))
|
||||
// )
|
||||
// )
|
||||
// io.out.cp0_addr := Cat(inst(15, 11), inst(2, 0))
|
||||
// io.out.dual_issue := dual_issue
|
||||
// io.out.whilo := VecInit(FU_MUL, FU_DIV, FU_MTHILO).contains(fusel) && op =/= EXE_MUL // MUL不写HILO
|
||||
// io.out.inst := inst
|
||||
// io.out.wmem := fusel === FU_MEM && (!reg_wen.orR || op === EXE_SC)
|
||||
// io.out.rmem := fusel === FU_MEM && reg_wen.orR
|
||||
// io.out.mul := fusel === FU_MUL
|
||||
// io.out.div := fusel === FU_DIV
|
||||
// io.out.ifence := inst(16) === 0.U && op === EXE_CACHE
|
||||
// io.out.dfence := inst(16) === 1.U && op === EXE_CACHE
|
||||
// io.out.tlbfence := VecInit(EXE_MTC0, EXE_TLBWI, EXE_TLBWR).contains(op)
|
||||
// io.out.branch_link := VecInit(EXE_JAL, EXE_JALR, EXE_BGEZAL, EXE_BLTZAL).contains(op)
|
||||
// io.out.mem_addr := DontCare
|
||||
// io.out.mem_wreg := VecInit(EXE_LB, EXE_LBU, EXE_LH, EXE_LHU, EXE_LW, EXE_LL, EXE_LWL, EXE_LWR).contains(op)
|
||||
// }
|
||||
|
|
|
@ -1,453 +1,453 @@
|
|||
package cpu.pipeline.execute
|
||||
// package cpu.pipeline.execute
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.pipeline.memory.Cp0Info
|
||||
import cpu.CpuConfig
|
||||
import cpu.pipeline.decoder.Cp0DecoderUnit
|
||||
// import chisel3._
|
||||
// import chisel3.util._
|
||||
// import cpu.defines._
|
||||
// import cpu.defines.Const._
|
||||
// import cpu.pipeline.memory.Cp0Info
|
||||
// import cpu.CpuConfig
|
||||
// import cpu.pipeline.decoder.Cp0DecoderUnit
|
||||
|
||||
class Cp0MemoryUnit(implicit val config: CpuConfig) extends Bundle {
|
||||
val in = Input(new Bundle {
|
||||
val inst = Vec(
|
||||
config.fuNum,
|
||||
new Bundle {
|
||||
val pc = UInt(PC_WID.W)
|
||||
val ex = new ExceptionInfo()
|
||||
}
|
||||
)
|
||||
})
|
||||
val out = Output(new Bundle {
|
||||
val flush = Bool()
|
||||
val flush_pc = UInt(PC_WID.W)
|
||||
})
|
||||
}
|
||||
// class Cp0MemoryUnit(implicit val config: CpuConfig) extends Bundle {
|
||||
// val in = Input(new Bundle {
|
||||
// val inst = Vec(
|
||||
// config.fuNum,
|
||||
// new Bundle {
|
||||
// val pc = UInt(PC_WID.W)
|
||||
// val ex = new ExceptionInfo()
|
||||
// }
|
||||
// )
|
||||
// })
|
||||
// val out = Output(new Bundle {
|
||||
// val flush = Bool()
|
||||
// val flush_pc = UInt(PC_WID.W)
|
||||
// })
|
||||
// }
|
||||
|
||||
class Cp0ExecuteUnit(implicit val config: CpuConfig) extends Bundle {
|
||||
val in = Input(new Bundle {
|
||||
val inst_info = Vec(config.fuNum, new InstInfo())
|
||||
val mtc0_wdata = UInt(DATA_WID.W)
|
||||
})
|
||||
val out = Output(new Bundle {
|
||||
val cp0_rdata = Vec(config.fuNum, UInt(DATA_WID.W))
|
||||
val debug = Output(new Cp0Info())
|
||||
})
|
||||
}
|
||||
// class Cp0ExecuteUnit(implicit val config: CpuConfig) extends Bundle {
|
||||
// val in = Input(new Bundle {
|
||||
// val inst_info = Vec(config.fuNum, new InstInfo())
|
||||
// val mtc0_wdata = UInt(DATA_WID.W)
|
||||
// })
|
||||
// val out = Output(new Bundle {
|
||||
// val cp0_rdata = Vec(config.fuNum, UInt(DATA_WID.W))
|
||||
// val debug = Output(new Cp0Info())
|
||||
// })
|
||||
// }
|
||||
|
||||
class Cp0(implicit val config: CpuConfig) extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val ext_int = Input(UInt(EXT_INT_WID.W))
|
||||
val ctrl = Input(new Bundle {
|
||||
val exe_stall = Bool()
|
||||
val mem_stall = Bool()
|
||||
})
|
||||
val decoderUnit = Output(new Cp0DecoderUnit())
|
||||
val executeUnit = new Cp0ExecuteUnit()
|
||||
val memoryUnit = new Cp0MemoryUnit()
|
||||
val tlb = Vec(
|
||||
2,
|
||||
new Bundle {
|
||||
val vpn2 = Input(UInt(VPN2_WID.W))
|
||||
// class Cp0(implicit val config: CpuConfig) extends Module {
|
||||
// val io = IO(new Bundle {
|
||||
// val ext_int = Input(UInt(EXT_INT_WID.W))
|
||||
// val ctrl = Input(new Bundle {
|
||||
// val exe_stall = Bool()
|
||||
// val mem_stall = Bool()
|
||||
// })
|
||||
// val decoderUnit = Output(new Cp0DecoderUnit())
|
||||
// val executeUnit = new Cp0ExecuteUnit()
|
||||
// val memoryUnit = new Cp0MemoryUnit()
|
||||
// val tlb = Vec(
|
||||
// 2,
|
||||
// new Bundle {
|
||||
// val vpn2 = Input(UInt(VPN2_WID.W))
|
||||
|
||||
val found = Output(Bool())
|
||||
val info = Output(new TlbEntry())
|
||||
}
|
||||
)
|
||||
})
|
||||
// 优先使用inst0的信息
|
||||
val ex_sel = io.memoryUnit.in.inst(0).ex.flush_req || !io.memoryUnit.in.inst(1).ex.flush_req
|
||||
val pc = Mux(ex_sel, io.memoryUnit.in.inst(0).pc, io.memoryUnit.in.inst(1).pc)
|
||||
val ex = Mux(ex_sel, io.memoryUnit.in.inst(0).ex, io.memoryUnit.in.inst(1).ex)
|
||||
val mtc0_wen = io.executeUnit.in.inst_info(0).op === EXE_MTC0
|
||||
val mtc0_wdata = io.executeUnit.in.mtc0_wdata
|
||||
val mtc0_addr = io.executeUnit.in.inst_info(0).cp0_addr
|
||||
val exe_op = io.executeUnit.in.inst_info(0).op
|
||||
val exe_stall = io.ctrl.exe_stall
|
||||
val mem_stall = io.ctrl.mem_stall
|
||||
// val found = Output(Bool())
|
||||
// val info = Output(new TlbEntry())
|
||||
// }
|
||||
// )
|
||||
// })
|
||||
// // 优先使用inst0的信息
|
||||
// val ex_sel = io.memoryUnit.in.inst(0).ex.flush_req || !io.memoryUnit.in.inst(1).ex.flush_req
|
||||
// val pc = Mux(ex_sel, io.memoryUnit.in.inst(0).pc, io.memoryUnit.in.inst(1).pc)
|
||||
// val ex = Mux(ex_sel, io.memoryUnit.in.inst(0).ex, io.memoryUnit.in.inst(1).ex)
|
||||
// val mtc0_wen = io.executeUnit.in.inst_info(0).op === EXE_MTC0
|
||||
// val mtc0_wdata = io.executeUnit.in.mtc0_wdata
|
||||
// val mtc0_addr = io.executeUnit.in.inst_info(0).cp0_addr
|
||||
// val exe_op = io.executeUnit.in.inst_info(0).op
|
||||
// val exe_stall = io.ctrl.exe_stall
|
||||
// val mem_stall = io.ctrl.mem_stall
|
||||
|
||||
val tlb_l2 = Module(new TlbL2()).io
|
||||
// val tlb_l2 = Module(new TlbL2()).io
|
||||
|
||||
tlb_l2.in.tlb1_vpn2 := io.tlb(0).vpn2
|
||||
tlb_l2.in.tlb2_vpn2 := io.tlb(1).vpn2
|
||||
io.tlb(0).found := tlb_l2.out.tlb1_found
|
||||
io.tlb(1).found := tlb_l2.out.tlb2_found
|
||||
io.tlb(0).info := tlb_l2.out.tlb1_entry
|
||||
io.tlb(1).info := tlb_l2.out.tlb2_entry
|
||||
// tlb_l2.in.tlb1_vpn2 := io.tlb(0).vpn2
|
||||
// tlb_l2.in.tlb2_vpn2 := io.tlb(1).vpn2
|
||||
// io.tlb(0).found := tlb_l2.out.tlb1_found
|
||||
// io.tlb(1).found := tlb_l2.out.tlb2_found
|
||||
// io.tlb(0).info := tlb_l2.out.tlb1_entry
|
||||
// io.tlb(1).info := tlb_l2.out.tlb2_entry
|
||||
|
||||
// ---------------cp0-defines-----------------
|
||||
// // ---------------cp0-defines-----------------
|
||||
|
||||
// index register (0,0)
|
||||
val cp0_index = RegInit(0.U.asTypeOf(new Cp0Index()))
|
||||
// // index register (0,0)
|
||||
// val cp0_index = RegInit(0.U.asTypeOf(new Cp0Index()))
|
||||
|
||||
// random register (1,0)
|
||||
val random_init = Wire(new Cp0Random())
|
||||
random_init := 0.U.asTypeOf(new Cp0Random())
|
||||
random_init.random := (TLB_NUM - 1).U
|
||||
val cp0_random = RegInit(random_init)
|
||||
// // random register (1,0)
|
||||
// val random_init = Wire(new Cp0Random())
|
||||
// random_init := 0.U.asTypeOf(new Cp0Random())
|
||||
// random_init.random := (TLB_NUM - 1).U
|
||||
// val cp0_random = RegInit(random_init)
|
||||
|
||||
// entrylo0 register (2,0)
|
||||
val cp0_entrylo0 = RegInit(0.U.asTypeOf(new Cp0EntryLo()))
|
||||
// // entrylo0 register (2,0)
|
||||
// val cp0_entrylo0 = RegInit(0.U.asTypeOf(new Cp0EntryLo()))
|
||||
|
||||
// entrylo1 register (3,0)
|
||||
val cp0_entrylo1 = RegInit(0.U.asTypeOf(new Cp0EntryLo()))
|
||||
// // entrylo1 register (3,0)
|
||||
// val cp0_entrylo1 = RegInit(0.U.asTypeOf(new Cp0EntryLo()))
|
||||
|
||||
// context register (4,0)
|
||||
val cp0_context = RegInit(0.U.asTypeOf(new Cp0Context()))
|
||||
// // context register (4,0)
|
||||
// val cp0_context = RegInit(0.U.asTypeOf(new Cp0Context()))
|
||||
|
||||
// page mask register (5,0)
|
||||
val cp0_pagemask = 0.U
|
||||
// // page mask register (5,0)
|
||||
// val cp0_pagemask = 0.U
|
||||
|
||||
// wired register (6,0)
|
||||
val cp0_wired = RegInit(0.U.asTypeOf(new Cp0Wired()))
|
||||
// // wired register (6,0)
|
||||
// val cp0_wired = RegInit(0.U.asTypeOf(new Cp0Wired()))
|
||||
|
||||
// badvaddr register (8,0)
|
||||
val cp0_badvaddr = RegInit(0.U.asTypeOf(new Cp0BadVAddr()))
|
||||
// // badvaddr register (8,0)
|
||||
// val cp0_badvaddr = RegInit(0.U.asTypeOf(new Cp0BadVAddr()))
|
||||
|
||||
// count register (9,0)
|
||||
val count_init = Wire(new Cp0Count())
|
||||
count_init := 0.U.asTypeOf(new Cp0Count())
|
||||
count_init.count := 1.U
|
||||
val cp0_count = RegInit(count_init)
|
||||
// // count register (9,0)
|
||||
// val count_init = Wire(new Cp0Count())
|
||||
// count_init := 0.U.asTypeOf(new Cp0Count())
|
||||
// count_init.count := 1.U
|
||||
// val cp0_count = RegInit(count_init)
|
||||
|
||||
// entryhi register (10,0)
|
||||
val cp0_entryhi = RegInit(0.U.asTypeOf(new Cp0EntryHi()))
|
||||
// // entryhi register (10,0)
|
||||
// val cp0_entryhi = RegInit(0.U.asTypeOf(new Cp0EntryHi()))
|
||||
|
||||
// compare register (11,0)
|
||||
val cp0_compare = RegInit(0.U.asTypeOf(new Cp0Compare()))
|
||||
// // compare register (11,0)
|
||||
// val cp0_compare = RegInit(0.U.asTypeOf(new Cp0Compare()))
|
||||
|
||||
// status register (12,0)
|
||||
val status_init = Wire(new Cp0Status())
|
||||
status_init := 0.U.asTypeOf(new Cp0Status())
|
||||
status_init.bev := true.B
|
||||
val cp0_status = RegInit(status_init)
|
||||
// // status register (12,0)
|
||||
// val status_init = Wire(new Cp0Status())
|
||||
// status_init := 0.U.asTypeOf(new Cp0Status())
|
||||
// status_init.bev := true.B
|
||||
// val cp0_status = RegInit(status_init)
|
||||
|
||||
// cause register (13,0)
|
||||
val cp0_cause = RegInit(0.U.asTypeOf(new Cp0Cause()))
|
||||
// // cause register (13,0)
|
||||
// val cp0_cause = RegInit(0.U.asTypeOf(new Cp0Cause()))
|
||||
|
||||
// epc register (14,0)
|
||||
val cp0_epc = RegInit(0.U.asTypeOf(new Cp0Epc()))
|
||||
// // epc register (14,0)
|
||||
// val cp0_epc = RegInit(0.U.asTypeOf(new Cp0Epc()))
|
||||
|
||||
// prid register (15,0)
|
||||
val prid = "h_0001_8003".U
|
||||
// // prid register (15,0)
|
||||
// val prid = "h_0001_8003".U
|
||||
|
||||
// ebase register (15,1)
|
||||
val ebase_init = Wire(new Cp0Ebase())
|
||||
ebase_init := 0.U.asTypeOf(new Cp0Ebase())
|
||||
ebase_init.fill := true.B
|
||||
val cp0_ebase = RegInit(ebase_init)
|
||||
// // ebase register (15,1)
|
||||
// val ebase_init = Wire(new Cp0Ebase())
|
||||
// ebase_init := 0.U.asTypeOf(new Cp0Ebase())
|
||||
// ebase_init.fill := true.B
|
||||
// val cp0_ebase = RegInit(ebase_init)
|
||||
|
||||
// config register (16,0)
|
||||
val cp0_config = Wire(new Cp0Config())
|
||||
cp0_config := 0.U.asTypeOf(new Cp0Config())
|
||||
cp0_config.k0 := 3.U
|
||||
cp0_config.mt := 1.U
|
||||
cp0_config.m := true.B
|
||||
// // config register (16,0)
|
||||
// val cp0_config = Wire(new Cp0Config())
|
||||
// cp0_config := 0.U.asTypeOf(new Cp0Config())
|
||||
// cp0_config.k0 := 3.U
|
||||
// cp0_config.mt := 1.U
|
||||
// cp0_config.m := true.B
|
||||
|
||||
// config1 register (16,1)
|
||||
val cp0_config1 = Wire(new Cp0Config1())
|
||||
cp0_config1 := 0.U.asTypeOf(new Cp0Config1())
|
||||
cp0_config1.il := 5.U
|
||||
cp0_config1.ia := 1.U
|
||||
cp0_config1.dl := 5.U
|
||||
cp0_config1.da := 1.U
|
||||
cp0_config1.ms := (TLB_NUM - 1).U
|
||||
// // config1 register (16,1)
|
||||
// val cp0_config1 = Wire(new Cp0Config1())
|
||||
// cp0_config1 := 0.U.asTypeOf(new Cp0Config1())
|
||||
// cp0_config1.il := 5.U
|
||||
// cp0_config1.ia := 1.U
|
||||
// cp0_config1.dl := 5.U
|
||||
// cp0_config1.da := 1.U
|
||||
// cp0_config1.ms := (TLB_NUM - 1).U
|
||||
|
||||
// taglo register (28,0)
|
||||
val cp0_taglo = RegInit(0.U(DATA_WID.W))
|
||||
// // taglo register (28,0)
|
||||
// val cp0_taglo = RegInit(0.U(DATA_WID.W))
|
||||
|
||||
// taghi register (29,0)
|
||||
val cp0_taghi = RegInit(0.U(DATA_WID.W))
|
||||
// // taghi register (29,0)
|
||||
// val cp0_taghi = RegInit(0.U(DATA_WID.W))
|
||||
|
||||
// error epc register (30,0)
|
||||
val cp0_error_epc = RegInit(0.U.asTypeOf(new Cp0Epc()))
|
||||
// // error epc register (30,0)
|
||||
// val cp0_error_epc = RegInit(0.U.asTypeOf(new Cp0Epc()))
|
||||
|
||||
tlb_l2.in.write.en := !exe_stall && (exe_op === EXE_TLBWI || exe_op === EXE_TLBWR)
|
||||
tlb_l2.in.write.index := Mux(exe_op === EXE_TLBWI, cp0_index.index, cp0_random.random)
|
||||
tlb_l2.in.write.entry.asid := cp0_entryhi.asid
|
||||
tlb_l2.in.write.entry.vpn2 := cp0_entryhi.vpn2
|
||||
tlb_l2.in.write.entry.g := cp0_entrylo0.g || cp0_entrylo1.g
|
||||
tlb_l2.in.write.entry.pfn(0) := cp0_entrylo0.pfn
|
||||
tlb_l2.in.write.entry.pfn(1) := cp0_entrylo1.pfn
|
||||
tlb_l2.in.write.entry.c(0) := cp0_entrylo0.c
|
||||
tlb_l2.in.write.entry.c(1) := cp0_entrylo1.c
|
||||
tlb_l2.in.write.entry.d(0) := cp0_entrylo0.d
|
||||
tlb_l2.in.write.entry.d(1) := cp0_entrylo1.d
|
||||
tlb_l2.in.write.entry.v(0) := cp0_entrylo0.v
|
||||
tlb_l2.in.write.entry.v(1) := cp0_entrylo1.v
|
||||
tlb_l2.in.entry_hi.asid := cp0_entryhi.asid
|
||||
tlb_l2.in.entry_hi.vpn2 := cp0_entryhi.vpn2
|
||||
tlb_l2.in.read.index := cp0_index.index
|
||||
// tlb_l2.in.write.en := !exe_stall && (exe_op === EXE_TLBWI || exe_op === EXE_TLBWR)
|
||||
// tlb_l2.in.write.index := Mux(exe_op === EXE_TLBWI, cp0_index.index, cp0_random.random)
|
||||
// tlb_l2.in.write.entry.asid := cp0_entryhi.asid
|
||||
// tlb_l2.in.write.entry.vpn2 := cp0_entryhi.vpn2
|
||||
// tlb_l2.in.write.entry.g := cp0_entrylo0.g || cp0_entrylo1.g
|
||||
// tlb_l2.in.write.entry.pfn(0) := cp0_entrylo0.pfn
|
||||
// tlb_l2.in.write.entry.pfn(1) := cp0_entrylo1.pfn
|
||||
// tlb_l2.in.write.entry.c(0) := cp0_entrylo0.c
|
||||
// tlb_l2.in.write.entry.c(1) := cp0_entrylo1.c
|
||||
// tlb_l2.in.write.entry.d(0) := cp0_entrylo0.d
|
||||
// tlb_l2.in.write.entry.d(1) := cp0_entrylo1.d
|
||||
// tlb_l2.in.write.entry.v(0) := cp0_entrylo0.v
|
||||
// tlb_l2.in.write.entry.v(1) := cp0_entrylo1.v
|
||||
// tlb_l2.in.entry_hi.asid := cp0_entryhi.asid
|
||||
// tlb_l2.in.entry_hi.vpn2 := cp0_entryhi.vpn2
|
||||
// tlb_l2.in.read.index := cp0_index.index
|
||||
|
||||
// index register (0,0)
|
||||
when(!exe_stall) {
|
||||
when(mtc0_wen && mtc0_addr === CP0_INDEX_ADDR) {
|
||||
cp0_index.index := mtc0_wdata(log2Ceil(TLB_NUM) - 1, 0)
|
||||
}.elsewhen(exe_op === EXE_TLBP) {
|
||||
cp0_index.index := Mux(tlb_l2.out.tlb_found, tlb_l2.out.tlb_match_index, cp0_index.index)
|
||||
cp0_index.p := !tlb_l2.out.tlb_found
|
||||
}
|
||||
}
|
||||
// // index register (0,0)
|
||||
// when(!exe_stall) {
|
||||
// when(mtc0_wen && mtc0_addr === CP0_INDEX_ADDR) {
|
||||
// cp0_index.index := mtc0_wdata(log2Ceil(TLB_NUM) - 1, 0)
|
||||
// }.elsewhen(exe_op === EXE_TLBP) {
|
||||
// cp0_index.index := Mux(tlb_l2.out.tlb_found, tlb_l2.out.tlb_match_index, cp0_index.index)
|
||||
// cp0_index.p := !tlb_l2.out.tlb_found
|
||||
// }
|
||||
// }
|
||||
|
||||
// random register (1,0)
|
||||
cp0_random.random := Mux(cp0_random.random === cp0_wired.wired, (TLB_NUM - 1).U, (cp0_random.random - 1.U))
|
||||
// // random register (1,0)
|
||||
// cp0_random.random := Mux(cp0_random.random === cp0_wired.wired, (TLB_NUM - 1).U, (cp0_random.random - 1.U))
|
||||
|
||||
// entrylo0 register (2,0)
|
||||
when(!exe_stall) {
|
||||
when(mtc0_wen && mtc0_addr === CP0_ENTRYLO0_ADDR) {
|
||||
val wdata = mtc0_wdata.asTypeOf(new Cp0EntryLo())
|
||||
cp0_entrylo0.pfn := wdata.pfn
|
||||
cp0_entrylo0.c := wdata.c
|
||||
cp0_entrylo0.d := wdata.d
|
||||
cp0_entrylo0.v := wdata.v
|
||||
cp0_entrylo0.g := wdata.g
|
||||
}.elsewhen(exe_op === EXE_TLBR) {
|
||||
cp0_entrylo0.pfn := tlb_l2.out.read.entry.pfn(0)
|
||||
cp0_entrylo0.g := tlb_l2.out.read.entry.g
|
||||
cp0_entrylo0.c := Cat(1.U((C_WID - 1).W), tlb_l2.out.read.entry.c(0))
|
||||
cp0_entrylo0.d := tlb_l2.out.read.entry.d(0)
|
||||
cp0_entrylo0.v := tlb_l2.out.read.entry.v(0)
|
||||
}
|
||||
}
|
||||
// // entrylo0 register (2,0)
|
||||
// when(!exe_stall) {
|
||||
// when(mtc0_wen && mtc0_addr === CP0_ENTRYLO0_ADDR) {
|
||||
// val wdata = mtc0_wdata.asTypeOf(new Cp0EntryLo())
|
||||
// cp0_entrylo0.pfn := wdata.pfn
|
||||
// cp0_entrylo0.c := wdata.c
|
||||
// cp0_entrylo0.d := wdata.d
|
||||
// cp0_entrylo0.v := wdata.v
|
||||
// cp0_entrylo0.g := wdata.g
|
||||
// }.elsewhen(exe_op === EXE_TLBR) {
|
||||
// cp0_entrylo0.pfn := tlb_l2.out.read.entry.pfn(0)
|
||||
// cp0_entrylo0.g := tlb_l2.out.read.entry.g
|
||||
// cp0_entrylo0.c := Cat(1.U((C_WID - 1).W), tlb_l2.out.read.entry.c(0))
|
||||
// cp0_entrylo0.d := tlb_l2.out.read.entry.d(0)
|
||||
// cp0_entrylo0.v := tlb_l2.out.read.entry.v(0)
|
||||
// }
|
||||
// }
|
||||
|
||||
// entrylo1 register (3,0)
|
||||
when(!exe_stall) {
|
||||
when(mtc0_wen && mtc0_addr === CP0_ENTRYLO1_ADDR) {
|
||||
val wdata = mtc0_wdata.asTypeOf(new Cp0EntryLo())
|
||||
cp0_entrylo1.pfn := wdata.pfn
|
||||
cp0_entrylo1.c := wdata.c
|
||||
cp0_entrylo1.d := wdata.d
|
||||
cp0_entrylo1.v := wdata.v
|
||||
cp0_entrylo1.g := wdata.g
|
||||
}.elsewhen(exe_op === EXE_TLBR) {
|
||||
cp0_entrylo1.pfn := tlb_l2.out.read.entry.pfn(1)
|
||||
cp0_entrylo1.g := tlb_l2.out.read.entry.g
|
||||
cp0_entrylo1.c := Cat(1.U((C_WID - 1).W), tlb_l2.out.read.entry.c(1))
|
||||
cp0_entrylo1.d := tlb_l2.out.read.entry.d(1)
|
||||
cp0_entrylo1.v := tlb_l2.out.read.entry.v(1)
|
||||
}
|
||||
}
|
||||
// // entrylo1 register (3,0)
|
||||
// when(!exe_stall) {
|
||||
// when(mtc0_wen && mtc0_addr === CP0_ENTRYLO1_ADDR) {
|
||||
// val wdata = mtc0_wdata.asTypeOf(new Cp0EntryLo())
|
||||
// cp0_entrylo1.pfn := wdata.pfn
|
||||
// cp0_entrylo1.c := wdata.c
|
||||
// cp0_entrylo1.d := wdata.d
|
||||
// cp0_entrylo1.v := wdata.v
|
||||
// cp0_entrylo1.g := wdata.g
|
||||
// }.elsewhen(exe_op === EXE_TLBR) {
|
||||
// cp0_entrylo1.pfn := tlb_l2.out.read.entry.pfn(1)
|
||||
// cp0_entrylo1.g := tlb_l2.out.read.entry.g
|
||||
// cp0_entrylo1.c := Cat(1.U((C_WID - 1).W), tlb_l2.out.read.entry.c(1))
|
||||
// cp0_entrylo1.d := tlb_l2.out.read.entry.d(1)
|
||||
// cp0_entrylo1.v := tlb_l2.out.read.entry.v(1)
|
||||
// }
|
||||
// }
|
||||
|
||||
// context register (4,0)
|
||||
when(!mem_stall && ex.flush_req) {
|
||||
when(VecInit(EX_TLBL, EX_TLBS, EX_MOD).contains(ex.excode)) {
|
||||
cp0_context.badvpn2 := ex.badvaddr(31, 13)
|
||||
}
|
||||
}.elsewhen(!exe_stall) {
|
||||
when(mtc0_wen && mtc0_addr === CP0_CONTEXT_ADDR) {
|
||||
cp0_context.ptebase := mtc0_wdata.asTypeOf(new Cp0Context()).ptebase
|
||||
}
|
||||
}
|
||||
// // context register (4,0)
|
||||
// when(!mem_stall && ex.flush_req) {
|
||||
// when(VecInit(EX_TLBL, EX_TLBS, EX_MOD).contains(ex.excode)) {
|
||||
// cp0_context.badvpn2 := ex.badvaddr(31, 13)
|
||||
// }
|
||||
// }.elsewhen(!exe_stall) {
|
||||
// when(mtc0_wen && mtc0_addr === CP0_CONTEXT_ADDR) {
|
||||
// cp0_context.ptebase := mtc0_wdata.asTypeOf(new Cp0Context()).ptebase
|
||||
// }
|
||||
// }
|
||||
|
||||
// wired register (6,0)
|
||||
when(!exe_stall) {
|
||||
when(mtc0_wen && mtc0_addr === CP0_WIRED_ADDR) {
|
||||
cp0_wired.wired := mtc0_wdata.asTypeOf(new Cp0Wired()).wired
|
||||
cp0_random.random := (TLB_NUM - 1).U
|
||||
}
|
||||
}
|
||||
// // wired register (6,0)
|
||||
// when(!exe_stall) {
|
||||
// when(mtc0_wen && mtc0_addr === CP0_WIRED_ADDR) {
|
||||
// cp0_wired.wired := mtc0_wdata.asTypeOf(new Cp0Wired()).wired
|
||||
// cp0_random.random := (TLB_NUM - 1).U
|
||||
// }
|
||||
// }
|
||||
|
||||
// badvaddr register (8,0)
|
||||
when(!mem_stall && ex.flush_req) {
|
||||
when(VecInit(EX_ADEL, EX_TLBL, EX_ADES, EX_TLBS, EX_MOD).contains(ex.excode)) {
|
||||
cp0_badvaddr.badvaddr := ex.badvaddr
|
||||
}
|
||||
}
|
||||
// // badvaddr register (8,0)
|
||||
// when(!mem_stall && ex.flush_req) {
|
||||
// when(VecInit(EX_ADEL, EX_TLBL, EX_ADES, EX_TLBS, EX_MOD).contains(ex.excode)) {
|
||||
// cp0_badvaddr.badvaddr := ex.badvaddr
|
||||
// }
|
||||
// }
|
||||
|
||||
// count register (9,0)
|
||||
val tick = RegInit(false.B)
|
||||
tick := !tick
|
||||
when(tick) {
|
||||
cp0_count.count := cp0_count.count + 1.U
|
||||
}
|
||||
when(!exe_stall) {
|
||||
when(mtc0_wen && mtc0_addr === CP0_COUNT_ADDR) {
|
||||
cp0_count.count := mtc0_wdata.asTypeOf(new Cp0Count()).count
|
||||
}
|
||||
}
|
||||
// // count register (9,0)
|
||||
// val tick = RegInit(false.B)
|
||||
// tick := !tick
|
||||
// when(tick) {
|
||||
// cp0_count.count := cp0_count.count + 1.U
|
||||
// }
|
||||
// when(!exe_stall) {
|
||||
// when(mtc0_wen && mtc0_addr === CP0_COUNT_ADDR) {
|
||||
// cp0_count.count := mtc0_wdata.asTypeOf(new Cp0Count()).count
|
||||
// }
|
||||
// }
|
||||
|
||||
// entryhi register (10,0)
|
||||
when(!mem_stall && ex.flush_req) {
|
||||
when(VecInit(EX_TLBL, EX_TLBS, EX_MOD).contains(ex.excode)) {
|
||||
cp0_entryhi.vpn2 := ex.badvaddr(31, 13)
|
||||
}
|
||||
}.elsewhen(!exe_stall) {
|
||||
when(mtc0_wen && mtc0_addr === CP0_ENTRYHI_ADDR) {
|
||||
val wdata = mtc0_wdata.asTypeOf(new Cp0EntryHi())
|
||||
cp0_entryhi.asid := wdata.asid
|
||||
cp0_entryhi.vpn2 := wdata.vpn2
|
||||
}
|
||||
}
|
||||
// // entryhi register (10,0)
|
||||
// when(!mem_stall && ex.flush_req) {
|
||||
// when(VecInit(EX_TLBL, EX_TLBS, EX_MOD).contains(ex.excode)) {
|
||||
// cp0_entryhi.vpn2 := ex.badvaddr(31, 13)
|
||||
// }
|
||||
// }.elsewhen(!exe_stall) {
|
||||
// when(mtc0_wen && mtc0_addr === CP0_ENTRYHI_ADDR) {
|
||||
// val wdata = mtc0_wdata.asTypeOf(new Cp0EntryHi())
|
||||
// cp0_entryhi.asid := wdata.asid
|
||||
// cp0_entryhi.vpn2 := wdata.vpn2
|
||||
// }
|
||||
// }
|
||||
|
||||
// compare register (11,0)
|
||||
when(!exe_stall) {
|
||||
when(mtc0_wen && mtc0_addr === CP0_COMPARE_ADDR) {
|
||||
cp0_compare.compare := mtc0_wdata.asTypeOf(new Cp0Compare()).compare
|
||||
}
|
||||
}
|
||||
// // compare register (11,0)
|
||||
// when(!exe_stall) {
|
||||
// when(mtc0_wen && mtc0_addr === CP0_COMPARE_ADDR) {
|
||||
// cp0_compare.compare := mtc0_wdata.asTypeOf(new Cp0Compare()).compare
|
||||
// }
|
||||
// }
|
||||
|
||||
// status register (12,0)
|
||||
when(!mem_stall && ex.eret) {
|
||||
when(cp0_status.erl) {
|
||||
cp0_status.erl := false.B
|
||||
}.otherwise {
|
||||
cp0_status.exl := false.B
|
||||
}
|
||||
}.elsewhen(!mem_stall && ex.flush_req) {
|
||||
cp0_status.exl := true.B
|
||||
}.elsewhen(!exe_stall) {
|
||||
when(mtc0_wen && mtc0_addr === CP0_STATUS_ADDR) {
|
||||
val wdata = mtc0_wdata.asTypeOf(new Cp0Status())
|
||||
cp0_status.cu0 := wdata.cu0
|
||||
cp0_status.ie := wdata.ie
|
||||
cp0_status.exl := wdata.exl
|
||||
cp0_status.erl := wdata.erl
|
||||
cp0_status.um := wdata.um
|
||||
cp0_status.im := wdata.im
|
||||
cp0_status.bev := wdata.bev
|
||||
}
|
||||
}
|
||||
// // status register (12,0)
|
||||
// when(!mem_stall && ex.eret) {
|
||||
// when(cp0_status.erl) {
|
||||
// cp0_status.erl := false.B
|
||||
// }.otherwise {
|
||||
// cp0_status.exl := false.B
|
||||
// }
|
||||
// }.elsewhen(!mem_stall && ex.flush_req) {
|
||||
// cp0_status.exl := true.B
|
||||
// }.elsewhen(!exe_stall) {
|
||||
// when(mtc0_wen && mtc0_addr === CP0_STATUS_ADDR) {
|
||||
// val wdata = mtc0_wdata.asTypeOf(new Cp0Status())
|
||||
// cp0_status.cu0 := wdata.cu0
|
||||
// cp0_status.ie := wdata.ie
|
||||
// cp0_status.exl := wdata.exl
|
||||
// cp0_status.erl := wdata.erl
|
||||
// cp0_status.um := wdata.um
|
||||
// cp0_status.im := wdata.im
|
||||
// cp0_status.bev := wdata.bev
|
||||
// }
|
||||
// }
|
||||
|
||||
// cause register (13,0)
|
||||
cp0_cause.ip := Cat(
|
||||
cp0_cause.ip(7) || cp0_compare.compare === cp0_count.count || io.ext_int(5), // TODO:此处的ext_int可能不对
|
||||
io.ext_int(4, 0),
|
||||
cp0_cause.ip(1, 0)
|
||||
)
|
||||
when(!mem_stall && ex.flush_req && !ex.eret) {
|
||||
when(!cp0_status.exl) {
|
||||
cp0_cause.bd := ex.bd
|
||||
}
|
||||
cp0_cause.excode := MuxLookup(ex.excode, cp0_cause.excode)(
|
||||
Seq(
|
||||
EX_NO -> EXC_NO,
|
||||
EX_INT -> EXC_INT,
|
||||
EX_MOD -> EXC_MOD,
|
||||
EX_TLBL -> EXC_TLBL,
|
||||
EX_TLBS -> EXC_TLBS,
|
||||
EX_ADEL -> EXC_ADEL,
|
||||
EX_ADES -> EXC_ADES,
|
||||
EX_SYS -> EXC_SYS,
|
||||
EX_BP -> EXC_BP,
|
||||
EX_RI -> EXC_RI,
|
||||
EX_CPU -> EXC_CPU,
|
||||
EX_OV -> EXC_OV
|
||||
)
|
||||
)
|
||||
}.elsewhen(!exe_stall) {
|
||||
when(mtc0_wen) {
|
||||
when(mtc0_addr === CP0_COMPARE_ADDR) {
|
||||
cp0_cause.ip := Cat(false.B, cp0_cause.ip(6, 0))
|
||||
}.elsewhen(mtc0_addr === CP0_CAUSE_ADDR) {
|
||||
val wdata = mtc0_wdata.asTypeOf(new Cp0Cause())
|
||||
cp0_cause.ip := Cat(
|
||||
cp0_cause.ip(7, 2),
|
||||
wdata.ip(1, 0)
|
||||
)
|
||||
cp0_cause.iv := wdata.iv
|
||||
}
|
||||
}
|
||||
}
|
||||
// // cause register (13,0)
|
||||
// cp0_cause.ip := Cat(
|
||||
// cp0_cause.ip(7) || cp0_compare.compare === cp0_count.count || io.ext_int(5), // TODO:此处的ext_int可能不对
|
||||
// io.ext_int(4, 0),
|
||||
// cp0_cause.ip(1, 0)
|
||||
// )
|
||||
// when(!mem_stall && ex.flush_req && !ex.eret) {
|
||||
// when(!cp0_status.exl) {
|
||||
// cp0_cause.bd := ex.bd
|
||||
// }
|
||||
// cp0_cause.excode := MuxLookup(ex.excode, cp0_cause.excode)(
|
||||
// Seq(
|
||||
// EX_NO -> EXC_NO,
|
||||
// EX_INT -> EXC_INT,
|
||||
// EX_MOD -> EXC_MOD,
|
||||
// EX_TLBL -> EXC_TLBL,
|
||||
// EX_TLBS -> EXC_TLBS,
|
||||
// EX_ADEL -> EXC_ADEL,
|
||||
// EX_ADES -> EXC_ADES,
|
||||
// EX_SYS -> EXC_SYS,
|
||||
// EX_BP -> EXC_BP,
|
||||
// EX_RI -> EXC_RI,
|
||||
// EX_CPU -> EXC_CPU,
|
||||
// EX_OV -> EXC_OV
|
||||
// )
|
||||
// )
|
||||
// }.elsewhen(!exe_stall) {
|
||||
// when(mtc0_wen) {
|
||||
// when(mtc0_addr === CP0_COMPARE_ADDR) {
|
||||
// cp0_cause.ip := Cat(false.B, cp0_cause.ip(6, 0))
|
||||
// }.elsewhen(mtc0_addr === CP0_CAUSE_ADDR) {
|
||||
// val wdata = mtc0_wdata.asTypeOf(new Cp0Cause())
|
||||
// cp0_cause.ip := Cat(
|
||||
// cp0_cause.ip(7, 2),
|
||||
// wdata.ip(1, 0)
|
||||
// )
|
||||
// cp0_cause.iv := wdata.iv
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// epc register (14,0)
|
||||
when(!mem_stall && ex.flush_req) {
|
||||
when(!cp0_status.exl) {
|
||||
cp0_epc.epc := Mux(ex.bd, pc - 4.U, pc)
|
||||
}
|
||||
}.elsewhen(!exe_stall) {
|
||||
when(mtc0_wen && mtc0_addr === CP0_EPC_ADDR) {
|
||||
cp0_epc.epc := mtc0_wdata.asTypeOf(new Cp0Epc()).epc
|
||||
}
|
||||
}
|
||||
// // epc register (14,0)
|
||||
// when(!mem_stall && ex.flush_req) {
|
||||
// when(!cp0_status.exl) {
|
||||
// cp0_epc.epc := Mux(ex.bd, pc - 4.U, pc)
|
||||
// }
|
||||
// }.elsewhen(!exe_stall) {
|
||||
// when(mtc0_wen && mtc0_addr === CP0_EPC_ADDR) {
|
||||
// cp0_epc.epc := mtc0_wdata.asTypeOf(new Cp0Epc()).epc
|
||||
// }
|
||||
// }
|
||||
|
||||
// ebase register (15,1)
|
||||
when(!exe_stall) {
|
||||
when(mtc0_wen && mtc0_addr === CP0_EBASE_ADDR) {
|
||||
cp0_ebase.ebase := mtc0_wdata.asTypeOf(new Cp0Ebase()).ebase
|
||||
}
|
||||
}
|
||||
// // ebase register (15,1)
|
||||
// when(!exe_stall) {
|
||||
// when(mtc0_wen && mtc0_addr === CP0_EBASE_ADDR) {
|
||||
// cp0_ebase.ebase := mtc0_wdata.asTypeOf(new Cp0Ebase()).ebase
|
||||
// }
|
||||
// }
|
||||
|
||||
// taglo register (28,0)
|
||||
when(!exe_stall) {
|
||||
when(mtc0_wen && mtc0_addr === CP0_TAGLO_ADDR) {
|
||||
cp0_taglo := mtc0_wdata
|
||||
}
|
||||
}
|
||||
// // taglo register (28,0)
|
||||
// when(!exe_stall) {
|
||||
// when(mtc0_wen && mtc0_addr === CP0_TAGLO_ADDR) {
|
||||
// cp0_taglo := mtc0_wdata
|
||||
// }
|
||||
// }
|
||||
|
||||
// taghi register (29,0)
|
||||
when(!exe_stall) {
|
||||
when(mtc0_wen && mtc0_addr === CP0_TAGHI_ADDR) {
|
||||
cp0_taghi := mtc0_wdata
|
||||
}
|
||||
}
|
||||
// // taghi register (29,0)
|
||||
// when(!exe_stall) {
|
||||
// when(mtc0_wen && mtc0_addr === CP0_TAGHI_ADDR) {
|
||||
// cp0_taghi := mtc0_wdata
|
||||
// }
|
||||
// }
|
||||
|
||||
// error epc register (30,0)
|
||||
when(!exe_stall) {
|
||||
when(mtc0_wen && mtc0_addr === CP0_ERROR_EPC_ADDR) {
|
||||
cp0_error_epc.epc := mtc0_wdata.asTypeOf(new Cp0Epc()).epc
|
||||
}
|
||||
}
|
||||
// // error epc register (30,0)
|
||||
// when(!exe_stall) {
|
||||
// when(mtc0_wen && mtc0_addr === CP0_ERROR_EPC_ADDR) {
|
||||
// cp0_error_epc.epc := mtc0_wdata.asTypeOf(new Cp0Epc()).epc
|
||||
// }
|
||||
// }
|
||||
|
||||
for (i <- 0 until config.fuNum) {
|
||||
io.executeUnit.out.cp0_rdata(i) := MuxLookup(io.executeUnit.in.inst_info(i).cp0_addr, 0.U)(
|
||||
Seq(
|
||||
CP0_INDEX_ADDR -> cp0_index.asUInt,
|
||||
CP0_RANDOM_ADDR -> cp0_random.asUInt,
|
||||
CP0_ENTRYLO0_ADDR -> cp0_entrylo0.asUInt,
|
||||
CP0_ENTRYLO1_ADDR -> cp0_entrylo1.asUInt,
|
||||
CP0_CONTEXT_ADDR -> cp0_context.asUInt,
|
||||
CP0_PAGE_MASK_ADDR -> cp0_pagemask,
|
||||
CP0_WIRED_ADDR -> cp0_wired.asUInt,
|
||||
CP0_BADV_ADDR -> cp0_badvaddr.asUInt,
|
||||
CP0_COUNT_ADDR -> cp0_count.asUInt,
|
||||
CP0_ENTRYHI_ADDR -> cp0_entryhi.asUInt,
|
||||
CP0_COMPARE_ADDR -> cp0_compare.asUInt,
|
||||
CP0_STATUS_ADDR -> cp0_status.asUInt,
|
||||
CP0_CAUSE_ADDR -> cp0_cause.asUInt,
|
||||
CP0_EPC_ADDR -> cp0_epc.asUInt,
|
||||
CP0_PRID_ADDR -> prid,
|
||||
CP0_EBASE_ADDR -> cp0_ebase.asUInt,
|
||||
CP0_CONFIG_ADDR -> cp0_config.asUInt,
|
||||
CP0_CONFIG1_ADDR -> cp0_config1.asUInt,
|
||||
CP0_TAGLO_ADDR -> cp0_taglo,
|
||||
CP0_TAGHI_ADDR -> cp0_taghi,
|
||||
CP0_ERROR_EPC_ADDR -> cp0_error_epc.asUInt
|
||||
)
|
||||
)
|
||||
}
|
||||
io.decoderUnit.cause_ip := cp0_cause.ip
|
||||
io.decoderUnit.status_im := cp0_status.im
|
||||
io.decoderUnit.kernel_mode := (cp0_status.exl && !(ex.eret && cp0_status.erl)) ||
|
||||
(cp0_status.erl && !ex.eret) ||
|
||||
!cp0_status.um ||
|
||||
(ex.flush_req && !ex.eret)
|
||||
io.decoderUnit.access_allowed := io.decoderUnit.kernel_mode || cp0_status.cu0
|
||||
io.decoderUnit.intterupt_allowed := cp0_status.ie && !cp0_status.exl && !cp0_status.erl
|
||||
// for (i <- 0 until config.fuNum) {
|
||||
// io.executeUnit.out.cp0_rdata(i) := MuxLookup(io.executeUnit.in.inst_info(i).cp0_addr, 0.U)(
|
||||
// Seq(
|
||||
// CP0_INDEX_ADDR -> cp0_index.asUInt,
|
||||
// CP0_RANDOM_ADDR -> cp0_random.asUInt,
|
||||
// CP0_ENTRYLO0_ADDR -> cp0_entrylo0.asUInt,
|
||||
// CP0_ENTRYLO1_ADDR -> cp0_entrylo1.asUInt,
|
||||
// CP0_CONTEXT_ADDR -> cp0_context.asUInt,
|
||||
// CP0_PAGE_MASK_ADDR -> cp0_pagemask,
|
||||
// CP0_WIRED_ADDR -> cp0_wired.asUInt,
|
||||
// CP0_BADV_ADDR -> cp0_badvaddr.asUInt,
|
||||
// CP0_COUNT_ADDR -> cp0_count.asUInt,
|
||||
// CP0_ENTRYHI_ADDR -> cp0_entryhi.asUInt,
|
||||
// CP0_COMPARE_ADDR -> cp0_compare.asUInt,
|
||||
// CP0_STATUS_ADDR -> cp0_status.asUInt,
|
||||
// CP0_CAUSE_ADDR -> cp0_cause.asUInt,
|
||||
// CP0_EPC_ADDR -> cp0_epc.asUInt,
|
||||
// CP0_PRID_ADDR -> prid,
|
||||
// CP0_EBASE_ADDR -> cp0_ebase.asUInt,
|
||||
// CP0_CONFIG_ADDR -> cp0_config.asUInt,
|
||||
// CP0_CONFIG1_ADDR -> cp0_config1.asUInt,
|
||||
// CP0_TAGLO_ADDR -> cp0_taglo,
|
||||
// CP0_TAGHI_ADDR -> cp0_taghi,
|
||||
// CP0_ERROR_EPC_ADDR -> cp0_error_epc.asUInt
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
// io.decoderUnit.cause_ip := cp0_cause.ip
|
||||
// io.decoderUnit.status_im := cp0_status.im
|
||||
// io.decoderUnit.kernel_mode := (cp0_status.exl && !(ex.eret && cp0_status.erl)) ||
|
||||
// (cp0_status.erl && !ex.eret) ||
|
||||
// !cp0_status.um ||
|
||||
// (ex.flush_req && !ex.eret)
|
||||
// io.decoderUnit.access_allowed := io.decoderUnit.kernel_mode || cp0_status.cu0
|
||||
// io.decoderUnit.intterupt_allowed := cp0_status.ie && !cp0_status.exl && !cp0_status.erl
|
||||
|
||||
io.executeUnit.out.debug.cp0_cause := cp0_cause.asUInt
|
||||
io.executeUnit.out.debug.cp0_count := cp0_count.asUInt
|
||||
io.executeUnit.out.debug.cp0_random := cp0_random.asUInt
|
||||
// io.executeUnit.out.debug.cp0_cause := cp0_cause.asUInt
|
||||
// io.executeUnit.out.debug.cp0_count := cp0_count.asUInt
|
||||
// io.executeUnit.out.debug.cp0_random := cp0_random.asUInt
|
||||
|
||||
val trap_base = Mux(
|
||||
cp0_status.bev,
|
||||
"hbfc00200".U(PC_WID.W),
|
||||
cp0_ebase.asUInt
|
||||
)
|
||||
io.memoryUnit.out.flush := false.B
|
||||
io.memoryUnit.out.flush_pc := 0.U
|
||||
when(ex.eret) {
|
||||
io.memoryUnit.out.flush := true.B && !io.ctrl.mem_stall
|
||||
io.memoryUnit.out.flush_pc := Mux(cp0_status.erl, cp0_error_epc.epc, cp0_epc.epc)
|
||||
}.elsewhen(ex.flush_req) {
|
||||
io.memoryUnit.out.flush := true.B && !io.ctrl.mem_stall
|
||||
io.memoryUnit.out.flush_pc := Mux(
|
||||
cp0_status.exl,
|
||||
trap_base + "h180".U,
|
||||
trap_base + Mux(
|
||||
ex.excode === EX_INT && cp0_cause.iv && !cp0_status.bev,
|
||||
"h200".U,
|
||||
Mux(ex.tlb_refill && ex.excode =/= EX_INT, 0.U, "h180".U)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
// val trap_base = Mux(
|
||||
// cp0_status.bev,
|
||||
// "hbfc00200".U(PC_WID.W),
|
||||
// cp0_ebase.asUInt
|
||||
// )
|
||||
// io.memoryUnit.out.flush := false.B
|
||||
// io.memoryUnit.out.flush_pc := 0.U
|
||||
// when(ex.eret) {
|
||||
// io.memoryUnit.out.flush := true.B && !io.ctrl.mem_stall
|
||||
// io.memoryUnit.out.flush_pc := Mux(cp0_status.erl, cp0_error_epc.epc, cp0_epc.epc)
|
||||
// }.elsewhen(ex.flush_req) {
|
||||
// io.memoryUnit.out.flush := true.B && !io.ctrl.mem_stall
|
||||
// io.memoryUnit.out.flush_pc := Mux(
|
||||
// cp0_status.exl,
|
||||
// trap_base + "h180".U,
|
||||
// trap_base + Mux(
|
||||
// ex.excode === EX_INT && cp0_cause.iv && !cp0_status.bev,
|
||||
// "h200".U,
|
||||
// Mux(ex.tlb_refill && ex.excode =/= EX_INT, 0.U, "h180".U)
|
||||
// )
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -1,118 +1,118 @@
|
|||
package cpu.pipeline.execute
|
||||
// package cpu.pipeline.execute
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
// import chisel3._
|
||||
// import chisel3.util._
|
||||
// import cpu.defines._
|
||||
// import cpu.defines.Const._
|
||||
// import cpu.CpuConfig
|
||||
|
||||
class Fu(implicit val config: CpuConfig) extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val ctrl = new ExecuteFuCtrl()
|
||||
val inst = Vec(
|
||||
config.decoderNum,
|
||||
new Bundle {
|
||||
val pc = Input(UInt(PC_WID.W))
|
||||
val hilo_wen = Input(Bool())
|
||||
val mul_en = Input(Bool())
|
||||
val div_en = Input(Bool())
|
||||
val inst_info = Input(new InstInfo())
|
||||
val src_info = Input(new SrcInfo())
|
||||
val ex = new Bundle {
|
||||
val in = Input(new ExceptionInfo())
|
||||
val out = Output(new ExceptionInfo())
|
||||
}
|
||||
val result = Output(UInt(DATA_WID.W))
|
||||
},
|
||||
)
|
||||
val cp0_rdata = Input(Vec(config.fuNum, UInt(DATA_WID.W)))
|
||||
val stall_req = Output(Bool())
|
||||
val branch = new Bundle {
|
||||
val pred_branch = Input(Bool())
|
||||
val branch = Output(Bool())
|
||||
val pred_fail = Output(Bool())
|
||||
}
|
||||
val llbit = Output(Bool())
|
||||
// class Fu(implicit val config: CpuConfig) extends Module {
|
||||
// val io = IO(new Bundle {
|
||||
// val ctrl = new ExecuteFuCtrl()
|
||||
// val inst = Vec(
|
||||
// config.decoderNum,
|
||||
// new Bundle {
|
||||
// val pc = Input(UInt(PC_WID.W))
|
||||
// val hilo_wen = Input(Bool())
|
||||
// val mul_en = Input(Bool())
|
||||
// val div_en = Input(Bool())
|
||||
// val inst_info = Input(new InstInfo())
|
||||
// val src_info = Input(new SrcInfo())
|
||||
// val ex = new Bundle {
|
||||
// val in = Input(new ExceptionInfo())
|
||||
// val out = Output(new ExceptionInfo())
|
||||
// }
|
||||
// val result = Output(UInt(DATA_WID.W))
|
||||
// },
|
||||
// )
|
||||
// val cp0_rdata = Input(Vec(config.fuNum, UInt(DATA_WID.W)))
|
||||
// val stall_req = Output(Bool())
|
||||
// val branch = new Bundle {
|
||||
// val pred_branch = Input(Bool())
|
||||
// val branch = Output(Bool())
|
||||
// val pred_fail = Output(Bool())
|
||||
// }
|
||||
// val llbit = Output(Bool())
|
||||
|
||||
val statistic = if (!config.build) Some(new BranchPredictorUnitStatistic()) else None
|
||||
})
|
||||
// val statistic = if (!config.build) Some(new BranchPredictorUnitStatistic()) else None
|
||||
// })
|
||||
|
||||
val alu = Seq.fill(config.decoderNum)(Module(new Alu()))
|
||||
val mul = Module(new Mul()).io
|
||||
val div = Module(new Div()).io
|
||||
val hilo = Module(new HiLo()).io
|
||||
val branchCtrl = Module(new BranchCtrl()).io
|
||||
val llbit = Module(new LLbit()).io
|
||||
// val alu = Seq.fill(config.decoderNum)(Module(new Alu()))
|
||||
// val mul = Module(new Mul()).io
|
||||
// val div = Module(new Div()).io
|
||||
// val hilo = Module(new HiLo()).io
|
||||
// val branchCtrl = Module(new BranchCtrl()).io
|
||||
// val llbit = Module(new LLbit()).io
|
||||
|
||||
branchCtrl.in.inst_info := io.inst(0).inst_info
|
||||
branchCtrl.in.src_info := io.inst(0).src_info
|
||||
branchCtrl.in.pred_branch := io.branch.pred_branch
|
||||
io.branch.branch := branchCtrl.out.branch
|
||||
io.branch.pred_fail := branchCtrl.out.pred_fail
|
||||
// branchCtrl.in.inst_info := io.inst(0).inst_info
|
||||
// branchCtrl.in.src_info := io.inst(0).src_info
|
||||
// branchCtrl.in.pred_branch := io.branch.pred_branch
|
||||
// io.branch.branch := branchCtrl.out.branch
|
||||
// io.branch.pred_fail := branchCtrl.out.pred_fail
|
||||
|
||||
for (i <- 0 until (config.fuNum)) {
|
||||
alu(i).io.inst_info := io.inst(i).inst_info
|
||||
alu(i).io.src_info := io.inst(i).src_info
|
||||
alu(i).io.hilo.rdata := hilo.rdata
|
||||
alu(i).io.mul.result := mul.result
|
||||
alu(i).io.mul.ready := mul.ready
|
||||
alu(i).io.div.ready := div.ready
|
||||
alu(i).io.div.result := div.result
|
||||
alu(i).io.cp0_rdata := io.cp0_rdata(i)
|
||||
alu(i).io.llbit := io.llbit
|
||||
io.inst(i).ex.out := io.inst(i).ex.in
|
||||
io.inst(i).ex.out.flush_req := io.inst(i).ex.in.flush_req || alu(i).io.overflow
|
||||
io.inst(i).ex.out.excode := MuxCase(
|
||||
io.inst(i).ex.in.excode,
|
||||
Seq(
|
||||
(io.inst(i).ex.in.excode =/= EX_NO) -> io.inst(i).ex.in.excode,
|
||||
alu(i).io.overflow -> EX_OV,
|
||||
),
|
||||
)
|
||||
}
|
||||
// for (i <- 0 until (config.fuNum)) {
|
||||
// alu(i).io.inst_info := io.inst(i).inst_info
|
||||
// alu(i).io.src_info := io.inst(i).src_info
|
||||
// alu(i).io.hilo.rdata := hilo.rdata
|
||||
// alu(i).io.mul.result := mul.result
|
||||
// alu(i).io.mul.ready := mul.ready
|
||||
// alu(i).io.div.ready := div.ready
|
||||
// alu(i).io.div.result := div.result
|
||||
// alu(i).io.cp0_rdata := io.cp0_rdata(i)
|
||||
// alu(i).io.llbit := io.llbit
|
||||
// io.inst(i).ex.out := io.inst(i).ex.in
|
||||
// io.inst(i).ex.out.flush_req := io.inst(i).ex.in.flush_req || alu(i).io.overflow
|
||||
// io.inst(i).ex.out.excode := MuxCase(
|
||||
// io.inst(i).ex.in.excode,
|
||||
// Seq(
|
||||
// (io.inst(i).ex.in.excode =/= EX_NO) -> io.inst(i).ex.in.excode,
|
||||
// alu(i).io.overflow -> EX_OV,
|
||||
// ),
|
||||
// )
|
||||
// }
|
||||
|
||||
mul.src1 := Mux(io.inst(0).mul_en, io.inst(0).src_info.src1_data, io.inst(1).src_info.src1_data)
|
||||
mul.src2 := Mux(io.inst(0).mul_en, io.inst(0).src_info.src2_data, io.inst(1).src_info.src2_data)
|
||||
mul.signed := Mux(io.inst(0).mul_en, alu(0).io.mul.signed, alu(1).io.mul.signed)
|
||||
mul.start := Mux(io.inst(0).mul_en, alu(0).io.mul.en, alu(1).io.mul.en)
|
||||
mul.allow_to_go := io.ctrl.allow_to_go
|
||||
// mul.src1 := Mux(io.inst(0).mul_en, io.inst(0).src_info.src1_data, io.inst(1).src_info.src1_data)
|
||||
// mul.src2 := Mux(io.inst(0).mul_en, io.inst(0).src_info.src2_data, io.inst(1).src_info.src2_data)
|
||||
// mul.signed := Mux(io.inst(0).mul_en, alu(0).io.mul.signed, alu(1).io.mul.signed)
|
||||
// mul.start := Mux(io.inst(0).mul_en, alu(0).io.mul.en, alu(1).io.mul.en)
|
||||
// mul.allow_to_go := io.ctrl.allow_to_go
|
||||
|
||||
div.src1 := Mux(io.inst(0).div_en, io.inst(0).src_info.src1_data, io.inst(1).src_info.src1_data)
|
||||
div.src2 := Mux(io.inst(0).div_en, io.inst(0).src_info.src2_data, io.inst(1).src_info.src2_data)
|
||||
div.signed := Mux(io.inst(0).div_en, alu(0).io.div.signed, alu(1).io.div.signed)
|
||||
div.start := Mux(io.inst(0).div_en, alu(0).io.div.en, alu(1).io.div.en)
|
||||
div.allow_to_go := io.ctrl.allow_to_go
|
||||
// div.src1 := Mux(io.inst(0).div_en, io.inst(0).src_info.src1_data, io.inst(1).src_info.src1_data)
|
||||
// div.src2 := Mux(io.inst(0).div_en, io.inst(0).src_info.src2_data, io.inst(1).src_info.src2_data)
|
||||
// div.signed := Mux(io.inst(0).div_en, alu(0).io.div.signed, alu(1).io.div.signed)
|
||||
// div.start := Mux(io.inst(0).div_en, alu(0).io.div.en, alu(1).io.div.en)
|
||||
// div.allow_to_go := io.ctrl.allow_to_go
|
||||
|
||||
io.stall_req := (io.inst.map(_.div_en).reduce(_ || _) && !div.ready) ||
|
||||
(io.inst.map(_.mul_en).reduce(_ || _) && !mul.ready)
|
||||
// io.stall_req := (io.inst.map(_.div_en).reduce(_ || _) && !div.ready) ||
|
||||
// (io.inst.map(_.mul_en).reduce(_ || _) && !mul.ready)
|
||||
|
||||
io.inst(0).result := Mux(
|
||||
io.inst(0).inst_info.branch_link,
|
||||
io.inst(0).pc + 8.U,
|
||||
alu(0).io.result,
|
||||
)
|
||||
io.inst(1).result := alu(1).io.result
|
||||
// io.inst(0).result := Mux(
|
||||
// io.inst(0).inst_info.branch_link,
|
||||
// io.inst(0).pc + 8.U,
|
||||
// alu(0).io.result,
|
||||
// )
|
||||
// io.inst(1).result := alu(1).io.result
|
||||
|
||||
hilo.wen := ((io.inst(1).hilo_wen && !io.inst.map(_.ex.out.flush_req).reduce(_ || _)) ||
|
||||
(io.inst(0).hilo_wen && !io.inst(0).ex.out.flush_req)) && io.ctrl.allow_to_go && !io.ctrl.do_flush
|
||||
hilo.wdata := Mux(io.inst(1).hilo_wen, alu(1).io.hilo.wdata, alu(0).io.hilo.wdata)
|
||||
// hilo.wen := ((io.inst(1).hilo_wen && !io.inst.map(_.ex.out.flush_req).reduce(_ || _)) ||
|
||||
// (io.inst(0).hilo_wen && !io.inst(0).ex.out.flush_req)) && io.ctrl.allow_to_go && !io.ctrl.do_flush
|
||||
// hilo.wdata := Mux(io.inst(1).hilo_wen, alu(1).io.hilo.wdata, alu(0).io.hilo.wdata)
|
||||
|
||||
llbit.do_flush := io.ctrl.eret
|
||||
llbit.wen := (io.inst(0).inst_info.op === EXE_LL || io.inst(0).inst_info.op === EXE_SC ||
|
||||
io.inst(1).inst_info.op === EXE_LL || io.inst(1).inst_info.op === EXE_SC) && io.ctrl.allow_to_go
|
||||
llbit.wdata := io.inst(0).inst_info.op === EXE_LL || io.inst(1).inst_info.op === EXE_LL
|
||||
val llbit_rdata = if (config.build) llbit.rdata else true.B
|
||||
io.llbit := llbit_rdata
|
||||
// llbit.do_flush := io.ctrl.eret
|
||||
// llbit.wen := (io.inst(0).inst_info.op === EXE_LL || io.inst(0).inst_info.op === EXE_SC ||
|
||||
// io.inst(1).inst_info.op === EXE_LL || io.inst(1).inst_info.op === EXE_SC) && io.ctrl.allow_to_go
|
||||
// llbit.wdata := io.inst(0).inst_info.op === EXE_LL || io.inst(1).inst_info.op === EXE_LL
|
||||
// val llbit_rdata = if (config.build) llbit.rdata else true.B
|
||||
// io.llbit := llbit_rdata
|
||||
|
||||
// ===----------------------------------------------------------------===
|
||||
// statistic
|
||||
// ===----------------------------------------------------------------===
|
||||
if (!config.build) {
|
||||
val branch_cnt = RegInit(0.U(32.W))
|
||||
val success_cnt = RegInit(0.U(32.W))
|
||||
when(io.branch.branch) { branch_cnt := branch_cnt + 1.U }
|
||||
when(!io.branch.pred_fail) { success_cnt := success_cnt + 1.U }
|
||||
io.statistic.get.branch := branch_cnt
|
||||
io.statistic.get.success := success_cnt
|
||||
}
|
||||
}
|
||||
// // ===----------------------------------------------------------------===
|
||||
// // statistic
|
||||
// // ===----------------------------------------------------------------===
|
||||
// if (!config.build) {
|
||||
// val branch_cnt = RegInit(0.U(32.W))
|
||||
// val success_cnt = RegInit(0.U(32.W))
|
||||
// when(io.branch.branch) { branch_cnt := branch_cnt + 1.U }
|
||||
// when(!io.branch.pred_fail) { success_cnt := success_cnt + 1.U }
|
||||
// io.statistic.get.branch := branch_cnt
|
||||
// io.statistic.get.success := success_cnt
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
package cpu.pipeline.execute
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines.Const._
|
||||
|
||||
import cpu.defines._
|
||||
class HiLo extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val wen = Input(Bool())
|
||||
val wdata = Input(UInt(HILO_WID.W))
|
||||
val rdata = Output(UInt(HILO_WID.W))
|
||||
})
|
||||
// output
|
||||
val hilo = RegInit(0.U(HILO_WID.W))
|
||||
|
||||
when(io.wen) {
|
||||
hilo := io.wdata
|
||||
}
|
||||
|
||||
io.rdata := hilo
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
package cpu.pipeline.execute
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
||||
class LLbit extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val do_flush = Input(Bool())
|
||||
val wen = Input(Bool())
|
||||
val wdata = Input(Bool())
|
||||
|
||||
val rdata = Output(Bool())
|
||||
})
|
||||
val llbit = RegInit(false.B)
|
||||
|
||||
when(io.do_flush) {
|
||||
llbit := false.B
|
||||
}.elsewhen(io.wen) {
|
||||
llbit := io.wdata
|
||||
}
|
||||
|
||||
io.rdata := llbit
|
||||
}
|
|
@ -1,225 +1,225 @@
|
|||
package cpu.pipeline.execute
|
||||
// package cpu.pipeline.execute
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
// import chisel3._
|
||||
// import chisel3.util._
|
||||
// import cpu.defines._
|
||||
// import cpu.defines.Const._
|
||||
// import cpu.CpuConfig
|
||||
|
||||
class SignedMul extends BlackBox with HasBlackBoxResource {
|
||||
val io = IO(new Bundle {
|
||||
val CLK = Input(Clock())
|
||||
val CE = Input(Bool())
|
||||
val A = Input(UInt((DATA_WID + 1).W))
|
||||
val B = Input(UInt((DATA_WID + 1).W))
|
||||
// class SignedMul extends BlackBox with HasBlackBoxResource {
|
||||
// val io = IO(new Bundle {
|
||||
// val CLK = Input(Clock())
|
||||
// val CE = Input(Bool())
|
||||
// val A = Input(UInt((DATA_WID + 1).W))
|
||||
// val B = Input(UInt((DATA_WID + 1).W))
|
||||
|
||||
val P = Output(UInt((HILO_WID + 2).W))
|
||||
})
|
||||
}
|
||||
|
||||
class Mul(implicit val config: CpuConfig) extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val src1 = Input(UInt(DATA_WID.W))
|
||||
val src2 = Input(UInt(DATA_WID.W))
|
||||
val signed = Input(Bool())
|
||||
val start = Input(Bool())
|
||||
val allow_to_go = Input(Bool())
|
||||
|
||||
val ready = Output(Bool())
|
||||
val result = Output(UInt(HILO_WID.W))
|
||||
})
|
||||
|
||||
if (config.build) {
|
||||
val signedMul = Module(new SignedMul()).io
|
||||
val cnt = RegInit(0.U(log2Ceil(config.mulClockNum + 1).W))
|
||||
|
||||
cnt := MuxCase(
|
||||
cnt,
|
||||
Seq(
|
||||
(io.start && !io.ready) -> (cnt + 1.U),
|
||||
io.allow_to_go -> 0.U,
|
||||
),
|
||||
)
|
||||
|
||||
signedMul.CLK := clock
|
||||
signedMul.CE := io.start
|
||||
when(io.signed) {
|
||||
signedMul.A := Cat(io.src1(DATA_WID - 1), io.src1)
|
||||
signedMul.B := Cat(io.src2(DATA_WID - 1), io.src2)
|
||||
}.otherwise {
|
||||
signedMul.A := Cat(0.U(1.W), io.src1)
|
||||
signedMul.B := Cat(0.U(1.W), io.src2)
|
||||
}
|
||||
io.ready := cnt >= config.mulClockNum.U
|
||||
io.result := signedMul.P(HILO_WID - 1, 0)
|
||||
} else {
|
||||
val cnt = RegInit(0.U(log2Ceil(config.mulClockNum + 1).W))
|
||||
cnt := MuxCase(
|
||||
cnt,
|
||||
Seq(
|
||||
(io.start && !io.ready) -> (cnt + 1.U),
|
||||
io.allow_to_go -> 0.U,
|
||||
),
|
||||
)
|
||||
|
||||
val signed = RegInit(0.U(HILO_WID.W))
|
||||
val unsigned = RegInit(0.U(HILO_WID.W))
|
||||
when(io.start) {
|
||||
signed := (io.src1.asSInt * io.src2.asSInt).asUInt
|
||||
unsigned := io.src1 * io.src2
|
||||
}
|
||||
io.result := Mux(io.signed, signed, unsigned)
|
||||
io.ready := cnt >= config.mulClockNum.U
|
||||
}
|
||||
}
|
||||
|
||||
// class ArrayMulDataModule(len: Int) extends Module {
|
||||
// val io = IO(new Bundle() {
|
||||
// val a, b = Input(UInt(len.W))
|
||||
// val regEnables = Input(Vec(2, Bool()))
|
||||
// val result = Output(UInt((2 * len).W))
|
||||
// val P = Output(UInt((HILO_WID + 2).W))
|
||||
// })
|
||||
// val (a, b) = (io.a, io.b)
|
||||
|
||||
// val b_sext, bx2, neg_b, neg_bx2 = Wire(UInt((len + 1).W))
|
||||
// b_sext := SignExt(b, len + 1)
|
||||
// bx2 := b_sext << 1
|
||||
// neg_b := (~b_sext).asUInt()
|
||||
// neg_bx2 := neg_b << 1
|
||||
|
||||
// val columns: Array[Seq[Bool]] = Array.fill(2 * len)(Seq())
|
||||
|
||||
// var last_x = WireInit(0.U(3.W))
|
||||
// for (i <- Range(0, len, 2)) {
|
||||
// val x = if (i == 0) Cat(a(1, 0), 0.U(1.W)) else if (i + 1 == len) SignExt(a(i, i - 1), 3) else a(i + 1, i - 1)
|
||||
// val pp_temp = MuxLookup(
|
||||
// x,
|
||||
// 0.U,
|
||||
// Seq(
|
||||
// 1.U -> b_sext,
|
||||
// 2.U -> b_sext,
|
||||
// 3.U -> bx2,
|
||||
// 4.U -> neg_bx2,
|
||||
// 5.U -> neg_b,
|
||||
// 6.U -> neg_b,
|
||||
// ),
|
||||
// )
|
||||
// val s = pp_temp(len)
|
||||
// val t = MuxLookup(
|
||||
// last_x,
|
||||
// 0.U(2.W),
|
||||
// Seq(
|
||||
// 4.U -> 2.U(2.W),
|
||||
// 5.U -> 1.U(2.W),
|
||||
// 6.U -> 1.U(2.W),
|
||||
// ),
|
||||
// )
|
||||
// last_x = x
|
||||
// val (pp, weight) = i match {
|
||||
// case 0 =>
|
||||
// (Cat(~s, s, s, pp_temp), 0)
|
||||
// case n if (n == len - 1) || (n == len - 2) =>
|
||||
// (Cat(~s, pp_temp, t), i - 2)
|
||||
// case _ =>
|
||||
// (Cat(1.U(1.W), ~s, pp_temp, t), i - 2)
|
||||
// }
|
||||
// for (j <- columns.indices) {
|
||||
// if (j >= weight && j < (weight + pp.getWidth)) {
|
||||
// columns(j) = columns(j) :+ pp(j - weight)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// def addOneColumn(col: Seq[Bool], cin: Seq[Bool]): (Seq[Bool], Seq[Bool], Seq[Bool]) = {
|
||||
// var sum = Seq[Bool]()
|
||||
// var cout1 = Seq[Bool]()
|
||||
// var cout2 = Seq[Bool]()
|
||||
// col.size match {
|
||||
// case 1 => // do nothing
|
||||
// sum = col ++ cin
|
||||
// case 2 =>
|
||||
// val c22 = Module(new C22)
|
||||
// c22.io.in := col
|
||||
// sum = c22.io.out(0).asBool() +: cin
|
||||
// cout2 = Seq(c22.io.out(1).asBool())
|
||||
// case 3 =>
|
||||
// val c32 = Module(new C32)
|
||||
// c32.io.in := col
|
||||
// sum = c32.io.out(0).asBool() +: cin
|
||||
// cout2 = Seq(c32.io.out(1).asBool())
|
||||
// case 4 =>
|
||||
// val c53 = Module(new C53)
|
||||
// for ((x, y) <- c53.io.in.take(4) zip col) {
|
||||
// x := y
|
||||
// }
|
||||
// c53.io.in.last := (if (cin.nonEmpty) cin.head else 0.U)
|
||||
// sum = Seq(c53.io.out(0).asBool()) ++ (if (cin.nonEmpty) cin.drop(1) else Nil)
|
||||
// cout1 = Seq(c53.io.out(1).asBool())
|
||||
// cout2 = Seq(c53.io.out(2).asBool())
|
||||
// case n =>
|
||||
// val cin_1 = if (cin.nonEmpty) Seq(cin.head) else Nil
|
||||
// val cin_2 = if (cin.nonEmpty) cin.drop(1) else Nil
|
||||
// val (s_1, c_1_1, c_1_2) = addOneColumn(col take 4, cin_1)
|
||||
// val (s_2, c_2_1, c_2_2) = addOneColumn(col drop 4, cin_2)
|
||||
// sum = s_1 ++ s_2
|
||||
// cout1 = c_1_1 ++ c_2_1
|
||||
// cout2 = c_1_2 ++ c_2_2
|
||||
// }
|
||||
// (sum, cout1, cout2)
|
||||
// }
|
||||
|
||||
// def max(in: Iterable[Int]): Int = in.reduce((a, b) => if (a > b) a else b)
|
||||
// def addAll(cols: Array[Seq[Bool]], depth: Int): (UInt, UInt) = {
|
||||
// if (max(cols.map(_.size)) <= 2) {
|
||||
// val sum = Cat(cols.map(_(0)).reverse)
|
||||
// var k = 0
|
||||
// while (cols(k).size == 1) k = k + 1
|
||||
// val carry = Cat(cols.drop(k).map(_(1)).reverse)
|
||||
// (sum, Cat(carry, 0.U(k.W)))
|
||||
// } else {
|
||||
// val columns_next = Array.fill(2 * len)(Seq[Bool]())
|
||||
// var cout1, cout2 = Seq[Bool]()
|
||||
// for (i <- cols.indices) {
|
||||
// val (s, c1, c2) = addOneColumn(cols(i), cout1)
|
||||
// columns_next(i) = s ++ cout2
|
||||
// cout1 = c1
|
||||
// cout2 = c2
|
||||
// }
|
||||
|
||||
// val needReg = depth == 4
|
||||
// val toNextLayer =
|
||||
// if (needReg)
|
||||
// columns_next.map(_.map(x => RegEnable(x, io.regEnables(1))))
|
||||
// else
|
||||
// columns_next
|
||||
|
||||
// addAll(toNextLayer, depth + 1)
|
||||
// }
|
||||
// }
|
||||
|
||||
// val columns_reg = columns.map(col => col.map(b => RegEnable(b, io.regEnables(0))))
|
||||
// val (sum, carry) = addAll(cols = columns_reg, depth = 0)
|
||||
|
||||
// io.result := sum + carry
|
||||
// }
|
||||
|
||||
// class ArrayMultiplier(len: Int) extends Module {
|
||||
// override def latency = 2
|
||||
// class Mul(implicit val config: CpuConfig) extends Module {
|
||||
// val io = IO(new Bundle {
|
||||
// val src1 = Input(UInt(DATA_WID.W))
|
||||
// val src2 = Input(UInt(DATA_WID.W))
|
||||
// val signed = Input(Bool())
|
||||
// val start = Input(Bool())
|
||||
// val allow_to_go = Input(Bool())
|
||||
|
||||
// val mulDataModule = Module(new ArrayMulDataModule(len))
|
||||
// mulDataModule.io.a := io.in.bits.src(0)
|
||||
// mulDataModule.io.b := io.in.bits.src(1)
|
||||
// mulDataModule.io.regEnables := VecInit((1 to latency) map (i => regEnable(i)))
|
||||
// val result = mulDataModule.io.result
|
||||
// val ready = Output(Bool())
|
||||
// val result = Output(UInt(HILO_WID.W))
|
||||
// })
|
||||
|
||||
// var ctrlVec = Seq(ctrl)
|
||||
// for (i <- 1 to latency) {
|
||||
// ctrlVec = ctrlVec :+ PipelineReg(i)(ctrlVec(i - 1))
|
||||
// if (config.build) {
|
||||
// val signedMul = Module(new SignedMul()).io
|
||||
// val cnt = RegInit(0.U(log2Ceil(config.mulClockNum + 1).W))
|
||||
|
||||
// cnt := MuxCase(
|
||||
// cnt,
|
||||
// Seq(
|
||||
// (io.start && !io.ready) -> (cnt + 1.U),
|
||||
// io.allow_to_go -> 0.U,
|
||||
// ),
|
||||
// )
|
||||
|
||||
// signedMul.CLK := clock
|
||||
// signedMul.CE := io.start
|
||||
// when(io.signed) {
|
||||
// signedMul.A := Cat(io.src1(DATA_WID - 1), io.src1)
|
||||
// signedMul.B := Cat(io.src2(DATA_WID - 1), io.src2)
|
||||
// }.otherwise {
|
||||
// signedMul.A := Cat(0.U(1.W), io.src1)
|
||||
// signedMul.B := Cat(0.U(1.W), io.src2)
|
||||
// }
|
||||
// io.ready := cnt >= config.mulClockNum.U
|
||||
// io.result := signedMul.P(HILO_WID - 1, 0)
|
||||
// } else {
|
||||
// val cnt = RegInit(0.U(log2Ceil(config.mulClockNum + 1).W))
|
||||
// cnt := MuxCase(
|
||||
// cnt,
|
||||
// Seq(
|
||||
// (io.start && !io.ready) -> (cnt + 1.U),
|
||||
// io.allow_to_go -> 0.U,
|
||||
// ),
|
||||
// )
|
||||
|
||||
// val signed = RegInit(0.U(HILO_WID.W))
|
||||
// val unsigned = RegInit(0.U(HILO_WID.W))
|
||||
// when(io.start) {
|
||||
// signed := (io.src1.asSInt * io.src2.asSInt).asUInt
|
||||
// unsigned := io.src1 * io.src2
|
||||
// }
|
||||
// io.result := Mux(io.signed, signed, unsigned)
|
||||
// io.ready := cnt >= config.mulClockNum.U
|
||||
// }
|
||||
// val 32 = len - 1
|
||||
// val res = Mux(ctrlVec.last.isHi, result(2 * 32 - 1, 32), result(32 - 1, 0))
|
||||
|
||||
// io.out.bits.data := Mux(ctrlVec.last.isW, SignExt(res(31, 0), 32), res)
|
||||
|
||||
// XSDebug(p"validVec:${Binary(Cat(validVec))} flushVec:${Binary(Cat(flushVec))}\n")
|
||||
// }
|
||||
|
||||
// // class ArrayMulDataModule(len: Int) extends Module {
|
||||
// // val io = IO(new Bundle() {
|
||||
// // val a, b = Input(UInt(len.W))
|
||||
// // val regEnables = Input(Vec(2, Bool()))
|
||||
// // val result = Output(UInt((2 * len).W))
|
||||
// // })
|
||||
// // val (a, b) = (io.a, io.b)
|
||||
|
||||
// // val b_sext, bx2, neg_b, neg_bx2 = Wire(UInt((len + 1).W))
|
||||
// // b_sext := SignExt(b, len + 1)
|
||||
// // bx2 := b_sext << 1
|
||||
// // neg_b := (~b_sext).asUInt()
|
||||
// // neg_bx2 := neg_b << 1
|
||||
|
||||
// // val columns: Array[Seq[Bool]] = Array.fill(2 * len)(Seq())
|
||||
|
||||
// // var last_x = WireInit(0.U(3.W))
|
||||
// // for (i <- Range(0, len, 2)) {
|
||||
// // val x = if (i == 0) Cat(a(1, 0), 0.U(1.W)) else if (i + 1 == len) SignExt(a(i, i - 1), 3) else a(i + 1, i - 1)
|
||||
// // val pp_temp = MuxLookup(
|
||||
// // x,
|
||||
// // 0.U,
|
||||
// // Seq(
|
||||
// // 1.U -> b_sext,
|
||||
// // 2.U -> b_sext,
|
||||
// // 3.U -> bx2,
|
||||
// // 4.U -> neg_bx2,
|
||||
// // 5.U -> neg_b,
|
||||
// // 6.U -> neg_b,
|
||||
// // ),
|
||||
// // )
|
||||
// // val s = pp_temp(len)
|
||||
// // val t = MuxLookup(
|
||||
// // last_x,
|
||||
// // 0.U(2.W),
|
||||
// // Seq(
|
||||
// // 4.U -> 2.U(2.W),
|
||||
// // 5.U -> 1.U(2.W),
|
||||
// // 6.U -> 1.U(2.W),
|
||||
// // ),
|
||||
// // )
|
||||
// // last_x = x
|
||||
// // val (pp, weight) = i match {
|
||||
// // case 0 =>
|
||||
// // (Cat(~s, s, s, pp_temp), 0)
|
||||
// // case n if (n == len - 1) || (n == len - 2) =>
|
||||
// // (Cat(~s, pp_temp, t), i - 2)
|
||||
// // case _ =>
|
||||
// // (Cat(1.U(1.W), ~s, pp_temp, t), i - 2)
|
||||
// // }
|
||||
// // for (j <- columns.indices) {
|
||||
// // if (j >= weight && j < (weight + pp.getWidth)) {
|
||||
// // columns(j) = columns(j) :+ pp(j - weight)
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// // def addOneColumn(col: Seq[Bool], cin: Seq[Bool]): (Seq[Bool], Seq[Bool], Seq[Bool]) = {
|
||||
// // var sum = Seq[Bool]()
|
||||
// // var cout1 = Seq[Bool]()
|
||||
// // var cout2 = Seq[Bool]()
|
||||
// // col.size match {
|
||||
// // case 1 => // do nothing
|
||||
// // sum = col ++ cin
|
||||
// // case 2 =>
|
||||
// // val c22 = Module(new C22)
|
||||
// // c22.io.in := col
|
||||
// // sum = c22.io.out(0).asBool() +: cin
|
||||
// // cout2 = Seq(c22.io.out(1).asBool())
|
||||
// // case 3 =>
|
||||
// // val c32 = Module(new C32)
|
||||
// // c32.io.in := col
|
||||
// // sum = c32.io.out(0).asBool() +: cin
|
||||
// // cout2 = Seq(c32.io.out(1).asBool())
|
||||
// // case 4 =>
|
||||
// // val c53 = Module(new C53)
|
||||
// // for ((x, y) <- c53.io.in.take(4) zip col) {
|
||||
// // x := y
|
||||
// // }
|
||||
// // c53.io.in.last := (if (cin.nonEmpty) cin.head else 0.U)
|
||||
// // sum = Seq(c53.io.out(0).asBool()) ++ (if (cin.nonEmpty) cin.drop(1) else Nil)
|
||||
// // cout1 = Seq(c53.io.out(1).asBool())
|
||||
// // cout2 = Seq(c53.io.out(2).asBool())
|
||||
// // case n =>
|
||||
// // val cin_1 = if (cin.nonEmpty) Seq(cin.head) else Nil
|
||||
// // val cin_2 = if (cin.nonEmpty) cin.drop(1) else Nil
|
||||
// // val (s_1, c_1_1, c_1_2) = addOneColumn(col take 4, cin_1)
|
||||
// // val (s_2, c_2_1, c_2_2) = addOneColumn(col drop 4, cin_2)
|
||||
// // sum = s_1 ++ s_2
|
||||
// // cout1 = c_1_1 ++ c_2_1
|
||||
// // cout2 = c_1_2 ++ c_2_2
|
||||
// // }
|
||||
// // (sum, cout1, cout2)
|
||||
// // }
|
||||
|
||||
// // def max(in: Iterable[Int]): Int = in.reduce((a, b) => if (a > b) a else b)
|
||||
// // def addAll(cols: Array[Seq[Bool]], depth: Int): (UInt, UInt) = {
|
||||
// // if (max(cols.map(_.size)) <= 2) {
|
||||
// // val sum = Cat(cols.map(_(0)).reverse)
|
||||
// // var k = 0
|
||||
// // while (cols(k).size == 1) k = k + 1
|
||||
// // val carry = Cat(cols.drop(k).map(_(1)).reverse)
|
||||
// // (sum, Cat(carry, 0.U(k.W)))
|
||||
// // } else {
|
||||
// // val columns_next = Array.fill(2 * len)(Seq[Bool]())
|
||||
// // var cout1, cout2 = Seq[Bool]()
|
||||
// // for (i <- cols.indices) {
|
||||
// // val (s, c1, c2) = addOneColumn(cols(i), cout1)
|
||||
// // columns_next(i) = s ++ cout2
|
||||
// // cout1 = c1
|
||||
// // cout2 = c2
|
||||
// // }
|
||||
|
||||
// // val needReg = depth == 4
|
||||
// // val toNextLayer =
|
||||
// // if (needReg)
|
||||
// // columns_next.map(_.map(x => RegEnable(x, io.regEnables(1))))
|
||||
// // else
|
||||
// // columns_next
|
||||
|
||||
// // addAll(toNextLayer, depth + 1)
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// // val columns_reg = columns.map(col => col.map(b => RegEnable(b, io.regEnables(0))))
|
||||
// // val (sum, carry) = addAll(cols = columns_reg, depth = 0)
|
||||
|
||||
// // io.result := sum + carry
|
||||
// // }
|
||||
|
||||
// // class ArrayMultiplier(len: Int) extends Module {
|
||||
// // override def latency = 2
|
||||
|
||||
// // val mulDataModule = Module(new ArrayMulDataModule(len))
|
||||
// // mulDataModule.io.a := io.in.bits.src(0)
|
||||
// // mulDataModule.io.b := io.in.bits.src(1)
|
||||
// // mulDataModule.io.regEnables := VecInit((1 to latency) map (i => regEnable(i)))
|
||||
// // val result = mulDataModule.io.result
|
||||
|
||||
// // var ctrlVec = Seq(ctrl)
|
||||
// // for (i <- 1 to latency) {
|
||||
// // ctrlVec = ctrlVec :+ PipelineReg(i)(ctrlVec(i - 1))
|
||||
// // }
|
||||
// // val 32 = len - 1
|
||||
// // val res = Mux(ctrlVec.last.isHi, result(2 * 32 - 1, 32), result(32 - 1, 0))
|
||||
|
||||
// // io.out.bits.data := Mux(ctrlVec.last.isW, SignExt(res(31, 0), 32), res)
|
||||
|
||||
// // XSDebug(p"validVec:${Binary(Cat(validVec))} flushVec:${Binary(Cat(flushVec))}\n")
|
||||
// // }
|
||||
|
|
Loading…
Reference in New Issue