@@ -1585,6 +1585,7 @@ Function: verilog_synthesist::instantiate_port
15851585\*******************************************************************/
15861586
15871587void verilog_synthesist::instantiate_port (
1588+ bool is_output,
15881589 const symbol_exprt &port,
15891590 const exprt &value,
15901591 const replace_mapt &replace_map,
@@ -1601,10 +1602,24 @@ void verilog_synthesist::instantiate_port(
16011602 << " failed to find port symbol " << port_identifier << " in replace_map" ;
16021603 }
16031604
1604- // Much like always @(*) port = value.
1605+ // Much like
1606+ // always @(*) port = value for an input, and
1607+ // always @(*) value = port for an output.
16051608 // Note that the types need not match.
1606- verilog_forcet assignment (
1607- it->second , typecast_exprt::conditional_cast (value, it->second .type ()));
1609+ exprt lhs, rhs;
1610+
1611+ if (is_output)
1612+ {
1613+ lhs = value;
1614+ rhs = typecast_exprt::conditional_cast (it->second , value.type ());
1615+ }
1616+ else
1617+ {
1618+ lhs = it->second ;
1619+ rhs = typecast_exprt::conditional_cast (value, it->second .type ());
1620+ }
1621+
1622+ verilog_forcet assignment{lhs, rhs};
16081623
16091624 assignment.add_source_location () = source_location;
16101625
@@ -1635,15 +1650,21 @@ void verilog_synthesist::instantiate_ports(
16351650 const replace_mapt &replace_map,
16361651 transt &trans)
16371652{
1638- const irept::subt &ports=symbol.type .find (ID_ports).get_sub ();
1639-
16401653 if (inst.operands ().size ()==0 )
16411654 return ;
16421655
16431656 // named port connection?
16441657
16451658 if (to_multi_ary_expr (inst).op0 ().id () == ID_named_port_connection)
16461659 {
1660+ const irept::subt &ports = symbol.type .find (ID_ports).get_sub ();
1661+
1662+ std::set<irep_idt> output_identifiers;
1663+ for (auto &port : ports)
1664+ if (port.get_bool (ID_output))
1665+ output_identifiers.insert (
1666+ to_symbol_expr ((const exprt &)(port)).get_identifier ());
1667+
16471668 // no requirement that all ports are connected
16481669 for (const auto &o_it : inst.operands ())
16491670 {
@@ -1653,13 +1674,19 @@ void verilog_synthesist::instantiate_ports(
16531674 const exprt &op1 = to_binary_expr (o_it).op1 ();
16541675
16551676 if (op1.is_not_nil ())
1677+ {
1678+ bool is_output = output_identifiers.find (op0.get_identifier ()) !=
1679+ output_identifiers.end ();
16561680 instantiate_port (
1657- op0, op1, replace_map, inst.source_location (), trans);
1681+ is_output, op0, op1, replace_map, inst.source_location (), trans);
1682+ }
16581683 }
16591684 }
16601685 }
16611686 else // just a list without names
16621687 {
1688+ const irept::subt &ports = symbol.type .find (ID_ports).get_sub ();
1689+
16631690 if (inst.operands ().size ()!=ports.size ())
16641691 {
16651692 throw errort ().with_location (inst.source_location ())
@@ -1676,7 +1703,10 @@ void verilog_synthesist::instantiate_ports(
16761703
16771704 auto &port = to_symbol_expr ((const exprt &)(*p_it));
16781705
1679- instantiate_port (port, o_it, replace_map, inst.source_location (), trans);
1706+ bool is_output = port.get_bool (ID_output);
1707+
1708+ instantiate_port (
1709+ is_output, port, o_it, replace_map, inst.source_location (), trans);
16801710 p_it++;
16811711 }
16821712 }
0 commit comments