Modules
Modules in Neo are similar to those in Verilog or any other HDL. They have parameters, inputs and outputs, interfaces, and a body that defines the internal implementation.
neo
// @top marks the module as an entry point for SystemVerilog generation
// other modules are only instantiated if they are used
@top
module MyModule {
// Inputs and outputs are declared here
// The number in parenthesis after the name indicates which cycle the value is valid for
input a(0): Int(32),
input b(0): Int(32),
output out(1): Int(32),
} {
// Other modules are instantiated like so, where any parameters are passed like a function call
mod adder = Adder(32);
// The returned module instance has fields for its I/O
assign adder.a = a;
assign adder.b = b;
assign out = adder.out;
}
// Modules without @top can have parameters
module Adder(width: Nat) {
input a(0): Int(width),
input b(0): Int(width),
output out(1): Int(width),
} {
assign out = Reg(a + b);
}
Each Neo module will become a SystemVerilog module upon generation. Parameterized modules will be generated once for each set of parameters they are instantiated with. That is because Neo parameters do not translate to SystemVerilog parameters and are applied at generation. For more on the parameterization system, read here.