mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	WIP
This commit is contained in:
		
							parent
							
								
									941365b4bb
								
							
						
					
					
						commit
						c748391730
					
				
					 1 changed files with 68 additions and 14 deletions
				
			
		| 
						 | 
					@ -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,7 +213,7 @@ 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;
 | 
										Wire *w = b.wire;
 | 
				
			||||||
					if (!w) continue;
 | 
										if (!w) continue;
 | 
				
			||||||
| 
						 | 
					@ -219,30 +221,32 @@ struct XAigerWriter
 | 
				
			||||||
					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.insert(b);
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					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.insert(O);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				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,19 +260,19 @@ 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 (auto bit : ci_bits)
 | 
				
			||||||
			undriven_bits.erase(bit);
 | 
								undriven_bits.erase(bit);
 | 
				
			||||||
| 
						 | 
					@ -491,6 +495,7 @@ struct XAigerWriter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if (output_bits.count(b) || co_bits.count(b)) {
 | 
										if (output_bits.count(b) || co_bits.count(b)) {
 | 
				
			||||||
						int o = ordered_outputs.at(b);
 | 
											int o = ordered_outputs.at(b);
 | 
				
			||||||
 | 
											if (output_seen && output_bits.count(b))
 | 
				
			||||||
							output_seen = !miter_mode;
 | 
												output_seen = !miter_mode;
 | 
				
			||||||
						if (GetSize(wire) != 1)
 | 
											if (GetSize(wire) != 1)
 | 
				
			||||||
							symbols[stringf("%c%d", miter_mode ? 'b' : 'o', o)].push_back(stringf("%s[%d]", log_id(wire), i));
 | 
												symbols[stringf("%c%d", miter_mode ? 'b' : 'o', o)].push_back(stringf("%s[%d]", log_id(wire), i));
 | 
				
			||||||
| 
						 | 
					@ -532,7 +537,52 @@ 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();
 | 
				
			||||||
 | 
									else
 | 
				
			||||||
 | 
										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)
 | 
				
			||||||
| 
						 | 
					@ -557,6 +607,10 @@ struct XAigerWriter
 | 
				
			||||||
					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));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// Only continue if this input is not a CO,
 | 
				
			||||||
 | 
										// otherwise write as CO below
 | 
				
			||||||
 | 
										if (!co_bits.count(b))
 | 
				
			||||||
						continue;
 | 
											continue;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -606,7 +660,7 @@ struct XAigerWriter
 | 
				
			||||||
			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_lines.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)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue