2323USING_YOSYS_NAMESPACE
2424PRIVATE_NAMESPACE_BEGIN
2525
26+ struct ThresholdHierarchyKeeping {
27+ Design *design;
28+ CellCosts costs;
29+ dict<Module *, int > done;
30+ pool<Module *> in_progress;
31+ uint64_t threshold;
32+
33+ ThresholdHierarchyKeeping (Design *design, uint64_t threshold)
34+ : design(design), costs(design), threshold(threshold) {}
35+
36+ uint64_t visit (RTLIL::Module *module ) {
37+ if (module ->has_attribute (ID (gate_cost_equivalent)))
38+ return module ->attributes [ID (gate_cost_equivalent)].as_int ();
39+
40+ if (module ->has_attribute (ID (keep_hierarchy)))
41+ return 0 ;
42+
43+ if (module ->get_blackbox_attribute ())
44+ log_error (" Missing cost information on instanced blackbox %s\n " , log_id (module ));
45+
46+ if (done.count (module ))
47+ return done.at (module );
48+
49+ if (in_progress.count (module ))
50+ log_error (" Circular hierarchy\n " );
51+ in_progress.insert (module );
52+
53+ uint64_t size = 0 ;
54+ module ->has_processes_warn ();
55+
56+ for (auto cell : module ->cells ()) {
57+ if (!cell->type .isPublic ()) {
58+ size += costs.get (cell);
59+ } else {
60+ RTLIL::Module *submodule = design->module (cell->type );
61+ if (!submodule)
62+ log_error (" Hierarchy contains unknown module '%s' (instanced as %s in %s)\n " ,
63+ log_id (cell->type ), log_id (cell), log_id (module ));
64+ size += visit (submodule);
65+ }
66+ }
67+
68+ if (size > threshold) {
69+ log (" Keeping %s (estimated size above threshold: %llu > %llu).\n " , log_id (module ), size, threshold);
70+ module ->set_bool_attribute (ID::keep_hierarchy);
71+ size = 0 ;
72+ }
73+
74+ in_progress.erase (module );
75+ done[module ] = size;
76+ return size;
77+ }
78+ };
79+
2680struct KeepHierarchyPass : public Pass {
27- KeepHierarchyPass () : Pass(" keep_hierarchy" , " add the keep_hierarchy attribute" ) {}
81+ KeepHierarchyPass () : Pass(" keep_hierarchy" , " selectively add the keep_hierarchy attribute" ) {}
2882 void help () override
2983 {
3084 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
3185 log (" \n " );
32- log (" keep_hierarchy [options]\n " );
86+ log (" keep_hierarchy [options] [selection] \n " );
3387 log (" \n " );
3488 log (" Add the keep_hierarchy attribute.\n " );
3589 log (" \n " );
3690 log (" -min_cost <min_cost>\n " );
37- log (" only add the attribute to modules estimated to have more\n " );
38- log (" than <min_cost> gates after simple techmapping. Intended\n " );
39- log (" for tuning trade-offs between quality and yosys runtime.\n " );
91+ log (" only add the attribute to modules estimated to have more than <min_cost>\n " );
92+ log (" gates after simple techmapping. Intended for tuning trade-offs between\n " );
93+ log (" quality and yosys runtime.\n " );
94+ log (" \n " );
95+ log (" When evaluating a module's cost, gates which are within a submodule\n " );
96+ log (" which is marked with the keep_hierarchy attribute are not counted\n " );
97+ log (" towards the upper module's cost. This applies to both when the attribute\n " );
98+ log (" was added by this command or was pre-existing.\n " );
99+ log (" \n " );
40100 }
41101 void execute (std::vector<std::string> args, RTLIL::Design *design) override
42102 {
@@ -54,16 +114,15 @@ struct KeepHierarchyPass : public Pass {
54114 }
55115 extra_args (args, argidx, design);
56116
57- CellCosts costs (design);
117+ if (min_cost) {
118+ RTLIL::Module *top = design->top_module ();
119+ if (!top)
120+ log_cmd_error (" '-min_cost' mode requires a single top module in the design\n " );
58121
59- for (auto module : design->selected_modules ()) {
60- if (min_cost) {
61- unsigned int cost = costs.get (module );
62- if (cost > min_cost) {
63- log (" Marking %s (module too big: %d > %d).\n " , log_id (module ), cost, min_cost);
64- module ->set_bool_attribute (ID::keep_hierarchy);
65- }
66- } else {
122+ ThresholdHierarchyKeeping worker (design, min_cost);
123+ worker.visit (top);
124+ } else {
125+ for (auto module : design->selected_modules ()) {
67126 log (" Marking %s.\n " , log_id (module ));
68127 module ->set_bool_attribute (ID::keep_hierarchy);
69128 }
0 commit comments