> configure(npc)
ysyx_22040000 李心杨 Linux calcite 6.6.19 #1-NixOS SMP PREEMPT_DYNAMIC Fri Mar 1 12:35:11 UTC 2024 x86_64 GNU/Linux 15:19:20 up 3 days 6:09, 2 users, load average: 2.75, 1.76, 1.60
This commit is contained in:
parent
0560c97eda
commit
a7d59b4d37
5 changed files with 81 additions and 35 deletions
|
@ -10,8 +10,8 @@ class ALUControlInterface extends Bundle {
|
|||
}
|
||||
val op = Input(OpSelect())
|
||||
|
||||
type ctrlTypes = OpSelect.Type :: HNil
|
||||
def ctrlBindPorts: ctrlTypes = {
|
||||
type CtrlTypes = OpSelect.Type :: HNil
|
||||
def ctrlBindPorts: CtrlTypes = {
|
||||
op :: HNil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ class PcControl(width: Int) extends Bundle {
|
|||
}
|
||||
|
||||
|
||||
import flow.components.{ RegisterFile, RegFileInterface, ProgramCounter, ALU }
|
||||
import flow.components.{ RegControl, PcControlInterface, ALUControlInterface }
|
||||
class Control(width: Int) extends Module {
|
||||
val inst = IO(Input(UInt(width.W)))
|
||||
|
@ -65,23 +64,43 @@ class Control(width: Int) extends Module {
|
|||
val slices = reversePrefixSum.zip(reversePrefixSum.tail)
|
||||
val srcList = slices.map(s => out(s._1 - 1, s._2))
|
||||
|
||||
// def m[T <: Data](src: UInt, dst: T) = dst match {
|
||||
// case dst: EnumType => dst := src.asTypeOf(chiselTypeOf(dst))
|
||||
// case dst: Data => dst := src
|
||||
// }
|
||||
|
||||
srcList.zip(dstList).foreach({
|
||||
case (src, dst) => dst := src.asTypeOf(dst)
|
||||
})
|
||||
}
|
||||
|
||||
import flow.components.{ RegisterFile, RegFileInterface, ProgramCounter, ALU }
|
||||
class Flow extends Module {
|
||||
val io = IO(new Bundle { })
|
||||
val ram = SRAM(size=128*1024*1024, tpe=UInt(32.W), numReadPorts=2, numWritePorts=1,numReadwritePorts=0)
|
||||
val dataType = UInt(32.W)
|
||||
|
||||
val ram = SRAM(size=128*1024*1024, tpe=dataType, numReadPorts=2, numWritePorts=1,numReadwritePorts=0)
|
||||
val control = Module(new Control(32))
|
||||
val reg = RegisterFile(32, dataType, 2, 2)
|
||||
val pc = Module(new ProgramCounter(dataType))
|
||||
val alu = Module(new ALU(dataType))
|
||||
|
||||
// Instruction Fetch
|
||||
ram.readPorts(0).enable := true.B
|
||||
val instruction = ram.readPorts(0).address
|
||||
ram.readPorts(0).address := pc.out
|
||||
val inst = ram.readPorts(0).data
|
||||
|
||||
control.inst := inst
|
||||
reg.control <> control.reg
|
||||
pc.control <> control.pc
|
||||
alu.control <> control.alu
|
||||
|
||||
import control.reg.WriteSelect._
|
||||
import control.pc.SrcSelect._
|
||||
import control.alu.OpSelect._
|
||||
|
||||
reg.in.writeData(rAluOut.litValue.toInt) := alu.out.result
|
||||
// TODO: Read address in load command goes here
|
||||
ram.readPorts(1).enable := false.B
|
||||
ram.readPorts(1).address := 0.U
|
||||
reg.in.writeData(rMemOut.litValue.toInt) := ram.readPorts(1).data
|
||||
reg.in.writeAddr := inst(11, 7)
|
||||
reg.in.rs(0) := inst(19, 15)
|
||||
reg.in.rs(1) := inst(24, 20)
|
||||
|
||||
alu.in.a := reg.out.src(0)
|
||||
alu.in.b := reg.out.src(1)
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ class PcControlInterface extends Bundle {
|
|||
|
||||
val srcSelect = Input(SrcSelect())
|
||||
|
||||
type ctrlTypes = SrcSelect.Type :: HNil
|
||||
def ctrlBindPorts: ctrlTypes = {
|
||||
type CtrlTypes = SrcSelect.Type :: HNil
|
||||
def ctrlBindPorts: CtrlTypes = {
|
||||
srcSelect :: HNil
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,10 @@ class ProgramCounter[T <: Data](tpe: T) extends Module {
|
|||
})
|
||||
val out = IO(Output(tpe))
|
||||
|
||||
out := in.pcSrcs(control.srcSelect.asUInt)
|
||||
private val pc = RegInit(0x80000000L.U)
|
||||
|
||||
pc := in.pcSrcs(control.srcSelect.asUInt)
|
||||
out := pc
|
||||
}
|
||||
|
||||
object ProgramCounter {
|
||||
|
|
|
@ -14,8 +14,8 @@ class RegControl extends Bundle {
|
|||
val writeEnable = Input(Bool())
|
||||
val writeSelect = Input(WriteSelect())
|
||||
|
||||
type ctrlTypes = Bool :: WriteSelect.Type :: HNil
|
||||
def ctrlBindPorts: ctrlTypes = {
|
||||
type CtrlTypes = Bool :: WriteSelect.Type :: HNil
|
||||
def ctrlBindPorts: CtrlTypes = {
|
||||
writeEnable :: writeSelect :: HNil
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,15 @@ class RegFileData[T <: Data](size:Int, tpe: T, numReadPorts: Int, numWritePorts:
|
|||
|
||||
class RegFileInterface[T <: Data](size: Int, tpe: T, numReadPorts: Int, numWritePorts: Int) extends Bundle {
|
||||
val control = new RegControl
|
||||
val data = new RegFileData(size, tpe, numReadPorts, numWritePorts)
|
||||
// val data = new RegFileData(size, tpe, numReadPorts, numWritePorts)
|
||||
val in = new Bundle {
|
||||
val writeAddr = Input(UInt(size.W))
|
||||
val writeData = Input(Vec(numWritePorts, tpe))
|
||||
val rs = Input(Vec(numReadPorts, UInt(size.W)))
|
||||
}
|
||||
val out = new Bundle {
|
||||
val src = Output(Vec(numReadPorts, tpe))
|
||||
}
|
||||
}
|
||||
|
||||
class RegisterFileCore[T <: Data](size: Int, tpe: T, numReadPorts: Int) extends Module {
|
||||
|
@ -66,13 +74,11 @@ object RegisterFile {
|
|||
val _out = Wire(new RegFileInterface(size, tpe, numReadPorts, numWritePorts))
|
||||
val clock = core.clock
|
||||
for (i <- 0 until numReadPorts) {
|
||||
core.readPorts(i).addr := _out.data.read(i).rs
|
||||
_out.data.read(i).src := core.readPorts(i).data
|
||||
core.readPorts(i).addr := _out.in.rs(i)
|
||||
_out.out.src(i) := core.readPorts(i).data
|
||||
}
|
||||
core.writePort.addr := _out.data.write.addr
|
||||
core.writePort.data := MuxLookup(_out.control.writeSelect, 0.U)(
|
||||
_out.control.WriteSelect.all.map(x => (x -> _out.data.write.data(x.asUInt).asUInt))
|
||||
)
|
||||
core.writePort.addr := _out.in.writeAddr
|
||||
core.writePort.data := _out.in.writeData(_out.control.writeSelect.asUInt)
|
||||
core.writePort.enable := _out.control.writeEnable
|
||||
_out
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package flowpc
|
||||
package flow
|
||||
|
||||
import chisel3._
|
||||
import chiseltest._
|
||||
|
@ -41,22 +41,40 @@ class RegisterFileSpec extends AnyFreeSpec with ChiselScalatestTester {
|
|||
}
|
||||
}
|
||||
"RegisterInterface" - {
|
||||
"worked" in {
|
||||
class Top extends Module {
|
||||
val io = IO(new RegFileInterface(32, UInt(32.W), 2, 2))
|
||||
val rf = RegisterFile(32, UInt(32.W), 2, 2)
|
||||
io :<>= rf
|
||||
}
|
||||
"write" in {
|
||||
test(new Top).withAnnotations(Seq(WriteVcdAnnotation)) { c =>
|
||||
import c.io.control.WriteSelect._
|
||||
val writePort = rAluOut.litValue.toInt
|
||||
c.io.control.writeEnable.poke(true)
|
||||
c.io.control.writeSelect.poke(rAluOut)
|
||||
c.io.data.write.addr.poke(5)
|
||||
c.io.data.write.data(writePort).poke(0xcdef)
|
||||
c.io.data.read(0).rs.poke(5)
|
||||
c.io.in.writeAddr.poke(5)
|
||||
c.io.in.writeData(writePort).poke(0xcdef)
|
||||
c.io.in.rs(0).poke(5)
|
||||
c.clock.step(1)
|
||||
c.io.data.read(0).src.expect(0xcdef)
|
||||
c.io.out.src(0).expect(0xcdef)
|
||||
}
|
||||
}
|
||||
"no data is written when not enabled" in {
|
||||
test(new Top).withAnnotations(Seq(WriteVcdAnnotation)) { c =>
|
||||
import c.io.control.WriteSelect._
|
||||
val writePort = rAluOut.litValue.toInt
|
||||
c.io.control.writeEnable.poke(true)
|
||||
c.io.control.writeSelect.poke(rAluOut)
|
||||
c.io.in.writeAddr.poke(5)
|
||||
c.io.in.writeData(writePort).poke(0xcdef)
|
||||
c.io.in.rs(0).poke(5)
|
||||
c.clock.step(1)
|
||||
|
||||
c.io.control.writeEnable.poke(false)
|
||||
c.io.in.writeData(writePort).poke(0x1234)
|
||||
c.clock.step(1)
|
||||
|
||||
c.io.out.src(0).expect(0xcdef)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue