Reputation: 33
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.
Upvotes: 3
Views: 102
Reputation: 6065
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.
Upvotes: 0