文件结构调整

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 {
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) {

View File

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

View File

@ -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),
// HILO的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),
// // HILO的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)
// }

View File

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

View File

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

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.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")
// // }