0

I'm writing an architecture that makes extensive internal use of SyncReadMem, which is intended to represent SRAM memory banks. Our current synthesis toolchain, however, does not support SRAM properly, but is fine for registers and computational logic. So, whenever we're running a synthesis build, I pass in a flag that disables the elaboration of any SyncReadMem modules and treats them purely as IO signals:

class exampleModule (synthesis: Boolean) extends Module {
  val io = IO(new Bundle {
    val in = Input(UInt(32.W))
    val out = Output(Uint(32.W))
    val synth_bundle = if (synthesis) Some(new Bundle() {
      val synth_out = Output(UInt(32.W))
      val synth_in = Input(UInt(4.W))
    }) else None
  }

  val mem_read = if (synthesis) {
    val memory = SyncReadMem(1 << 32, UInt(4.W))
    memory.read(io.in)
  } else {
    io.synth_bundle.get.synth_out := io.in
    io.synth_bundle.get.synth_in
  }
  
  io.out := mem_read * 2.U
}

This, to my understanding, should properly elaborate all of my logic (ie not optimize anything out that I want to be there), and won't elaborate any of the memory whenever I have synthesis builds enabled.

The problem I'm running into is that for really hierarchical modules where a deeply ingrained module needs something like this, it requires every module above it to implement this synth_bundle style IO, requiring a bit of writing and adding no functionality. Is there some easier / more canonical way to do this?

Thank you

Chris
  • 566
  • 2
  • 7
  • 22
  • Is the `synth_[out|in]` something you actually need during the synthesis run? – l Steveo l Jan 20 '22 at 21:02
  • Something like a Chisel `BlackBox` could be useful here in the case where you don't want the `SyncReadMem` to be placed – l Steveo l Jan 20 '22 at 21:07
  • No, the out and in wires are currently what I'm using to ensure that any logic connected to the `SyncReadMem`s doesn't get optimized out in the synthesis build (and they don't incur the same power overheads as the registers and logic that actually get synthesized). I've looked briefly at `BlackBox`. I understand that it will produce Verilog with an empty module that will be defined by an external source. But I'm unsure of the behavior if I don't have an external source for this black box. Are you aware? – Chris Jan 21 '22 at 01:08

0 Answers0