1 ///////////////////////////////////////////////////////////////////////////////
2 // BSD 3-Clause License
3 //
4 // Copyright (c) 2019, Nefelus Inc
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are met:
9 //
10 // * Redistributions of source code must retain the above copyright notice, this
11 //   list of conditions and the following disclaimer.
12 //
13 // * Redistributions in binary form must reproduce the above copyright notice,
14 //   this list of conditions and the following disclaimer in the documentation
15 //   and/or other materials provided with the distribution.
16 //
17 // * Neither the name of the copyright holder nor the names of its
18 //   contributors may be used to endorse or promote products derived from
19 //   this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 // POSSIBILITY OF SUCH DAMAGE.
32 
33 #ifndef ADS_EXT_H
34 #define ADS_EXT_H
35 
36 #include <tcl.h>
37 
38 #include "extRCap.h"
39 #include "exttree.h"
40 
41 namespace utl {
42 class Logger;
43 }
44 
45 namespace rcx {
46 
47 using utl::Logger;
48 class Ext
49 
50 #ifndef SWIG  // causes swig warnings
51     : public odb::ZInterface
52 #endif
53 {
54  public:
55   Ext();
56   ~Ext();
57 
58   void init(Tcl_Interp* tcl_interp, odb::dbDatabase* db, Logger* logger);
59   void setLogger(Logger* logger);
60 
61   bool load_model(const std::string& name,
62                   bool lef_rc,
63                   const std::string& file,
64                   int setMin,
65                   int setTyp,
66                   int setMax);
67   bool read_process(const std::string& name, const std::string& file);
68   bool rules_gen(const std::string& name,
69                  const std::string& dir,
70                  const std::string& file,
71                  bool write_to_solver,
72                  bool read_from_solver,
73                  bool run_solver,
74                  int pattern,
75                  bool keep_file);
76   bool metal_rules_gen(const std::string& name,
77                        const std::string& dir,
78                        const std::string& file,
79                        bool write_to_solver,
80                        bool read_from_solver,
81                        bool run_solver,
82                        int pattern,
83                        bool keep_file,
84                        int metal);
85   bool write_rules(const std::string& name,
86                    const std::string& dir,
87                    const std::string& file,
88                    int pattern,
89                    bool read_from_db,
90                    bool read_from_solver);
91   bool get_ext_metal_count(int& metal_count);
92   bool bench_net(const std::string& dir,
93                  int net,
94                  bool write_to_solver,
95                  bool read_from_solver,
96                  bool run_solver,
97                  int max_track_count);
98   bool bench_verilog(const std::string& file);
99   bool run_solver(const std::string& dir, int net, int shape);
100 
101   struct BenchWiresOptions
102   {
103     const char* block = "blk";
104     int over_dist = 100;
105     int under_dist = 100;
106     int met_cnt = 1000;
107     int met = -1;
108     int over_met = -1;
109     int under_met = -1;
110     int len = 200;
111     int cnt = 5;
112     const char* w = "1";
113     const char* s = "1";
114     const char* th = "1";
115     const char* d = "0.0";
116     const char* w_list = "1";
117     const char* s_list = "1 2 2.5 3 3.5 4 4.5 5 6 8 10 12";
118     const char* th_list = "0 1 2 2.5 3 3.5 4 4.5 5 6 8 10 12";
119     const char* grid_list = "";
120     bool default_lef_rules = false;
121     bool nondefault_lef_rules = false;
122     const char* dir = "./Bench";
123     bool Over = false;
124     bool db_only = false;
125     bool ddd = false;
126     bool multiple_widths = false;
127     bool write_to_solver = false;
128     bool read_from_solver = false;
129     bool run_solver = false;
130     bool diag = false;
131     bool over_under = false;
132     bool gen_def_patterns = false;
133     bool resPatterns = false;
134   };
135 
136   bool bench_wires(const BenchWiresOptions& bwo);
137   bool assembly(odb::dbBlock* block, odb::dbBlock* main_block);
138   bool write_spef_nets(odb::dbObject* block,
139                        bool flatten,
140                        bool parallel,
141                        int corner);
142   bool flatten(odb::dbBlock* block, bool spef);
143 
144   struct ExtractOptions
145   {
146     bool min = false;
147     bool max = false;
148     bool typ = false;
149     int set_min = -1;
150     int set_typ = -1;
151     int set_max = -1;
152     bool litho = false;
153     bool wire_density = false;
154     const char* debug_net = nullptr;
155     const char* cmp_file = nullptr;
156     const char* ext_model_file = nullptr;
157     const char* net = nullptr;
158     const char* bbox = nullptr;
159     const char* ibox = nullptr;
160     int test = 0;
161     int cc_band_tracks = 1000;
162     int signal_table = 3;
163     int cc_up = 2;
164     uint preserve_geom = 0;
165     int corner_cnt = 1;
166     double max_res = 50.0;
167     bool no_merge_via_res = false;
168     float coupling_threshold = 0.1;
169     int context_depth = 5;
170     int cc_model = 10;
171     bool over_cell = false;
172     bool remove_cc = false;
173     bool remove_ext = false;
174     bool unlink_ext = false;
175     bool eco = false;
176     bool no_gs = false;
177     bool re_run = false;
178     bool skip_via_wires = false;
179     bool tile = false;
180     int tiling = 0;
181     bool skip_m1_caps = false;
182     bool power_grid = false;
183     bool write_total_caps = false;
184     const char* exclude_cells = nullptr;
185     bool skip_power_stubs = false;
186     const char* power_source_coords = nullptr;
187     bool lef_rc = false;
188     bool lef_res = false;
189     bool rlog = false;
190   };
191 
192   bool extract(ExtractOptions options);
193 
194   bool define_process_corner(int ext_model_index, const std::string& name);
195   bool define_derived_corner(const std::string& name,
196                              const std::string& process_corner_name,
197                              float res_factor,
198                              float cc_factor,
199                              float gndc_factor);
200   bool get_ext_db_corner(int& index, const std::string& name);
201   bool get_corners(std::list<std::string>& corner_list);
202   bool delete_corners();
203   bool clean(bool all_models, bool ext_only);
204   bool adjust_rc(float res_factor, float cc_factor, float gndc_factor);
205 
206   bool init_incremental_spef(const std::string& origp,
207                              const std::string& newp,
208                              bool no_backslash,
209                              const std::string& exclude_cells);
210   struct SpefOptions
211   {
212     const char* nets = nullptr;
213     int net_id = 0;
214     const char* ext_corner_name = nullptr;
215     int corner = -1;
216     int debug = 0;
217     bool flatten = false;
218     bool parallel = false;
219     bool init = false;
220     bool end = false;
221     bool use_ids = false;
222     bool no_name_map = false;
223     const char* N = nullptr;
224     bool term_junction_xy = false;
225     bool single_pi = false;
226     const char* file = nullptr;
227     bool gz = false;
228     bool stop_after_map = false;
229     bool w_clock = false;
230     bool w_conn = false;
231     bool w_cap = false;
232     bool w_cc_cap = false;
233     bool w_res = false;
234     bool no_c_num = false;
235     bool no_backslash = false;
236     const char* exclude_cells = nullptr;
237     const char* cap_units = "PF";
238     const char* res_units = "OHM";
239   };
240   bool write_spef(const SpefOptions& options);
241 
242   bool independent_spef_corner();
243 
244   struct ReadSpefOpts
245   {
246     const char* file = nullptr;
247     const char* net = nullptr;
248     bool force = false;
249     bool use_ids = false;
250     bool keep_loaded_corner = false;
251     bool stamp_wire = false;
252     int test_parsing = 0;
253     const char* N = nullptr;
254     bool r_conn = false;
255     bool r_cap = false;
256     bool r_cc_cap = false;
257     bool r_res = false;
258     float cc_threshold = -0.5;
259     float cc_ground_factor = 0;
260     int app_print_limit = 0;
261     int corner = -1;
262     const char* db_corner_name = nullptr;
263     const char* calibrate_base_corner = nullptr;
264     int spef_corner = -1;
265     bool m_map = false;
266     bool more_to_read = false;
267     float length_unit = 1;
268     int fix_loop = 0;
269     bool no_cap_num_collapse = false;
270     const char* cap_node_map_file = nullptr;
271     bool log = false;
272   };
273 
274   bool read_spef(ReadSpefOpts& opt);
275 
276   struct DiffOptions
277   {
278     const char* net = nullptr;
279     bool use_ids = false;
280     bool test_parsing = 0;
281     const char* file = nullptr;
282     const char* db_corner_name = nullptr;
283     int spef_corner = -1;
284     const char* exclude_net_subword = nullptr;
285     const char* net_subword = nullptr;
286     const char* rc_stats_file = nullptr;
287     bool r_conn = false;
288     bool r_cap = false;
289     bool r_cc_cap = false;
290     bool r_res = false;
291     int ext_corner = -1;
292     float low_guard = 1;
293     float upper_guard = -1;
294     bool m_map = false;
295     bool log = false;
296   };
297 
298   bool diff_spef(const DiffOptions& opt);
299   bool calibrate(const std::string& spef_file,
300                  const std::string& db_corner_name,
301                  int corner,
302                  int spef_corner,
303                  bool m_map,
304                  float upper_limit,
305                  float lower_limit);
306   bool match(const std::string& spef_file,
307              const std::string& db_corner_name,
308              int corner,
309              int spef_corner,
310              bool m_map);
311   bool set_block(const std::string& block_name,
312                  odb::dbBlock* block,
313                  const std::string& inst_name,
314                  odb::dbInst* inst);
315   bool report_total_cap(const std::string& file,
316                         bool res_only,
317                         bool cap_only,
318                         float ccmult,
319                         const std::string& ref,
320                         const std::string& read);
321   bool report_total_cc(const std::string& file,
322                        const std::string& ref,
323                        const std::string& read);
324 
325   bool export_sdb(odb::ZPtr<odb::ISdb>& net_sdb, odb::ZPtr<odb::ISdb>& cc_sdb);
326   bool dump(bool open_tree_file,
327             bool close_tree_file,
328             bool cc_cap_geom,
329             bool cc_net_geom,
330             bool track_cnt,
331             bool signal,
332             bool power,
333             int layer,
334             const std::string& file);
335   bool count(bool signal_wire_seg, bool power_wire_seg);
336   bool read_qcap(const std::string& file_name,
337                  const std::string& cap_file,
338                  bool skip_bterms,
339                  bool no_qcap,
340                  const std::string& design);
341   bool rc_tree(float max_cap, uint test, int net, const std::string& print_tag);
342   bool net_stats(std::list<int>& net_ids,
343                  const std::string& tcap,
344                  const std::string& ccap,
345                  const std::string& ratio_cap,
346                  const std::string& res,
347                  const std::string& len,
348                  const std::string& met_cnt,
349                  const std::string& wire_cnt,
350                  const std::string& via_cnt,
351                  const std::string& seg_cnt,
352                  const std::string& term_cnt,
353                  const std::string& bterm_cnt,
354                  const std::string& file,
355                  const std::string& bbox,
356                  const std::string& branch_len);
357 
358  private:
359   odb::dbDatabase* _db;
360   extMain* _ext;
361   extRcTree* _tree;
362   Logger* logger_;
363 };  // namespace rcx
364 
365 }  // namespace rcx
366 
367 #endif
368