From 8ad846b861f584c2790f815d7991d49247db5263 Mon Sep 17 00:00:00 2001
From: Minyong Li <ml10g20@soton.ac.uk>
Date: Sun, 11 Jul 2021 17:48:54 +0100
Subject: [PATCH] core.CanCore: re-impl, refactor

This version of core uses a more RISC-like architecture.

- a register file is added
- unused configs and signals are removed
- various changes
---
 .../ecs/can/config/CanCoreConfiguration.scala |  4 +-
 .../uk/ac/soton/ecs/can/core/CanCore.scala    | 92 ++++++++++++++++++-
 .../ac/soton/ecs/can/core/RegisterFile.scala  | 25 +++++
 .../ecs/can/types/CanCoreControlWord.scala    |  7 +-
 4 files changed, 123 insertions(+), 5 deletions(-)
 create mode 100644 src/main/scala/uk/ac/soton/ecs/can/core/RegisterFile.scala

diff --git a/src/main/scala/uk/ac/soton/ecs/can/config/CanCoreConfiguration.scala b/src/main/scala/uk/ac/soton/ecs/can/config/CanCoreConfiguration.scala
index c6acc2b..26fb9e3 100644
--- a/src/main/scala/uk/ac/soton/ecs/can/config/CanCoreConfiguration.scala
+++ b/src/main/scala/uk/ac/soton/ecs/can/config/CanCoreConfiguration.scala
@@ -8,8 +8,6 @@ case class CanCoreConfiguration(
     programMemoryWords: Int,
     dataMemoryWords: Int,
     syncReadMemory: Boolean,
-    regAfterBlockInitializer: Boolean,
-    regBetweenRounds: Boolean,
-    regAfterAdder: Boolean,
+    registerFileWords: Int,
     quarterRoundType: Int
 )
diff --git a/src/main/scala/uk/ac/soton/ecs/can/core/CanCore.scala b/src/main/scala/uk/ac/soton/ecs/can/core/CanCore.scala
index 25705df..7c903e9 100644
--- a/src/main/scala/uk/ac/soton/ecs/can/core/CanCore.scala
+++ b/src/main/scala/uk/ac/soton/ecs/can/core/CanCore.scala
@@ -4,6 +4,96 @@
 package uk.ac.soton.ecs.can.core
 
 import chisel3._
+import chisel3.util.log2Ceil
+import uk.ac.soton.ecs.can.types._
 import uk.ac.soton.ecs.can.config.CanCoreConfiguration
 
