3

I have a Chisel module, that has lots of submodules. The top module is configured with a set of parameters. The submodules have their configuration too; based on the input parameters and some hardcoded values.

Depending on all these configurations, I calculate e.g. the expected latency of the module. But, I cannot calculate it just by looking at the input parameters. Encoding all submodule information, and their hardcoded values into the input parameters would be horrible.

As a solution, I can print the latency when executing the emitVerilog function within myModuleDriver. However, I do not want to print it, I want the myModuleDriver to write the latency value to a file together with input parameters.

I provide an example piece of code. Simply, I want to access latency from myModule, when executing the myModuleDriver. Is there a way to do it from emitVerilog, or some other way?

import chisel3._
import chisel3.stage.ChiselStage

class myModule(
  val params: ParameterSet = new ParameterSet(...)
) extends Module {

  // inputs
  // outputs

  // submodule declarations; based on input params and some hardcoded internal parameters

  val latency = submoduleA.latency + submoduleB.latency
  println(s"latency: $latency")

  // output is available after given latency
}

object myModuleDriver extends App {

  val params = new ParameterSet(...)
  
  (new ChiselStage).emitVerilog(new myModule(params))


  write(params, myModule(params).latency) ????
}

Yet I could not find any solution.

1 Answer 1

0

Certain things about the software architecture of Chisel make us a bit hesitant to return the elaborated Module object itself. There are a lot of things that feel like they should "work" on the returned object that do not, so the built-in APIs don't return the object. I would like to change this architecture but it's a lot of otherwise unimportant work so it tends to float on the backlog.

All this being said, your desire to capture calculated values is totally reasonable. There is a hacky way to do this. Fortunately, it looks nasty enough that I think any use of it is sufficient warning to the user to tread lightly with what they do with the returned module object.

You can try the following:

object myModuleDriver extends App {

  val params = new ParameterSet(...)

  // Capture the elaborated Module object at your own risk
  var elaboratedResult: myModule = null
  
  (new ChiselStage).emitVerilog {
    elaboratedResult = new myModule(params)
    elaboratedResult
  }

  write(params, elaboratedResult.latency) ????
}

Another option is you could pass a mutable data structure (like a Map or a class with var fields) and mutate it during elaboration. If params were mutable you could store latency in it and access it that way.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.