mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-30 19:22:31 +00:00 
			
		
		
		
	Merge branch 'xaig' into xc7mux
This commit is contained in:
		
						commit
						538592067e
					
				
					 9 changed files with 246 additions and 100 deletions
				
			
		|  | @ -312,10 +312,10 @@ Verilog Attributes and non-standard features | ||||||
|   passes to identify input and output ports of cells. The Verilog backend |   passes to identify input and output ports of cells. The Verilog backend | ||||||
|   also does not output blackbox modules on default. |   also does not output blackbox modules on default. | ||||||
| 
 | 
 | ||||||
| - The ``dynports'' attribute is used by the Verilog front-end to mark modules | - The ``dynports`` attribute is used by the Verilog front-end to mark modules | ||||||
|   that have ports with a width that depends on a parameter. |   that have ports with a width that depends on a parameter. | ||||||
| 
 | 
 | ||||||
| - The ``hdlname'' attribute is used by some passes to document the original | - The ``hdlname`` attribute is used by some passes to document the original | ||||||
|   (HDL) name of a module when renaming a module. |   (HDL) name of a module when renaming a module. | ||||||
| 
 | 
 | ||||||
| - The ``keep`` attribute on cells and wires is used to mark objects that should | - The ``keep`` attribute on cells and wires is used to mark objects that should | ||||||
|  |  | ||||||
|  | @ -47,7 +47,7 @@ struct XAigerWriter | ||||||
| 	dict<SigBit, SigBit> not_map, ff_map, alias_map; | 	dict<SigBit, SigBit> not_map, ff_map, alias_map; | ||||||
| 	dict<SigBit, pair<SigBit, SigBit>> and_map; | 	dict<SigBit, pair<SigBit, SigBit>> and_map; | ||||||
| 	pool<SigBit> initstate_bits; | 	pool<SigBit> initstate_bits; | ||||||
| 	pool<SigBit> ci_bits, co_bits; | 	vector<std::pair<SigBit,int>> ci_bits, co_bits; | ||||||
| 	dict<IdString, unsigned> type_map; | 	dict<IdString, unsigned> type_map; | ||||||
| 
 | 
 | ||||||
| 	vector<pair<int, int>> aig_gates; | 	vector<pair<int, int>> aig_gates; | ||||||
|  | @ -61,6 +61,8 @@ struct XAigerWriter | ||||||
| 	dict<SigBit, int> init_inputs; | 	dict<SigBit, int> init_inputs; | ||||||
| 	int initstate_ff = 0; | 	int initstate_ff = 0; | ||||||
| 
 | 
 | ||||||
|  | 	vector<Cell*> box_list; | ||||||
|  | 
 | ||||||
