From b8660af50f9642d289989a2881b1f29d8a59f34e Mon Sep 17 00:00:00 2001
From: Martin Schoeberl <martin@jopdesign.com>
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