mirror of
https://github.com/handsomezhuzhu/2025-yatcpu.git
synced 2026-02-20 20:10:14 +00:00
整理
This commit is contained in:
70
lab1/朱梓涵24325356/core/ALU.scala
Normal file
70
lab1/朱梓涵24325356/core/ALU.scala
Normal file
@@ -0,0 +1,70 @@
|
||||
// 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.experimental.ChiselEnum
|
||||
import chisel3.util._
|
||||
import riscv.Parameters
|
||||
|
||||
object ALUFunctions extends ChiselEnum {
|
||||
val zero, add, sub, sll, slt, xor, or, and, srl, sra, sltu = Value
|
||||
}
|
||||
|
||||
class ALU extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val func = Input(ALUFunctions())
|
||||
|
||||
val op1 = Input(UInt(Parameters.DataWidth))
|
||||
val op2 = Input(UInt(Parameters.DataWidth))
|
||||
|
||||
val result = Output(UInt(Parameters.DataWidth))
|
||||
})
|
||||
|
||||
io.result := 0.U
|
||||
switch(io.func) {
|
||||
is(ALUFunctions.add) {
|
||||
io.result := io.op1 + io.op2
|
||||
}
|
||||
is(ALUFunctions.sub) {
|
||||
io.result := io.op1 - io.op2
|
||||
}
|
||||
is(ALUFunctions.sll) {
|
||||
io.result := io.op1 << io.op2(4, 0)
|
||||
}
|
||||
is(ALUFunctions.slt) {
|
||||
io.result := io.op1.asSInt < io.op2.asSInt
|
||||
}
|
||||
is(ALUFunctions.xor) {
|
||||
io.result := io.op1 ^ io.op2
|
||||
}
|
||||
is(ALUFunctions.or) {
|
||||
io.result := io.op1 | io.op2
|
||||
}
|
||||
is(ALUFunctions.and) {
|
||||
io.result := io.op1 & io.op2
|
||||
}
|
||||
is(ALUFunctions.srl) {
|
||||
io.result := io.op1 >> io.op2(4, 0)
|
||||
}
|
||||
is(ALUFunctions.sra) {
|
||||
io.result := (io.op1.asSInt >> io.op2(4, 0)).asUInt
|
||||
}
|
||||
is(ALUFunctions.sltu) {
|
||||
io.result := io.op1 < io.op2
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
86
lab1/朱梓涵24325356/core/ALUControl.scala
Normal file
86
lab1/朱梓涵24325356/core/ALUControl.scala
Normal file
@@ -0,0 +1,86 @@
|
||||
// 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._
|
||||
|
||||
class ALUControl extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val opcode = Input(UInt(7.W))
|
||||
val funct3 = Input(UInt(3.W))
|
||||
val funct7 = Input(UInt(7.W))
|
||||
|
||||
val alu_funct = Output(ALUFunctions())
|
||||
})
|
||||
|
||||
io.alu_funct := ALUFunctions.zero
|
||||
|
||||
switch(io.opcode) {
|
||||
is(InstructionTypes.I) {
|
||||
io.alu_funct := MuxLookup(
|
||||
io.funct3,
|
||||
ALUFunctions.zero,
|
||||
IndexedSeq(
|
||||
InstructionsTypeI.addi -> ALUFunctions.add,
|
||||
InstructionsTypeI.slli -> ALUFunctions.sll,
|
||||
InstructionsTypeI.slti -> ALUFunctions.slt,
|
||||
InstructionsTypeI.sltiu -> ALUFunctions.sltu,
|
||||
InstructionsTypeI.xori -> ALUFunctions.xor,
|
||||
InstructionsTypeI.ori -> ALUFunctions.or,
|
||||
InstructionsTypeI.andi -> ALUFunctions.and,
|
||||
InstructionsTypeI.sri -> Mux(io.funct7(5), ALUFunctions.sra, ALUFunctions.srl)
|
||||
),
|
||||
)
|
||||
}
|
||||
is(InstructionTypes.RM) {
|
||||
io.alu_funct := MuxLookup(
|
||||
io.funct3,
|
||||
ALUFunctions.zero,
|
||||
IndexedSeq(
|
||||
InstructionsTypeR.add_sub -> Mux(io.funct7(5), ALUFunctions.sub, ALUFunctions.add),
|
||||
InstructionsTypeR.sll -> ALUFunctions.sll,
|
||||
InstructionsTypeR.slt -> ALUFunctions.slt,
|
||||
InstructionsTypeR.sltu -> ALUFunctions.sltu,
|
||||
InstructionsTypeR.xor -> ALUFunctions.xor,
|
||||
InstructionsTypeR.or -> ALUFunctions.or,
|
||||
InstructionsTypeR.and -> ALUFunctions.and,
|
||||
InstructionsTypeR.sr -> Mux(io.funct7(5), ALUFunctions.sra, ALUFunctions.srl)
|
||||
),
|
||||
)
|
||||
}
|
||||
is(InstructionTypes.B) {
|
||||
io.alu_funct := ALUFunctions.add
|
||||
}
|
||||
is(InstructionTypes.L) {
|
||||
io.alu_funct := ALUFunctions.add
|
||||
}
|
||||
is(InstructionTypes.S) {
|
||||
io.alu_funct := ALUFunctions.add
|
||||
}
|
||||
is(Instructions.jal) {
|
||||
io.alu_funct := ALUFunctions.add
|
||||
}
|
||||
is(Instructions.jalr) {
|
||||
io.alu_funct := ALUFunctions.add
|
||||
}
|
||||
is(Instructions.lui) {
|
||||
io.alu_funct := ALUFunctions.add
|
||||
}
|
||||
is(Instructions.auipc) {
|
||||
io.alu_funct := ALUFunctions.add
|
||||
}
|
||||
}
|
||||
}
|
||||
82
lab1/朱梓涵24325356/core/CPU.scala
Normal file
82
lab1/朱梓涵24325356/core/CPU.scala
Normal file
@@ -0,0 +1,82 @@
|
||||
// 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
|
||||
import riscv.{CPUBundle, Parameters}
|
||||
|
||||
class CPU extends Module {
|
||||
val io = IO(new CPUBundle)
|
||||
|
||||
val regs = Module(new RegisterFile)
|
||||
val inst_fetch = Module(new InstructionFetch)
|
||||
val id = Module(new InstructionDecode)
|
||||
val ex = Module(new Execute)
|
||||
val mem = Module(new MemoryAccess)
|
||||
val wb = Module(new WriteBack)
|
||||
|
||||
|
||||
io.deviceSelect := mem.io.memory_bundle.address(Parameters.AddrBits - 1, Parameters.AddrBits - Parameters.SlaveDeviceCountBits)
|
||||
|
||||
inst_fetch.io.jump_address_id := ex.io.if_jump_address
|
||||
inst_fetch.io.jump_flag_id := ex.io.if_jump_flag
|
||||
inst_fetch.io.instruction_valid := io.instruction_valid
|
||||
inst_fetch.io.instruction_read_data := io.instruction
|
||||
io.instruction_address := inst_fetch.io.instruction_address
|
||||
|
||||
regs.io.write_enable := id.io.reg_write_enable
|
||||
regs.io.write_address := id.io.reg_write_address
|
||||
regs.io.write_data := wb.io.regs_write_data
|
||||
regs.io.read_address1 := id.io.regs_reg1_read_address
|
||||
regs.io.read_address2 := id.io.regs_reg2_read_address
|
||||
|
||||
regs.io.debug_read_address := io.debug_read_address
|
||||
io.debug_read_data := regs.io.debug_read_data
|
||||
|
||||
id.io.instruction := inst_fetch.io.instruction
|
||||
|
||||
// lab1(cpu)
|
||||
|
||||
ex.io.instruction := inst_fetch.io.instruction
|
||||
ex.io.instruction_address := inst_fetch.io.instruction_address
|
||||
ex.io.reg1_data := regs.io.read_data1
|
||||
ex.io.reg2_data := regs.io.read_data2
|
||||
ex.io.immediate := id.io.ex_immediate
|
||||
ex.io.aluop1_source := id.io.ex_aluop1_source
|
||||
ex.io.aluop2_source := id.io.ex_aluop2_source
|
||||
|
||||
|
||||
|
||||
// lab1(cpu) end
|
||||
|
||||
|
||||
mem.io.alu_result := ex.io.mem_alu_result
|
||||
mem.io.reg2_data := regs.io.read_data2
|
||||
mem.io.memory_read_enable := id.io.memory_read_enable
|
||||
mem.io.memory_write_enable := id.io.memory_write_enable
|
||||
mem.io.funct3 := inst_fetch.io.instruction(14, 12)
|
||||
|
||||
io.memory_bundle.address := Cat(0.U(Parameters.SlaveDeviceCountBits.W),mem.io.memory_bundle.address(Parameters.AddrBits - 1 - Parameters.SlaveDeviceCountBits, 0))
|
||||
io.memory_bundle.write_enable := mem.io.memory_bundle.write_enable
|
||||
io.memory_bundle.write_data := mem.io.memory_bundle.write_data
|
||||
io.memory_bundle.write_strobe := mem.io.memory_bundle.write_strobe
|
||||
mem.io.memory_bundle.read_data := io.memory_bundle.read_data
|
||||
|
||||
wb.io.instruction_address := inst_fetch.io.instruction_address
|
||||
wb.io.alu_result := ex.io.mem_alu_result
|
||||
wb.io.memory_read_data := mem.io.wb_memory_read_data
|
||||
wb.io.regs_write_source := id.io.wb_reg_write_source
|
||||
}
|
||||
81
lab1/朱梓涵24325356/core/Execute.scala
Normal file
81
lab1/朱梓涵24325356/core/Execute.scala
Normal file
@@ -0,0 +1,81 @@
|
||||
// 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 mem_alu_result = 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 rd = io.instruction(11, 7)
|
||||
val uimm = io.instruction(19, 15)
|
||||
|
||||
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
|
||||
|
||||
// lab1(Execute)
|
||||
alu.io.func := alu_ctrl.io.alu_funct
|
||||
alu.io.op1 := Mux(
|
||||
io.aluop1_source === ALUOp1Source.Register,
|
||||
io.reg1_data,
|
||||
io.instruction_address
|
||||
)
|
||||
alu.io.op2 := Mux(
|
||||
io.aluop2_source === ALUOp2Source.Register,
|
||||
io.reg2_data,
|
||||
io.immediate
|
||||
)
|
||||
|
||||
|
||||
// lab1(Execute) end
|
||||
|
||||
io.mem_alu_result := alu.io.result
|
||||
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)
|
||||
}
|
||||
205
lab1/朱梓涵24325356/core/InstructionDecode.scala
Normal file
205
lab1/朱梓涵24325356/core/InstructionDecode.scala
Normal file
@@ -0,0 +1,205 @@
|
||||
// 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 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
|
||||
)
|
||||
|
||||
// lab1(InstructionDecode)
|
||||
io.ex_aluop2_source := Mux(opcode === InstructionTypes.RM,
|
||||
ALUOp2Source.Register,
|
||||
ALUOp2Source.Immediate
|
||||
)
|
||||
// 仅当指令是 Load 类型时,才使能内存读。
|
||||
io.memory_read_enable := opcode === InstructionTypes.L
|
||||
// 仅当指令是 Store 类型时,才使能内存写。
|
||||
io.memory_write_enable := opcode === InstructionTypes.S
|
||||
// 根据指令类型,选择写回寄存器的数据来源。
|
||||
io.wb_reg_write_source := MuxLookup(
|
||||
opcode,
|
||||
RegWriteSource.ALUResult // 默认来源是ALU计算结果
|
||||
)( // 使用新的 MuxLookup 语法
|
||||
IndexedSeq(
|
||||
InstructionTypes.L -> RegWriteSource.Memory, // Load 指令来源是内存
|
||||
Instructions.jal -> RegWriteSource.NextInstructionAddress, // jal/jalr 来源是下一条指令地址 (PC+4)
|
||||
Instructions.jalr -> RegWriteSource.NextInstructionAddress
|
||||
)
|
||||
)
|
||||
// lab1(InstructionDecode) end
|
||||
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)
|
||||
io.reg_write_address := io.instruction(11, 7)
|
||||
}
|
||||
55
lab1/朱梓涵24325356/core/InstructionFetch.scala
Normal file
55
lab1/朱梓涵24325356/core/InstructionFetch.scala
Normal file
@@ -0,0 +1,55 @@
|
||||
// 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 riscv.Parameters
|
||||
|
||||
object ProgramCounter {
|
||||
val EntryAddress = Parameters.EntryAddress
|
||||
}
|
||||
|
||||
class InstructionFetch extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val jump_flag_id = Input(Bool())
|
||||
val jump_address_id = Input(UInt(Parameters.AddrWidth))
|
||||
val instruction_read_data = Input(UInt(Parameters.DataWidth))
|
||||
val instruction_valid = Input(Bool())
|
||||
|
||||
val instruction_address = Output(UInt(Parameters.AddrWidth))
|
||||
val instruction = Output(UInt(Parameters.InstructionWidth))
|
||||
})
|
||||
val pc = RegInit(ProgramCounter.EntryAddress)
|
||||
|
||||
when(io.instruction_valid) {
|
||||
io.instruction := io.instruction_read_data
|
||||
// lab1(InstructionFetch)
|
||||
|
||||
when(io.jump_flag_id) {
|
||||
pc := io.jump_address_id
|
||||
}.otherwise {
|
||||
pc := pc + 4.U
|
||||
}
|
||||
|
||||
|
||||
// la1(InstructionFetch) end
|
||||
|
||||
|
||||
}.otherwise{
|
||||
pc := pc
|
||||
io.instruction := 0x00000013.U
|
||||
}
|
||||
io.instruction_address := pc
|
||||
}
|
||||
106
lab1/朱梓涵24325356/core/MemoryAccess.scala
Normal file
106
lab1/朱梓涵24325356/core/MemoryAccess.scala
Normal file
@@ -0,0 +1,106 @@
|
||||
// Copyright 2022 Canbin Huang
|
||||
//
|
||||
// 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 peripheral.RAMBundle
|
||||
import riscv.Parameters
|
||||
|
||||
class MemoryAccess extends Module {
|
||||
val io = IO(new Bundle() {
|
||||
val alu_result = Input(UInt(Parameters.DataWidth))
|
||||
val reg2_data = Input(UInt(Parameters.DataWidth))
|
||||
val memory_read_enable = Input(Bool())
|
||||
val memory_write_enable = Input(Bool())
|
||||
val funct3 = Input(UInt(3.W))
|
||||
|
||||
val wb_memory_read_data = Output(UInt(Parameters.DataWidth))
|
||||
|
||||
val memory_bundle = Flipped(new RAMBundle)
|
||||
})
|
||||
val mem_address_index = io.alu_result(log2Up(Parameters.WordSize) - 1, 0).asUInt
|
||||
|
||||
io.memory_bundle.write_enable := false.B
|
||||
io.memory_bundle.write_data := 0.U
|
||||
io.memory_bundle.address := io.alu_result
|
||||
io.memory_bundle.write_strobe := VecInit(Seq.fill(Parameters.WordSize)(false.B))
|
||||
io.wb_memory_read_data := 0.U
|
||||
|
||||
when(io.memory_read_enable) {
|
||||
val data = io.memory_bundle.read_data
|
||||
io.wb_memory_read_data := MuxLookup(
|
||||
io.funct3,
|
||||
0.U,
|
||||
IndexedSeq(
|
||||
InstructionsTypeL.lb -> MuxLookup(
|
||||
mem_address_index,
|
||||
Cat(Fill(24, data(31)), data(31, 24)),
|
||||
IndexedSeq(
|
||||
0.U -> Cat(Fill(24, data(7)), data(7, 0)),
|
||||
1.U -> Cat(Fill(24, data(15)), data(15, 8)),
|
||||
2.U -> Cat(Fill(24, data(23)), data(23, 16))
|
||||
)
|
||||
),
|
||||
InstructionsTypeL.lbu -> MuxLookup(
|
||||
mem_address_index,
|
||||
Cat(Fill(24, 0.U), data(31, 24)),
|
||||
IndexedSeq(
|
||||
0.U -> Cat(Fill(24, 0.U), data(7, 0)),
|
||||
1.U -> Cat(Fill(24, 0.U), data(15, 8)),
|
||||
2.U -> Cat(Fill(24, 0.U), data(23, 16))
|
||||
)
|
||||
),
|
||||
InstructionsTypeL.lh -> Mux(
|
||||
mem_address_index === 0.U,
|
||||
Cat(Fill(16, data(15)), data(15, 0)),
|
||||
Cat(Fill(16, data(31)), data(31, 16))
|
||||
|
||||
),
|
||||
InstructionsTypeL.lhu -> Mux(
|
||||
mem_address_index === 0.U,
|
||||
Cat(Fill(16, 0.U), data(15, 0)),
|
||||
Cat(Fill(16, 0.U), data(31, 16))
|
||||
),
|
||||
InstructionsTypeL.lw -> data
|
||||
)
|
||||
)
|
||||
}.elsewhen(io.memory_write_enable) {
|
||||
io.memory_bundle.write_data := io.reg2_data
|
||||
io.memory_bundle.write_enable := true.B
|
||||
io.memory_bundle.write_strobe := VecInit(Seq.fill(Parameters.WordSize)(false.B))
|
||||
when(io.funct3 === InstructionsTypeS.sb) {
|
||||
io.memory_bundle.write_strobe(mem_address_index) := true.B
|
||||
io.memory_bundle.write_data := io.reg2_data(Parameters.ByteBits, 0) << (mem_address_index << log2Up(Parameters.ByteBits).U)
|
||||
}.elsewhen(io.funct3 === InstructionsTypeS.sh) {
|
||||
when(mem_address_index === 0.U) {
|
||||
for (i <- 0 until Parameters.WordSize / 2) {
|
||||
io.memory_bundle.write_strobe(i) := true.B
|
||||
}
|
||||
io.memory_bundle.write_data := io.reg2_data(Parameters.WordSize / 2 * Parameters.ByteBits, 0)
|
||||
}.otherwise {
|
||||
for (i <- Parameters.WordSize / 2 until Parameters.WordSize) {
|
||||
io.memory_bundle.write_strobe(i) := true.B
|
||||
}
|
||||
io.memory_bundle.write_data := io.reg2_data(Parameters.WordSize / 2 * Parameters.ByteBits, 0) << (Parameters
|
||||
.WordSize / 2 * Parameters.ByteBits)
|
||||
}
|
||||
}.elsewhen(io.funct3 === InstructionsTypeS.sw) {
|
||||
for (i <- 0 until Parameters.WordSize) {
|
||||
io.memory_bundle.write_strobe(i) := true.B
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
70
lab1/朱梓涵24325356/core/RegisterFile.scala
Normal file
70
lab1/朱梓涵24325356/core/RegisterFile.scala
Normal file
@@ -0,0 +1,70 @@
|
||||
// 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 riscv.Parameters
|
||||
|
||||
object Registers extends Enumeration {
|
||||
type Register = Value
|
||||
val zero,
|
||||
ra, sp, gp, tp,
|
||||
t0, t1, t2, fp,
|
||||
s1,
|
||||
a0, a1, a2, a3, a4, a5, a6, a7,
|
||||
s2, s3, s4, s5, s6, s7, s8, s9, s10, s11,
|
||||
t3, t4, t5, t6 = Value
|
||||
}
|
||||
|
||||
class RegisterFile extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val write_enable = Input(Bool())
|
||||
val write_address = Input(UInt(Parameters.PhysicalRegisterAddrWidth))
|
||||
val write_data = Input(UInt(Parameters.DataWidth))
|
||||
|
||||
val read_address1 = Input(UInt(Parameters.PhysicalRegisterAddrWidth))
|
||||
val read_address2 = Input(UInt(Parameters.PhysicalRegisterAddrWidth))
|
||||
val read_data1 = Output(UInt(Parameters.DataWidth))
|
||||
val read_data2 = Output(UInt(Parameters.DataWidth))
|
||||
|
||||
val debug_read_address = Input(UInt(Parameters.PhysicalRegisterAddrWidth))
|
||||
val debug_read_data = Output(UInt(Parameters.DataWidth))
|
||||
})
|
||||
val registers = RegInit(VecInit(Seq.fill(Parameters.PhysicalRegisters)(0.U(Parameters.DataWidth))))
|
||||
|
||||
when(!reset.asBool) {
|
||||
when(io.write_enable && io.write_address =/= 0.U) {
|
||||
registers(io.write_address) := io.write_data
|
||||
}
|
||||
}
|
||||
|
||||
io.read_data1 := Mux(
|
||||
io.read_address1 === 0.U,
|
||||
0.U,
|
||||
registers(io.read_address1)
|
||||
)
|
||||
|
||||
io.read_data2 := Mux(
|
||||
io.read_address2 === 0.U,
|
||||
0.U,
|
||||
registers(io.read_address2)
|
||||
)
|
||||
|
||||
io.debug_read_data := Mux(
|
||||
io.debug_read_address === 0.U,
|
||||
0.U,
|
||||
registers(io.debug_read_address)
|
||||
)
|
||||
}
|
||||
37
lab1/朱梓涵24325356/core/WriteBack.scala
Normal file
37
lab1/朱梓涵24325356/core/WriteBack.scala
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2022 Canbin Huang
|
||||
//
|
||||
// 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
|
||||
|
||||
class WriteBack extends Module {
|
||||
val io = IO(new Bundle() {
|
||||
val instruction_address = Input(UInt(Parameters.AddrWidth))
|
||||
val alu_result = Input(UInt(Parameters.DataWidth))
|
||||
val memory_read_data = Input(UInt(Parameters.DataWidth))
|
||||
val regs_write_source = Input(UInt(2.W))
|
||||
val regs_write_data = Output(UInt(Parameters.DataWidth))
|
||||
})
|
||||
io.regs_write_data := MuxLookup(
|
||||
io.regs_write_source,
|
||||
io.alu_result,
|
||||
IndexedSeq(
|
||||
RegWriteSource.Memory -> io.memory_read_data,
|
||||
RegWriteSource.NextInstructionAddress -> (io.instruction_address + 4.U)
|
||||
)
|
||||
)
|
||||
}
|
||||
BIN
lab1/朱梓涵24325356/report.pdf
Normal file
BIN
lab1/朱梓涵24325356/report.pdf
Normal file
Binary file not shown.
Reference in New Issue
Block a user