diff options
Diffstat (limited to 'passes/techmap')
| -rw-r--r-- | passes/techmap/abc9.cc | 47 | ||||
| -rw-r--r-- | passes/techmap/shregmap.cc | 179 | 
2 files changed, 13 insertions, 213 deletions
| diff --git a/passes/techmap/abc9.cc b/passes/techmap/abc9.cc index 84cb2c04f..968c68b70 100644 --- a/passes/techmap/abc9.cc +++ b/passes/techmap/abc9.cc @@ -76,8 +76,7 @@ inline std::string remap_name(RTLIL::IdString abc_name)  	return stringf("$abc$%d$%s", map_autoidx, abc_name.c_str()+1);  } -void handle_loops(RTLIL::Design *design, -		const dict<IdString,pool<IdString>> &scc_break_inputs) +void handle_loops(RTLIL::Design *design)  {  	Pass::call(design, "scc -set_attr abc_scc_id {}"); @@ -114,30 +113,6 @@ void handle_loops(RTLIL::Design *design,  			}  			cell->attributes.erase(it);  		} - -		auto jt = scc_break_inputs.find(cell->type); -		if (jt != scc_break_inputs.end()) -			for (auto port_name : jt->second) { -				RTLIL::SigSpec sig; -				auto &rhs = cell->connections_.at(port_name); -				for (auto b : rhs) { -					Wire *w = b.wire; -					if (!w) continue; -					w->port_output = true; -					w->set_bool_attribute(ID(abc_scc_break)); -					w = module->wire(stringf("%s.abci", w->name.c_str())); -					if (!w) { -						w = module->addWire(stringf("%s.abci", b.wire->name.c_str()), GetSize(b.wire)); -						w->port_input = true; -					} -					else { -						log_assert(b.offset < GetSize(w)); -						log_assert(w->port_input); -					} -					sig.append(RTLIL::SigBit(w, b.offset)); -				} -				rhs = sig; -			}  	}  	module->fixup_ports(); @@ -272,8 +247,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri  		bool cleanup, vector<int> lut_costs, bool dff_mode, std::string clk_str,  		bool /*keepff*/, std::string delay_target, std::string /*lutin_shared*/, bool fast_mode,  		bool show_tempdir, std::string box_file, std::string lut_file, -		std::string wire_delay, const dict<int,IdString> &box_lookup, -		const dict<IdString,pool<IdString>> &scc_break_inputs +		std::string wire_delay, const dict<int,IdString> &box_lookup  )  {  	module = current_module; @@ -413,7 +387,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri  		RTLIL::Selection& sel = design->selection_stack.back();  		sel.select(module); -		handle_loops(design, scc_break_inputs); +		handle_loops(design);  		Pass::call(design, "aigmap"); @@ -1067,7 +1041,6 @@ struct Abc9Pass : public Pass {  		extra_args(args, argidx, design);  		dict<int,IdString> box_lookup; -		dict<IdString,pool<IdString>> scc_break_inputs;  		for (auto m : design->modules()) {  			auto it = m->attributes.find(ID(abc_box_id));  			if (it == m->attributes.end()) @@ -1085,17 +1058,13 @@ struct Abc9Pass : public Pass {  			for (auto p : m->ports) {  				auto w = m->wire(p);  				log_assert(w); -				if (w->port_input) { -					if (w->attributes.count(ID(abc_scc_break))) -						scc_break_inputs[m->name].insert(p); -					if (w->attributes.count(ID(abc_carry))) { +				if (w->attributes.count(ID(abc_carry))) { +					if (w->port_input) {  						if (carry_in)  							log_error("Module '%s' contains more than one 'abc_carry' input port.\n", log_id(m));  						carry_in = w;  					} -				} -				if (w->port_output) { -					if (w->attributes.count(ID(abc_carry))) { +					else if (w->port_output) {  						if (carry_out)  							log_error("Module '%s' contains more than one 'abc_carry' input port.\n", log_id(m));  						carry_out = w; @@ -1147,7 +1116,7 @@ struct Abc9Pass : public Pass {  			if (!dff_mode || !clk_str.empty()) {  				abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, dff_mode, clk_str, keepff,  						delay_target, lutin_shared, fast_mode, show_tempdir, -						box_file, lut_file, wire_delay, box_lookup, scc_break_inputs); +						box_file, lut_file, wire_delay, box_lookup);  				continue;  			} @@ -1293,7 +1262,7 @@ struct Abc9Pass : public Pass {  				en_sig = assign_map(std::get<3>(it.first));  				abc9_module(design, mod, script_file, exe_file, cleanup, lut_costs, !clk_sig.empty(), "$",  						keepff, delay_target, lutin_shared, fast_mode, show_tempdir, -						box_file, lut_file, wire_delay, box_lookup, scc_break_inputs); +						box_file, lut_file, wire_delay, box_lookup);  				assign_map.set(mod);  			}  		} diff --git a/passes/techmap/shregmap.cc b/passes/techmap/shregmap.cc index 5e298d8dd..9da69e8ba 100644 --- a/passes/techmap/shregmap.cc +++ b/passes/techmap/shregmap.cc @@ -26,9 +26,7 @@ PRIVATE_NAMESPACE_BEGIN  struct ShregmapTech  {  	virtual ~ShregmapTech() { } -	virtual void init(const Module * /*module*/, const SigMap &/*sigmap*/) {} -	virtual void non_chain_user(const SigBit &/*bit*/, const Cell* /*cell*/, IdString /*port*/) {} -	virtual bool analyze(vector<int> &taps, const vector<SigBit> &qbits) = 0; +	virtual bool analyze(vector<int> &taps) = 0;  	virtual bool fixup(Cell *cell, dict<int, SigBit> &taps) = 0;  }; @@ -56,7 +54,7 @@ struct ShregmapOptions  struct ShregmapTechGreenpak4 : ShregmapTech  { -	bool analyze(vector<int> &taps, const vector<SigBit> &/*qbits*/) +	bool analyze(vector<int> &taps)  	{  		if (GetSize(taps) > 2 && taps[0] == 0 && taps[2] < 17) {  			taps.clear(); @@ -93,155 +91,6 @@ struct ShregmapTechGreenpak4 : ShregmapTech  	}  }; -struct ShregmapTechXilinx7 : ShregmapTech -{ -	dict<SigBit, std::tuple<Cell*,int,int>> sigbit_to_shiftx_offset; -	const ShregmapOptions &opts; - -	ShregmapTechXilinx7(const ShregmapOptions &opts) : opts(opts) {} - -	virtual void init(const Module* module, const SigMap &sigmap) override -	{ -		for (const auto &i : module->cells_) { -			auto cell = i.second; -			if (cell->type == ID($shiftx)) { -				if (cell->getParam(ID(Y_WIDTH)) != 1) continue; -				int j = 0; -				for (auto bit : sigmap(cell->getPort(ID::A))) -					sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, j++, 0); -				log_assert(j == cell->getParam(ID(A_WIDTH)).as_int()); -			} -			else if (cell->type == ID($mux)) { -				int j = 0; -				for (auto bit : sigmap(cell->getPort(ID::A))) -					sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 0, j++); -				j = 0; -				for (auto bit : sigmap(cell->getPort(ID::B))) -					sigbit_to_shiftx_offset[bit] = std::make_tuple(cell, 1, j++); -			} -		} -	} - -	virtual void non_chain_user(const SigBit &bit, const Cell *cell, IdString port) override -	{ -		auto it = sigbit_to_shiftx_offset.find(bit); -		if (it == sigbit_to_shiftx_offset.end()) -			return; -		if (cell) { -			if (cell->type == ID($shiftx) && port == ID::A) -				return; -			if (cell->type == ID($mux) && port.in(ID::A, ID::B)) -				return; -		} -		sigbit_to_shiftx_offset.erase(it); -	} - -	virtual bool analyze(vector<int> &taps, const vector<SigBit> &qbits) override -	{ -		if (GetSize(taps) == 1) -			return taps[0] >= opts.minlen-1 && sigbit_to_shiftx_offset.count(qbits[0]); - -		if (taps.back() < opts.minlen-1) -			return false; - -		Cell *shiftx = nullptr; -		int group = 0; -		for (int i = 0; i < GetSize(taps); ++i) { -			auto it = sigbit_to_shiftx_offset.find(qbits[i]); -			if (it == sigbit_to_shiftx_offset.end()) -				return false; - -			// Check taps are sequential -			if (i != taps[i]) -				return false; -			// Check taps are not connected to a shift register, -			// or sequential to the same shift register -			if (i == 0) { -				int offset; -				std::tie(shiftx,offset,group) = it->second; -				if (offset != i) -					return false; -			} -			else { -				Cell *shiftx_ = std::get<0>(it->second); -				if (shiftx_ != shiftx) -					return false; -				int offset = std::get<1>(it->second); -				if (offset != i) -					return false; -				int group_ = std::get<2>(it->second); -				if (group_ != group) -					return false; -			} -		} -		log_assert(shiftx); - -		// Only map if $shiftx exclusively covers the shift register -		if (shiftx->type == ID($shiftx)) { -			if (GetSize(taps) > shiftx->getParam(ID(A_WIDTH)).as_int()) -				return false; -			// Due to padding the most significant bits of A may be 1'bx, -			//   and if so, discount them -			if (GetSize(taps) < shiftx->getParam(ID(A_WIDTH)).as_int()) { -				const SigSpec A = shiftx->getPort(ID::A); -				const int A_width = shiftx->getParam(ID(A_WIDTH)).as_int(); -				for (int i = GetSize(taps); i < A_width; ++i) -					if (A[i] != RTLIL::Sx) return false; -			} -			else if (GetSize(taps) != shiftx->getParam(ID(A_WIDTH)).as_int()) -				return false; -		} -		else if (shiftx->type == ID($mux)) { -			if (GetSize(taps) != 2) -				return false; -		} -		else log_abort(); - -		return true; -	} - -	virtual bool fixup(Cell *cell, dict<int, SigBit> &taps) override -	{ -		const auto &tap = *taps.begin(); -		auto bit = tap.second; - -		auto it = sigbit_to_shiftx_offset.find(bit); -		log_assert(it != sigbit_to_shiftx_offset.end()); - -		auto newcell = cell->module->addCell(NEW_ID, ID($__XILINX_SHREG_)); -		newcell->set_src_attribute(cell->get_src_attribute()); -		newcell->setParam(ID(DEPTH), cell->getParam(ID(DEPTH))); -		newcell->setParam(ID(INIT), cell->getParam(ID(INIT))); -		newcell->setParam(ID(CLKPOL), cell->getParam(ID(CLKPOL))); -		newcell->setParam(ID(ENPOL), cell->getParam(ID(ENPOL))); - -		newcell->setPort(ID(C), cell->getPort(ID(C))); -		newcell->setPort(ID(D), cell->getPort(ID(D))); -		if (cell->hasPort(ID(E))) -			newcell->setPort(ID(E), cell->getPort(ID(E))); - -		Cell* shiftx = std::get<0>(it->second); -		RTLIL::SigSpec l_wire, q_wire; -		if (shiftx->type == ID($shiftx)) { -			l_wire = shiftx->getPort(ID::B); -			q_wire = shiftx->getPort(ID::Y); -			shiftx->setPort(ID::Y, cell->module->addWire(NEW_ID)); -		} -		else if (shiftx->type == ID($mux)) { -			l_wire = shiftx->getPort(ID(S)); -			q_wire = shiftx->getPort(ID::Y); -			shiftx->setPort(ID::Y, cell->module->addWire(NEW_ID)); -		} -		else log_abort(); - -		newcell->setPort(ID(Q), q_wire); -		newcell->setPort(ID(L), l_wire); - -		return false; -	} -}; - -  struct ShregmapWorker  {  	Module *module; @@ -264,10 +113,8 @@ struct ShregmapWorker  		for (auto wire : module->wires())  		{  			if (wire->port_output || wire->get_bool_attribute(ID::keep)) { -				for (auto bit : sigmap(wire)) { +				for (auto bit : sigmap(wire))  					sigbit_with_non_chain_users.insert(bit); -					if (opts.tech) opts.tech->non_chain_user(bit, nullptr, {}); -				}  			}  			if (wire->attributes.count(ID(init))) { @@ -317,10 +164,8 @@ struct ShregmapWorker  			for (auto conn : cell->connections())  				if (cell->input(conn.first)) -					for (auto bit : sigmap(conn.second)) { +					for (auto bit : sigmap(conn.second))  						sigbit_with_non_chain_users.insert(bit); -						if (opts.tech) opts.tech->non_chain_user(bit, cell, conn.first); -					}  		}  	} @@ -425,7 +270,7 @@ struct ShregmapWorker  					if (taps.empty() || taps.back() < depth-1)  						taps.push_back(depth-1); -					if (opts.tech->analyze(taps, qbits)) +					if (opts.tech->analyze(taps))  						break;  					taps.pop_back(); @@ -544,9 +389,6 @@ struct ShregmapWorker  	ShregmapWorker(Module *module, const ShregmapOptions &opts) :  			module(module), sigmap(module), opts(opts), dff_count(0), shreg_count(0)  	{ -		if (opts.tech) -			opts.tech->init(module, sigmap); -  		make_sigbit_chain_next_prev();  		find_chain_start_cells(); @@ -617,11 +459,6 @@ struct ShregmapPass : public Pass {  		log("\n");  		log("    -tech greenpak4\n");  		log("        map to greenpak4 shift registers.\n"); -		log("        this option also implies -clkpol pos -zinit\n"); -		log("\n"); -		log("    -tech xilinx\n"); -		log("        map to xilinx dynamic-length shift registers.\n"); -		log("        this option also implies -params -init\n");  		log("\n");  	}  	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE @@ -676,12 +513,6 @@ struct ShregmapPass : public Pass {  					clkpol = "pos";  					opts.zinit = true;  					opts.tech = new ShregmapTechGreenpak4; -				} -				else if (tech == "xilinx") { -					opts.init = true; -					opts.params = true; -					enpol = "any_or_none"; -					opts.tech = new ShregmapTechXilinx7(opts);  				} else {  					argidx--;  					break; | 
