diff options
author | Andrew Zonenberg <azonenberg@drawersteak.com> | 2017-02-11 11:25:16 -0800 |
---|---|---|
committer | Andrew Zonenberg <azonenberg@drawersteak.com> | 2017-02-11 11:25:16 -0800 |
commit | 203b521a781ccc4c8dba05d2cc73e4625bcf2a8e (patch) | |
tree | 12efc580521210c43957c010a7fe5367606cb2f2 /frontends | |
parent | 0d7e71f7abd49d1c95f0657993b55bb5f66317a1 (diff) | |
parent | cdb6ceb8c63f2c38bdba3f66be7c444def43897e (diff) | |
download | yosys-203b521a781ccc4c8dba05d2cc73e4625bcf2a8e.tar.gz yosys-203b521a781ccc4c8dba05d2cc73e4625bcf2a8e.tar.bz2 yosys-203b521a781ccc4c8dba05d2cc73e4625bcf2a8e.zip |
Merge https://github.com/cliffordwolf/yosys
Diffstat (limited to 'frontends')
-rw-r--r-- | frontends/verific/verific.cc | 145 | ||||
-rw-r--r-- | frontends/verilog/verilog_lexer.l | 20 | ||||
-rw-r--r-- | frontends/verilog/verilog_parser.y | 15 |
3 files changed, 161 insertions, 19 deletions
diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index f3b997dc5..bc0bd60fc 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -57,7 +57,7 @@ PRIVATE_NAMESPACE_BEGIN void msg_func(msg_type_t msg_type, const char *message_id, linefile_type linefile, const char *msg, va_list args) { - log("VERIFIC-%s [%s] ", + string message = stringf("VERIFIC-%s [%s] ", msg_type == VERIFIC_NONE ? "NONE" : msg_type == VERIFIC_ERROR ? "ERROR" : msg_type == VERIFIC_WARNING ? "WARNING" : @@ -65,10 +65,16 @@ void msg_func(msg_type_t msg_type, const char *message_id, linefile_type linefil msg_type == VERIFIC_INFO ? "INFO" : msg_type == VERIFIC_COMMENT ? "COMMENT" : msg_type == VERIFIC_PROGRAM_ERROR ? "PROGRAM_ERROR" : "UNKNOWN", message_id); + if (linefile) - log("%s:%d: ", LineFile::GetFileName(linefile), LineFile::GetLineNo(linefile)); - logv(msg, args); - log("\n"); + message += stringf("%s:%d: ", LineFile::GetFileName(linefile), LineFile::GetLineNo(linefile)); + + message += vstringf(msg, args); + + if (msg_type == VERIFIC_ERROR || msg_type == VERIFIC_WARNING || msg_type == VERIFIC_PROGRAM_ERROR) + log_warning("%s\n", message.c_str()); + else + log("%s\n", message.c_str()); } struct VerificImporter @@ -617,6 +623,10 @@ struct VerificImporter module->fixup_ports(); + dict<Net*, char, hash_ptr_ops> init_nets; + pool<Net*, hash_ptr_ops> anyconst_nets; + pool<Net*, hash_ptr_ops> anyseq_nets; + FOREACH_NET_OF_NETLIST(nl, mi, net) { if (net->IsRamNet()) @@ -643,9 +653,59 @@ struct VerificImporter memory->width = bits_in_word; memory->size = number_of_bits / bits_in_word; + + const char *ascii_initdata = net->GetWideInitialValue(); + if (ascii_initdata) { + while (*ascii_initdata != 0 && *ascii_initdata != '\'') + ascii_initdata++; + if (*ascii_initdata == '\'') + ascii_initdata++; + if (*ascii_initdata != 0) { + log_assert(*ascii_initdata == 'b'); + ascii_initdata++; + } + for (int word_idx = 0; word_idx < memory->size; word_idx++) { + Const initval = Const(State::Sx, memory->width); + bool initval_valid = false; + for (int bit_idx = memory->width-1; bit_idx >= 0; bit_idx--) { + if (*ascii_initdata == 0) + break; + if (*ascii_initdata == '0' || *ascii_initdata == '1') { + initval[bit_idx] = (*ascii_initdata == '0') ? State::S0 : State::S1; + initval_valid = true; + } + ascii_initdata++; + } + if (initval_valid) { + RTLIL::Cell *cell = module->addCell(NEW_ID, "$meminit"); + cell->parameters["\\WORDS"] = 1; + if (net->GetOrigTypeRange()->LeftRangeBound() < net->GetOrigTypeRange()->RightRangeBound()) + cell->setPort("\\ADDR", word_idx); + else + cell->setPort("\\ADDR", memory->size - word_idx - 1); + cell->setPort("\\DATA", initval); + cell->parameters["\\MEMID"] = RTLIL::Const(memory->name.str()); + cell->parameters["\\ABITS"] = 32; + cell->parameters["\\WIDTH"] = memory->width; + cell->parameters["\\PRIORITY"] = RTLIL::Const(autoidx-1); + } + } + } continue; } + if (net->GetInitialValue()) + init_nets[net] = net->GetInitialValue(); + + const char *rand_const_attr = net->GetAttValue(" rand_const"); + const char *rand_attr = net->GetAttValue(" rand"); + + if (rand_const_attr != nullptr && !strcmp(rand_const_attr, "1")) + anyconst_nets.insert(net); + + else if (rand_attr != nullptr && !strcmp(rand_attr, "1")) + anyseq_nets.insert(net); + if (net_map.count(net)) { // log(" skipping net %s.\n", net->Name()); continue; @@ -683,25 +743,94 @@ struct VerificImporter wire->start_offset = min(netbus->LeftIndex(), netbus->RightIndex()); import_attributes(wire->attributes, netbus); - for (int i = netbus->LeftIndex();; i += netbus->IsUp() ? +1 : -1) { - if (netbus->ElementAtIndex(i)) { + RTLIL::Const initval = Const(State::Sx, GetSize(wire)); + bool initval_valid = false; + + for (int i = netbus->LeftIndex();; i += netbus->IsUp() ? +1 : -1) + { + if (netbus->ElementAtIndex(i)) + { + int bitidx = i - wire->start_offset; net = netbus->ElementAtIndex(i); - RTLIL::SigBit bit(wire, i - wire->start_offset); + RTLIL::SigBit bit(wire, bitidx); + + if (init_nets.count(net)) { + if (init_nets.at(net) == '0') + initval.bits.at(bitidx) = State::S0; + if (init_nets.at(net) == '1') + initval.bits.at(bitidx) = State::S1; + initval_valid = true; + init_nets.erase(net); + } + if (net_map.count(net) == 0) net_map[net] = bit; else module->connect(bit, net_map.at(net)); } + if (i == netbus->RightIndex()) break; } + + if (initval_valid) + wire->attributes["\\init"] = initval; } else { // log(" skipping netbus %s.\n", netbus->Name()); } + + SigSpec anyconst_sig; + SigSpec anyseq_sig; + + for (int i = netbus->RightIndex();; i += netbus->IsUp() ? -1 : +1) { + net = netbus->ElementAtIndex(i); + if (net != nullptr && anyconst_nets.count(net)) { + anyconst_sig.append(net_map.at(net)); + anyconst_nets.erase(net); + } + if (net != nullptr && anyseq_nets.count(net)) { + anyseq_sig.append(net_map.at(net)); + anyseq_nets.erase(net); + } + if (i == netbus->LeftIndex()) + break; + } + + if (GetSize(anyconst_sig)) + module->connect(anyconst_sig, module->Anyconst(NEW_ID, GetSize(anyconst_sig))); + + if (GetSize(anyseq_sig)) + module->connect(anyseq_sig, module->Anyseq(NEW_ID, GetSize(anyseq_sig))); } + for (auto it : init_nets) + { + Const initval; + SigBit bit = net_map.at(it.first); + log_assert(bit.wire); + + if (bit.wire->attributes.count("\\init")) + initval = bit.wire->attributes.at("\\init"); + + while (GetSize(initval) < GetSize(bit.wire)) + initval.bits.push_back(State::Sx); + + if (it.second == '0') + initval.bits.at(bit.offset) = State::S0; + if (it.second == '1') + initval.bits.at(bit.offset) = State::S1; + + bit.wire->attributes["\\init"] = initval; + } + + for (auto net : anyconst_nets) + module->connect(net_map.at(net), module->Anyconst(NEW_ID)); + + for (auto net : anyseq_nets) + module->connect(net_map.at(net), module->Anyseq(NEW_ID)); + FOREACH_INSTANCE_OF_NETLIST(nl, mi, inst) { if (inst->Type() == PRIM_SVA_POSEDGE) { @@ -733,7 +862,7 @@ struct VerificImporter SigBit outsig = net_map.at(out); log_assert(outsig.wire && GetSize(outsig.wire) == 1); - outsig.wire->attributes["\\init"] == Const(0, 1); + outsig.wire->attributes["\\init"] = Const(1, 1); module->addDff(NEW_ID, net_map.at(clk), net_map.at(in2), net_map.at(out)); continue; diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 97af0ae2d..ff2fa5753 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -175,15 +175,17 @@ YOSYS_NAMESPACE_END "always_ff" { SV_KEYWORD(TOK_ALWAYS); } "always_latch" { SV_KEYWORD(TOK_ALWAYS); } -"assert" { if (formal_mode) return TOK_ASSERT; SV_KEYWORD(TOK_ASSERT); } -"assume" { if (formal_mode) return TOK_ASSUME; SV_KEYWORD(TOK_ASSUME); } -"cover" { if (formal_mode) return TOK_COVER; SV_KEYWORD(TOK_COVER); } -"restrict" { if (formal_mode) return TOK_RESTRICT; SV_KEYWORD(TOK_RESTRICT); } -"property" { if (formal_mode) return TOK_PROPERTY; SV_KEYWORD(TOK_PROPERTY); } -"rand" { if (formal_mode) return TOK_RAND; SV_KEYWORD(TOK_RAND); } -"const" { if (formal_mode) return TOK_CONST; SV_KEYWORD(TOK_CONST); } -"logic" { SV_KEYWORD(TOK_REG); } -"bit" { SV_KEYWORD(TOK_REG); } +"assert" { if (formal_mode) return TOK_ASSERT; SV_KEYWORD(TOK_ASSERT); } +"assume" { if (formal_mode) return TOK_ASSUME; SV_KEYWORD(TOK_ASSUME); } +"cover" { if (formal_mode) return TOK_COVER; SV_KEYWORD(TOK_COVER); } +"restrict" { if (formal_mode) return TOK_RESTRICT; SV_KEYWORD(TOK_RESTRICT); } +"property" { if (formal_mode) return TOK_PROPERTY; SV_KEYWORD(TOK_PROPERTY); } +"rand" { if (formal_mode) return TOK_RAND; SV_KEYWORD(TOK_RAND); } +"const" { if (formal_mode) return TOK_CONST; SV_KEYWORD(TOK_CONST); } +"checker" { if (formal_mode) return TOK_CHECKER; SV_KEYWORD(TOK_CHECKER); } +"endchecker" { if (formal_mode) return TOK_ENDCHECKER; SV_KEYWORD(TOK_ENDCHECKER); } +"logic" { SV_KEYWORD(TOK_REG); } +"bit" { SV_KEYWORD(TOK_REG); } "input" { return TOK_INPUT; } "output" { return TOK_OUTPUT; } diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 3eb03dfd8..1879ff441 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -116,7 +116,7 @@ static void free_attr(std::map<std::string, AstNode*> *al) %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_ASSUME %token TOK_RESTRICT TOK_COVER TOK_PROPERTY TOK_ENUM TOK_TYPEDEF -%token TOK_RAND TOK_CONST +%token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER %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 @@ -465,7 +465,18 @@ module_body: module_body_stmt: task_func_decl | param_decl | localparam_decl | defparam_decl | wire_decl | assign_stmt | cell_stmt | - always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property; + always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property | checker_decl; + +checker_decl: + TOK_CHECKER TOK_ID ';' { + AstNode *node = new AstNode(AST_GENBLOCK); + node->str = *$2; + ast_stack.back()->children.push_back(node); + ast_stack.push_back(node); + } module_body TOK_ENDCHECKER { + delete $2; + ast_stack.pop_back(); + }; task_func_decl: attr TOK_DPI_FUNCTION TOK_ID TOK_ID { |