Skip to content

Check for typedefs before calculating width #505

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 53 additions & 1 deletion systemverilog-plugin/UhdmAst.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <uhdm/ExprEval.h>
#include <uhdm/uhdm.h>
#include <uhdm/vpi_user.h>
#include "uhdm/vpi_visitor.h" // visit_object

#include "third_party/yosys/const2ast.h"
#include "third_party/yosys/simplify.h"
Expand Down Expand Up @@ -1250,6 +1251,10 @@ static void simplify_sv(AST::AstNode *current_node, AST::AstNode *parent_node)
current_node->children.push_back(result);
}
}
//if (current_node->id2ast && current_node->id2ast->type == AST::AST_TYPEDEF) {
// log_assert(current_node->id2ast->children.size());
// current_node->id2ast = current_node->id2ast->children[0];
//}
break;
case AST::AST_STRUCT:
case AST::AST_UNION:
Expand Down Expand Up @@ -1282,6 +1287,23 @@ static void simplify_sv(AST::AstNode *current_node, AST::AstNode *parent_node)
if (current_node->str == "$display" || current_node->str == "$write")
simplify_format_string(current_node);
break;
case AST::AST_FCALL: {
AST::AstNode *arg = current_node->children[0];
if (arg->type == AST::AST_IDENTIFIER) {
//current_node->dumpAst(nullptr, "->");
if (!arg->id2ast) {
std::cout << "id2ast is null!\n";
simplify_sv(arg, current_node);
}
if (!arg->id2ast) {
std::cout << "id2ast is null again!\n";
}
//&& arg->id2ast && arg->id2ast->type == Yosys::AST::AST_TYPEDEF)
simplify(current_node, true, false, false, 1, -1, false, false);
}

break;
}
case AST::AST_COND:
case AST::AST_CONDX:
case AST::AST_CONDZ:
Expand Down Expand Up @@ -1965,6 +1987,33 @@ AST::AstNode *UhdmAst::find_ancestor(const std::unordered_set<AST::AstNodeType>
return nullptr;
}

static void replace_ids_typedefs(AST::AstNode *tree) {
if (!tree) return;

if (tree->type == AST::AST_IDENTIFIER) {
std::cout << "identifier: \n";
tree->dumpAst(nullptr, "+");

if (!tree->id2ast) {
if (AST_INTERNAL::current_scope.count(tree->str))
tree->id2ast = AST_INTERNAL::current_scope[tree->str];
else
return;
}

if (tree->id2ast->type == AST::AST_TYPEDEF) {
tree->id2ast = tree->id2ast->children[0];
tree->id2ast->dumpAst(nullptr, ">");
} else {
std::cout << "Has no id2ast!\n";
}
std::cout << std::endl;
}
for (auto child: tree->children) {
replace_ids_typedefs(child);
}
}

void UhdmAst::process_design()
{
current_node = make_ast_node(AST::AST_DESIGN);
Expand Down Expand Up @@ -2011,6 +2060,7 @@ void UhdmAst::process_design()
check_memories(pair.second);
setup_current_scope(shared.top_nodes, pair.second);
simplify_sv(pair.second, nullptr);
//replace_ids_typedefs(pair.second);
clear_current_scope();
current_node->children.push_back(pair.second);
}
Expand Down Expand Up @@ -4293,6 +4343,7 @@ void UhdmAst::process_logic_var()