| 	int mkgate(int a0, int a1) | 	int mkgate(int a0, int a1) | ||||||
| 	{ | 	{ | ||||||
| 		aig_m++, aig_a++; | 		aig_m++, aig_a++; | ||||||
|  | @ -211,38 +213,38 @@ struct XAigerWriter | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			for (const auto &c : cell->connections()) { | 			for (const auto &c : cell->connections()) { | ||||||
| 				if (c.second.is_fully_const()) continue; | 				/*if (c.second.is_fully_const()) continue;*/ | ||||||
| 				for (auto b : c.second.bits()) { | 				for (auto b : c.second.bits()) { | ||||||
| 					Wire *w = b.wire; |  | ||||||
| 					if (!w) continue; |  | ||||||
| 					auto is_input = cell->input(c.first); | 					auto is_input = cell->input(c.first); | ||||||
| 					auto is_output = cell->output(c.first); | 					auto is_output = cell->output(c.first); | ||||||
| 					log_assert(is_input || is_output); | 					log_assert(is_input || is_output); | ||||||
| 					if (is_input) { | 					if (is_input) { | ||||||
| 						if (!w->port_input) { | 						/*if (!w->port_input)*/ { | ||||||
| 							SigBit I = sigmap(b); | 							SigBit I = sigmap(b); | ||||||
| 							if (I != b) | 							if (I != b) | ||||||
| 								alias_map[b] = I; | 								alias_map[b] = I; | ||||||
| 							if (!output_bits.count(b)) | 							/*if (!output_bits.count(b))*/ | ||||||
| 								co_bits.insert(b); | 								co_bits.emplace_back(b, 0); | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
| 					if (is_output) { | 					if (is_output) { | ||||||
| 						SigBit O = sigmap(b); | 						SigBit O = sigmap(b); | ||||||
| 						if (!input_bits.count(O)) | 						/*if (!input_bits.count(O))*/ | ||||||
| 							ci_bits.insert(O); | 							ci_bits.emplace_back(O, 0); | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 				if (!type_map.count(cell->type)) | 				if (!type_map.count(cell->type)) | ||||||
| 					type_map[cell->type] = type_map.size()+1; | 					type_map[cell->type] = type_map.size()+1; | ||||||
| 			} | 			} | ||||||
| 			//log_error("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell));
 | 
 | ||||||
|  | 			box_list.emplace_back(cell); | ||||||
|  | 			//log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell));
 | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (auto bit : input_bits) { | 		for (auto bit : input_bits) { | ||||||
| 			RTLIL::Wire *wire = bit.wire; | 			RTLIL::Wire *wire = bit.wire; | ||||||
| 			// If encountering an inout port, then create a new wire with $inout.out
 | 			// If encountering an inout port, then create a new wire with $inout.out
 | ||||||
| 			// suffix, make it a CO driven by the existing inout, and inherit existing
 | 			// suffix, make it a PO driven by the existing inout, and inherit existing
 | ||||||
| 			// inout's drivers
 | 			// inout's drivers
 | ||||||
| 			if (wire->port_input && wire->port_output && !undriven_bits.count(bit)) { | 			if (wire->port_input && wire->port_output && !undriven_bits.count(bit)) { | ||||||
| 				RTLIL::Wire *new_wire = module->wire(wire->name.str() + "$inout.out"); | 				RTLIL::Wire *new_wire = module->wire(wire->name.str() + "$inout.out"); | ||||||
|  | @ -256,22 +258,22 @@ struct XAigerWriter | ||||||
| 					and_map[new_bit] = and_map.at(bit); | 					and_map[new_bit] = and_map.at(bit); | ||||||
| 				else if (alias_map.count(bit)) | 				else if (alias_map.count(bit)) | ||||||
| 					alias_map[new_bit] = alias_map.at(bit); | 					alias_map[new_bit] = alias_map.at(bit); | ||||||
| 				co_bits.insert(new_bit); | 				output_bits.insert(new_bit); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// Do some CI/CO post-processing:
 | 		// Do some CI/CO post-processing:
 | ||||||
| 		// Erase all POs and COs that are undriven
 | 		// Erase all POs and COs that are undriven
 | ||||||
| 		for (auto bit : undriven_bits) { | 		for (auto bit : undriven_bits) { | ||||||
| 			co_bits.erase(bit); | 			//co_bits.erase(bit);
 | ||||||
| 			output_bits.erase(bit); | 			output_bits.erase(bit); | ||||||
| 		} | 		} | ||||||
| 		// Erase all CIs that are also COs
 | 		// Erase all CIs that are also COs
 | ||||||
| 		for (auto bit : co_bits) | 		//for (auto bit : co_bits)
 | ||||||
| 			ci_bits.erase(bit); | 		//	ci_bits.erase(bit);
 | ||||||
| 		// CIs cannot be undriven
 | 		// CIs cannot be undriven
 | ||||||
| 		for (auto bit : ci_bits) | 		for (const auto &c : ci_bits) | ||||||
| 			undriven_bits.erase(bit); | 			undriven_bits.erase(c.first); | ||||||
| 
 | 
 | ||||||
| 		for (auto bit : unused_bits) | 		for (auto bit : unused_bits) | ||||||
| 			undriven_bits.erase(bit); | 			undriven_bits.erase(bit); | ||||||
|  | @ -295,12 +297,13 @@ struct XAigerWriter | ||||||
| 		aig_map[State::S0] = 0; | 		aig_map[State::S0] = 0; | ||||||
| 		aig_map[State::S1] = 1; | 		aig_map[State::S1] = 1; | ||||||
| 
 | 
 | ||||||
| 		for (auto bit : input_bits) { | 		for (auto &c : ci_bits) { | ||||||
| 			aig_m++, aig_i++; | 			aig_m++, aig_i++; | ||||||
| 			aig_map[bit] = 2*aig_m; | 			c.second = 2*aig_m; | ||||||
|  | 			aig_map[c.first] = c.second; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (auto bit : ci_bits) { | 		for (auto bit : input_bits) { | ||||||
| 			aig_m++, aig_i++; | 			aig_m++, aig_i++; | ||||||
| 			aig_map[bit] = 2*aig_m; | 			aig_map[bit] = 2*aig_m; | ||||||
| 		} | 		} | ||||||
|  | @ -365,19 +368,19 @@ struct XAigerWriter | ||||||
| 		if (!initstate_bits.empty() || !init_inputs.empty()) | 		if (!initstate_bits.empty() || !init_inputs.empty()) | ||||||
| 			aig_latchin.push_back(1); | 			aig_latchin.push_back(1); | ||||||
| 
 | 
 | ||||||
| 		for (auto bit : co_bits) { | 		for (auto &c : co_bits) { | ||||||
| 			aig_o++; | 			RTLIL::SigBit bit = c.first; | ||||||
| 			ordered_outputs[bit] = aig_o-1; | 			c.second = aig_o++; | ||||||
|  | 			ordered_outputs[bit] = c.second; | ||||||
| 			aig_outputs.push_back(bit2aig(bit)); | 			aig_outputs.push_back(bit2aig(bit)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		for (auto bit : output_bits) { | 		for (auto bit : output_bits) { | ||||||
| 			aig_o++; | 			ordered_outputs[bit] = aig_o++; | ||||||
| 			ordered_outputs[bit] = aig_o-1; |  | ||||||
| 			aig_outputs.push_back(bit2aig(bit)); | 			aig_outputs.push_back(bit2aig(bit)); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (omode && output_bits.empty() && co_bits.empty()) { | 		if (omode && output_bits.empty()) { | ||||||
| 			aig_o++; | 			aig_o++; | ||||||
| 			aig_outputs.push_back(0); | 			aig_outputs.push_back(0); | ||||||
| 		} | 		} | ||||||
|  | @ -480,7 +483,7 @@ struct XAigerWriter | ||||||
| 				for (int i = 0; i < GetSize(wire); i++) | 				for (int i = 0; i < GetSize(wire); i++) | ||||||
| 				{ | 				{ | ||||||
| 					RTLIL::SigBit b(wire, i); | 					RTLIL::SigBit b(wire, i); | ||||||
| 					if (input_bits.count(b) || ci_bits.count(b)) { | 					if (input_bits.count(b)) { | ||||||
| 						int a = aig_map.at(sig[i]); | 						int a = aig_map.at(sig[i]); | ||||||
| 						log_assert((a & 1) == 0); | 						log_assert((a & 1) == 0); | ||||||
| 						if (GetSize(wire) != 1) | 						if (GetSize(wire) != 1) | ||||||
|  | @ -489,7 +492,7 @@ struct XAigerWriter | ||||||
| 							symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("%s", log_id(wire))); | 							symbols[stringf("i%d", (a >> 1)-1)].push_back(stringf("%s", log_id(wire))); | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					if (output_bits.count(b) || co_bits.count(b)) { | 					if (output_bits.count(b)) { | ||||||
| 						int o = ordered_outputs.at(b); | 						int o = ordered_outputs.at(b); | ||||||
| 						output_seen = !miter_mode; | 						output_seen = !miter_mode; | ||||||
| 						if (GetSize(wire) != 1) | 						if (GetSize(wire) != 1) | ||||||
|  | @ -532,7 +535,53 @@ struct XAigerWriter | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		f << stringf("c\nGenerated by %s\n", yosys_version_str); | 		f << "c"; | ||||||
|  | 
 | ||||||
|  | 		std::stringstream h_buffer; | ||||||
|  | 		auto write_h_buffer = [&h_buffer](int i32) { | ||||||
|  | 			// TODO: Don't assume we're on little endian
 | ||||||
|  | #ifdef _WIN32 | ||||||
|  | 			int i32_be = _byteswap_ulong(i32); | ||||||
|  | #else | ||||||
|  | 			int i32_be = __builtin_bswap32(i32); | ||||||
|  | #endif | ||||||
|  | 			h_buffer.write(reinterpret_cast<const char*>(&i32_be), sizeof(i32_be)); | ||||||
|  | 		}; | ||||||
|  | 		int num_outputs = output_bits.size(); | ||||||
|  | 		if (omode && num_outputs == 0) | ||||||
|  | 			num_outputs = 1; | ||||||
|  | 		write_h_buffer(1); | ||||||
|  | 		write_h_buffer(input_bits.size() + ci_bits.size()); | ||||||
|  | 		write_h_buffer(num_outputs + co_bits.size()); | ||||||
|  | 		write_h_buffer(input_bits.size()); | ||||||
|  | 		write_h_buffer(num_outputs); | ||||||
|  | 		write_h_buffer(box_list.size()); | ||||||
|  | 		int box_id = 0; | ||||||
|  | 		for (auto cell : box_list) { | ||||||
|  | 			int box_inputs = 0, box_outputs = 0; | ||||||
|  | 			for (const auto &c : cell->connections()) { | ||||||
|  | 				if (cell->input(c.first)) | ||||||
|  | 					box_inputs += c.second.size(); | ||||||
|  | 				if (cell->output(c.first)) | ||||||
|  | 					box_outputs += c.second.size(); | ||||||
|  | 			} | ||||||
|  | 			write_h_buffer(box_inputs); | ||||||
|  | 			write_h_buffer(box_outputs); | ||||||
|  | 			write_h_buffer(box_id++); | ||||||
|  | 			write_h_buffer(0 /* OldBoxNum */); | ||||||
|  | 		} | ||||||
|  | 		std::string h_buffer_str = h_buffer.str(); | ||||||
|  | 		// TODO: Don't assume we're on little endian
 | ||||||
|  | #ifdef _WIN32 | ||||||
|  | 		int h_buffer_size_be = _byteswap_ulong(h_buffer_str.size()); | ||||||
|  | #else | ||||||
|  | 		int h_buffer_size_be = __builtin_bswap32(h_buffer_str.size()); | ||||||
|  | #endif | ||||||
|  | 		f << "h"; | ||||||
|  | 		f.write(reinterpret_cast<const char*>(&h_buffer_size_be), sizeof(h_buffer_size_be)); | ||||||
|  | 		f.write(h_buffer_str.data(), h_buffer_str.size()); | ||||||
|  | 
 | ||||||
|  | 		f << stringf("Generated by %s\n", yosys_version_str); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	void write_map(std::ostream &f, bool verbose_map, bool omode) | 	void write_map(std::ostream &f, bool verbose_map, bool omode) | ||||||
|  | @ -553,14 +602,13 @@ struct XAigerWriter | ||||||
| 			for (int i = 0; i < GetSize(wire); i++) | 			for (int i = 0; i < GetSize(wire); i++) | ||||||
| 			{ | 			{ | ||||||
| 				RTLIL::SigBit b(wire, i); | 				RTLIL::SigBit b(wire, i); | ||||||
| 				if (input_bits.count(b) || ci_bits.count(b)) { | 				if (input_bits.count(b)) { | ||||||
| 					int a = aig_map.at(sig[i]); | 					int a = aig_map.at(sig[i]); | ||||||
| 					log_assert((a & 1) == 0); | 					log_assert((a & 1) == 0); | ||||||
| 					input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, i, log_id(wire)); | 					input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, i, log_id(wire)); | ||||||
| 					continue; |  | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				if (output_bits.count(b) || co_bits.count(b)) { | 				if (output_bits.count(b)) { | ||||||
| 					int o = ordered_outputs.at(b); | 					int o = ordered_outputs.at(b); | ||||||
| 					output_lines[o] += stringf("output %d %d %s\n", o, i, log_id(wire)); | 					output_lines[o] += stringf("output %d %d %s\n", o, i, log_id(wire)); | ||||||
| 					continue; | 					continue; | ||||||
|  | @ -592,6 +640,25 @@ struct XAigerWriter | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		for (const auto &c : ci_bits) { | ||||||
|  | 			RTLIL::SigBit b = c.first; | ||||||
|  | 			RTLIL::Wire *wire = b.wire; | ||||||
|  | 			int i = b.offset; | ||||||
|  | 			int a = c.second; | ||||||
|  | 			log_assert((a & 1) == 0); | ||||||
|  | 			input_lines[a] += stringf("input %d %d %s\n", (a >> 1)-1, i, log_id(wire)); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for (const auto &c : co_bits) { | ||||||
|  | 			RTLIL::SigBit b = c.first; | ||||||
|  | 			RTLIL::Wire *wire = b.wire; | ||||||
|  | 			int o = c.second; | ||||||
|  | 			if (wire) | ||||||
|  | 				output_lines[o] += stringf("output %d %d %s\n", o, b.offset, log_id(wire)); | ||||||
|  | 			else | ||||||
|  | 				output_lines[o] += stringf("output %d %d __const%d__\n", o, 0, b.data); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		input_lines.sort(); | 		input_lines.sort(); | ||||||
| 		for (auto &it : input_lines) | 		for (auto &it : input_lines) | ||||||
| 			f << it.second; | 			f << it.second; | ||||||
|  | @ -605,8 +672,8 @@ struct XAigerWriter | ||||||
| 		for (auto &it : output_lines) | 		for (auto &it : output_lines) | ||||||
| 			f << it.second; | 			f << it.second; | ||||||
| 		log_assert(output_lines.size() == output_bits.size() + co_bits.size()); | 		log_assert(output_lines.size() == output_bits.size() + co_bits.size()); | ||||||
| 		if (omode && output_lines.empty()) | 		if (omode && output_bits.empty()) | ||||||
| 			f << "output 0 0 __dummy_o__\n"; | 			f << "output " << output_lines.size() << " 0 __dummy_o__\n"; | ||||||
| 
 | 
 | ||||||
| 		latch_lines.sort(); | 		latch_lines.sort(); | ||||||
| 		for (auto &it : latch_lines) | 		for (auto &it : latch_lines) | ||||||
|  |  | ||||||
|  | @ -439,19 +439,37 @@ next_line: | ||||||
|         std::string type, symbol; |         std::string type, symbol; | ||||||
|         int variable, index; |         int variable, index; | ||||||
|         while (mf >> type >> variable >> index >> symbol) { |         while (mf >> type >> variable >> index >> symbol) { | ||||||
|             RTLIL::IdString escaped_symbol = RTLIL::escape_id(symbol); |             RTLIL::IdString escaped_s = RTLIL::escape_id(symbol); | ||||||
|             if (type == "input") { |             if (type == "input") { | ||||||
|                 log_assert(static_cast<unsigned>(variable) < inputs.size()); |                 log_assert(static_cast<unsigned>(variable) < inputs.size()); | ||||||
|                 RTLIL::Wire* wire = inputs[variable]; |                 RTLIL::Wire* wire = inputs[variable]; | ||||||
|                 log_assert(wire); |                 log_assert(wire); | ||||||
|                 log_assert(wire->port_input); |                 log_assert(wire->port_input); | ||||||
| 
 | 
 | ||||||
|                 if (index == 0) |                 if (index == 0) { | ||||||
|                     module->rename(wire, escaped_symbol); |                     // Cope with the fact that a CI might be identical
 | ||||||
|  |                     // to a PI (necessary due to ABC); in those cases
 | ||||||
|  |                     // simply connect the latter to the former
 | ||||||
|  |                     RTLIL::Wire* existing = module->wire(escaped_s); | ||||||
|  |                     if (!existing) | ||||||
|  |                         module->rename(wire, escaped_s); | ||||||
|  |                     else { | ||||||
|  |                         wire->port_input = false; | ||||||
|  |                         module->connect(wire, existing); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|                 else if (index > 0) { |                 else if (index > 0) { | ||||||
|                     module->rename(wire, stringf("%s[%d]", escaped_symbol.c_str(), index)); |                     std::string indexed_name = stringf("%s[%d]", escaped_s.c_str(), index); | ||||||
|                     if (wideports) |                     RTLIL::Wire* existing = module->wire(indexed_name); | ||||||
|                         wideports_cache[escaped_symbol] = std::max(wideports_cache[escaped_symbol], index); |                     if (!existing) { | ||||||
|  |                         module->rename(wire, indexed_name); | ||||||
|  |                         if (wideports) | ||||||
|  |                             wideports_cache[escaped_s] = std::max(wideports_cache[escaped_s], index); | ||||||
|  |                     } | ||||||
|  |                     else { | ||||||
|  |                         module->connect(wire, existing); | ||||||
|  |                         wire->port_input = false; | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             else if (type == "output") { |             else if (type == "output") { | ||||||
|  | @ -459,13 +477,55 @@ next_line: | ||||||
|                 RTLIL::Wire* wire = outputs[variable]; |                 RTLIL::Wire* wire = outputs[variable]; | ||||||
|                 log_assert(wire); |                 log_assert(wire); | ||||||
|                 log_assert(wire->port_output); |                 log_assert(wire->port_output); | ||||||
|  |                 if (escaped_s.in("\\__dummy_o__", "\\__const0__", "\\__const1__")) { | ||||||
|  |                     wire->port_output = false; | ||||||
|  |                     continue; | ||||||
|  |                 } | ||||||
| 
 | 
 | ||||||
|                 if (index == 0) |                 if (index == 0) { | ||||||
|                     module->rename(wire, escaped_symbol); |                     // Cope with the fact that a CO might be identical
 | ||||||
|  |                     // to a PO (necessary due to ABC); in those cases
 | ||||||
|  |                     // simply connect the latter to the former
 | ||||||
|  |                     RTLIL::Wire* existing = module->wire(escaped_s); | ||||||
|  |                     if (!existing) { | ||||||
|  |                         if (escaped_s.ends_with("$inout.out")) { | ||||||
|  |                             wire->port_output = false; | ||||||
|  |                             RTLIL::Wire *in_wire = module->wire(escaped_s.substr(0, escaped_s.size()-10)); | ||||||
|  |                             log_assert(in_wire); | ||||||
|  |                             log_assert(in_wire->port_input && !in_wire->port_output); | ||||||
|  |                             in_wire->port_output = true; | ||||||
|  |                             module->connect(in_wire, wire); | ||||||
|  |                         } | ||||||
|  |                         else | ||||||
|  |                             module->rename(wire, escaped_s); | ||||||
|  |                     } | ||||||
|  |                     else { | ||||||
|  |                         wire->port_output = false; | ||||||
|  |                         module->connect(wire, existing); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|                 else if (index > 0) { |                 else if (index > 0) { | ||||||
|                     module->rename(wire, stringf("%s[%d]", escaped_symbol.c_str(), index)); |                     std::string indexed_name = stringf("%s[%d]", escaped_s.c_str(), index); | ||||||
|                     if (wideports) |                     RTLIL::Wire* existing = module->wire(indexed_name); | ||||||
|                         wideports_cache[escaped_symbol] = std::max(wideports_cache[escaped_symbol], index); |                     if (!existing) { | ||||||
|  |                         if (escaped_s.ends_with("$inout.out")) { | ||||||
|  |                             wire->port_output = false; | ||||||
|  |                             RTLIL::Wire *in_wire = module->wire(stringf("%s[%d]", escaped_s.substr(0, escaped_s.size()-10).c_str(), index)); | ||||||
|  |                             log_assert(in_wire); | ||||||
|  |                             log_assert(in_wire->port_input && !in_wire->port_output); | ||||||
|  |                             in_wire->port_output = true; | ||||||
|  |                             module->connect(in_wire, wire); | ||||||
|  |                         } | ||||||
|  |                         else { | ||||||
|  |                             module->rename(wire, indexed_name); | ||||||
|  |                             if (wideports) | ||||||
|  |                                 wideports_cache[escaped_s] = std::max(wideports_cache[escaped_s], index); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     else { | ||||||
|  |                         module->connect(wire, existing); | ||||||
|  |                         wire->port_output = false; | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             else |             else | ||||||
|  |  | ||||||
|  | @ -34,7 +34,7 @@ void proc_rmdead(RTLIL::SwitchRule *sw, int &counter) | ||||||
| 
 | 
 | ||||||
| 	for (size_t i = 0; i < sw->cases.size(); i++) | 	for (size_t i = 0; i < sw->cases.size(); i++) | ||||||
| 	{ | 	{ | ||||||
| 		bool is_default = GetSize(sw->cases[i]->compare) == 0 || GetSize(sw->signal) == 0; | 		bool is_default = GetSize(sw->cases[i]->compare) == 0 && (!pool.empty() || GetSize(sw->signal) == 0); | ||||||
| 
 | 
 | ||||||
| 		for (size_t j = 0; j < sw->cases[i]->compare.size(); j++) { | 		for (size_t j = 0; j < sw->cases[i]->compare.size(); j++) { | ||||||
| 			RTLIL::SigSpec sig = sw->cases[i]->compare[j]; | 			RTLIL::SigSpec sig = sw->cases[i]->compare[j]; | ||||||
|  |  | ||||||
|  | @ -319,10 +319,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri | ||||||
| 	if (!cleanup) | 	if (!cleanup) | ||||||
| 		tempdir_name[0] = tempdir_name[4] = '_'; | 		tempdir_name[0] = tempdir_name[4] = '_'; | ||||||
| 	tempdir_name = make_temp_dir(tempdir_name); | 	tempdir_name = make_temp_dir(tempdir_name); | ||||||
| 	log_header(design, "Extracting gate netlist of module `%s' to `%s/input.aig'..\n", | 	log_header(design, "Extracting gate netlist of module `%s' to `%s/input.xaig'..\n", | ||||||
| 			module->name.c_str(), replace_tempdir(tempdir_name, tempdir_name, show_tempdir).c_str()); | 			module->name.c_str(), replace_tempdir(tempdir_name, tempdir_name, show_tempdir).c_str()); | ||||||
| 
 | 
 | ||||||
| 	std::string abc_script = stringf("read %s/input.aig; &get -n; ", tempdir_name.c_str()); | 	std::string abc_script = stringf("&read %s/input.xaig; &ps ", tempdir_name.c_str()); | ||||||
| 
 | 
 | ||||||
| 	if (!liberty_file.empty()) { | 	if (!liberty_file.empty()) { | ||||||
| 		abc_script += stringf("read_lib -w %s; ", liberty_file.c_str()); | 		abc_script += stringf("read_lib -w %s; ", liberty_file.c_str()); | ||||||
|  | @ -420,7 +420,7 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri | ||||||
| 
 | 
 | ||||||
| 	handle_loops(design); | 	handle_loops(design); | ||||||
| 
 | 
 | ||||||
| 	Pass::call(design, stringf("write_xaiger -O -symbols %s/input.aig; ", tempdir_name.c_str())); | 	Pass::call(design, stringf("write_xaiger -O -map %s/input.sym %s/input.xaig; ", tempdir_name.c_str(), tempdir_name.c_str())); | ||||||
| 
 | 
 | ||||||
| 	design->selection_stack.pop_back(); | 	design->selection_stack.pop_back(); | ||||||
| 
 | 
 | ||||||
|  | @ -536,7 +536,8 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri | ||||||
| 		bool builtin_lib = liberty_file.empty(); | 		bool builtin_lib = liberty_file.empty(); | ||||||
| 		RTLIL::Design *mapped_design = new RTLIL::Design; | 		RTLIL::Design *mapped_design = new RTLIL::Design; | ||||||
| 		//parse_blif(mapped_design, ifs, builtin_lib ? "\\DFF" : "\\_dff_", false, sop_mode);
 | 		//parse_blif(mapped_design, ifs, builtin_lib ? "\\DFF" : "\\_dff_", false, sop_mode);
 | ||||||
| 		AigerReader reader(mapped_design, ifs, "\\netlist", "" /* clk_name */, "" /* map_filename */, true /* wideports */); | 		buffer = stringf("%s/%s", tempdir_name.c_str(), "input.sym"); | ||||||
|  | 		AigerReader reader(mapped_design, ifs, "\\netlist", "" /* clk_name */, buffer.c_str() /* map_filename */, true /* wideports */); | ||||||
| 		reader.parse_xaiger(); | 		reader.parse_xaiger(); | ||||||
| 
 | 
 | ||||||
| 		ifs.close(); | 		ifs.close(); | ||||||
|  | @ -558,10 +559,10 @@ void abc9_module(RTLIL::Design *design, RTLIL::Module *current_module, std::stri | ||||||
| 						output_bits.insert({wire, i}); | 						output_bits.insert({wire, i}); | ||||||
| 				} | 				} | ||||||
| 				else { | 				else { | ||||||
| 					if (w->name.str() == "\\__dummy_o__") { | 					//if (w->name == "\\__dummy_o__") {
 | ||||||
| 						log("Don't call ABC as there is nothing to map.\n"); | 					//	log("Don't call ABC as there is nothing to map.\n");
 | ||||||
| 						goto cleanup; | 					//	goto cleanup;
 | ||||||
| 					} | 					//}
 | ||||||
| 
 | 
 | ||||||
| 					// Attempt another wideports_split here because there
 | 					// Attempt another wideports_split here because there
 | ||||||
| 					// exists the possibility that different bits of a port
 | 					// exists the possibility that different bits of a port
 | ||||||
|  |  | ||||||
|  | @ -30,10 +30,15 @@ module GND(output G); | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module IBUF(output O, input I); | module IBUF(output O, input I); | ||||||
|  |   parameter IOSTANDARD = "default"; | ||||||
|  |   parameter IBUF_LOW_PWR = 0; | ||||||
|   assign O = I; |   assign O = I; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module OBUF(output O, input I); | module OBUF(output O, input I); | ||||||
|  |   parameter IOSTANDARD = "default"; | ||||||
|  |   parameter DRIVE = 12; | ||||||
|  |   parameter SLEW = "SLOW"; | ||||||
|   assign O = I; |   assign O = I; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
|  | @ -41,6 +46,42 @@ module BUFG(output O, input I); | ||||||
|   assign O = I; |   assign O = I; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
|  | module BUFGCTRL( | ||||||
|  |     output O, | ||||||
|  |     input I0, input I1, | ||||||
|  |     input S0, input S1, | ||||||
|  |     input CE0, input CE1, | ||||||
|  |     input IGNORE0, input IGNORE1); | ||||||
|  | 
 | ||||||
|  | parameter [0:0] INIT_OUT = 1'b0; | ||||||
|  | parameter PRESELECT_I0 = "FALSE"; | ||||||
|  | parameter PRESELECT_I1 = "FALSE"; | ||||||
|  | parameter [0:0] IS_CE0_INVERTED = 1'b0; | ||||||
|  | parameter [0:0] IS_CE1_INVERTED = 1'b0; | ||||||
|  | parameter [0:0] IS_S0_INVERTED = 1'b0; | ||||||
|  | parameter [0:0] IS_S1_INVERTED = 1'b0; | ||||||
|  | parameter [0:0] IS_IGNORE0_INVERTED = 1'b0; | ||||||
|  | parameter [0:0] IS_IGNORE1_INVERTED = 1'b0; | ||||||
|  | 
 | ||||||
|  | wire I0_internal = ((CE0 ^ IS_CE0_INVERTED) ? I0 : INIT_OUT); | ||||||
|  | wire I1_internal = ((CE1 ^ IS_CE1_INVERTED) ? I1 : INIT_OUT); | ||||||
|  | wire S0_true = (S0 ^ IS_S0_INVERTED); | ||||||
|  | wire S1_true = (S1 ^ IS_S1_INVERTED); | ||||||
|  | 
 | ||||||
|  | assign O = S0_true ? I0_internal : (S1_true ? I1_internal : INIT_OUT); | ||||||
|  | 
 | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module BUFHCE(output O, input I, input CE); | ||||||
|  | 
 | ||||||
|  | parameter [0:0] INIT_OUT = 1'b0; | ||||||
|  | parameter CE_TYPE = "SYNC"; | ||||||
|  | parameter [0:0] IS_CE_INVERTED = 1'b0; | ||||||
|  | 
 | ||||||
|  | assign O = ((CE ^ IS_CE_INVERTED) ? I : INIT_OUT); | ||||||
|  | 
 | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
| // module OBUFT(output O, input I, T); | // module OBUFT(output O, input I, T); | ||||||
| //   assign O = T ? 1'bz : I; | //   assign O = T ? 1'bz : I; | ||||||
| // endmodule | // endmodule | ||||||
|  | @ -98,6 +139,22 @@ module LUT6(output O, input I0, I1, I2, I3, I4, I5); | ||||||
|   assign O = I0 ? s1[1] : s1[0]; |   assign O = I0 ? s1[1] : s1[0]; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
|  | module LUT6_2(output O6, output O5, input I0, I1, I2, I3, I4, I5); | ||||||
|  |   parameter [63:0] INIT = 0; | ||||||
|  |   wire [31: 0] s5 = I5 ? INIT[63:32] : INIT[31: 0]; | ||||||
|  |   wire [15: 0] s4 = I4 ?   s5[31:16] :   s5[15: 0]; | ||||||
|  |   wire [ 7: 0] s3 = I3 ?   s4[15: 8] :   s4[ 7: 0]; | ||||||
|  |   wire [ 3: 0] s2 = I2 ?   s3[ 7: 4] :   s3[ 3: 0]; | ||||||
|  |   wire [ 1: 0] s1 = I1 ?   s2[ 3: 2] :   s2[ 1: 0]; | ||||||
|  |   assign O6 = I0 ? s1[1] : s1[0]; | ||||||
|  | 
 | ||||||
|  |   wire [15: 0] s5_4 = I4 ? INIT[31:16] : INIT[15: 0]; | ||||||
|  |   wire [ 7: 0] s5_3 = I3 ? s5_4[15: 8] : s5_4[ 7: 0]; | ||||||
|  |   wire [ 3: 0] s5_2 = I2 ? s5_3[ 7: 4] : s5_3[ 3: 0]; | ||||||
|  |   wire [ 1: 0] s5_1 = I1 ? s5_2[ 3: 2] : s5_2[ 1: 0]; | ||||||
|  |   assign O5 = I0 ? s5_1[1] : s5_1[0]; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
| module MUXCY(output O, input CI, DI, S); | module MUXCY(output O, input CI, DI, S); | ||||||
|   assign O = S ? CI : DI; |   assign O = S ? CI : DI; | ||||||
| endmodule | endmodule | ||||||
|  |  | ||||||
|  | @ -28,12 +28,12 @@ function xtract_cell_decl() | ||||||
| 	# xtract_cell_decl BUFG | 	# xtract_cell_decl BUFG | ||||||
| 	xtract_cell_decl BUFGCE | 	xtract_cell_decl BUFGCE | ||||||
| 	xtract_cell_decl BUFGCE_1 | 	xtract_cell_decl BUFGCE_1 | ||||||
| 	xtract_cell_decl BUFGCTRL | 	#xtract_cell_decl BUFGCTRL | ||||||
| 	xtract_cell_decl BUFGMUX | 	xtract_cell_decl BUFGMUX | ||||||
| 	xtract_cell_decl BUFGMUX_1 | 	xtract_cell_decl BUFGMUX_1 | ||||||
| 	xtract_cell_decl BUFGMUX_CTRL | 	xtract_cell_decl BUFGMUX_CTRL | ||||||
| 	xtract_cell_decl BUFH | 	xtract_cell_decl BUFH | ||||||
| 	xtract_cell_decl BUFHCE | 	#xtract_cell_decl BUFHCE | ||||||
| 	xtract_cell_decl BUFIO | 	xtract_cell_decl BUFIO | ||||||
| 	xtract_cell_decl BUFMR | 	xtract_cell_decl BUFMR | ||||||
| 	xtract_cell_decl BUFMRCE | 	xtract_cell_decl BUFMRCE | ||||||
|  | @ -92,7 +92,7 @@ function xtract_cell_decl() | ||||||
| 	# xtract_cell_decl LUT4 | 	# xtract_cell_decl LUT4 | ||||||
| 	# xtract_cell_decl LUT5 | 	# xtract_cell_decl LUT5 | ||||||
| 	# xtract_cell_decl LUT6 | 	# xtract_cell_decl LUT6 | ||||||
| 	xtract_cell_decl LUT6_2 | 	#xtract_cell_decl LUT6_2 | ||||||
| 	xtract_cell_decl MMCME2_ADV | 	xtract_cell_decl MMCME2_ADV | ||||||
| 	xtract_cell_decl MMCME2_BASE | 	xtract_cell_decl MMCME2_BASE | ||||||
| 	# xtract_cell_decl MUXF7 | 	# xtract_cell_decl MUXF7 | ||||||
|  |  | ||||||
|  | @ -30,29 +30,6 @@ module BUFGCE_1 (...); | ||||||
|     input CE, I; |     input CE, I; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module BUFGCTRL (...); |  | ||||||
|     output O; |  | ||||||
|     input CE0; |  | ||||||
|     input CE1; |  | ||||||
|     input I0; |  | ||||||
|     input I1; |  | ||||||
|     input IGNORE0; |  | ||||||
|     input IGNORE1; |  | ||||||
|     input S0; |  | ||||||
|     input S1; |  | ||||||
|     parameter integer INIT_OUT = 0; |  | ||||||
|     parameter PRESELECT_I0 = "FALSE"; |  | ||||||
|     parameter PRESELECT_I1 = "FALSE"; |  | ||||||
|     parameter [0:0] IS_CE0_INVERTED = 1'b0; |  | ||||||
|     parameter [0:0] IS_CE1_INVERTED = 1'b0; |  | ||||||
|     parameter [0:0] IS_I0_INVERTED = 1'b0; |  | ||||||
|     parameter [0:0] IS_I1_INVERTED = 1'b0; |  | ||||||
|     parameter [0:0] IS_IGNORE0_INVERTED = 1'b0; |  | ||||||
|     parameter [0:0] IS_IGNORE1_INVERTED = 1'b0; |  | ||||||
|     parameter [0:0] IS_S0_INVERTED = 1'b0; |  | ||||||
|     parameter [0:0] IS_S1_INVERTED = 1'b0; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module BUFGMUX (...); | module BUFGMUX (...); | ||||||
|     parameter CLK_SEL_TYPE = "SYNC"; |     parameter CLK_SEL_TYPE = "SYNC"; | ||||||
|     output O; |     output O; | ||||||
|  | @ -77,15 +54,6 @@ module BUFH (...); | ||||||
|     input I; |     input I; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module BUFHCE (...); |  | ||||||
|     parameter CE_TYPE = "SYNC"; |  | ||||||
|     parameter integer INIT_OUT = 0; |  | ||||||
|     parameter [0:0] IS_CE_INVERTED = 1'b0; |  | ||||||
|     output O; |  | ||||||
|     input CE; |  | ||||||
|     input I; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module BUFIO (...); | module BUFIO (...); | ||||||
|     output O; |     output O; | ||||||
|     input I; |     input I; | ||||||
|  | @ -2420,12 +2388,6 @@ module LDPE (...); | ||||||
|     input D, G, GE, PRE; |     input D, G, GE, PRE; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module LUT6_2 (...); |  | ||||||
|     parameter [63:0] INIT = 64'h0000000000000000; |  | ||||||
|     input I0, I1, I2, I3, I4, I5; |  | ||||||
|     output O5, O6; |  | ||||||
| endmodule |  | ||||||
| 
 |  | ||||||
| module MMCME2_ADV (...); | module MMCME2_ADV (...); | ||||||
|     parameter BANDWIDTH = "OPTIMIZED"; |     parameter BANDWIDTH = "OPTIMIZED"; | ||||||
|     parameter real CLKFBOUT_MULT_F = 5.000; |     parameter real CLKFBOUT_MULT_F = 5.000; | ||||||
|  |  | ||||||
|  | @ -8,13 +8,12 @@ read_verilog -formal <<EOT | ||||||
|                 3'b?1?: Y = B; |                 3'b?1?: Y = B; | ||||||
|                 3'b1??: Y = C; |                 3'b1??: Y = C; | ||||||
|                 3'b000: Y = D; |                 3'b000: Y = D; | ||||||
|                 default: Y = 'bx; |  | ||||||
|             endcase |             endcase | ||||||
|     endmodule |     endmodule | ||||||
| EOT | EOT | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| ## Example usage for "pmuxtree" and "muxcover" | ## Examle usage for "pmuxtree" and "muxcover" | ||||||
| 
 | 
 | ||||||
| proc | proc | ||||||
| pmuxtree | pmuxtree | ||||||
|  | @ -36,7 +35,7 @@ read_verilog -formal <<EOT | ||||||
|                 3'b010: Y = B; |                 3'b010: Y = B; | ||||||
|                 3'b100: Y = C; |                 3'b100: Y = C; | ||||||
|                 3'b000: Y = D; |                 3'b000: Y = D; | ||||||
|                 default: Y = 'bx; | 		default: Y = 'bx; | ||||||
|             endcase |             endcase | ||||||
|     endmodule |     endmodule | ||||||
| EOT | EOT | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue