Skip to content

Commit 0fc2ab6

Browse files
authored
Merge pull request #640 from diffblue/verilog-instantiate-outputs
Verilog: fix assignment for module output ports
2 parents e3bc203 + c9e0ee9 commit 0fc2ab6

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

src/verilog/verilog_synthesis.cpp

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1585,6 +1585,7 @@ Function: verilog_synthesist::instantiate_port
15851585
\*******************************************************************/
15861586

15871587
void 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
}

src/verilog/verilog_synthesis_class.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ class verilog_synthesist:
322322
void replace_symbols(const irep_idt &target, exprt &dest);
323323

324324
void instantiate_port(
325+
bool is_output,
325326
const symbol_exprt &port,
326327
const exprt &value,
327328
const replace_mapt &,

0 commit comments

Comments
 (0)