Search code examples
fpgachiselspartan

Implement high impedance 'Z' input output property with chisel


My board (apf27) has a processor (i.MX27) and a FPGA (Spartan3A) that communicate through a "memory bus" called WEIM in proc datasheet.

I want to transfer data from the FPGA to the processor. I managed to do it with a simple Output() IO :

  val io = IO(new Bundle {
  ...
    val data = Output(UInt(16.W))
    val oen = Input(Bool())
  ...  

I can read data from the processor, but that "lock" the bus. I have to release it for the nand component also present on it.

To release it I can use the signal oen (output enable) but I can't assign a high impedance value like 'Z' in Verilog/VHDL to 'release' it.

What is the right way to do it in Chisel3 ? I saw something called 'AnalogRawModule" in chisel3 github is it the things to use ?


Solution

  • Analog is what you're looking for. It is basically an escape to allow bidirectional wires and other signals that aren't really supported by Chisel to still connect through your Chisel design.

    Here's an example:

    import chisel3._
    import chisel3.experimental.Analog
    
    class AnalogBlackBox extends BlackBox {
      val io = IO(new Bundle {
        val bus = Analog(32.W)
      })
    }
    
    class AnalogModule extends Module {
      val io = IO(new Bundle {
        val bus = Analog(32.W)
      })
    
      val inst = Module(new AnalogBlackBox)
      inst.io.bus <> io.bus
    }
    
    
    object AnalogDriver extends App {
      chisel3.Driver.execute(args, () => new AnalogModule)
    }
    

    You can't drive Analog-type wires in Chisel and unfortunately you can't do concatenation or bit select (although we should support that), but you can at least connect signals through. If you need to do any kind of bit selection or concatenation, you need to do that in a BlackBox.