Difference between revisions of "How to evaluate a Verilog expression"
From Verific Design Automation FAQ
(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...") |
|||
| Line 1: | Line 1: | ||
| − | This applicatione example shows how to evaluate a Verilog expression. | + | This applicatione example shows how to evaluate a Verilog expression. It requires Verific 'Static Elaboration' feature. |
| + | |||
| + | Note that a, b, and c are declared in the Verilog module. The application evaluates an expression of these variables. | ||
C++: | C++: | ||
| Line 89: | Line 91: | ||
</nowiki> | </nowiki> | ||
| + | Verilog testcase: | ||
| + | |||
| + | <nowiki> | ||
| + | module test_module; | ||
| + | wire a [1:0]; | ||
| + | wire [1:0] b; | ||
| + | wire [1:0] c; | ||
| + | endmodule | ||
| + | </nowiki> | ||
Run: | Run: | ||
Revision as of 09:06, 21 February 2025
This applicatione example shows how to evaluate a Verilog expression. It requires Verific 'Static Elaboration' feature.
Note that a, b, and c are declared in the Verilog module. The application evaluates an expression of these variables.
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 ;
}
Verilog testcase:
module test_module;
wire a [1:0];
wire [1:0] b;
wire [1:0] c;
endmodule
Run:
$ test-linux -- Analyzing Verilog file 'test.v' (VERI-1482) test.v(5): INFO: Evaluated value: 2'b10 (2) $