mirror of
https://github.com/handsomezhuzhu/2025-yatcpu.git
synced 2026-02-20 20:10:14 +00:00
209 lines
6.2 KiB
Scala
209 lines
6.2 KiB
Scala
// 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._
|
|
import riscv.Parameters
|
|
|
|
object InstructionTypes {
|
|
val L = "b0000011".U
|
|
val I = "b0010011".U
|
|
val S = "b0100011".U
|
|
val RM = "b0110011".U
|
|
val B = "b1100011".U
|
|
}
|
|
|
|
object Instructions {
|
|
val lui = "b0110111".U
|
|
val nop = "b0000001".U
|
|
val jal = "b1101111".U
|
|
val jalr = "b1100111".U
|
|
val auipc = "b0010111".U
|
|
val csr = "b1110011".U
|
|
val fence = "b0001111".U
|
|
}
|
|
|
|
object InstructionsTypeL {
|
|
val lb = "b000".U
|
|
val lh = "b001".U
|
|
val lw = "b010".U
|
|
val lbu = "b100".U
|
|
val lhu = "b101".U
|
|
}
|
|
|
|
object InstructionsTypeI {
|
|
val addi = 0.U
|
|
val slli = 1.U
|
|
val slti = 2.U
|
|
val sltiu = 3.U
|
|
val xori = 4.U
|
|
val sri = 5.U
|
|
val ori = 6.U
|
|
val andi = 7.U
|
|
}
|
|
|
|
object InstructionsTypeS {
|
|
val sb = "b000".U
|
|
val sh = "b001".U
|
|
val sw = "b010".U
|
|
}
|
|
|
|
object InstructionsTypeR {
|
|
val add_sub = 0.U
|
|
val sll = 1.U
|
|
val slt = 2.U
|
|
val sltu = 3.U
|
|
val xor = 4.U
|
|
val sr = 5.U
|
|
val or = 6.U
|
|
val and = 7.U
|
|
}
|
|
|
|
object InstructionsTypeM {
|
|
val mul = 0.U
|
|
val mulh = 1.U
|
|
val mulhsu = 2.U
|
|
val mulhum = 3.U
|
|
val div = 4.U
|
|
val divu = 5.U
|
|
val rem = 6.U
|
|
val remu = 7.U
|
|
}
|
|
|
|
object InstructionsTypeB {
|
|
val beq = "b000".U
|
|
val bne = "b001".U
|
|
val blt = "b100".U
|
|
val bge = "b101".U
|
|
val bltu = "b110".U
|
|
val bgeu = "b111".U
|
|
}
|
|
|
|
object InstructionsTypeCSR {
|
|
val csrrw = "b001".U
|
|
val csrrs = "b010".U
|
|
val csrrc = "b011".U
|
|
val csrrwi = "b101".U
|
|
val csrrsi = "b110".U
|
|
val csrrci = "b111".U
|
|
}
|
|
|
|
object InstructionsNop {
|
|
val nop = 0x00000013L.U(Parameters.DataWidth)
|
|
}
|
|
|
|
object InstructionsRet {
|
|
val mret = 0x30200073L.U(Parameters.DataWidth)
|
|
val ret = 0x00008067L.U(Parameters.DataWidth)
|
|
}
|
|
|
|
object InstructionsEnv {
|
|
val ecall = 0x00000073L.U(Parameters.DataWidth)
|
|
val ebreak = 0x00100073L.U(Parameters.DataWidth)
|
|
}
|
|
|
|
object ALUOp1Source {
|
|
val Register = 0.U(1.W)
|
|
val InstructionAddress = 1.U(1.W)
|
|
}
|
|
|
|
object ALUOp2Source {
|
|
val Register = 0.U(1.W)
|
|
val Immediate = 1.U(1.W)
|
|
}
|
|
|
|
object RegWriteSource {
|
|
val ALUResult = 0.U(2.W)
|
|
val Memory = 1.U(2.W)
|
|
val CSR = 2.U(2.W)
|
|
val NextInstructionAddress = 3.U(2.W)
|
|
}
|
|
|
|
class InstructionDecode extends Module {
|
|
val io = IO(new Bundle {
|
|
val instruction = Input(UInt(Parameters.InstructionWidth))
|
|
|
|
val regs_reg1_read_address = Output(UInt(Parameters.PhysicalRegisterAddrWidth))
|
|
val regs_reg2_read_address = Output(UInt(Parameters.PhysicalRegisterAddrWidth))
|
|
val ex_immediate = Output(UInt(Parameters.DataWidth))
|
|
val ex_aluop1_source = Output(UInt(1.W))
|
|
val ex_aluop2_source = Output(UInt(1.W))
|
|
val memory_read_enable = Output(Bool())
|
|
val memory_write_enable = Output(Bool())
|
|
val wb_reg_write_source = Output(UInt(2.W))
|
|
val reg_write_enable = Output(Bool())
|
|
val reg_write_address = Output(UInt(Parameters.PhysicalRegisterAddrWidth))
|
|
val csr_reg_write_enable = Output(Bool())
|
|
val csr_reg_address = Output(UInt(Parameters.DataWidth))
|
|
})
|
|
val opcode = io.instruction(6, 0)
|
|
val funct3 = io.instruction(14, 12)
|
|
val funct7 = io.instruction(31, 25)
|
|
val rd = io.instruction(11, 7)
|
|
val rs1 = io.instruction(19, 15)
|
|
val rs2 = io.instruction(24, 20)
|
|
|
|
io.regs_reg1_read_address := Mux(opcode === Instructions.lui, 0.U(Parameters.PhysicalRegisterAddrWidth), rs1)
|
|
io.regs_reg2_read_address := rs2
|
|
val immediate = MuxLookup(
|
|
opcode,
|
|
Cat(Fill(20, io.instruction(31)), io.instruction(31, 20)),
|
|
IndexedSeq(
|
|
InstructionTypes.I -> Cat(Fill(21, io.instruction(31)), io.instruction(30, 20)),
|
|
InstructionTypes.L -> Cat(Fill(21, io.instruction(31)), io.instruction(30, 20)),
|
|
Instructions.jalr -> Cat(Fill(21, io.instruction(31)), io.instruction(30, 20)),
|
|
InstructionTypes.S -> Cat(Fill(21, io.instruction(31)), io.instruction(30, 25), io.instruction(11, 7)),
|
|
InstructionTypes.B -> Cat(Fill(20, io.instruction(31)), io.instruction(7), io.instruction(30, 25), io.instruction(11, 8), 0.U(1.W)),
|
|
Instructions.lui -> Cat(io.instruction(31, 12), 0.U(12.W)),
|
|
Instructions.auipc -> Cat(io.instruction(31, 12), 0.U(12.W)),
|
|
Instructions.jal -> Cat(Fill(12, io.instruction(31)), io.instruction(19, 12), io.instruction(20), io.instruction(30, 21), 0.U(1.W))
|
|
)
|
|
)
|
|
io.ex_immediate := immediate
|
|
io.ex_aluop1_source := Mux(
|
|
opcode === Instructions.auipc || opcode === InstructionTypes.B || opcode === Instructions.jal,
|
|
ALUOp1Source.InstructionAddress,
|
|
ALUOp1Source.Register
|
|
)
|
|
io.ex_aluop2_source := Mux(
|
|
opcode === InstructionTypes.RM,
|
|
ALUOp2Source.Register,
|
|
ALUOp2Source.Immediate
|
|
)
|
|
io.memory_read_enable := opcode === InstructionTypes.L
|
|
io.memory_write_enable := opcode === InstructionTypes.S
|
|
io.wb_reg_write_source := MuxLookup(
|
|
opcode,
|
|
RegWriteSource.ALUResult,
|
|
IndexedSeq(
|
|
InstructionTypes.L -> RegWriteSource.Memory,
|
|
Instructions.jal -> RegWriteSource.NextInstructionAddress,
|
|
Instructions.jalr -> RegWriteSource.NextInstructionAddress,
|
|
Instructions.csr -> RegWriteSource.CSR
|
|
)
|
|
)
|
|
io.reg_write_enable := (opcode === InstructionTypes.RM) || (opcode === InstructionTypes.I) ||
|
|
(opcode === InstructionTypes.L) || (opcode === Instructions.auipc) || (opcode === Instructions.lui) ||
|
|
(opcode === Instructions.jal) || (opcode === Instructions.jalr) || (opcode === Instructions.csr)
|
|
io.reg_write_address := io.instruction(11, 7)
|
|
io.csr_reg_address := io.instruction(31,20)
|
|
io.csr_reg_write_enable := (opcode === Instructions.csr) && (
|
|
funct3 === InstructionsTypeCSR.csrrw || funct3 === InstructionsTypeCSR.csrrwi ||
|
|
funct3 === InstructionsTypeCSR.csrrs || funct3 === InstructionsTypeCSR.csrrsi ||
|
|
funct3 === InstructionsTypeCSR.csrrc || funct3 === InstructionsTypeCSR.csrrci
|
|
)
|
|
}
|