How to evaluate a Verilog expression
From Verific Design Automation FAQ
Revision as of 10:20, 20 February 2025 by Hoa (Talk | contribs) (Created page with "This applicatione example shows how to evaluate a Verilog expression. Note that it requires 'Static Elaboration' feature. C++: <nowiki> #include "veri_file.h" #include "Veri...")
This applicatione example shows how to evaluate a Verilog expression. Note that it requires 'Static Elaboration' feature.
C++:
#include "veri_file.h" #include "VeriExpression.h" #include "VeriModule.h" #include "VeriBaseValue_Stat.h" #include "Strings.h" #include "Array.h" #include "Map.h" #ifdef VERIFIC_NAMESPACE using namespace Verific ; #endif int main(int argc, const char **argv) { const char *file_name = (argc > 1) ? argv[1] : "test.v" ; const char *module_name = (argc > 2) ? argv[2] : "test_module" ; Array files(1) ; files.Insert(file_name) ; if (!veri_file::AnalyzeMultipleFiles(&files, veri_file::SYSTEM_VERILOG)) return 1 ; const VeriModule *mod = veri_file::GetModule(module_name) ; if (!mod) return 2 ; // Apply following known values to evaluate "a[b] + c": // a = {1'b1, 1'b1} // b = 2'b00 // c = 2'b01 const char *expr_string = "a[b] + c" ; Map known_values(STRING_HASH) ; (void) known_values.Insert("a", "{1'b1, 1'b1}") ; (void) known_values.Insert("b", "2'b00") ; (void) known_values.Insert("c", "2'b01") ; ValueTable df ; MapIter mi ; const char *id_name ; const char *val_str ; FOREACH_MAP_ITEM(&known_values, mi, &id_name, &val_str) { if (!id_name || !val_str) continue ; // Find the identifier: VeriIdDef *id = mod->FindDeclared(id_name) ; if (!id) return 3 ; // Create the expression: VeriExpression *expr = veri_file::AnalyzeExpr(val_str, veri_file::SYSTEM_VERILOG) ; if (!expr) return 4 ; // Evaluate the expression: // If this is a literal expression, we do not need the value value or Resolve() call or else we need both: VeriBaseValue *val = expr->StaticEvaluate(0 /* self context */, 0 /* value table */) ; delete expr ; if (!val) return 5 ; // Insert into the table to be used later: if (!df.Insert(id, val)) { delete val ; return 6 ; } } // Now create the expression for to be evaluated: VeriExpression *expr = veri_file::AnalyzeExpr(expr_string, veri_file::SYSTEM_VERILOG) ; if (!expr) return 7 ; // Resolve the expression so that the id-refs are resolved: expr->Resolve(mod->GetScope(), VeriTreeNode::VERI_UNDEF_ENV) ; VeriBaseValue *val = expr->StaticEvaluate(0 /* self context */, &df /* use this table with the known values */) ; delete expr ; if (!val) return 8 ; // Failed to evaluate char *image = val->Image() ; int result = val->GetIntegerValue() ; mod->Info("Evaluated value: %s (%d)", ((image)?image:""), result) ; Strings::free(image) ; delete val ; return 0 ; }
Run:
$ test-linux -- Analyzing Verilog file 'test.v' (VERI-1482) test.v(5): INFO: Evaluated value: 2'b10 (2) $