blob: 0fb6290e62c40553a928884aaf80901a2014001c [file] [log] [blame]
// SPDX-FileCopyrightText: 2020 Muhammad Hadir Khan
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-License-Identifier: Apache-2.0
package core
import chisel3._
class ForwardUnit extends Module {
val io = IO(new Bundle {
val EX_MEM_REGRD = Input(UInt(5.W))
val MEM_WB_REGRD = Input(UInt(5.W))
val ID_EX_REGRS1 = Input(UInt(5.W))
val ID_EX_REGRS2 = Input(UInt(5.W))
val ID_EX_inst_op = Input(UInt(7.W))
val EX_MEM_REGWR = Input(UInt(1.W))
val MEM_WB_REGWR = Input(UInt(1.W))
val forward_a = Output(UInt(2.W))
val forward_b = Output(UInt(2.W))
})
io.forward_a := "b00".U
io.forward_b := "b00".U
// EX HAZARD
// additional checking by opcode 0110111 because this is lui and it does not have any rs1, rs2 so we will not forward in that scenario
when(io.EX_MEM_REGWR === "b1".U && io.EX_MEM_REGRD =/= "b00000".U && (io.EX_MEM_REGRD === io.ID_EX_REGRS1) && (io.EX_MEM_REGRD === io.ID_EX_REGRS2) && io.ID_EX_inst_op =/= "b0110111".U) {
// if both the source register 1 and source register 2 are dependent on the destination
// register of previous instruction we forward the destination register value
// in both the operands of ALU for example: addi x2, x0, 2
// add x2, x2, x2
io.forward_a := "b01".U
io.forward_b := "b01".U
} .elsewhen(io.EX_MEM_REGWR === "b1".U && io.EX_MEM_REGRD =/= "b00000".U && (io.EX_MEM_REGRD === io.ID_EX_REGRS2) && io.ID_EX_inst_op =/= "b0110111".U) {
io.forward_b := "b01".U
//io.forward_a := "b00".U
} .elsewhen(io.EX_MEM_REGWR === "b1".U && io.EX_MEM_REGRD =/= "b00000".U && (io.EX_MEM_REGRD === io.ID_EX_REGRS1) && io.ID_EX_inst_op =/= "b0110111".U) {
io.forward_a := "b01".U
// io.forward_b := "b00".U
}
// MEM HAZARD
when(io.MEM_WB_REGWR === "b1".U && io.MEM_WB_REGRD =/= "b00000".U && ~((io.EX_MEM_REGWR === "b1".U) && (io.EX_MEM_REGRD =/= "b00000".U) && (io.EX_MEM_REGRD === io.ID_EX_REGRS1) && (io.EX_MEM_REGRD === io.ID_EX_REGRS2)) && (io.MEM_WB_REGRD === io.ID_EX_REGRS1) && (io.MEM_WB_REGRD === io.ID_EX_REGRS2) && io.ID_EX_inst_op =/= "b0110111".U) {
io.forward_a := "b10".U
io.forward_b := "b10".U
} .elsewhen(io.MEM_WB_REGWR === "b1".U && io.MEM_WB_REGRD =/= "b00000".U && ~((io.EX_MEM_REGWR === "b1".U) && (io.EX_MEM_REGRD =/= "b00000".U) && (io.EX_MEM_REGRD === io.ID_EX_REGRS2)) && (io.MEM_WB_REGRD === io.ID_EX_REGRS2) && io.ID_EX_inst_op =/= "b0110111".U) {
io.forward_b := "b10".U
//io.forward_a := "b00".U
} .elsewhen(io.MEM_WB_REGWR === "b1".U && io.MEM_WB_REGRD =/= "b00000".U && ~((io.EX_MEM_REGWR === "b1".U) && (io.EX_MEM_REGRD =/= "b00000".U) && (io.EX_MEM_REGRD === io.ID_EX_REGRS1)) && (io.MEM_WB_REGRD === io.ID_EX_REGRS1) && io.ID_EX_inst_op =/= "b0110111".U) {
io.forward_a := "b10".U
// io.forward_b := "b00".U
}
}