Skip to content

Commit 75df29e

Browse files
Skip non-synthesizable objects (#243)
* Skip non-synthesizable objects Signed-off-by: Kamil Rakoczy <[email protected]> * Add check for case node Signed-off-by: Kamil Rakoczy <[email protected]> * Add AST_BLOCK if not present in initial Signed-off-by: Kamil Rakoczy <[email protected]> * Add AST_BLOCK if stmt is missing in always Signed-off-by: Kamil Rakoczy <[email protected]> * Add AST_BLOCK if stmt is missing in initial Signed-off-by: Kamil Rakoczy <[email protected]> * Check if node is present in hier_path Signed-off-by: Kamil Rakoczy <[email protected]> * Check for node in if_else Signed-off-by: Kamil Rakoczy <[email protected]> * Rely on UHDM's SynthSubset to filter out non-synthesizables Signed-off-by: Krzysztof Bieganski <[email protected]> Co-authored-by: Krzysztof Bieganski <[email protected]>
1 parent 37b40cc commit 75df29e

File tree

6 files changed

+65
-56
lines changed

6 files changed

+65
-56
lines changed

systemverilog-plugin/UhdmAst.cc

Lines changed: 53 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,7 +1376,12 @@ static void add_or_replace_child(AST::AstNode *parent, AST::AstNode *child)
13761376
if (initial_node_it != parent->children.end()) {
13771377
AST::AstNode *initial_node = *initial_node_it;
13781378

1379-
log_assert(!(initial_node->children.empty()));
1379+
// simplify assumes that initial has a block under it
1380+
// In case we don't have one (there were no statements under the initial), let's add it
1381+
if (initial_node->children.empty()) {
1382+
initial_node->children.push_back(new AST::AstNode(AST::AST_BLOCK));
1383+
}
1384+
13801385
log_assert(initial_node->children[0]->type == AST::AST_BLOCK);
13811386
log_assert(!(child->children.empty()));
13821387
log_assert(child->children[0]->type == AST::AST_BLOCK);
@@ -2471,13 +2476,18 @@ void UhdmAst::process_always()
24712476
{
24722477
current_node = make_ast_node(AST::AST_ALWAYS);
24732478
visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
2474-
AST::AstNode *block = nullptr;
2475-
if (node && node->type != AST::AST_BLOCK) {
2476-
block = new AST::AstNode(AST::AST_BLOCK, node);
2479+
if (node) {
2480+
AST::AstNode *block = nullptr;
2481+
if (node->type != AST::AST_BLOCK) {
2482+
block = new AST::AstNode(AST::AST_BLOCK, node);
2483+
} else {
2484+
block = node;
2485+
}
2486+
current_node->children.push_back(block);
24772487
} else {
2478-
block = node;
2488+
// create empty block
2489+
current_node->children.push_back(new AST::AstNode(AST::AST_BLOCK));
24792490
}
2480-
current_node->children.push_back(block);
24812491
});
24822492
switch (vpi_get(vpiAlwaysType, obj_h)) {
24832493
case vpiAlwaysComb:
@@ -2525,6 +2535,8 @@ void UhdmAst::process_initial()
25252535
node = block_node;
25262536
}
25272537
current_node->children.push_back(node);
2538+
} else {
2539+
current_node->children.push_back(make_ast_node(AST::AST_BLOCK));
25282540
}
25292541
});
25302542
}
@@ -3104,7 +3116,8 @@ void UhdmAst::process_if_else()
31043116
condition->children.push_back(constant);
31053117
visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
31063118
auto *statements = new AST::AstNode(AST::AST_BLOCK);
3107-
statements->children.push_back(node);
3119+
if (node)
3120+
statements->children.push_back(node);
31083121
condition->children.push_back(statements);
31093122
});
31103123
current_node->children.push_back(condition);
@@ -3115,7 +3128,8 @@ void UhdmAst::process_if_else()
31153128
condition->children.push_back(elseBlock);
31163129
visit_one_to_one({vpiElseStmt}, obj_h, [&](AST::AstNode *node) {
31173130
auto *statements = new AST::AstNode(AST::AST_BLOCK);
3118-
statements->children.push_back(node);
3131+
if (node)
3132+
statements->children.push_back(node);
31193133
condition->children.push_back(statements);
31203134
});
31213135
current_node->children.push_back(condition);
@@ -3224,12 +3238,14 @@ void UhdmAst::process_case_item()
32243238
current_node->children.push_back(new AST::AstNode(AST::AST_DEFAULT));
32253239
}
32263240
visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
3227-
if (node->type != AST::AST_BLOCK) {
3228-
auto block_node = new AST::AstNode(AST::AST_BLOCK);
3229-
block_node->children.push_back(node);
3230-
node = block_node;
3241+
if (node) {
3242+
if (node->type != AST::AST_BLOCK) {
3243+
auto block_node = new AST::AstNode(AST::AST_BLOCK);
3244+
block_node->children.push_back(node);
3245+
node = block_node;
3246+
}
3247+
current_node->children.push_back(node);
32313248
}
3232-
current_node->children.push_back(node);
32333249
});
32343250
}
32353251

