@@ -1470,6 +1470,7 @@ Function: verilog_synthesist::instantiate_port
1470
1470
\*******************************************************************/
1471
1471
1472
1472
void verilog_synthesist::instantiate_port (
1473
+ bool is_output,
1473
1474
const symbol_exprt &port,
1474
1475
const exprt &value,
1475
1476
const replace_mapt &replace_map,
@@ -1486,10 +1487,24 @@ void verilog_synthesist::instantiate_port(
1486
1487
<< " failed to find port symbol " << port_identifier << " in replace_map" ;
1487
1488
}
1488
1489
1489
- // Much like always @(*) port = value.
1490
+ // Much like
1491
+ // always @(*) port = value for an input, and
1492
+ // always @(*) value = port for an output.
1490
1493
// Note that the types need not match.
1491
- verilog_forcet assignment (
1492
- it->second , typecast_exprt::conditional_cast (value, it->second .type ()));
1494
+ exprt lhs, rhs;
1495
+
1496
+ if (is_output)
1497
+ {
1498
+ lhs = value;
1499
+ rhs = typecast_exprt::conditional_cast (it->second , value.type ());
1500
+ }
1501
+ else
1502
+ {
1503
+ lhs = it->second ;
1504
+ rhs = typecast_exprt::conditional_cast (value, it->second .type ());
1505
+ }
1506
+
1507
+ verilog_forcet assignment{lhs, rhs};
1493
1508
1494
1509
assignment.add_source_location () = source_location;
1495
1510
@@ -1520,15 +1535,21 @@ void verilog_synthesist::instantiate_ports(
1520
1535
const replace_mapt &replace_map,
1521
1536
transt &trans)
1522
1537
{
1523
- const irept::subt &ports=symbol.type .find (ID_ports).get_sub ();
1524
-
1525
1538
if (inst.operands ().size ()==0 )
1526
1539
return ;
1527
1540
1528
1541
// named port connection?
1529
1542
1530
1543
if (to_multi_ary_expr (inst).op0 ().id () == ID_named_port_connection)
1531
1544
{
1545
+ const irept::subt &ports = symbol.type .find (ID_ports).get_sub ();
1546
+
1547
+ std::set<irep_idt> output_identifiers;
1548
+ for (auto &port : ports)
1549
+ if (port.get_bool (ID_output))
1550
+ output_identifiers.insert (
1551
+ to_symbol_expr ((const exprt &)(port)).get_identifier ());
1552
+
1532
1553
// no requirement that all ports are connected
1533
1554
for (const auto &o_it : inst.operands ())
1534
1555
{
@@ -1538,13 +1559,19 @@ void verilog_synthesist::instantiate_ports(
1538
1559
const exprt &op1 = to_binary_expr (o_it).op1 ();
1539
1560
1540
1561
if (op1.is_not_nil ())
1562
+ {
1563
+ bool is_output = output_identifiers.find (op0.get_identifier ()) !=
1564
+ output_identifiers.end ();
1541
1565
instantiate_port (
1542
- op0, op1, replace_map, inst.source_location (), trans);
1566
+ is_output, op0, op1, replace_map, inst.source_location (), trans);
1567
+ }
1543
1568
}
1544
1569
}
1545
1570
}
1546
1571
else // just a list without names
1547
1572
{
1573
+ const irept::subt &ports = symbol.type .find (ID_ports).get_sub ();
1574
+
1548
1575
if (inst.operands ().size ()!=ports.size ())
1549
1576
{
1550
1577
throw errort ().with_location (inst.source_location ())
@@ -1561,7 +1588,10 @@ void verilog_synthesist::instantiate_ports(
1561
1588
1562
1589
auto &port = to_symbol_expr ((const exprt &)(*p_it));
1563
1590
1564
- instantiate_port (port, o_it, replace_map, inst.source_location (), trans);
1591
+ bool is_output = port.get_bool (ID_output);
1592
+
1593
+ instantiate_port (
1594
+ is_output, port, o_it, replace_map, inst.source_location (), trans);
1565
1595
p_it++;
1566
1596
}
1567
1597
}
0 commit comments