77#include < memory>
88#include < string>
99
10+ #include " db_sta/dbSta.hh"
1011#include " gtest/gtest.h"
1112#include " odb/db.h"
13+ #include " sta/NetworkClass.hh"
1214#include " sta/VerilogWriter.hh"
1315#include " tst/IntegratedFixture.h"
1416#include " utl/Logger.h"
@@ -30,6 +32,212 @@ class BufRemTest3 : public tst::IntegratedFixture
3032 bool debug_ = false ; // Set to true to generate debug output
3133};
3234
35+ TEST_F (BufRemTest3, RemoveBufferCase9)
36+ {
37+ std::string test_name = " TestBufferRemoval3_9" ;
38+ readVerilogAndSetup (test_name + " .v" );
39+
40+ // Netlist before buffer removal:
41+ // (undriven input) -> buf1 -> out
42+
43+ // Dump pre ECO state
44+ if (debug_) {
45+ dumpVerilogAndOdb (test_name + " _pre_eco" );
46+ }
47+
48+ odb::dbDatabase::beginEco (block_);
49+
50+ // Pre sanity check
51+ sta_->updateTiming (true );
52+ // Do not call checkAxioms() because there is an undriven buffer.
53+
54+ // ----------------------------------------------------
55+ // Remove buffer
56+ // ----------------------------------------------------
57+ auto insts = std::make_unique<sta::InstanceSeq>();
58+ odb::dbInst* buf_inst = block_->findInst (" buf1" );
59+ ASSERT_NE (buf_inst, nullptr );
60+ sta::Instance* sta_buf = db_network_->dbToSta (buf_inst);
61+ insts->emplace_back (sta_buf);
62+ resizer_.removeBuffers (*insts);
63+
64+ // Post sanity check
65+ sta_->updateTiming (true );
66+ // Do not call checkAxioms() because there is an undriven buffer.
67+
68+ // Write verilog and check the content after buffer removal
69+ const std::string after_vlog_path = test_name + " _after.v" ;
70+ sta::writeVerilog (after_vlog_path.c_str (), true , false , {}, sta_->network ());
71+
72+ std::ifstream file_after (after_vlog_path);
73+ std::string content_after ((std::istreambuf_iterator<char >(file_after)),
74+ std::istreambuf_iterator<char >());
75+
76+ // Netlist after buffer removal:
77+ // in -> mod_inst/mod_in -> assign -> mod_inst/mod_out -> out
78+ const std::string expected_after_vlog = R"( module top (clk,
79+ in,
80+ out);
81+ input clk;
82+ input in;
83+ output out;
84+
85+
86+ endmodule
87+ )" ;
88+
89+ EXPECT_EQ (content_after, expected_after_vlog);
90+
91+ odb::dbDatabase::undoEco (block_);
92+
93+ // Dump undo ECO state
94+ if (debug_) {
95+ dumpVerilogAndOdb (test_name + " _undo_eco" );
96+ }
97+
98+ // Clean up
99+ removeFile (after_vlog_path);
100+ }
101+
102+ TEST_F (BufRemTest3, RemoveBufferCase8)
103+ {
104+ std::string test_name = " TestBufferRemoval3_8" ;
105+ readVerilogAndSetup (test_name + " .v" );
106+
107+ // Netlist before buffer removal:
108+ // (undriven input) -> buf1 -> out
109+
110+ // Dump pre ECO state
111+ if (debug_) {
112+ dumpVerilogAndOdb (test_name + " _pre_eco" );
113+ }
114+
115+ odb::dbDatabase::beginEco (block_);
116+
117+ // Pre sanity check
118+ sta_->updateTiming (true );
119+ // Do not call checkAxioms() because there is an undriven buffer.
120+
121+ // ----------------------------------------------------
122+ // Remove buffer
123+ // ----------------------------------------------------
124+ auto insts = std::make_unique<sta::InstanceSeq>();
125+ odb::dbInst* buf_inst = block_->findInst (" buf1" );
126+ ASSERT_NE (buf_inst, nullptr );
127+ sta::Instance* sta_buf = db_network_->dbToSta (buf_inst);
128+ insts->emplace_back (sta_buf);
129+ resizer_.removeBuffers (*insts);
130+
131+ // Post sanity check
132+ sta_->updateTiming (true );
133+ // Do not call checkAxioms() because there is an undriven buffer.
134+
135+ // Write verilog and check the content after buffer removal
136+ const std::string after_vlog_path = test_name + " _after.v" ;
137+ sta::writeVerilog (after_vlog_path.c_str (), true , false , {}, sta_->network ());
138+
139+ std::ifstream file_after (after_vlog_path);
140+ std::string content_after ((std::istreambuf_iterator<char >(file_after)),
141+ std::istreambuf_iterator<char >());
142+
143+ // Netlist after buffer removal:
144+ // in -> mod_inst/mod_in -> assign -> mod_inst/mod_out -> out
145+ const std::string expected_after_vlog = R"( module top (clk,
146+ in,
147+ out);
148+ input clk;
149+ input in;
150+ output out;
151+
152+
153+ BUF_X1 buf1 (.Z(out));
154+ endmodule
155+ )" ;
156+
157+ EXPECT_EQ (content_after, expected_after_vlog);
158+
159+ odb::dbDatabase::undoEco (block_);
160+
161+ // Dump undo ECO state
162+ if (debug_) {
163+ dumpVerilogAndOdb (test_name + " _undo_eco" );
164+ }
165+
166+ // Clean up
167+ removeFile (after_vlog_path);
168+ }
169+
170+ TEST_F (BufRemTest3, RemoveBufferCase7)
171+ {
172+ std::string test_name = " TestBufferRemoval3_7" ;
173+ readVerilogAndSetup (test_name + " .v" );
174+
175+ // Netlist before buffer removal:
176+ // (undriven input) -> buf1 -> buf2 -> out
177+
178+ // Dump pre ECO state
179+ if (debug_) {
180+ dumpVerilogAndOdb (test_name + " _pre_eco" );
181+ }
182+
183+ odb::dbDatabase::beginEco (block_);
184+
185+ // Pre sanity check
186+ sta_->updateTiming (true );
187+ // Do not call checkAxioms() because there is an undriven buffer.
188+
189+ // ----------------------------------------------------
190+ // Remove buffer
191+ // ----------------------------------------------------
192+ auto insts = std::make_unique<sta::InstanceSeq>();
193+ odb::dbInst* buf_inst = block_->findInst (" buf1" );
194+ ASSERT_NE (buf_inst, nullptr );
195+ sta::Instance* sta_buf = db_network_->dbToSta (buf_inst);
196+ insts->emplace_back (sta_buf);
197+ resizer_.removeBuffers (*insts);
198+
199+ // Post sanity check
200+ sta_->updateTiming (true );
201+ // Do not call checkAxioms() because there is an undriven buffer.
202+
203+ // Write verilog and check the content after buffer removal
204+ const std::string after_vlog_path = test_name + " _after.v" ;
205+ sta::writeVerilog (after_vlog_path.c_str (), true , false , {}, sta_->network ());
206+
207+ std::ifstream file_after (after_vlog_path);
208+ std::string content_after ((std::istreambuf_iterator<char >(file_after)),
209+ std::istreambuf_iterator<char >());
210+
211+ // Netlist after buffer removal:
212+ // in -> mod_inst/mod_in -> assign -> mod_inst/mod_out -> out
213+ const std::string expected_after_vlog = R"( module top (clk,
214+ in,
215+ out);
216+ input clk;
217+ input in;
218+ output out;
219+
220+ wire n1;
221+
222+ BUF_X1 buf1 (.Z(n1));
223+ BUF_X1 buf2 (.A(n1),
224+ .Z(out));
225+ endmodule
226+ )" ;
227+
228+ EXPECT_EQ (content_after, expected_after_vlog);
229+
230+ odb::dbDatabase::undoEco (block_);
231+
232+ // Dump undo ECO state
233+ if (debug_) {
234+ dumpVerilogAndOdb (test_name + " _undo_eco" );
235+ }
236+
237+ // Clean up
238+ removeFile (after_vlog_path);
239+ }
240+
33241TEST_F (BufRemTest3, RemoveBufferCase6)
34242{
35243 std::string test_name = " TestBufferRemoval3_6" ;
0 commit comments