ucb-bar / chisel2-deprecated

chisel.eecs.berkeley.edu
388 stars 90 forks source link

BlackBox submodules instantiation #629

Closed ghost closed 8 years ago

ghost commented 8 years ago

Hello,

I would like to instantiate a submodule which is an already existing Verilog block. Here is my code:

class HelloModule extends Module {
  val io = new Bundle { 
    val datain = UInt(INPUT, 128)
    val datain_valid = Bool(INPUT)
    val dataout = UInt(OUTPUT, 128)
    val dataout_valid = Bool(OUTPUT)
  }
  val submodule = new Submodule
  //val submoduleIO = new SubmoduleIO

  val state_reg = Reg(init = UInt(0, width = 128))
  when (io.datain_valid) { 
    state_reg := io.datain
  } .otherwise { 
    state_reg := submodule.io.s_output
  } 

  submodule.io.s_input := state_reg

  io.dataout := state_reg
}

class SubmoduleIO extends Bundle { 
  val s_input = UInt(INPUT,  128) 
  val s_output = UInt(OUTPUT, 128) 
} 

class Submodule extends BlackBox { 
  val io = new SubmoduleIO()
} 

However I am getting the following error:

[error] hello.scala:22: assigning to your own input port /*? in < (class Hello.Submodule)>*/ Chisel.UInt(INPUT, width=128, connect to 0 inputs: ()) RHS: /*? in < (class Hello.Submodule)>*/ Chisel.UInt(OUTPUT, width=None, connect to 1 inputs: (?[Chisel.RegReset] in Hello.Submodule)) in class Hello.HelloModule
[error] hello.scala:24: assigning to a non parent module's output port: /*? in < (class Hello.HelloModule)>*/ Chisel.UInt(OUTPUT, width=128, connect to 0 inputs: ()) RHS: /*? in < (class Hello.Submodule)>*/ Chisel.UInt(OUTPUT, width=None, connect to 1 inputs: (?[Chisel.RegReset] in Hello.Submodule)) in class Hello.HelloModule
Re-running Chisel in debug mode to obtain erroneous line numbers...
[error] hcl.scala:203: Hello.Submodule was not properly wrapped into a module() call. in class Chisel.BlackBox
[error] hello.scala:22: assigning to your own input port /*? in < (class Hello.Submodule)>*/ Chisel.UInt(INPUT, width=128, connect to 0 inputs: ()) RHS: /*? in < (class Hello.Submodule)>*/ Chisel.UInt(OUTPUT, width=None, connect to 1 inputs: (?[Chisel.RegReset] in Hello.Submodule)) in class Hello.HelloModule
[error] hello.scala:24: assigning to a non parent module's output port: /*? in < (class Hello.HelloModule)>*/ Chisel.UInt(OUTPUT, width=128, connect to 0 inputs: ()) RHS: /*? in < (class Hello.Submodule)>*/ Chisel.UInt(OUTPUT, width=None, connect to 1 inputs: (?[Chisel.RegReset] in Hello.Submodule)) in class Hello.HelloModule
[error] (run-main-0) java.lang.IllegalStateException: CODE HAS 3 ERRORS and 0 WARNINGS
java.lang.IllegalStateException: CODE HAS 3 ERRORS and 0 WARNINGS
    at Chisel.ChiselError$.checkpoint(ChiselError.scala:158)
    at Chisel.Backend.elaborate(Backend.scala:826)
    at Chisel.VerilogBackend.elaborate(Verilog.scala:729)
    at Chisel.Driver$.execute(Driver.scala:93)
    at Chisel.Driver$.apply(Driver.scala:41)
    at Chisel.Driver$.apply(Driver.scala:46)
    at Chisel.Driver$.apply(Driver.scala:52)
    at Chisel.chiselMain$.apply(hcl.scala:63)
    at Chisel.chiselMainTest$.apply(hcl.scala:76)
    at Hello.Hello$.main(hello.scala:44)
    at Hello.Hello.main(hello.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
[trace] Stack trace suppressed: run last compile:run for the full output.
java.lang.RuntimeException: Nonzero exit code: 1
    at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) Nonzero exit code: 1
  1. Any ideas what may be wrong here? Could you please add a description of a similar case in the manual?
  2. Is it possible to add a high-level functionality of the BlackBox submodule (assuming the HDL already exists and doesn't need to be generated) for testing purpose?

Thanks for help.

ghost commented 8 years ago

Figured out question 1. BlackBoxes should be used as normal modules: intead of

val submodule = new Submodule

should be

val submodule = Module(new Submodule())
da-steve101 commented 8 years ago

A blackbox is the same as a module except the verilog definition is not generated. Perhaps the following example will help illustrate. If I have generated a pipelined floating point add module in verilog using a tool (eg quartus). I called it "my_fp_add", the add takes 7 cycles, and has the inputs dataA, dataB, clock, rst and outputs result. This would be my blackbox:

class myFpAdd extends BlackBox {
  setModuleName("my_fp_add")
  renameClock("clk", "clock")
  renameReset("rst")
  val io = new Bundle {
    val dataA = Flo(INPUT)
    dataA.setName("dataA")
    val dataB = Flo(INPUT)
    dataB.setName("dataB")
    val result = Flo(OUTPUT)
    result.setName("result")
  }
  // Now the module will generate correctly as a BlackBox and is quite usable
  // however we want to still use chisel to simulate the result
  // This is achieved exactly the same way as normal chisel
  // The blackbox just indicates not to put in generated code
  // In this case it is quite easy to simulate
  io.result := ShiftRegister(io.dataA + io.dataB, 7)
}

I haven't run it so might be syntax errs but you get the idea

ghost commented 8 years ago

Thank you for explanations!