From fefe0fc0430f4f173a25e674708aa0f4f0854b31 Mon Sep 17 00:00:00 2001 From: Ruben Undheim Date: Thu, 3 Nov 2016 23:18:00 +0100 Subject: Imported yosys 0.7 --- frontends/ast/ast.cc | 9 +++- frontends/ast/genrtlil.cc | 20 ++++++--- frontends/ast/simplify.cc | 10 ++++- frontends/blif/blifparse.cc | 20 ++++++--- frontends/ilang/ilang_lexer.l | 1 + frontends/ilang/ilang_parser.y | 16 ++++++- frontends/liberty/liberty.cc | 85 +++++++++++++++++++++----------------- frontends/verilog/verilog_parser.y | 2 +- 8 files changed, 106 insertions(+), 57 deletions(-) (limited to 'frontends') 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 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 &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 &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 &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 &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 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> &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(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> 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(bit_width, std::min(bit_from, bit_to), upto); - next_type:; - } + std::map> 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> 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 { -- cgit v1.2.3