Merge pull request #392 from antmicro/assign-op-type
systemverilog: Support op type on assignment
diff --git a/systemverilog-plugin/UhdmAst.cc b/systemverilog-plugin/UhdmAst.cc
index bcc4d6f..6790fe9 100644
--- a/systemverilog-plugin/UhdmAst.cc
+++ b/systemverilog-plugin/UhdmAst.cc
@@ -2269,10 +2269,14 @@
process_cont_assign_net();
}
-void UhdmAst::process_assignment()
+void UhdmAst::process_assignment(const UHDM::BaseClass *object)
{
auto type = vpi_get(vpiBlocking, obj_h) == 1 ? AST::AST_ASSIGN_EQ : AST::AST_ASSIGN_LE;
+ bool shift_unsigned = false;
+ int op_type = vpi_get(vpiOpType, obj_h);
+ AST::AstNodeType node_type;
current_node = make_ast_node(type);
+
visit_one_to_one({vpiLhs, vpiRhs}, obj_h, [&](AST::AstNode *node) {
if (node) {
if (node->type == AST::AST_PARAMETER || node->type == AST::AST_LOCALPARAM) {
@@ -2281,6 +2285,64 @@
current_node->children.push_back(node);
}
});
+ if (op_type && op_type != vpiAssignmentOp) {
+ switch (op_type) {
+ case vpiSubOp:
+ node_type = AST::AST_SUB;
+ break;
+ case vpiDivOp:
+ node_type = AST::AST_DIV;
+ break;
+ case vpiModOp:
+ node_type = AST::AST_MOD;
+ break;
+ case vpiLShiftOp:
+ node_type = AST::AST_SHIFT_LEFT;
+ shift_unsigned = true;
+ break;
+ case vpiRShiftOp:
+ node_type = AST::AST_SHIFT_RIGHT;
+ shift_unsigned = true;
+ break;
+ case vpiAddOp:
+ node_type = AST::AST_ADD;
+ break;
+ case vpiMultOp:
+ node_type = AST::AST_MUL;
+ break;
+ case vpiBitAndOp:
+ node_type = AST::AST_BIT_AND;
+ break;
+ case vpiBitOrOp:
+ node_type = AST::AST_BIT_OR;
+ break;
+ case vpiBitXorOp:
+ node_type = AST::AST_BIT_XOR;
+ break;
+ case vpiArithLShiftOp:
+ node_type = AST::AST_SHIFT_SLEFT;
+ shift_unsigned = true;
+ break;
+ case vpiArithRShiftOp:
+ node_type = AST::AST_SHIFT_SRIGHT;
+ shift_unsigned = true;
+ break;
+ default:
+ delete current_node;
+ current_node = nullptr;
+ report_error("%s:%d: Encountered unhandled compound assignment with operation type %d\n", object->VpiFile().c_str(), object->VpiLineNo(),
+ op_type);
+ return;
+ }
+ log_assert(current_node->children.size() == 2);
+ auto child_node = new AST::AstNode(node_type, current_node->children[0]->clone(), current_node->children[1]);
+ current_node->children[1] = child_node;
+ if (shift_unsigned) {
+ log_assert(current_node->children[1]->children.size() == 2);
+ auto unsigned_node = new AST::AstNode(AST::AST_TO_UNSIGNED, current_node->children[1]->children[1]);
+ current_node->children[1]->children[1] = unsigned_node;
+ }
+ }
if (current_node->children.size() == 1 && current_node->children[0]->type == AST::AST_WIRE) {
auto top_node = find_ancestor({AST::AST_MODULE});
if (!top_node)
@@ -4122,7 +4184,7 @@
break;
case vpiAssignStmt:
case vpiAssignment:
- process_assignment();
+ process_assignment(object);
break;
case vpiInterfaceTypespec:
case vpiRefVar:
diff --git a/systemverilog-plugin/UhdmAst.h b/systemverilog-plugin/UhdmAst.h
index b7877a6..0d41f14 100644
--- a/systemverilog-plugin/UhdmAst.h
+++ b/systemverilog-plugin/UhdmAst.h
@@ -93,7 +93,7 @@
void process_cont_assign();
void process_cont_assign_net();
void process_cont_assign_var_init();
- void process_assignment();
+ void process_assignment(const UHDM::BaseClass *object);
void process_net();
void process_packed_array_net();
void process_array_net(const UHDM::BaseClass *object);