@@ -3307,22 +3323,24 @@ void UhdmAst::process_hier_path()
33073323
current_node->str = "\\";
33083324
AST::AstNode *top_node = nullptr;
33093325
visit_one_to_many({vpiActual}, obj_h, [&](AST::AstNode *node) {
3310-
if (node->str.find('[') != std::string::npos)
3311-
node->str = node->str.substr(0, node->str.find('['));
3312-
// for first node, just set correct string and move any children
3313-
if (!top_node) {
3314-
current_node->str += node->str.substr(1);
3315-
current_node->children = std::move(node->children);
3316-
top_node = current_node;
3317-
delete node;
3318-
} else {
3319-
if (node->str.empty()) {
3320-
log_assert(!node->children.empty());
3321-
top_node->children.push_back(node->children[0]);
3326+
if (node) {
3327+
if (node->str.find('[') != std::string::npos)
3328+
node->str = node->str.substr(0, node->str.find('['));
3329+
// for first node, just set correct string and move any children
3330+
if (!top_node) {
3331+
current_node->str += node->str.substr(1);
3332+
current_node->children = std::move(node->children);
3333+
top_node = current_node;
3334+
delete node;
33223335
} else {
3323-
node->type = static_cast<AST::AstNodeType>(AST::AST_DOT);
3324-
top_node->children.push_back(node);
3325-
top_node = node;
3336+
if (node->str.empty()) {
3337+
log_assert(!node->children.empty());
3338+
top_node->children.push_back(node->children[0]);
3339+
} else {
3340+
node->type = static_cast<AST::AstNodeType>(AST::AST_DOT);
3341+
top_node->children.push_back(node);
3342+
top_node = node;
3343+
}
33263344
}
33273345
}
33283346
});
@@ -3435,20 +3453,6 @@ void UhdmAst::process_sys_func_call()
34353453
{
34363454
current_node = make_ast_node(AST::AST_FCALL);
34373455

3438-
// skip unsupported simulation functions
3439-
std::string to_skip[] = {
3440-
"\\$value$plusargs", "\\$test$plusargs", "\\$displayb", "\\$displayh", "\\$displayo", "\\$strobeb", "\\$strobeh", "\\$strobeo",
3441-
"\\$writeb", "\\$writeh", "\\$writeo", "\\$dumplimit", "\\$dumpflush", "\\$fdisplay", "\\$fdisplayb", "\\$fdisplayh",
3442-
"\\$fdisplayo", "\\$fmonitor", "\\$fstrobe", "\\$fstrobeb", "\\$fstrobeh", "\\$fstrobeo", "\\$fwrite", "\\$fwriteb",
3443-
"\\$fwriteh", "\\$fwriteo", "\\$ungetc", "\\$fgetc", "\\$fgets", "\\$ftell", "\\$printtimescale"};
3444-
3445-
if (std::find(std::begin(to_skip), std::end(to_skip), current_node->str) != std::end(to_skip)) {
3446-
log_warning("System function %s was skipped\n", current_node->str.substr(1).c_str());
3447-
delete current_node;
3448-
current_node = nullptr;
3449-
return;
3450-
}
3451-
34523456
std::string task_calls[] = {"\\$display", "\\$monitor", "\\$write", "\\$time", "\\$readmemh", "\\$readmemb", "\\$finish", "\\$stop"};
34533457

34543458
if (current_node->str == "\\$signed") {
@@ -3503,16 +3507,6 @@ void UhdmAst::process_immediate_assert()
35033507
});
35043508
}
35053509

3506-
void UhdmAst::process_nonsynthesizable(const UHDM::BaseClass *object)
3507-
{
3508-
log_warning("%s:%d: Non-synthesizable object of type '%s'\n", object->VpiFile().c_str(), object->VpiLineNo(), UHDM::VpiTypeName(obj_h).c_str());
3509-
current_node = make_ast_node(AST::AST_BLOCK);
3510-
visit_one_to_one({vpiStmt}, obj_h, [&](AST::AstNode *node) {
3511-
if (node)
3512-
current_node->children.push_back(node);
3513-
});
3514-
}
3515-
35163510
void UhdmAst::process_logic_typespec()
35173511
{
35183512
current_node = make_ast_node(AST::AST_WIRE);
@@ -4040,6 +4034,13 @@ AST::AstNode *UhdmAst::process_object(vpiHandle obj_handle)
40404034
const unsigned object_type = vpi_get(vpiType, obj_h);
40414035
const uhdm_handle *const handle = (const uhdm_handle *)obj_h;
40424036
const UHDM::BaseClass *const object = (const UHDM::BaseClass *)handle->object;
4037+
for (auto *obj : shared.nonSynthesizableObjects) {
4038+
if (!object->Compare(obj)) {
4039+
log_warning("%s:%d: Skipping non-synthesizable object of type '%s'\n", object->VpiFile().c_str(), object->VpiLineNo(),
4040+
UHDM::VpiTypeName(obj_h).c_str());
4041+
return nullptr;
4042+
}
4043+
}
40434044

40444045
if (shared.debug_flag) {
40454046
std::cout << indent << "Object '" << object->VpiName() << "' of type '" << UHDM::VpiTypeName(obj_h) << '\'' << std::endl;
@@ -4236,9 +4237,6 @@ AST::AstNode *UhdmAst::process_object(vpiHandle obj_handle)
42364237
break;
42374238
case UHDM::uhdmimport_typespec:
42384239
break;
4239-
case vpiDelayControl:
4240-
process_nonsynthesizable(object);
4241-
break;
42424240
case vpiLogicTypespec:
42434241
process_logic_typespec();
42444242
break;

systemverilog-plugin/UhdmAst.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ class UhdmAst
148148
void process_gate();
149149
void process_primterm();
150150
void simplify_parameter(AST::AstNode *parameter, AST::AstNode *module_node = nullptr);
151-
void process_nonsynthesizable(const UHDM::BaseClass *object);
152151
void process_unsupported_stmt(const UHDM::BaseClass *object);
153152

154153
UhdmAst(UhdmAst *p, UhdmAstShared &s, const std::string &i) : parent(p), shared(s), indent(i)

systemverilog-plugin/uhdmastfrontend.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ struct UhdmAstFrontend : public UhdmCommonFrontend {
4444
UHDM::Serializer serializer;
4545

4646
std::vector<vpiHandle> restoredDesigns = serializer.Restore(filename);
47+
UHDM::SynthSubset *synthSubset = new UHDM::SynthSubset(&serializer, this->shared.nonSynthesizableObjects, false);
48+
synthSubset->listenDesigns(restoredDesigns);
49+
delete synthSubset;
4750
if (this->shared.debug_flag || !this->report_directory.empty()) {
4851
for (auto design : restoredDesigns) {
4952
std::stringstream strstr;

systemverilog-plugin/uhdmastshared.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ class UhdmAstShared
5252
std::unordered_map<std::string, AST::AstNode *> param_types;
5353

5454
AST::AstNode *current_top_node = nullptr;
55+
// Set of non-synthesizable objects to skip in current design;
56+
std::set<const UHDM::BaseClass *> nonSynthesizableObjects;
5557
};
5658

5759
YOSYS_NAMESPACE_END

systemverilog-plugin/uhdmcommonfrontend.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include "UhdmAst.h"
2121
#include "frontends/ast/ast.h"
2222
#include "kernel/yosys.h"
23+
#include "uhdm/SynthSubset.h"
24+
#include "uhdm/VpiListener.h"
2325
#include <string>
2426
#include <vector>
2527

systemverilog-plugin/uhdmsurelogastfrontend.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ struct UhdmSurelogAstFrontend : public UhdmCommonFrontend {
121121
}
122122
}
123123

124+
UHDM::Serializer serializer;
125+
UHDM::SynthSubset *synthSubset = new UHDM::SynthSubset(&serializer, this->shared.nonSynthesizableObjects, false);
126+
synthSubset->listenDesigns(uhdm_design);
127+
delete synthSubset;
128+
124129
SURELOG::shutdown_compiler(compiler);
125130
delete clp;
126131
delete symbolTable;

0 commit comments

Comments
 (0)