aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenedikt Tutzer <benedikt.tutzer@gmail.com>2019-10-15 10:13:21 +0200
committerBenedikt Tutzer <benedikt.tutzer@gmail.com>2019-10-15 10:13:21 +0200
commitf8f572fbfc4e5de3afa7dc05f5fa1feff87aabd3 (patch)
treedaca10f9ee8149bc7ee13eb9cf89702886275947
parent79be986e2248540854c3e8e1e21f5bf971079690 (diff)
parent2daa56859f51631992cc172ccddad55e741b0c3d (diff)
downloadyosys-f8f572fbfc4e5de3afa7dc05f5fa1feff87aabd3.tar.gz
yosys-f8f572fbfc4e5de3afa7dc05f5fa1feff87aabd3.tar.bz2
yosys-f8f572fbfc4e5de3afa7dc05f5fa1feff87aabd3.zip
Merge branch 'master' of https://github.com/YosysHQ/yosys into feature/python_wrappers/globals_and_streams
-rw-r--r--Makefile1
-rw-r--r--README.md2
-rw-r--r--frontends/ast/ast.cc3
-rw-r--r--frontends/ast/ast.h7
-rw-r--r--frontends/ast/genrtlil.cc1
-rw-r--r--frontends/ast/simplify.cc116
-rw-r--r--frontends/verilog/verilog_parser.y80
-rw-r--r--techlibs/ecp5/cells_bb.v7
-rw-r--r--techlibs/ecp5/cells_ff.vh16
-rw-r--r--techlibs/ecp5/synth_ecp5.cc1
-rw-r--r--techlibs/xilinx/cells_sim.v11
-rw-r--r--techlibs/xilinx/cells_xtra.py6
-rw-r--r--techlibs/xilinx/xc6s_cells_xtra.v10
-rw-r--r--techlibs/xilinx/xc6v_cells_xtra.v10
-rw-r--r--techlibs/xilinx/xc7_cells_xtra.v10
-rw-r--r--tests/svtypes/.gitignore3
-rwxr-xr-xtests/svtypes/run-test.sh20
-rw-r--r--tests/svtypes/typedef_memory.sv10
-rw-r--r--tests/svtypes/typedef_memory.ys3
-rw-r--r--tests/svtypes/typedef_memory_2.sv10
-rw-r--r--tests/svtypes/typedef_memory_2.ys4
-rw-r--r--tests/svtypes/typedef_package.sv11
-rw-r--r--tests/svtypes/typedef_param.sv22
-rw-r--r--tests/svtypes/typedef_scopes.sv23
-rw-r--r--tests/svtypes/typedef_simple.sv19
25 files changed, 345 insertions, 61 deletions
diff --git a/Makefile b/Makefile
index 33c04cf92..895cfbf89 100644
--- a/Makefile
+++ b/Makefile
@@ -708,6 +708,7 @@ test: $(TARGETS) $(EXTRA_TARGETS)
+cd tests/various && bash run-test.sh
+cd tests/sat && bash run-test.sh
+cd tests/svinterfaces && bash run-test.sh $(SEEDOPT)
+ +cd tests/svtypes && bash run-test.sh $(SEEDOPT)
+cd tests/proc && bash run-test.sh
+cd tests/opt && bash run-test.sh
+cd tests/aiger && bash run-test.sh $(ABCOPT)
diff --git a/README.md b/README.md
index fdd4bb410..db7810cb4 100644
--- a/README.md
+++ b/README.md
@@ -510,6 +510,8 @@ from SystemVerilog:
into a design with ``read_verilog``, all its packages are available to
SystemVerilog files being read into the same design afterwards.
+- typedefs are supported (including inside packages)
+
- SystemVerilog interfaces (SVIs) are supported. Modports for specifying whether
ports are inputs or outputs are supported.
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 37a69d8bf..5bbea0faf 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -164,6 +164,8 @@ std::string AST::type2str(AstNodeType type)
X(AST_MODPORT)
X(AST_MODPORTMEMBER)
X(AST_PACKAGE)
+ X(AST_WIRETYPE)
+ X(AST_TYPEDEF)
#undef X
default:
log_abort();
@@ -206,6 +208,7 @@ AstNode::AstNode(AstNodeType type, AstNode *child1, AstNode *child2, AstNode *ch
was_checked = false;
range_valid = false;
range_swapped = false;
+ is_custom_type = false;
port_id = 0;
range_left = -1;
range_right = 0;
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 0ec249ab9..918d178c7 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -148,7 +148,10 @@ namespace AST
AST_INTERFACEPORTTYPE,
AST_MODPORT,
AST_MODPORTMEMBER,
- AST_PACKAGE
+ AST_PACKAGE,
+
+ AST_WIRETYPE,
+ AST_TYPEDEF
};
// convert an node type to a string (e.g. for debug output)
@@ -174,7 +177,7 @@ namespace AST
// node content - most of it is unused in most node types
std::string str;
std::vector<RTLIL::State> bits;
- bool is_input, is_output, is_reg, is_logic, is_signed, is_string, is_wand, is_wor, range_valid, range_swapped, was_checked, is_unsized;
+ bool is_input, is_output, is_reg, is_logic, is_signed, is_string, is_wand, is_wor, range_valid, range_swapped, was_checked, is_unsized, is_custom_type;
int port_id, range_left, range_right;
uint32_t integer;
double realvalue;
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index 407a34472..94f5c0a04 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -863,6 +863,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
case AST_PACKAGE:
case AST_MODPORT:
case AST_MODPORTMEMBER:
+ case AST_TYPEDEF:
break;
case AST_INTERFACEPORT: {
// If a port in a module with unknown type is found, mark it with the attribute 'is_interface'
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index b1ee22f42..44fd32cdc 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -318,7 +318,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
}
// activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.)
- if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX)
+ if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_DEFPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX || type == AST_TYPEDEF)
const_fold = true;
if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM))
const_fold = true;
@@ -336,6 +336,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
std::map<std::string, AstNode*> this_wire_scope;
for (size_t i = 0; i < children.size(); i++) {
AstNode *node = children[i];
+
if (node->type == AST_WIRE) {
if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) {
for (auto c : node->children[0]->children) {
@@ -405,14 +406,15 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
this_wire_scope[node->str] = node;
}
if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_GENVAR ||
- node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION || node->type == AST_CELL) {
+ node->type == AST_MEMORY || node->type == AST_FUNCTION || node->type == AST_TASK || node->type == AST_DPI_FUNCTION || node->type == AST_CELL ||
+ node->type == AST_TYPEDEF) {
backup_scope[node->str] = current_scope[node->str];
current_scope[node->str] = node;
}
}
for (size_t i = 0; i < children.size(); i++) {
AstNode *node = children[i];
- if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY)
+ if (node->type == AST_PARAMETER || node->type == AST_LOCALPARAM || node->type == AST_WIRE || node->type == AST_AUTOWIRE || node->type == AST_MEMORY || node->type == AST_TYPEDEF)
while (node->simplify(true, false, false, 1, -1, false, node->type == AST_PARAMETER || node->type == AST_LOCALPARAM))
did_something = true;
}
@@ -780,6 +782,99 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
delete_children();
}
+ // resolve typedefs
+ if (type == AST_TYPEDEF) {
+ log_assert(children.size() == 1);
+ log_assert(children[0]->type == AST_WIRE || children[0]->type == AST_MEMORY);
+ while(children[0]->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param))
+ did_something = true;
+ log_assert(!children[0]->is_custom_type);
+ }
+
+ // resolve types of wires
+ if (type == AST_WIRE || type == AST_MEMORY) {
+ if (is_custom_type) {
+ log_assert(children.size() >= 1);
+ log_assert(children[0]->type == AST_WIRETYPE);
+ if (!current_scope.count(children[0]->str))
+ log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[0]->str.c_str());
+ AstNode *resolved_type = current_scope.at(children[0]->str);
+ if (resolved_type->type != AST_TYPEDEF)
+ log_file_error(filename, linenum, "`%s' does not name a type\n", children[0]->str.c_str());
+ log_assert(resolved_type->children.size() == 1);
+ AstNode *templ = resolved_type->children[0];
+ // Remove type reference
+ delete children[0];
+ children.erase(children.begin());
+
+ // Ensure typedef itself is fully simplified
+ while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {};
+
+ if (type == AST_WIRE)
+ type = templ->type;
+ is_reg = templ->is_reg;
+ is_logic = templ->is_logic;
+ is_signed = templ->is_signed;
+ is_string = templ->is_string;
+ is_custom_type = templ->is_custom_type;
+
+ range_valid = templ->range_valid;
+ range_swapped = templ->range_swapped;
+ range_left = templ->range_left;
+ range_right = templ->range_right;
+
+ // Insert clones children from template at beginning
+ for (int i = 0; i < GetSize(templ->children); i++)
+ children.insert(children.begin() + i, templ->children[i]->clone());
+
+ if (type == AST_MEMORY && GetSize(children) == 1) {
+ // Single-bit memories must have [0:0] range
+ AstNode *rng = new AstNode(AST_RANGE);
+ rng->children.push_back(AstNode::mkconst_int(0, true));
+ rng->children.push_back(AstNode::mkconst_int(0, true));
+ children.insert(children.begin(), rng);
+ }
+
+ did_something = true;
+ }
+ log_assert(!is_custom_type);
+ }
+
+ // resolve types of parameters
+ if (type == AST_LOCALPARAM || type == AST_PARAMETER) {
+ if (is_custom_type) {
+ log_assert(children.size() == 2);
+ log_assert(children[1]->type == AST_WIRETYPE);
+ if (!current_scope.count(children[1]->str))
+ log_file_error(filename, linenum, "Unknown identifier `%s' used as type name\n", children[1]->str.c_str());
+ AstNode *resolved_type = current_scope.at(children[1]->str);
+ if (resolved_type->type != AST_TYPEDEF)
+ log_file_error(filename, linenum, "`%s' does not name a type\n", children[1]->str.c_str());
+ log_assert(resolved_type->children.size() == 1);
+ AstNode *templ = resolved_type->children[0];
+ delete children[1];
+ children.pop_back();
+
+ // Ensure typedef itself is fully simplified
+ while(templ->simplify(const_fold, at_zero, in_lvalue, stage, width_hint, sign_hint, in_param)) {};
+
+ if (templ->type == AST_MEMORY)
+ log_file_error(filename, linenum, "unpacked array type `%s' cannot be used for a parameter\n", children[1]->str.c_str());
+ is_signed = templ->is_signed;
+ is_string = templ->is_string;
+ is_custom_type = templ->is_custom_type;
+
+ range_valid = templ->range_valid;
+ range_swapped = templ->range_swapped;
+ range_left = templ->range_left;
+ range_right = templ->range_right;
+ for (auto template_child : templ->children)
+ children.push_back(template_child->clone());
+ did_something = true;
+ }
+ log_assert(!is_custom_type);
+ }
+
// resolve constant prefixes
if (type == AST_PREFIX) {
if (children[0]->type != AST_CONSTANT) {
@@ -1194,7 +1289,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
if (type == AST_BLOCK && str.empty())
{
for (size_t i = 0; i < children.size(); i++)
- if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM)
+ if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM || children[i]->type == AST_TYPEDEF)
log_file_error(children[i]->filename, children[i]->linenum, "Local declaration in unnamed block is an unsupported SystemVerilog feature!\n");
}
@@ -1206,7 +1301,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
std::vector<AstNode*> new_children;
for (size_t i = 0; i < children.size(); i++)
- if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM) {
+ if (children[i]->type == AST_WIRE || children[i]->type == AST_MEMORY || children[i]->type == AST_PARAMETER || children[i]->type == AST_LOCALPARAM || children[i]->type == AST_TYPEDEF) {
children[i]->simplify(false, false, false, stage, -1, false, false);
current_ast_mod->children.push_back(children[i]);
current_scope[children[i]->str] = children[i];
@@ -2906,7 +3001,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
}
}
- if ((type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL) && name_map.count(str) > 0)
+ if ((type == AST_IDENTIFIER || type == AST_FCALL || type == AST_TCALL || type == AST_WIRETYPE) && name_map.count(str) > 0)
str = name_map[str];
std::map<std::string, std::string> backup_name_map;
@@ -2914,7 +3009,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
for (size_t i = 0; i < children.size(); i++) {
AstNode *child = children[i];
if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER || child->type == AST_LOCALPARAM ||
- child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL) {
+ child->type == AST_FUNCTION || child->type == AST_TASK || child->type == AST_CELL || child->type == AST_TYPEDEF) {
if (backup_name_map.size() == 0)
backup_name_map = name_map;
std::string new_name = prefix[0] == '\\' ? prefix.substr(1) : prefix;
@@ -2945,6 +3040,7 @@ void AstNode::expand_genblock(std::string index_var, std::string prefix, std::ma
child->expand_genblock(index_var, prefix, name_map);
}
+
if (backup_name_map.size() > 0)
name_map.swap(backup_name_map);
}
@@ -2998,6 +3094,9 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg
uint32_t children_flags = 0;
int lhs_children_counter = 0;
+ if (type == AST_TYPEDEF)
+ return; // don't touch content of typedefs
+
if (type == AST_ASSIGN || type == AST_ASSIGN_LE || type == AST_ASSIGN_EQ)
{
// mark all memories that are used in a complex expression on the left side of an assignment
@@ -3155,6 +3254,9 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
if (type == AST_FUNCTION || type == AST_TASK)
return false;
+ if (type == AST_TYPEDEF)
+ return false;
+
if (type == AST_MEMINIT && id2ast && mem2reg_set.count(id2ast))
{
log_assert(children[0]->type == AST_CONSTANT);
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 4afd72b73..77f6d2051 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -155,7 +155,7 @@ struct specify_rise_fall {
%type <ast> range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int
%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
-%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id
+%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id
%type <boolean> opt_signed opt_property unique_case_attr
%type <al> attr case_attr
@@ -206,6 +206,7 @@ design:
task_func_decl design |
param_decl design |
localparam_decl design |
+ typedef_decl design |
package design |
interface design |
/* empty */;
@@ -290,6 +291,9 @@ hierarchical_id:
$$ = $1;
};
+hierarchical_type_id:
+ '(' hierarchical_id ')' { $$ = $2; };
+
module:
attr TOK_MODULE TOK_ID {
do_not_require_port_stubs = false;
@@ -324,13 +328,13 @@ single_module_para:
astbuf1 = new AstNode(AST_PARAMETER);
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
append_attr(astbuf1, $1);
- } param_signed param_integer param_range single_param_decl |
+ } param_type single_param_decl |
attr TOK_LOCALPARAM {
if (astbuf1) delete astbuf1;
astbuf1 = new AstNode(AST_LOCALPARAM);
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
append_attr(astbuf1, $1);
- } param_signed param_integer param_range single_param_decl |
+ } param_type single_param_decl |
single_param_decl;
module_args_opt:
@@ -426,6 +430,7 @@ package_body:
package_body package_body_stmt |;
package_body_stmt:
+ typedef_decl |
localparam_decl;
interface:
@@ -452,7 +457,7 @@ interface_body:
interface_body interface_body_stmt |;
interface_body_stmt:
- param_decl | localparam_decl | defparam_decl | wire_decl | always_stmt | assign_stmt |
+ param_decl | localparam_decl | typedef_decl | defparam_decl | wire_decl | always_stmt | assign_stmt |
modport_stmt;
non_opt_delay:
@@ -475,8 +480,14 @@ wire_type:
};
wire_type_token_list:
- wire_type_token | wire_type_token_list wire_type_token |
- wire_type_token_io ;
+ wire_type_token |
+ wire_type_token_list wire_type_token |
+ wire_type_token_io |
+ hierarchical_type_id {
+ astbuf3->is_custom_type = true;
+ astbuf3->children.push_back(new AstNode(AST_WIRETYPE));
+ astbuf3->children.back()->str = *$1;
+ };
wire_type_token_io:
TOK_INPUT {
@@ -591,7 +602,7 @@ module_body:
/* empty */;
module_body_stmt:
- task_func_decl | specify_block |param_decl | localparam_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt |
+ task_func_decl | specify_block | param_decl | localparam_decl | typedef_decl | defparam_decl | specparam_declaration | wire_decl | assign_stmt | cell_stmt |
always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property | checker_decl | ignored_specify_block;
checker_decl:
@@ -1149,12 +1160,20 @@ param_range:
}
};
+param_type:
+ param_signed param_integer param_real param_range |
+ hierarchical_type_id {
+ astbuf1->is_custom_type = true;
+ astbuf1->children.push_back(new AstNode(AST_WIRETYPE));
+ astbuf1->children.back()->str = *$1;
+ };
+
param_decl:
attr TOK_PARAMETER {
astbuf1 = new AstNode(AST_PARAMETER);
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
append_attr(astbuf1, $1);
- } param_signed param_integer param_real param_range param_decl_list ';' {
+ } param_type param_decl_list ';' {
delete astbuf1;
};
@@ -1163,7 +1182,7 @@ localparam_decl:
astbuf1 = new AstNode(AST_LOCALPARAM);
astbuf1->children.push_back(AstNode::mkconst_int(0, true));
append_attr(astbuf1, $1);
- } param_signed param_integer param_real param_range param_decl_list ';' {
+ } param_type param_decl_list ';' {
delete astbuf1;
};
@@ -1327,7 +1346,7 @@ wire_name:
if ($2 != NULL) {
if (node->is_input || node->is_output)
frontend_verilog_yyerror("input/output/inout ports cannot have unpacked dimensions.");
- if (!astbuf2) {
+ if (!astbuf2 && !node->is_custom_type) {
AstNode *rng = new AstNode(AST_RANGE);
rng->children.push_back(AstNode::mkconst_int(0, true));
rng->children.push_back(AstNode::mkconst_int(0, true));
@@ -1377,6 +1396,45 @@ assign_expr:
ast_stack.back()->children.push_back(new AstNode(AST_ASSIGN, $1, $3));
};
+typedef_decl:
+ TOK_TYPEDEF wire_type range TOK_ID range_or_multirange ';' {
+ astbuf1 = $2;
+ astbuf2 = $3;
+ if (astbuf1->range_left >= 0 && astbuf1->range_right >= 0) {
+ if (astbuf2) {
+ frontend_verilog_yyerror("integer/genvar types cannot have packed dimensions.");
+ } else {
+ astbuf2 = new AstNode(AST_RANGE);
+ astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_left, true));
+ astbuf2->children.push_back(AstNode::mkconst_int(astbuf1->range_right, true));
+ }
+ }
+ if (astbuf2 && astbuf2->children.size() != 2)
+ frontend_verilog_yyerror("wire/reg/logic packed dimension must be of the form: [<expr>:<expr>], [<expr>+:<expr>], or [<expr>-:<expr>]");
+ if (astbuf2)
+ astbuf1->children.push_back(astbuf2);
+
+ if ($5 != NULL) {
+ if (!astbuf2) {
+ AstNode *rng = new AstNode(AST_RANGE);
+ rng->children.push_back(AstNode::mkconst_int(0, true));
+ rng->children.push_back(AstNode::mkconst_int(0, true));
+ astbuf1->children.push_back(rng);
+ }
+ astbuf1->type = AST_MEMORY;
+ auto *rangeNode = $5;
+ if (rangeNode->type == AST_RANGE && rangeNode->children.size() == 1) {
+ // SV array size [n], rewrite as [n-1:0]
+ rangeNode->children[0] = new AstNode(AST_SUB, rangeNode->children[0], AstNode::mkconst_int(1, true));
+ rangeNode->children.push_back(AstNode::mkconst_int(0, false));
+ }
+ astbuf1->children.push_back(rangeNode);
+ }
+
+ ast_stack.back()->children.push_back(new AstNode(AST_TYPEDEF, astbuf1));
+ ast_stack.back()->children.back()->str = *$4;
+ };
+
cell_stmt:
attr TOK_ID {
astbuf1 = new AstNode(AST_CELL);
@@ -1823,7 +1881,7 @@ simple_behavioral_stmt:
// this production creates the obligatory if-else shift/reduce conflict
behavioral_stmt:
- defattr | assert | wire_decl | param_decl | localparam_decl |
+ defattr | assert | wire_decl | param_decl | localparam_decl | typedef_decl |
non_opt_delay behavioral_stmt |
simple_behavioral_stmt ';' | ';' |
hierarchical_id attr {
diff --git a/techlibs/ecp5/cells_bb.v b/techlibs/ecp5/cells_bb.v
index 0a5046db2..ae124e7a3 100644
--- a/techlibs/ecp5/cells_bb.v
+++ b/techlibs/ecp5/cells_bb.v
@@ -334,6 +334,13 @@ module ECLKSYNCB(
endmodule
(* blackbox *)
+module ECLKBRIDGECS(
+ input CLK0, CLK1, SEL,
+ output ECSOUT
+);
+endmodule
+
+(* blackbox *)
module DCCA(
input CLKI, CE,
output CLKO
diff --git a/techlibs/ecp5/cells_ff.vh b/techlibs/ecp5/cells_ff.vh
index 0c9689ebd..501c1b3b2 100644
--- a/techlibs/ecp5/cells_ff.vh
+++ b/techlibs/ecp5/cells_ff.vh
@@ -23,15 +23,15 @@ module FD1S3JX(input PD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLI
// module FL1S3AY(); endmodule
// Diamond I/O registers
-module IFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
-module IFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
-module IFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
-module IFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
+module IFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
+module IFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
+module IFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
+module IFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="input" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
-module OFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
-module OFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
-module OFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
-module OFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
+module OFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
+module OFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
+module OFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
+module OFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; (* syn_useioff, ioff_dir="output" *) TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
// TODO: Diamond I/O latches
// module IFS1S1B(input PD, D, SCLK, output Q); endmodule
diff --git a/techlibs/ecp5/synth_ecp5.cc b/techlibs/ecp5/synth_ecp5.cc
index 80aa1dbc5..a79dee31f 100644
--- a/techlibs/ecp5/synth_ecp5.cc
+++ b/techlibs/ecp5/synth_ecp5.cc
@@ -297,6 +297,7 @@ struct SynthEcp5Pass : public ScriptPass
run("simplemap");
run("ecp5_ffinit");
run("ecp5_gsr");
+ run("attrmvcp -copy -attr syn_useioff");
run("opt_clean");
}
diff --git a/techlibs/xilinx/cells_sim.v b/techlibs/xilinx/cells_sim.v
index 28cd208cd..03985b1be 100644
--- a/techlibs/xilinx/cells_sim.v
+++ b/techlibs/xilinx/cells_sim.v
@@ -38,6 +38,17 @@ module IBUF(
assign O = I;
endmodule
+module IBUFG(
+ output O,
+ (* iopad_external_pin *)
+ input I);
+ parameter CAPACITANCE = "DONT_CARE";
+ parameter IBUF_DELAY_VALUE = "0";
+ parameter IBUF_LOW_PWR = "TRUE";
+ parameter IOSTANDARD = "DEFAULT";
+ assign O = I;
+endmodule
+
module OBUF(
(* iopad_external_pin *)
output O,
diff --git a/techlibs/xilinx/cells_xtra.py b/techlibs/xilinx/cells_xtra.py
index ee20ae992..9a4747ff3 100644
--- a/techlibs/xilinx/cells_xtra.py
+++ b/techlibs/xilinx/cells_xtra.py
@@ -53,7 +53,7 @@ XC6S_CELLS = [
# Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
- Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
+ # Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUFGDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFGDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IOBUF', port_attrs={'IO': ['iopad_external_pin']}),
@@ -174,7 +174,7 @@ XC6V_CELLS = [
Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_GTHE1', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
- Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
+ # Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUFGDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFGDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IDELAYCTRL', keep=True, port_attrs={'REFCLK': ['clkbuf_sink']}),
@@ -307,7 +307,7 @@ XC7_CELLS = [
Cell('IBUFDS_GTE2', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
- Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
+ # Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUFGDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFGDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IDELAYCTRL', keep=True, port_attrs={'REFCLK': ['clkbuf_sink']}),
diff --git a/techlibs/xilinx/xc6s_cells_xtra.v b/techlibs/xilinx/xc6s_cells_xtra.v
index f8dcce81d..7c0462b52 100644
--- a/techlibs/xilinx/xc6s_cells_xtra.v
+++ b/techlibs/xilinx/xc6s_cells_xtra.v
@@ -1282,16 +1282,6 @@ module IBUFDS_DIFF_OUT (...);
input IB;
endmodule
-module IBUFG (...);
- parameter CAPACITANCE = "DONT_CARE";
- parameter IBUF_DELAY_VALUE = "0";
- parameter IBUF_LOW_PWR = "TRUE";
- parameter IOSTANDARD = "DEFAULT";
- output O;
- (* iopad_external_pin *)
- input I;
-endmodule
-
module IBUFGDS (...);
parameter CAPACITANCE = "DONT_CARE";
parameter DIFF_TERM = "FALSE";
diff --git a/techlibs/xilinx/xc6v_cells_xtra.v b/techlibs/xilinx/xc6v_cells_xtra.v
index d9e06eae2..87656fa49 100644
--- a/techlibs/xilinx/xc6v_cells_xtra.v
+++ b/techlibs/xilinx/xc6v_cells_xtra.v
@@ -1821,16 +1821,6 @@ module IBUFDS_GTHE1 (...);
input IB;
endmodule
-module IBUFG (...);
- parameter CAPACITANCE = "DONT_CARE";
- parameter IBUF_DELAY_VALUE = "0";
- parameter IBUF_LOW_PWR = "TRUE";
- parameter IOSTANDARD = "DEFAULT";
- output O;
- (* iopad_external_pin *)
- input I;
-endmodule
-
module IBUFGDS (...);
parameter CAPACITANCE = "DONT_CARE";
parameter DIFF_TERM = "FALSE";
diff --git a/techlibs/xilinx/xc7_cells_xtra.v b/techlibs/xilinx/xc7_cells_xtra.v
index f36e4baa2..10eea4a5f 100644
--- a/techlibs/xilinx/xc7_cells_xtra.v
+++ b/techlibs/xilinx/xc7_cells_xtra.v
@@ -3932,16 +3932,6 @@ module IBUFDS_INTERMDISABLE (...);
input INTERMDISABLE;
endmodule
-module IBUFG (...);
- parameter CAPACITANCE = "DONT_CARE";
- parameter IBUF_DELAY_VALUE = "0";
- parameter IBUF_LOW_PWR = "TRUE";
- parameter IOSTANDARD = "DEFAULT";
- output O;
- (* iopad_external_pin *)
- input I;
-endmodule
-
module IBUFGDS (...);
parameter CAPACITANCE = "DONT_CARE";
parameter DIFF_TERM = "FALSE";
diff --git a/tests/svtypes/.gitignore b/tests/svtypes/.gitignore
new file mode 100644
index 000000000..b48f808a1
--- /dev/null
+++ b/tests/svtypes/.gitignore
@@ -0,0 +1,3 @@
+/*.log
+/*.out
+/run-test.mk
diff --git a/tests/svtypes/run-test.sh b/tests/svtypes/run-test.sh
new file mode 100755
index 000000000..09a30eed1
--- /dev/null
+++ b/tests/svtypes/run-test.sh
@@ -0,0 +1,20 @@
+#!/usr/bin/env bash
+set -e
+{
+echo "all::"
+for x in *.ys; do
+ echo "all:: run-$x"
+ echo "run-$x:"
+ echo " @echo 'Running $x..'"
+ echo " @../../yosys -ql ${x%.ys}.log $x"
+done
+for x in *.sv; do
+ if [ ! -f "${x%.sv}.ys" ]; then
+ echo "all:: check-$x"
+ echo "check-$x:"
+ echo " @echo 'Checking $x..'"
+ echo " @../../yosys -ql ${x%.sv}.log -p \"prep -top top; sat -verify -prove-asserts\" $x"
+ fi
+done
+} > run-test.mk
+exec ${MAKE:-make} -f run-test.mk
diff --git a/tests/svtypes/typedef_memory.sv b/tests/svtypes/typedef_memory.sv
new file mode 100644
index 000000000..577e484ad
--- /dev/null
+++ b/tests/svtypes/typedef_memory.sv
@@ -0,0 +1,10 @@
+module top(input [3:0] addr, wdata, input clk, wen, output reg [3:0] rdata);
+ typedef logic [3:0] ram16x4_t[0:15];
+
+ (ram16x4_t) mem;
+
+ always @(posedge clk) begin
+ if (wen) mem[addr] <= wdata;
+ rdata <= mem[addr];
+ end
+endmodule
diff --git a/tests/svtypes/typedef_memory.ys b/tests/svtypes/typedef_memory.ys
new file mode 100644
index 000000000..93cf47bbe
--- /dev/null
+++ b/tests/svtypes/typedef_memory.ys
@@ -0,0 +1,3 @@
+read_verilog -sv typedef_memory.sv
+prep -top top
+select -assert-count 1 t:$mem r:SIZE=16 %i r:WIDTH=4 %i
diff --git a/tests/svtypes/typedef_memory_2.sv b/tests/svtypes/typedef_memory_2.sv
new file mode 100644
index 000000000..f3089bf55
--- /dev/null
+++ b/tests/svtypes/typedef_memory_2.sv
@@ -0,0 +1,10 @@
+module top(input [3:0] addr, wdata, input clk, wen, output reg [3:0] rdata);
+ typedef logic [3:0] nibble;
+
+ (nibble) mem[0:15];
+
+ always @(posedge clk) begin
+ if (wen) mem[addr] <= wdata;
+ rdata <= mem[addr];
+ end
+endmodule
diff --git a/tests/svtypes/typedef_memory_2.ys b/tests/svtypes/typedef_memory_2.ys
new file mode 100644
index 000000000..854e554f3
--- /dev/null
+++ b/tests/svtypes/typedef_memory_2.ys
@@ -0,0 +1,4 @@
+read_verilog -sv typedef_memory_2.sv
+prep -top top
+dump
+select -assert-count 1 t:$mem r:SIZE=16 %i r:WIDTH=4 %i
diff --git a/tests/svtypes/typedef_package.sv b/tests/svtypes/typedef_package.sv
new file mode 100644
index 000000000..a1e16d4b1
--- /dev/null
+++ b/tests/svtypes/typedef_package.sv
@@ -0,0 +1,11 @@
+package pkg;
+ typedef logic [7:0] uint8_t;
+endpackage
+
+module top;
+
+ (* keep *) (pkg::uint8_t) a = 8'hAA;
+
+ always @* assert(a == 8'hAA);
+
+endmodule
diff --git a/tests/svtypes/typedef_param.sv b/tests/svtypes/typedef_param.sv
new file mode 100644
index 000000000..ddbd471e0
--- /dev/null
+++ b/tests/svtypes/typedef_param.sv
@@ -0,0 +1,22 @@
+`define STRINGIFY(x) `"x`"
+`define STATIC_ASSERT(x) if(!(x)) $error({"assert failed: ", `STRINGIFY(x)})
+
+module top;
+
+ typedef logic [1:0] uint2_t;
+ typedef logic signed [3:0] int4_t;
+ typedef logic signed [7:0] int8_t;
+ typedef (int8_t) char_t;
+
+ parameter (uint2_t) int2 = 2'b10;
+ localparam (int4_t) int4 = -1;
+ localparam (int8_t) int8 = int4;
+ localparam (char_t) ch = int8;
+
+
+ `STATIC_ASSERT(int2 == 2'b10);
+ `STATIC_ASSERT(int4 == 4'b1111);
+ `STATIC_ASSERT(int8 == 8'b11111111);
+ `STATIC_ASSERT(ch == 8'b11111111);
+
+endmodule
diff --git a/tests/svtypes/typedef_scopes.sv b/tests/svtypes/typedef_scopes.sv
new file mode 100644
index 000000000..faa385bd6
--- /dev/null
+++ b/tests/svtypes/typedef_scopes.sv
@@ -0,0 +1,23 @@
+
+typedef logic [3:0] outer_uint4_t;
+
+module top;
+
+ (outer_uint4_t) u4_i = 8'hA5;
+ always @(*) assert(u4_i == 4'h5);
+
+ typedef logic [3:0] inner_type;
+ (inner_type) inner_i1 = 8'h5A;
+ always @(*) assert(inner_i1 == 4'hA);
+
+ if (1) begin: genblock
+ typedef logic [7:0] inner_type;
+ (inner_type) inner_gb_i = 8'hA5;
+ always @(*) assert(inner_gb_i == 8'hA5);
+ end
+
+ (inner_type) inner_i2 = 8'h42;
+ always @(*) assert(inner_i2 == 4'h2);
+
+
+endmodule
diff --git a/tests/svtypes/typedef_simple.sv b/tests/svtypes/typedef_simple.sv
new file mode 100644
index 000000000..7e760dee4
--- /dev/null
+++ b/tests/svtypes/typedef_simple.sv
@@ -0,0 +1,19 @@
+module top;
+
+ typedef logic [1:0] uint2_t;
+ typedef logic signed [3:0] int4_t;
+ typedef logic signed [7:0] int8_t;
+ typedef (int8_t) char_t;
+
+ (* keep *) (uint2_t) int2 = 2'b10;
+ (* keep *) (int4_t) int4 = -1;
+ (* keep *) (int8_t) int8 = int4;
+ (* keep *) (char_t) ch = int8;
+
+
+ always @* assert(int2 == 2'b10);
+ always @* assert(int4 == 4'b1111);
+ always @* assert(int8 == 8'b11111111);
+ always @* assert(ch == 8'b11111111);
+
+endmodule