@@ -22,6 +22,15 @@ void BLIF_file::reset(CStr nm, uint16_t tr) noexcept {
22
22
err_msg_.clear ();
23
23
}
24
24
25
+ // "model "
26
+ static inline bool starts_w_model (CStr z, size_t len) noexcept {
27
+ assert (z);
28
+ if (len < 6 )
29
+ return false ;
30
+ return z[0 ] == ' m' and z[1 ] == ' o' and z[2 ] == ' d' and
31
+ z[3 ] == ' e' and z[4 ] == ' l' and ::isspace (z[5 ]);
32
+ }
33
+
25
34
// "inputs "
26
35
static inline bool starts_w_inputs (CStr z, size_t len) noexcept {
27
36
assert (z);
@@ -78,6 +87,18 @@ static inline bool starts_w_R_eq(CStr z) noexcept {
78
87
return z[0 ] == ' R' and z[1 ] == ' =' ;
79
88
}
80
89
90
+ // "T="
91
+ static inline bool starts_w_T_eq (CStr z) noexcept {
92
+ assert (z);
93
+ if (::strlen (z) < 2 )
94
+ return false ;
95
+ return z[0 ] == ' T' and z[1 ] == ' =' ;
96
+ }
97
+
98
+ static inline bool starts_w_R_or_T (CStr z) noexcept {
99
+ return starts_w_R_eq (z) or starts_w_T_eq (z);
100
+ }
101
+
81
102
// "I="
82
103
static inline bool starts_w_I_eq (CStr z) noexcept {
83
104
assert (z);
@@ -86,6 +107,30 @@ static inline bool starts_w_I_eq(CStr z) noexcept {
86
107
return z[0 ] == ' I' and z[1 ] == ' =' ;
87
108
}
88
109
110
+ // "O="
111
+ static inline bool starts_w_O_eq (CStr z) noexcept {
112
+ assert (z);
113
+ if (::strlen (z) < 2 )
114
+ return false ;
115
+ return z[0 ] == ' O' and z[1 ] == ' =' ;
116
+ }
117
+
118
+ // "Y="
119
+ static inline bool starts_w_Y_eq (CStr z) noexcept {
120
+ assert (z);
121
+ if (::strlen (z) < 2 )
122
+ return false ;
123
+ return z[0 ] == ' Y' and z[1 ] == ' =' ;
124
+ }
125
+
126
+ // "Q="
127
+ static inline bool starts_w_Q_eq (CStr z) noexcept {
128
+ assert (z);
129
+ if (::strlen (z) < 2 )
130
+ return false ;
131
+ return z[0 ] == ' Q' and z[1 ] == ' =' ;
132
+ }
133
+
89
134
// sometimes in eblif the gate output is not the last token. correct it.
90
135
static void place_output_at_back (vector<string>& dat) noexcept {
91
136
size_t dsz = dat.size ();
@@ -113,7 +158,7 @@ bool BLIF_file::readBlif() noexcept {
113
158
if (ts) {
114
159
int tr = ::atoi (ts);
115
160
if (tr > 0 ) {
116
- tr = std::max (tr, 1000 );
161
+ tr = std::min (tr, 1000 );
117
162
trace_ = tr;
118
163
}
119
164
}
@@ -169,6 +214,9 @@ bool BLIF_file::readBlif() noexcept {
169
214
lprintf (" ....\\ ... num_escaped= %zu\n " , num_escaped);
170
215
}
171
216
217
+ std::vector<string> V; // tmp buffer for tokenizing
218
+ V.reserve (16 );
219
+
172
220
inputs_lnum_ = outputs_lnum_ = 0 ;
173
221
err_lnum_ = 0 ;
174
222
for (size_t i = 1 ; i < lsz; i++) {
@@ -187,19 +235,26 @@ bool BLIF_file::readBlif() noexcept {
187
235
outputs_lnum_ = i;
188
236
continue ;
189
237
}
190
- if (inputs_lnum_ and outputs_lnum_) break ;
238
+ if (starts_w_model (cs + 1 , len - 1 )) {
239
+ V.clear ();
240
+ Fio::split_spa (cs, V);
241
+ if (V.size () > 1 )
242
+ topModel_ = V.back ();
243
+ }
244
+ if (inputs_lnum_ and outputs_lnum_)
245
+ break ;
191
246
}
192
247
if (!inputs_lnum_ and !outputs_lnum_) {
193
248
err_msg_ = " .inputs/.outputs not found" ;
194
249
return false ;
195
250
}
196
251
197
252
if (trace_ >= 3 ) {
253
+ lprintf (" \t .... topModel_= %s\n " , topModel_.c_str ());
198
254
lprintf (" \t .... inputs_lnum_= %zu outputs_lnum_= %zu\n " , inputs_lnum_, outputs_lnum_);
199
255
}
200
256
201
- std::vector<string> V;
202
- V.reserve (16 );
257
+ V.clear ();
203
258
if (inputs_lnum_) {
204
259
Fio::split_spa (lines_[inputs_lnum_], V);
205
260
if (V.size () > 1 and V.front () == " .inputs" ) {
@@ -355,10 +410,10 @@ uint BLIF_file::printNodes(std::ostream& os) const noexcept {
355
410
for (uint i = 1 ; i <= n; i++) {
356
411
const Node& nd = nodePool_[i];
357
412
os_printf (os,
358
- " |%u| L:%u %s inDeg=%u outDeg=%u par=%u out:%s " ,
413
+ " |%u| L:%u %s inDeg=%u outDeg=%u par=%u out:%s mog:%i/%i " ,
359
414
i, nd.lnum_ , nd.kw_ .c_str (),
360
415
nd.inDeg (), nd.outDeg (), nd.parent_ ,
361
- nd.cOut ());
416
+ nd.cOut (), nd. isMog (), nd. isVirtualMog () );
362
417
if (nd.data_ .empty ()) {
363
418
os << endl;
364
419
} else {
@@ -373,6 +428,69 @@ uint BLIF_file::printNodes(std::ostream& os) const noexcept {
373
428
return n;
374
429
}
375
430
431
+ static bool s_is_MOG (const vector<string>& data,
432
+ vector<string>& terms) noexcept {
433
+ terms.clear ();
434
+ uint dsz = data.size ();
435
+ assert (dsz < 1000000 );
436
+ if (dsz < 4 )
437
+ return false ;
438
+
439
+ bool has_O = false , has_Y = false , has_Q = false ;
440
+ uint sum = 0 ;
441
+
442
+ for (uint i = dsz - 1 ; i > 1 ; i--) {
443
+ CStr cs = data[i].c_str ();
444
+ if (!has_O) {
445
+ has_O = starts_w_O_eq (cs);
446
+ if (has_O)
447
+ terms.emplace_back (cs);
448
+ }
449
+ if (!has_Y) {
450
+ has_Y = starts_w_Y_eq (cs);
451
+ if (has_Y)
452
+ terms.emplace_back (cs);
453
+ }
454
+ if (!has_Q) {
455
+ has_Q = starts_w_Q_eq (cs);
456
+ if (has_Q)
457
+ terms.emplace_back (cs);
458
+ }
459
+ sum = uint (has_O) + uint (has_Y) + uint (has_Q);
460
+ if (sum == 3 )
461
+ break ;
462
+ }
463
+
464
+ sum = uint (has_O) + uint (has_Y) + uint (has_Q);
465
+ if (sum < 2 ) {
466
+ terms.clear ();
467
+ return false ;
468
+ }
469
+ return true ;
470
+ }
471
+
472
+ static void s_remove_MOG_terms (vector<string>& data) noexcept {
473
+ uint dsz = data.size ();
474
+ assert (dsz < 1000000 );
475
+ if (dsz < 4 )
476
+ return ;
477
+ for (uint i = dsz - 1 ; i > 1 ; i--) {
478
+ CStr cs = data[i].c_str ();
479
+ if (starts_w_O_eq (cs)) {
480
+ data.erase (data.begin () + i);
481
+ continue ;
482
+ }
483
+ if (starts_w_Y_eq (cs)) {
484
+ data.erase (data.begin () + i);
485
+ continue ;
486
+ }
487
+ if (starts_w_Q_eq (cs)) {
488
+ data.erase (data.begin () + i);
489
+ continue ;
490
+ }
491
+ }
492
+ }
493
+
376
494
bool BLIF_file::createNodes () noexcept {
377
495
nodePool_.clear ();
378
496
topInputs_.clear ();
@@ -460,6 +578,55 @@ bool BLIF_file::createNodes() noexcept {
460
578
return false ;
461
579
}
462
580
581
+ // -- replace MOGs by virtual SOGs
582
+ num_MOGs_ = 0 ;
583
+ for (uint i = 1 ; i <= nn; i++) {
584
+ V.clear ();
585
+ Node& nd = nodePool_[i];
586
+ if (nd.kw_ != " .subckt" and nd.kw_ != " .gate" )
587
+ continue ;
588
+ if (nd.data_ .size () < 4 )
589
+ continue ;
590
+ if (nd.is_IBUF () or nd.is_OBUF ())
591
+ continue ;
592
+ assert (!nd.is_mog_ );
593
+
594
+ // if (topModel_ == "MOG_01" and i == 10)
595
+ // lputs9();
596
+
597
+ s_is_MOG (nd.data_ , V);
598
+ bool is_mog = V.size () > 1 ;
599
+ if (is_mog) {
600
+ if (trace_ >= 5 ) {
601
+ lprintf (" \t\t .... MOG-type: %s\n " , nd.cType ());
602
+ lprintf (" \t\t .... [terms] V.size()= %zu\n " , V.size ());
603
+ logVec (V, " [V-terms] " );
604
+ lputs ();
605
+ }
606
+
607
+ s_remove_MOG_terms (nd.data_ );
608
+ uint startVirtual = nodePool_.size ();
609
+ for (uint j = 1 ; j < V.size (); j++) {
610
+ nodePool_.emplace_back (nd);
611
+ nodePool_.back ().virtualOrigin_ = i;
612
+ nodePool_.back ().is_mog_ = true ;
613
+ }
614
+ nd.data_ .push_back (V.front ());
615
+ nd.is_mog_ = true ;
616
+ // give one output term to each virtual MOG:
617
+ uint V_index = 1 ;
618
+ for (uint k = startVirtual; k < nodePool_.size (); k++) {
619
+ assert (V_index < V.size ());
620
+ Node& k_node = nodePool_[k];
621
+ k_node.data_ .push_back (V[V_index++]);
622
+ }
623
+ num_MOGs_++;
624
+ }
625
+ }
626
+
627
+ nn = numNodes ();
628
+ assert (nn);
629
+
463
630
fabricNodes_.reserve (nn);
464
631
465
632
// -- finish and index nodes:
@@ -681,8 +848,8 @@ bool BLIF_file::linkNodes() noexcept {
681
848
assert (pinIndex >= 0 );
682
849
assert (uint (pinIndex) < par->data_ .size ());
683
850
const string& pinToken = par->data_ [pinIndex];
684
- if (not starts_w_R_eq (pinToken.c_str ())) {
685
- // skipping reset pins "R="
851
+ if (not starts_w_R_or_T (pinToken.c_str ())) {
852
+ // skipping reset (and similar) pins "R=", "T ="
686
853
// because they can be both input and output.
687
854
// need to read library primitives to determine direction.
688
855
err_msg_ = " output port contacts fabric input: " ;
@@ -736,8 +903,6 @@ bool BLIF_file::linkNodes() noexcept {
736
903
}
737
904
738
905
// 4. every node except topInputs_ should be driven
739
- /*
740
- ///// --- not ready - need to support multi-driver cells
741
906
string inp1;
742
907
for (Node* fab_nd : fabricNodes_) {
743
908
Node& nd = *fab_nd;
@@ -752,7 +917,7 @@ bool BLIF_file::linkNodes() noexcept {
752
917
continue ;
753
918
Node* drv_cell = findFabricDriver (nd.id_ , inp1);
754
919
if (!drv_cell) {
755
- lputs9();
920
+ // lputs9();
756
921
err_msg_ = " undriven cell input: " ;
757
922
err_msg_ += inp1;
758
923
if (trace_ >= 2 ) {
@@ -763,7 +928,6 @@ bool BLIF_file::linkNodes() noexcept {
763
928
return false ;
764
929
}
765
930
}
766
- */
767
931
768
932
return true ;
769
933
}
0 commit comments