-
Notifications
You must be signed in to change notification settings - Fork 177
Understanding Firrtl Intermediate Representation
This page describes common FirrtlNodes found in firrtl/src/main/scala/firrtl/ir/IR.scala.
For more detail on components not mentioned here, please refer to The FIRRTL Specification.
The Firrtl datastructure is an AST (abstract syntax tree) describing a digital circuit, with a corresponding concrete syntax that is human-readable. The following examples show examples of concrete syntax parsed into the Firrtl AST.
Many Firrtl nodes contain an info: Info
field, which the parser can either insert file information like line number and column number, or insert a NoInfo
token. For clarity and simplicity, the following examples will all insert a NoInfo
token.
Circuit is the root node of any Firrtl datastructure. There is only ever one Circuit, and that Circuit contains a list of module definitions and the name of the top-level module.
Circuit(info: Info, modules: Seq[DefModule], main: String)
circuit Adder:
... //List of modules
Circuit(NoInfo, Seq(...), "Adder")
Modules are the unit of modularity within Firrtl and are never directly nested (declaring an instance of a module has its own concrete syntax and AST representation). Each Module has a name, and a list of ports, and a body containing its implementation.
Module(info: Info, name: String, ports: Seq[Port], body: Stmt) extends DefModule
module Adder:
... // list of ports
... // statements
Module(NoInfo, "Adder", Seq(...), )
A port defines part of a Module's io, and has a name, direction (input or output), and type.
class Port(info: Info, name: String, direction: Direction, tpe: Type)
input x: UInt
Port(NoInfo, "x", INPUT, UIntType(UnknownWidth))
A statement is used to describe the components within a module and how they interact. Below are some commonly used statements:
A group of statements. Commonly used as the body field in a Module declaration.
A wire declaration, containing a name and type.
DefWire(info: Info, name: String, tpe: Type)
wire w: UInt
DefWire(NoInfo, "w", UIntType(UnknownWidth))
A register declaration, containing a name, type, clock signal, reset signal, and reset value.
DefRegister(info: Info, name: String, tpe: Type, clock: Expression, reset: Expression, init: Expression)
Circuit(info: Info, modules: Seq[DefModule], main: String)
Module(info: Info, name: String, ports: Seq[Port], body: Stmt)
Port(info: Info, name: String, direction: Direction, tpe: Type)
Block(stmts: Seq[Stmt])
Connect(info: Info, name: String, value: Expression)
Ref(name: String, tpe: Type)
Circuit(NoInfo, Seq(Module(NoInfo, Seq(Port(NoInfo, )), "Adder")