From f86489b59e82c4ae4e39b6ba0caf9fd279d4aa16 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Tue, 31 Oct 2017 15:33:41 -0700 Subject: [PATCH] JTAG: Use sorted map for stability (#1073) * JTAG: Use sorted map for stability Otherwise the generated FIRRTL/Verilog is non deterministic * jtag : parens for clarity * jtag: Use deterministic ListMap and sort for stability * JTAG: use slightly clearer SortedMap (clearer to me anyway) * jtag: whitespace cleanup --- src/main/scala/devices/debug/DebugTransport.scala | 3 ++- src/main/scala/jtag/JtagTap.scala | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/scala/devices/debug/DebugTransport.scala b/src/main/scala/devices/debug/DebugTransport.scala index 7a5dd8d2..e7e2363e 100644 --- a/src/main/scala/devices/debug/DebugTransport.scala +++ b/src/main/scala/devices/debug/DebugTransport.scala @@ -243,7 +243,8 @@ class DebugTransportModuleJTAG(debugAddrBits: Int, c: JtagDTMConfig) idcode.mfrId := io.jtag_mfr_id val tapIO = JtagTapGenerator(irLength = 5, - instructions = Map(dtmJTAGAddrs.DMI_ACCESS -> dmiAccessChain, + instructions = Map( + dtmJTAGAddrs.DMI_ACCESS -> dmiAccessChain, dtmJTAGAddrs.DTM_INFO -> dtmInfoChain), icode = Some(dtmJTAGAddrs.IDCODE) ) diff --git a/src/main/scala/jtag/JtagTap.scala b/src/main/scala/jtag/JtagTap.scala index 44a55ef1..c935cd30 100644 --- a/src/main/scala/jtag/JtagTap.scala +++ b/src/main/scala/jtag/JtagTap.scala @@ -2,6 +2,8 @@ package freechips.rocketchip.jtag +import scala.collection.SortedMap + import chisel3._ import chisel3.util._ import freechips.rocketchip.config.Parameters @@ -203,9 +205,12 @@ object JtagTapGenerator { bypassChain.io.chainIn := controllerInternal.io.dataChainOut // for simplicity, doesn't visibly affect anything else require(allInstructions.size > 0, "Seriously? JTAG TAP with no instructions?") - val chainToIcode = allInstructions groupBy { case (icode, chain) => chain } map { + // Need to ensure that this mapping is ordered to produce deterministic verilog, + // and neither Map nor groupBy are deterministic. + // Therefore, we first sort by IDCODE, then sort the groups by the first IDCODE in each group. + val chainToIcode = (SortedMap(allInstructions.toList:_*).groupBy { case (icode, chain) => chain } map { case (chain, icodeToChain) => chain -> icodeToChain.keys - } + }).toList.sortBy(_._2.head) val chainToSelect = chainToIcode map { case (chain, icodes) => {