@@ -41,6 +41,8 @@ struct Smt2Worker
41
41
std::set<RTLIL::Cell*> exported_cells, hiercells, hiercells_queue;
42
42
pool<Cell*> recursive_cells, registers;
43
43
44
+ pool<SigBit> clock_posedge, clock_negedge;
45
+
44
46
std::map<RTLIL::SigBit, std::pair<int , int >> fcache;
45
47
std::map<Cell*, int > memarrays;
46
48
std::map<int , int > bvsizes;
@@ -104,18 +106,24 @@ struct Smt2Worker
104
106
decls.push_back (decl_str + " \n " );
105
107
}
106
108
107
- Smt2Worker (RTLIL::Module *module , bool bvmode, bool memmode, bool wiresmode, bool verbose, bool statebv, bool statedt, dict<IdString, int > &mod_stbv_width) :
109
+ Smt2Worker (RTLIL::Module *module , bool bvmode, bool memmode, bool wiresmode, bool verbose, bool statebv, bool statedt,
110
+ dict<IdString, int > &mod_stbv_width, dict<IdString, dict<IdString, pair<bool , bool >>> &mod_clk_cache) :
108
111
ct (module ->design), sigmap(module ), module (module ), bvmode(bvmode), memmode(memmode), wiresmode(wiresmode),
109
112
verbose (verbose), statebv(statebv), statedt(statedt), mod_stbv_width(mod_stbv_width), idcounter(0 ), statebv_width(0 )
110
113
{
114
+ pool<SigBit> noclock;
115
+
111
116
makebits (stringf (" %s_is" , get_id (module )));
112
117
113
118
for (auto cell : module ->cells ())
114
- for (auto &conn : cell->connections ()) {
119
+ for (auto &conn : cell->connections ())
120
+ {
115
121
if (GetSize (conn.second ) == 0 )
116
122
continue ;
123
+
117
124
bool is_input = ct.cell_input (cell->type , conn.first );
118
125
bool is_output = ct.cell_output (cell->type , conn.first );
126
+
119
127
if (is_output && !is_input)
120
128
for (auto bit : sigmap (conn.second )) {
121
129
if (bit_driver.count (bit))
@@ -125,6 +133,48 @@ struct Smt2Worker
125
133
else if (is_output || !is_input)
126
134
log_error (" Unsupported or unknown directionality on port %s of cell %s.%s (%s).\n " ,
127
135
log_id (conn.first ), log_id (module ), log_id (cell), log_id (cell->type ));
136
+
137
+ if (cell->type .in (" $dff" , " $_DFF_P_" , " $_DFF_N_" ) && conn.first .in (" \\ CLK" , " \\ C" ))
138
+ {
139
+ bool posedge = (cell->type == " $_DFF_N_" ) || (cell->type == " $dff" && cell->getParam (" \\ CLK_POLARITY" ).as_bool ());
140
+ for (auto bit : sigmap (conn.second )) {
141
+ if (posedge)
142
+ clock_posedge.insert (bit);
143
+ else
144
+ clock_negedge.insert (bit);
145
+ }
146
+ }
147
+ else
148
+ if (mod_clk_cache.count (cell->type ) && mod_clk_cache.at (cell->type ).count (conn.first ))
149
+ {
150
+ for (auto bit : sigmap (conn.second )) {
151
+ if (mod_clk_cache.at (cell->type ).at (conn.first ).first )
152
+ clock_posedge.insert (bit);
153
+ if (mod_clk_cache.at (cell->type ).at (conn.first ).second )
154
+ clock_negedge.insert (bit);
155
+ }
156
+ }
157
+ else
158
+ {
159
+ for (auto bit : sigmap (conn.second ))
160
+ noclock.insert (bit);
161
+ }
162
+ }
163
+
164
+ for (auto bit : noclock) {
165
+ clock_posedge.erase (bit);
166
+ clock_negedge.erase (bit);
167
+ }
168
+
169
+ for (auto wire : module ->wires ())
170
+ {
171
+ if (!wire->port_input || GetSize (wire) != 1 )
172
+ continue ;
173
+ SigBit bit = sigmap (wire);
174
+ if (clock_posedge.count (bit))
175
+ mod_clk_cache[module ->name ][wire->name ].first = true ;
176
+ if (clock_negedge.count (bit))
177
+ mod_clk_cache[module ->name ][wire->name ].second = true ;
128
178
}
129
179
}
130
180
@@ -731,6 +781,9 @@ struct Smt2Worker
731
781
decls.push_back (stringf (" ; yosys-smt2-register %s %d\n " , get_id (wire), wire->width ));
732
782
if (wire->get_bool_attribute (" \\ keep" ) || (wiresmode && wire->name [0 ] == ' \\ ' ))
733
783
decls.push_back (stringf (" ; yosys-smt2-wire %s %d\n " , get_id (wire), wire->width ));
784
+ if (GetSize (wire) == 1 && (clock_posedge.count (sig) || clock_negedge.count (sig)))
785
+ decls.push_back (stringf (" ; yosys-smt2-clock %s%s%s\n " , get_id (wire),
786
+ clock_posedge.count (sig) ? " posedge" : " " , clock_negedge.count (sig) ? " negedge" : " " ));
734
787
if (bvmode && GetSize (sig) > 1 ) {
735
788
decls.push_back (stringf (" (define-fun |%s_n %s| ((state |%s_s|)) (_ BitVec %d) %s)\n " ,
736
789
get_id (module ), get_id (wire), get_id (module ), GetSize (sig), get_bv (sig).c_str ()));
@@ -1386,6 +1439,7 @@ struct Smt2Backend : public Backend {
1386
1439
}
1387
1440
1388
1441
dict<IdString, int > mod_stbv_width;
1442
+ dict<IdString, dict<IdString, pair<bool , bool >>> mod_clk_cache;
1389
1443
Module *topmod = design->top_module ();
1390
1444
std::string topmod_id;
1391
1445
@@ -1396,7 +1450,7 @@ struct Smt2Backend : public Backend {
1396
1450
1397
1451
log (" Creating SMT-LIBv2 representation of module %s.\n " , log_id (module ));
1398
1452
1399
- Smt2Worker worker (module , bvmode, memmode, wiresmode, verbose, statebv, statedt, mod_stbv_width);
1453
+ Smt2Worker worker (module , bvmode, memmode, wiresmode, verbose, statebv, statedt, mod_stbv_width, mod_clk_cache );
1400
1454
worker.run ();
1401
1455
worker.write (*f);
1402
1456
0 commit comments