From b8660af50f9642d289989a2881b1f29d8a59f34e Mon Sep 17 00:00:00 2001 From: Martin Schoeberl Date: Tue, 8 Oct 2024 09:27:11 -0700 Subject: [PATCH] Split Leros into core (Leros) and top that contains the memories --- Makefile | 4 +-- src/main/scala/leros/DataMem.scala | 18 +++++----- src/main/scala/leros/Leros.scala | 44 ++++++++++++++----------- src/main/scala/leros/LerosTestTop.scala | 12 +++---- src/main/scala/leros/LerosTop.scala | 37 +++++++++++++++++++++ 5 files changed, 79 insertions(+), 36 deletions(-) create mode 100644 src/main/scala/leros/LerosTop.scala diff --git a/Makefile b/Makefile index b83e7d4..897391a 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ swsim: sbt -Dprogram=$(APP) "testOnly leros.sim.LerosSimTest" hw: - sbt "runMain leros.Leros asm/$(APP).s" + sbt "runMain leros.LerosTop asm/$(APP).s" test-alu: sbt "test:runMain leros.AluTester" @@ -59,7 +59,7 @@ synpath: source /home/shared/Xilinx/Vivado/2017.4/settings64.sh synth: - ./vivado_synth -t Leros -p xc7a100tcsg324-1 -x nexysA7.xdc -o build generated/Leros.sv + ./vivado_synth -t LerosTop -p xc7a100tcsg324-1 -x nexysA7.xdc -o build generated/LerosTop.sv cp-bit: -mkdir build diff --git a/src/main/scala/leros/DataMem.scala b/src/main/scala/leros/DataMem.scala index 1796a74..780ce00 100644 --- a/src/main/scala/leros/DataMem.scala +++ b/src/main/scala/leros/DataMem.scala @@ -4,18 +4,20 @@ import chisel3._ import leros.util.Assembler +class DataMemIO(memAddrWidth: Int) extends Bundle { + val rdAddr = Input(UInt(memAddrWidth.W)) + val rdData = Output(UInt(32.W)) + val wrAddr = Input(UInt(memAddrWidth.W)) + val wrData = Input(UInt(32.W)) + val wr = Input(Bool()) + val wrMask = Input(UInt(4.W)) +} + /** * Data memory. */ class DataMem(memAddrWidth: Int, debugMem: Boolean = false) extends Module { - val io = IO(new Bundle { - val rdAddr = Input(UInt(memAddrWidth.W)) - val rdData = Output(UInt(32.W)) - val wrAddr = Input(UInt(memAddrWidth.W)) - val wrData = Input(UInt(32.W)) - val wr = Input(Bool()) - val wrMask = Input(UInt(4.W)) - }) + val io = IO(new DataMemIO(memAddrWidth)) val entries = 1 << memAddrWidth val wrVec = Wire(Vec(4, UInt(8.W))) diff --git a/src/main/scala/leros/Leros.scala b/src/main/scala/leros/Leros.scala index d9fa227..0fdaf9f 100644 --- a/src/main/scala/leros/Leros.scala +++ b/src/main/scala/leros/Leros.scala @@ -12,6 +12,12 @@ import leros.State._ */ class Leros(prog: String, size: Int = 32, memAddrWidth: Int = 8) extends Module { + val imemIO = IO(new Bundle { + val addr = Output(UInt(memAddrWidth.W)) + val instr = Input(UInt(16.W)) + }) + val dmemIO = IO(Flipped(new DataMemIO(memAddrWidth))) + val io = IO(new Bundle { // val dout = Output(UInt(32.W)) // val sw = Input(UInt(4.W)) @@ -29,9 +35,8 @@ class Leros(prog: String, size: Int = 32, memAddrWidth: Int = 8) extends Module val pcNext = WireDefault(pcReg + 1.U) // Fetch from instruction memory with an address register that is reset to 0 - val instrMem = Module(new InstrMem(memAddrWidth, prog)) - instrMem.io.addr := pcNext - val instr = instrMem.io.instr + imemIO.addr := pcNext + val instr = imemIO.instr // Decode val dec = Module(new Decode()) @@ -53,17 +58,16 @@ class Leros(prog: String, size: Int = 32, memAddrWidth: Int = 8) extends Module // Data memory, including the register memory // read in fetch, write in execute - val dataMem = Module(new DataMem((memAddrWidth), false)) val memAddr = Mux(decout.isDataAccess, effAddrWord, instr(7, 0)) val memAddrReg = RegNext(memAddr) val effAddrOffReg = RegNext(effAddrOff) - dataMem.io.rdAddr := memAddr - val dataRead = dataMem.io.rdData - dataMem.io.wrAddr := memAddrReg - dataMem.io.wrData := accu - dataMem.io.wr := false.B - dataMem.io.wrMask := "b1111".U + dmemIO.rdAddr := memAddr + val dataRead = dmemIO.rdData + dmemIO.wrAddr := memAddrReg + dmemIO.wrData := accu + dmemIO.wr := false.B + dmemIO.wrMask := "b1111".U // ALU connection alu.io.op := decReg.op @@ -105,11 +109,11 @@ class Leros(prog: String, size: Int = 32, memAddrWidth: Int = 8) extends Module } is (store) { - dataMem.io.wr := true.B + dmemIO.wr := true.B } is (storeInd) { - dataMem.io.wr := true.B + dmemIO.wr := true.B // TODO: am I missing here something? See the other store indirect // TODO: this is a super quick hack to get the LED blinking outReg := accu @@ -117,18 +121,18 @@ class Leros(prog: String, size: Int = 32, memAddrWidth: Int = 8) extends Module is (storeIndB) { // wr and wrMask could be set in decode and registered - dataMem.io.wr := true.B - dataMem.io.wrMask := "b0001".U << effAddrOffReg + dmemIO.wr := true.B + dmemIO.wrMask := "b0001".U << effAddrOffReg vecAccu(effAddrOffReg) := accu(7, 0) - dataMem.io.wrData := vecAccu(3) ## vecAccu(2) ## vecAccu(1) ## vecAccu(0) + dmemIO.wrData := vecAccu(3) ## vecAccu(2) ## vecAccu(1) ## vecAccu(0) } is (storeIndH) { - dataMem.io.wr := true.B - dataMem.io.wrMask := "b0011".U << effAddrOffReg + dmemIO.wr := true.B + dmemIO.wrMask := "b0011".U << effAddrOffReg vecAccu(effAddrOffReg) := accu(7, 0) vecAccu(effAddrOffReg | 1.U) := accu(15, 8) - dataMem.io.wrData := vecAccu(3) ## vecAccu(2) ## vecAccu(1) ## vecAccu(0) + dmemIO.wrData := vecAccu(3) ## vecAccu(2) ## vecAccu(1) ## vecAccu(0) } is (branch) { @@ -147,8 +151,8 @@ class Leros(prog: String, size: Int = 32, memAddrWidth: Int = 8) extends Module is (jal) { pcNext := accu - dataMem.io.wr := true.B - dataMem.io.wrData := pcReg + 1.U + dmemIO.wr := true.B + dmemIO.wrData := pcReg + 1.U } is (scall) { diff --git a/src/main/scala/leros/LerosTestTop.scala b/src/main/scala/leros/LerosTestTop.scala index 27a7989..9631ee9 100644 --- a/src/main/scala/leros/LerosTestTop.scala +++ b/src/main/scala/leros/LerosTestTop.scala @@ -25,18 +25,18 @@ class LerosTestTop(prog: String, size: Int = 32, memAddrWidth: Int = 8) extends val dbg = new Debug(size, memAddrWidth) val led = Output(UInt(8.W)) }) - val leros = Module(new Leros(prog)) - io.led := leros.io.led + val lerosTop = Module(new LerosTop(prog)) + io.led := lerosTop.io.led // Boring Utils for debugging io.dbg.accu := DontCare io.dbg.pc := DontCare io.dbg.instr := DontCare io.dbg.exit := DontCare - BoringUtils.bore(leros.accu, Seq(io.dbg.accu)) - BoringUtils.bore(leros.pcReg, Seq(io.dbg.pc)) - BoringUtils.bore(leros.instr, Seq(io.dbg.instr)) - BoringUtils.bore(leros.exit, Seq(io.dbg.exit)) + BoringUtils.bore(lerosTop.leros.accu, Seq(io.dbg.accu)) + BoringUtils.bore(lerosTop.leros.pcReg, Seq(io.dbg.pc)) + BoringUtils.bore(lerosTop.leros.instr, Seq(io.dbg.instr)) + BoringUtils.bore(lerosTop.leros.exit, Seq(io.dbg.exit)) } diff --git a/src/main/scala/leros/LerosTop.scala b/src/main/scala/leros/LerosTop.scala new file mode 100644 index 0000000..edfcd7d --- /dev/null +++ b/src/main/scala/leros/LerosTop.scala @@ -0,0 +1,37 @@ +package leros + +import chisel3._ +import chisel3.util._ +import leros.State._ +import leros.shared.Constants._ + +/** + * Leros top level. + * + * Sequential implementation with two states. + */ +class LerosTop(prog: String, size: Int = 32, memAddrWidth: Int = 8) extends Module { + + val io = IO(new Bundle { + // val dout = Output(UInt(32.W)) + // val sw = Input(UInt(4.W)) + val led = Output(UInt(8.W)) + }) + + val leros = Module(new Leros(prog)) + // Fetch from instruction memory with an address register that is reset to 0 + val instrMem = Module(new InstrMem(memAddrWidth, prog)) + // Data memory, including the register memory + // read in fetch, write in execute + val dataMem = Module(new DataMem((memAddrWidth), false)) + + instrMem.io <> leros.imemIO + dataMem.io <> leros.dmemIO + + // TODO: LED and decoding for it + io.led := leros.io.led +} + +object LerosTop extends App { + emitVerilog(new LerosTop(args(0)), Array("--target-dir", "generated")) +} \ No newline at end of file