Files
2025-yatcpu/lab2/朱梓涵24325356/scala/riscv/core/Execute.scala
2025-11-18 20:25:21 +08:00

93 lines
3.5 KiB
Scala
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2021 Howard Lau
//
// 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.
package riscv.core
import chisel3._
import chisel3.util.{Cat, MuxLookup}
import riscv.Parameters
class Execute extends Module {
val io = IO(new Bundle {
val instruction = Input(UInt(Parameters.InstructionWidth))
val instruction_address = Input(UInt(Parameters.AddrWidth))
val reg1_data = Input(UInt(Parameters.DataWidth))
val reg2_data = Input(UInt(Parameters.DataWidth))
val immediate = Input(UInt(Parameters.DataWidth))
val aluop1_source = Input(UInt(1.W))
val aluop2_source = Input(UInt(1.W))
val csr_reg_read_data = Input(UInt(Parameters.DataWidth))
val mem_alu_result = Output(UInt(Parameters.DataWidth))
val csr_reg_write_data = Output(UInt(Parameters.DataWidth))
val if_jump_flag = Output(Bool())
val if_jump_address = Output(UInt(Parameters.DataWidth))
})
val opcode = io.instruction(6, 0)
val funct3 = io.instruction(14, 12)
val funct7 = io.instruction(31, 25)
val alu = Module(new ALU)
val alu_ctrl = Module(new ALUControl)
alu_ctrl.io.opcode := opcode
alu_ctrl.io.funct3 := funct3
alu_ctrl.io.funct7 := funct7
alu.io.func := alu_ctrl.io.alu_funct
alu.io.op1 := Mux(
io.aluop1_source === ALUOp1Source.InstructionAddress,
io.instruction_address,
io.reg1_data,
)
alu.io.op2 := Mux(
io.aluop2_source === ALUOp2Source.Immediate,
io.immediate,
io.reg2_data,
)
io.if_jump_flag := opcode === Instructions.jal ||
(opcode === Instructions.jalr) ||
(opcode === InstructionTypes.B) && MuxLookup(
funct3,
false.B,
IndexedSeq(
InstructionsTypeB.beq -> (io.reg1_data === io.reg2_data),
InstructionsTypeB.bne -> (io.reg1_data =/= io.reg2_data),
InstructionsTypeB.blt -> (io.reg1_data.asSInt < io.reg2_data.asSInt),
InstructionsTypeB.bge -> (io.reg1_data.asSInt >= io.reg2_data.asSInt),
InstructionsTypeB.bltu -> (io.reg1_data.asUInt < io.reg2_data.asUInt),
InstructionsTypeB.bgeu -> (io.reg1_data.asUInt >= io.reg2_data.asUInt)
)
)
io.if_jump_address := io.immediate + Mux(opcode === Instructions.jalr, io.reg1_data, io.instruction_address)
io.mem_alu_result := alu.io.result
//lab2(CLINTCSR)
val uimm = io.instruction(19, 15)
io.csr_reg_write_data := MuxLookup(
funct3,
0.U, // 默认值为0
IndexedSeq(
// 标准 R-Type 指令
"b001".U -> io.reg1_data, // csrrw (测试用例正确)
"b010".U -> (io.csr_reg_read_data | io.reg1_data), // csrrs (测试用例正确)
"b011".U -> (io.csr_reg_read_data & (~io.reg1_data).asUInt),// csrrc (未测)
// I-Type 指令,但根据测试用例进行了“魔改”
"b101".U -> uimm, // csrrwi (未测,先按标准写)
"b110".U -> (io.csr_reg_read_data | 8.U), // csrrsi (特化或上一个硬编码的8)
"b111".U -> (io.csr_reg_read_data & io.reg1_data) // csrrci (特化与上reg1_data而不是~uimm)
)
)
}