文件结构调整

This commit is contained in:
Liphen 2023-11-13 20:10:19 +08:00
parent f229789a12
commit 61930afee6
8 changed files with 902 additions and 947 deletions

View File

@ -3,7 +3,7 @@ import circt.stage._
object Elaborate extends App { object Elaborate extends App {
implicit val config = new CpuConfig() implicit val config = new CpuConfig()
def top = new PuaMips() def top = new PuaCpu()
val useMFC = false // use MLIR-based firrtl compiler val useMFC = false // use MLIR-based firrtl compiler
val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top)) val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top))
if (useMFC) { if (useMFC) {

View File

@ -4,7 +4,7 @@ import cache._
import cpu._ import cpu._
import cpu.defines._ import cpu.defines._
class PuaMips extends Module { class PuaCpu extends Module {
implicit val config = new CpuConfig() implicit val config = new CpuConfig()
val io = IO(new Bundle { val io = IO(new Bundle {
val ext_int = Input(UInt(6.W)) val ext_int = Input(UInt(6.W))

View File

@ -1,194 +1,194 @@
package cpu.pipeline.decoder // package cpu.pipeline.decoder
import chisel3._ // import chisel3._
import chisel3.util._ // import chisel3.util._
import cpu.defines._ // import cpu.defines._
import cpu.defines.Const._ // import cpu.defines.Const._
class Decoder extends Module { // class Decoder extends Module {
val io = IO(new Bundle { // val io = IO(new Bundle {
// inputs // // inputs
val in = Input(new Bundle { // val in = Input(new Bundle {
val inst = UInt(INST_WID.W) // val inst = UInt(INST_WID.W)
}) // })
// outputs // // outputs
val out = Output(new InstInfo()) // val out = Output(new InstInfo())
}) // })
val inst = io.in.inst // val inst = io.in.inst
val signals: List[UInt] = ListLookup( // val signals: List[UInt] = ListLookup(
//@formatter:off // //@formatter:off
inst, // inst,
List(INST_INVALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_NOP, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE), // 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 */ // Array( /* inst_valid | reg1_ren | reg2_ren | fusel | op | reg_wen | reg_waddr | imm_type | dual_issue */
// NOP // // NOP
NOP -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_NOP, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // LUI -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_OR, WRITE_ENABLE, WRA_T2, IMM_HZE, DUAL_ISSUE),
// Move // // Move
MOVN -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_MOVN, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE), // 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), // MOVZ -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_ALU, EXE_MOVZ, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE),
// HILO的Move指令 // // HILO的Move指令
MFHI -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_MFHILO, EXE_MFHI, WRITE_ENABLE, WRA_T1, IMM_N, DUAL_ISSUE), // 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), // 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), // 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), // MTLO -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_MTHILO, EXE_MTLO, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
// C0的Move指令 // // C0的Move指令
MFC0 -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_MFC0, WRITE_ENABLE, WRA_T2, IMM_N, DUAL_ISSUE), // 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), // 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), // 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), // 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), // 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), // SLTIU -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_SLTU, WRITE_ENABLE, WRA_T2, IMM_LSE, DUAL_ISSUE),
// Trap // // Trap
TEQ -> List(INST_VALID, READ_ENABLE, READ_ENABLE, FU_EX, EXE_TEQ, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // BLTZAL -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_BR, EXE_BLTZAL, WRITE_ENABLE, WRA_T3, IMM_N, DUAL_ISSUE),
// TLB // // TLB
TLBP -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_TLBP, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // 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), // PREFX -> List(INST_VALID, READ_DISABLE, READ_DISABLE, FU_ALU, EXE_NOP, WRITE_DISABLE, WRA_X, IMM_N, DUAL_ISSUE),
// Cache // // Cache
CACHE -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_CACHE, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE), // CACHE -> List(INST_VALID, READ_ENABLE, READ_DISABLE, FU_ALU, EXE_CACHE, WRITE_DISABLE, WRA_X, IMM_N, SINGLE_ISSUE),
), // ),
// @formatter:on // // @formatter:on
) // )
val inst_valid :: reg1_ren :: reg2_ren :: fusel :: op :: reg_wen :: reg_waddr_type :: imm_type :: dual_issue :: Nil = // val inst_valid :: reg1_ren :: reg2_ren :: fusel :: op :: reg_wen :: reg_waddr_type :: imm_type :: dual_issue :: Nil =
signals // signals
val rt = inst(20, 16) // val rt = inst(20, 16)
val rd = inst(15, 11) // val rd = inst(15, 11)
val sa = inst(10, 6) // val sa = inst(10, 6)
val rs = inst(25, 21) // val rs = inst(25, 21)
val imm16 = inst(15, 0) // val imm16 = inst(15, 0)
io.out.inst_valid := inst_valid // io.out.inst_valid := inst_valid
io.out.reg1_ren := reg1_ren // io.out.reg1_ren := reg1_ren
io.out.reg1_raddr := rs // io.out.reg1_raddr := rs
io.out.reg2_ren := reg2_ren // io.out.reg2_ren := reg2_ren
io.out.reg2_raddr := rt // io.out.reg2_raddr := rt
io.out.fusel := fusel // io.out.fusel := fusel
io.out.op := op // io.out.op := op
io.out.reg_wen := reg_wen // io.out.reg_wen := reg_wen
io.out.reg_waddr := MuxLookup(reg_waddr_type, AREG_31)( // "b11111", 即31号寄存器 // io.out.reg_waddr := MuxLookup(reg_waddr_type, AREG_31)( // "b11111", 即31号寄存器
Seq( // Seq(
WRA_T1 -> rd, // 取inst(15,11) // WRA_T1 -> rd, // 取inst(15,11)
WRA_T2 -> rt // 取inst(20,16) // WRA_T2 -> rt // 取inst(20,16)
) // )
) // )
io.out.imm32 := MuxLookup(imm_type, Util.zeroExtend(sa))( // default IMM_SHT // io.out.imm32 := MuxLookup(imm_type, Util.zeroExtend(sa))( // default IMM_SHT
Seq( // Seq(
IMM_LSE -> Util.signedExtend(imm16), // IMM_LSE -> Util.signedExtend(imm16),
IMM_LZE -> Util.zeroExtend(imm16), // IMM_LZE -> Util.zeroExtend(imm16),
IMM_HZE -> Cat(imm16, Fill(16, 0.U)) // IMM_HZE -> Cat(imm16, Fill(16, 0.U))
) // )
) // )
io.out.cp0_addr := Cat(inst(15, 11), inst(2, 0)) // io.out.cp0_addr := Cat(inst(15, 11), inst(2, 0))
io.out.dual_issue := dual_issue // 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.whilo := VecInit(FU_MUL, FU_DIV, FU_MTHILO).contains(fusel) && op =/= EXE_MUL // MUL不写HILO
io.out.inst := inst // io.out.inst := inst
io.out.wmem := fusel === FU_MEM && (!reg_wen.orR || op === EXE_SC) // io.out.wmem := fusel === FU_MEM && (!reg_wen.orR || op === EXE_SC)
io.out.rmem := fusel === FU_MEM && reg_wen.orR // io.out.rmem := fusel === FU_MEM && reg_wen.orR
io.out.mul := fusel === FU_MUL // io.out.mul := fusel === FU_MUL
io.out.div := fusel === FU_DIV // io.out.div := fusel === FU_DIV
io.out.ifence := inst(16) === 0.U && op === EXE_CACHE // io.out.ifence := inst(16) === 0.U && op === EXE_CACHE
io.out.dfence := inst(16) === 1.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.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.branch_link := VecInit(EXE_JAL, EXE_JALR, EXE_BGEZAL, EXE_BLTZAL).contains(op)
io.out.mem_addr := DontCare // 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.mem_wreg := VecInit(EXE_LB, EXE_LBU, EXE_LH, EXE_LHU, EXE_LW, EXE_LL, EXE_LWL, EXE_LWR).contains(op)
} // }

View File

@ -1,453 +1,453 @@
package cpu.pipeline.execute // package cpu.pipeline.execute
import chisel3._ // import chisel3._
import chisel3.util._ // import chisel3.util._
import cpu.defines._ // import cpu.defines._
import cpu.defines.Const._ // import cpu.defines.Const._
import cpu.pipeline.memory.Cp0Info // import cpu.pipeline.memory.Cp0Info
import cpu.CpuConfig // import cpu.CpuConfig
import cpu.pipeline.decoder.Cp0DecoderUnit // import cpu.pipeline.decoder.Cp0DecoderUnit
class Cp0MemoryUnit(implicit val config: CpuConfig) extends Bundle { // class Cp0MemoryUnit(implicit val config: CpuConfig) extends Bundle {
val in = Input(new Bundle { // val in = Input(new Bundle {
val inst = Vec( // val inst = Vec(
config.fuNum, // config.fuNum,
new Bundle { // new Bundle {
val pc = UInt(PC_WID.W) // val pc = UInt(PC_WID.W)
val ex = new ExceptionInfo() // val ex = new ExceptionInfo()
} // }
) // )
}) // })
val out = Output(new Bundle { // val out = Output(new Bundle {
val flush = Bool() // val flush = Bool()
val flush_pc = UInt(PC_WID.W) // val flush_pc = UInt(PC_WID.W)
}) // })
} // }
class Cp0ExecuteUnit(implicit val config: CpuConfig) extends Bundle { // class Cp0ExecuteUnit(implicit val config: CpuConfig) extends Bundle {
val in = Input(new Bundle { // val in = Input(new Bundle {
val inst_info = Vec(config.fuNum, new InstInfo()) // val inst_info = Vec(config.fuNum, new InstInfo())
val mtc0_wdata = UInt(DATA_WID.W) // val mtc0_wdata = UInt(DATA_WID.W)
}) // })
val out = Output(new Bundle { // val out = Output(new Bundle {
val cp0_rdata = Vec(config.fuNum, UInt(DATA_WID.W)) // val cp0_rdata = Vec(config.fuNum, UInt(DATA_WID.W))
val debug = Output(new Cp0Info()) // val debug = Output(new Cp0Info())
}) // })
} // }
class Cp0(implicit val config: CpuConfig) extends Module { // class Cp0(implicit val config: CpuConfig) extends Module {
val io = IO(new Bundle { // val io = IO(new Bundle {
val ext_int = Input(UInt(EXT_INT_WID.W)) // val ext_int = Input(UInt(EXT_INT_WID.W))
val ctrl = Input(new Bundle { // val ctrl = Input(new Bundle {
val exe_stall = Bool() // val exe_stall = Bool()
val mem_stall = Bool() // val mem_stall = Bool()
}) // })
val decoderUnit = Output(new Cp0DecoderUnit()) // val decoderUnit = Output(new Cp0DecoderUnit())
val executeUnit = new Cp0ExecuteUnit() // val executeUnit = new Cp0ExecuteUnit()
val memoryUnit = new Cp0MemoryUnit() // val memoryUnit = new Cp0MemoryUnit()
val tlb = Vec( // val tlb = Vec(
2, // 2,
new Bundle { // new Bundle {
val vpn2 = Input(UInt(VPN2_WID.W)) // val vpn2 = Input(UInt(VPN2_WID.W))
val found = Output(Bool()) // val found = Output(Bool())
val info = Output(new TlbEntry()) // val info = Output(new TlbEntry())
} // }
) // )
}) // })
// 优先使用inst0的信息 // // 优先使用inst0的信息
val ex_sel = io.memoryUnit.in.inst(0).ex.flush_req || !io.memoryUnit.in.inst(1).ex.flush_req // 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 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 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_wen = io.executeUnit.in.inst_info(0).op === EXE_MTC0
val mtc0_wdata = io.executeUnit.in.mtc0_wdata // val mtc0_wdata = io.executeUnit.in.mtc0_wdata
val mtc0_addr = io.executeUnit.in.inst_info(0).cp0_addr // val mtc0_addr = io.executeUnit.in.inst_info(0).cp0_addr
val exe_op = io.executeUnit.in.inst_info(0).op // val exe_op = io.executeUnit.in.inst_info(0).op
val exe_stall = io.ctrl.exe_stall // val exe_stall = io.ctrl.exe_stall
val mem_stall = io.ctrl.mem_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.tlb1_vpn2 := io.tlb(0).vpn2
tlb_l2.in.tlb2_vpn2 := io.tlb(1).vpn2 // tlb_l2.in.tlb2_vpn2 := io.tlb(1).vpn2
io.tlb(0).found := tlb_l2.out.tlb1_found // io.tlb(0).found := tlb_l2.out.tlb1_found
io.tlb(1).found := tlb_l2.out.tlb2_found // io.tlb(1).found := tlb_l2.out.tlb2_found
io.tlb(0).info := tlb_l2.out.tlb1_entry // io.tlb(0).info := tlb_l2.out.tlb1_entry
io.tlb(1).info := tlb_l2.out.tlb2_entry // io.tlb(1).info := tlb_l2.out.tlb2_entry
// ---------------cp0-defines----------------- // // ---------------cp0-defines-----------------
// index register (0,0) // // index register (0,0)
val cp0_index = RegInit(0.U.asTypeOf(new Cp0Index())) // val cp0_index = RegInit(0.U.asTypeOf(new Cp0Index()))
// random register (1,0) // // random register (1,0)
val random_init = Wire(new Cp0Random()) // val random_init = Wire(new Cp0Random())
random_init := 0.U.asTypeOf(new Cp0Random()) // random_init := 0.U.asTypeOf(new Cp0Random())
random_init.random := (TLB_NUM - 1).U // random_init.random := (TLB_NUM - 1).U
val cp0_random = RegInit(random_init) // val cp0_random = RegInit(random_init)
// entrylo0 register (2,0) // // entrylo0 register (2,0)
val cp0_entrylo0 = RegInit(0.U.asTypeOf(new Cp0EntryLo())) // val cp0_entrylo0 = RegInit(0.U.asTypeOf(new Cp0EntryLo()))
// entrylo1 register (3,0) // // entrylo1 register (3,0)
val cp0_entrylo1 = RegInit(0.U.asTypeOf(new Cp0EntryLo())) // val cp0_entrylo1 = RegInit(0.U.asTypeOf(new Cp0EntryLo()))
// context register (4,0) // // context register (4,0)
val cp0_context = RegInit(0.U.asTypeOf(new Cp0Context())) // val cp0_context = RegInit(0.U.asTypeOf(new Cp0Context()))
// page mask register (5,0) // // page mask register (5,0)
val cp0_pagemask = 0.U // val cp0_pagemask = 0.U
// wired register (6,0) // // wired register (6,0)
val cp0_wired = RegInit(0.U.asTypeOf(new Cp0Wired())) // val cp0_wired = RegInit(0.U.asTypeOf(new Cp0Wired()))
// badvaddr register (8,0) // // badvaddr register (8,0)
val cp0_badvaddr = RegInit(0.U.asTypeOf(new Cp0BadVAddr())) // val cp0_badvaddr = RegInit(0.U.asTypeOf(new Cp0BadVAddr()))
// count register (9,0) // // count register (9,0)
val count_init = Wire(new Cp0Count()) // val count_init = Wire(new Cp0Count())
count_init := 0.U.asTypeOf(new Cp0Count()) // count_init := 0.U.asTypeOf(new Cp0Count())
count_init.count := 1.U // count_init.count := 1.U
val cp0_count = RegInit(count_init) // val cp0_count = RegInit(count_init)
// entryhi register (10,0) // // entryhi register (10,0)
val cp0_entryhi = RegInit(0.U.asTypeOf(new Cp0EntryHi())) // val cp0_entryhi = RegInit(0.U.asTypeOf(new Cp0EntryHi()))
// compare register (11,0) // // compare register (11,0)
val cp0_compare = RegInit(0.U.asTypeOf(new Cp0Compare())) // val cp0_compare = RegInit(0.U.asTypeOf(new Cp0Compare()))
// status register (12,0) // // status register (12,0)
val status_init = Wire(new Cp0Status()) // val status_init = Wire(new Cp0Status())
status_init := 0.U.asTypeOf(new Cp0Status()) // status_init := 0.U.asTypeOf(new Cp0Status())
status_init.bev := true.B // status_init.bev := true.B
val cp0_status = RegInit(status_init) // val cp0_status = RegInit(status_init)
// cause register (13,0) // // cause register (13,0)
val cp0_cause = RegInit(0.U.asTypeOf(new Cp0Cause())) // val cp0_cause = RegInit(0.U.asTypeOf(new Cp0Cause()))
// epc register (14,0) // // epc register (14,0)
val cp0_epc = RegInit(0.U.asTypeOf(new Cp0Epc())) // val cp0_epc = RegInit(0.U.asTypeOf(new Cp0Epc()))
// prid register (15,0) // // prid register (15,0)
val prid = "h_0001_8003".U // val prid = "h_0001_8003".U
// ebase register (15,1) // // ebase register (15,1)
val ebase_init = Wire(new Cp0Ebase()) // val ebase_init = Wire(new Cp0Ebase())
ebase_init := 0.U.asTypeOf(new Cp0Ebase()) // ebase_init := 0.U.asTypeOf(new Cp0Ebase())
ebase_init.fill := true.B // ebase_init.fill := true.B
val cp0_ebase = RegInit(ebase_init) // val cp0_ebase = RegInit(ebase_init)
// config register (16,0) // // config register (16,0)
val cp0_config = Wire(new Cp0Config()) // val cp0_config = Wire(new Cp0Config())
cp0_config := 0.U.asTypeOf(new Cp0Config()) // cp0_config := 0.U.asTypeOf(new Cp0Config())
cp0_config.k0 := 3.U // cp0_config.k0 := 3.U
cp0_config.mt := 1.U // cp0_config.mt := 1.U
cp0_config.m := true.B // cp0_config.m := true.B
// config1 register (16,1) // // config1 register (16,1)
val cp0_config1 = Wire(new Cp0Config1()) // val cp0_config1 = Wire(new Cp0Config1())
cp0_config1 := 0.U.asTypeOf(new Cp0Config1()) // cp0_config1 := 0.U.asTypeOf(new Cp0Config1())
cp0_config1.il := 5.U // cp0_config1.il := 5.U
cp0_config1.ia := 1.U // cp0_config1.ia := 1.U
cp0_config1.dl := 5.U // cp0_config1.dl := 5.U
cp0_config1.da := 1.U // cp0_config1.da := 1.U
cp0_config1.ms := (TLB_NUM - 1).U // cp0_config1.ms := (TLB_NUM - 1).U
// taglo register (28,0) // // taglo register (28,0)
val cp0_taglo = RegInit(0.U(DATA_WID.W)) // val cp0_taglo = RegInit(0.U(DATA_WID.W))
// taghi register (29,0) // // taghi register (29,0)
val cp0_taghi = RegInit(0.U(DATA_WID.W)) // val cp0_taghi = RegInit(0.U(DATA_WID.W))
// error epc register (30,0) // // error epc register (30,0)
val cp0_error_epc = RegInit(0.U.asTypeOf(new Cp0Epc())) // 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.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.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.asid := cp0_entryhi.asid
tlb_l2.in.write.entry.vpn2 := cp0_entryhi.vpn2 // 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.g := cp0_entrylo0.g || cp0_entrylo1.g
tlb_l2.in.write.entry.pfn(0) := cp0_entrylo0.pfn // 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.pfn(1) := cp0_entrylo1.pfn
tlb_l2.in.write.entry.c(0) := cp0_entrylo0.c // 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.c(1) := cp0_entrylo1.c
tlb_l2.in.write.entry.d(0) := cp0_entrylo0.d // 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.d(1) := cp0_entrylo1.d
tlb_l2.in.write.entry.v(0) := cp0_entrylo0.v // tlb_l2.in.write.entry.v(0) := cp0_entrylo0.v
tlb_l2.in.write.entry.v(1) := cp0_entrylo1.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.asid := cp0_entryhi.asid
tlb_l2.in.entry_hi.vpn2 := cp0_entryhi.vpn2 // tlb_l2.in.entry_hi.vpn2 := cp0_entryhi.vpn2
tlb_l2.in.read.index := cp0_index.index // tlb_l2.in.read.index := cp0_index.index
// index register (0,0) // // index register (0,0)
when(!exe_stall) { // when(!exe_stall) {
when(mtc0_wen && mtc0_addr === CP0_INDEX_ADDR) { // when(mtc0_wen && mtc0_addr === CP0_INDEX_ADDR) {
cp0_index.index := mtc0_wdata(log2Ceil(TLB_NUM) - 1, 0) // cp0_index.index := mtc0_wdata(log2Ceil(TLB_NUM) - 1, 0)
}.elsewhen(exe_op === EXE_TLBP) { // }.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.index := Mux(tlb_l2.out.tlb_found, tlb_l2.out.tlb_match_index, cp0_index.index)
cp0_index.p := !tlb_l2.out.tlb_found // cp0_index.p := !tlb_l2.out.tlb_found
} // }
} // }
// random register (1,0) // // random register (1,0)
cp0_random.random := Mux(cp0_random.random === cp0_wired.wired, (TLB_NUM - 1).U, (cp0_random.random - 1.U)) // cp0_random.random := Mux(cp0_random.random === cp0_wired.wired, (TLB_NUM - 1).U, (cp0_random.random - 1.U))
// entrylo0 register (2,0) // // entrylo0 register (2,0)
when(!exe_stall) { // when(!exe_stall) {
when(mtc0_wen && mtc0_addr === CP0_ENTRYLO0_ADDR) { // when(mtc0_wen && mtc0_addr === CP0_ENTRYLO0_ADDR) {
val wdata = mtc0_wdata.asTypeOf(new Cp0EntryLo()) // val wdata = mtc0_wdata.asTypeOf(new Cp0EntryLo())
cp0_entrylo0.pfn := wdata.pfn // cp0_entrylo0.pfn := wdata.pfn
cp0_entrylo0.c := wdata.c // cp0_entrylo0.c := wdata.c
cp0_entrylo0.d := wdata.d // cp0_entrylo0.d := wdata.d
cp0_entrylo0.v := wdata.v // cp0_entrylo0.v := wdata.v
cp0_entrylo0.g := wdata.g // cp0_entrylo0.g := wdata.g
}.elsewhen(exe_op === EXE_TLBR) { // }.elsewhen(exe_op === EXE_TLBR) {
cp0_entrylo0.pfn := tlb_l2.out.read.entry.pfn(0) // cp0_entrylo0.pfn := tlb_l2.out.read.entry.pfn(0)
cp0_entrylo0.g := tlb_l2.out.read.entry.g // 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.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.d := tlb_l2.out.read.entry.d(0)
cp0_entrylo0.v := tlb_l2.out.read.entry.v(0) // cp0_entrylo0.v := tlb_l2.out.read.entry.v(0)
} // }
} // }
// entrylo1 register (3,0) // // entrylo1 register (3,0)
when(!exe_stall) { // when(!exe_stall) {
when(mtc0_wen && mtc0_addr === CP0_ENTRYLO1_ADDR) { // when(mtc0_wen && mtc0_addr === CP0_ENTRYLO1_ADDR) {
val wdata = mtc0_wdata.asTypeOf(new Cp0EntryLo()) // val wdata = mtc0_wdata.asTypeOf(new Cp0EntryLo())
cp0_entrylo1.pfn := wdata.pfn // cp0_entrylo1.pfn := wdata.pfn
cp0_entrylo1.c := wdata.c // cp0_entrylo1.c := wdata.c
cp0_entrylo1.d := wdata.d // cp0_entrylo1.d := wdata.d
cp0_entrylo1.v := wdata.v // cp0_entrylo1.v := wdata.v
cp0_entrylo1.g := wdata.g // cp0_entrylo1.g := wdata.g
}.elsewhen(exe_op === EXE_TLBR) { // }.elsewhen(exe_op === EXE_TLBR) {
cp0_entrylo1.pfn := tlb_l2.out.read.entry.pfn(1) // cp0_entrylo1.pfn := tlb_l2.out.read.entry.pfn(1)
cp0_entrylo1.g := tlb_l2.out.read.entry.g // 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.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.d := tlb_l2.out.read.entry.d(1)
cp0_entrylo1.v := tlb_l2.out.read.entry.v(1) // cp0_entrylo1.v := tlb_l2.out.read.entry.v(1)
} // }
} // }
// context register (4,0) // // context register (4,0)
when(!mem_stall && ex.flush_req) { // when(!mem_stall && ex.flush_req) {
when(VecInit(EX_TLBL, EX_TLBS, EX_MOD).contains(ex.excode)) { // when(VecInit(EX_TLBL, EX_TLBS, EX_MOD).contains(ex.excode)) {
cp0_context.badvpn2 := ex.badvaddr(31, 13) // cp0_context.badvpn2 := ex.badvaddr(31, 13)
} // }
}.elsewhen(!exe_stall) { // }.elsewhen(!exe_stall) {
when(mtc0_wen && mtc0_addr === CP0_CONTEXT_ADDR) { // when(mtc0_wen && mtc0_addr === CP0_CONTEXT_ADDR) {
cp0_context.ptebase := mtc0_wdata.asTypeOf(new Cp0Context()).ptebase // cp0_context.ptebase := mtc0_wdata.asTypeOf(new Cp0Context()).ptebase
} // }
} // }
// wired register (6,0) // // wired register (6,0)
when(!exe_stall) { // when(!exe_stall) {
when(mtc0_wen && mtc0_addr === CP0_WIRED_ADDR) { // when(mtc0_wen && mtc0_addr === CP0_WIRED_ADDR) {
cp0_wired.wired := mtc0_wdata.asTypeOf(new Cp0Wired()).wired // cp0_wired.wired := mtc0_wdata.asTypeOf(new Cp0Wired()).wired
cp0_random.random := (TLB_NUM - 1).U // cp0_random.random := (TLB_NUM - 1).U
} // }
} // }
// badvaddr register (8,0) // // badvaddr register (8,0)
when(!mem_stall && ex.flush_req) { // when(!mem_stall && ex.flush_req) {
when(VecInit(EX_ADEL, EX_TLBL, EX_ADES, EX_TLBS, EX_MOD).contains(ex.excode)) { // when(VecInit(EX_ADEL, EX_TLBL, EX_ADES, EX_TLBS, EX_MOD).contains(ex.excode)) {
cp0_badvaddr.badvaddr := ex.badvaddr // cp0_badvaddr.badvaddr := ex.badvaddr
} // }
} // }
// count register (9,0) // // count register (9,0)
val tick = RegInit(false.B) // val tick = RegInit(false.B)
tick := !tick // tick := !tick
when(tick) { // when(tick) {
cp0_count.count := cp0_count.count + 1.U // cp0_count.count := cp0_count.count + 1.U
} // }
when(!exe_stall) { // when(!exe_stall) {
when(mtc0_wen && mtc0_addr === CP0_COUNT_ADDR) { // when(mtc0_wen && mtc0_addr === CP0_COUNT_ADDR) {
cp0_count.count := mtc0_wdata.asTypeOf(new Cp0Count()).count // cp0_count.count := mtc0_wdata.asTypeOf(new Cp0Count()).count
} // }
} // }
// entryhi register (10,0) // // entryhi register (10,0)
when(!mem_stall && ex.flush_req) { // when(!mem_stall && ex.flush_req) {
when(VecInit(EX_TLBL, EX_TLBS, EX_MOD).contains(ex.excode)) { // when(VecInit(EX_TLBL, EX_TLBS, EX_MOD).contains(ex.excode)) {
cp0_entryhi.vpn2 := ex.badvaddr(31, 13) // cp0_entryhi.vpn2 := ex.badvaddr(31, 13)
} // }
}.elsewhen(!exe_stall) { // }.elsewhen(!exe_stall) {
when(mtc0_wen && mtc0_addr === CP0_ENTRYHI_ADDR) { // when(mtc0_wen && mtc0_addr === CP0_ENTRYHI_ADDR) {
val wdata = mtc0_wdata.asTypeOf(new Cp0EntryHi()) // val wdata = mtc0_wdata.asTypeOf(new Cp0EntryHi())
cp0_entryhi.asid := wdata.asid // cp0_entryhi.asid := wdata.asid
cp0_entryhi.vpn2 := wdata.vpn2 // cp0_entryhi.vpn2 := wdata.vpn2
} // }
} // }
// compare register (11,0) // // compare register (11,0)
when(!exe_stall) { // when(!exe_stall) {
when(mtc0_wen && mtc0_addr === CP0_COMPARE_ADDR) { // when(mtc0_wen && mtc0_addr === CP0_COMPARE_ADDR) {
cp0_compare.compare := mtc0_wdata.asTypeOf(new Cp0Compare()).compare // cp0_compare.compare := mtc0_wdata.asTypeOf(new Cp0Compare()).compare
} // }
} // }
// status register (12,0) // // status register (12,0)
when(!mem_stall && ex.eret) { // when(!mem_stall && ex.eret) {
when(cp0_status.erl) { // when(cp0_status.erl) {
cp0_status.erl := false.B // cp0_status.erl := false.B
}.otherwise { // }.otherwise {
cp0_status.exl := false.B // cp0_status.exl := false.B
} // }
}.elsewhen(!mem_stall && ex.flush_req) { // }.elsewhen(!mem_stall && ex.flush_req) {
cp0_status.exl := true.B // cp0_status.exl := true.B
}.elsewhen(!exe_stall) { // }.elsewhen(!exe_stall) {
when(mtc0_wen && mtc0_addr === CP0_STATUS_ADDR) { // when(mtc0_wen && mtc0_addr === CP0_STATUS_ADDR) {
val wdata = mtc0_wdata.asTypeOf(new Cp0Status()) // val wdata = mtc0_wdata.asTypeOf(new Cp0Status())
cp0_status.cu0 := wdata.cu0 // cp0_status.cu0 := wdata.cu0
cp0_status.ie := wdata.ie // cp0_status.ie := wdata.ie
cp0_status.exl := wdata.exl // cp0_status.exl := wdata.exl
cp0_status.erl := wdata.erl // cp0_status.erl := wdata.erl
cp0_status.um := wdata.um // cp0_status.um := wdata.um
cp0_status.im := wdata.im // cp0_status.im := wdata.im
cp0_status.bev := wdata.bev // cp0_status.bev := wdata.bev
} // }
} // }
// cause register (13,0) // // cause register (13,0)
cp0_cause.ip := Cat( // cp0_cause.ip := Cat(
cp0_cause.ip(7) || cp0_compare.compare === cp0_count.count || io.ext_int(5), // TODO:此处的ext_int可能不对 // cp0_cause.ip(7) || cp0_compare.compare === cp0_count.count || io.ext_int(5), // TODO:此处的ext_int可能不对
io.ext_int(4, 0), // io.ext_int(4, 0),
cp0_cause.ip(1, 0) // cp0_cause.ip(1, 0)
) // )
when(!mem_stall && ex.flush_req && !ex.eret) { // when(!mem_stall && ex.flush_req && !ex.eret) {
when(!cp0_status.exl) { // when(!cp0_status.exl) {
cp0_cause.bd := ex.bd // cp0_cause.bd := ex.bd
} // }
cp0_cause.excode := MuxLookup(ex.excode, cp0_cause.excode)( // cp0_cause.excode := MuxLookup(ex.excode, cp0_cause.excode)(
Seq( // Seq(
EX_NO -> EXC_NO, // EX_NO -> EXC_NO,
EX_INT -> EXC_INT, // EX_INT -> EXC_INT,
EX_MOD -> EXC_MOD, // EX_MOD -> EXC_MOD,
EX_TLBL -> EXC_TLBL, // EX_TLBL -> EXC_TLBL,
EX_TLBS -> EXC_TLBS, // EX_TLBS -> EXC_TLBS,
EX_ADEL -> EXC_ADEL, // EX_ADEL -> EXC_ADEL,
EX_ADES -> EXC_ADES, // EX_ADES -> EXC_ADES,
EX_SYS -> EXC_SYS, // EX_SYS -> EXC_SYS,
EX_BP -> EXC_BP, // EX_BP -> EXC_BP,
EX_RI -> EXC_RI, // EX_RI -> EXC_RI,
EX_CPU -> EXC_CPU, // EX_CPU -> EXC_CPU,
EX_OV -> EXC_OV // EX_OV -> EXC_OV
) // )
) // )
}.elsewhen(!exe_stall) { // }.elsewhen(!exe_stall) {
when(mtc0_wen) { // when(mtc0_wen) {
when(mtc0_addr === CP0_COMPARE_ADDR) { // when(mtc0_addr === CP0_COMPARE_ADDR) {
cp0_cause.ip := Cat(false.B, cp0_cause.ip(6, 0)) // cp0_cause.ip := Cat(false.B, cp0_cause.ip(6, 0))
}.elsewhen(mtc0_addr === CP0_CAUSE_ADDR) { // }.elsewhen(mtc0_addr === CP0_CAUSE_ADDR) {
val wdata = mtc0_wdata.asTypeOf(new Cp0Cause()) // val wdata = mtc0_wdata.asTypeOf(new Cp0Cause())
cp0_cause.ip := Cat( // cp0_cause.ip := Cat(
cp0_cause.ip(7, 2), // cp0_cause.ip(7, 2),
wdata.ip(1, 0) // wdata.ip(1, 0)
) // )
cp0_cause.iv := wdata.iv // cp0_cause.iv := wdata.iv
} // }
} // }
} // }
// epc register (14,0) // // epc register (14,0)
when(!mem_stall && ex.flush_req) { // when(!mem_stall && ex.flush_req) {
when(!cp0_status.exl) { // when(!cp0_status.exl) {
cp0_epc.epc := Mux(ex.bd, pc - 4.U, pc) // cp0_epc.epc := Mux(ex.bd, pc - 4.U, pc)
} // }
}.elsewhen(!exe_stall) { // }.elsewhen(!exe_stall) {
when(mtc0_wen && mtc0_addr === CP0_EPC_ADDR) { // when(mtc0_wen && mtc0_addr === CP0_EPC_ADDR) {
cp0_epc.epc := mtc0_wdata.asTypeOf(new Cp0Epc()).epc // cp0_epc.epc := mtc0_wdata.asTypeOf(new Cp0Epc()).epc
} // }
} // }
// ebase register (15,1) // // ebase register (15,1)
when(!exe_stall) { // when(!exe_stall) {
when(mtc0_wen && mtc0_addr === CP0_EBASE_ADDR) { // when(mtc0_wen && mtc0_addr === CP0_EBASE_ADDR) {
cp0_ebase.ebase := mtc0_wdata.asTypeOf(new Cp0Ebase()).ebase // cp0_ebase.ebase := mtc0_wdata.asTypeOf(new Cp0Ebase()).ebase
} // }
} // }
// taglo register (28,0) // // taglo register (28,0)
when(!exe_stall) { // when(!exe_stall) {
when(mtc0_wen && mtc0_addr === CP0_TAGLO_ADDR) { // when(mtc0_wen && mtc0_addr === CP0_TAGLO_ADDR) {
cp0_taglo := mtc0_wdata // cp0_taglo := mtc0_wdata
} // }
} // }
// taghi register (29,0) // // taghi register (29,0)
when(!exe_stall) { // when(!exe_stall) {
when(mtc0_wen && mtc0_addr === CP0_TAGHI_ADDR) { // when(mtc0_wen && mtc0_addr === CP0_TAGHI_ADDR) {
cp0_taghi := mtc0_wdata // cp0_taghi := mtc0_wdata
} // }
} // }
// error epc register (30,0) // // error epc register (30,0)
when(!exe_stall) { // when(!exe_stall) {
when(mtc0_wen && mtc0_addr === CP0_ERROR_EPC_ADDR) { // when(mtc0_wen && mtc0_addr === CP0_ERROR_EPC_ADDR) {
cp0_error_epc.epc := mtc0_wdata.asTypeOf(new Cp0Epc()).epc // cp0_error_epc.epc := mtc0_wdata.asTypeOf(new Cp0Epc()).epc
} // }
} // }
for (i <- 0 until config.fuNum) { // for (i <- 0 until config.fuNum) {
io.executeUnit.out.cp0_rdata(i) := MuxLookup(io.executeUnit.in.inst_info(i).cp0_addr, 0.U)( // io.executeUnit.out.cp0_rdata(i) := MuxLookup(io.executeUnit.in.inst_info(i).cp0_addr, 0.U)(
Seq( // Seq(
CP0_INDEX_ADDR -> cp0_index.asUInt, // CP0_INDEX_ADDR -> cp0_index.asUInt,
CP0_RANDOM_ADDR -> cp0_random.asUInt, // CP0_RANDOM_ADDR -> cp0_random.asUInt,
CP0_ENTRYLO0_ADDR -> cp0_entrylo0.asUInt, // CP0_ENTRYLO0_ADDR -> cp0_entrylo0.asUInt,
CP0_ENTRYLO1_ADDR -> cp0_entrylo1.asUInt, // CP0_ENTRYLO1_ADDR -> cp0_entrylo1.asUInt,
CP0_CONTEXT_ADDR -> cp0_context.asUInt, // CP0_CONTEXT_ADDR -> cp0_context.asUInt,
CP0_PAGE_MASK_ADDR -> cp0_pagemask, // CP0_PAGE_MASK_ADDR -> cp0_pagemask,
CP0_WIRED_ADDR -> cp0_wired.asUInt, // CP0_WIRED_ADDR -> cp0_wired.asUInt,
CP0_BADV_ADDR -> cp0_badvaddr.asUInt, // CP0_BADV_ADDR -> cp0_badvaddr.asUInt,
CP0_COUNT_ADDR -> cp0_count.asUInt, // CP0_COUNT_ADDR -> cp0_count.asUInt,
CP0_ENTRYHI_ADDR -> cp0_entryhi.asUInt, // CP0_ENTRYHI_ADDR -> cp0_entryhi.asUInt,
CP0_COMPARE_ADDR -> cp0_compare.asUInt, // CP0_COMPARE_ADDR -> cp0_compare.asUInt,
CP0_STATUS_ADDR -> cp0_status.asUInt, // CP0_STATUS_ADDR -> cp0_status.asUInt,
CP0_CAUSE_ADDR -> cp0_cause.asUInt, // CP0_CAUSE_ADDR -> cp0_cause.asUInt,
CP0_EPC_ADDR -> cp0_epc.asUInt, // CP0_EPC_ADDR -> cp0_epc.asUInt,
CP0_PRID_ADDR -> prid, // CP0_PRID_ADDR -> prid,
CP0_EBASE_ADDR -> cp0_ebase.asUInt, // CP0_EBASE_ADDR -> cp0_ebase.asUInt,
CP0_CONFIG_ADDR -> cp0_config.asUInt, // CP0_CONFIG_ADDR -> cp0_config.asUInt,
CP0_CONFIG1_ADDR -> cp0_config1.asUInt, // CP0_CONFIG1_ADDR -> cp0_config1.asUInt,
CP0_TAGLO_ADDR -> cp0_taglo, // CP0_TAGLO_ADDR -> cp0_taglo,
CP0_TAGHI_ADDR -> cp0_taghi, // CP0_TAGHI_ADDR -> cp0_taghi,
CP0_ERROR_EPC_ADDR -> cp0_error_epc.asUInt // CP0_ERROR_EPC_ADDR -> cp0_error_epc.asUInt
) // )
) // )
} // }
io.decoderUnit.cause_ip := cp0_cause.ip // io.decoderUnit.cause_ip := cp0_cause.ip
io.decoderUnit.status_im := cp0_status.im // io.decoderUnit.status_im := cp0_status.im
io.decoderUnit.kernel_mode := (cp0_status.exl && !(ex.eret && cp0_status.erl)) || // io.decoderUnit.kernel_mode := (cp0_status.exl && !(ex.eret && cp0_status.erl)) ||
(cp0_status.erl && !ex.eret) || // (cp0_status.erl && !ex.eret) ||
!cp0_status.um || // !cp0_status.um ||
(ex.flush_req && !ex.eret) // (ex.flush_req && !ex.eret)
io.decoderUnit.access_allowed := io.decoderUnit.kernel_mode || cp0_status.cu0 // 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.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_cause := cp0_cause.asUInt
io.executeUnit.out.debug.cp0_count := cp0_count.asUInt // io.executeUnit.out.debug.cp0_count := cp0_count.asUInt
io.executeUnit.out.debug.cp0_random := cp0_random.asUInt // io.executeUnit.out.debug.cp0_random := cp0_random.asUInt
val trap_base = Mux( // val trap_base = Mux(
cp0_status.bev, // cp0_status.bev,
"hbfc00200".U(PC_WID.W), // "hbfc00200".U(PC_WID.W),
cp0_ebase.asUInt // cp0_ebase.asUInt
) // )
io.memoryUnit.out.flush := false.B // io.memoryUnit.out.flush := false.B
io.memoryUnit.out.flush_pc := 0.U // io.memoryUnit.out.flush_pc := 0.U
when(ex.eret) { // when(ex.eret) {
io.memoryUnit.out.flush := true.B && !io.ctrl.mem_stall // 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) // io.memoryUnit.out.flush_pc := Mux(cp0_status.erl, cp0_error_epc.epc, cp0_epc.epc)
}.elsewhen(ex.flush_req) { // }.elsewhen(ex.flush_req) {
io.memoryUnit.out.flush := true.B && !io.ctrl.mem_stall // io.memoryUnit.out.flush := true.B && !io.ctrl.mem_stall
io.memoryUnit.out.flush_pc := Mux( // io.memoryUnit.out.flush_pc := Mux(
cp0_status.exl, // cp0_status.exl,
trap_base + "h180".U, // trap_base + "h180".U,
trap_base + Mux( // trap_base + Mux(
ex.excode === EX_INT && cp0_cause.iv && !cp0_status.bev, // ex.excode === EX_INT && cp0_cause.iv && !cp0_status.bev,
"h200".U, // "h200".U,
Mux(ex.tlb_refill && ex.excode =/= EX_INT, 0.U, "h180".U) // Mux(ex.tlb_refill && ex.excode =/= EX_INT, 0.U, "h180".U)
) // )
) // )
} // }
} // }

View File

@ -1,118 +1,118 @@
package cpu.pipeline.execute // package cpu.pipeline.execute
import chisel3._ // import chisel3._
import chisel3.util._ // import chisel3.util._
import cpu.defines._ // import cpu.defines._
import cpu.defines.Const._ // import cpu.defines.Const._
import cpu.CpuConfig // import cpu.CpuConfig
class Fu(implicit val config: CpuConfig) extends Module { // class Fu(implicit val config: CpuConfig) extends Module {
val io = IO(new Bundle { // val io = IO(new Bundle {
val ctrl = new ExecuteFuCtrl() // val ctrl = new ExecuteFuCtrl()
val inst = Vec( // val inst = Vec(
config.decoderNum, // config.decoderNum,
new Bundle { // new Bundle {
val pc = Input(UInt(PC_WID.W)) // val pc = Input(UInt(PC_WID.W))
val hilo_wen = Input(Bool()) // val hilo_wen = Input(Bool())
val mul_en = Input(Bool()) // val mul_en = Input(Bool())
val div_en = Input(Bool()) // val div_en = Input(Bool())
val inst_info = Input(new InstInfo()) // val inst_info = Input(new InstInfo())
val src_info = Input(new SrcInfo()) // val src_info = Input(new SrcInfo())
val ex = new Bundle { // val ex = new Bundle {
val in = Input(new ExceptionInfo()) // val in = Input(new ExceptionInfo())
val out = Output(new ExceptionInfo()) // val out = Output(new ExceptionInfo())
} // }
val result = Output(UInt(DATA_WID.W)) // val result = Output(UInt(DATA_WID.W))
}, // },
) // )
val cp0_rdata = Input(Vec(config.fuNum, UInt(DATA_WID.W))) // val cp0_rdata = Input(Vec(config.fuNum, UInt(DATA_WID.W)))
val stall_req = Output(Bool()) // val stall_req = Output(Bool())
val branch = new Bundle { // val branch = new Bundle {
val pred_branch = Input(Bool()) // val pred_branch = Input(Bool())
val branch = Output(Bool()) // val branch = Output(Bool())
val pred_fail = Output(Bool()) // val pred_fail = Output(Bool())
} // }
val llbit = 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 alu = Seq.fill(config.decoderNum)(Module(new Alu()))
val mul = Module(new Mul()).io // val mul = Module(new Mul()).io
val div = Module(new Div()).io // val div = Module(new Div()).io
val hilo = Module(new HiLo()).io // val hilo = Module(new HiLo()).io
val branchCtrl = Module(new BranchCtrl()).io // val branchCtrl = Module(new BranchCtrl()).io
val llbit = Module(new LLbit()).io // val llbit = Module(new LLbit()).io
branchCtrl.in.inst_info := io.inst(0).inst_info // branchCtrl.in.inst_info := io.inst(0).inst_info
branchCtrl.in.src_info := io.inst(0).src_info // branchCtrl.in.src_info := io.inst(0).src_info
branchCtrl.in.pred_branch := io.branch.pred_branch // branchCtrl.in.pred_branch := io.branch.pred_branch
io.branch.branch := branchCtrl.out.branch // io.branch.branch := branchCtrl.out.branch
io.branch.pred_fail := branchCtrl.out.pred_fail // io.branch.pred_fail := branchCtrl.out.pred_fail
for (i <- 0 until (config.fuNum)) { // for (i <- 0 until (config.fuNum)) {
alu(i).io.inst_info := io.inst(i).inst_info // alu(i).io.inst_info := io.inst(i).inst_info
alu(i).io.src_info := io.inst(i).src_info // alu(i).io.src_info := io.inst(i).src_info
alu(i).io.hilo.rdata := hilo.rdata // alu(i).io.hilo.rdata := hilo.rdata
alu(i).io.mul.result := mul.result // alu(i).io.mul.result := mul.result
alu(i).io.mul.ready := mul.ready // alu(i).io.mul.ready := mul.ready
alu(i).io.div.ready := div.ready // alu(i).io.div.ready := div.ready
alu(i).io.div.result := div.result // alu(i).io.div.result := div.result
alu(i).io.cp0_rdata := io.cp0_rdata(i) // alu(i).io.cp0_rdata := io.cp0_rdata(i)
alu(i).io.llbit := io.llbit // alu(i).io.llbit := io.llbit
io.inst(i).ex.out := io.inst(i).ex.in // 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.flush_req := io.inst(i).ex.in.flush_req || alu(i).io.overflow
io.inst(i).ex.out.excode := MuxCase( // io.inst(i).ex.out.excode := MuxCase(
io.inst(i).ex.in.excode, // io.inst(i).ex.in.excode,
Seq( // Seq(
(io.inst(i).ex.in.excode =/= EX_NO) -> io.inst(i).ex.in.excode, // (io.inst(i).ex.in.excode =/= EX_NO) -> io.inst(i).ex.in.excode,
alu(i).io.overflow -> EX_OV, // 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.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.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.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.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.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.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.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.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.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.allow_to_go := io.ctrl.allow_to_go
io.stall_req := (io.inst.map(_.div_en).reduce(_ || _) && !div.ready) || // io.stall_req := (io.inst.map(_.div_en).reduce(_ || _) && !div.ready) ||
(io.inst.map(_.mul_en).reduce(_ || _) && !mul.ready) // (io.inst.map(_.mul_en).reduce(_ || _) && !mul.ready)
io.inst(0).result := Mux( // io.inst(0).result := Mux(
io.inst(0).inst_info.branch_link, // io.inst(0).inst_info.branch_link,
io.inst(0).pc + 8.U, // io.inst(0).pc + 8.U,
alu(0).io.result, // alu(0).io.result,
) // )
io.inst(1).result := alu(1).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(_ || _)) || // 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 // (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.wdata := Mux(io.inst(1).hilo_wen, alu(1).io.hilo.wdata, alu(0).io.hilo.wdata)
llbit.do_flush := io.ctrl.eret // llbit.do_flush := io.ctrl.eret
llbit.wen := (io.inst(0).inst_info.op === EXE_LL || io.inst(0).inst_info.op === EXE_SC || // 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 // 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 // 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 // val llbit_rdata = if (config.build) llbit.rdata else true.B
io.llbit := llbit_rdata // io.llbit := llbit_rdata
// ===----------------------------------------------------------------=== // // ===----------------------------------------------------------------===
// statistic // // statistic
// ===----------------------------------------------------------------=== // // ===----------------------------------------------------------------===
if (!config.build) { // if (!config.build) {
val branch_cnt = RegInit(0.U(32.W)) // val branch_cnt = RegInit(0.U(32.W))
val success_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.branch) { branch_cnt := branch_cnt + 1.U }
when(!io.branch.pred_fail) { success_cnt := success_cnt + 1.U } // when(!io.branch.pred_fail) { success_cnt := success_cnt + 1.U }
io.statistic.get.branch := branch_cnt // io.statistic.get.branch := branch_cnt
io.statistic.get.success := success_cnt // io.statistic.get.success := success_cnt
} // }
} // }

View File

@ -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
}

View File

@ -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
}

View File

@ -1,225 +1,225 @@
package cpu.pipeline.execute // package cpu.pipeline.execute
import chisel3._ // import chisel3._
import chisel3.util._ // import chisel3.util._
import cpu.defines._ // import cpu.defines._
import cpu.defines.Const._ // import cpu.defines.Const._
import cpu.CpuConfig // import cpu.CpuConfig
class SignedMul extends BlackBox with HasBlackBoxResource { // class SignedMul extends BlackBox with HasBlackBoxResource {
val io = IO(new Bundle { // val io = IO(new Bundle {
val CLK = Input(Clock()) // val CLK = Input(Clock())
val CE = Input(Bool()) // val CE = Input(Bool())
val A = Input(UInt((DATA_WID + 1).W)) // val A = Input(UInt((DATA_WID + 1).W))
val B = Input(UInt((DATA_WID + 1).W)) // val B = Input(UInt((DATA_WID + 1).W))
val P = Output(UInt((HILO_WID + 2).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 (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 { // class Mul(implicit val config: CpuConfig) extends Module {
// override def latency = 2 // 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)) // val ready = Output(Bool())
// mulDataModule.io.a := io.in.bits.src(0) // val result = Output(UInt(HILO_WID.W))
// 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) // if (config.build) {
// for (i <- 1 to latency) { // val signedMul = Module(new SignedMul()).io
// ctrlVec = ctrlVec :+ PipelineReg(i)(ctrlVec(i - 1)) // 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")
// // }