void UhdmAst::process_sys_func_call()
{

current_node = make_ast_node(AST::AST_FCALL);

std::string task_calls[] = {"\\$display", "\\$monitor", "\\$write", "\\$time", "\\$readmemh", "\\$readmemb", "\\$finish", "\\$stop"};
Expand Down Expand Up @@ -5143,9 +5194,10 @@ AST::AstNode *UhdmAst::process_object(vpiHandle obj_handle)
case vpiLogicVar:
process_logic_var();
break;
case vpiSysFuncCall:
case vpiSysFuncCall: {
process_sys_func_call();
break;
}
case vpiFuncCall:
process_tf_call(AST::AST_FCALL);
break;
Expand Down
77 changes: 48 additions & 29 deletions systemverilog-plugin/third_party/yosys/simplify.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ namespace systemverilog_plugin
using namespace ::Yosys;
using namespace ::Yosys::AST_INTERNAL;


void detect_sign_width_proxy(Yosys::AST::AstNode * node, int& width, bool& sign, bool *found_real = NULL) {
if (node->type == Yosys::AST::AST_IDENTIFIER && node->id2ast && node->id2ast->type == Yosys::AST::AST_TYPEDEF) {
node->id2ast = node->id2ast->children[0];
}
node->detectSignWidth(width, sign, found_real);
}

void annotateTypedEnums(Yosys::AST::AstNode *ast_node, Yosys::AST::AstNode *template_node)
{
//check if enum
Expand Down Expand Up @@ -535,17 +543,17 @@ static void check_auto_nosync(Yosys::AST::AstNode *node)
}

static inline std::string encode_filename(const std::string &filename)
{
std::stringstream val;
if (!std::any_of(filename.begin(), filename.end(), [](char c) {
return static_cast<unsigned char>(c) < 33 || static_cast<unsigned char>(c) > 126;
{
std::stringstream val;
if (!std::any_of(filename.begin(), filename.end(), [](char c) {
return static_cast<unsigned char>(c) < 33 || static_cast<unsigned char>(c) > 126;
})) return filename;
for (unsigned char const c : filename) {
if (c < 33 || c > 126)
if (c < 33 || c > 126)
val << stringf("$%02x", c);
else
else
val << c;
}
}
return val.str();
}

Expand Down Expand Up @@ -1036,8 +1044,8 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
did_something = true;
while (!ast_node->children[1]->basic_prep && simplify(ast_node->children[1], false, false, false, stage, -1, false, in_param) == true)
did_something = true;
ast_node->children[0]->detectSignWidth(backup_width_hint, backup_sign_hint);
ast_node->children[1]->detectSignWidth(width_hint, sign_hint);
detect_sign_width_proxy(ast_node->children[0], backup_width_hint, backup_sign_hint);
detect_sign_width_proxy(ast_node->children[1], width_hint, sign_hint);
width_hint = max(width_hint, backup_width_hint);
child_0_is_self_determined = true;
// test only once, before optimizations and memory mappings but after assignment LHS was mapped to an identifier
Expand Down Expand Up @@ -1117,7 +1125,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
}
while (!ast_node->children[0]->basic_prep && simplify(ast_node->children[0], false, false, false, stage, -1, false, true) == true)
did_something = true;
ast_node->children[0]->detectSignWidth(width_hint, sign_hint);
detect_sign_width_proxy(ast_node->children[0], width_hint, sign_hint);
if (ast_node->children.size() > 1 && ast_node->children[1]->type == Yosys::AST::AST_RANGE) {
while (!ast_node->children[1]->basic_prep && simplify(ast_node->children[1], false, false, false, stage, -1, false, true) == true)
did_something = true;
Expand All @@ -1129,7 +1137,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
case Yosys::AST::AST_ENUM_ITEM:
while (!ast_node->children[0]->basic_prep && simplify(ast_node->children[0], false, false, false, stage, -1, false, in_param))
did_something = true;
ast_node->children[0]->detectSignWidth(width_hint, sign_hint);
detect_sign_width_proxy(ast_node->children[0], width_hint, sign_hint);
if (ast_node->children.size() > 1 && ast_node->children[1]->type == Yosys::AST::AST_RANGE) {
while (!ast_node->children[1]->basic_prep && simplify(ast_node->children[1], false, false, false, stage, -1, false, in_param))
did_something = true;
Expand Down Expand Up @@ -1230,11 +1238,11 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
for (auto child : ast_node->children)
while (!child->basic_prep && simplify(child, false, false, in_lvalue, stage, -1, false, in_param) == true)
did_something = true;
ast_node->detectSignWidth(width_hint, sign_hint);
detect_sign_width_proxy(ast_node, width_hint, sign_hint);
}

if (ast_node->type == Yosys::AST::AST_FCALL && ast_node->str == "\\$past")
ast_node->detectSignWidth(width_hint, sign_hint);
detect_sign_width_proxy(ast_node, width_hint, sign_hint);

if (ast_node->type == Yosys::AST::AST_TERNARY) {
if (width_hint < 0) {
Expand All @@ -1253,13 +1261,13 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
did_something = true;

unevaluated_tern_branch = backup_unevaluated_tern_branch;
ast_node->detectSignWidth(width_hint, sign_hint);
detect_sign_width_proxy(ast_node, width_hint, sign_hint);
}
int width_hint_left, width_hint_right;
bool sign_hint_left, sign_hint_right;
bool found_real_left, found_real_right;
ast_node->children[1]->detectSignWidth(width_hint_left, sign_hint_left, &found_real_left);
ast_node->children[2]->detectSignWidth(width_hint_right, sign_hint_right, &found_real_right);
detect_sign_width_proxy(ast_node->children[1], width_hint_left, sign_hint_left, &found_real_left);
detect_sign_width_proxy(ast_node->children[2], width_hint_right, sign_hint_right, &found_real_right);
if (found_real_left || found_real_right) {
child_1_is_self_determined = true;
child_2_is_self_determined = true;
Expand All @@ -1280,7 +1288,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool

if (const_fold && ast_node->type == Yosys::AST::AST_CASE)
{
ast_node->detectSignWidth(width_hint, sign_hint);
detect_sign_width_proxy(ast_node, width_hint, sign_hint);
while (simplify(ast_node->children[0], const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) { }
if (ast_node->children[0]->type == Yosys::AST::AST_CONSTANT && ast_node->children[0]->bits_only_01()) {
ast_node->children[0]->is_signed = sign_hint;
Expand Down Expand Up @@ -1415,7 +1423,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
width_hint = backup_width_hint;
sign_hint = backup_sign_hint;
if (width_hint < 0)
ast_node->detectSignWidth(width_hint, sign_hint);
detect_sign_width_proxy(ast_node, width_hint, sign_hint);
}

current_block = backup_current_block;
Expand Down Expand Up @@ -1864,6 +1872,11 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
current_scope[ast_node->str] = auto_wire;
did_something = true;
} else {
ast_node->dumpAst(nullptr, "----");
if (ast_node->id2ast)
ast_node->id2ast->dumpAst(nullptr, "____");
else
std::cout << "has no id2ast\n";
log_file_error(ast_node->filename, ast_node->location.first_line, "Identifier `%s' is implicitly declared and `default_nettype is set to none.\n", ast_node->str.c_str());
}
}
Expand Down Expand Up @@ -1994,7 +2007,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
{
int expr_width_hint = -1;
bool expr_sign_hint = true;
varbuf->detectSignWidth(expr_width_hint, expr_sign_hint);
detect_sign_width_proxy(varbuf, expr_width_hint, expr_sign_hint);
while (simplify(varbuf, true, false, false, stage, 32, true, false)) { }
}

Expand Down Expand Up @@ -2035,7 +2048,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
{
int expr_width_hint = -1;
bool expr_sign_hint = true;
buf->detectSignWidth(expr_width_hint, expr_sign_hint);
detect_sign_width_proxy(buf, expr_width_hint, expr_sign_hint);
while (simplify(buf, true, false, false, stage, expr_width_hint, expr_sign_hint, false)) { }
}

Expand Down Expand Up @@ -2086,7 +2099,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool
{
int expr_width_hint = -1;
bool expr_sign_hint = true;
buf->detectSignWidth(expr_width_hint, expr_sign_hint);
detect_sign_width_proxy(buf, expr_width_hint, expr_sign_hint);
while (simplify(buf, true, false, false, stage, expr_width_hint, expr_sign_hint, true)) { }
}

Expand Down Expand Up @@ -2500,7 +2513,7 @@ bool simplify(Yosys::AST::AstNode *ast_node, bool const_fold, bool at_zero, bool

int shamt_width_hint = -1;
bool shamt_sign_hint = true;
shift_expr->detectSignWidth(shamt_width_hint, shamt_sign_hint);
detect_sign_width_proxy(shift_expr, shamt_width_hint, shamt_sign_hint);

Yosys::AST::AstNode *wire_sel = new Yosys::AST::AstNode(Yosys::AST::AST_WIRE, new Yosys::AST::AstNode(Yosys::AST::AST_RANGE, ast_node->mkconst_int(shamt_width_hint-1, true), ast_node->mkconst_int(0, true)));
wire_sel->str = stringf("$bitselwrite$sel$%s:%d$%d", encode_filename(ast_node->filename).c_str(), ast_node->location.first_line, autoidx++);
Expand Down Expand Up @@ -2709,7 +2722,7 @@ skip_dynamic_range_lvalue_expansion:;
{
int child_width_hint = -1;
bool child_sign_hint = true;
child->detectSignWidth(child_width_hint, child_sign_hint);
detect_sign_width_proxy(child, child_width_hint, child_sign_hint);

Yosys::AST::AstNode *rhs = wire_tmp_id->clone();
rhs->children.push_back(new Yosys::AST::AstNode(Yosys::AST::AST_RANGE, ast_node->mkconst_int(cursor+child_width_hint-1, true), ast_node->mkconst_int(cursor, true)));
Expand Down Expand Up @@ -3127,7 +3140,13 @@ skip_dynamic_range_lvalue_expansion:;

// Is this needed?
//while (simplify(buf, true, false, false, stage, width_hint, sign_hint, false)) { }
buf->detectSignWidth(width_hint, sign_hint);

//if (buf->type == Yosys::AST::AST_IDENTIFIER && buf->id2ast && buf->id2ast->type == Yosys::AST::AST_TYPEDEF) {
// // If the identifier points to a typedef, use the type that is stored inside the typedef (children[0]).
// log_assert(buf->id2ast->children.size());
// buf->id2ast = buf->id2ast->children[0];
//}
detect_sign_width_proxy(buf, width_hint, sign_hint);

if (buf->type == Yosys::AST::AST_IDENTIFIER) {
id_ast = buf->id2ast;
Expand Down Expand Up @@ -3279,7 +3298,7 @@ skip_dynamic_range_lvalue_expansion:;
RTLIL::unescape_id(ast_node->str).c_str());
int child_width_hint = width_hint;
bool child_sign_hint = sign_hint;
ast_node->children[0]->detectSignWidth(child_width_hint, child_sign_hint);
detect_sign_width_proxy(ast_node->children[0], child_width_hint, child_sign_hint);
x = ast_node->children[0]->asReal(child_sign_hint);
}

Expand All @@ -3290,7 +3309,7 @@ skip_dynamic_range_lvalue_expansion:;
RTLIL::unescape_id(ast_node->str).c_str());
int child_width_hint = width_hint;
bool child_sign_hint = sign_hint;
ast_node->children[1]->detectSignWidth(child_width_hint, child_sign_hint);
detect_sign_width_proxy(ast_node->children[1], child_width_hint, child_sign_hint);
y = ast_node->children[1]->asReal(child_sign_hint);
}

Expand Down Expand Up @@ -3358,7 +3377,7 @@ skip_dynamic_range_lvalue_expansion:;
int exp_width = -1;
bool exp_sign = false;
Yosys::AST::AstNode *exp = ast_node->children[0];
exp->detectSignWidth(exp_width, exp_sign, NULL);
detect_sign_width_proxy(exp, exp_width, exp_sign, NULL);

newNode = ast_node->mkconst_int(0, false);

Expand Down Expand Up @@ -3991,10 +4010,10 @@ replace_fcall_later:;
if (choice->type == Yosys::AST::AST_CONSTANT) {
int other_width_hint = width_hint;
bool other_sign_hint = sign_hint, other_real = false;
not_choice->detectSignWidth(other_width_hint, other_sign_hint, &other_real);
detect_sign_width_proxy(not_choice, other_width_hint, other_sign_hint, &other_real);
if (other_real) {
newNode = new Yosys::AST::AstNode(Yosys::AST::AST_REALVALUE);
choice->detectSignWidth(width_hint, sign_hint);
detect_sign_width_proxy(choice, width_hint, sign_hint);
newNode->realvalue = choice->asReal(sign_hint);
} else {
RTLIL::Const y = choice->bitsAsConst(width_hint, sign_hint);
Expand Down