diff --git a/ivtest/gold/br_gh1175a.gold b/ivtest/gold/br_gh1175a.gold new file mode 100644 index 000000000..a86e60cb1 --- /dev/null +++ b/ivtest/gold/br_gh1175a.gold @@ -0,0 +1 @@ +./ivltests/br_gh1175a.v:1: error: The UDP input port count (1) does not match the number of input table entries (6) in primitive "id_0". diff --git a/ivtest/gold/br_gh1175b.gold b/ivtest/gold/br_gh1175b.gold new file mode 100644 index 000000000..3e6034d66 --- /dev/null +++ b/ivtest/gold/br_gh1175b.gold @@ -0,0 +1 @@ +./ivltests/br_gh1175b.v:1: error: The UDP input port count (1) does not match the number of input table entries (6) in primitive "id_0". diff --git a/ivtest/gold/br_gh1175c.gold b/ivtest/gold/br_gh1175c.gold new file mode 100644 index 000000000..6396fbcf3 --- /dev/null +++ b/ivtest/gold/br_gh1175c.gold @@ -0,0 +1,4 @@ +./ivltests/br_gh1175c.v:3: syntax error +./ivltests/br_gh1175c.v:3: errors in UDP table +./ivltests/br_gh1175c.v:1: error: Invalid table for UDP primitive id_0. + diff --git a/ivtest/gold/br_gh1175d.gold b/ivtest/gold/br_gh1175d.gold new file mode 100644 index 000000000..6c42835a7 --- /dev/null +++ b/ivtest/gold/br_gh1175d.gold @@ -0,0 +1,4 @@ +./ivltests/br_gh1175d.v:3: syntax error +./ivltests/br_gh1175d.v:3: errors in UDP table +./ivltests/br_gh1175d.v:1: error: Invalid table for UDP primitive id_0. + diff --git a/ivtest/gold/br_gh1175e.gold b/ivtest/gold/br_gh1175e.gold new file mode 100644 index 000000000..349b984e1 --- /dev/null +++ b/ivtest/gold/br_gh1175e.gold @@ -0,0 +1,4 @@ +./ivltests/br_gh1175e.v:3: syntax error +./ivltests/br_gh1175e.v:3: errors in UDP table +./ivltests/br_gh1175e.v:1: error: Invalid table for UDP primitive id_0. + diff --git a/ivtest/gold/br_gh1175f.gold b/ivtest/gold/br_gh1175f.gold new file mode 100644 index 000000000..da8e61279 --- /dev/null +++ b/ivtest/gold/br_gh1175f.gold @@ -0,0 +1,2 @@ +./ivltests/br_gh1175f.v:7: error: Primitive id_0 was already declared here: ./ivltests/br_gh1175f.v:1 + diff --git a/ivtest/ivltests/br_gh1175a.v b/ivtest/ivltests/br_gh1175a.v new file mode 100644 index 000000000..7b99d4882 --- /dev/null +++ b/ivtest/ivltests/br_gh1175a.v @@ -0,0 +1,5 @@ +primitive id_0(output id_2, input id_1); + table + ? 1 ? 0 0 0 : 0; + endtable +endprimitive diff --git a/ivtest/ivltests/br_gh1175b.v b/ivtest/ivltests/br_gh1175b.v new file mode 100644 index 000000000..aabb55928 --- /dev/null +++ b/ivtest/ivltests/br_gh1175b.v @@ -0,0 +1,5 @@ +primitive id_0(output reg id_2, input id_1); + table + ? 1 ? 0 0 0 : 0 : 0; + endtable +endprimitive diff --git a/ivtest/ivltests/br_gh1175c.v b/ivtest/ivltests/br_gh1175c.v new file mode 100644 index 000000000..37b189861 --- /dev/null +++ b/ivtest/ivltests/br_gh1175c.v @@ -0,0 +1,5 @@ +primitive id_0(output id_2, input id_1); + table + 0 : 0 0; + endtable +endprimitive diff --git a/ivtest/ivltests/br_gh1175d.v b/ivtest/ivltests/br_gh1175d.v new file mode 100644 index 000000000..effb72bd6 --- /dev/null +++ b/ivtest/ivltests/br_gh1175d.v @@ -0,0 +1,5 @@ +primitive id_0(output reg id_2, input id_1); + table + 0 : 0 0 : 0; + endtable +endprimitive diff --git a/ivtest/ivltests/br_gh1175e.v b/ivtest/ivltests/br_gh1175e.v new file mode 100644 index 000000000..b5d8235d8 --- /dev/null +++ b/ivtest/ivltests/br_gh1175e.v @@ -0,0 +1,5 @@ +primitive id_0(output reg id_2, input id_1); + table + 0 : 0 : 0 0; + endtable +endprimitive diff --git a/ivtest/ivltests/br_gh1175f.v b/ivtest/ivltests/br_gh1175f.v new file mode 100644 index 000000000..e2d2bc3ac --- /dev/null +++ b/ivtest/ivltests/br_gh1175f.v @@ -0,0 +1,11 @@ +primitive id_0(output reg id_2, input id_1); + table + 0 : 0 : 0; + endtable +endprimitive + +primitive id_0(output reg id_2, input id_1); + table + 1 : 0 : 0; + endtable +endprimitive diff --git a/ivtest/regress-vlg.list b/ivtest/regress-vlg.list index dc09f946c..1454e6170 100644 --- a/ivtest/regress-vlg.list +++ b/ivtest/regress-vlg.list @@ -353,6 +353,12 @@ br_gh788 normal,-gno-io-range-error,-Wno-anachronisms ivltests gold=br_gh788.go br_gh793 normal ivltests br_gh827 normal ivltests gold=br_gh827.gold br_gh889 normal,-gspecify ivltests gold=br_gh889.gold +br_gh1175a CE ivltests gold=br_gh1175a.gold +br_gh1175b CE ivltests gold=br_gh1175b.gold +br_gh1175c CE ivltests gold=br_gh1175c.gold +br_gh1175d CE ivltests gold=br_gh1175d.gold +br_gh1175e CE ivltests gold=br_gh1175e.gold +br_gh1175f CE ivltests gold=br_gh1175f.gold br_gh1178a CE ivltests gold=br_gh1178a.gold br_gh1178b normal ivltests br_gh1178c normal ivltests diff --git a/parse.y b/parse.y index d160c3725..4cddc1ad4 100644 --- a/parse.y +++ b/parse.y @@ -6703,7 +6703,8 @@ statement_item /* This is roughly statement_item in the LRM */ current_block_stack.push(tmp); } block_item_decls_opt - { if (!$2) { + { + if (!$2) { if ($4) { pform_requires_sv(@4, "Variable declaration in unnamed block"); } else { @@ -7133,7 +7134,7 @@ udp_body } | K_table error K_endtable { lex_end_table(); - yyerror(@2, "Errors in UDP table"); + yyerror(@2, "errors in UDP table"); yyerrok; $$ = 0; } diff --git a/pform.cc b/pform.cc index 3be307d85..9322288f3 100644 --- a/pform.cc +++ b/pform.cc @@ -1798,7 +1798,7 @@ static void process_udp_table(PUdp*udp, list*table, placed in the PUdp object. The table strings are made up by the parser to be two or - three substrings separated by ';', i.e.: + three substrings separated by ':', i.e.: 0101:1:1 (synchronous device entry) 0101:0 (combinational device entry) @@ -1814,40 +1814,36 @@ static void process_udp_table(PUdp*udp, list*table, output.resize(table->size()); { unsigned idx = 0; - for (list::iterator cur = table->begin() - ; cur != table->end() ; ++ cur , idx += 1) { + for (list::iterator cur = table->begin() ; + cur != table->end() ; ++cur , idx += 1) { string tmp = *cur; /* Pull the input values from the string. */ - assert(tmp.find(':') == (udp->ports.size() - 1)); + if (tmp.find(':') != (udp->ports.size()-1)) { + cerr << loc << ": error: " + << "The UDP input port count (" << (udp->ports.size()-1) + << ") does not match the number of input table entries (" + << tmp.find(':') << ") in primitive \"" + << udp->name_ << "\"." << endl; + error_count += 1; + break; + } input[idx] = tmp.substr(0, udp->ports.size()-1); tmp = tmp.substr(udp->ports.size()-1); - assert(tmp[0] == ':'); /* If this is a synchronous device, get the current output string. */ if (synchronous_flag) { - if (tmp.size() != 4) { - cerr << loc << ": error: " - << "Invalid table format for" - << " sequential primitive." << endl; - error_count += 1; - break; - } + assert(tmp[0] == ':'); assert(tmp.size() == 4); current[idx] = tmp[1]; tmp = tmp.substr(2); - } else if (tmp.size() != 2) { - cerr << loc << ": error: " - << "Invalid table format for" - << " combinational primitive." << endl; - error_count += 1; - break; } /* Finally, extract the desired output. */ + assert(tmp[0] == ':'); assert(tmp.size() == 2); output[idx] = tmp[1]; } @@ -2101,7 +2097,11 @@ void pform_make_udp(const struct vlltype&loc, perm_string name, // Put the primitive into the primitives table if (pform_primitives[name]) { - VLerror("error: UDP primitive already exists."); + ostringstream msg; + msg << "error: Primitive " << name << " was already declared here: " + << pform_primitives[name]->get_fileline() << endl; + // Some compilers warn if there is just a single C string. + VLerror(loc, msg.str().c_str(), ""); } else { PUdp*udp = new PUdp(name, pins.size()); @@ -2115,11 +2115,18 @@ void pform_make_udp(const struct vlltype&loc, perm_string name, udp->ports[idx] = pins[idx]->basename(); ivl_assert(loc, udp); - ivl_assert(loc, table); - process_udp_table(udp, table, loc); - udp->initial = init; + if (table) { + process_udp_table(udp, table, loc); + udp->initial = init; - pform_primitives[name] = udp; + pform_primitives[name] = udp; + } else { + ostringstream msg; + msg << "error: Invalid table for UDP primitive " << name + << "." << endl; + // Some compilers warn if there is just a single C string. + VLerror(loc, msg.str().c_str(), ""); + } } delete parms;