mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/xaig_dff' into eddie/abc9_refactor
This commit is contained in:
		
						commit
						c28bea0382
					
				
					 22 changed files with 1075 additions and 1153 deletions
				
			
		| 
						 | 
				
			
			@ -78,11 +78,11 @@ struct XAigerWriter
 | 
			
		|||
	Module *module;
 | 
			
		||||
	SigMap sigmap;
 | 
			
		||||
 | 
			
		||||
	pool<SigBit> input_bits, output_bits;
 | 
			
		||||
	pool<SigBit> input_bits, output_bits, external_bits;
 | 
			
		||||
	dict<SigBit, SigBit> not_map, alias_map;
 | 
			
		||||
	dict<SigBit, pair<SigBit, SigBit>> and_map;
 | 
			
		||||
	vector<SigBit> ci_bits, co_bits;
 | 
			
		||||
	dict<SigBit, std::pair<int,int>> ff_bits;
 | 
			
		||||
	dict<SigBit, Cell*> ff_bits;
 | 
			
		||||
	dict<SigBit, float> arrival_times;
 | 
			
		||||
 | 
			
		||||
	vector<pair<int, int>> aig_gates;
 | 
			
		||||
| 
						 | 
				
			
			@ -93,6 +93,7 @@ struct XAigerWriter
 | 
			
		|||
	dict<SigBit, int> ordered_outputs;
 | 
			
		||||
 | 
			
		||||
	vector<Cell*> box_list;
 | 
			
		||||
	dict<IdString, std::vector<IdString>> box_ports;
 | 
			
		||||
 | 
			
		||||
	int mkgate(int a0, int a1)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -140,7 +141,6 @@ struct XAigerWriter
 | 
			
		|||
	{
 | 
			
		||||
		pool<SigBit> undriven_bits;
 | 
			
		||||
		pool<SigBit> unused_bits;
 | 
			
		||||
		pool<SigBit> inout_bits;
 | 
			
		||||
 | 
			
		||||
		// promote public wires
 | 
			
		||||
		for (auto wire : module->wires())
 | 
			
		||||
| 
						 | 
				
			
			@ -157,7 +157,12 @@ struct XAigerWriter
 | 
			
		|||
			if (wire->get_bool_attribute(ID::keep))
 | 
			
		||||
				sigmap.add(wire);
 | 
			
		||||
 | 
			
		||||
		for (auto wire : module->wires())
 | 
			
		||||
		// First, collect all the ports in port_id order
 | 
			
		||||
		//   since module->wires() could be sorted
 | 
			
		||||
		//   alphabetically
 | 
			
		||||
		for (auto port : module->ports) {
 | 
			
		||||
			auto wire = module->wire(port);
 | 
			
		||||
			log_assert(wire);
 | 
			
		||||
			for (int i = 0; i < GetSize(wire); i++)
 | 
			
		||||
			{
 | 
			
		||||
				SigBit wirebit(wire, i);
 | 
			
		||||
| 
						 | 
				
			
			@ -171,9 +176,6 @@ struct XAigerWriter
 | 
			
		|||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				undriven_bits.insert(bit);
 | 
			
		||||
				unused_bits.insert(bit);
 | 
			
		||||
 | 
			
		||||
				if (wire->port_input)
 | 
			
		||||
					input_bits.insert(bit);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -182,9 +184,19 @@ struct XAigerWriter
 | 
			
		|||
						alias_map[wirebit] = bit;
 | 
			
		||||
					output_bits.insert(wirebit);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
				if (wire->port_input && wire->port_output)
 | 
			
		||||
					inout_bits.insert(wirebit);
 | 
			
		||||
		for (auto wire : module->wires())
 | 
			
		||||
			for (int i = 0; i < GetSize(wire); i++)
 | 
			
		||||
			{
 | 
			
		||||
				SigBit wirebit(wire, i);
 | 
			
		||||
				SigBit bit = sigmap(wirebit);
 | 
			
		||||
 | 
			
		||||
				if (bit.wire) {
 | 
			
		||||
					undriven_bits.insert(bit);
 | 
			
		||||
					unused_bits.insert(bit);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		// TODO: Speed up toposort -- ultimately we care about
 | 
			
		||||
| 
						 | 
				
			
			@ -192,7 +204,6 @@ struct XAigerWriter
 | 
			
		|||
		dict<SigBit, pool<IdString>> bit_drivers, bit_users;
 | 
			
		||||
		TopoSort<IdString, RTLIL::sort_by_id_str> toposort;
 | 
			
		||||
		bool abc9_box_seen = false;
 | 
			
		||||
		std::vector<Cell*> flop_boxes;
 | 
			
		||||
 | 
			
		||||
		for (auto cell : module->selected_cells()) {
 | 
			
		||||
			if (cell->type == "$_NOT_")
 | 
			
		||||
| 
						 | 
				
			
			@ -224,25 +235,44 @@ struct XAigerWriter
 | 
			
		|||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cell->type == "$__ABC9_FF_")
 | 
			
		||||
			if (cell->type == "$__ABC9_FF_" &&
 | 
			
		||||
                                        // The presence of an abc9_mergeability attribute indicates
 | 
			
		||||
                                        //   that we do want to pass this flop to ABC
 | 
			
		||||
                                        cell->attributes.count("\\abc9_mergeability"))
 | 
			
		||||
			{
 | 
			
		||||
				SigBit D = sigmap(cell->getPort("\\D").as_bit());
 | 
			
		||||
				SigBit Q = sigmap(cell->getPort("\\Q").as_bit());
 | 
			
		||||
				unused_bits.erase(D);
 | 
			
		||||
				undriven_bits.erase(Q);
 | 
			
		||||
				alias_map[Q] = D;
 | 
			
		||||
				auto r = ff_bits.insert(std::make_pair(D, std::make_pair(0, 2)));
 | 
			
		||||
				auto r YS_ATTRIBUTE(unused) = ff_bits.insert(std::make_pair(D, cell));
 | 
			
		||||
				log_assert(r.second);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			RTLIL::Module* inst_module = module->design->module(cell->type);
 | 
			
		||||
			if (inst_module) {
 | 
			
		||||
				bool abc9_box = inst_module->attributes.count("\\abc9_box_id") && !cell->get_bool_attribute("\\abc9_keep");
 | 
			
		||||
				bool abc9_box = inst_module->attributes.count("\\abc9_box_id");
 | 
			
		||||
				bool abc9_flop = inst_module->get_bool_attribute("\\abc9_flop");
 | 
			
		||||
				if (abc9_box && cell->get_bool_attribute("\\abc9_keep"))
 | 
			
		||||
					abc9_box = false;
 | 
			
		||||
 | 
			
		||||
				for (const auto &conn : cell->connections()) {
 | 
			
		||||
					auto port_wire = inst_module->wire(conn.first);
 | 
			
		||||
 | 
			
		||||
					if (abc9_box) {
 | 
			
		||||
						// Ignore inout for the sake of topographical ordering
 | 
			
		||||
						if (port_wire->port_input && !port_wire->port_output)
 | 
			
		||||
							for (auto bit : sigmap(conn.second))
 | 
			
		||||
								bit_users[bit].insert(cell->name);
 | 
			
		||||
						if (port_wire->port_output)
 | 
			
		||||
							for (auto bit : sigmap(conn.second))
 | 
			
		||||
								bit_drivers[bit].insert(cell->name);
 | 
			
		||||
 | 
			
		||||
						if (!abc9_flop)
 | 
			
		||||
							continue;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if (port_wire->port_output) {
 | 
			
		||||
						int arrival = 0;
 | 
			
		||||
						auto it = port_wire->attributes.find("\\abc9_arrival");
 | 
			
		||||
| 
						 | 
				
			
			@ -255,27 +285,13 @@ struct XAigerWriter
 | 
			
		|||
							for (auto bit : sigmap(conn.second))
 | 
			
		||||
								arrival_times[bit] = arrival;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if (abc9_box) {
 | 
			
		||||
						// Ignore inout for the sake of topographical ordering
 | 
			
		||||
						if (port_wire->port_input && !port_wire->port_output)
 | 
			
		||||
							for (auto bit : sigmap(conn.second))
 | 
			
		||||
								bit_users[bit].insert(cell->name);
 | 
			
		||||
						if (port_wire->port_output)
 | 
			
		||||
							for (auto bit : sigmap(conn.second))
 | 
			
		||||
								bit_drivers[bit].insert(cell->name);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
                                if (abc9_box) {
 | 
			
		||||
                                        abc9_box_seen = true;
 | 
			
		||||
 | 
			
		||||
                                        toposort.node(cell->name);
 | 
			
		||||
 | 
			
		||||
                                        if (inst_module->attributes.count("\\abc9_flop"))
 | 
			
		||||
                                                flop_boxes.push_back(cell);
 | 
			
		||||
                                        continue;
 | 
			
		||||
                                }
 | 
			
		||||
				if (abc9_box) {
 | 
			
		||||
					abc9_box_seen = true;
 | 
			
		||||
					toposort.node(cell->name);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			bool cell_known = inst_module || cell->known();
 | 
			
		||||
| 
						 | 
				
			
			@ -298,76 +314,12 @@ struct XAigerWriter
 | 
			
		|||
							output_bits.insert(b);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
				if (is_output)
 | 
			
		||||
					for (auto b : c.second) {
 | 
			
		||||
						Wire *w = b.wire;
 | 
			
		||||
						if (!w) continue;
 | 
			
		||||
						SigBit O = sigmap(b);
 | 
			
		||||
						if (O != b)
 | 
			
		||||
							alias_map[O] = b;
 | 
			
		||||
						input_bits.insert(O);
 | 
			
		||||
					}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			//log_warning("Unsupported cell type: %s (%s)\n", log_id(cell->type), log_id(cell));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (abc9_box_seen) {
 | 
			
		||||
			dict<IdString, std::pair<IdString,int>> flop_q;
 | 
			
		||||
			for (auto cell : flop_boxes) {
 | 
			
		||||
				auto r = flop_q.insert(std::make_pair(cell->type, std::make_pair(IdString(), 0)));
 | 
			
		||||
				SigBit d;
 | 
			
		||||
				if (r.second) {
 | 
			
		||||
					for (const auto &conn : cell->connections()) {
 | 
			
		||||
						const SigSpec &rhs = conn.second;
 | 
			
		||||
						if (!rhs.is_bit())
 | 
			
		||||
							continue;
 | 
			
		||||
						if (!ff_bits.count(rhs))
 | 
			
		||||
							continue;
 | 
			
		||||
						r.first->second.first = conn.first;
 | 
			
		||||
						Module *inst_module = module->design->module(cell->type);
 | 
			
		||||
						Wire *wire = inst_module->wire(conn.first);
 | 
			
		||||
						log_assert(wire);
 | 
			
		||||
						auto jt = wire->attributes.find("\\abc9_arrival");
 | 
			
		||||
						if (jt != wire->attributes.end()) {
 | 
			
		||||
							if (jt->second.flags != 0)
 | 
			
		||||
								log_error("Attribute 'abc9_arrival' on port '%s' of module '%s' is not an integer.\n", log_id(wire), log_id(cell->type));
 | 
			
		||||
							r.first->second.second = jt->second.as_int();
 | 
			
		||||
						}
 | 
			
		||||
						d = rhs;
 | 
			
		||||
						log_assert(d == sigmap(d));
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
					d = cell->getPort(r.first->second.first);
 | 
			
		||||
 | 
			
		||||
				auto &rhs = ff_bits.at(d);
 | 
			
		||||
 | 
			
		||||
				auto it = cell->attributes.find(ID(abc9_mergeability));
 | 
			
		||||
				log_assert(it != cell->attributes.end());
 | 
			
		||||
				rhs.first = it->second.as_int();
 | 
			
		||||
				cell->attributes.erase(it);
 | 
			
		||||
 | 
			
		||||
				it = cell->attributes.find(ID(abc9_init));
 | 
			
		||||
				log_assert(it != cell->attributes.end());
 | 
			
		||||
				log_assert(GetSize(it->second) == 1);
 | 
			
		||||
				if (it->second[0] == State::S1)
 | 
			
		||||
					rhs.second = 1;
 | 
			
		||||
				else if (it->second[0] == State::S0)
 | 
			
		||||
					rhs.second = 0;
 | 
			
		||||
				else {
 | 
			
		||||
					log_assert(it->second[0] == State::Sx);
 | 
			
		||||
					rhs.second = 0;
 | 
			
		||||
				}
 | 
			
		||||
				cell->attributes.erase(it);
 | 
			
		||||
 | 
			
		||||
				auto arrival = r.first->second.second;
 | 
			
		||||
				if (arrival)
 | 
			
		||||
					arrival_times[d] = arrival;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for (auto &it : bit_users)
 | 
			
		||||
				if (bit_drivers.count(it.first))
 | 
			
		||||
					for (auto driver_cell : bit_drivers.at(it.first))
 | 
			
		||||
| 
						 | 
				
			
			@ -396,18 +348,49 @@ struct XAigerWriter
 | 
			
		|||
				log_assert(cell);
 | 
			
		||||
 | 
			
		||||
				RTLIL::Module* box_module = module->design->module(cell->type);
 | 
			
		||||
				if (!box_module || !box_module->attributes.count("\\abc9_box_id")
 | 
			
		||||
						|| cell->get_bool_attribute("\\abc9_keep"))
 | 
			
		||||
				if (!box_module || !box_module->attributes.count("\\abc9_box_id"))
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				bool blackbox = box_module->get_blackbox_attribute(true /* ignore_wb */);
 | 
			
		||||
 | 
			
		||||
				auto r = box_ports.insert(cell->type);
 | 
			
		||||
				if (r.second) {
 | 
			
		||||
					// Make carry in the last PI, and carry out the last PO
 | 
			
		||||
					//   since ABC requires it this way
 | 
			
		||||
					IdString carry_in, carry_out;
 | 
			
		||||
					for (const auto &port_name : box_module->ports) {
 | 
			
		||||
						auto w = box_module->wire(port_name);
 | 
			
		||||
						log_assert(w);
 | 
			
		||||
						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(box_module));
 | 
			
		||||
								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(box_module));
 | 
			
		||||
								carry_out = port_name;
 | 
			
		||||
							}
 | 
			
		||||
						}
 | 
			
		||||
						else
 | 
			
		||||
							r.first->second.push_back(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(box_module));
 | 
			
		||||
					if (carry_in == IdString() && carry_out != IdString())
 | 
			
		||||
						log_error("Module '%s' contains an 'abc9_carry' output port but no input port.\n", log_id(box_module));
 | 
			
		||||
					if (carry_in != IdString()) {
 | 
			
		||||
						r.first->second.push_back(carry_in);
 | 
			
		||||
						r.first->second.push_back(carry_out);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Fully pad all unused input connections of this box cell with S0
 | 
			
		||||
				// Fully pad all undriven output connections of this box cell with anonymous wires
 | 
			
		||||
				// NB: Assume box_module->ports are sorted alphabetically
 | 
			
		||||
				//     (as RTLIL::Module::fixup_ports() would do)
 | 
			
		||||
				for (const auto &port_name : box_module->ports) {
 | 
			
		||||
					RTLIL::Wire* w = box_module->wire(port_name);
 | 
			
		||||
				for (auto port_name : r.first->second) {
 | 
			
		||||
					auto w = box_module->wire(port_name);
 | 
			
		||||
					log_assert(w);
 | 
			
		||||
					auto it = cell->connections_.find(port_name);
 | 
			
		||||
					if (w->port_input) {
 | 
			
		||||
| 
						 | 
				
			
			@ -422,7 +405,7 @@ struct XAigerWriter
 | 
			
		|||
							cell->setPort(port_name, rhs);
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						for (auto b : rhs.bits()) {
 | 
			
		||||
						for (auto b : rhs) {
 | 
			
		||||
							SigBit I = sigmap(b);
 | 
			
		||||
							if (b == RTLIL::Sx)
 | 
			
		||||
								b = State::S0;
 | 
			
		||||
| 
						 | 
				
			
			@ -453,21 +436,20 @@ struct XAigerWriter
 | 
			
		|||
						}
 | 
			
		||||
 | 
			
		||||
						for (const auto &b : rhs.bits()) {
 | 
			
		||||
							ci_bits.emplace_back(b);
 | 
			
		||||
							SigBit O = sigmap(b);
 | 
			
		||||
							if (O != b)
 | 
			
		||||
								alias_map[O] = b;
 | 
			
		||||
							input_bits.erase(O);
 | 
			
		||||
							ci_bits.emplace_back(b);
 | 
			
		||||
							undriven_bits.erase(O);
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Connect <cell>.$abc9_currQ (inserted by abc9_map.v) as an input to the flop box
 | 
			
		||||
				// Connect <cell>.abc9_ff.Q (inserted by abc9_map.v) as the last input to the flop box
 | 
			
		||||
				if (box_module->get_bool_attribute("\\abc9_flop")) {
 | 
			
		||||
					SigSpec rhs = module->wire(stringf("%s.$abc9_currQ", cell->name.c_str()));
 | 
			
		||||
					SigSpec rhs = module->wire(stringf("%s.abc9_ff.Q", cell->name.c_str()));
 | 
			
		||||
					if (rhs.empty())
 | 
			
		||||
						log_error("'%s.$abc9_currQ' is not a wire present in module '%s'.\n", log_id(cell), log_id(module));
 | 
			
		||||
						log_error("'%s.abc9_ff.Q' is not a wire present in module '%s'.\n", log_id(cell), log_id(module));
 | 
			
		||||
 | 
			
		||||
					for (auto b : rhs) {
 | 
			
		||||
						SigBit I = sigmap(b);
 | 
			
		||||
| 
						 | 
				
			
			@ -496,62 +478,54 @@ struct XAigerWriter
 | 
			
		|||
			unused_bits.erase(sigmap(bit));
 | 
			
		||||
		for (auto bit : unused_bits)
 | 
			
		||||
			undriven_bits.erase(bit);
 | 
			
		||||
		if (!undriven_bits.empty()) {
 | 
			
		||||
			for (auto bit : undriven_bits) {
 | 
			
		||||
				log_warning("Treating undriven bit %s.%s like $anyseq.\n", log_id(module), log_signal(bit));
 | 
			
		||||
				input_bits.insert(bit);
 | 
			
		||||
			}
 | 
			
		||||
			log_warning("Treating a total of %d undriven bits in %s like $anyseq.\n", GetSize(undriven_bits), log_id(module));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		struct sort_by_port_id {
 | 
			
		||||
			bool operator()(const RTLIL::SigBit& a, const RTLIL::SigBit& b) const {
 | 
			
		||||
				return a.wire->port_id < b.wire->port_id;
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
		input_bits.sort(sort_by_port_id());
 | 
			
		||||
		output_bits.sort(sort_by_port_id());
 | 
			
		||||
		not_map.sort();
 | 
			
		||||
		and_map.sort();
 | 
			
		||||
		// Make all undriven bits a primary input
 | 
			
		||||
		for (auto bit : undriven_bits) {
 | 
			
		||||
			input_bits.insert(bit);
 | 
			
		||||
			undriven_bits.erase(bit);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		aig_map[State::S0] = 0;
 | 
			
		||||
		aig_map[State::S1] = 1;
 | 
			
		||||
 | 
			
		||||
		for (auto bit : input_bits) {
 | 
			
		||||
		// pool<> iterates in LIFO order...
 | 
			
		||||
		for (int i = input_bits.size()-1; i >= 0; i--) {
 | 
			
		||||
			const auto &bit = *input_bits.element(i);
 | 
			
		||||
			aig_m++, aig_i++;
 | 
			
		||||
			log_assert(!aig_map.count(bit));
 | 
			
		||||
			aig_map[bit] = 2*aig_m;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (const auto &i : ff_bits) {
 | 
			
		||||
			const SigBit &bit = i.first;
 | 
			
		||||
			const Cell *cell = i.second;
 | 
			
		||||
			const SigBit &q = sigmap(cell->getPort("\\Q"));
 | 
			
		||||
			aig_m++, aig_i++;
 | 
			
		||||
			log_assert(!aig_map.count(q));
 | 
			
		||||
			aig_map[q] = 2*aig_m;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (auto &bit : ci_bits) {
 | 
			
		||||
			aig_m++, aig_i++;
 | 
			
		||||
			log_assert(!aig_map.count(bit));
 | 
			
		||||
			aig_map[bit] = 2*aig_m;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		dict<SigBit, int> ff_aig_map;
 | 
			
		||||
		for (auto &bit : ci_bits) {
 | 
			
		||||
			aig_m++, aig_i++;
 | 
			
		||||
			auto r = aig_map.insert(std::make_pair(bit, 2*aig_m));
 | 
			
		||||
			if (!r.second)
 | 
			
		||||
				ff_aig_map[bit] = 2*aig_m;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (auto bit : co_bits) {
 | 
			
		||||
			ordered_outputs[bit] = aig_o++;
 | 
			
		||||
			aig_outputs.push_back(bit2aig(bit));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (auto bit : output_bits) {
 | 
			
		||||
		// pool<> iterates in LIFO order...
 | 
			
		||||
		for (int i = output_bits.size()-1; i >= 0; i--) {
 | 
			
		||||
			const auto &bit = *output_bits.element(i);
 | 
			
		||||
			ordered_outputs[bit] = aig_o++;
 | 
			
		||||
			aig_outputs.push_back(bit2aig(bit));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (auto &i : ff_bits) {
 | 
			
		||||
			const SigBit &bit = i.first;
 | 
			
		||||
			const SigBit &d = i.first;
 | 
			
		||||
			aig_o++;
 | 
			
		||||
			aig_outputs.push_back(ff_aig_map.at(bit));
 | 
			
		||||
			aig_outputs.push_back(aig_map.at(d));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -653,9 +627,7 @@ struct XAigerWriter
 | 
			
		|||
				RTLIL::Module* box_module = module->design->module(derived_name);
 | 
			
		||||
 | 
			
		||||
				int box_inputs = 0, box_outputs = 0;
 | 
			
		||||
				// NB: Assume box_module->ports are sorted alphabetically
 | 
			
		||||
				//     (as RTLIL::Module::fixup_ports() would do)
 | 
			
		||||
				for (const auto &port_name : box_module->ports) {
 | 
			
		||||
				for (auto port_name : box_ports.at(cell->type)) {
 | 
			
		||||
					RTLIL::Wire *w = box_module->wire(port_name);
 | 
			
		||||
					log_assert(w);
 | 
			
		||||
					if (w->port_input)
 | 
			
		||||
| 
						 | 
				
			
			@ -664,8 +636,7 @@ struct XAigerWriter
 | 
			
		|||
						box_outputs += GetSize(w);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// For flops only, create an extra 1-bit input that drives a new wire
 | 
			
		||||
				//   called "<cell>.$abc9_currQ" that is used below
 | 
			
		||||
				// For flops only, create an extra 1-bit input for abc9_ff.Q
 | 
			
		||||
				if (box_module->get_bool_attribute("\\abc9_flop"))
 | 
			
		||||
					box_inputs++;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -685,13 +656,25 @@ struct XAigerWriter
 | 
			
		|||
			write_s_buffer(ff_bits.size());
 | 
			
		||||
 | 
			
		||||
			for (const auto &i : ff_bits) {
 | 
			
		||||
				const SigBit &bit = i.first;
 | 
			
		||||
				int mergeability = i.second.first;
 | 
			
		||||
				const SigBit &d = i.first;
 | 
			
		||||
				const Cell *cell = i.second;
 | 
			
		||||
 | 
			
		||||
				int mergeability = cell->attributes.at(ID(abc9_mergeability)).as_int();
 | 
			
		||||
				log_assert(mergeability > 0);
 | 
			
		||||
				write_r_buffer(mergeability);
 | 
			
		||||
				int init = i.second.second;
 | 
			
		||||
				write_s_buffer(init);
 | 
			
		||||
				write_i_buffer(arrival_times.at(bit, 0));
 | 
			
		||||
 | 
			
		||||
				Const init = cell->attributes.at(ID(abc9_init));
 | 
			
		||||
				log_assert(GetSize(init) == 1);
 | 
			
		||||
				if (init == State::S1)
 | 
			
		||||
					write_s_buffer(1);
 | 
			
		||||
				else if (init == State::S0)
 | 
			
		||||
					write_s_buffer(0);
 | 
			
		||||
				else {
 | 
			
		||||
					log_assert(init == State::Sx);
 | 
			
		||||
					write_s_buffer(0);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				write_i_buffer(arrival_times.at(d, 0));
 | 
			
		||||
				//write_o_buffer(0);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue