Chisel code conversion
So I have a theoretical question about chisel code conversion.
I know Chisel is actually a collection of Scala definitions, so it compiles to Java bytecodes, which in turn gets run in the JVM and, like magic, spits out the equivalent Verilog description and even the C ++ description for more older versions of Chisel.
The point is, I couldn't figure out how this "magic" works. I am assuming the code conversion from Chisel to Verilog / C ++ is based on Scala reflection. But I am not sure about this as I could not find anything related to this topic.
So, is it about reflection? If so, is it our runtime compile time? Can someone please give me the key?
Many thanks.
source to share
Basically, the writing driller writes a Scala program to create the schema. What you are describing is a bit like a high level synthesis, which is very different from a bit. Instead of mapping Scala (or Java) primitives to hardware, Chisel executes Scala code to build a hardware AST , which is then compiled for Verilog.
I'll try to make it clearer with an annotated example.
// The body of a Scala class is the default constructor // MyModule default constructor has a single Int argument // Superclass Module is a chisel3 Class that begins construction of a hardware module // Implicit clock and reset inputs are added by the Module constructor class MyModule(width: Int) extends Module { // io is a required field for subclasses of Module // new Bundle creates an instance of an anonymous subclass of Chisel Bundle (like a struct) // When executing the function IO(...), Chisel adds ports to the Module based on the Bundle object val io = IO(new Bundle { val in = Input(UInt(width.W)) // Input port with width defined by parameter val out = Output(UInt()) // Output port with width inferred by Chisel }) // A Scala println that will print at elaboration time each time this Module is instantiated // This does NOT create a node in the Module AST println(s"Constructing MyModule with width $width") // Adds a register declaration node to the Module AST // This counter register resets to the value of input port io.in // The implicit clock and reset inputs feed into this node val counter = RegInit(io.in) // Adds an addition node to the hardware AST with operands counter and 1 val inc = counter + 1.U // + is overloaded, this is actually a Chisel function call // Connects the output of the addition node to the "next" value of counter counter := inc // Adds a printf node to the Module AST that will print at simulation time // The value of counter feeds into this node printf("counter = %d\n", counter) }
source to share
This is also a question that interests me. I think "build hardware AST" is programmed and compiled as * .class. When classes are generated, since firrtl. After you execute this class the rtl is generated, it feels like a built-in toolchain. But I cannot tell you how to do it. Wish someone told more.
source to share