Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lab3 #12

Closed
wants to merge 11 commits into from
Closed

Lab3 #12

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions src/main/scala/components/forwarding.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,17 @@ import chisel3._
/**
* The Forwarding unit
*
* Here we should describe the I/O
* Input: rs1, the register number for which the data is used in the execute stage
* Input: rs2, the register number for which the data is used in the execute stage
* Input: exmemrd, the destination register for the instruction in the mem stage
* Input: exmemrw, true if the bit in the memory stage needs to write the register file
* Input: memwbrd, the destination register for the instruction in the writeback stage
* Input: memwbrw, true if the bit in the writeback stage needs to write the register file
*
* Output: forwardA, 0, don't forward. 1, forward from mem stage. 2, forward from wb stage.
* This is used for the "readdata1" forwarding
* Output: forwardB, 0, don't forward. 1, forward from mem stage. 2, forward from wb stage.
* This is used for the "readdata2" forwarding
*
* For more information, see Section 4.7 of Patterson and Hennessy
* This follows figure 4.53
Expand All @@ -25,20 +35,19 @@ class ForwardingUnit extends Module {
val forwardA = Output(UInt(2.W))
val forwardB = Output(UInt(2.W))
})

when (io.rs1 === io.exmemrd && io.exmemrd =/= 0.U && io.exmemrw) {
io.forwardA := 1.U
} .elsewhen (io.rs1 === io.memwbrd && io.memwbrd =/= 0.U && io.memwbrw) {
io.forwardA := 2.U
} .otherwise {
}.otherwise {
io.forwardA := 0.U
}

when (io.rs2 === io.exmemrd && io.exmemrd =/= 0.U && io.exmemrw) {
io.forwardB := 1.U
} .elsewhen (io.rs2 === io.memwbrd && io.memwbrd =/= 0.U && io.memwbrw) {
io.forwardB := 2.U
} .otherwise {
}.otherwise {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Revert this line. Why did you get rid of this space?

io.forwardB := 0.U
}
}
1 change: 0 additions & 1 deletion src/main/scala/components/hazard.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,4 @@ class HazardUnit extends Module {
io.ifid_write := false.B
io.idex_bubble := true.B
}

}
27 changes: 21 additions & 6 deletions src/main/scala/components/register-file.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,28 @@ class RegisterFile(implicit val conf: CPUConfig) extends Module {

val regs = Reg(Vec(32, UInt(32.W)))

// When the write enable is high, write the data
when (io.wen) {
regs(io.writereg) := io.writedata
}


// *Always* read the data. This is required for the single cycle CPU since in a single cycle it
// might both read and write the registers (e.g., an add)
io.readdata1 := regs(io.readreg1)
io.readdata2 := regs(io.readreg2)

when (io.readreg1 === io.writereg && io.wen){
//Forward writedata to readdata1 to avoid hazard when writing to and reading from the same register in a cycle
regs(io.writereg) := io.writedata
io.readdata1 := io.writedata
io.readdata2 := regs(io.readreg2)
} .elsewhen (io.readreg2 === io.writereg && io.wen) {
//Forward writedata to readdata2 to avoid hazard when writing to and reading from the same register in a cycle
regs(io.writereg) := io.writedata
io.readdata1 := regs(io.readreg1)
io.readdata2 := io.writedata
}.otherwise {
// When the write enable is high, write the data
when (io.wen) {
regs(io.writereg) := io.writedata
}
io.readdata1 := regs(io.readreg1)
io.readdata2 := regs(io.readreg2)
}

}
37 changes: 20 additions & 17 deletions src/main/scala/five-cycle/cpu.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ class FiveCycleCPU(implicit val conf: CPUConfig) extends Module {
}

class EXControl extends Bundle {
val add = UInt(2.W)
val add = Bool()
val immediate = Bool()
val alusrc1 = UInt(2.W)
val branch = Bool()
val alusrc1 = UInt(2.W)
val branch = Bool()
}

class MControl extends Bundle {
Expand All @@ -46,7 +46,6 @@ class FiveCycleCPU(implicit val conf: CPUConfig) extends Module {
class WBControl extends Bundle {
val toreg = UInt(2.W)
val regwrite = Bool()
val pctoreg = Bool()
}

class IDEXBundle extends Bundle {
Expand Down Expand Up @@ -108,8 +107,8 @@ class FiveCycleCPU(implicit val conf: CPUConfig) extends Module {
val branch_taken = Wire(Bool())

// For flushing stages.
val flush_idex = Wire(Bool())
val flush_exmem = Wire(Bool())
val bubble_idex = Wire(Bool())
val bubble_exmem = Wire(Bool())

/////////////////////////////////////////////////////////////////////////////
// FETCH STAGE
Expand Down Expand Up @@ -153,7 +152,7 @@ class FiveCycleCPU(implicit val conf: CPUConfig) extends Module {
id_ex.pc := if_id.pc
id_ex.pcplusfour := if_id.pcplusfour

when (flush_idex) {
when (bubble_idex) {
id_ex.excontrol := 0.U.asTypeOf(new EXControl)
id_ex.mcontrol := 0.U.asTypeOf(new MControl)
id_ex.wbcontrol := 0.U.asTypeOf(new WBControl)
Expand All @@ -162,10 +161,13 @@ class FiveCycleCPU(implicit val conf: CPUConfig) extends Module {
id_ex.excontrol.immediate := control.io.immediate
id_ex.excontrol.alusrc1 := control.io.alusrc1
id_ex.excontrol.branch := control.io.branch

id_ex.mcontrol.jump := control.io.jump
id_ex.mcontrol.memread := control.io.memread
id_ex.mcontrol.memwrite := control.io.memwrite
id_ex.mcontrol.maskmode := if_id.instruction(13,12)
id_ex.mcontrol.sext := ~if_id.instruction(14)


id_ex.wbcontrol.toreg := control.io.toreg
id_ex.wbcontrol.regwrite := control.io.regwrite
Expand Down Expand Up @@ -205,11 +207,12 @@ class FiveCycleCPU(implicit val conf: CPUConfig) extends Module {
ex_mem.readdata2 := id_ex.readdata2
ex_mem.aluresult := alu.io.result
ex_mem.taken := branchCtrl.io.taken
ex_mem.mcontrol.jump := id_ex.mcontrol.jump

when (branchCtrl.io.taken || control.io.jump === 2.U) {
when (branchCtrl.io.taken || id_ex.mcontrol.jump === 2.U) {
ex_mem.nextpc := branchAdd.io.result
ex_mem.taken := true.B
} .elsewhen (control.io.jump === 3.U) {
} .elsewhen (id_ex.mcontrol.jump === 3.U) {
ex_mem.nextpc := alu.io.result & Cat(Fill(31, 1.U), 0.U)
ex_mem.taken := true.B
} .otherwise {
Expand All @@ -220,7 +223,7 @@ class FiveCycleCPU(implicit val conf: CPUConfig) extends Module {
ex_mem.writereg := id_ex.writereg
ex_mem.pcplusfour := id_ex.pcplusfour

when (flush_exmem) {
when (bubble_exmem) {
ex_mem.mcontrol := 0.U.asTypeOf(new MControl)
ex_mem.wbcontrol := 0.U.asTypeOf(new WBControl)
} .otherwise {
Expand All @@ -233,7 +236,7 @@ class FiveCycleCPU(implicit val conf: CPUConfig) extends Module {
/////////////////////////////////////////////////////////////////////////////
// MEM STAGE
/////////////////////////////////////////////////////////////////////////////

printf("jump =%x\n", control.io.jump)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed?

io.dmem.address := ex_mem.aluresult
io.dmem.writedata := ex_mem.readdata2
io.dmem.memread := ex_mem.mcontrol.memread
Expand All @@ -254,13 +257,13 @@ class FiveCycleCPU(implicit val conf: CPUConfig) extends Module {
// Now we know the direction of the branch. If it's taken, clear the control
// for the previous stages.
when (branch_taken) {
flush_exmem := true.B
flush_idex := true.B
bubble_exmem := true.B
bubble_idex := true.B
} .otherwise {
flush_exmem := false.B
flush_idex := false.B
bubble_exmem := false.B
bubble_idex := false.B
}

printf(p"MEM/WB: $mem_wb\n")

/////////////////////////////////////////////////////////////////////////////
Expand Down
Loading