Chisel does not support X.
This is probably what you want:
io.rdData := mem(io.rdAddr)
(this prevents muxing between zero and mem's readout data).
If, for example, one is trying to infer a single-ported SRAM, the Chisel tutorial/manual describes how to do so (https://chisel.eecs.berkeley.edu/latest/chisel-tutorial.pdf):
val ram1p =
Mem(UInt(width = 32), 1024, seqRead = true)
val reg_raddr = Reg(UInt())
when (wen) { ram1p(waddr) := wdata }
.elsewhen (ren) { reg_raddr := raddr }
val rdata = ram1p(reg_raddr)
In short, the read address needs to be registered (since we're dealing with synchronous memory in this example), and the enable signal on this register dictates that the read-out data only changes with that enable is true. Thus, the backend understands this a read-enable signal exists on the read port, and in this example, the write port and the read port are one and the same (since only one is ever accessed at a time). Or if you want 1w/1r (as per your example), you can change the "elsewhen (ren)" to a "when (ren)".