diff --git a/src/main/scala/uk/ac/soton/ecs/can/CanConfiguration.scala b/src/main/scala/uk/ac/soton/ecs/can/CanConfiguration.scala
new file mode 100644
index 0000000000000000000000000000000000000000..dbf81b019d785dd24206e3604e041a79a7f60c64
--- /dev/null
+++ b/src/main/scala/uk/ac/soton/ecs/can/CanConfiguration.scala
@@ -0,0 +1,7 @@
+package uk.ac.soton.ecs.can
+
+import core.CanCoreConfiguration
+
+case class CanConfiguration(
+    core: CanCoreConfiguration
+)
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 3a644e0b4ebc7eca6a5841ccd89e39ed35c468d2..4b7844862106bc221461495607231c9202dae9c1 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
@@ -6,23 +6,16 @@ package uk.ac.soton.ecs.can.core
 import chisel3._
 import scala.math.{ceil, log}
 
-class CanCore(
-    programMemoryWords: Int,
-    dataMemoryWords: Int,
-    syncReadMemory: Boolean = true,
-    regAfterBlockInitializer: Boolean = true,
-    regBetweenRounds: Boolean = true,
-    regAfterAdder: Boolean = true
-) extends MultiIOModule {
+class CanCore(implicit cfg: CanCoreConfiguration) extends MultiIOModule {
 
   // ========== Calculated Parameters ========== //
 
   private val programMemoryAddressWidth = ceil(
-    log(programMemoryWords) / log(2)
+    log(cfg.programMemoryWords) / log(2)
   ).toInt
   private val controlWordWidth = ControlWord(programMemoryAddressWidth).getWidth
   private val dataMemoryAddressWidth = ceil(
-    log(dataMemoryWords) / log(2)
+    log(cfg.dataMemoryWords) / log(2)
   ).toInt
   private val blockWidth = 512
 
@@ -60,16 +53,16 @@ class CanCore(
     new ProgramMemory(
       programMemoryAddressWidth,
       controlWordWidth,
-      programMemoryWords,
-      syncReadMemory
+      cfg.programMemoryWords,
+      cfg.syncReadMemory
     )
   )
   private val dataMemory = Module(
     new DataMemory(
       dataMemoryAddressWidth,
       blockWidth,
-      dataMemoryWords,
-      syncReadMemory
+      cfg.dataMemoryWords,
+      cfg.syncReadMemory
     )
   )
   private val blockInitializer = Module(new BlockInitializer)
@@ -81,18 +74,18 @@ class CanCore(
   // ========== Non-Module Components ========== //
 
   private val afterBlockInitializer =
-    if (regAfterBlockInitializer)
+    if (cfg.regAfterBlockInitializer)
       Reg(Vec(16, UInt(32.W)))
     else
       Wire(Vec(16, UInt(32.W)))
   private val betweenRounds =
-    if (regBetweenRounds)
+    if (cfg.regBetweenRounds)
       Reg(Vec(16, UInt(32.W)))
     else
       Wire(Vec(16, UInt(32.W)))
   private val afterRounds = Reg(Vec(16, UInt(32.W)))
   private val afterAdder =
-    if (regAfterAdder)
+    if (cfg.regAfterAdder)
       Reg(Vec(16, UInt(32.W)))
     else
       Wire(Vec(16, UInt(32.W)))
diff --git a/src/main/scala/uk/ac/soton/ecs/can/core/CanCoreConfiguration.scala b/src/main/scala/uk/ac/soton/ecs/can/core/CanCoreConfiguration.scala
new file mode 100644
index 0000000000000000000000000000000000000000..9919bf5b1296e9759c3a8401c3bcddbaaa782af8
--- /dev/null
+++ b/src/main/scala/uk/ac/soton/ecs/can/core/CanCoreConfiguration.scala
@@ -0,0 +1,10 @@
+package uk.ac.soton.ecs.can.core
+
+case class CanCoreConfiguration(
+    programMemoryWords: Int,
+    dataMemoryWords: Int,
+    syncReadMemory: Boolean = true,
+    regAfterBlockInitializer: Boolean = true,
+    regBetweenRounds: Boolean = true,
+    regAfterAdder: Boolean = true
+)