@@ -91,7 +91,7 @@ struct Index {
91
91
int pos = index_wires (info, m);
92
92
93
93
for (auto cell : m->cells ()) {
94
- if (cell->type .in (KNOWN_OPS) || cell->type .in (ID ($scopeinfo), ID ($specify2), ID ($specify3)))
94
+ if (cell->type .in (KNOWN_OPS) || cell->type .in (ID ($scopeinfo), ID ($specify2), ID ($specify3), ID ($input_port) ))
95
95
continue ;
96
96
97
97
Module *submodule = m->design ->module (cell->type );
@@ -566,7 +566,7 @@ struct Index {
566
566
}
567
567
568
568
Lit ret;
569
- if (!bit.wire ->port_input ) {
569
+ if (!bit.wire ->port_input || bit. wire -> port_output ) {
570
570
// an output of a cell
571
571
Cell *driver = bit.wire ->driverCell ();
572
572
@@ -618,7 +618,7 @@ struct Index {
618
618
619
619
if (!cursor) {
620
620
log_assert (bit.wire ->module == top);
621
- log_assert (bit.wire ->port_input );
621
+ log_assert (bit.wire ->port_input && !bit. wire -> port_output );
622
622
return lits[top_minfo->windices [bit.wire ] + bit.offset ];
623
623
} else {
624
624
log_assert (bit.wire ->module == cursor->leaf_module (*this ));
@@ -723,7 +723,7 @@ struct AigerWriter : Index<AigerWriter, unsigned int, 0, 1> {
723
723
for (auto id : top->ports ) {
724
724
Wire *w = top->wire (id);
725
725
log_assert (w);
726
- if (w->port_input )
726
+ if (w->port_input && !w-> port_output )
727
727
for (int i = 0 ; i < w->width ; i++) {
728
728
pi_literal (SigBit (w, i)) = lit_counter;
729
729
inputs.push_back (SigBit (w, i));
@@ -828,7 +828,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
828
828
{
829
829
log_assert (cursor.is_top ()); // TOOD: fix analyzer to work with hierarchy
830
830
831
- if (bit.wire ->port_input )
831
+ if (bit.wire ->port_input && !bit. wire -> port_output )
832
832
return false ;
833
833
834
834
Cell *driver = bit.wire ->driverCell ();
@@ -838,7 +838,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
838
838
839
839
int max = 1 ;
840
840
for (auto wire : mod->wires ())
841
- if (wire->port_input )
841
+ if (wire->port_input && !wire-> port_output )
842
842
for (int i = 0 ; i < wire->width ; i++) {
843
843
int ilevel = visit (cursor, driver->getPort (wire->name )[i]);
844
844
max = std::max (max, ilevel + 1 );
@@ -858,7 +858,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
858
858
for (auto id : top->ports ) {
859
859
Wire *w = top->wire (id);
860
860
log_assert (w);
861
- if (w->port_input )
861
+ if (w->port_input && !w-> port_output )
862
862
for (int i = 0 ; i < w->width ; i++)
863
863
pi_literal (SigBit (w, i)) = 0 ;
864
864
}
@@ -868,7 +868,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
868
868
Module *def = design->module (box->type );
869
869
if (!(def && def->has_attribute (ID::abc9_box_id)))
870
870
for (auto &conn : box->connections_ )
871
- if (box->output (conn.first ))
871
+ if (box->port_dir (conn.first ) != RTLIL::PD_INPUT )
872
872
for (auto bit : conn.second )
873
873
pi_literal (bit, &cursor) = 0 ;
874
874
}
@@ -883,7 +883,7 @@ struct XAigerAnalysis : Index<XAigerAnalysis, int, 0, 0> {
883
883
Module *def = design->module (box->type );
884
884
if (!(def && def->has_attribute (ID::abc9_box_id)))
885
885
for (auto &conn : box->connections_ )
886
- if (box->input (conn.first ))
886
+ if (box->port_dir (conn.first ) == RTLIL::PD_INPUT )
887
887
for (auto bit : conn.second )
888
888
(void ) eval_po (bit);
889
889
}
@@ -903,6 +903,16 @@ struct XAigerWriter : AigerWriter {
903
903
typedef std::pair<SigBit, HierCursor> HierBit;
904
904
std::vector<HierBit> pos;
905
905
std::vector<HierBit> pis;
906
+
907
+ // * The aiger output port sequence is COs (inputs to modeled boxes),
908
+ // inputs to opaque boxes, then module outputs. COs going first is
909
+ // required by abc.
910
+ // * proper_pos_counter counts ports which follow after COs
911
+ // * The mapping file `pseudopo` and `po` statements use indexing relative
912
+ // to the first port following COs.
913
+ // * If a module output is directly driven by an opaque box, the emission
914
+ // of the po statement in the mapping file is skipped. This is done to
915
+ // aid re-integration of the mapped result.
906
916
int proper_pos_counter = 0 ;
907
917
908
918
pool<SigBit> driven_by_opaque_box;
@@ -937,15 +947,10 @@ struct XAigerWriter : AigerWriter {
937
947
lit_counter += 2 ;
938
948
}
939
949
940
- void append_box_ports (Cell *box, HierCursor &cursor, bool inputs)
950
+ void append_opaque_box_ports (Cell *box, HierCursor &cursor, bool inputs)
941
951
{
942
952
for (auto &conn : box->connections_ ) {
943
- bool is_input = box->input (conn.first );
944
- bool is_output = box->output (conn.first );
945
-
946
- if (!(is_input || is_output) || (is_input && is_output))
947
- log_error (" Ambiguous port direction on %s/%s\n " ,
948
- log_id (box->type ), log_id (conn.first ));
953
+ bool is_input = box->port_dir (conn.first ) == RTLIL::PD_INPUT;
949
954
950
955
if (is_input && inputs) {
951
956
int bitp = 0 ;
@@ -955,24 +960,25 @@ struct XAigerWriter : AigerWriter {
955
960
continue ;
956
961
}
957
962
963
+ // Inputs to opaque boxes are proper POs as far as abc is concerned
958
964
if (map_file.is_open ()) {
959
965
log_assert (cursor.is_top ());
960
- map_file << " pseudopo " << proper_pos_counter++ << " " << bitp
966
+ map_file << " pseudopo " << proper_pos_counter << " " << bitp
961
967
<< " " << box->name .c_str ()
962
968
<< " " << conn.first .c_str () << " \n " ;
963
969
}
964
-
970
+ proper_pos_counter++;
965
971
pos.push_back (std::make_pair (bit, cursor));
966
972
967
973
if (mapping_prep)
968
974
conn.second [bitp] = RTLIL::Sx;
969
975
970
976
bitp++;
971
977
}
972
- } else if (is_output && !inputs) {
978
+ } else if (!is_input && !inputs) {
973
979
for (auto &bit : conn.second ) {
974
- if (!bit.wire || bit.wire ->port_input )
975
- log_error (" Bad connection" );
980
+ if (!bit.wire || ( bit.wire ->port_input && !bit. wire -> port_output ) )
981
+ log_error (" Bad connection %s/%s ~ %s \n " , log_id (box), log_id (conn. first ), log_signal (conn. second ) );
976
982
977
983
978
984
ensure_pi (bit, cursor);
@@ -1012,7 +1018,7 @@ struct XAigerWriter : AigerWriter {
1012
1018
1013
1019
for (auto box : minfo.found_blackboxes ) {
1014
1020
log_debug (" - %s.%s (type %s): " , cursor.path ().c_str (),
1015
- RTLIL::unescape_id (box->name ). c_str () ,
1021
+ RTLIL::unescape_id (box->name ),
1016
1022
log_id (box->type ));
1017
1023
1018
1024
Module *box_module = design->module (box->type ), *box_derived;
@@ -1038,7 +1044,7 @@ struct XAigerWriter : AigerWriter {
1038
1044
});
1039
1045
1040
1046
for (auto [cursor, box, def] : opaque_boxes)
1041
- append_box_ports (box, cursor, false );
1047
+ append_opaque_box_ports (box, cursor, false );
1042
1048
1043
1049
holes_module = design->addModule (NEW_ID);
1044
1050
std::vector<RTLIL::Wire *> holes_pis;
@@ -1086,6 +1092,8 @@ struct XAigerWriter : AigerWriter {
1086
1092
bit = RTLIL::Sx;
1087
1093
}
1088
1094
1095
+ // Nonopaque box inputs come first and are not part of
1096
+ // the PO numbering used by the mapping file.
1089
1097
pos.push_back (std::make_pair (bit, cursor));
1090
1098
}
1091
1099
boxes_co_num += port->width ;
@@ -1106,7 +1114,7 @@ struct XAigerWriter : AigerWriter {
1106
1114
holes_pi_idx++;
1107
1115
}
1108
1116
holes_wb->setPort (port_id, in_conn);
1109
- } else if (port->port_output && !port-> port_input ) {
1117
+ } else if (port->port_output ) {
1110
1118
// primary
1111
1119
for (int i = 0 ; i < port->width ; i++) {
1112
1120
SigBit bit;
@@ -1138,7 +1146,7 @@ struct XAigerWriter : AigerWriter {
1138
1146
}
1139
1147
1140
1148
for (auto [cursor, box, def] : opaque_boxes)
1141
- append_box_ports (box, cursor, true );
1149
+ append_opaque_box_ports (box, cursor, true );
1142
1150
1143
1151
write_be32 (h_buffer, 1 );
1144
1152
write_be32 (h_buffer, pis.size ());
@@ -1159,7 +1167,7 @@ struct XAigerWriter : AigerWriter {
1159
1167
log_assert (port);
1160
1168
if (port->port_input && !port->port_output ) {
1161
1169
box_co_num += port->width ;
1162
- } else if (port->port_output && !port-> port_input ) {
1170
+ } else if (port->port_output ) {
1163
1171
box_ci_num += port->width ;
1164
1172
} else {
1165
1173
log_abort ();
@@ -1182,7 +1190,7 @@ struct XAigerWriter : AigerWriter {
1182
1190
reset_counters ();
1183
1191
1184
1192
for (auto w : top->wires ())
1185
- if (w->port_input )
1193
+ if (w->port_input && !w-> port_output )
1186
1194
for (int i = 0 ; i < w->width ; i++)
1187
1195
ensure_pi (SigBit (w, i));
1188
1196
@@ -1195,10 +1203,14 @@ struct XAigerWriter : AigerWriter {
1195
1203
for (auto w : top->wires ())
1196
1204
if (w->port_output )
1197
1205
for (int i = 0 ; i < w->width ; i++) {
1206
+ // When a module output is directly driven by an opaque box, we
1207
+ // don't emit it to the mapping file to aid re-integration, but we
1208
+ // do emit a proper PO.
1198
1209
if (map_file.is_open () && !driven_by_opaque_box.count (SigBit (w, i))) {
1199
- map_file << " po " << proper_pos_counter++ << " " << i
1210
+ map_file << " po " << proper_pos_counter << " " << i
1200
1211
<< " " << w->name .c_str () << " \n " ;
1201
1212
}
1213
+ proper_pos_counter++;
1202
1214
pos.push_back (std::make_pair (SigBit (w, i), HierCursor{}));
1203
1215
}
1204
1216
@@ -1446,7 +1458,7 @@ struct XAiger2Backend : Backend {
1446
1458
if (!map_filename.empty ()) {
1447
1459
writer.map_file .open (map_filename);
1448
1460
if (!writer.map_file )
1449
- log_cmd_error (" Failed to open '%s' for writing\n " , map_filename. c_str () );
1461
+ log_cmd_error (" Failed to open '%s' for writing\n " , map_filename);
1450
1462
}
1451
1463
1452
1464
design->bufNormalize (true );
0 commit comments