summaryrefslogtreecommitdiff
path: root/frontends
diff options
context:
space:
mode:
Diffstat (limited to 'frontends')
-rw-r--r--frontends/ast/ast.cc9
-rw-r--r--frontends/ast/genrtlil.cc20
-rw-r--r--frontends/ast/simplify.cc10
-rw-r--r--frontends/blif/blifparse.cc20
-rw-r--r--frontends/ilang/ilang_lexer.l1
-rw-r--r--frontends/ilang/ilang_parser.y16
-rw-r--r--frontends/liberty/liberty.cc85
-rw-r--r--frontends/verilog/verilog_parser.y2
8 files changed, 106 insertions, 57 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index fd272400..92513a24 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -934,10 +934,15 @@ static AstModule* process_module(AstNode *ast, bool defer)
if (flag_lib) {
std::vector<AstNode*> new_children;
for (auto child : ast->children) {
- if (child->type == AST_WIRE && (child->is_input || child->is_output))
+ if (child->type == AST_WIRE && (child->is_input || child->is_output)) {
new_children.push_back(child);
- else
+ } else if (child->type == AST_PARAMETER) {
+ child->delete_children();
+ child->children.push_back(AstNode::mkconst_int(0, false, 0));
+ new_children.push_back(child);
+ } else {
delete child;
+ }
}
ast->children.swap(new_children);
ast->attributes["\\blackbox"] = AstNode::mkconst_int(1, false);
diff --git a/frontends/ast/genrtlil.cc b/frontends/ast/genrtlil.cc
index 3c57162a..db8d7409 100644
--- a/frontends/ast/genrtlil.cc
+++ b/frontends/ast/genrtlil.cc
@@ -220,12 +220,19 @@ struct AST_INTERNAL::ProcessGenerator
subst_lvalue_to = new_temp_signal(subst_lvalue_from);
subst_lvalue_map = subst_lvalue_from.to_sigbit_map(subst_lvalue_to);
+ bool found_global_syncs = false;
bool found_anyedge_syncs = false;
for (auto child : always->children)
- if (child->type == AST_EDGE)
- found_anyedge_syncs = true;
+ if (child->type == AST_EDGE) {
+ if (GetSize(child->children) == 1 && child->children.at(0)->type == AST_IDENTIFIER && child->children.at(0)->str == "\\$global_clock")
+ found_global_syncs = true;
+ else
+ found_anyedge_syncs = true;
+ }
if (found_anyedge_syncs) {
+ if (found_global_syncs)
+ log_error("Found non-synthesizable event list at %s:%d!\n", always->filename.c_str(), always->linenum);
log("Note: Assuming pure combinatorial block at %s:%d in\n", always->filename.c_str(), always->linenum);
log("compliance with IEC 62142(E):2005 / IEEE Std. 1364.1(E):2002. Recommending\n");
log("use of @* instead of @(...) for better match of synthesis and simulation.\n");
@@ -236,7 +243,7 @@ struct AST_INTERNAL::ProcessGenerator
for (auto child : always->children)
if (child->type == AST_POSEDGE || child->type == AST_NEGEDGE) {
found_clocked_sync = true;
- if (found_anyedge_syncs)
+ if (found_global_syncs || found_anyedge_syncs)
log_error("Found non-synthesizable event list at %s:%d!\n", always->filename.c_str(), always->linenum);
RTLIL::SyncRule *syncrule = new RTLIL::SyncRule;
syncrule->type = child->type == AST_POSEDGE ? RTLIL::STp : RTLIL::STn;
@@ -248,7 +255,7 @@ struct AST_INTERNAL::ProcessGenerator
}
if (proc->syncs.empty()) {
RTLIL::SyncRule *syncrule = new RTLIL::SyncRule;
- syncrule->type = RTLIL::STa;
+ syncrule->type = found_global_syncs ? RTLIL::STg : RTLIL::STa;
syncrule->signal = RTLIL::SigSpec();
addChunkActions(syncrule->actions, subst_lvalue_from, subst_lvalue_to, true);
proc->syncs.push_back(syncrule);
@@ -755,7 +762,7 @@ void AstNode::detectSignWidthWorker(int &width_hint, bool &sign_hint, bool *foun
break;
case AST_FCALL:
- if (str == "\\$anyconst") {
+ if (str == "\\$anyconst" || str == "\\$anyseq") {
if (GetSize(children) == 1) {
while (children[0]->simplify(true, false, false, 1, -1, false, true) == true) { }
if (children[0]->type != AST_CONSTANT)
@@ -1264,6 +1271,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
wire->attributes["\\src"] = stringf("%s:%d", filename.c_str(), linenum);
int mem_width, mem_size, addr_bits;
+ is_signed = id2ast->is_signed;
id2ast->meminfo(mem_width, mem_size, addr_bits);
RTLIL::SigSpec addr_sig = children[0]->genRTLIL();
@@ -1458,7 +1466,7 @@ RTLIL::SigSpec AstNode::genRTLIL(int width_hint, bool sign_hint)
} break;
case AST_FCALL: {
- if (str == "\\$anyconst")
+ if (str == "\\$anyconst" || str == "\\$anyseq")
{
string myid = stringf("%s$%d", str.c_str() + 1, autoidx++);
int width = width_hint;
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index 57aa648c..9d5c75fe 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -1510,6 +1510,7 @@ skip_dynamic_range_lvalue_expansion:;
}
int mem_width, mem_size, addr_bits;
+ bool mem_signed = children[0]->id2ast->is_signed;
children[0]->id2ast->meminfo(mem_width, mem_size, addr_bits);
int data_range_left = children[0]->id2ast->children[0]->range_left;
@@ -1529,6 +1530,7 @@ skip_dynamic_range_lvalue_expansion:;
AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
wire_data->str = id_data;
+ wire_data->is_signed = mem_signed;
current_ast_mod->children.push_back(wire_data);
current_scope[wire_data->str] = wire_data;
while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
@@ -1807,8 +1809,8 @@ skip_dynamic_range_lvalue_expansion:;
goto apply_newNode;
}
- // $anyconst is mapped in AstNode::genRTLIL()
- if (str == "\\$anyconst") {
+ // $anyconst and $anyseq are mapped in AstNode::genRTLIL()
+ if (str == "\\$anyconst" || str == "\\$anyseq") {
recursion_counter--;
return false;
}
@@ -2894,6 +2896,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
int mem_width, mem_size, addr_bits;
+ bool mem_signed = children[0]->id2ast->is_signed;
children[0]->id2ast->meminfo(mem_width, mem_size, addr_bits);
AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
@@ -2906,6 +2909,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
wire_data->str = id_data;
wire_data->is_reg = true;
+ wire_data->is_signed = mem_signed;
wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
mod->children.push_back(wire_data);
while (wire_data->simplify(true, false, false, 1, -1, false, false)) { }
@@ -2967,6 +2971,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
std::string id_addr = sstr.str() + "_ADDR", id_data = sstr.str() + "_DATA";
int mem_width, mem_size, addr_bits;
+ bool mem_signed = id2ast->is_signed;
id2ast->meminfo(mem_width, mem_size, addr_bits);
AstNode *wire_addr = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(addr_bits-1, true), mkconst_int(0, true)));
@@ -2980,6 +2985,7 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod,
AstNode *wire_data = new AstNode(AST_WIRE, new AstNode(AST_RANGE, mkconst_int(mem_width-1, true), mkconst_int(0, true)));
wire_data->str = id_data;
wire_data->is_reg = true;
+ wire_data->is_signed = mem_signed;
if (block)
wire_data->attributes["\\nosync"] = AstNode::mkconst_int(1, false);
mod->children.push_back(wire_data);
diff --git a/frontends/blif/blifparse.cc b/frontends/blif/blifparse.cc
index 3717a1e5..6d4d6087 100644
--- a/frontends/blif/blifparse.cc
+++ b/frontends/blif/blifparse.cc
@@ -23,6 +23,7 @@ YOSYS_NAMESPACE_BEGIN
static bool read_next_line(char *&buffer, size_t &buffer_size, int &line_count, std::istream &f)
{
+ string strbuf;
int buffer_len = 0;
buffer[0] = 0;
@@ -42,8 +43,13 @@ static bool read_next_line(char *&buffer, size_t &buffer_size, int &line_count,
if (buffer_len > 0 && buffer[buffer_len-1] == '\\')
buffer[--buffer_len] = 0;
line_count++;
- if (!f.getline(buffer+buffer_len, buffer_size-buffer_len))
+ if (!std::getline(f, strbuf))
return false;
+ while (buffer_size-buffer_len < strbuf.size()+1) {
+ buffer_size *= 2;
+ buffer = (char*)realloc(buffer, buffer_size);
+ }
+ strcpy(buffer+buffer_len, strbuf.c_str());
} else
return true;
}
@@ -256,9 +262,13 @@ void parse_blif(RTLIL::Design *design, std::istream &f, std::string dff_name, bo
cell = module->addDlatch(NEW_ID, blif_wire(clock), blif_wire(d), blif_wire(q), false);
else {
no_latch_clock:
- cell = module->addCell(NEW_ID, dff_name);
- cell->setPort("\\D", blif_wire(d));
- cell->setPort("\\Q", blif_wire(q));
+ if (dff_name.empty()) {
+ cell = module->addFf(NEW_ID, blif_wire(d), blif_wire(q));
+ } else {
+ cell = module->addCell(NEW_ID, dff_name);
+ cell->setPort("\\D", blif_wire(d));
+ cell->setPort("\\Q", blif_wire(q));
+ }
}
obj_attributes = &cell->attributes;
@@ -477,7 +487,7 @@ struct BlifFrontend : public Frontend {
}
extra_args(f, filename, args, argidx);
- parse_blif(design, *f, "\\DFF", true, sop_mode);
+ parse_blif(design, *f, "", true, sop_mode);
}
} BlifFrontend;
diff --git a/frontends/ilang/ilang_lexer.l b/frontends/ilang/ilang_lexer.l
index 415de74e..84238854 100644
--- a/frontends/ilang/ilang_lexer.l
+++ b/frontends/ilang/ilang_lexer.l
@@ -74,6 +74,7 @@ USING_YOSYS_NAMESPACE
"negedge" { return TOK_NEGEDGE; }
"edge" { return TOK_EDGE; }
"always" { return TOK_ALWAYS; }
+"global" { return TOK_GLOBAL; }
"init" { return TOK_INIT; }
"update" { return TOK_UPDATE; }
"process" { return TOK_PROCESS; }
diff --git a/frontends/ilang/ilang_parser.y b/frontends/ilang/ilang_parser.y
index cc31c864..bfc062fe 100644
--- a/frontends/ilang/ilang_parser.y
+++ b/frontends/ilang/ilang_parser.y
@@ -57,7 +57,7 @@ USING_YOSYS_NAMESPACE
%token <integer> TOK_INT
%token TOK_AUTOIDX TOK_MODULE TOK_WIRE TOK_WIDTH TOK_INPUT TOK_OUTPUT TOK_INOUT
%token TOK_CELL TOK_CONNECT TOK_SWITCH TOK_CASE TOK_ASSIGN TOK_SYNC
-%token TOK_LOW TOK_HIGH TOK_POSEDGE TOK_NEGEDGE TOK_EDGE TOK_ALWAYS TOK_INIT
+%token TOK_LOW TOK_HIGH TOK_POSEDGE TOK_NEGEDGE TOK_EDGE TOK_ALWAYS TOK_GLOBAL TOK_INIT
%token TOK_UPDATE TOK_PROCESS TOK_END TOK_INVALID TOK_EOL TOK_OFFSET
%token TOK_PARAMETER TOK_ATTRIBUTE TOK_MEMORY TOK_SIZE TOK_SIGNED TOK_UPTO
@@ -112,7 +112,13 @@ module_body:
/* empty */;
module_stmt:
- attr_stmt | wire_stmt | memory_stmt | cell_stmt | proc_stmt | conn_stmt;
+ param_stmt | attr_stmt | wire_stmt | memory_stmt | cell_stmt | proc_stmt | conn_stmt;
+
+param_stmt:
+ TOK_PARAMETER TOK_ID EOL {
+ current_module->avail_parameters.insert($2);
+ free($2);
+ };
attr_stmt:
TOK_ATTRIBUTE TOK_ID constant EOL {
@@ -301,6 +307,12 @@ sync_list:
rule->signal = RTLIL::SigSpec();
current_process->syncs.push_back(rule);
} update_list |
+ sync_list TOK_SYNC TOK_GLOBAL EOL {
+ RTLIL::SyncRule *rule = new RTLIL::SyncRule;
+ rule->type = RTLIL::SyncType::STg;
+ rule->signal = RTLIL::SigSpec();
+ current_process->syncs.push_back(rule);
+ } update_list |
sync_list TOK_SYNC TOK_INIT EOL {
RTLIL::SyncRule *rule = new RTLIL::SyncRule;
rule->type = RTLIL::SyncType::STi;
diff --git a/frontends/liberty/liberty.cc b/frontends/liberty/liberty.cc
index 73d927fa..4666c818 100644
--- a/frontends/liberty/liberty.cc
+++ b/frontends/liberty/liberty.cc
@@ -401,6 +401,47 @@ static void create_latch(RTLIL::Module *module, LibertyAst *node)
cell->setPort("\\E", enable_sig);
}
+void parse_type_map(std::map<std::string, std::tuple<int, int, bool>> &type_map, LibertyAst *ast)
+{
+ for (auto type_node : ast->children)
+ {
+ if (type_node->id != "type" || type_node->args.size() != 1)
+ continue;
+
+ std::string type_name = type_node->args.at(0);
+ int bit_width = -1, bit_from = -1, bit_to = -1;
+ bool upto = false;
+
+ for (auto child : type_node->children)
+ {
+ if (child->id == "base_type" && child->value != "array")
+ goto next_type;
+
+ if (child->id == "data_type" && child->value != "bit")
+ goto next_type;
+
+ if (child->id == "bit_width")
+ bit_width = atoi(child->value.c_str());
+
+ if (child->id == "bit_from")
+ bit_from = atoi(child->value.c_str());
+
+ if (child->id == "bit_to")
+ bit_to = atoi(child->value.c_str());
+
+ if (child->id == "downto" && (child->value == "0" || child->value == "false" || child->value == "FALSE"))
+ upto = true;
+ }
+
+ if (bit_width != (std::max(bit_from, bit_to) - std::min(bit_from, bit_to) + 1))
+ log_error("Incompatible array type '%s': bit_width=%d, bit_from=%d, bit_to=%d.\n",
+ type_name.c_str(), bit_width, bit_from, bit_to);
+
+ type_map[type_name] = std::tuple<int, int, bool>(bit_width, std::min(bit_from, bit_to), upto);
+ next_type:;
+ }
+}
+
struct LibertyFrontend : public Frontend {
LibertyFrontend() : Frontend("liberty", "read cells from liberty file") { }
virtual void help()
@@ -469,45 +510,8 @@ struct LibertyFrontend : public Frontend {
LibertyParser parser(*f);
int cell_count = 0;
- std::map<std::string, std::tuple<int, int, bool>> type_map;
-
- for (auto type_node : parser.ast->children)
- {
- if (type_node->id != "type" || type_node->args.size() != 1)
- continue;
-
- std::string type_name = type_node->args.at(0);
- int bit_width = -1, bit_from = -1, bit_to = -1;
- bool upto = false;
-
- for (auto child : type_node->children)
- {
- if (child->id == "base_type" && child->value != "array")
- goto next_type;
-
- if (child->id == "data_type" && child->value != "bit")
- goto next_type;
-
- if (child->id == "bit_width")
- bit_width = atoi(child->value.c_str());
-
- if (child->id == "bit_from")
- bit_from = atoi(child->value.c_str());
-
- if (child->id == "bit_to")
- bit_to = atoi(child->value.c_str());
-
- if (child->id == "downto" && (child->value == "0" || child->value == "false" || child->value == "FALSE"))
- upto = true;
- }
-
- if (bit_width != (std::max(bit_from, bit_to) - std::min(bit_from, bit_to) + 1))
- log_error("Incompatible array type '%s': bit_width=%d, bit_from=%d, bit_to=%d.\n",
- type_name.c_str(), bit_width, bit_from, bit_to);
-
- type_map[type_name] = std::tuple<int, int, bool>(bit_width, std::min(bit_from, bit_to), upto);
- next_type:;
- }
+ std::map<std::string, std::tuple<int, int, bool>> global_type_map;
+ parse_type_map(global_type_map, parser.ast);
for (auto cell : parser.ast->children)
{
@@ -524,6 +528,9 @@ struct LibertyFrontend : public Frontend {
// log("Processing cell type %s.\n", RTLIL::unescape_id(cell_name).c_str());
+ std::map<std::string, std::tuple<int, int, bool>> type_map = global_type_map;
+ parse_type_map(type_map, cell);
+
RTLIL::Module *module = new RTLIL::Module;
module->name = cell_name;
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index c730ce5b..5bbda535 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -1229,7 +1229,7 @@ rvalue:
$$ = new AstNode(AST_IDENTIFIER, $2);
$$->str = *$1;
delete $1;
- if ($2 == nullptr && formal_mode && ($$->str == "\\$initstate" || $$->str == "\\$anyconst"))
+ if ($2 == nullptr && formal_mode && ($$->str == "\\$initstate" || $$->str == "\\$anyconst" || $$->str == "\\$anyseq"))
$$->type = AST_FCALL;
} |
hierarchical_id non_opt_multirange {