@@ -1585,6 +1585,7 @@ Function: verilog_synthesist::instantiate_port
1585
1585
\*******************************************************************/
1586
1586
1587
1587
void verilog_synthesist::instantiate_port (
1588
+ bool is_output,
1588
1589
const symbol_exprt &port,
1589
1590
const exprt &value,
1590
1591
const replace_mapt &replace_map,
@@ -1601,10 +1602,24 @@ void verilog_synthesist::instantiate_port(
1601
1602
<< " failed to find port symbol " << port_identifier << " in replace_map" ;
1602
1603
}
1603
1604
1604
- // Much like always @(*) port = value.
1605
+ // Much like
1606
+ // always @(*) port = value for an input, and
1607
+ // always @(*) value = port for an output.
1605
1608
// 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};
1608
1623
1609
1624
assignment.add_source_location () = source_location;
1610
1625
@@ -1635,15 +1650,21 @@ void verilog_synthesist::instantiate_ports(
1635
1650
const replace_mapt &replace_map,
1636
1651
transt &trans)
1637
1652
{
1638
- const irept::subt &ports=symbol.type .find (ID_ports).get_sub ();
1639
-
1640
1653
if (inst.operands ().size ()==0 )
1641
1654
return ;
1642
1655
1643
1656
// named port connection?
1644
1657
1645
1658
if (to_multi_ary_expr (inst).op0 ().id () == ID_named_port_connection)
1646
1659
{
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
+
1647
1668
// no requirement that all ports are connected
1648
1669
for (const auto &o_it : inst.operands ())
1649
1670
{
@@ -1653,13 +1674,19 @@ void verilog_synthesist::instantiate_ports(
1653
1674
const exprt &op1 = to_binary_expr (o_it).op1 ();
1654
1675
1655
1676
if (op1.is_not_nil ())
1677
+ {
1678
+ bool is_output = output_identifiers.find (op0.get_identifier ()) !=
1679
+ output_identifiers.end ();
1656
1680
instantiate_port (
1657
- op0, op1, replace_map, inst.source_location (), trans);
1681
+ is_output, op0, op1, replace_map, inst.source_location (), trans);
1682
+ }
1658
1683
}
1659
1684
}
1660
1685
}
1661
1686
else // just a list without names
1662
1687
{
1688
+ const irept::subt &ports = symbol.type .find (ID_ports).get_sub ();
1689
+
1663
1690
if (inst.operands ().size ()!=ports.size ())
1664
1691
{
1665
1692
throw errort ().with_location (inst.source_location ())
@@ -1676,7 +1703,10 @@ void verilog_synthesist::instantiate_ports(
1676
1703
1677
1704
auto &port = to_symbol_expr ((const exprt &)(*p_it));
1678
1705
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);
1680
1710
p_it++;
1681
1711
}
1682
1712
}
0 commit comments