2

The following Chisel code works as expected.

class Memo extends Module {                                                                                                                                                                                                                    
  val io = new Bundle {
    val wen     = Bool(INPUT)
    val wrAddr  = UInt(INPUT,  8)
    val wrData  = UInt(INPUT,  8)
    val ren     = Bool(INPUT)
    val rdAddr  = UInt(INPUT,  8)
    val rdData  = UInt(OUTPUT, 8)
  }
  val mem = Mem(UInt(width = 8), 256)
  when (io.wen) { mem(io.wrAddr) := io.wrData }                                                                                                                                                                                                
  io.rdData := UInt(0)
  when (io.ren) { io.rdData := mem(io.rdAddr) }                                                                                                                                                                                                
}

However, it's a compile-time error if I don't specify io.rdData := UInt(0), because defaults are required. Is there a way to either explicitly specify X or to have modules without defaults output X, erm, by default?

Some reasons you might want to do this are that nothing should rely on the output if ren isn't asserted, and Xs let you specify it, and specifying an X can tell the synthesis tool that it's a don't care, for optimization purposes.

dan
  • 4,262
  • 7
  • 25
  • 40

2 Answers2

1

From the Chisel 2.0 Tutorial paper, only binary logic is supported at the moment:

2 Hardware expressible in Chisel

This version of Chisel also only supports binary logic, and does not support tri-state signals.

We focus on binary logic designs as they constitute the vast majority of designs in practice. We omit support for tri-state logic in the current Chisel language as this is in any case poorly supported by industry flows, and difficult to use reliably outside of controlled hard macros.

Garrett
  • 47,045
  • 6
  • 61
  • 50
  • Ahh, the part where they say they focus on binary logic only answers the question. But, X is distinct from tri-state. Tri-state means that you're not driving anything at all, whereas, X represents an unknown value. Unlike tri-state, it's widely used in industry. I wonder if I can write a post-processor to the Verilog Chisel emits to substitute X in cases where I want an X. – dan Sep 11 '13 at 16:30
  • True. Edited for clarity. A constructor of X values to support explicit assignment would be a nice feature. – Garrett Sep 11 '13 at 16:54
1

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)".

Chris
  • 3,827
  • 22
  • 30