From 522b32e04e35b0fd16bcd9b3a043d271016d4d0a Mon Sep 17 00:00:00 2001 From: Minyong Li <ml10g20@soton.ac.uk> Date: Mon, 23 Aug 2021 22:28:12 +0100 Subject: [PATCH] core.BaseRound: fix reversed casts Chisel UInt conversion from/to aggregates involves reversal. This causes problem for the Quarter Rounds, since they receive wrong bits, leading to completely different results (which are wrong). --- .../scala/uk/ac/soton/ecs/can/core/Adder.scala | 2 ++ .../uk/ac/soton/ecs/can/core/BaseRound.scala | 15 +++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) 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 index 9d5c083..581e558 100644 --- a/src/main/scala/uk/ac/soton/ecs/can/core/Adder.scala +++ b/src/main/scala/uk/ac/soton/ecs/can/core/Adder.scala @@ -10,6 +10,8 @@ class Adder extends MultiIOModule { val rhs = IO(Input(UInt(512.W))) val out = IO(Output(UInt(512.W))) + // NOTE: Unlike what's done in `BaseRound`, here no reversal is applied, since + // the additions are done on the basis of words and do not spread bits. private val _lhs = lhs.asTypeOf(Vec(16, UInt(32.W))) private val _rhs = rhs.asTypeOf(Vec(16, UInt(32.W))) private val _out = Wire(Vec(16, UInt(32.W))) diff --git a/src/main/scala/uk/ac/soton/ecs/can/core/BaseRound.scala b/src/main/scala/uk/ac/soton/ecs/can/core/BaseRound.scala index f92a53a..66523ee 100644 --- a/src/main/scala/uk/ac/soton/ecs/can/core/BaseRound.scala +++ b/src/main/scala/uk/ac/soton/ecs/can/core/BaseRound.scala @@ -4,6 +4,7 @@ package uk.ac.soton.ecs.can.core import chisel3._ +import chisel3.util.Cat import uk.ac.soton.ecs.can.config.CanCoreConfiguration abstract class BaseRound(implicit cfg: CanCoreConfiguration) @@ -11,9 +12,19 @@ abstract class BaseRound(implicit cfg: CanCoreConfiguration) val in = IO(Input(UInt(512.W))) val out = IO(Output(UInt(512.W))) - protected val _in = in.asTypeOf(Vec(16, UInt(32.W))) + // NOTE: A conversion between an UInt and an aggregate type reverses the + // sequence of elements. The `_in` cast below reverses such reversal by + // manually creating a `Vec` with the elements in the casted `Vec` reversed. + // Same for the `out` connection, where `Cat`, which concatenates elements + // from the most significant element to the least significant element, is used + // instead of `_out.asUInt()`, which puts the first element in the `Vec` to + // the least significant position of `UInt`. + // + // See also: + // - https://github.com/chipsalliance/chisel3/blob/master/core/src/main/scala/chisel3/Data.scala#L695-L696 + protected val _in = VecInit(in.asTypeOf(Vec(16, UInt(32.W))).reverse) protected val _out = Wire(Vec(16, UInt(32.W))) - out := _out.asUInt() + out := Cat(_out) protected def wire(wireBox: Seq[Seq[Int]]): Unit = wireBox.foreach { wireSeq => -- GitLab