diff options
| author | Eddie Hung <eddie@fpgeh.com> | 2020-01-10 14:49:52 -0800 | 
|---|---|---|
| committer | Eddie Hung <eddie@fpgeh.com> | 2020-01-10 14:49:52 -0800 | 
| commit | 475d983676a42e57a104aaf5e72462d704c0c3aa (patch) | |
| tree | bcd804d13c1809617ce5b3b03a29e39deb482b37 | |
| parent | e0af812180528c45e79291209e2e3726c98b80ae (diff) | |
| download | yosys-475d983676a42e57a104aaf5e72462d704c0c3aa.tar.gz yosys-475d983676a42e57a104aaf5e72462d704c0c3aa.tar.bz2 yosys-475d983676a42e57a104aaf5e72462d704c0c3aa.zip | |
abc9_ops -prep_times: generate flop boxes from abc9_required attr
| -rw-r--r-- | passes/techmap/abc9_ops.cc | 84 | ||||
| -rw-r--r-- | techlibs/xilinx/abc9_xc7.box | 61 | 
2 files changed, 67 insertions, 78 deletions
| diff --git a/passes/techmap/abc9_ops.cc b/passes/techmap/abc9_ops.cc index 14b3f6c43..918afd284 100644 --- a/passes/techmap/abc9_ops.cc +++ b/passes/techmap/abc9_ops.cc @@ -39,9 +39,13 @@ void check(RTLIL::Design *design)  {  	dict<IdString,IdString> box_lookup;  	for (auto m : design->modules()) { +		auto flop = m->get_bool_attribute(ID(abc9_flop));  		auto it = m->attributes.find(ID(abc9_box_id)); -		if (it == m->attributes.end()) +		if (it == m->attributes.end()) { +			if (flop) +				log_error("Module '%s' contains (* abc9_flop *) but not (* abc9_box_id=<int> *).\n", log_id(m));  			continue; +		}  		if (m->name.begins_with("$paramod"))  			continue;  		auto id = it->second.as_int(); @@ -59,21 +63,31 @@ void check(RTLIL::Design *design)  			if (w->get_bool_attribute("\\abc9_carry")) {  				if (w->port_input) {  					if (carry_in != IdString()) -						log_error("Module '%s' contains more than one 'abc9_carry' input port.\n", log_id(m)); +						log_error("Module '%s' contains more than one (* abc9_carry *) input port.\n", log_id(m));  					carry_in = port_name;  				}  				if (w->port_output) {  					if (carry_out != IdString()) -						log_error("Module '%s' contains more than one 'abc9_carry' output port.\n", log_id(m)); +						log_error("Module '%s' contains more than one (* abc9_carry *) output port.\n", log_id(m));  					carry_out = port_name;  				}  			}  		}  		if (carry_in != IdString() && carry_out == IdString()) -			log_error("Module '%s' contains an 'abc9_carry' input port but no output port.\n", log_id(m)); +			log_error("Module '%s' contains an (* abc9_carry *) input port but no output port.\n", log_id(m));  		if (carry_in == IdString() && carry_out != IdString()) -			log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(m)); +			log_error("Module '%s' contains an (* abc9_carry *) output port but no input port.\n", log_id(m)); + +		if (flop) { +			int num_outputs = 0; +			for (auto port_name : m->ports) { +				auto wire = m->wire(port_name); +				if (wire->port_output) num_outputs++; +			} +			if (num_outputs != 1) +				log_error("Module '%s' with (* abc_flop *) has %d outputs (expect 1).\n", log_id(m), num_outputs); +		}  	}  } @@ -464,12 +478,10 @@ void prep_holes(RTLIL::Module *module, bool dff)  void prep_times(RTLIL::Design *design)  {  	std::set<int> delays; +	pool<Module*> flops;  	std::vector<Cell*> boxes;  	std::map<int,std::vector<int>> requireds;  	for (auto module : design->selected_modules()) { -		if (module->get_bool_attribute("\\abc9_holes")) -			continue; -  		if (module->processes.size() > 0) {  			log("Skipping module %s as it contains processes.\n", log_id(module));  			continue; @@ -485,10 +497,13 @@ void prep_times(RTLIL::Design *design)  				continue;  			if (!inst_module->get_blackbox_attribute())  				continue; -			// Only flop boxes are not combinatorial and may have required times, -			//   however those times are captured by this flop box, no need to -			//   add delay boxes -			if (cell->attributes.count(ID(abc9_box_id))) +			if (inst_module->get_bool_attribute(ID(abc9_flop))) { +				flops.insert(inst_module); +				continue; +			} +			// All remaining boxes are combinatorial and cannot +			//   contain a required time +			if (inst_module->attributes.count(ID(abc9_box_id)))  				continue;  			boxes.emplace_back(cell);  		} @@ -536,15 +551,48 @@ void prep_times(RTLIL::Design *design)  		std::stringstream ss;  		bool first = true; -		for (auto d : delays) -			if (first) { +		for (auto d : delays) { +			if (first)  				first = false; -				ss << d; -			}  			else -				ss << " " << d; +				ss << " "; +			ss << d; +		}  		module->attributes[ID(abc9_delays)] = ss.str();  	} + +	std::stringstream ss; +	for (auto flop_module : flops) { +		// Skip parameterised flop_modules for now (since we do not +		//   dynamically generate the abc9_box_id) +		if (flop_module->name.begins_with("$paramod")) +			continue; + +		int num_inputs = 0, num_outputs = 0; +		for (auto port_name : flop_module->ports) { +			auto wire = flop_module->wire(port_name); +			if (wire->port_input) num_inputs++; +			if (wire->port_output) num_outputs++; +		} +		log_assert(num_outputs == 1); + +		ss << log_id(flop_module) << " " << flop_module->attributes.at(ID(abc9_box_id)).as_int(); +		ss << " 1 " << num_inputs+1 << " " << num_outputs << std::endl; +		bool first = true; +		for (auto port_name : flop_module->ports) { +			auto wire = flop_module->wire(port_name); +			if (!wire->port_input) +				continue; +			if (first) +				first = false; +			else +				ss << " "; +			ss << wire->attributes.at("\\abc9_required", 0).as_int(); +		} +		// Last input is 'abc9_ff.Q' +		ss << " 0" << std::endl << std::endl; +	} +	design->scratchpad_set_string("abc9_ops.box.flops", ss.str());  }  void write_box(RTLIL::Module *module, const std::string &src, const std::string &dst) { @@ -559,6 +607,8 @@ void write_box(RTLIL::Module *module, const std::string &src, const std::string  		ifs.close();  	} +	ofs << module->design->scratchpad_get_string("abc9_ops.box.flops"); +  	auto it = module->attributes.find(ID(abc9_delays));  	if (it != module->attributes.end()) {  		for (const auto &tok : split_tokens(it->second.decode_string())) { diff --git a/techlibs/xilinx/abc9_xc7.box b/techlibs/xilinx/abc9_xc7.box index 13f4f0e61..48d492801 100644 --- a/techlibs/xilinx/abc9_xc7.box +++ b/techlibs/xilinx/abc9_xc7.box @@ -62,67 +62,6 @@ $__ABC9_ASYNC1 1001 1   2   1  #A S  0  764 # Y -# Flop boxes: -# * Max delays from https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L237-L251 -#                   https://github.com/SymbiFlow/prjxray-db/blob/23c8b0851f979f0799318eaca90174413a46b257/artix7/timings/slicel.sdf#L265-L277 -# * Exception: $abc9_currQ is a special input (located last) necessary for clock-enable functionality - -# Box 1100 : FDRE -# name ID   w/b ins outs -FDRE   1100 1   5   1 -#C CE  D   R   $abc9_currQ -#0 109 -46 404 0 -0 109 0   404 0 # Q (-46ps Tsu clamped to 0) - -# Box 1101 : FDRE_1 -# name ID   w/b ins outs -FDRE_1 1101 1   5   1 -#C CE  D   R   $abc9_currQ -#0 109 -46 404 0 -0 109 0   404 0 # Q (-46ps Tsu clamped to 0) - -# Box 1102 : FDSE -# name ID   w/b ins outs -FDSE   1102 1   5   1 -#C CE  D   R   $abc9_currQ -#0 109 -46 404 0 -0 109 0   404 0 # Q (-46ps Tsu clamped to 0) - -# Box 1103 : FDSE_1 -# name ID   w/b ins outs -FDSE_1 1103 1   5   1 -#C CE  D   R   $abc9_currQ -#0 109 -46 404 0 -0 109 0   404 0 # Q (-46ps Tsu clamped to 0) - -# Box 1104 : FDCE -# name ID   w/b ins outs -FDCE   1104 1   5   1 -#C CE  CLR D   $abc9_currQ -#0 109 764 -46 0 -0 109 764 0   0 # Q (-46ps Tsu clamped to 0) - -# Box 1105 : FDCE_1 -# name ID   w/b ins outs -FDCE_1 1105 1   5   1 -#C CE  CLR D   $abc9_currQ -#0 109 764 -46 0 -0 109 764 0   0 # Q (-46ps Tsu clamped to 0) - -# Box 1106 : FDPE -# name ID   w/b ins outs -FDPE   1106 1   5   1 -#C CE  D   PRE $abc9_currQ -#0 109 -46 764 0 -0 109 0   764 0 # Q (-46ps Tsu clamped to 0) - -# Box 1107 : FDPE_1 -# name ID   w/b ins outs -FDPE_1 1107 1   5   1 -#C CE  D   PRE $abc9_currQ -#0 109 -46 764 0 -0 109 0   764 0 # Q (-46ps Tsu clamped to 0) -  # Box 2000 : $__ABC9_LUT6  #            (private cell to emulate async behaviour of LUTRAMs)  # SLICEM/A6LUT | 
