I want to write a simple chisel3 blinking led design on my AC701 kit (artix7). But to do that I have to instantiate a clock input differential buffer. Xilinx give the following verilog template to do that :
IBUFDS #( .DIFF_TERM("TRUE"), .IOSTANDARD("DEFAULT") ) IBUFDS1_inst ( .O(clock1), // Clock buffer .I(clock1_p), // Diff_p clock .IB(clock1_n) // Diff_n clock );
I read on chisel documentation
class IbufdsParam extends VerilogParameters { val DIFF_TERM = "TRUE" val IOSTANDARD = "DEFAULT" } class IBUFDS extends BlackBox { val params = new IbufdsParam() val io = IO(new Bundle { val O = Output(Bool()) val I = Input(Bool()) val IB = Input(Bool())}) io.O.setName("O") io.I.setName("I") io.IB.setName("IB") /* For simulation */ io.O := io.I & ~io.IB }
But it seem that chisel3 doesn't know VerilogParameters class :
[error] blinking_led/blink.scala:5: not found: type VerilogParameters [error] class IbufdsParam extends VerilogParameters {
Once this blackbox correctly declared, I will have to connect the output clock ('O') to the main clock of my blinking module. I'm not sure about how to do that. I'm thinking about that :
class Blink extends Module { val io = IO(new Bundle { val clock_p = Input(Bool()) val clock_n = Input(Bool()) val led = Output(Bool()) }) val ibufds = IBUFDS() Driver.implicitClock := ibufds.io.O ibufds.io.I := io.clock_p ibufds.io.IB:= io.clock_n ... }
But I think it's maybe not the right way, isn't it ?
This is a documentation failure, I'll be sure to add a page on the chisel3 wiki for parameterized blackboxes shortly. Parameterized blackboxes are currently any experimental feature of Chisel3 that can be used by passing a Map of String to Strings or Ints or Longs to the BlackBox constructor. Thus for your particular case, try:
import chisel3._ import chisel3.experimental._ class IBUFDS extends BlackBox(Map("DIFF_TERM" -> "TRUE", "IOSTANDARD" -> "DEFAULT")) { val io = IO(new Bundle { val O = Output(Clock()) val I = Input(Clock()) val IB = Input(Clock()) }) }
In chisel3, there is no implicit clock or reset for BlackBoxes, ports also can't be renamed but will instead get the name given in the io Bundle (without any io_ added). Simulation behavior is also not currently supported, but you can provide a Verilog implementation and simulate your whole design with Verilator.
Now, we want to use the O
output of IBUFDS
and connect it to some Blink
Module. You cannot use a submodule to overrule the clock of its parent, but you can set the clock of a submodule. Thus, I can provide some Top
Module that instantiates both IBUFDS
and Blink
, eg.
class Blink extends Module { val io = IO(new Bundle { val led = Output(Bool()) }) val reg = Reg(init = false.B) reg := !reg io.led := reg } class Top extends Module { val io = IO(new Bundle { val clock_p = Input(Clock()) val clock_n = Input(Clock()) val led = Output(Bool()) }) val ibufds = Module(new IBUFDS) ibufds.io.I := io.clock_p ibufds.io.IB:= io.clock_n val blink = Module(new Blink) blink.clock := ibufds.io.O io.led := blink.io.led }
This code leads to IBUFDS
being instantiated as follows:
IBUFDS #(.DIFF_TERM("TRUE"), .IOSTANDARD("DEFAULT")) ibufds ( .IB(ibufds_IB), .I(ibufds_I), .O(ibufds_O) );
which I believe should do what you want!