Initializing one word of asyncRam

I’m looking to implement a register file with a zero register. In previous Verilog projects, I found the most performant way to do this was to make an asynchronous RAM initialized to have 0 in the zero-register position and gate the write-enable based on the address being nonzero.

In Clash it seems like the asyncRam primitive doesn’t have an initialization option. Is there a way to implement this behavior? The options that leap to mind are either another primitive that I haven’t found yet or some way of introducing a register write during the reset phase, but I don’t know my way around the documentation well enough yet to be able to know if such things are possible.

I also don’t see a way to do that right away, but it seems like a good feature to have. Could you open an issue on the issue tracker?

The tricky thing would probably be coming up with a good API for such a feature.

I’ve seen people write small wrappers these things, something like:

regFile :: _ => SNat n -> Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
regFile size rd wr = res
 where
  res = mux (rd .==. 0) (pure 0) (asyncRam size rd wr')
  wr' = fmap ignoreWrite0 wr
  ignoreWrite0 (Just (0,_)) = Nothing
  ignoreWrite0 x = x

I don’t know if the Clash side is smart enough to optimize that properly - my design isn’t far enough along to start testing in hardware yet - but in a previous plain-Verilog implementation yosys+nextpnr generated substantially faster bitstreams when using an initialized RAM primitive rather than a mux. I have something like that in my current implementation but I suspect it will be slow.

Clash will not optimise this, no. Thanks for the issue report!