How to create new module in Verilog parsetree

From Verific Design Automation FAQ
Revision as of 12:01, 23 June 2020 by Hoa (Talk | contribs) (Created page with "This code sample also shows how to add new parameters and new ports to a module. C++: <nowiki> #include <iostream> #include "veri_file.h" #include "veri_tokens.h" #include...")

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

This code sample also shows how to add new parameters and new ports to a module.

C++:

#include <iostream>

#include "veri_file.h"
#include "veri_tokens.h"
#include "VeriId.h"
#include "VeriModule.h"
#include "VeriScope.h"
#include "VeriMisc.h"
#include "VeriConstVal.h"
#include "VeriExpression.h"

#include "Array.h"

#include "Strings.h"

#ifdef VERIFIC_NAMESPACE
using namespace Verific ;
#endif

int main()
{
    // Module id (not declared anywhere):
    const char *module_name = "test" ;
    VeriIdDef *module_id = new VeriModuleId(Strings::save(module_name)) ;

    // Scope of the module : declare all ids in here:
    VeriScope *scope = new VeriScope(0 /* upper scope */, module_id) ;

    // Declare ANSI parameters:
    // Parameters can be declared within body in module_items as well.
    VeriIdDef *ansi_param_id = new VeriParamId(Strings::save("P1")) ;
    if (!scope->Declare(ansi_param_id)) ansi_param_id->Error("%s is already declared", ansi_param_id->Name()) ;
    ansi_param_id->SetInitialValue(new VeriIntVal(1)) ;
    VeriDataDecl *ansi_param_decl = new VeriDataDecl(VERI_PARAMETER, 0 /* data type */, ansi_param_id) ;
    Array *ansi_params = new Array(1) ;
    ansi_params->InsertLast(ansi_param_decl) ;

    // Declare input port:
    Array *ports = new Array(2) ;
    VeriIdDef *inp = new VeriVariable(Strings::save("in1")) ;
    if (!scope->Declare(inp)) inp->Error("%s is already declared", inp->Name()) ;
    ports->InsertLast(new VeriDataDecl(VERI_INPUT, new VeriDataType(VERI_REG, 0, 0), inp)) ;

    // Declare output port:
    VeriIdDef *outp = new VeriVariable(Strings::save("out1")) ;
    if (!scope->Declare(outp)) outp->Error("%s is already declared", outp->Name()) ;
    ports->InsertLast(new VeriDataDecl(VERI_OUTPUT, new VeriDataType(VERI_WIRE, 0, 0), outp)) ;

    // Create the assignment from input to output port:
    Array *assigns = new Array(1) ;
    assigns->InsertLast(new VeriNetRegAssign(new VeriIdRef(outp), new VeriIdRef(inp))) ;
    Array *module_items = new Array(1) ;
    module_items->InsertLast(new VeriContinuousAssign(0, 0, assigns)) ;

    // Create the module:
    VeriModule *mod = new VeriModule(module_id, ansi_params, ports, module_items, scope) ;

    // Resolve it:
    mod->ResolveBody() ;

    // Now add the module into a library using VeriLibrary::AddModule() API

    // Check if we did it correctly:
    char *mod_str = mod->GetPrettyPrintedString() ;
    mod->Info("Module created: %s", mod_str) ;
    Strings::free(mod_str) ;

    return 0;
}
 

Run:

$ test-linux
INFO: Module created:
module test #(parameter P1 = 1) (input reg in1, output wire out1) ;
    assign out1 = in1 ;
endmodule
$