diff options
| -rw-r--r-- | passes/techmap/abc9.cc | 61 | ||||
| -rw-r--r-- | passes/techmap/abc9_ops.cc | 39 | ||||
| -rw-r--r-- | tests/arch/xilinx/abc9_dff.ys | 4 | 
3 files changed, 66 insertions, 38 deletions
| diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index b57ea3cf7..1a5604f7d 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -281,41 +281,52 @@ struct Abc9Pass : public ScriptPass  		if (check_label("dff", "(only if -dff)")) {  			if (dff_mode || help_mode) {  				run("abc9_ops -prep_dff_hier"); // derive all used (* abc9_flop *) modules, -                                                // create stubs in $abc9_unmap design +								// create stubs in $abc9_unmap design  				run("design -stash $abc9");  				run("design -copy-from $abc9 @$abc9_flops"); // copy derived modules in  				run("proc");  				run("wbflip");  				run("techmap");  				run("opt"); +				if (!help_mode) +					active_design->scratchpad_unset("abc9_ops.prep_dff_map.did_something");  				run("abc9_ops -prep_dff_map"); // rewrite specify -									// select all $_DFF_[NP]_ -									// then select all its fanins -									// then select all fanouts of all that -									// lastly remove $_DFF_[NP]_ cells -				run("setattr -set submod \"$abc9_flop\" t:$_DFF_?_ %ci* %co* t:$_DFF_?_ %d"); -				run("submod"); -				run("design -copy-to $abc9 *_$abc9_flop"); // copy submod out -				run("delete *_$abc9_flop"); -				if (help_mode) { -					run("foreach module in design"); -					run("    rename <module-name>_$abc9_flop _TECHMAP_REPLACE_"); +				bool did_something = help_mode || active_design->scratchpad_get_bool("abc9_ops.prep_dff_map.did_something"); +				if (did_something) { +										// select all $_DFF_[NP]_ +										// then select all its fanins +										// then select all fanouts of all that +										// lastly remove $_DFF_[NP]_ cells +					run("setattr -set submod \"$abc9_flop\" t:$_DFF_?_ %ci* %co* t:$_DFF_?_ %d"); +					run("submod"); +					run("design -copy-to $abc9 *_$abc9_flop"); // copy submod out +					run("delete *_$abc9_flop"); +					if (help_mode) { +						run("foreach module in design"); +						run("    rename <module-name>_$abc9_flop _TECHMAP_REPLACE_"); +					} +					else { +						// Rename all submod-s to _TECHMAP_REPLACE_ to inherit name + attrs +						for (auto module : active_design->selected_modules()) { +							active_design->selected_active_module = module->name.str(); +							if (module->cell(stringf("%s_$abc9_flop", module->name.c_str()))) +								run(stringf("rename %s_$abc9_flop _TECHMAP_REPLACE_", module->name.c_str())); +						} +					} +					run("design -stash $abc9_map"); +					run("design -load $abc9"); +					run("design -delete $abc9"); +					run("select -unset $abc9_flops"); +					run("techmap -wb -map %$abc9_map"); // techmap user design into submod + $_DFF_[NP]_ +					run("design -delete $abc9_map"); +					run("setattr -mod -set whitebox 1 -set abc9_flop 1 -set abc9_box 1 *_$abc9_flop"); +					run("abc9_ops -prep_dff_unmap"); // implement $abc9_unmap design  				}  				else { -					// Rename all submod-s to _TECHMAP_REPLACE_ to inherit name + attrs -					for (auto module : active_design->selected_modules()) { -						active_design->selected_active_module = module->name.str(); -						run(stringf("rename %s_$abc9_flop _TECHMAP_REPLACE_", module->name.c_str())); -					} +					run("design -load $abc9"); +					run("design -delete $abc9"); +					run("select -unset $abc9_flops");  				} -				run("design -stash $abc9_map"); -				run("design -load $abc9"); -				run("design -delete $abc9"); -				run("select -unset $abc9_flops"); -				run("abc9_ops -prep_dff_unmap"); // implement $abc9_unmap design -				run("techmap -map %$abc9_map"); // techmap user design into submod + $_DFF_[NP]_ -				run("design -delete $abc9_map"); -				run("setattr -mod -set whitebox 1 -set abc9_flop 1 -set abc9_box 1 *_$abc9_flop");  			}  		} diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 2f1b531e2..e00a4dc81 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -161,10 +161,23 @@ void prep_dff_hier(RTLIL::Design *design)  void prep_dff_map(RTLIL::Design *design)  { +	Design *unmap_design = saved_designs.at("$abc9_unmap"); +  	for (auto module : design->modules()) {  		vector<Cell*> specify_cells;  		SigBit D, Q;  		Cell* dff_cell = nullptr; + +		// If module has a public name (i.e. not $paramod) and it doesn't exist +		//   in the $abc9_unmap then it means only derived modules were +		//   instantiated, so make this a blackbox +		if (module->name[0] == '\\' && !unmap_design->module(module->name.str() + "_$abc9_flop")) { +			module->makeblackbox(); +			module->set_bool_attribute(ID::blackbox, false); +			module->set_bool_attribute(ID::whitebox, true); +			continue; +		} +  		for (auto cell : module->cells())  			if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) {  				if (dff_cell) @@ -185,6 +198,7 @@ void prep_dff_map(RTLIL::Design *design)  					log_warning("Module '%s' contains a %s cell with non-zero initial state -- this is not unsupported for ABC9 sequential synthesis. Treating as a blackbox.\n", log_id(module), log_id(cell->type));  					module->makeblackbox(); +					module->set_bool_attribute(ID::blackbox, false);  					auto wire = module->addWire(ID(_TECHMAP_FAIL_));  					wire->set_bool_attribute(ID::keep); @@ -215,19 +229,20 @@ void prep_dff_map(RTLIL::Design *design)  			D = w;  		} -		if (GetSize(specify_cells) == 0) { -			log_warning("Module '%s' marked (* abc9_flop *) contains no specify timing information.\n", log_id(module)); -		} -		else { -			// Rewrite $specify cells that end with $_DFF_[NP]_.Q -			//   to $_DFF_[NP]_.D since it will be moved into -			//   the submodule -			for (auto cell : specify_cells) { -				auto DST = cell->getPort(ID::DST); -				DST.replace(Q, D); -				cell->setPort(ID::DST, DST); -			} +		if (GetSize(specify_cells) == 0) +			log_error("Module '%s' marked (* abc9_flop *) contains no specify timing information.\n", log_id(module)); + +		// Rewrite $specify cells that end with $_DFF_[NP]_.Q +		//   to $_DFF_[NP]_.D since it will be moved into +		//   the submodule +		for (auto cell : specify_cells) { +			auto DST = cell->getPort(ID::DST); +			DST.replace(Q, D); +			cell->setPort(ID::DST, DST);  		} + +		design->scratchpad_set_bool("abc9_ops.prep_dff_map.did_something", true); +  continue_outer_loop: ;  	}  } diff --git a/tests/arch/xilinx/abc9_dff.ys b/tests/arch/xilinx/abc9_dff.ys index abe597e2c..15343970f 100644 --- a/tests/arch/xilinx/abc9_dff.ys +++ b/tests/arch/xilinx/abc9_dff.ys @@ -14,6 +14,7 @@ endmodule  EOT  equiv_opt -assert -multiclock -map +/xilinx/cells_sim.v synth_xilinx -abc9 -dff -noiopad -noclkbuf  design -load postopt +select -assert-count 6 t:FD*  select -assert-count 6 c:fd2 c:fd3 c:fd4 c:fd6 c:fd7 c:fd8 @@ -32,6 +33,7 @@ endmodule  EOT  equiv_opt -assert -multiclock -map +/xilinx/cells_sim.v synth_xilinx -abc9 -dff -noiopad -noclkbuf  design -load postopt +select -assert-count 4 t:FD*  select -assert-count 4 c:fd3 c:fd4 c:fd7 c:fd8 @@ -54,6 +56,6 @@ logger -expect warning "Module 'FDSE' contains a \$_DFF_P_ cell .*" 1  logger -expect warning "Module '\$paramod\\FDSE_1\\INIT=1' contains a \$_DFF_N_ cell .*" 1  equiv_opt -assert -multiclock -map +/xilinx/cells_sim.v synth_xilinx -abc9 -dff -noiopad -noclkbuf  design -load postopt -#select -assert-count 4 c:fd3 c:fd4 c:fd7 c:fd8 +select -assert-count 8 t:FD*  logger -expect-no-warnings | 
