From b803be17756010180b86f9c8bf6f6df693f88db2 Mon Sep 17 00:00:00 2001
From: Minyong Li <ml10g20@soton.ac.uk>
Date: Sat, 26 Jun 2021 20:32:05 +0100
Subject: [PATCH] core.{Add,Xor}er{,Test}: impl

These are trivial modules, but add convenience when wiring up
the processor.
---
 .../uk/ac/soton/ecs/can/core/Adder.scala      | 11 ++++++++
 .../uk/ac/soton/ecs/can/core/Xorer.scala      | 11 ++++++++
 .../uk/ac/soton/ecs/can/core/AdderTest.scala  | 27 +++++++++++++++++++
 .../uk/ac/soton/ecs/can/core/XorerTest.scala  | 23 ++++++++++++++++
 4 files changed, 72 insertions(+)
 create mode 100644 src/main/scala/uk/ac/soton/ecs/can/core/Adder.scala
 create mode 100644 src/main/scala/uk/ac/soton/ecs/can/core/Xorer.scala
 create mode 100644 src/test/scala/uk/ac/soton/ecs/can/core/AdderTest.scala
 create mode 100644 src/test/scala/uk/ac/soton/ecs/can/core/XorerTest.scala

diff --git a/src/main/scala/uk/ac/soton/ecs/can/core/Adder.scala b/src/main/scala/uk/ac/soton/ecs/can/core/Adder.scala
new file mode 100644
index 0000000..d29dd8e
--- /dev/null
+++ b/src/main/scala/uk/ac/soton/ecs/can/core/Adder.scala
@@ -0,0 +1,11 @@
+package uk.ac.soton.ecs.can.core
+
+import chisel3._
+
+class Adder extends MultiIOModule {
+  val lhs = IO(Input(Vec(16, UInt(32.W))))
+  val rhs = IO(Input(Vec(16, UInt(32.W))))
+  val out = IO(Output(Vec(16, UInt(32.W))))
+
+  out := lhs.zip(rhs).map { case (lhs, rhs) => lhs + rhs }
+}
diff --git a/src/main/scala/uk/ac/soton/ecs/can/core/Xorer.scala b/src/main/scala/uk/ac/soton/ecs/can/core/Xorer.scala
new file mode 100644
index 0000000..e553a6a
--- /dev/null
+++ b/src/main/scala/uk/ac/soton/ecs/can/core/Xorer.scala
@@ -0,0 +1,11 @@
+package uk.ac.soton.ecs.can.core
+
+import chisel3._
+
+class Xorer extends MultiIOModule {
+  val lhs = IO(Input(Vec(16, UInt(32.W))))
+  val rhs = IO(Input(Vec(16, UInt(32.W))))
+  val out = IO(Output(Vec(16, UInt(32.W))))
+
+  out := lhs.zip(rhs).map { case (lhs, rhs) => lhs ^ rhs }
+}
diff --git a/src/test/scala/uk/ac/soton/ecs/can/core/AdderTest.scala b/src/test/scala/uk/ac/soton/ecs/can/core/AdderTest.scala
new file mode 100644
index 0000000..d90ada8
--- /dev/null
+++ b/src/test/scala/uk/ac/soton/ecs/can/core/AdderTest.scala
@@ -0,0 +1,27 @@
+package uk.ac.soton.ecs.can.core
+
+import org.scalatest._
+import chiseltest._
+import chisel3._
+import scala.util.Random
+import scala.math.abs
+
+class AdderTest extends FlatSpec with ChiselScalatestTester {
+  private val maxUInt = (Int.MaxValue.toLong << 1) | 1
+
+  behavior of "The Adder"
+
+  it should "sum the 16 32b unsigned integers" in {
+    test(new Adder) { c =>
+      val randomLhs = c.lhs.map(_ => abs(Random.nextInt))
+      val randomRhs = c.rhs.map(_ => abs(Random.nextInt))
+      val randomRes = randomLhs.zip(randomRhs).map { case (l, r) =>
+        (l.toLong + r.toLong) % maxUInt
+      }
+
+      c.lhs.zip(randomLhs).foreach { case (p, r) => p.poke(r.U) }
+      c.rhs.zip(randomRhs).foreach { case (p, r) => p.poke(r.U) }
+      c.out.zip(randomRes).foreach { case (p, r) => p.expect(r.U) }
+    }
+  }
+}
diff --git a/src/test/scala/uk/ac/soton/ecs/can/core/XorerTest.scala b/src/test/scala/uk/ac/soton/ecs/can/core/XorerTest.scala
new file mode 100644
index 0000000..b37df1c
--- /dev/null
+++ b/src/test/scala/uk/ac/soton/ecs/can/core/XorerTest.scala
@@ -0,0 +1,23 @@
+package uk.ac.soton.ecs.can.core
+
+import org.scalatest._
+import chiseltest._
+import chisel3._
+import scala.util.Random
+import scala.math.abs
+
+class XorerTest extends FlatSpec with ChiselScalatestTester {
+  behavior of "The Xorer"
+
+  it should "exclusive-or the 16 32b unsigned integers" in {
+    test(new Xorer) { c =>
+      val randomLhs = c.lhs.map(_ => abs(Random.nextInt))
+      val randomRhs = c.rhs.map(_ => abs(Random.nextInt))
+      val randomRes = randomLhs.zip(randomRhs).map { case (l, r) => l ^ r }
+
+      c.lhs.zip(randomLhs).foreach { case (p, r) => p.poke(r.U) }
+      c.rhs.zip(randomRhs).foreach { case (p, r) => p.poke(r.U) }
+      c.out.zip(randomRes).foreach { case (p, r) => p.expect(r.U) }
+    }
+  }
+}
-- 
GitLab