-class CanCore(implicit cfg: CanCoreConfiguration) extends MultiIOModule {}
+class CanCore(implicit cfg: CanCoreConfiguration) extends MultiIOModule {
+
+  //////////////////// Calculated parameters ////////////////////
+
+  private val programMemoryAddressWidth = log2Ceil(cfg.programMemoryWords)
+  private val programMemoryDataWidth = (new CanCoreControlWord).getWidth
+  private val dataMemoryAddressWidth = log2Ceil(cfg.dataMemoryWords)
+  private val dataMemoryDataWidth = 512
+
+  //////////////////// Ports ////////////////////
+
+  val io = IO(new Bundle {
+    val programMemory = new Bundle {
+      val read =
+        new MemoryReadIO(programMemoryAddressWidth, programMemoryDataWidth)
+      val write =
+        new MemoryWriteIO(programMemoryAddressWidth, programMemoryDataWidth)
+    }
+    val dataMemory = new Bundle {
+      val take = Input(Bool())
+      val read =
+        new MemoryReadIO(dataMemoryAddressWidth, dataMemoryDataWidth)
+      val write =
+        new MemoryWriteIO(dataMemoryAddressWidth, dataMemoryDataWidth)
+    }
+  })
+
+  //////////////////// Modules ////////////////////
+
+  private val programMemory = Module(new ProgramMemory)
+  private val dataMemory = Module(new DataMemory)
+  private val registerFile = Module(new RegisterFile)
+  private val alu = Module(new ALU)
+
+  //////////////////// Control Paths ////////////////////
+
+  private val ctrl = programMemory.cw.asTypeOf(new CanCoreControlWord)
+
+  programMemory.br.abs := ctrl.absoluteBranch
+  programMemory.br.rel := ctrl.relativeBranch
+  programMemory.br.addr := ctrl.immediate
+
+  dataMemory.read.addr := Mux(
+    io.dataMemory.take,
+    io.dataMemory.read.addr,
+    ctrl.dataMemoryReadAddress
+  )
+  dataMemory.write.en := Mux(
+    io.dataMemory.take,
+    io.dataMemory.write.en,
+    ctrl.dataMemoryWriteEnable
+  )
+  dataMemory.write.addr := Mux(
+    io.dataMemory.take,
+    io.dataMemory.write.addr,
+    ctrl.dataMemoryWriteAddress
+  )
+
+  registerFile.read(0).addr := ctrl.registerFileReadAddress(0)
+  registerFile.read(1).addr := ctrl.registerFileReadAddress(1)
+
+  registerFile.write.en := ctrl.registerFileWriteEnable
+  registerFile.write.addr := ctrl.registerFileWriteAddress
+
+  alu.fillConstant := ctrl.fillConstant
+  alu.incrementBlockCount := ctrl.incrementBlockCount
+  alu.f := ctrl.aluFunction
+
+  //////////////////// Data Paths ////////////////////
+
+  programMemory.read <> io.programMemory.read
+  programMemory.write <> io.programMemory.write
+
+  io.dataMemory.read.data := dataMemory.read.data
+  dataMemory.write.data := Mux(
+    io.dataMemory.take,
+    io.dataMemory.write.data,
+    alu.y
+  )
+
+  alu.a := registerFile.read(0).data
+  alu.b := registerFile.read(1).data
+  registerFile.write.data := Mux(
+    ctrl.registerFileWriteFrom,
+    dataMemory.read.data,
+    alu.y
+  )
+
+}
diff --git a/src/main/scala/uk/ac/soton/ecs/can/core/RegisterFile.scala b/src/main/scala/uk/ac/soton/ecs/can/core/RegisterFile.scala
new file mode 100644
index 0000000..dc29fb9
--- /dev/null
+++ b/src/main/scala/uk/ac/soton/ecs/can/core/RegisterFile.scala
@@ -0,0 +1,25 @@
+// SPDX-FileCopyrightText: 2021 Minyong Li <ml10g20@soton.ac.uk>
+// SPDX-License-Identifier: CERN-OHL-W-2.0
+
+package uk.ac.soton.ecs.can.core
+
+import chisel3._
+import chisel3.util._
+import uk.ac.soton.ecs.can.types._
+import uk.ac.soton.ecs.can.config.CanCoreConfiguration
+
+class RegisterFile(implicit cfg: CanCoreConfiguration) extends MultiIOModule {
+  private val addrWidth = log2Ceil(cfg.registerFileWords)
+
+  val read = IO(Vec(2, new MemoryReadIO(addrWidth, 512)))
+  val write = IO(new MemoryWriteIO(addrWidth, 512))
+
+  private val reg = Reg(Vec(cfg.registerFileWords, UInt(512.W)))
+
+  read(0).data := reg(read(0).addr)
+  read(1).data := reg(read(1).addr)
+
+  when(write.en) {
+    reg(write.addr) := write.data
+  }
+}
diff --git a/src/main/scala/uk/ac/soton/ecs/can/types/CanCoreControlWord.scala b/src/main/scala/uk/ac/soton/ecs/can/types/CanCoreControlWord.scala
index 63439d1..0ccc8e5 100644
--- a/src/main/scala/uk/ac/soton/ecs/can/types/CanCoreControlWord.scala
+++ b/src/main/scala/uk/ac/soton/ecs/can/types/CanCoreControlWord.scala
@@ -10,16 +10,21 @@ import uk.ac.soton.ecs.can.config.CanCoreConfiguration
 class CanCoreControlWord(implicit val cfg: CanCoreConfiguration)
     extends Bundle {
   private val dataMemoryAddressWidth = log2Ceil(cfg.dataMemoryWords)
+  private val registerFileAddressWidth = log2Ceil(cfg.registerFileWords)
 
   val immediate = UInt(cfg.immediateWidth.W)
   val absoluteBranch = Bool()
   val relativeBranch = Bool()
 
-  val dataMemoryReadEnable = Bool()
   val dataMemoryReadAddress = UInt(dataMemoryAddressWidth.W)
   val dataMemoryWriteEnable = Bool()
   val dataMemoryWriteAddress = UInt(dataMemoryAddressWidth.W)
 
+  val registerFileReadAddress = Vec(2, UInt(registerFileAddressWidth.W))
+  val registerFileWriteFrom = Bool()
+  val registerFileWriteEnable = Bool()
+  val registerFileWriteAddress = UInt(registerFileAddressWidth.W)
+
   val fillConstant = Bool()
   val incrementBlockCount = Bool()
   val aluFunction = UInt(CanCoreALUFunction.requiredWidth.W)
-- 
GitLab