mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 05:19:11 +00:00 
			
		
		
		
	Merge pull request #1767 from YosysHQ/eddie/idstrings
IdString: use more ID::*, make them easier to use, speed up IdString::in()
This commit is contained in:
		
						commit
						5f662b1c43
					
				
					 163 changed files with 5340 additions and 5201 deletions
				
			
		| 
						 | 
				
			
			@ -42,9 +42,9 @@ static void add_formal(RTLIL::Module *module, const std::string &celltype, const
 | 
			
		|||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		RTLIL::Cell *formal_cell = module->addCell(NEW_ID, "$" + celltype);
 | 
			
		||||
		formal_cell->setPort(ID(A), wire);
 | 
			
		||||
		formal_cell->setPort(ID::A, wire);
 | 
			
		||||
		if(enable_name == "") {
 | 
			
		||||
			formal_cell->setPort(ID(EN), State::S1);
 | 
			
		||||
			formal_cell->setPort(ID::EN, State::S1);
 | 
			
		||||
			log("Added $%s cell for wire \"%s.%s\"\n", celltype.c_str(), module->name.str().c_str(), name.c_str());
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ static void add_formal(RTLIL::Module *module, const std::string &celltype, const
 | 
			
		|||
			if(enable_wire == nullptr)
 | 
			
		||||
				log_error("Could not find enable wire with name \"%s\".\n", enable_name.c_str());
 | 
			
		||||
 | 
			
		||||
			formal_cell->setPort(ID(EN), enable_wire);
 | 
			
		||||
			formal_cell->setPort(ID::EN, enable_wire);
 | 
			
		||||
			log("Added $%s cell for wire \"%s.%s\" enabled by wire \"%s.%s\".\n", celltype.c_str(), module->name.str().c_str(), name.c_str(), module->name.str().c_str(), enable_name.c_str());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -212,7 +212,7 @@ struct AddPass : public Pass {
 | 
			
		|||
			log_assert(module != nullptr);
 | 
			
		||||
			if (!design->selected_whole_module(module->name))
 | 
			
		||||
				continue;
 | 
			
		||||
			if (module->get_bool_attribute("\\blackbox"))
 | 
			
		||||
			if (module->get_bool_attribute(ID::blackbox))
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			selected_anything = true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,7 +73,7 @@ struct BlackboxPass : public Pass {
 | 
			
		|||
 | 
			
		||||
			module->remove(remove_wires);
 | 
			
		||||
 | 
			
		||||
			module->set_bool_attribute("\\blackbox");
 | 
			
		||||
			module->set_bool_attribute(ID::blackbox);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
} BlackboxPass;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -155,7 +155,7 @@ struct BugpointPass : public Pass {
 | 
			
		|||
 | 
			
		||||
				for (auto wire : mod->wires())
 | 
			
		||||
				{
 | 
			
		||||
					if (!stage2 && wire->get_bool_attribute("$bugpoint"))
 | 
			
		||||
					if (!stage2 && wire->get_bool_attribute(ID($bugpoint)))
 | 
			
		||||
						continue;
 | 
			
		||||
 | 
			
		||||
					if (wire->port_input || wire->port_output)
 | 
			
		||||
| 
						 | 
				
			
			@ -220,7 +220,7 @@ struct BugpointPass : public Pass {
 | 
			
		|||
						{
 | 
			
		||||
							log("Trying to expose cell port %s.%s.%s as module port.\n", mod->name.c_str(), cell->name.c_str(), it.first.c_str());
 | 
			
		||||
							RTLIL::Wire *wire = mod->addWire(NEW_ID, port.size());
 | 
			
		||||
							wire->set_bool_attribute("$bugpoint");
 | 
			
		||||
							wire->set_bool_attribute(ID($bugpoint));
 | 
			
		||||
							wire->port_input = cell->input(it.first);
 | 
			
		||||
							wire->port_output = cell->output(it.first);
 | 
			
		||||
							cell->unsetPort(it.first);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -99,47 +99,47 @@ struct CheckPass : public Pass {
 | 
			
		|||
		log_header(design, "Executing CHECK pass (checking for obvious problems).\n");
 | 
			
		||||
 | 
			
		||||
		pool<IdString> fftypes;
 | 
			
		||||
		fftypes.insert("$sr");
 | 
			
		||||
		fftypes.insert("$ff");
 | 
			
		||||
		fftypes.insert("$dff");
 | 
			
		||||
		fftypes.insert("$dffe");
 | 
			
		||||
		fftypes.insert("$dffsr");
 | 
			
		||||
		fftypes.insert("$adff");
 | 
			
		||||
		fftypes.insert("$dlatch");
 | 
			
		||||
		fftypes.insert("$dlatchsr");
 | 
			
		||||
		fftypes.insert("$_DFFE_NN_");
 | 
			
		||||
		fftypes.insert("$_DFFE_NP_");
 | 
			
		||||
		fftypes.insert("$_DFFE_PN_");
 | 
			
		||||
		fftypes.insert("$_DFFE_PP_");
 | 
			
		||||
		fftypes.insert("$_DFFSR_NNN_");
 | 
			
		||||
		fftypes.insert("$_DFFSR_NNP_");
 | 
			
		||||
		fftypes.insert("$_DFFSR_NPN_");
 | 
			
		||||
		fftypes.insert("$_DFFSR_NPP_");
 | 
			
		||||
		fftypes.insert("$_DFFSR_PNN_");
 | 
			
		||||
		fftypes.insert("$_DFFSR_PNP_");
 | 
			
		||||
		fftypes.insert("$_DFFSR_PPN_");
 | 
			
		||||
		fftypes.insert("$_DFFSR_PPP_");
 | 
			
		||||
		fftypes.insert("$_DFF_NN0_");
 | 
			
		||||
		fftypes.insert("$_DFF_NN1_");
 | 
			
		||||
		fftypes.insert("$_DFF_NP0_");
 | 
			
		||||
		fftypes.insert("$_DFF_NP1_");
 | 
			
		||||
		fftypes.insert("$_DFF_N_");
 | 
			
		||||
		fftypes.insert("$_DFF_PN0_");
 | 
			
		||||
		fftypes.insert("$_DFF_PN1_");
 | 
			
		||||
		fftypes.insert("$_DFF_PP0_");
 | 
			
		||||
		fftypes.insert("$_DFF_PP1_");
 | 
			
		||||
		fftypes.insert("$_DFF_P_");
 | 
			
		||||
		fftypes.insert("$_DLATCHSR_NNN_");
 | 
			
		||||
		fftypes.insert("$_DLATCHSR_NNP_");
 | 
			
		||||
		fftypes.insert("$_DLATCHSR_NPN_");
 | 
			
		||||
		fftypes.insert("$_DLATCHSR_NPP_");
 | 
			
		||||
		fftypes.insert("$_DLATCHSR_PNN_");
 | 
			
		||||
		fftypes.insert("$_DLATCHSR_PNP_");
 | 
			
		||||
		fftypes.insert("$_DLATCHSR_PPN_");
 | 
			
		||||
		fftypes.insert("$_DLATCHSR_PPP_");
 | 
			
		||||
		fftypes.insert("$_DLATCH_N_");
 | 
			
		||||
		fftypes.insert("$_DLATCH_P_");
 | 
			
		||||
		fftypes.insert("$_FF_");
 | 
			
		||||
		fftypes.insert(ID($sr));
 | 
			
		||||
		fftypes.insert(ID($ff));
 | 
			
		||||
		fftypes.insert(ID($dff));
 | 
			
		||||
		fftypes.insert(ID($dffe));
 | 
			
		||||
		fftypes.insert(ID($dffsr));
 | 
			
		||||
		fftypes.insert(ID($adff));
 | 
			
		||||
		fftypes.insert(ID($dlatch));
 | 
			
		||||
		fftypes.insert(ID($dlatchsr));
 | 
			
		||||
		fftypes.insert(ID($_DFFE_NN_));
 | 
			
		||||
		fftypes.insert(ID($_DFFE_NP_));
 | 
			
		||||
		fftypes.insert(ID($_DFFE_PN_));
 | 
			
		||||
		fftypes.insert(ID($_DFFE_PP_));
 | 
			
		||||
		fftypes.insert(ID($_DFFSR_NNN_));
 | 
			
		||||
		fftypes.insert(ID($_DFFSR_NNP_));
 | 
			
		||||
		fftypes.insert(ID($_DFFSR_NPN_));
 | 
			
		||||
		fftypes.insert(ID($_DFFSR_NPP_));
 | 
			
		||||
		fftypes.insert(ID($_DFFSR_PNN_));
 | 
			
		||||
		fftypes.insert(ID($_DFFSR_PNP_));
 | 
			
		||||
		fftypes.insert(ID($_DFFSR_PPN_));
 | 
			
		||||
		fftypes.insert(ID($_DFFSR_PPP_));
 | 
			
		||||
		fftypes.insert(ID($_DFF_NN0_));
 | 
			
		||||
		fftypes.insert(ID($_DFF_NN1_));
 | 
			
		||||
		fftypes.insert(ID($_DFF_NP0_));
 | 
			
		||||
		fftypes.insert(ID($_DFF_NP1_));
 | 
			
		||||
		fftypes.insert(ID($_DFF_N_));
 | 
			
		||||
		fftypes.insert(ID($_DFF_PN0_));
 | 
			
		||||
		fftypes.insert(ID($_DFF_PN1_));
 | 
			
		||||
		fftypes.insert(ID($_DFF_PP0_));
 | 
			
		||||
		fftypes.insert(ID($_DFF_PP1_));
 | 
			
		||||
		fftypes.insert(ID($_DFF_P_));
 | 
			
		||||
		fftypes.insert(ID($_DLATCHSR_NNN_));
 | 
			
		||||
		fftypes.insert(ID($_DLATCHSR_NNP_));
 | 
			
		||||
		fftypes.insert(ID($_DLATCHSR_NPN_));
 | 
			
		||||
		fftypes.insert(ID($_DLATCHSR_NPP_));
 | 
			
		||||
		fftypes.insert(ID($_DLATCHSR_PNN_));
 | 
			
		||||
		fftypes.insert(ID($_DLATCHSR_PNP_));
 | 
			
		||||
		fftypes.insert(ID($_DLATCHSR_PPN_));
 | 
			
		||||
		fftypes.insert(ID($_DLATCHSR_PPP_));
 | 
			
		||||
		fftypes.insert(ID($_DLATCH_N_));
 | 
			
		||||
		fftypes.insert(ID($_DLATCH_P_));
 | 
			
		||||
		fftypes.insert(ID($_FF_));
 | 
			
		||||
 | 
			
		||||
		for (auto module : design->selected_whole_modules_warn())
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -202,8 +202,8 @@ struct CheckPass : public Pass {
 | 
			
		|||
				if (wire->port_input && !wire->port_output)
 | 
			
		||||
					for (auto bit : sigmap(wire))
 | 
			
		||||
						if (bit.wire) wire_drivers_count[bit]++;
 | 
			
		||||
				if (wire->attributes.count("\\init")) {
 | 
			
		||||
					Const initval = wire->attributes.at("\\init");
 | 
			
		||||
				if (wire->attributes.count(ID::init)) {
 | 
			
		||||
					Const initval = wire->attributes.at(ID::init);
 | 
			
		||||
					for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++)
 | 
			
		||||
						if (initval[i] == State::S0 || initval[i] == State::S1)
 | 
			
		||||
							init_bits.insert(sigmap(SigBit(wire, i)));
 | 
			
		||||
| 
						 | 
				
			
			@ -245,7 +245,7 @@ struct CheckPass : public Pass {
 | 
			
		|||
					if (fftypes.count(cell->type) == 0)
 | 
			
		||||
						continue;
 | 
			
		||||
 | 
			
		||||
					for (auto bit : sigmap(cell->getPort("\\Q")))
 | 
			
		||||
					for (auto bit : sigmap(cell->getPort(ID::Q)))
 | 
			
		||||
						init_bits.erase(bit);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,23 +77,23 @@ struct ChformalPass : public Pass {
 | 
			
		|||
		for (argidx = 1; argidx < args.size(); argidx++)
 | 
			
		||||
		{
 | 
			
		||||
			if (args[argidx] == "-assert") {
 | 
			
		||||
				constr_types.insert("$assert");
 | 
			
		||||
				constr_types.insert(ID($assert));
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-assume") {
 | 
			
		||||
				constr_types.insert("$assume");
 | 
			
		||||
				constr_types.insert(ID($assume));
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-live") {
 | 
			
		||||
				constr_types.insert("$live");
 | 
			
		||||
				constr_types.insert(ID($live));
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-fair") {
 | 
			
		||||
				constr_types.insert("$fair");
 | 
			
		||||
				constr_types.insert(ID($fair));
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (args[argidx] == "-cover") {
 | 
			
		||||
				constr_types.insert("$cover");
 | 
			
		||||
				constr_types.insert(ID($cover));
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (mode == 0 && args[argidx] == "-remove") {
 | 
			
		||||
| 
						 | 
				
			
			@ -139,11 +139,11 @@ struct ChformalPass : public Pass {
 | 
			
		|||
		extra_args(args, argidx, design);
 | 
			
		||||
 | 
			
		||||
		if (constr_types.empty()) {
 | 
			
		||||
			constr_types.insert("$assert");
 | 
			
		||||
			constr_types.insert("$assume");
 | 
			
		||||
			constr_types.insert("$live");
 | 
			
		||||
			constr_types.insert("$fair");
 | 
			
		||||
			constr_types.insert("$cover");
 | 
			
		||||
			constr_types.insert(ID($assert));
 | 
			
		||||
			constr_types.insert(ID($assume));
 | 
			
		||||
			constr_types.insert(ID($live));
 | 
			
		||||
			constr_types.insert(ID($fair));
 | 
			
		||||
			constr_types.insert(ID($cover));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (mode == 0)
 | 
			
		||||
| 
						 | 
				
			
			@ -171,11 +171,11 @@ struct ChformalPass : public Pass {
 | 
			
		|||
 | 
			
		||||
				for (auto wire : module->wires())
 | 
			
		||||
				{
 | 
			
		||||
					if (wire->attributes.count("\\init") == 0)
 | 
			
		||||
					if (wire->attributes.count(ID::init) == 0)
 | 
			
		||||
						continue;
 | 
			
		||||
 | 
			
		||||
					SigSpec initsig = sigmap(wire);
 | 
			
		||||
					Const initval = wire->attributes.at("\\init");
 | 
			
		||||
					Const initval = wire->attributes.at(ID::init);
 | 
			
		||||
 | 
			
		||||
					for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++) {
 | 
			
		||||
						if (initval[i] == State::S0)
 | 
			
		||||
| 
						 | 
				
			
			@ -187,17 +187,17 @@ struct ChformalPass : public Pass {
 | 
			
		|||
 | 
			
		||||
				for (auto cell : module->selected_cells())
 | 
			
		||||
				{
 | 
			
		||||
					if (cell->type == "$ff") {
 | 
			
		||||
						SigSpec D = sigmap(cell->getPort("\\D"));
 | 
			
		||||
						SigSpec Q = sigmap(cell->getPort("\\Q"));
 | 
			
		||||
					if (cell->type == ID($ff)) {
 | 
			
		||||
						SigSpec D = sigmap(cell->getPort(ID::D));
 | 
			
		||||
						SigSpec Q = sigmap(cell->getPort(ID::Q));
 | 
			
		||||
						for (int i = 0; i < GetSize(D); i++)
 | 
			
		||||
							ffmap[Q[i]] = make_pair(D[i], make_pair(State::Sm, false));
 | 
			
		||||
					}
 | 
			
		||||
					if (cell->type == "$dff") {
 | 
			
		||||
						SigSpec D = sigmap(cell->getPort("\\D"));
 | 
			
		||||
						SigSpec Q = sigmap(cell->getPort("\\Q"));
 | 
			
		||||
						SigSpec C = sigmap(cell->getPort("\\CLK"));
 | 
			
		||||
						bool clockpol = cell->getParam("\\CLK_POLARITY").as_bool();
 | 
			
		||||
					if (cell->type == ID($dff)) {
 | 
			
		||||
						SigSpec D = sigmap(cell->getPort(ID::D));
 | 
			
		||||
						SigSpec Q = sigmap(cell->getPort(ID::Q));
 | 
			
		||||
						SigSpec C = sigmap(cell->getPort(ID::CLK));
 | 
			
		||||
						bool clockpol = cell->getParam(ID::CLK_POLARITY).as_bool();
 | 
			
		||||
						for (int i = 0; i < GetSize(D); i++)
 | 
			
		||||
							ffmap[Q[i]] = make_pair(D[i], make_pair(C, clockpol));
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			@ -206,15 +206,15 @@ struct ChformalPass : public Pass {
 | 
			
		|||
				for (auto cell : constr_cells)
 | 
			
		||||
					while (true)
 | 
			
		||||
					{
 | 
			
		||||
						SigSpec A = sigmap(cell->getPort("\\A"));
 | 
			
		||||
						SigSpec EN = sigmap(cell->getPort("\\EN"));
 | 
			
		||||
						SigSpec A = sigmap(cell->getPort(ID::A));
 | 
			
		||||
						SigSpec EN = sigmap(cell->getPort(ID::EN));
 | 
			
		||||
 | 
			
		||||
						if (ffmap.count(A) == 0 || ffmap.count(EN) == 0)
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						if (!init_zero.count(EN)) {
 | 
			
		||||
							if (cell->type == "$cover") break;
 | 
			
		||||
							if (cell->type.in("$assert", "$assume") && !init_one.count(A)) break;
 | 
			
		||||
							if (cell->type == ID($cover)) break;
 | 
			
		||||
							if (cell->type.in(ID($assert), ID($assume)) && !init_one.count(A)) break;
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						const auto &A_map = ffmap.at(A);
 | 
			
		||||
| 
						 | 
				
			
			@ -223,8 +223,8 @@ struct ChformalPass : public Pass {
 | 
			
		|||
						if (A_map.second != EN_map.second)
 | 
			
		||||
							break;
 | 
			
		||||
 | 
			
		||||
						cell->setPort("\\A", A_map.first);
 | 
			
		||||
						cell->setPort("\\EN", EN_map.first);
 | 
			
		||||
						cell->setPort(ID::A, A_map.first);
 | 
			
		||||
						cell->setPort(ID::EN, EN_map.first);
 | 
			
		||||
					}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
| 
						 | 
				
			
			@ -233,18 +233,18 @@ struct ChformalPass : public Pass {
 | 
			
		|||
				for (auto cell : constr_cells)
 | 
			
		||||
				for (int i = 0; i < mode_arg; i++)
 | 
			
		||||
				{
 | 
			
		||||
					SigSpec orig_a = cell->getPort("\\A");
 | 
			
		||||
					SigSpec orig_en = cell->getPort("\\EN");
 | 
			
		||||
					SigSpec orig_a = cell->getPort(ID::A);
 | 
			
		||||
					SigSpec orig_en = cell->getPort(ID::EN);
 | 
			
		||||
 | 
			
		||||
					Wire *new_a = module->addWire(NEW_ID);
 | 
			
		||||
					Wire *new_en = module->addWire(NEW_ID);
 | 
			
		||||
					new_en->attributes["\\init"] = State::S0;
 | 
			
		||||
					new_en->attributes[ID::init] = State::S0;
 | 
			
		||||
 | 
			
		||||
					module->addFf(NEW_ID, orig_a, new_a);
 | 
			
		||||
					module->addFf(NEW_ID, orig_en, new_en);
 | 
			
		||||
 | 
			
		||||
					cell->setPort("\\A", new_a);
 | 
			
		||||
					cell->setPort("\\EN", new_en);
 | 
			
		||||
					cell->setPort(ID::A, new_a);
 | 
			
		||||
					cell->setPort(ID::EN, new_en);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
| 
						 | 
				
			
			@ -254,26 +254,26 @@ struct ChformalPass : public Pass {
 | 
			
		|||
 | 
			
		||||
				for (int i = 0; i < mode_arg; i++) {
 | 
			
		||||
					Wire *w = module->addWire(NEW_ID);
 | 
			
		||||
					w->attributes["\\init"] = State::S0;
 | 
			
		||||
					w->attributes[ID::init] = State::S0;
 | 
			
		||||
					module->addFf(NEW_ID, en, w);
 | 
			
		||||
					en = w;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				for (auto cell : constr_cells)
 | 
			
		||||
					cell->setPort("\\EN", module->LogicAnd(NEW_ID, en, cell->getPort("\\EN")));
 | 
			
		||||
					cell->setPort(ID::EN, module->LogicAnd(NEW_ID, en, cell->getPort(ID::EN)));
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			if (mode == 'c')
 | 
			
		||||
			{
 | 
			
		||||
				for (auto cell : constr_cells)
 | 
			
		||||
					if (assert2assume && cell->type == "$assert")
 | 
			
		||||
						cell->type = "$assume";
 | 
			
		||||
					else if (assume2assert && cell->type == "$assume")
 | 
			
		||||
						cell->type = "$assert";
 | 
			
		||||
					else if (live2fair && cell->type == "$live")
 | 
			
		||||
						cell->type = "$fair";
 | 
			
		||||
					else if (fair2live && cell->type == "$fair")
 | 
			
		||||
						cell->type = "$live";
 | 
			
		||||
					if (assert2assume && cell->type == ID($assert))
 | 
			
		||||
						cell->type = ID($assume);
 | 
			
		||||
					else if (assume2assert && cell->type == ID($assume))
 | 
			
		||||
						cell->type = ID($assert);
 | 
			
		||||
					else if (live2fair && cell->type == ID($live))
 | 
			
		||||
						cell->type = ID($fair);
 | 
			
		||||
					else if (fair2live && cell->type == ID($fair))
 | 
			
		||||
						cell->type = ID($live);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,8 +107,8 @@ struct DeletePass : public Pass {
 | 
			
		|||
			for (auto &it : module->cells_) {
 | 
			
		||||
				if (design->selected(module, it.second))
 | 
			
		||||
					delete_cells.insert(it.second);
 | 
			
		||||
				if (it.second->type.in("$memrd", "$memwr") &&
 | 
			
		||||
						delete_mems.count(it.second->parameters.at("\\MEMID").decode_string()) != 0)
 | 
			
		||||
				if (it.second->type.in(ID($memrd), ID($memwr)) &&
 | 
			
		||||
						delete_mems.count(it.second->parameters.at(ID::MEMID).decode_string()) != 0)
 | 
			
		||||
					delete_cells.insert(it.second);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -207,7 +207,7 @@ struct DesignPass : public Pass {
 | 
			
		|||
			if (import_mode) {
 | 
			
		||||
				for (auto module : copy_src_modules)
 | 
			
		||||
				{
 | 
			
		||||
					if (module->get_bool_attribute("\\top")) {
 | 
			
		||||
					if (module->get_bool_attribute(ID::top)) {
 | 
			
		||||
						copy_src_modules.clear();
 | 
			
		||||
						copy_src_modules.push_back(module);
 | 
			
		||||
						break;
 | 
			
		||||
| 
						 | 
				
			
			@ -244,7 +244,7 @@ struct DesignPass : public Pass {
 | 
			
		|||
				RTLIL::Module *t = mod->clone();
 | 
			
		||||
				t->name = prefix;
 | 
			
		||||
				t->design = copy_to_design;
 | 
			
		||||
				t->attributes.erase("\\top");
 | 
			
		||||
				t->attributes.erase(ID::top);
 | 
			
		||||
				copy_to_design->add(t);
 | 
			
		||||
 | 
			
		||||
				queue.insert(t);
 | 
			
		||||
| 
						 | 
				
			
			@ -276,7 +276,7 @@ struct DesignPass : public Pass {
 | 
			
		|||
						RTLIL::Module *t = fmod->clone();
 | 
			
		||||
						t->name = trg_name;
 | 
			
		||||
						t->design = copy_to_design;
 | 
			
		||||
						t->attributes.erase("\\top");
 | 
			
		||||
						t->attributes.erase(ID::top);
 | 
			
		||||
						copy_to_design->add(t);
 | 
			
		||||
 | 
			
		||||
						queue.insert(t);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -737,7 +737,7 @@ struct QwpWorker
 | 
			
		|||
 | 
			
		||||
		for (auto &node : nodes)
 | 
			
		||||
			if (node.cell != nullptr)
 | 
			
		||||
				node.cell->attributes["\\qwp_position"] = stringf("%f %f", node.pos, node.alt_pos);
 | 
			
		||||
				node.cell->attributes[ID::qwp_position] = stringf("%f %f", node.pos, node.alt_pos);
 | 
			
		||||
 | 
			
		||||
		vector<double> edge_lengths;
 | 
			
		||||
		vector<double> weighted_edge_lengths;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -159,10 +159,10 @@ struct WbflipPass : public Pass {
 | 
			
		|||
			if (!design->selected(module))
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			if (module->get_bool_attribute("\\blackbox"))
 | 
			
		||||
			if (module->get_bool_attribute(ID::blackbox))
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			module->set_bool_attribute("\\whitebox", !module->get_bool_attribute("\\whitebox"));
 | 
			
		||||
			module->set_bool_attribute(ID::whitebox, !module->get_bool_attribute(ID::whitebox));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
} WbflipPass;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -360,10 +360,10 @@ struct SetundefPass : public Pass {
 | 
			
		|||
				pool<Wire*> initwires;
 | 
			
		||||
 | 
			
		||||
				pool<IdString> fftypes;
 | 
			
		||||
				fftypes.insert("$dff");
 | 
			
		||||
				fftypes.insert("$dffe");
 | 
			
		||||
				fftypes.insert("$dffsr");
 | 
			
		||||
				fftypes.insert("$adff");
 | 
			
		||||
				fftypes.insert(ID($dff));
 | 
			
		||||
				fftypes.insert(ID($dffe));
 | 
			
		||||
				fftypes.insert(ID($dffsr));
 | 
			
		||||
				fftypes.insert(ID($adff));
 | 
			
		||||
 | 
			
		||||
				std::vector<char> list_np = {'N', 'P'}, list_01 = {'0', '1'};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -389,7 +389,7 @@ struct SetundefPass : public Pass {
 | 
			
		|||
					if (!fftypes.count(cell->type))
 | 
			
		||||
						continue;
 | 
			
		||||
 | 
			
		||||
					for (auto bit : sigmap(cell->getPort("\\Q")))
 | 
			
		||||
					for (auto bit : sigmap(cell->getPort(ID::Q)))
 | 
			
		||||
						ffbits.insert(bit);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -411,7 +411,7 @@ struct SetundefPass : public Pass {
 | 
			
		|||
 | 
			
		||||
					for (auto wire : initwires)
 | 
			
		||||
					{
 | 
			
		||||
						Const &initval = wire->attributes["\\init"];
 | 
			
		||||
						Const &initval = wire->attributes[ID::init];
 | 
			
		||||
						initval.bits.resize(GetSize(wire), State::Sx);
 | 
			
		||||
 | 
			
		||||
						for (int i = 0; i < GetSize(wire); i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -423,7 +423,7 @@ struct SetundefPass : public Pass {
 | 
			
		|||
						}
 | 
			
		||||
 | 
			
		||||
						if (initval.is_fully_undef())
 | 
			
		||||
							wire->attributes.erase("\\init");
 | 
			
		||||
							wire->attributes.erase(ID::init);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					initwires.clear();
 | 
			
		||||
| 
						 | 
				
			
			@ -439,14 +439,14 @@ struct SetundefPass : public Pass {
 | 
			
		|||
							if (wire->name[0] == (wire_types ? '\\' : '$'))
 | 
			
		||||
								continue;
 | 
			
		||||
 | 
			
		||||
							if (!wire->attributes.count("\\init"))
 | 
			
		||||
							if (!wire->attributes.count(ID::init))
 | 
			
		||||
								continue;
 | 
			
		||||
 | 
			
		||||
							Const &initval = wire->attributes["\\init"];
 | 
			
		||||
							Const &initval = wire->attributes[ID::init];
 | 
			
		||||
							initval.bits.resize(GetSize(wire), State::Sx);
 | 
			
		||||
 | 
			
		||||
							if (initval.is_fully_undef()) {
 | 
			
		||||
								wire->attributes.erase("\\init");
 | 
			
		||||
								wire->attributes.erase(ID::init);
 | 
			
		||||
								continue;
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -482,8 +482,8 @@ struct ShowWorker
 | 
			
		|||
			}
 | 
			
		||||
 | 
			
		||||
			std::string proc_src = RTLIL::unescape_id(proc->name);
 | 
			
		||||
			if (proc->attributes.count("\\src") > 0)
 | 
			
		||||
				proc_src = proc->attributes.at("\\src").decode_string();
 | 
			
		||||
			if (proc->attributes.count(ID::src) > 0)
 | 
			
		||||
				proc_src = proc->attributes.at(ID::src).decode_string();
 | 
			
		||||
			fprintf(f, "p%d [shape=box, style=rounded, label=\"PROC %s\\n%s\"];\n", pidx, findLabel(proc->name.str()), proc_src.c_str());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,13 +75,13 @@ struct SpliceWorker
 | 
			
		|||
		RTLIL::SigSpec new_sig = sig;
 | 
			
		||||
 | 
			
		||||
		if (sig_a.size() != sig.size()) {
 | 
			
		||||
			RTLIL::Cell *cell = module->addCell(NEW_ID, "$slice");
 | 
			
		||||
			cell->parameters["\\OFFSET"] = offset;
 | 
			
		||||
			cell->parameters["\\A_WIDTH"] = sig_a.size();
 | 
			
		||||
			cell->parameters["\\Y_WIDTH"] = sig.size();
 | 
			
		||||
			cell->setPort("\\A", sig_a);
 | 
			
		||||
			cell->setPort("\\Y", module->addWire(NEW_ID, sig.size()));
 | 
			
		||||
			new_sig = cell->getPort("\\Y");
 | 
			
		||||
			RTLIL::Cell *cell = module->addCell(NEW_ID, ID($slice));
 | 
			
		||||
			cell->parameters[ID::OFFSET] = offset;
 | 
			
		||||
			cell->parameters[ID::A_WIDTH] = sig_a.size();
 | 
			
		||||
			cell->parameters[ID::Y_WIDTH] = sig.size();
 | 
			
		||||
			cell->setPort(ID::A, sig_a);
 | 
			
		||||
			cell->setPort(ID::Y, module->addWire(NEW_ID, sig.size()));
 | 
			
		||||
			new_sig = cell->getPort(ID::Y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		sliced_signals_cache[sig] = new_sig;
 | 
			
		||||
| 
						 | 
				
			
			@ -132,13 +132,13 @@ struct SpliceWorker
 | 
			
		|||
		RTLIL::SigSpec new_sig = get_sliced_signal(chunks.front());
 | 
			
		||||
		for (size_t i = 1; i < chunks.size(); i++) {
 | 
			
		||||
			RTLIL::SigSpec sig2 = get_sliced_signal(chunks[i]);
 | 
			
		||||
			RTLIL::Cell *cell = module->addCell(NEW_ID, "$concat");
 | 
			
		||||
			cell->parameters["\\A_WIDTH"] = new_sig.size();
 | 
			
		||||
			cell->parameters["\\B_WIDTH"] = sig2.size();
 | 
			
		||||
			cell->setPort("\\A", new_sig);
 | 
			
		||||
			cell->setPort("\\B", sig2);
 | 
			
		||||
			cell->setPort("\\Y", module->addWire(NEW_ID, new_sig.size() + sig2.size()));
 | 
			
		||||
			new_sig = cell->getPort("\\Y");
 | 
			
		||||
			RTLIL::Cell *cell = module->addCell(NEW_ID, ID($concat));
 | 
			
		||||
			cell->parameters[ID::A_WIDTH] = new_sig.size();
 | 
			
		||||
			cell->parameters[ID::B_WIDTH] = sig2.size();
 | 
			
		||||
			cell->setPort(ID::A, new_sig);
 | 
			
		||||
			cell->setPort(ID::B, sig2);
 | 
			
		||||
			cell->setPort(ID::Y, module->addWire(NEW_ID, new_sig.size() + sig2.size()));
 | 
			
		||||
			new_sig = cell->getPort(ID::Y);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		spliced_signals_cache[sig] = new_sig;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,17 +60,17 @@ struct SplitnetsWorker
 | 
			
		|||
		new_wire->port_input = wire->port_input;
 | 
			
		||||
		new_wire->port_output = wire->port_output;
 | 
			
		||||
 | 
			
		||||
		if (wire->attributes.count("\\src"))
 | 
			
		||||
			new_wire->attributes["\\src"] = wire->attributes.at("\\src");
 | 
			
		||||
		if (wire->attributes.count(ID::src))
 | 
			
		||||
			new_wire->attributes[ID::src] = wire->attributes.at(ID::src);
 | 
			
		||||
 | 
			
		||||
		if (wire->attributes.count("\\keep"))
 | 
			
		||||
			new_wire->attributes["\\keep"] = wire->attributes.at("\\keep");
 | 
			
		||||
		if (wire->attributes.count(ID::keep))
 | 
			
		||||
			new_wire->attributes[ID::keep] = wire->attributes.at(ID::keep);
 | 
			
		||||
 | 
			
		||||
		if (wire->attributes.count("\\init")) {
 | 
			
		||||
			Const old_init = wire->attributes.at("\\init"), new_init;
 | 
			
		||||
		if (wire->attributes.count(ID::init)) {
 | 
			
		||||
			Const old_init = wire->attributes.at(ID::init), new_init;
 | 
			
		||||
			for (int i = offset; i < offset+width; i++)
 | 
			
		||||
				new_init.bits.push_back(i < GetSize(old_init) ? old_init.bits.at(i) : State::Sx);
 | 
			
		||||
			new_wire->attributes["\\init"] = new_init;
 | 
			
		||||
			new_wire->attributes[ID::init] = new_init;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		std::vector<RTLIL::SigBit> sigvec = RTLIL::SigSpec(new_wire).to_sigbit_vector();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -109,22 +109,22 @@ struct statdata_t
 | 
			
		|||
 | 
			
		||||
			if (width_mode)
 | 
			
		||||
			{
 | 
			
		||||
				if (cell_type.in("$not", "$pos", "$neg",
 | 
			
		||||
						"$logic_not", "$logic_and", "$logic_or",
 | 
			
		||||
						"$reduce_and", "$reduce_or", "$reduce_xor", "$reduce_xnor", "$reduce_bool",
 | 
			
		||||
						"$lut", "$and", "$or", "$xor", "$xnor",
 | 
			
		||||
						"$shl", "$shr", "$sshl", "$sshr", "$shift", "$shiftx",
 | 
			
		||||
						"$lt", "$le", "$eq", "$ne", "$eqx", "$nex", "$ge", "$gt",
 | 
			
		||||
						"$add", "$sub", "$mul", "$div", "$mod", "$pow", "$alu")) {
 | 
			
		||||
					int width_a = it.second->hasPort("\\A") ? GetSize(it.second->getPort("\\A")) : 0;
 | 
			
		||||
					int width_b = it.second->hasPort("\\B") ? GetSize(it.second->getPort("\\B")) : 0;
 | 
			
		||||
					int width_y = it.second->hasPort("\\Y") ? GetSize(it.second->getPort("\\Y")) : 0;
 | 
			
		||||
				if (cell_type.in(ID($not), ID($pos), ID($neg),
 | 
			
		||||
						ID($logic_not), ID($logic_and), ID($logic_or),
 | 
			
		||||
						ID($reduce_and), ID($reduce_or), ID($reduce_xor), ID($reduce_xnor), ID($reduce_bool),
 | 
			
		||||
						ID($lut), ID($and), ID($or), ID($xor), ID($xnor),
 | 
			
		||||
						ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx),
 | 
			
		||||
						ID($lt), ID($le), ID($eq), ID($ne), ID($eqx), ID($nex), ID($ge), ID($gt),
 | 
			
		||||
						ID($add), ID($sub), ID($mul), ID($div), ID($mod), ID($pow), ID($alu))) {
 | 
			
		||||
					int width_a = it.second->hasPort(ID::A) ? GetSize(it.second->getPort(ID::A)) : 0;
 | 
			
		||||
					int width_b = it.second->hasPort(ID::B) ? GetSize(it.second->getPort(ID::B)) : 0;
 | 
			
		||||
					int width_y = it.second->hasPort(ID::Y) ? GetSize(it.second->getPort(ID::Y)) : 0;
 | 
			
		||||
					cell_type = stringf("%s_%d", cell_type.c_str(), max<int>({width_a, width_b, width_y}));
 | 
			
		||||
				}
 | 
			
		||||
				else if (cell_type.in("$mux", "$pmux"))
 | 
			
		||||
					cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(it.second->getPort("\\Y")));
 | 
			
		||||
				else if (cell_type.in("$sr", "$dff", "$dffsr", "$adff", "$dlatch", "$dlatchsr"))
 | 
			
		||||
					cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(it.second->getPort("\\Q")));
 | 
			
		||||
				else if (cell_type.in(ID($mux), ID($pmux)))
 | 
			
		||||
					cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(it.second->getPort(ID::Y)));
 | 
			
		||||
				else if (cell_type.in(ID($sr), ID($dff), ID($dffsr), ID($adff), ID($dlatch), ID($dlatchsr)))
 | 
			
		||||
					cell_type = stringf("%s_%d", cell_type.c_str(), GetSize(it.second->getPort(ID::Q)));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (!cell_area.empty()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -172,12 +172,12 @@ struct statdata_t
 | 
			
		|||
 | 
			
		||||
		if (tech == "xilinx")
 | 
			
		||||
		{
 | 
			
		||||
			int lut6_cnt = num_cells_by_type["\\LUT6"];
 | 
			
		||||
			int lut5_cnt = num_cells_by_type["\\LUT5"];
 | 
			
		||||
			int lut4_cnt = num_cells_by_type["\\LUT4"];
 | 
			
		||||
			int lut3_cnt = num_cells_by_type["\\LUT3"];
 | 
			
		||||
			int lut2_cnt = num_cells_by_type["\\LUT2"];
 | 
			
		||||
			int lut1_cnt = num_cells_by_type["\\LUT1"];
 | 
			
		||||
			int lut6_cnt = num_cells_by_type[ID(LUT6)];
 | 
			
		||||
			int lut5_cnt = num_cells_by_type[ID(LUT5)];
 | 
			
		||||
			int lut4_cnt = num_cells_by_type[ID(LUT4)];
 | 
			
		||||
			int lut3_cnt = num_cells_by_type[ID(LUT3)];
 | 
			
		||||
			int lut2_cnt = num_cells_by_type[ID(LUT2)];
 | 
			
		||||
			int lut1_cnt = num_cells_by_type[ID(LUT1)];
 | 
			
		||||
			int lc_cnt = 0;
 | 
			
		||||
 | 
			
		||||
			lc_cnt += lut6_cnt;
 | 
			
		||||
| 
						 | 
				
			
			@ -235,7 +235,7 @@ struct statdata_t
 | 
			
		|||
 | 
			
		||||
				if (gate_costs.count(ctype))
 | 
			
		||||
					tran_cnt += cnum * gate_costs.at(ctype);
 | 
			
		||||
				else if (ctype.in("$_DFF_P_", "$_DFF_N_"))
 | 
			
		||||
				else if (ctype.in(ID($_DFF_P_), ID($_DFF_N_)))
 | 
			
		||||
					tran_cnt += cnum * 16;
 | 
			
		||||
				else
 | 
			
		||||
					tran_cnt_exact = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -357,7 +357,7 @@ struct StatPass : public Pass {
 | 
			
		|||
		for (auto mod : design->selected_modules())
 | 
			
		||||
		{
 | 
			
		||||
			if (!top_mod && design->full_selection())
 | 
			
		||||
				if (mod->get_bool_attribute("\\top"))
 | 
			
		||||
				if (mod->get_bool_attribute(ID::top))
 | 
			
		||||
					top_mod = mod;
 | 
			
		||||
 | 
			
		||||
			statdata_t data(design, mod, width_mode, cell_area, techname);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,9 +81,9 @@ struct TorderPass : public Pass {
 | 
			
		|||
					continue;
 | 
			
		||||
 | 
			
		||||
				if (!noautostop && yosys_celltypes.cell_known(cell->type)) {
 | 
			
		||||
					if (conn.first.in("\\Q", "\\CTRL_OUT", "\\RD_DATA"))
 | 
			
		||||
					if (conn.first.in(ID::Q, ID::CTRL_OUT, ID::RD_DATA))
 | 
			
		||||
						continue;
 | 
			
		||||
					if (cell->type == "$memrd" && conn.first == "\\DATA")
 | 
			
		||||
					if (cell->type == ID($memrd) && conn.first == ID::DATA)
 | 
			
		||||
						continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -152,7 +152,7 @@ struct EquivAddPass : public Pass {
 | 
			
		|||
 | 
			
		||||
			for (int i = 0; i < GetSize(gold_signal); i++) {
 | 
			
		||||
				Cell *equiv_cell = module->addEquiv(NEW_ID, gold_signal[i], gate_signal[i], equiv_signal[i]);
 | 
			
		||||
				equiv_cell->set_bool_attribute("\\keep");
 | 
			
		||||
				equiv_cell->set_bool_attribute(ID::keep);
 | 
			
		||||
				to_equiv_bits[gold_signal[i]] = equiv_signal[i];
 | 
			
		||||
				to_equiv_bits[gate_signal[i]] = equiv_signal[i];
 | 
			
		||||
				added_equiv_cells.insert(equiv_cell);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,9 +58,9 @@ struct EquivInductWorker
 | 
			
		|||
				log_warning("No SAT model available for cell %s (%s).\n", log_id(cell), log_id(cell->type));
 | 
			
		||||
				cell_warn_cache.insert(cell);
 | 
			
		||||
			}
 | 
			
		||||
			if (cell->type == "$equiv") {
 | 
			
		||||
				SigBit bit_a = sigmap(cell->getPort("\\A")).as_bit();
 | 
			
		||||
				SigBit bit_b = sigmap(cell->getPort("\\B")).as_bit();
 | 
			
		||||
			if (cell->type == ID($equiv)) {
 | 
			
		||||
				SigBit bit_a = sigmap(cell->getPort(ID::A)).as_bit();
 | 
			
		||||
				SigBit bit_b = sigmap(cell->getPort(ID::B)).as_bit();
 | 
			
		||||
				if (bit_a != bit_b) {
 | 
			
		||||
					int ez_a = satgen.importSigBit(bit_a, step);
 | 
			
		||||
					int ez_b = satgen.importSigBit(bit_b, step);
 | 
			
		||||
| 
						 | 
				
			
			@ -125,7 +125,7 @@ struct EquivInductWorker
 | 
			
		|||
			if (!ez->solve(new_step_not_consistent)) {
 | 
			
		||||
				log("  Proof for induction step holds. Entire workset of %d cells proven!\n", GetSize(workset));
 | 
			
		||||
				for (auto cell : workset)
 | 
			
		||||
					cell->setPort("\\B", cell->getPort("\\A"));
 | 
			
		||||
					cell->setPort(ID::B, cell->getPort(ID::A));
 | 
			
		||||
				success_counter += GetSize(workset);
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -137,10 +137,10 @@ struct EquivInductWorker
 | 
			
		|||
 | 
			
		||||
		for (auto cell : workset)
 | 
			
		||||
		{
 | 
			
		||||
			SigBit bit_a = sigmap(cell->getPort("\\A")).as_bit();
 | 
			
		||||
			SigBit bit_b = sigmap(cell->getPort("\\B")).as_bit();
 | 
			
		||||
			SigBit bit_a = sigmap(cell->getPort(ID::A)).as_bit();
 | 
			
		||||
			SigBit bit_b = sigmap(cell->getPort(ID::B)).as_bit();
 | 
			
		||||
 | 
			
		||||
			log("  Trying to prove $equiv for %s:", log_signal(sigmap(cell->getPort("\\Y"))));
 | 
			
		||||
			log("  Trying to prove $equiv for %s:", log_signal(sigmap(cell->getPort(ID::Y))));
 | 
			
		||||
 | 
			
		||||
			int ez_a = satgen.importSigBit(bit_a, max_seq+1);
 | 
			
		||||
			int ez_b = satgen.importSigBit(bit_b, max_seq+1);
 | 
			
		||||
| 
						 | 
				
			
			@ -151,7 +151,7 @@ struct EquivInductWorker
 | 
			
		|||
 | 
			
		||||
			if (!ez->solve(cond)) {
 | 
			
		||||
				log(" success!\n");
 | 
			
		||||
				cell->setPort("\\B", cell->getPort("\\A"));
 | 
			
		||||
				cell->setPort(ID::B, cell->getPort(ID::A));
 | 
			
		||||
				success_counter++;
 | 
			
		||||
			} else {
 | 
			
		||||
				log(" failed.\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -219,8 +219,8 @@ struct EquivInductPass : public Pass {
 | 
			
		|||
			pool<Cell*> unproven_equiv_cells;
 | 
			
		||||
 | 
			
		||||
			for (auto cell : module->selected_cells())
 | 
			
		||||
				if (cell->type == "$equiv") {
 | 
			
		||||
					if (cell->getPort("\\A") != cell->getPort("\\B"))
 | 
			
		||||
				if (cell->type == ID($equiv)) {
 | 
			
		||||
					if (cell->getPort(ID::A) != cell->getPort(ID::B))
 | 
			
		||||
						unproven_equiv_cells.insert(cell);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -406,7 +406,7 @@ struct EquivMakeWorker
 | 
			
		|||
	void init_bit2driven()
 | 
			
		||||
	{
 | 
			
		||||
		for (auto cell : equiv_mod->cells()) {
 | 
			
		||||
			if (!ct.cell_known(cell->type) && !cell->type.in("$dff", "$_DFF_P_", "$_DFF_N_", "$ff", "$_FF_"))
 | 
			
		||||
			if (!ct.cell_known(cell->type) && !cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_), ID($ff), ID($_FF_)))
 | 
			
		||||
				continue;
 | 
			
		||||
			for (auto &conn : cell->connections())
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ struct EquivMarkWorker
 | 
			
		|||
	{
 | 
			
		||||
		for (auto cell : module->cells())
 | 
			
		||||
		{
 | 
			
		||||
			if (cell->type == "$equiv")
 | 
			
		||||
			if (cell->type == ID($equiv))
 | 
			
		||||
				equiv_cells.insert(cell->name);
 | 
			
		||||
 | 
			
		||||
			for (auto &port : cell->connections())
 | 
			
		||||
| 
						 | 
				
			
			@ -122,8 +122,8 @@ struct EquivMarkWorker
 | 
			
		|||
		{
 | 
			
		||||
			auto cell = module->cell(cell_name);
 | 
			
		||||
 | 
			
		||||
			SigSpec sig_a = sigmap(cell->getPort("\\A"));
 | 
			
		||||
			SigSpec sig_b = sigmap(cell->getPort("\\B"));
 | 
			
		||||
			SigSpec sig_a = sigmap(cell->getPort(ID::A));
 | 
			
		||||
			SigSpec sig_b = sigmap(cell->getPort(ID::B));
 | 
			
		||||
 | 
			
		||||
			if (sig_a == sig_b) {
 | 
			
		||||
				for (auto bit : sig_a)
 | 
			
		||||
| 
						 | 
				
			
			@ -139,11 +139,11 @@ struct EquivMarkWorker
 | 
			
		|||
 | 
			
		||||
		for (auto cell : module->cells())
 | 
			
		||||
		{
 | 
			
		||||
			if (cell_regions.count(cell->name) || cell->type != "$equiv")
 | 
			
		||||
			if (cell_regions.count(cell->name) || cell->type != ID($equiv))
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			SigSpec sig_a = sigmap(cell->getPort("\\A"));
 | 
			
		||||
			SigSpec sig_b = sigmap(cell->getPort("\\B"));
 | 
			
		||||
			SigSpec sig_a = sigmap(cell->getPort(ID::A));
 | 
			
		||||
			SigSpec sig_b = sigmap(cell->getPort(ID::B));
 | 
			
		||||
 | 
			
		||||
			log_assert(sig_a != sig_b);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -176,10 +176,10 @@ struct EquivMarkWorker
 | 
			
		|||
		{
 | 
			
		||||
			if (cell_regions.count(cell->name)) {
 | 
			
		||||
				int r = final_region_map.at(cell_regions.at(cell->name));
 | 
			
		||||
				cell->attributes["\\equiv_region"] = Const(r);
 | 
			
		||||
				cell->attributes[ID::equiv_region] = Const(r);
 | 
			
		||||
				region_cell_count[r]++;
 | 
			
		||||
			} else
 | 
			
		||||
				cell->attributes.erase("\\equiv_region");
 | 
			
		||||
				cell->attributes.erase(ID::equiv_region);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (auto wire : module->wires())
 | 
			
		||||
| 
						 | 
				
			
			@ -191,10 +191,10 @@ struct EquivMarkWorker
 | 
			
		|||
 | 
			
		||||
			if (GetSize(regions) == 1) {
 | 
			
		||||
				int r = final_region_map.at(*regions.begin());
 | 
			
		||||
				wire->attributes["\\equiv_region"] = Const(r);
 | 
			
		||||
				wire->attributes[ID::equiv_region] = Const(r);
 | 
			
		||||
				region_wire_count[r]++;
 | 
			
		||||
			} else
 | 
			
		||||
				wire->attributes.erase("\\equiv_region");
 | 
			
		||||
				wire->attributes.erase(ID::equiv_region);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < next_final_region; i++)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,7 +47,7 @@ struct EquivMiterWorker
 | 
			
		|||
		if (cone.count(c))
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		if (c->type == "$equiv" && !seed_cells.count(c)) {
 | 
			
		||||
		if (c->type == ID($equiv) && !seed_cells.count(c)) {
 | 
			
		||||
			leaves.insert(c);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +57,7 @@ struct EquivMiterWorker
 | 
			
		|||
		for (auto &conn : c->connections()) {
 | 
			
		||||
			if (!ct.cell_input(c->type, conn.first))
 | 
			
		||||
				continue;
 | 
			
		||||
			if (c->type == "$equiv" && (conn.first == "\\A") != gold_mode)
 | 
			
		||||
			if (c->type == ID($equiv) && (conn.first == ID::A) != gold_mode)
 | 
			
		||||
				continue;
 | 
			
		||||
			for (auto bit : sigmap(conn.second))
 | 
			
		||||
				if (bit_to_driver.count(bit))
 | 
			
		||||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ struct EquivMiterWorker
 | 
			
		|||
		// find seed cells
 | 
			
		||||
 | 
			
		||||
		for (auto c : source_module->selected_cells())
 | 
			
		||||
			if (c->type == "$equiv") {
 | 
			
		||||
			if (c->type == ID($equiv)) {
 | 
			
		||||
				log("Seed $equiv cell: %s\n", log_id(c));
 | 
			
		||||
				seed_cells.insert(c);
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -213,18 +213,18 @@ struct EquivMiterWorker
 | 
			
		|||
		vector<Cell*> equiv_cells;
 | 
			
		||||
 | 
			
		||||
		for (auto c : miter_module->cells())
 | 
			
		||||
			if (c->type == "$equiv" && c->getPort("\\A") != c->getPort("\\B"))
 | 
			
		||||
			if (c->type == ID($equiv) && c->getPort(ID::A) != c->getPort(ID::B))
 | 
			
		||||
				equiv_cells.push_back(c);
 | 
			
		||||
 | 
			
		||||
		for (auto c : equiv_cells)
 | 
			
		||||
		{
 | 
			
		||||
			SigSpec cmp = mode_undef ?
 | 
			
		||||
					miter_module->LogicOr(NEW_ID, miter_module->Eqx(NEW_ID, c->getPort("\\A"), State::Sx),
 | 
			
		||||
							miter_module->Eqx(NEW_ID, c->getPort("\\A"), c->getPort("\\B"))) :
 | 
			
		||||
					miter_module->Eq(NEW_ID, c->getPort("\\A"), c->getPort("\\B"));
 | 
			
		||||
					miter_module->LogicOr(NEW_ID, miter_module->Eqx(NEW_ID, c->getPort(ID::A), State::Sx),
 | 
			
		||||
							miter_module->Eqx(NEW_ID, c->getPort(ID::A), c->getPort(ID::B))) :
 | 
			
		||||
					miter_module->Eq(NEW_ID, c->getPort(ID::A), c->getPort(ID::B));
 | 
			
		||||
 | 
			
		||||
			if (mode_cmp) {
 | 
			
		||||
				string cmp_name = string("\\cmp") + log_signal(c->getPort("\\Y"));
 | 
			
		||||
				string cmp_name = stringf("\\cmp%s", log_signal(c->getPort(ID::Y)));
 | 
			
		||||
				for (int i = 1; i < GetSize(cmp_name); i++)
 | 
			
		||||
					if (cmp_name[i] == '\\')
 | 
			
		||||
						cmp_name[i] = '_';
 | 
			
		||||
| 
						 | 
				
			
			@ -242,7 +242,7 @@ struct EquivMiterWorker
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		if (mode_trigger) {
 | 
			
		||||
			auto w = miter_module->addWire("\\trigger");
 | 
			
		||||
			auto w = miter_module->addWire(ID(trigger));
 | 
			
		||||
			w->port_output = true;
 | 
			
		||||
			miter_module->addReduceOr(NEW_ID, trigger_signals, w);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -102,7 +102,7 @@ struct EquivPurgeWorker
 | 
			
		|||
 | 
			
		||||
		for (auto cell : module->cells())
 | 
			
		||||
		{
 | 
			
		||||
			if (cell->type != "$equiv") {
 | 
			
		||||
			if (cell->type != ID($equiv)) {
 | 
			
		||||
				for (auto &port : cell->connections()) {
 | 
			
		||||
					if (cell->input(port.first))
 | 
			
		||||
						for (auto bit : sigmap(port.second))
 | 
			
		||||
| 
						 | 
				
			
			@ -114,9 +114,9 @@ struct EquivPurgeWorker
 | 
			
		|||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			SigSpec sig_a = sigmap(cell->getPort("\\A"));
 | 
			
		||||
			SigSpec sig_b = sigmap(cell->getPort("\\B"));
 | 
			
		||||
			SigSpec sig_y = sigmap(cell->getPort("\\Y"));
 | 
			
		||||
			SigSpec sig_a = sigmap(cell->getPort(ID::A));
 | 
			
		||||
			SigSpec sig_b = sigmap(cell->getPort(ID::B));
 | 
			
		||||
			SigSpec sig_y = sigmap(cell->getPort(ID::Y));
 | 
			
		||||
 | 
			
		||||
			if (sig_a == sig_b)
 | 
			
		||||
				continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -130,7 +130,7 @@ struct EquivPurgeWorker
 | 
			
		|||
			for (auto bit : sig_y)
 | 
			
		||||
				visited.insert(bit);
 | 
			
		||||
 | 
			
		||||
			cell->setPort("\\Y", make_output(sig_y, cell->name));
 | 
			
		||||
			cell->setPort(ID::Y, make_output(sig_y, cell->name));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		SigSpec srcsig;
 | 
			
		||||
| 
						 | 
				
			
			@ -167,8 +167,8 @@ struct EquivPurgeWorker
 | 
			
		|||
				rewrite_sigmap.add(chunk, make_input(chunk));
 | 
			
		||||
 | 
			
		||||
		for (auto cell : module->cells())
 | 
			
		||||
			if (cell->type == "$equiv")
 | 
			
		||||
				cell->setPort("\\Y", rewrite_sigmap(sigmap(cell->getPort("\\Y"))));
 | 
			
		||||
			if (cell->type == ID($equiv))
 | 
			
		||||
				cell->setPort(ID::Y, rewrite_sigmap(sigmap(cell->getPort(ID::Y))));
 | 
			
		||||
 | 
			
		||||
		module->fixup_ports();
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -68,9 +68,9 @@ struct EquivRemovePass : public Pass {
 | 
			
		|||
		for (auto module : design->selected_modules())
 | 
			
		||||
		{
 | 
			
		||||
			for (auto cell : module->selected_cells())
 | 
			
		||||
				if (cell->type == "$equiv" && (mode_gold || mode_gate || cell->getPort("\\A") == cell->getPort("\\B"))) {
 | 
			
		||||
					log("Removing $equiv cell %s.%s (%s).\n", log_id(module), log_id(cell), log_signal(cell->getPort("\\Y")));
 | 
			
		||||
					module->connect(cell->getPort("\\Y"), mode_gate ? cell->getPort("\\B") : cell->getPort("\\A"));
 | 
			
		||||
				if (cell->type == ID($equiv) && (mode_gold || mode_gate || cell->getPort(ID::A) == cell->getPort(ID::B))) {
 | 
			
		||||
					log("Removing $equiv cell %s.%s (%s).\n", log_id(module), log_id(cell), log_signal(cell->getPort(ID::Y)));
 | 
			
		||||
					module->connect(cell->getPort(ID::Y), mode_gate ? cell->getPort(ID::B) : cell->getPort(ID::A));
 | 
			
		||||
					module->remove(cell);
 | 
			
		||||
					remove_count++;
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,8 +60,8 @@ struct EquivSimpleWorker
 | 
			
		|||
		for (auto &conn : cell->connections())
 | 
			
		||||
			if (yosys_celltypes.cell_input(cell->type, conn.first))
 | 
			
		||||
				for (auto bit : sigmap(conn.second)) {
 | 
			
		||||
					if (cell->type.in("$dff", "$_DFF_P_", "$_DFF_N_", "$ff", "$_FF_")) {
 | 
			
		||||
						if (!conn.first.in("\\CLK", "\\C"))
 | 
			
		||||
					if (cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_), ID($ff), ID($_FF_))) {
 | 
			
		||||
						if (!conn.first.in(ID::CLK, ID::C))
 | 
			
		||||
							next_seed.insert(bit);
 | 
			
		||||
					} else
 | 
			
		||||
						find_input_cone(next_seed, cells_cone, bits_cone, cells_stop, bits_stop, input_bits, bit);
 | 
			
		||||
| 
						 | 
				
			
			@ -90,8 +90,8 @@ struct EquivSimpleWorker
 | 
			
		|||
 | 
			
		||||
	bool run_cell()
 | 
			
		||||
	{
 | 
			
		||||
		SigBit bit_a = sigmap(equiv_cell->getPort("\\A")).as_bit();
 | 
			
		||||
		SigBit bit_b = sigmap(equiv_cell->getPort("\\B")).as_bit();
 | 
			
		||||
		SigBit bit_a = sigmap(equiv_cell->getPort(ID::A)).as_bit();
 | 
			
		||||
		SigBit bit_b = sigmap(equiv_cell->getPort(ID::B)).as_bit();
 | 
			
		||||
		int ez_context = ez->frozen_literal();
 | 
			
		||||
 | 
			
		||||
		if (satgen.model_undef)
 | 
			
		||||
| 
						 | 
				
			
			@ -115,9 +115,9 @@ struct EquivSimpleWorker
 | 
			
		|||
 | 
			
		||||
		if (verbose) {
 | 
			
		||||
			log("  Trying to prove $equiv cell %s:\n", log_id(equiv_cell));
 | 
			
		||||
			log("    A = %s, B = %s, Y = %s\n", log_signal(bit_a), log_signal(bit_b), log_signal(equiv_cell->getPort("\\Y")));
 | 
			
		||||
			log("    A = %s, B = %s, Y = %s\n", log_signal(bit_a), log_signal(bit_b), log_signal(equiv_cell->getPort(ID::Y)));
 | 
			
		||||
		} else {
 | 
			
		||||
			log("  Trying to prove $equiv for %s:", log_signal(equiv_cell->getPort("\\Y")));
 | 
			
		||||
			log("  Trying to prove $equiv for %s:", log_signal(equiv_cell->getPort(ID::Y)));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		int step = max_seq;
 | 
			
		||||
| 
						 | 
				
			
			@ -199,7 +199,7 @@ struct EquivSimpleWorker
 | 
			
		|||
 | 
			
		||||
			if (!ez->solve(ez_context)) {
 | 
			
		||||
				log(verbose ? "    Proved equivalence! Marking $equiv cell as proven.\n" : " success!\n");
 | 
			
		||||
				equiv_cell->setPort("\\B", equiv_cell->getPort("\\A"));
 | 
			
		||||
				equiv_cell->setPort(ID::B, equiv_cell->getPort(ID::A));
 | 
			
		||||
				ez->assume(ez->NOT(ez_context));
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -256,7 +256,7 @@ struct EquivSimpleWorker
 | 
			
		|||
		if (GetSize(equiv_cells) > 1) {
 | 
			
		||||
			SigSpec sig;
 | 
			
		||||
			for (auto c : equiv_cells)
 | 
			
		||||
				sig.append(sigmap(c->getPort("\\Y")));
 | 
			
		||||
				sig.append(sigmap(c->getPort(ID::Y)));
 | 
			
		||||
			log(" Grouping SAT models for %s:\n", log_signal(sig));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -344,8 +344,8 @@ struct EquivSimplePass : public Pass {
 | 
			
		|||
			int unproven_cells_counter = 0;
 | 
			
		||||
 | 
			
		||||
			for (auto cell : module->selected_cells())
 | 
			
		||||
				if (cell->type == "$equiv" && cell->getPort("\\A") != cell->getPort("\\B")) {
 | 
			
		||||
					auto bit = sigmap(cell->getPort("\\Y").as_bit());
 | 
			
		||||
				if (cell->type == ID($equiv) && cell->getPort(ID::A) != cell->getPort(ID::B)) {
 | 
			
		||||
					auto bit = sigmap(cell->getPort(ID::Y).as_bit());
 | 
			
		||||
					auto bit_group = bit;
 | 
			
		||||
					if (!nogroup && bit_group.wire)
 | 
			
		||||
						bit_group.offset = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -360,7 +360,7 @@ struct EquivSimplePass : public Pass {
 | 
			
		|||
					unproven_cells_counter, GetSize(unproven_equiv_cells), log_id(module));
 | 
			
		||||
 | 
			
		||||
			for (auto cell : module->cells()) {
 | 
			
		||||
				if (!ct.cell_known(cell->type) && !cell->type.in("$dff", "$_DFF_P_", "$_DFF_N_", "$ff", "$_FF_"))
 | 
			
		||||
				if (!ct.cell_known(cell->type) && !cell->type.in(ID($dff), ID($_DFF_P_), ID($_DFF_N_), ID($ff), ID($_FF_)))
 | 
			
		||||
					continue;
 | 
			
		||||
				for (auto &conn : cell->connections())
 | 
			
		||||
					if (yosys_celltypes.cell_output(cell->type, conn.first))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,8 +59,8 @@ struct EquivStatusPass : public Pass {
 | 
			
		|||
			int proven_equiv_cells = 0;
 | 
			
		||||
 | 
			
		||||
			for (auto cell : module->selected_cells())
 | 
			
		||||
				if (cell->type == "$equiv") {
 | 
			
		||||
					if (cell->getPort("\\A") != cell->getPort("\\B"))
 | 
			
		||||
				if (cell->type == ID($equiv)) {
 | 
			
		||||
					if (cell->getPort(ID::A) != cell->getPort(ID::B))
 | 
			
		||||
						unproven_equiv_cells.push_back(cell);
 | 
			
		||||
					else
 | 
			
		||||
						proven_equiv_cells++;
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +77,7 @@ struct EquivStatusPass : public Pass {
 | 
			
		|||
				log("  Equivalence successfully proven!\n");
 | 
			
		||||
			} else {
 | 
			
		||||
				for (auto cell : unproven_equiv_cells)
 | 
			
		||||
					log("  Unproven $equiv %s: %s %s\n", log_id(cell), log_signal(cell->getPort("\\A")), log_signal(cell->getPort("\\B")));
 | 
			
		||||
					log("  Unproven $equiv %s: %s %s\n", log_id(cell), log_signal(cell->getPort(ID::A)), log_signal(cell->getPort(ID::B)));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			unproven_count += GetSize(unproven_equiv_cells);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -110,9 +110,9 @@ struct EquivStructWorker
 | 
			
		|||
			module->connect(sig_b, sig_a);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		auto merged_attr = cell_b->get_strpool_attribute("\\equiv_merged");
 | 
			
		||||
		auto merged_attr = cell_b->get_strpool_attribute(ID::equiv_merged);
 | 
			
		||||
		merged_attr.insert(log_id(cell_b));
 | 
			
		||||
		cell_a->add_strpool_attribute("\\equiv_merged", merged_attr);
 | 
			
		||||
		cell_a->add_strpool_attribute(ID::equiv_merged, merged_attr);
 | 
			
		||||
		module->remove(cell_b);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -126,9 +126,9 @@ struct EquivStructWorker
 | 
			
		|||
		pool<IdString> cells;
 | 
			
		||||
 | 
			
		||||
		for (auto cell : module->selected_cells())
 | 
			
		||||
			if (cell->type == "$equiv") {
 | 
			
		||||
				SigBit sig_a = sigmap(cell->getPort("\\A").as_bit());
 | 
			
		||||
				SigBit sig_b = sigmap(cell->getPort("\\B").as_bit());
 | 
			
		||||
			if (cell->type == ID($equiv)) {
 | 
			
		||||
				SigBit sig_a = sigmap(cell->getPort(ID::A).as_bit());
 | 
			
		||||
				SigBit sig_b = sigmap(cell->getPort(ID::B).as_bit());
 | 
			
		||||
				equiv_bits.add(sig_b, sig_a);
 | 
			
		||||
				equiv_inputs.insert(sig_a);
 | 
			
		||||
				equiv_inputs.insert(sig_b);
 | 
			
		||||
| 
						 | 
				
			
			@ -139,10 +139,10 @@ struct EquivStructWorker
 | 
			
		|||
			}
 | 
			
		||||
 | 
			
		||||
		for (auto cell : module->selected_cells())
 | 
			
		||||
			if (cell->type == "$equiv") {
 | 
			
		||||
				SigBit sig_a = sigmap(cell->getPort("\\A").as_bit());
 | 
			
		||||
				SigBit sig_b = sigmap(cell->getPort("\\B").as_bit());
 | 
			
		||||
				SigBit sig_y = sigmap(cell->getPort("\\Y").as_bit());
 | 
			
		||||
			if (cell->type == ID($equiv)) {
 | 
			
		||||
				SigBit sig_a = sigmap(cell->getPort(ID::A).as_bit());
 | 
			
		||||
				SigBit sig_b = sigmap(cell->getPort(ID::B).as_bit());
 | 
			
		||||
				SigBit sig_y = sigmap(cell->getPort(ID::Y).as_bit());
 | 
			
		||||
				if (sig_a == sig_b && equiv_inputs.count(sig_y)) {
 | 
			
		||||
					log("    Purging redundant $equiv cell %s.\n", log_id(cell));
 | 
			
		||||
					module->connect(sig_y, sig_a);
 | 
			
		||||
| 
						 | 
				
			
			@ -316,7 +316,7 @@ struct EquivStructPass : public Pass {
 | 
			
		|||
	}
 | 
			
		||||
	void execute(std::vector<std::string> args, Design *design) YS_OVERRIDE
 | 
			
		||||
	{
 | 
			
		||||
		pool<IdString> fwonly_cells({ "$equiv" });
 | 
			
		||||
		pool<IdString> fwonly_cells({ ID($equiv) });
 | 
			
		||||
		bool mode_icells = false;
 | 
			
		||||
		bool mode_fwd = false;
 | 
			
		||||
		int max_iter = -1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,7 +55,7 @@ ret_false:
 | 
			
		|||
	sig2driver.find(sig, cellport_list);
 | 
			
		||||
	for (auto &cellport : cellport_list)
 | 
			
		||||
	{
 | 
			
		||||
		if ((cellport.first->type != "$mux" && cellport.first->type != "$pmux") || cellport.second != "\\Y") {
 | 
			
		||||
		if ((cellport.first->type != ID($mux) && cellport.first->type != ID($pmux)) || cellport.second != ID::Y) {
 | 
			
		||||
			goto ret_false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -67,8 +67,8 @@ ret_false:
 | 
			
		|||
 | 
			
		||||
		recursion_monitor.insert(cellport.first);
 | 
			
		||||
 | 
			
		||||
		RTLIL::SigSpec sig_a = assign_map(cellport.first->getPort("\\A"));
 | 
			
		||||
		RTLIL::SigSpec sig_b = assign_map(cellport.first->getPort("\\B"));
 | 
			
		||||
		RTLIL::SigSpec sig_a = assign_map(cellport.first->getPort(ID::A));
 | 
			
		||||
		RTLIL::SigSpec sig_b = assign_map(cellport.first->getPort(ID::B));
 | 
			
		||||
 | 
			
		||||
		if (!check_state_mux_tree(old_sig, sig_a, recursion_monitor, mux_tree_cache)) {
 | 
			
		||||
			recursion_monitor.erase(cellport.first);
 | 
			
		||||
| 
						 | 
				
			
			@ -99,18 +99,18 @@ static bool check_state_users(RTLIL::SigSpec sig)
 | 
			
		|||
		RTLIL::Cell *cell = cellport.first;
 | 
			
		||||
		if (muxtree_cells.count(cell) > 0)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (cell->type == "$logic_not" && assign_map(cell->getPort("\\A")) == sig)
 | 
			
		||||
		if (cell->type == ID($logic_not) && assign_map(cell->getPort(ID::A)) == sig)
 | 
			
		||||
			continue;
 | 
			
		||||
		if (cellport.second != "\\A" && cellport.second != "\\B")
 | 
			
		||||
		if (cellport.second != ID::A && cellport.second != ID::B)
 | 
			
		||||
			return false;
 | 
			
		||||
		if (!cell->hasPort("\\A") || !cell->hasPort("\\B") || !cell->hasPort("\\Y"))
 | 
			
		||||
		if (!cell->hasPort(ID::A) || !cell->hasPort(ID::B) || !cell->hasPort(ID::Y))
 | 
			
		||||
			return false;
 | 
			
		||||
		for (auto &port_it : cell->connections())
 | 
			
		||||
			if (port_it.first != "\\A" && port_it.first != "\\B" && port_it.first != "\\Y")
 | 
			
		||||
			if (port_it.first != ID::A && port_it.first != ID::B && port_it.first != ID::Y)
 | 
			
		||||
				return false;
 | 
			
		||||
		if (assign_map(cell->getPort("\\A")) == sig && cell->getPort("\\B").is_fully_const())
 | 
			
		||||
		if (assign_map(cell->getPort(ID::A)) == sig && cell->getPort(ID::B).is_fully_const())
 | 
			
		||||
			continue;
 | 
			
		||||
		if (assign_map(cell->getPort("\\B")) == sig && cell->getPort("\\A").is_fully_const())
 | 
			
		||||
		if (assign_map(cell->getPort(ID::B)) == sig && cell->getPort(ID::A).is_fully_const())
 | 
			
		||||
			continue;
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -120,9 +120,9 @@ static bool check_state_users(RTLIL::SigSpec sig)
 | 
			
		|||
 | 
			
		||||
static void detect_fsm(RTLIL::Wire *wire)
 | 
			
		||||
{
 | 
			
		||||
	bool has_fsm_encoding_attr = wire->attributes.count("\\fsm_encoding") > 0 && wire->attributes.at("\\fsm_encoding").decode_string() != "none";
 | 
			
		||||
	bool has_fsm_encoding_none = wire->attributes.count("\\fsm_encoding") > 0 && wire->attributes.at("\\fsm_encoding").decode_string() == "none";
 | 
			
		||||
	bool has_init_attr = wire->attributes.count("\\init") > 0;
 | 
			
		||||
	bool has_fsm_encoding_attr = wire->attributes.count(ID::fsm_encoding) > 0 && wire->attributes.at(ID::fsm_encoding).decode_string() != "none";
 | 
			
		||||
	bool has_fsm_encoding_none = wire->attributes.count(ID::fsm_encoding) > 0 && wire->attributes.at(ID::fsm_encoding).decode_string() == "none";
 | 
			
		||||
	bool has_init_attr = wire->attributes.count(ID::init) > 0;
 | 
			
		||||
	bool is_module_port = sig_at_port.check_any(assign_map(RTLIL::SigSpec(wire)));
 | 
			
		||||
	bool looks_like_state_reg = false, looks_like_good_state_reg = false;
 | 
			
		||||
	bool is_self_resetting = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -133,7 +133,7 @@ static void detect_fsm(RTLIL::Wire *wire)
 | 
			
		|||
	if (wire->width <= 1) {
 | 
			
		||||
		if (has_fsm_encoding_attr) {
 | 
			
		||||
			log_warning("Removing fsm_encoding attribute from 1-bit net: %s.%s\n", log_id(wire->module), log_id(wire));
 | 
			
		||||
			wire->attributes.erase("\\fsm_encoding");
 | 
			
		||||
			wire->attributes.erase(ID::fsm_encoding);
 | 
			
		||||
		}
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -143,13 +143,13 @@ static void detect_fsm(RTLIL::Wire *wire)
 | 
			
		|||
 | 
			
		||||
	for (auto &cellport : cellport_list)
 | 
			
		||||
	{
 | 
			
		||||
		if ((cellport.first->type != "$dff" && cellport.first->type != "$adff") || cellport.second != "\\Q")
 | 
			
		||||
		if ((cellport.first->type != ID($dff) && cellport.first->type != ID($adff)) || cellport.second != ID::Q)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		muxtree_cells.clear();
 | 
			
		||||
		pool<Cell*> recursion_monitor;
 | 
			
		||||
		RTLIL::SigSpec sig_q = assign_map(cellport.first->getPort("\\Q"));
 | 
			
		||||
		RTLIL::SigSpec sig_d = assign_map(cellport.first->getPort("\\D"));
 | 
			
		||||
		RTLIL::SigSpec sig_q = assign_map(cellport.first->getPort(ID::Q));
 | 
			
		||||
		RTLIL::SigSpec sig_d = assign_map(cellport.first->getPort(ID::D));
 | 
			
		||||
		dict<RTLIL::SigSpec, bool> mux_tree_cache;
 | 
			
		||||
 | 
			
		||||
		if (sig_q != assign_map(wire))
 | 
			
		||||
| 
						 | 
				
			
			@ -173,10 +173,10 @@ static void detect_fsm(RTLIL::Wire *wire)
 | 
			
		|||
			RTLIL::Cell *cell = cellport.first;
 | 
			
		||||
			bool set_output = false, clr_output = false;
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in("$ne", "$reduce_or", "$reduce_bool"))
 | 
			
		||||
			if (cell->type.in(ID($ne), ID($reduce_or), ID($reduce_bool)))
 | 
			
		||||
				set_output = true;
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in("$eq", "$logic_not", "$reduce_and"))
 | 
			
		||||
			if (cell->type.in(ID($eq), ID($logic_not), ID($reduce_and)))
 | 
			
		||||
				clr_output = true;
 | 
			
		||||
 | 
			
		||||
			if (set_output || clr_output) {
 | 
			
		||||
| 
						 | 
				
			
			@ -234,7 +234,7 @@ static void detect_fsm(RTLIL::Wire *wire)
 | 
			
		|||
	if (looks_like_state_reg && looks_like_good_state_reg && !has_init_attr && !is_module_port && !is_self_resetting)
 | 
			
		||||
	{
 | 
			
		||||
		log("Found FSM state register %s.%s.\n", log_id(wire->module), log_id(wire));
 | 
			
		||||
		wire->attributes["\\fsm_encoding"] = RTLIL::Const("auto");
 | 
			
		||||
		wire->attributes[ID::fsm_encoding] = RTLIL::Const("auto");
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	if (looks_like_state_reg)
 | 
			
		||||
| 
						 | 
				
			
			@ -284,38 +284,34 @@ struct FsmDetectPass : public Pass {
 | 
			
		|||
		ct.setup_stdcells();
 | 
			
		||||
		ct.setup_stdcells_mem();
 | 
			
		||||
 | 
			
		||||
		for (auto &mod_it : design->modules_)
 | 
			
		||||
		for (auto mod : design->selected_modules())
 | 
			
		||||
		{
 | 
			
		||||
			if (!design->selected(mod_it.second))
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			module = mod_it.second;
 | 
			
		||||
			module = mod;
 | 
			
		||||
			assign_map.set(module);
 | 
			
		||||
 | 
			
		||||
			sig2driver.clear();
 | 
			
		||||
			sig2user.clear();
 | 
			
		||||
			sig_at_port.clear();
 | 
			
		||||
			for (auto &cell_it : module->cells_)
 | 
			
		||||
				for (auto &conn_it : cell_it.second->connections()) {
 | 
			
		||||
					if (ct.cell_output(cell_it.second->type, conn_it.first) || !ct.cell_known(cell_it.second->type)) {
 | 
			
		||||
			for (auto cell : module->cells())
 | 
			
		||||
				for (auto &conn_it : cell->connections()) {
 | 
			
		||||
					if (ct.cell_output(cell->type, conn_it.first) || !ct.cell_known(cell->type)) {
 | 
			
		||||
						RTLIL::SigSpec sig = conn_it.second;
 | 
			
		||||
						assign_map.apply(sig);
 | 
			
		||||
						sig2driver.insert(sig, sig2driver_entry_t(cell_it.second, conn_it.first));
 | 
			
		||||
						sig2driver.insert(sig, sig2driver_entry_t(cell, conn_it.first));
 | 
			
		||||
					}
 | 
			
		||||
					if (!ct.cell_known(cell_it.second->type) || ct.cell_input(cell_it.second->type, conn_it.first)) {
 | 
			
		||||
					if (!ct.cell_known(cell->type) || ct.cell_input(cell->type, conn_it.first)) {
 | 
			
		||||
						RTLIL::SigSpec sig = conn_it.second;
 | 
			
		||||
						assign_map.apply(sig);
 | 
			
		||||
						sig2user.insert(sig, sig2driver_entry_t(cell_it.second, conn_it.first));
 | 
			
		||||
						sig2user.insert(sig, sig2driver_entry_t(cell, conn_it.first));
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			for (auto &wire_it : module->wires_)
 | 
			
		||||
				if (wire_it.second->port_id != 0)
 | 
			
		||||
					sig_at_port.add(assign_map(RTLIL::SigSpec(wire_it.second)));
 | 
			
		||||
			for (auto wire : module->wires())
 | 
			
		||||
				if (wire->port_id != 0)
 | 
			
		||||
					sig_at_port.add(assign_map(wire));
 | 
			
		||||
 | 
			
		||||
			for (auto &wire_it : module->wires_)
 | 
			
		||||
				if (design->selected(module, wire_it.second))
 | 
			
		||||
					detect_fsm(wire_it.second);
 | 
			
		||||
			for (auto wire : module->selected_wires())
 | 
			
		||||
				detect_fsm(wire);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		assign_map.clear();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,42 +47,42 @@ struct FsmExpand
 | 
			
		|||
 | 
			
		||||
	bool is_cell_merge_candidate(RTLIL::Cell *cell)
 | 
			
		||||
	{
 | 
			
		||||
		if (full_mode || cell->type == "$_MUX_")
 | 
			
		||||
		if (full_mode || cell->type == ID($_MUX_))
 | 
			
		||||
			return true;
 | 
			
		||||
 | 
			
		||||
		if (cell->type.in("$mux", "$pmux"))
 | 
			
		||||
			if (cell->getPort("\\A").size() < 2)
 | 
			
		||||
		if (cell->type.in(ID($mux), ID($pmux)))
 | 
			
		||||
			if (cell->getPort(ID::A).size() < 2)
 | 
			
		||||
				return true;
 | 
			
		||||
 | 
			
		||||
		int in_bits = 0;
 | 
			
		||||
		RTLIL::SigSpec new_signals;
 | 
			
		||||
 | 
			
		||||
		if (cell->hasPort("\\A")) {
 | 
			
		||||
			in_bits += GetSize(cell->getPort("\\A"));
 | 
			
		||||
			new_signals.append(assign_map(cell->getPort("\\A")));
 | 
			
		||||
		if (cell->hasPort(ID::A)) {
 | 
			
		||||
			in_bits += GetSize(cell->getPort(ID::A));
 | 
			
		||||
			new_signals.append(assign_map(cell->getPort(ID::A)));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (cell->hasPort("\\B")) {
 | 
			
		||||
			in_bits += GetSize(cell->getPort("\\B"));
 | 
			
		||||
			new_signals.append(assign_map(cell->getPort("\\B")));
 | 
			
		||||
		if (cell->hasPort(ID::B)) {
 | 
			
		||||
			in_bits += GetSize(cell->getPort(ID::B));
 | 
			
		||||
			new_signals.append(assign_map(cell->getPort(ID::B)));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (cell->hasPort("\\S")) {
 | 
			
		||||
			in_bits += GetSize(cell->getPort("\\S"));
 | 
			
		||||
			new_signals.append(assign_map(cell->getPort("\\S")));
 | 
			
		||||
		if (cell->hasPort(ID::S)) {
 | 
			
		||||
			in_bits += GetSize(cell->getPort(ID::S));
 | 
			
		||||
			new_signals.append(assign_map(cell->getPort(ID::S)));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (in_bits > 8)
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		if (cell->hasPort("\\Y"))
 | 
			
		||||
			new_signals.append(assign_map(cell->getPort("\\Y")));
 | 
			
		||||
		if (cell->hasPort(ID::Y))
 | 
			
		||||
			new_signals.append(assign_map(cell->getPort(ID::Y)));
 | 
			
		||||
 | 
			
		||||
		new_signals.sort_and_unify();
 | 
			
		||||
		new_signals.remove_const();
 | 
			
		||||
 | 
			
		||||
		new_signals.remove(assign_map(fsm_cell->getPort("\\CTRL_IN")));
 | 
			
		||||
		new_signals.remove(assign_map(fsm_cell->getPort("\\CTRL_OUT")));
 | 
			
		||||
		new_signals.remove(assign_map(fsm_cell->getPort(ID::CTRL_IN)));
 | 
			
		||||
		new_signals.remove(assign_map(fsm_cell->getPort(ID::CTRL_OUT)));
 | 
			
		||||
 | 
			
		||||
		if (new_signals.size() > 3)
 | 
			
		||||
			return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -94,10 +94,10 @@ struct FsmExpand
 | 
			
		|||
	{
 | 
			
		||||
		std::vector<RTLIL::Cell*> cell_list;
 | 
			
		||||
 | 
			
		||||
		for (auto c : sig2driver.find(assign_map(fsm_cell->getPort("\\CTRL_IN"))))
 | 
			
		||||
		for (auto c : sig2driver.find(assign_map(fsm_cell->getPort(ID::CTRL_IN))))
 | 
			
		||||
			cell_list.push_back(c);
 | 
			
		||||
 | 
			
		||||
		for (auto c : sig2user.find(assign_map(fsm_cell->getPort("\\CTRL_OUT"))))
 | 
			
		||||
		for (auto c : sig2user.find(assign_map(fsm_cell->getPort(ID::CTRL_OUT))))
 | 
			
		||||
			cell_list.push_back(c);
 | 
			
		||||
 | 
			
		||||
		current_set.clear();
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +106,7 @@ struct FsmExpand
 | 
			
		|||
			if (merged_set.count(c) > 0 || current_set.count(c) > 0 || no_candidate_set.count(c) > 0)
 | 
			
		||||
				continue;
 | 
			
		||||
			for (auto &p : c->connections()) {
 | 
			
		||||
				if (p.first != "\\A" && p.first != "\\B" && p.first != "\\S" && p.first != "\\Y")
 | 
			
		||||
				if (p.first != ID::A && p.first != ID::B && p.first != ID::S && p.first != ID::Y)
 | 
			
		||||
					goto next_cell;
 | 
			
		||||
			}
 | 
			
		||||
			if (!is_cell_merge_candidate(c)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -123,14 +123,14 @@ struct FsmExpand
 | 
			
		|||
		if (already_optimized)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		int trans_num = fsm_cell->parameters["\\TRANS_NUM"].as_int();
 | 
			
		||||
		int trans_num = fsm_cell->parameters[ID::TRANS_NUM].as_int();
 | 
			
		||||
		if (trans_num > limit_transitions)
 | 
			
		||||
		{
 | 
			
		||||
			log("  grown transition table to %d entries -> optimize.\n", trans_num);
 | 
			
		||||
			FsmData::optimize_fsm(fsm_cell, module);
 | 
			
		||||
			already_optimized = true;
 | 
			
		||||
 | 
			
		||||
			trans_num = fsm_cell->parameters["\\TRANS_NUM"].as_int();
 | 
			
		||||
			trans_num = fsm_cell->parameters[ID::TRANS_NUM].as_int();
 | 
			
		||||
			log("  transition table size after optimizaton: %d\n", trans_num);
 | 
			
		||||
			limit_transitions = 16 * trans_num;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -159,12 +159,12 @@ struct FsmExpand
 | 
			
		|||
		for (int i = 0; i < (1 << input_sig.size()); i++) {
 | 
			
		||||
			RTLIL::Const in_val(i, input_sig.size());
 | 
			
		||||
			RTLIL::SigSpec A, B, S;
 | 
			
		||||
			if (cell->hasPort("\\A"))
 | 
			
		||||
				A = assign_map(cell->getPort("\\A"));
 | 
			
		||||
			if (cell->hasPort("\\B"))
 | 
			
		||||
				B = assign_map(cell->getPort("\\B"));
 | 
			
		||||
			if (cell->hasPort("\\S"))
 | 
			
		||||
				S = assign_map(cell->getPort("\\S"));
 | 
			
		||||
			if (cell->hasPort(ID::A))
 | 
			
		||||
				A = assign_map(cell->getPort(ID::A));
 | 
			
		||||
			if (cell->hasPort(ID::B))
 | 
			
		||||
				B = assign_map(cell->getPort(ID::B));
 | 
			
		||||
			if (cell->hasPort(ID::S))
 | 
			
		||||
				S = assign_map(cell->getPort(ID::S));
 | 
			
		||||
			A.replace(input_sig, RTLIL::SigSpec(in_val));
 | 
			
		||||
			B.replace(input_sig, RTLIL::SigSpec(in_val));
 | 
			
		||||
			S.replace(input_sig, RTLIL::SigSpec(in_val));
 | 
			
		||||
| 
						 | 
				
			
			@ -178,14 +178,14 @@ struct FsmExpand
 | 
			
		|||
		fsm_data.copy_from_cell(fsm_cell);
 | 
			
		||||
 | 
			
		||||
		fsm_data.num_inputs += input_sig.size();
 | 
			
		||||
		RTLIL::SigSpec new_ctrl_in = fsm_cell->getPort("\\CTRL_IN");
 | 
			
		||||
		RTLIL::SigSpec new_ctrl_in = fsm_cell->getPort(ID::CTRL_IN);
 | 
			
		||||
		new_ctrl_in.append(input_sig);
 | 
			
		||||
		fsm_cell->setPort("\\CTRL_IN", new_ctrl_in);
 | 
			
		||||
		fsm_cell->setPort(ID::CTRL_IN, new_ctrl_in);
 | 
			
		||||
 | 
			
		||||
		fsm_data.num_outputs += output_sig.size();
 | 
			
		||||
		RTLIL::SigSpec new_ctrl_out = fsm_cell->getPort("\\CTRL_OUT");
 | 
			
		||||
		RTLIL::SigSpec new_ctrl_out = fsm_cell->getPort(ID::CTRL_OUT);
 | 
			
		||||
		new_ctrl_out.append(output_sig);
 | 
			
		||||
		fsm_cell->setPort("\\CTRL_OUT", new_ctrl_out);
 | 
			
		||||
		fsm_cell->setPort(ID::CTRL_OUT, new_ctrl_out);
 | 
			
		||||
 | 
			
		||||
		if (GetSize(input_sig) > 10)
 | 
			
		||||
			log_warning("Cell %s.%s (%s) has %d input bits, merging into FSM %s.%s might be problematic.\n",
 | 
			
		||||
| 
						 | 
				
			
			@ -246,7 +246,7 @@ struct FsmExpand
 | 
			
		|||
		log("Expanding FSM `%s' from module `%s':\n", fsm_cell->name.c_str(), module->name.c_str());
 | 
			
		||||
 | 
			
		||||
		already_optimized = false;
 | 
			
		||||
		limit_transitions =  16 * fsm_cell->parameters["\\TRANS_NUM"].as_int();
 | 
			
		||||
		limit_transitions =  16 * fsm_cell->parameters[ID::TRANS_NUM].as_int();
 | 
			
		||||
 | 
			
		||||
		for (create_current_set(); current_set.size() > 0; create_current_set()) {
 | 
			
		||||
			for (auto c : current_set)
 | 
			
		||||
| 
						 | 
				
			
			@ -295,15 +295,13 @@ struct FsmExpandPass : public Pass {
 | 
			
		|||
		}
 | 
			
		||||
		extra_args(args, argidx, design);
 | 
			
		||||
 | 
			
		||||
		for (auto &mod_it : design->modules_) {
 | 
			
		||||
			if (!design->selected(mod_it.second))
 | 
			
		||||
				continue;
 | 
			
		||||
		for (auto mod : design->selected_modules()) {
 | 
			
		||||
			std::vector<RTLIL::Cell*> fsm_cells;
 | 
			
		||||
			for (auto &cell_it : mod_it.second->cells_)
 | 
			
		||||
				if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second))
 | 
			
		||||
					fsm_cells.push_back(cell_it.second);
 | 
			
		||||
			for (auto cell : mod->selected_cells())
 | 
			
		||||
				if (cell->type == ID($fsm))
 | 
			
		||||
					fsm_cells.push_back(cell);
 | 
			
		||||
			for (auto c : fsm_cells) {
 | 
			
		||||
				FsmExpand fsm_expand(c, design, mod_it.second, full_mode);
 | 
			
		||||
				FsmExpand fsm_expand(c, design, mod, full_mode);
 | 
			
		||||
				fsm_expand.execute();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,7 +57,7 @@ void write_kiss2(struct RTLIL::Module *module, struct RTLIL::Cell *cell, std::st
 | 
			
		|||
	std::string kiss_name;
 | 
			
		||||
	size_t i;
 | 
			
		||||
 | 
			
		||||
	attr_it = cell->attributes.find("\\fsm_export");
 | 
			
		||||
	attr_it = cell->attributes.find(ID::fsm_export);
 | 
			
		||||
	if (!filename.empty()) {
 | 
			
		||||
		kiss_name.assign(filename);
 | 
			
		||||
	} else if (attr_it != cell->attributes.end() && attr_it->second.decode_string() != "") {
 | 
			
		||||
| 
						 | 
				
			
			@ -173,16 +173,15 @@ struct FsmExportPass : public Pass {
 | 
			
		|||
		}
 | 
			
		||||
		extra_args(args, argidx, design);
 | 
			
		||||
 | 
			
		||||
		for (auto &mod_it : design->modules_)
 | 
			
		||||
			if (design->selected(mod_it.second))
 | 
			
		||||
				for (auto &cell_it : mod_it.second->cells_)
 | 
			
		||||
					if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) {
 | 
			
		||||
						attr_it = cell_it.second->attributes.find("\\fsm_export");
 | 
			
		||||
						if (!flag_noauto || (attr_it != cell_it.second->attributes.end())) {
 | 
			
		||||
							write_kiss2(mod_it.second, cell_it.second, filename, flag_origenc);
 | 
			
		||||
							filename.clear();
 | 
			
		||||
						}
 | 
			
		||||
		for (auto mod : design->selected_modules())
 | 
			
		||||
			for (auto cell : mod->selected_cells())
 | 
			
		||||
				if (cell->type == ID($fsm)) {
 | 
			
		||||
					attr_it = cell->attributes.find(ID::fsm_export);
 | 
			
		||||
					if (!flag_noauto || (attr_it != cell->attributes.end())) {
 | 
			
		||||
						write_kiss2(mod, cell, filename, flag_origenc);
 | 
			
		||||
						filename.clear();
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
	}
 | 
			
		||||
} FsmExportPass;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -70,15 +70,15 @@ static bool find_states(RTLIL::SigSpec sig, const RTLIL::SigSpec &dff_out, RTLIL
 | 
			
		|||
	for (auto &cellport : cellport_list)
 | 
			
		||||
	{
 | 
			
		||||
		RTLIL::Cell *cell = module->cells_.at(cellport.first);
 | 
			
		||||
		if ((cell->type != "$mux" && cell->type != "$pmux") || cellport.second != "\\Y") {
 | 
			
		||||
		if ((cell->type != ID($mux) && cell->type != ID($pmux)) || cellport.second != ID::Y) {
 | 
			
		||||
			log("  unexpected cell type %s (%s) found in state selection tree.\n", cell->type.c_str(), cell->name.c_str());
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A"));
 | 
			
		||||
		RTLIL::SigSpec sig_b = assign_map(cell->getPort("\\B"));
 | 
			
		||||
		RTLIL::SigSpec sig_s = assign_map(cell->getPort("\\S"));
 | 
			
		||||
		RTLIL::SigSpec sig_y = assign_map(cell->getPort("\\Y"));
 | 
			
		||||
		RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
 | 
			
		||||
		RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
 | 
			
		||||
		RTLIL::SigSpec sig_s = assign_map(cell->getPort(ID::S));
 | 
			
		||||
		RTLIL::SigSpec sig_y = assign_map(cell->getPort(ID::Y));
 | 
			
		||||
 | 
			
		||||
		RTLIL::SigSpec sig_aa = sig;
 | 
			
		||||
		sig_aa.replace(sig_y, sig_a);
 | 
			
		||||
| 
						 | 
				
			
			@ -272,17 +272,17 @@ static void extract_fsm(RTLIL::Wire *wire)
 | 
			
		|||
	sig2driver.find(dff_out, cellport_list);
 | 
			
		||||
	for (auto &cellport : cellport_list) {
 | 
			
		||||
		RTLIL::Cell *cell = module->cells_.at(cellport.first);
 | 
			
		||||
		if ((cell->type != "$dff" && cell->type != "$adff") || cellport.second != "\\Q")
 | 
			
		||||
		if ((cell->type != ID($dff) && cell->type != ID($adff)) || cellport.second != ID::Q)
 | 
			
		||||
			continue;
 | 
			
		||||
		log("  found %s cell for state register: %s\n", cell->type.c_str(), cell->name.c_str());
 | 
			
		||||
		RTLIL::SigSpec sig_q = assign_map(cell->getPort("\\Q"));
 | 
			
		||||
		RTLIL::SigSpec sig_d = assign_map(cell->getPort("\\D"));
 | 
			
		||||
		clk = cell->getPort("\\CLK");
 | 
			
		||||
		clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool();
 | 
			
		||||
		if (cell->type == "$adff") {
 | 
			
		||||
			arst = cell->getPort("\\ARST");
 | 
			
		||||
			arst_polarity = cell->parameters["\\ARST_POLARITY"].as_bool();
 | 
			
		||||
			reset_state = cell->parameters["\\ARST_VALUE"];
 | 
			
		||||
		RTLIL::SigSpec sig_q = assign_map(cell->getPort(ID::Q));
 | 
			
		||||
		RTLIL::SigSpec sig_d = assign_map(cell->getPort(ID::D));
 | 
			
		||||
		clk = cell->getPort(ID::CLK);
 | 
			
		||||
		clk_polarity = cell->parameters[ID::CLK_POLARITY].as_bool();
 | 
			
		||||
		if (cell->type == ID($adff)) {
 | 
			
		||||
			arst = cell->getPort(ID::ARST);
 | 
			
		||||
			arst_polarity = cell->parameters[ID::ARST_POLARITY].as_bool();
 | 
			
		||||
			reset_state = cell->parameters[ID::ARST_VALUE];
 | 
			
		||||
		}
 | 
			
		||||
		sig_q.replace(dff_out, sig_d, &dff_in);
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			@ -320,14 +320,14 @@ static void extract_fsm(RTLIL::Wire *wire)
 | 
			
		|||
	sig2trigger.find(dff_out, cellport_list);
 | 
			
		||||
	for (auto &cellport : cellport_list) {
 | 
			
		||||
		RTLIL::Cell *cell = module->cells_.at(cellport.first);
 | 
			
		||||
		RTLIL::SigSpec sig_a = assign_map(cell->getPort("\\A"));
 | 
			
		||||
		RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
 | 
			
		||||
		RTLIL::SigSpec sig_b;
 | 
			
		||||
		if (cell->hasPort("\\B"))
 | 
			
		||||
			sig_b = assign_map(cell->getPort("\\B"));
 | 
			
		||||
		RTLIL::SigSpec sig_y = assign_map(cell->getPort("\\Y"));
 | 
			
		||||
		if (cellport.second == "\\A" && !sig_b.is_fully_const())
 | 
			
		||||
		if (cell->hasPort(ID::B))
 | 
			
		||||
			sig_b = assign_map(cell->getPort(ID::B));
 | 
			
		||||
		RTLIL::SigSpec sig_y = assign_map(cell->getPort(ID::Y));
 | 
			
		||||
		if (cellport.second == ID::A && !sig_b.is_fully_const())
 | 
			
		||||
			continue;
 | 
			
		||||
		if (cellport.second == "\\B" && !sig_a.is_fully_const())
 | 
			
		||||
		if (cellport.second == ID::B && !sig_a.is_fully_const())
 | 
			
		||||
			continue;
 | 
			
		||||
		log("  found ctrl output: %s\n", log_signal(sig_y));
 | 
			
		||||
		ctrl_out.append(sig_y);
 | 
			
		||||
| 
						 | 
				
			
			@ -368,21 +368,21 @@ static void extract_fsm(RTLIL::Wire *wire)
 | 
			
		|||
 | 
			
		||||
	// create fsm cell
 | 
			
		||||
 | 
			
		||||
	RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), autoidx++), "$fsm");
 | 
			
		||||
	fsm_cell->setPort("\\CLK", clk);
 | 
			
		||||
	fsm_cell->setPort("\\ARST", arst);
 | 
			
		||||
	fsm_cell->parameters["\\CLK_POLARITY"] = clk_polarity ? State::S1 : State::S0;
 | 
			
		||||
	fsm_cell->parameters["\\ARST_POLARITY"] = arst_polarity ? State::S1 : State::S0;
 | 
			
		||||
	fsm_cell->setPort("\\CTRL_IN", ctrl_in);
 | 
			
		||||
	fsm_cell->setPort("\\CTRL_OUT", ctrl_out);
 | 
			
		||||
	fsm_cell->parameters["\\NAME"] = RTLIL::Const(wire->name.str());
 | 
			
		||||
	RTLIL::Cell *fsm_cell = module->addCell(stringf("$fsm$%s$%d", wire->name.c_str(), autoidx++), ID($fsm));
 | 
			
		||||
	fsm_cell->setPort(ID::CLK, clk);
 | 
			
		||||
	fsm_cell->setPort(ID::ARST, arst);
 | 
			
		||||
	fsm_cell->parameters[ID::CLK_POLARITY] = clk_polarity ? State::S1 : State::S0;
 | 
			
		||||
	fsm_cell->parameters[ID::ARST_POLARITY] = arst_polarity ? State::S1 : State::S0;
 | 
			
		||||
	fsm_cell->setPort(ID::CTRL_IN, ctrl_in);
 | 
			
		||||
	fsm_cell->setPort(ID::CTRL_OUT, ctrl_out);
 | 
			
		||||
	fsm_cell->parameters[ID::NAME] = RTLIL::Const(wire->name.str());
 | 
			
		||||
	fsm_cell->attributes = wire->attributes;
 | 
			
		||||
	fsm_data.copy_to_cell(fsm_cell);
 | 
			
		||||
 | 
			
		||||
	// rename original state wire
 | 
			
		||||
 | 
			
		||||
	module->wires_.erase(wire->name);
 | 
			
		||||
	wire->attributes.erase("\\fsm_encoding");
 | 
			
		||||
	wire->attributes.erase(ID::fsm_encoding);
 | 
			
		||||
	wire->name = stringf("$fsm$oldstate%s", wire->name.c_str());
 | 
			
		||||
	module->wires_[wire->name] = wire;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -424,12 +424,9 @@ struct FsmExtractPass : public Pass {
 | 
			
		|||
 | 
			
		||||
		CellTypes ct(design);
 | 
			
		||||
 | 
			
		||||
		for (auto &mod_it : design->modules_)
 | 
			
		||||
		for (auto mod : design->selected_modules())
 | 
			
		||||
		{
 | 
			
		||||
			if (!design->selected(mod_it.second))
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			module = mod_it.second;
 | 
			
		||||
			module = mod;
 | 
			
		||||
			assign_map.set(module);
 | 
			
		||||
 | 
			
		||||
			sig2driver.clear();
 | 
			
		||||
| 
						 | 
				
			
			@ -442,15 +439,15 @@ struct FsmExtractPass : public Pass {
 | 
			
		|||
						assign_map.apply(sig);
 | 
			
		||||
						sig2driver.insert(sig, sig2driver_entry_t(cell->name, conn_it.first));
 | 
			
		||||
					}
 | 
			
		||||
					if (ct.cell_input(cell->type, conn_it.first) && cell->hasPort("\\Y") &&
 | 
			
		||||
							cell->getPort("\\Y").size() == 1 && (conn_it.first == "\\A" || conn_it.first == "\\B")) {
 | 
			
		||||
					if (ct.cell_input(cell->type, conn_it.first) && cell->hasPort(ID::Y) &&
 | 
			
		||||
							cell->getPort(ID::Y).size() == 1 && (conn_it.first == ID::A || conn_it.first == ID::B)) {
 | 
			
		||||
						RTLIL::SigSpec sig = conn_it.second;
 | 
			
		||||
						assign_map.apply(sig);
 | 
			
		||||
						sig2trigger.insert(sig, sig2driver_entry_t(cell->name, conn_it.first));
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if (cell->type == "$pmux") {
 | 
			
		||||
					RTLIL::SigSpec sel_sig = assign_map(cell->getPort("\\S"));
 | 
			
		||||
				if (cell->type == ID($pmux)) {
 | 
			
		||||
					RTLIL::SigSpec sel_sig = assign_map(cell->getPort(ID::S));
 | 
			
		||||
					for (auto &bit1 : sel_sig)
 | 
			
		||||
					for (auto &bit2 : sel_sig)
 | 
			
		||||
						if (bit1 != bit2)
 | 
			
		||||
| 
						 | 
				
			
			@ -459,10 +456,9 @@ struct FsmExtractPass : public Pass {
 | 
			
		|||
			}
 | 
			
		||||
 | 
			
		||||
			std::vector<RTLIL::Wire*> wire_list;
 | 
			
		||||
			for (auto &wire_it : module->wires_)
 | 
			
		||||
				if (wire_it.second->attributes.count("\\fsm_encoding") > 0 && wire_it.second->attributes["\\fsm_encoding"].decode_string() != "none")
 | 
			
		||||
					if (design->selected(module, wire_it.second))
 | 
			
		||||
						wire_list.push_back(wire_it.second);
 | 
			
		||||
			for (auto wire : module->selected_wires())
 | 
			
		||||
				if (wire->attributes.count(ID::fsm_encoding) > 0 && wire->attributes[ID::fsm_encoding].decode_string() != "none")
 | 
			
		||||
					wire_list.push_back(wire);
 | 
			
		||||
			for (auto wire : wire_list)
 | 
			
		||||
				extract_fsm(wire);
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,16 +46,15 @@ struct FsmInfoPass : public Pass {
 | 
			
		|||
		log_header(design, "Executing FSM_INFO pass (dumping all available information on FSM cells).\n");
 | 
			
		||||
		extra_args(args, 1, design);
 | 
			
		||||
 | 
			
		||||
		for (auto &mod_it : design->modules_)
 | 
			
		||||
			if (design->selected(mod_it.second))
 | 
			
		||||
				for (auto &cell_it : mod_it.second->cells_)
 | 
			
		||||
					if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second)) {
 | 
			
		||||
						log("\n");
 | 
			
		||||
						log("FSM `%s' from module `%s':\n", cell_it.second->name.c_str(), mod_it.first.c_str());
 | 
			
		||||
						FsmData fsm_data;
 | 
			
		||||
						fsm_data.copy_from_cell(cell_it.second);
 | 
			
		||||
						fsm_data.log_info(cell_it.second);
 | 
			
		||||
					}
 | 
			
		||||
		for (auto mod : design->selected_modules())
 | 
			
		||||
			for (auto cell : mod->selected_cells())
 | 
			
		||||
				if (cell->type == ID($fsm)) {
 | 
			
		||||
					log("\n");
 | 
			
		||||
					log("FSM `%s' from module `%s':\n", log_id(cell), log_id(mod));
 | 
			
		||||
					FsmData fsm_data;
 | 
			
		||||
					fsm_data.copy_from_cell(cell);
 | 
			
		||||
					fsm_data.log_info(cell);
 | 
			
		||||
				}
 | 
			
		||||
	}
 | 
			
		||||
} FsmInfoPass;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -74,15 +74,15 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const
 | 
			
		|||
			RTLIL::Wire *eq_wire = module->addWire(NEW_ID);
 | 
			
		||||
			and_sig.append(RTLIL::SigSpec(eq_wire));
 | 
			
		||||
 | 
			
		||||
			RTLIL::Cell *eq_cell = module->addCell(NEW_ID, "$eq");
 | 
			
		||||
			eq_cell->setPort("\\A", eq_sig_a);
 | 
			
		||||
			eq_cell->setPort("\\B", eq_sig_b);
 | 
			
		||||
			eq_cell->setPort("\\Y", RTLIL::SigSpec(eq_wire));
 | 
			
		||||
			eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false);
 | 
			
		||||
			eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false);
 | 
			
		||||
			eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(eq_sig_a.size());
 | 
			
		||||
			eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(eq_sig_b.size());
 | 
			
		||||
			eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
			RTLIL::Cell *eq_cell = module->addCell(NEW_ID, ID($eq));
 | 
			
		||||
			eq_cell->setPort(ID::A, eq_sig_a);
 | 
			
		||||
			eq_cell->setPort(ID::B, eq_sig_b);
 | 
			
		||||
			eq_cell->setPort(ID::Y, RTLIL::SigSpec(eq_wire));
 | 
			
		||||
			eq_cell->parameters[ID::A_SIGNED] = RTLIL::Const(false);
 | 
			
		||||
			eq_cell->parameters[ID::B_SIGNED] = RTLIL::Const(false);
 | 
			
		||||
			eq_cell->parameters[ID::A_WIDTH] = RTLIL::Const(eq_sig_a.size());
 | 
			
		||||
			eq_cell->parameters[ID::B_WIDTH] = RTLIL::Const(eq_sig_b.size());
 | 
			
		||||
			eq_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		std::set<int> complete_in_state_cache = it.second;
 | 
			
		||||
| 
						 | 
				
			
			@ -102,12 +102,12 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const
 | 
			
		|||
				RTLIL::Wire *or_wire = module->addWire(NEW_ID);
 | 
			
		||||
				and_sig.append(RTLIL::SigSpec(or_wire));
 | 
			
		||||
 | 
			
		||||
				RTLIL::Cell *or_cell = module->addCell(NEW_ID, "$reduce_or");
 | 
			
		||||
				or_cell->setPort("\\A", or_sig);
 | 
			
		||||
				or_cell->setPort("\\Y", RTLIL::SigSpec(or_wire));
 | 
			
		||||
				or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false);
 | 
			
		||||
				or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(or_sig.size());
 | 
			
		||||
				or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
				RTLIL::Cell *or_cell = module->addCell(NEW_ID, ID($reduce_or));
 | 
			
		||||
				or_cell->setPort(ID::A, or_sig);
 | 
			
		||||
				or_cell->setPort(ID::Y, RTLIL::SigSpec(or_wire));
 | 
			
		||||
				or_cell->parameters[ID::A_SIGNED] = RTLIL::Const(false);
 | 
			
		||||
				or_cell->parameters[ID::A_WIDTH] = RTLIL::Const(or_sig.size());
 | 
			
		||||
				or_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -118,15 +118,15 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const
 | 
			
		|||
				RTLIL::Wire *and_wire = module->addWire(NEW_ID);
 | 
			
		||||
				cases_vector.append(RTLIL::SigSpec(and_wire));
 | 
			
		||||
 | 
			
		||||
				RTLIL::Cell *and_cell = module->addCell(NEW_ID, "$and");
 | 
			
		||||
				and_cell->setPort("\\A", and_sig.extract(0, 1));
 | 
			
		||||
				and_cell->setPort("\\B", and_sig.extract(1, 1));
 | 
			
		||||
				and_cell->setPort("\\Y", RTLIL::SigSpec(and_wire));
 | 
			
		||||
				and_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false);
 | 
			
		||||
				and_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false);
 | 
			
		||||
				and_cell->parameters["\\A_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
				and_cell->parameters["\\B_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
				and_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
				RTLIL::Cell *and_cell = module->addCell(NEW_ID, ID($and));
 | 
			
		||||
				and_cell->setPort(ID::A, and_sig.extract(0, 1));
 | 
			
		||||
				and_cell->setPort(ID::B, and_sig.extract(1, 1));
 | 
			
		||||
				and_cell->setPort(ID::Y, RTLIL::SigSpec(and_wire));
 | 
			
		||||
				and_cell->parameters[ID::A_SIGNED] = RTLIL::Const(false);
 | 
			
		||||
				and_cell->parameters[ID::B_SIGNED] = RTLIL::Const(false);
 | 
			
		||||
				and_cell->parameters[ID::A_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
				and_cell->parameters[ID::B_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
				and_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		case 1:
 | 
			
		||||
| 
						 | 
				
			
			@ -141,12 +141,12 @@ static void implement_pattern_cache(RTLIL::Module *module, std::map<RTLIL::Const
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if (cases_vector.size() > 1) {
 | 
			
		||||
		RTLIL::Cell *or_cell = module->addCell(NEW_ID, "$reduce_or");
 | 
			
		||||
		or_cell->setPort("\\A", cases_vector);
 | 
			
		||||
		or_cell->setPort("\\Y", output);
 | 
			
		||||
		or_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false);
 | 
			
		||||
		or_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cases_vector.size());
 | 
			
		||||
		or_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
		RTLIL::Cell *or_cell = module->addCell(NEW_ID, ID($reduce_or));
 | 
			
		||||
		or_cell->setPort(ID::A, cases_vector);
 | 
			
		||||
		or_cell->setPort(ID::Y, output);
 | 
			
		||||
		or_cell->parameters[ID::A_SIGNED] = RTLIL::Const(false);
 | 
			
		||||
		or_cell->parameters[ID::A_WIDTH] = RTLIL::Const(cases_vector.size());
 | 
			
		||||
		or_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
	} else if (cases_vector.size() == 1) {
 | 
			
		||||
		module->connect(RTLIL::SigSig(output, cases_vector));
 | 
			
		||||
	} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -161,31 +161,31 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module)
 | 
			
		|||
	FsmData fsm_data;
 | 
			
		||||
	fsm_data.copy_from_cell(fsm_cell);
 | 
			
		||||
 | 
			
		||||
	RTLIL::SigSpec ctrl_in = fsm_cell->getPort("\\CTRL_IN");
 | 
			
		||||
	RTLIL::SigSpec ctrl_out = fsm_cell->getPort("\\CTRL_OUT");
 | 
			
		||||
	RTLIL::SigSpec ctrl_in = fsm_cell->getPort(ID::CTRL_IN);
 | 
			
		||||
	RTLIL::SigSpec ctrl_out = fsm_cell->getPort(ID::CTRL_OUT);
 | 
			
		||||
 | 
			
		||||
	// create state register
 | 
			
		||||
 | 
			
		||||
	RTLIL::Wire *state_wire = module->addWire(module->uniquify(fsm_cell->parameters["\\NAME"].decode_string()), fsm_data.state_bits);
 | 
			
		||||
	RTLIL::Wire *state_wire = module->addWire(module->uniquify(fsm_cell->parameters[ID::NAME].decode_string()), fsm_data.state_bits);
 | 
			
		||||
	RTLIL::Wire *next_state_wire = module->addWire(NEW_ID, fsm_data.state_bits);
 | 
			
		||||
 | 
			
		||||
	RTLIL::Cell *state_dff = module->addCell(NEW_ID, "");
 | 
			
		||||
	if (fsm_cell->getPort("\\ARST").is_fully_const()) {
 | 
			
		||||
		state_dff->type = "$dff";
 | 
			
		||||
	if (fsm_cell->getPort(ID::ARST).is_fully_const()) {
 | 
			
		||||
		state_dff->type = ID($dff);
 | 
			
		||||
	} else {
 | 
			
		||||
		state_dff->type = "$adff";
 | 
			
		||||
		state_dff->parameters["\\ARST_POLARITY"] = fsm_cell->parameters["\\ARST_POLARITY"];
 | 
			
		||||
		state_dff->parameters["\\ARST_VALUE"] = fsm_data.state_table[fsm_data.reset_state];
 | 
			
		||||
		for (auto &bit : state_dff->parameters["\\ARST_VALUE"].bits)
 | 
			
		||||
		state_dff->type = ID($adff);
 | 
			
		||||
		state_dff->parameters[ID::ARST_POLARITY] = fsm_cell->parameters[ID::ARST_POLARITY];
 | 
			
		||||
		state_dff->parameters[ID::ARST_VALUE] = fsm_data.state_table[fsm_data.reset_state];
 | 
			
		||||
		for (auto &bit : state_dff->parameters[ID::ARST_VALUE].bits)
 | 
			
		||||
			if (bit != RTLIL::State::S1)
 | 
			
		||||
				bit = RTLIL::State::S0;
 | 
			
		||||
		state_dff->setPort("\\ARST", fsm_cell->getPort("\\ARST"));
 | 
			
		||||
		state_dff->setPort(ID::ARST, fsm_cell->getPort(ID::ARST));
 | 
			
		||||
	}
 | 
			
		||||
	state_dff->parameters["\\WIDTH"] = RTLIL::Const(fsm_data.state_bits);
 | 
			
		||||
	state_dff->parameters["\\CLK_POLARITY"] = fsm_cell->parameters["\\CLK_POLARITY"];
 | 
			
		||||
	state_dff->setPort("\\CLK", fsm_cell->getPort("\\CLK"));
 | 
			
		||||
	state_dff->setPort("\\D", RTLIL::SigSpec(next_state_wire));
 | 
			
		||||
	state_dff->setPort("\\Q", RTLIL::SigSpec(state_wire));
 | 
			
		||||
	state_dff->parameters[ID::WIDTH] = RTLIL::Const(fsm_data.state_bits);
 | 
			
		||||
	state_dff->parameters[ID::CLK_POLARITY] = fsm_cell->parameters[ID::CLK_POLARITY];
 | 
			
		||||
	state_dff->setPort(ID::CLK, fsm_cell->getPort(ID::CLK));
 | 
			
		||||
	state_dff->setPort(ID::D, RTLIL::SigSpec(next_state_wire));
 | 
			
		||||
	state_dff->setPort(ID::Q, RTLIL::SigSpec(state_wire));
 | 
			
		||||
 | 
			
		||||
	// decode state register
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -212,20 +212,20 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module)
 | 
			
		|||
		{
 | 
			
		||||
			encoding_is_onehot = false;
 | 
			
		||||
 | 
			
		||||
			RTLIL::Cell *eq_cell = module->addCell(NEW_ID, "$eq");
 | 
			
		||||
			eq_cell->setPort("\\A", sig_a);
 | 
			
		||||
			eq_cell->setPort("\\B", sig_b);
 | 
			
		||||
			eq_cell->setPort("\\Y", RTLIL::SigSpec(state_onehot, i));
 | 
			
		||||
			eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(false);
 | 
			
		||||
			eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(false);
 | 
			
		||||
			eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_a.size());
 | 
			
		||||
			eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(sig_b.size());
 | 
			
		||||
			eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
			RTLIL::Cell *eq_cell = module->addCell(NEW_ID, ID($eq));
 | 
			
		||||
			eq_cell->setPort(ID::A, sig_a);
 | 
			
		||||
			eq_cell->setPort(ID::B, sig_b);
 | 
			
		||||
			eq_cell->setPort(ID::Y, RTLIL::SigSpec(state_onehot, i));
 | 
			
		||||
			eq_cell->parameters[ID::A_SIGNED] = RTLIL::Const(false);
 | 
			
		||||
			eq_cell->parameters[ID::B_SIGNED] = RTLIL::Const(false);
 | 
			
		||||
			eq_cell->parameters[ID::A_WIDTH] = RTLIL::Const(sig_a.size());
 | 
			
		||||
			eq_cell->parameters[ID::B_WIDTH] = RTLIL::Const(sig_b.size());
 | 
			
		||||
			eq_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (encoding_is_onehot)
 | 
			
		||||
		state_wire->set_bool_attribute("\\onehot");
 | 
			
		||||
		state_wire->set_bool_attribute(ID::onehot);
 | 
			
		||||
 | 
			
		||||
	// generate next_state signal
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -285,13 +285,13 @@ static void map_fsm(RTLIL::Cell *fsm_cell, RTLIL::Module *module)
 | 
			
		|||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			RTLIL::Cell *mux_cell = module->addCell(NEW_ID, "$pmux");
 | 
			
		||||
			mux_cell->setPort("\\A", sig_a);
 | 
			
		||||
			mux_cell->setPort("\\B", sig_b);
 | 
			
		||||
			mux_cell->setPort("\\S", sig_s);
 | 
			
		||||
			mux_cell->setPort("\\Y", RTLIL::SigSpec(next_state_wire));
 | 
			
		||||
			mux_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_a.size());
 | 
			
		||||
			mux_cell->parameters["\\S_WIDTH"] = RTLIL::Const(sig_s.size());
 | 
			
		||||
			RTLIL::Cell *mux_cell = module->addCell(NEW_ID, ID($pmux));
 | 
			
		||||
			mux_cell->setPort(ID::A, sig_a);
 | 
			
		||||
			mux_cell->setPort(ID::B, sig_b);
 | 
			
		||||
			mux_cell->setPort(ID::S, sig_s);
 | 
			
		||||
			mux_cell->setPort(ID::Y, RTLIL::SigSpec(next_state_wire));
 | 
			
		||||
			mux_cell->parameters[ID::WIDTH] = RTLIL::Const(sig_a.size());
 | 
			
		||||
			mux_cell->parameters[ID::S_WIDTH] = RTLIL::Const(sig_s.size());
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -336,15 +336,13 @@ struct FsmMapPass : public Pass {
 | 
			
		|||
		log_header(design, "Executing FSM_MAP pass (mapping FSMs to basic logic).\n");
 | 
			
		||||
		extra_args(args, 1, design);
 | 
			
		||||
 | 
			
		||||
		for (auto &mod_it : design->modules_) {
 | 
			
		||||
			if (!design->selected(mod_it.second))
 | 
			
		||||
				continue;
 | 
			
		||||
		for (auto mod : design->selected_modules()) {
 | 
			
		||||
			std::vector<RTLIL::Cell*> fsm_cells;
 | 
			
		||||
			for (auto &cell_it : mod_it.second->cells_)
 | 
			
		||||
				if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second))
 | 
			
		||||
					fsm_cells.push_back(cell_it.second);
 | 
			
		||||
			for (auto cell : mod->selected_cells())
 | 
			
		||||
				if (cell->type == ID($fsm))
 | 
			
		||||
					fsm_cells.push_back(cell);
 | 
			
		||||
			for (auto cell : fsm_cells)
 | 
			
		||||
					map_fsm(cell, mod_it.second);
 | 
			
		||||
					map_fsm(cell, mod);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
} FsmMapPass;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,10 +81,10 @@ struct FsmOpt
 | 
			
		|||
	{
 | 
			
		||||
		RTLIL::SigBit bit = sig.as_bit();
 | 
			
		||||
 | 
			
		||||
		if (bit.wire == NULL || bit.wire->attributes.count("\\unused_bits") == 0)
 | 
			
		||||
		if (bit.wire == NULL || bit.wire->attributes.count(ID::unused_bits) == 0)
 | 
			
		||||
			return false;
 | 
			
		||||
 | 
			
		||||
		char *str = strdup(bit.wire->attributes["\\unused_bits"].decode_string().c_str());
 | 
			
		||||
		char *str = strdup(bit.wire->attributes[ID::unused_bits].decode_string().c_str());
 | 
			
		||||
		for (char *tok = strtok(str, " "); tok != NULL; tok = strtok(NULL, " ")) {
 | 
			
		||||
			if (tok[0] && bit.offset == atoi(tok)) {
 | 
			
		||||
				free(str);
 | 
			
		||||
| 
						 | 
				
			
			@ -98,7 +98,7 @@ struct FsmOpt
 | 
			
		|||
 | 
			
		||||
	void opt_const_and_unused_inputs()
 | 
			
		||||
	{
 | 
			
		||||
		RTLIL::SigSpec ctrl_in = cell->getPort("\\CTRL_IN");
 | 
			
		||||
		RTLIL::SigSpec ctrl_in = cell->getPort(ID::CTRL_IN);
 | 
			
		||||
		std::vector<bool> ctrl_in_used(ctrl_in.size());
 | 
			
		||||
 | 
			
		||||
		std::vector<FsmData::transition_t> new_transition_table;
 | 
			
		||||
| 
						 | 
				
			
			@ -119,15 +119,15 @@ struct FsmOpt
 | 
			
		|||
 | 
			
		||||
		for (int i = int(ctrl_in_used.size())-1; i >= 0; i--) {
 | 
			
		||||
			if (!ctrl_in_used[i]) {
 | 
			
		||||
				log("  Removing unused input signal %s.\n", log_signal(cell->getPort("\\CTRL_IN").extract(i, 1)));
 | 
			
		||||
				log("  Removing unused input signal %s.\n", log_signal(cell->getPort(ID::CTRL_IN).extract(i, 1)));
 | 
			
		||||
				for (auto &tr : new_transition_table) {
 | 
			
		||||
					RTLIL::SigSpec tmp(tr.ctrl_in);
 | 
			
		||||
					tmp.remove(i, 1);
 | 
			
		||||
					tr.ctrl_in = tmp.as_const();
 | 
			
		||||
				}
 | 
			
		||||
				RTLIL::SigSpec new_ctrl_in = cell->getPort("\\CTRL_IN");
 | 
			
		||||
				RTLIL::SigSpec new_ctrl_in = cell->getPort(ID::CTRL_IN);
 | 
			
		||||
				new_ctrl_in.remove(i, 1);
 | 
			
		||||
				cell->setPort("\\CTRL_IN", new_ctrl_in);
 | 
			
		||||
				cell->setPort(ID::CTRL_IN, new_ctrl_in);
 | 
			
		||||
				fsm_data.num_inputs--;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -139,12 +139,12 @@ struct FsmOpt
 | 
			
		|||
	void opt_unused_outputs()
 | 
			
		||||
	{
 | 
			
		||||
		for (int i = 0; i < fsm_data.num_outputs; i++) {
 | 
			
		||||
			RTLIL::SigSpec sig = cell->getPort("\\CTRL_OUT").extract(i, 1);
 | 
			
		||||
			RTLIL::SigSpec sig = cell->getPort(ID::CTRL_OUT).extract(i, 1);
 | 
			
		||||
			if (signal_is_unused(sig)) {
 | 
			
		||||
				log("  Removing unused output signal %s.\n", log_signal(sig));
 | 
			
		||||
				RTLIL::SigSpec new_ctrl_out = cell->getPort("\\CTRL_OUT");
 | 
			
		||||
				RTLIL::SigSpec new_ctrl_out = cell->getPort(ID::CTRL_OUT);
 | 
			
		||||
				new_ctrl_out.remove(i, 1);
 | 
			
		||||
				cell->setPort("\\CTRL_OUT", new_ctrl_out);
 | 
			
		||||
				cell->setPort(ID::CTRL_OUT, new_ctrl_out);
 | 
			
		||||
				for (auto &tr : fsm_data.transition_table) {
 | 
			
		||||
					RTLIL::SigSpec tmp(tr.ctrl_out);
 | 
			
		||||
					tmp.remove(i, 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -158,7 +158,7 @@ struct FsmOpt
 | 
			
		|||
 | 
			
		||||
	void opt_alias_inputs()
 | 
			
		||||
	{
 | 
			
		||||
		RTLIL::SigSpec &ctrl_in = cell->connections_["\\CTRL_IN"];
 | 
			
		||||
		RTLIL::SigSpec &ctrl_in = cell->connections_[ID::CTRL_IN];
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < ctrl_in.size(); i++)
 | 
			
		||||
		for (int j = i+1; j < ctrl_in.size(); j++)
 | 
			
		||||
| 
						 | 
				
			
			@ -195,8 +195,8 @@ struct FsmOpt
 | 
			
		|||
 | 
			
		||||
	void opt_feedback_inputs()
 | 
			
		||||
	{
 | 
			
		||||
		RTLIL::SigSpec &ctrl_in = cell->connections_["\\CTRL_IN"];
 | 
			
		||||
		RTLIL::SigSpec &ctrl_out = cell->connections_["\\CTRL_OUT"];
 | 
			
		||||
		RTLIL::SigSpec &ctrl_in = cell->connections_[ID::CTRL_IN];
 | 
			
		||||
		RTLIL::SigSpec &ctrl_out = cell->connections_[ID::CTRL_OUT];
 | 
			
		||||
 | 
			
		||||
		for (int j = 0; j < ctrl_out.size(); j++)
 | 
			
		||||
		for (int i = 0; i < ctrl_in.size(); i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -340,12 +340,10 @@ struct FsmOptPass : public Pass {
 | 
			
		|||
		log_header(design, "Executing FSM_OPT pass (simple optimizations of FSMs).\n");
 | 
			
		||||
		extra_args(args, 1, design);
 | 
			
		||||
 | 
			
		||||
		for (auto &mod_it : design->modules_) {
 | 
			
		||||
			if (design->selected(mod_it.second))
 | 
			
		||||
				for (auto &cell_it : mod_it.second->cells_)
 | 
			
		||||
					if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second))
 | 
			
		||||
						FsmData::optimize_fsm(cell_it.second, mod_it.second);
 | 
			
		||||
		}
 | 
			
		||||
		for (auto mod : design->selected_modules())
 | 
			
		||||
			for (auto cell : mod->selected_cells())
 | 
			
		||||
				if (cell->type == ID($fsm))
 | 
			
		||||
					FsmData::optimize_fsm(cell, mod);
 | 
			
		||||
	}
 | 
			
		||||
} FsmOptPass;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,7 @@ PRIVATE_NAMESPACE_BEGIN
 | 
			
		|||
 | 
			
		||||
static void fm_set_fsm_print(RTLIL::Cell *cell, RTLIL::Module *module, FsmData &fsm_data, const char *prefix, FILE *f)
 | 
			
		||||
{
 | 
			
		||||
	std::string name = cell->parameters["\\NAME"].decode_string();
 | 
			
		||||
	std::string name = cell->parameters[ID::NAME].decode_string();
 | 
			
		||||
 | 
			
		||||
	fprintf(f, "set_fsm_state_vector {");
 | 
			
		||||
	for (int i = fsm_data.state_bits-1; i >= 0; i--)
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +53,7 @@ static void fm_set_fsm_print(RTLIL::Cell *cell, RTLIL::Module *module, FsmData &
 | 
			
		|||
 | 
			
		||||
static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fsm_file, FILE *encfile, std::string default_encoding)
 | 
			
		||||
{
 | 
			
		||||
	std::string encoding = cell->attributes.count("\\fsm_encoding") ? cell->attributes.at("\\fsm_encoding").decode_string() : "auto";
 | 
			
		||||
	std::string encoding = cell->attributes.count(ID::fsm_encoding) ? cell->attributes.at(ID::fsm_encoding).decode_string() : "auto";
 | 
			
		||||
 | 
			
		||||
	log("Recoding FSM `%s' from module `%s' using `%s' encoding:\n", cell->name.c_str(), module->name.c_str(), encoding.c_str());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -95,7 +95,7 @@ static void fsm_recode(RTLIL::Cell *cell, RTLIL::Module *module, FILE *fm_set_fs
 | 
			
		|||
		log_error("FSM encoding `%s' is not supported!\n", encoding.c_str());
 | 
			
		||||
 | 
			
		||||
	if (encfile)
 | 
			
		||||
		fprintf(encfile, ".fsm %s %s\n", log_id(module), RTLIL::unescape_id(cell->parameters["\\NAME"].decode_string()).c_str());
 | 
			
		||||
		fprintf(encfile, ".fsm %s %s\n", log_id(module), RTLIL::unescape_id(cell->parameters[ID::NAME].decode_string()).c_str());
 | 
			
		||||
 | 
			
		||||
	int state_idx_counter = fsm_data.reset_state >= 0 ? 1 : 0;
 | 
			
		||||
	for (int i = 0; i < int(fsm_data.state_table.size()); i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -181,11 +181,10 @@ struct FsmRecodePass : public Pass {
 | 
			
		|||
		}
 | 
			
		||||
		extra_args(args, argidx, design);
 | 
			
		||||
 | 
			
		||||
		for (auto &mod_it : design->modules_)
 | 
			
		||||
			if (design->selected(mod_it.second))
 | 
			
		||||
				for (auto &cell_it : mod_it.second->cells_)
 | 
			
		||||
					if (cell_it.second->type == "$fsm" && design->selected(mod_it.second, cell_it.second))
 | 
			
		||||
						fsm_recode(cell_it.second, mod_it.second, fm_set_fsm_file, encfile, default_encoding);
 | 
			
		||||
		for (auto mod : design->selected_modules())
 | 
			
		||||
			for (auto cell : mod->selected_cells())
 | 
			
		||||
				if (cell->type == ID($fsm))
 | 
			
		||||
					fsm_recode(cell, mod, fm_set_fsm_file, encfile, default_encoding);
 | 
			
		||||
 | 
			
		||||
		if (fm_set_fsm_file != NULL)
 | 
			
		||||
			fclose(fm_set_fsm_file);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,31 +33,31 @@ struct FsmData
 | 
			
		|||
 | 
			
		||||
	void copy_to_cell(RTLIL::Cell *cell)
 | 
			
		||||
	{
 | 
			
		||||
		cell->parameters["\\CTRL_IN_WIDTH"] = RTLIL::Const(num_inputs);
 | 
			
		||||
		cell->parameters["\\CTRL_OUT_WIDTH"] = RTLIL::Const(num_outputs);
 | 
			
		||||
		cell->parameters[ID::CTRL_IN_WIDTH] = RTLIL::Const(num_inputs);
 | 
			
		||||
		cell->parameters[ID::CTRL_OUT_WIDTH] = RTLIL::Const(num_outputs);
 | 
			
		||||
 | 
			
		||||
		int state_num_log2 = 0;
 | 
			
		||||
		for (int i = state_table.size(); i > 0; i = i >> 1)
 | 
			
		||||
			state_num_log2++;
 | 
			
		||||
		state_num_log2 = max(state_num_log2, 1);
 | 
			
		||||
 | 
			
		||||
		cell->parameters["\\STATE_BITS"] = RTLIL::Const(state_bits);
 | 
			
		||||
		cell->parameters["\\STATE_NUM"] = RTLIL::Const(state_table.size());
 | 
			
		||||
		cell->parameters["\\STATE_NUM_LOG2"] = RTLIL::Const(state_num_log2);
 | 
			
		||||
		cell->parameters["\\STATE_RST"] = RTLIL::Const(reset_state);
 | 
			
		||||
		cell->parameters["\\STATE_TABLE"] = RTLIL::Const();
 | 
			
		||||
		cell->parameters[ID::STATE_BITS] = RTLIL::Const(state_bits);
 | 
			
		||||
		cell->parameters[ID::STATE_NUM] = RTLIL::Const(state_table.size());
 | 
			
		||||
		cell->parameters[ID::STATE_NUM_LOG2] = RTLIL::Const(state_num_log2);
 | 
			
		||||
		cell->parameters[ID::STATE_RST] = RTLIL::Const(reset_state);
 | 
			
		||||
		cell->parameters[ID::STATE_TABLE] = RTLIL::Const();
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < int(state_table.size()); i++) {
 | 
			
		||||
			std::vector<RTLIL::State> &bits_table = cell->parameters["\\STATE_TABLE"].bits;
 | 
			
		||||
			std::vector<RTLIL::State> &bits_table = cell->parameters[ID::STATE_TABLE].bits;
 | 
			
		||||
			std::vector<RTLIL::State> &bits_state = state_table[i].bits;
 | 
			
		||||
			bits_table.insert(bits_table.end(), bits_state.begin(), bits_state.end());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		cell->parameters["\\TRANS_NUM"] = RTLIL::Const(transition_table.size());
 | 
			
		||||
		cell->parameters["\\TRANS_TABLE"] = RTLIL::Const();
 | 
			
		||||
		cell->parameters[ID::TRANS_NUM] = RTLIL::Const(transition_table.size());
 | 
			
		||||
		cell->parameters[ID::TRANS_TABLE] = RTLIL::Const();
 | 
			
		||||
		for (int i = 0; i < int(transition_table.size()); i++)
 | 
			
		||||
		{
 | 
			
		||||
			std::vector<RTLIL::State> &bits_table = cell->parameters["\\TRANS_TABLE"].bits;
 | 
			
		||||
			std::vector<RTLIL::State> &bits_table = cell->parameters[ID::TRANS_TABLE].bits;
 | 
			
		||||
			transition_t &tr = transition_table[i];
 | 
			
		||||
 | 
			
		||||
			RTLIL::Const const_state_in = RTLIL::Const(tr.state_in, state_num_log2);
 | 
			
		||||
| 
						 | 
				
			
			@ -78,21 +78,21 @@ struct FsmData
 | 
			
		|||
 | 
			
		||||
	void copy_from_cell(RTLIL::Cell *cell)
 | 
			
		||||
	{
 | 
			
		||||
		num_inputs = cell->parameters["\\CTRL_IN_WIDTH"].as_int();
 | 
			
		||||
		num_outputs = cell->parameters["\\CTRL_OUT_WIDTH"].as_int();
 | 
			
		||||
		num_inputs = cell->parameters[ID::CTRL_IN_WIDTH].as_int();
 | 
			
		||||
		num_outputs = cell->parameters[ID::CTRL_OUT_WIDTH].as_int();
 | 
			
		||||
 | 
			
		||||
		state_bits = cell->parameters["\\STATE_BITS"].as_int();
 | 
			
		||||
		reset_state = cell->parameters["\\STATE_RST"].as_int();
 | 
			
		||||
		state_bits = cell->parameters[ID::STATE_BITS].as_int();
 | 
			
		||||
		reset_state = cell->parameters[ID::STATE_RST].as_int();
 | 
			
		||||
 | 
			
		||||
		int state_num = cell->parameters["\\STATE_NUM"].as_int();
 | 
			
		||||
		int state_num_log2 = cell->parameters["\\STATE_NUM_LOG2"].as_int();
 | 
			
		||||
		int trans_num = cell->parameters["\\TRANS_NUM"].as_int();
 | 
			
		||||
		int state_num = cell->parameters[ID::STATE_NUM].as_int();
 | 
			
		||||
		int state_num_log2 = cell->parameters[ID::STATE_NUM_LOG2].as_int();
 | 
			
		||||
		int trans_num = cell->parameters[ID::TRANS_NUM].as_int();
 | 
			
		||||
 | 
			
		||||
		if (reset_state < 0 || reset_state >= state_num)
 | 
			
		||||
			reset_state = -1;
 | 
			
		||||
 | 
			
		||||
		RTLIL::Const state_table = cell->parameters["\\STATE_TABLE"];
 | 
			
		||||
		RTLIL::Const trans_table = cell->parameters["\\TRANS_TABLE"];
 | 
			
		||||
		RTLIL::Const state_table = cell->parameters[ID::STATE_TABLE];
 | 
			
		||||
		RTLIL::Const trans_table = cell->parameters[ID::TRANS_TABLE];
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < state_num; i++) {
 | 
			
		||||
			RTLIL::Const state_code;
 | 
			
		||||
| 
						 | 
				
			
			@ -134,7 +134,7 @@ struct FsmData
 | 
			
		|||
	{
 | 
			
		||||
		log("-------------------------------------\n");
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("  Information on FSM %s (%s):\n", cell->name.c_str(), cell->parameters["\\NAME"].decode_string().c_str());
 | 
			
		||||
		log("  Information on FSM %s (%s):\n", cell->name.c_str(), cell->parameters[ID::NAME].decode_string().c_str());
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("  Number of input signals:  %3d\n", num_inputs);
 | 
			
		||||
		log("  Number of output signals: %3d\n", num_outputs);
 | 
			
		||||
| 
						 | 
				
			
			@ -142,13 +142,13 @@ struct FsmData
 | 
			
		|||
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("  Input signals:\n");
 | 
			
		||||
		RTLIL::SigSpec sig_in = cell->getPort("\\CTRL_IN");
 | 
			
		||||
		RTLIL::SigSpec sig_in = cell->getPort(ID::CTRL_IN);
 | 
			
		||||
		for (int i = 0; i < GetSize(sig_in); i++)
 | 
			
		||||
			log("  %3d: %s\n", i, log_signal(sig_in[i]));
 | 
			
		||||
 | 
			
		||||
		log("\n");
 | 
			
		||||
		log("  Output signals:\n");
 | 
			
		||||
		RTLIL::SigSpec sig_out = cell->getPort("\\CTRL_OUT");
 | 
			
		||||
		RTLIL::SigSpec sig_out = cell->getPort(ID::CTRL_OUT);
 | 
			
		||||
		for (int i = 0; i < GetSize(sig_out); i++)
 | 
			
		||||
			log("  %3d: %s\n", i, log_signal(sig_out[i]));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -120,7 +120,7 @@ void generate(RTLIL::Design *design, const std::vector<std::string> &celltypes,
 | 
			
		|||
 | 
			
		||||
		RTLIL::Module *mod = new RTLIL::Module;
 | 
			
		||||
		mod->name = celltype;
 | 
			
		||||
		mod->attributes["\\blackbox"] = RTLIL::Const(1);
 | 
			
		||||
		mod->attributes[ID::blackbox] = RTLIL::Const(1);
 | 
			
		||||
		design->add(mod);
 | 
			
		||||
 | 
			
		||||
		for (auto &decl : ports) {
 | 
			
		||||
| 
						 | 
				
			
			@ -166,9 +166,9 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
 | 
			
		|||
 | 
			
		||||
	// If any of the ports are actually interface ports, we will always need to
 | 
			
		||||
	// reprocess the module:
 | 
			
		||||
	if(!module->get_bool_attribute("\\interfaces_replaced_in_module")) {
 | 
			
		||||
	if(!module->get_bool_attribute(ID::interfaces_replaced_in_module)) {
 | 
			
		||||
		for (auto wire : module->wires()) {
 | 
			
		||||
			if ((wire->port_input || wire->port_output) && wire->get_bool_attribute("\\is_interface"))
 | 
			
		||||
			if ((wire->port_input || wire->port_output) && wire->get_bool_attribute(ID::is_interface))
 | 
			
		||||
				has_interface_ports = true;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -177,7 +177,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
 | 
			
		|||
	dict<RTLIL::IdString, RTLIL::Module*> interfaces_in_module;
 | 
			
		||||
	for (auto cell : module->cells())
 | 
			
		||||
	{
 | 
			
		||||
		if(cell->get_bool_attribute("\\is_interface")) {
 | 
			
		||||
		if(cell->get_bool_attribute(ID::is_interface)) {
 | 
			
		||||
			RTLIL::Module *intf_module = design->module(cell->type);
 | 
			
		||||
			interfaces_in_module[cell->name] = intf_module;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -253,24 +253,24 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
 | 
			
		|||
		// Go over all connections and see if any of them are SV interfaces. If they are, then add the replacements to
 | 
			
		||||
		// some lists, so that the ports for sub-modules can be replaced further down:
 | 
			
		||||
		for (auto &conn : cell->connections()) {
 | 
			
		||||
			if(mod->wire(conn.first) != nullptr && mod->wire(conn.first)->get_bool_attribute("\\is_interface")) { // Check if the connection is present as an interface in the sub-module's port list
 | 
			
		||||
				//const pool<string> &interface_type_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_type");
 | 
			
		||||
			if(mod->wire(conn.first) != nullptr && mod->wire(conn.first)->get_bool_attribute(ID::is_interface)) { // Check if the connection is present as an interface in the sub-module's port list
 | 
			
		||||
				//const pool<string> &interface_type_pool = mod->wire(conn.first)->get_strpool_attribute(ID::interface_type);
 | 
			
		||||
				//for (auto &d : interface_type_pool) { // TODO: Compare interface type to type in parent module (not crucially important, but good for robustness)
 | 
			
		||||
				//}
 | 
			
		||||
 | 
			
		||||
				// Find if the sub-module has set a modport for the current interface connection:
 | 
			
		||||
				const pool<string> &interface_modport_pool = mod->wire(conn.first)->get_strpool_attribute("\\interface_modport");
 | 
			
		||||
				const pool<string> &interface_modport_pool = mod->wire(conn.first)->get_strpool_attribute(ID::interface_modport);
 | 
			
		||||
				std::string interface_modport = "";
 | 
			
		||||
				for (auto &d : interface_modport_pool) {
 | 
			
		||||
					interface_modport = "\\" + d;
 | 
			
		||||
				}
 | 
			
		||||
				if(conn.second.bits().size() == 1 && conn.second.bits()[0].wire->get_bool_attribute("\\is_interface")) { // Check if the connected wire is a potential interface in the parent module
 | 
			
		||||
				if(conn.second.bits().size() == 1 && conn.second.bits()[0].wire->get_bool_attribute(ID::is_interface)) { // Check if the connected wire is a potential interface in the parent module
 | 
			
		||||
					std::string interface_name_str = conn.second.bits()[0].wire->name.str();
 | 
			
		||||
					interface_name_str.replace(0,23,""); // Strip the prefix '$dummywireforinterface' from the dummy wire to get the name
 | 
			
		||||
					interface_name_str = "\\" + interface_name_str;
 | 
			
		||||
					RTLIL::IdString interface_name = interface_name_str;
 | 
			
		||||
					bool not_found_interface = false;
 | 
			
		||||
					if(module->get_bool_attribute("\\interfaces_replaced_in_module")) { // If 'interfaces' in the cell have not be been handled yet, there is no need to derive the sub-module either
 | 
			
		||||
					if(module->get_bool_attribute(ID::interfaces_replaced_in_module)) { // If 'interfaces' in the cell have not be been handled yet, there is no need to derive the sub-module either
 | 
			
		||||
						// Check if the interface instance is present in module:
 | 
			
		||||
						// Interface instances may either have the plain name or the name appended with '_inst_from_top_dummy'.
 | 
			
		||||
						// Check for both of them here
 | 
			
		||||
| 
						 | 
				
			
			@ -309,7 +309,7 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
 | 
			
		|||
					// which will delay the expansion of this cell:
 | 
			
		||||
					if (not_found_interface) {
 | 
			
		||||
						// If we have already gone over all cells in this module, and the interface has still not been found - flag it as an error:
 | 
			
		||||
						if(!(module->get_bool_attribute("\\cells_not_processed"))) {
 | 
			
		||||
						if(!(module->get_bool_attribute(ID::cells_not_processed))) {
 | 
			
		||||
							log_warning("Could not find interface instance for `%s' in `%s'\n", log_id(interface_name), log_id(module));
 | 
			
		||||
						}
 | 
			
		||||
						else {
 | 
			
		||||
| 
						 | 
				
			
			@ -367,10 +367,10 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
 | 
			
		|||
 | 
			
		||||
		// If there are no overridden parameters AND not interfaces, then we can use the existing module instance as the type
 | 
			
		||||
		// for the cell:
 | 
			
		||||
		if (cell->parameters.size() == 0 && (interfaces_to_add_to_submodule.size() == 0 || !(cell->get_bool_attribute("\\module_not_derived")))) {
 | 
			
		||||
		if (cell->parameters.size() == 0 && (interfaces_to_add_to_submodule.size() == 0 || !(cell->get_bool_attribute(ID::module_not_derived)))) {
 | 
			
		||||
			// If the cell being processed is an the interface instance itself, go down to "handle_interface_instance:",
 | 
			
		||||
			// so that the signals of the interface are added to the parent module.
 | 
			
		||||
			if (mod->get_bool_attribute("\\is_interface")) {
 | 
			
		||||
			if (mod->get_bool_attribute(ID::is_interface)) {
 | 
			
		||||
				goto handle_interface_instance;
 | 
			
		||||
			}
 | 
			
		||||
			continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -384,23 +384,23 @@ bool expand_module(RTLIL::Design *design, RTLIL::Module *module, bool flag_check
 | 
			
		|||
 | 
			
		||||
			// We add all the signals of the interface explicitly to the parent module. This is always needed when we encounter
 | 
			
		||||
			// an interface instance:
 | 
			
		||||
			if (mod->get_bool_attribute("\\is_interface") && cell->get_bool_attribute("\\module_not_derived")) {
 | 
			
		||||
				cell->set_bool_attribute("\\is_interface");
 | 
			
		||||
			if (mod->get_bool_attribute(ID::is_interface) && cell->get_bool_attribute(ID::module_not_derived)) {
 | 
			
		||||
				cell->set_bool_attribute(ID::is_interface);
 | 
			
		||||
				RTLIL::Module *derived_module = design->module(cell->type);
 | 
			
		||||
				interfaces_in_module[cell->name] = derived_module;
 | 
			
		||||
				did_something = true;
 | 
			
		||||
			}
 | 
			
		||||
		// We clear 'module_not_derived' such that we will not rederive the cell again (needed when there are interfaces connected to the cell)
 | 
			
		||||
		cell->attributes.erase("\\module_not_derived");
 | 
			
		||||
		cell->attributes.erase(ID::module_not_derived);
 | 
			
		||||
	}
 | 
			
		||||
	// Clear the attribute 'cells_not_processed' such that it can be known that we
 | 
			
		||||
	// have been through all cells at least once, and that we can know whether
 | 
			
		||||
	// to flag an error because of interface instances not found:
 | 
			
		||||
	module->attributes.erase("\\cells_not_processed");
 | 
			
		||||
	module->attributes.erase(ID::cells_not_processed);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	// If any interface instances or interface ports were found in the module, we need to rederive it completely:
 | 
			
		||||
	if ((interfaces_in_module.size() > 0 || has_interface_ports) && !module->get_bool_attribute("\\interfaces_replaced_in_module")) {
 | 
			
		||||
	if ((interfaces_in_module.size() > 0 || has_interface_ports) && !module->get_bool_attribute(ID::interfaces_replaced_in_module)) {
 | 
			
		||||
		module->reprocess_module(design, interfaces_in_module);
 | 
			
		||||
		return did_something;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -475,7 +475,7 @@ void hierarchy_clean(RTLIL::Design *design, RTLIL::Module *top, bool purge_lib)
 | 
			
		|||
			// safe to delete all of the remaining dummy interface ports:
 | 
			
		||||
			pool<RTLIL::Wire*> del_wires;
 | 
			
		||||
			for(auto wire : mod->wires()) {
 | 
			
		||||
				if ((wire->port_input || wire->port_output) && wire->get_bool_attribute("\\is_interface")) {
 | 
			
		||||
				if ((wire->port_input || wire->port_output) && wire->get_bool_attribute(ID::is_interface)) {
 | 
			
		||||
					del_wires.insert(wire);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -502,7 +502,7 @@ bool set_keep_assert(std::map<RTLIL::Module*, bool> &cache, RTLIL::Module *mod)
 | 
			
		|||
	if (cache.count(mod) == 0)
 | 
			
		||||
		for (auto c : mod->cells()) {
 | 
			
		||||
			RTLIL::Module *m = mod->design->module(c->type);
 | 
			
		||||
			if ((m != nullptr && set_keep_assert(cache, m)) || c->type.in("$assert", "$assume", "$live", "$fair", "$cover"))
 | 
			
		||||
			if ((m != nullptr && set_keep_assert(cache, m)) || c->type.in(ID($assert), ID($assume), ID($live), ID($fair), ID($cover)))
 | 
			
		||||
				return cache[mod] = true;
 | 
			
		||||
		}
 | 
			
		||||
	return cache[mod];
 | 
			
		||||
| 
						 | 
				
			
			@ -532,11 +532,11 @@ int find_top_mod_score(Design *design, Module *module, dict<Module*, int> &db)
 | 
			
		|||
 | 
			
		||||
RTLIL::Module *check_if_top_has_changed(Design *design, Module *top_mod)
 | 
			
		||||
{
 | 
			
		||||
	if(top_mod != NULL && top_mod->get_bool_attribute("\\initial_top"))
 | 
			
		||||
	if(top_mod != NULL && top_mod->get_bool_attribute(ID::initial_top))
 | 
			
		||||
		return top_mod;
 | 
			
		||||
	else {
 | 
			
		||||
		for (auto mod : design->modules()) {
 | 
			
		||||
			if (mod->get_bool_attribute("\\top")) {
 | 
			
		||||
			if (mod->get_bool_attribute(ID::top)) {
 | 
			
		||||
				return mod;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -814,7 +814,7 @@ struct HierarchyPass : public Pass {
 | 
			
		|||
 | 
			
		||||
		if (top_mod == nullptr)
 | 
			
		||||
			for (auto mod : design->modules())
 | 
			
		||||
				if (mod->get_bool_attribute("\\top"))
 | 
			
		||||
				if (mod->get_bool_attribute(ID::top))
 | 
			
		||||
					top_mod = mod;
 | 
			
		||||
 | 
			
		||||
		if (top_mod != nullptr && top_mod->name.begins_with("$abstract")) {
 | 
			
		||||
| 
						 | 
				
			
			@ -860,9 +860,9 @@ struct HierarchyPass : public Pass {
 | 
			
		|||
		if (top_mod != NULL) {
 | 
			
		||||
			for (auto mod : design->modules())
 | 
			
		||||
				if (mod == top_mod)
 | 
			
		||||
					mod->attributes["\\initial_top"] = RTLIL::Const(1);
 | 
			
		||||
					mod->attributes[ID::initial_top] = RTLIL::Const(1);
 | 
			
		||||
				else
 | 
			
		||||
					mod->attributes.erase("\\initial_top");
 | 
			
		||||
					mod->attributes.erase(ID::initial_top);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool did_something = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -897,7 +897,7 @@ struct HierarchyPass : public Pass {
 | 
			
		|||
			// Delete modules marked as 'to_delete':
 | 
			
		||||
			std::vector<RTLIL::Module *> modules_to_delete;
 | 
			
		||||
			for(auto mod : design->modules()) {
 | 
			
		||||
				if (mod->get_bool_attribute("\\to_delete")) {
 | 
			
		||||
				if (mod->get_bool_attribute(ID::to_delete)) {
 | 
			
		||||
					modules_to_delete.push_back(mod);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -915,10 +915,10 @@ struct HierarchyPass : public Pass {
 | 
			
		|||
		if (top_mod != NULL) {
 | 
			
		||||
			for (auto mod : design->modules()) {
 | 
			
		||||
				if (mod == top_mod)
 | 
			
		||||
					mod->attributes["\\top"] = RTLIL::Const(1);
 | 
			
		||||
					mod->attributes[ID::top] = RTLIL::Const(1);
 | 
			
		||||
				else
 | 
			
		||||
					mod->attributes.erase("\\top");
 | 
			
		||||
				mod->attributes.erase("\\initial_top");
 | 
			
		||||
					mod->attributes.erase(ID::top);
 | 
			
		||||
				mod->attributes.erase(ID::initial_top);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -927,7 +927,7 @@ struct HierarchyPass : public Pass {
 | 
			
		|||
			for (auto mod : design->modules())
 | 
			
		||||
				if (set_keep_assert(cache, mod)) {
 | 
			
		||||
					log("Module %s directly or indirectly contains formal properties -> setting \"keep\" attribute.\n", log_id(mod));
 | 
			
		||||
					mod->set_bool_attribute("\\keep");
 | 
			
		||||
					mod->set_bool_attribute(ID::keep);
 | 
			
		||||
				}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -983,8 +983,8 @@ struct HierarchyPass : public Pass {
 | 
			
		|||
		{
 | 
			
		||||
			for (auto module : design->modules())
 | 
			
		||||
				for (auto wire : module->wires())
 | 
			
		||||
					if (wire->port_input && wire->attributes.count("\\defaultvalue"))
 | 
			
		||||
						defaults_db[module->name][wire->name] = wire->attributes.at("\\defaultvalue");
 | 
			
		||||
					if (wire->port_input && wire->attributes.count(ID::defaultvalue))
 | 
			
		||||
						defaults_db[module->name][wire->name] = wire->attributes.at(ID::defaultvalue);
 | 
			
		||||
		}
 | 
			
		||||
		// Process SV implicit wildcard port connections
 | 
			
		||||
		std::set<Module*> blackbox_derivatives;
 | 
			
		||||
| 
						 | 
				
			
			@ -994,7 +994,7 @@ struct HierarchyPass : public Pass {
 | 
			
		|||
		{
 | 
			
		||||
			for (auto cell : module->cells())
 | 
			
		||||
			{
 | 
			
		||||
				if (!cell->get_bool_attribute(ID(wildcard_port_conns)))
 | 
			
		||||
				if (!cell->get_bool_attribute(ID::wildcard_port_conns))
 | 
			
		||||
					continue;
 | 
			
		||||
				Module *m = design->module(cell->type);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1003,7 +1003,7 @@ struct HierarchyPass : public Pass {
 | 
			
		|||
							RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
 | 
			
		||||
 | 
			
		||||
				// Need accurate port widths for error checking; so must derive blackboxes with dynamic port widths
 | 
			
		||||
				if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) {
 | 
			
		||||
				if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute(ID::dynports)) {
 | 
			
		||||
					IdString new_m_name = m->derive(design, cell->parameters, true);
 | 
			
		||||
					if (new_m_name.empty())
 | 
			
		||||
						continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -1036,7 +1036,7 @@ struct HierarchyPass : public Pass {
 | 
			
		|||
								RTLIL::id2cstr(wire->name), RTLIL::id2cstr(module->name), RTLIL::id2cstr(cell->name), RTLIL::id2cstr(cell->type));
 | 
			
		||||
					cell->setPort(wire->name, parent_wire);
 | 
			
		||||
				}
 | 
			
		||||
				cell->attributes.erase(ID(wildcard_port_conns));
 | 
			
		||||
				cell->attributes.erase(ID::wildcard_port_conns);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1071,11 +1071,11 @@ struct HierarchyPass : public Pass {
 | 
			
		|||
 | 
			
		||||
			for (auto wire : module->wires())
 | 
			
		||||
			{
 | 
			
		||||
				if (wire->get_bool_attribute("\\wand")) {
 | 
			
		||||
				if (wire->get_bool_attribute(ID::wand)) {
 | 
			
		||||
					wand_map[wire] = SigSpec();
 | 
			
		||||
					wand_wor_index.insert(wire);
 | 
			
		||||
				}
 | 
			
		||||
				if (wire->get_bool_attribute("\\wor")) {
 | 
			
		||||
				if (wire->get_bool_attribute(ID::wor)) {
 | 
			
		||||
					wor_map[wire] = SigSpec();
 | 
			
		||||
					wand_wor_index.insert(wire);
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -1186,7 +1186,7 @@ struct HierarchyPass : public Pass {
 | 
			
		|||
				if (m == nullptr)
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) {
 | 
			
		||||
				if (m->get_blackbox_attribute() && !cell->parameters.empty() && m->get_bool_attribute(ID::dynports)) {
 | 
			
		||||
					IdString new_m_name = m->derive(design, cell->parameters, true);
 | 
			
		||||
					if (new_m_name.empty())
 | 
			
		||||
						continue;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -176,16 +176,16 @@ struct SubmodWorker
 | 
			
		|||
			new_wire->start_offset = wire->start_offset;
 | 
			
		||||
			new_wire->attributes = wire->attributes;
 | 
			
		||||
			if (!flags.is_int_driven.is_fully_zero()) {
 | 
			
		||||
				new_wire->attributes.erase(ID(init));
 | 
			
		||||
				new_wire->attributes.erase(ID::init);
 | 
			
		||||
				auto sig = sigmap(wire);
 | 
			
		||||
				for (int i = 0; i < GetSize(sig); i++) {
 | 
			
		||||
					if (flags.is_int_driven[i] == State::S0)
 | 
			
		||||
						continue;
 | 
			
		||||
					if (!sig[i].wire)
 | 
			
		||||
						continue;
 | 
			
		||||
					auto it = sig[i].wire->attributes.find(ID(init));
 | 
			
		||||
					auto it = sig[i].wire->attributes.find(ID::init);
 | 
			
		||||
					if (it != sig[i].wire->attributes.end()) {
 | 
			
		||||
						auto jt = new_wire->attributes.insert(std::make_pair(ID(init), Const(State::Sx, GetSize(sig)))).first;
 | 
			
		||||
						auto jt = new_wire->attributes.insert(std::make_pair(ID::init, Const(State::Sx, GetSize(sig)))).first;
 | 
			
		||||
						jt->second[i] = it->second[sig[i].offset];
 | 
			
		||||
						it->second[sig[i].offset] = State::Sx;
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			@ -275,18 +275,18 @@ struct SubmodWorker
 | 
			
		|||
		if (opt_name.empty())
 | 
			
		||||
		{
 | 
			
		||||
			for (auto &it : module->wires_)
 | 
			
		||||
				it.second->attributes.erase("\\submod");
 | 
			
		||||
				it.second->attributes.erase(ID::submod);
 | 
			
		||||
 | 
			
		||||
			for (auto &it : module->cells_)
 | 
			
		||||
			{
 | 
			
		||||
				RTLIL::Cell *cell = it.second;
 | 
			
		||||
				if (cell->attributes.count("\\submod") == 0 || cell->attributes["\\submod"].bits.size() == 0) {
 | 
			
		||||
					cell->attributes.erase("\\submod");
 | 
			
		||||
				if (cell->attributes.count(ID::submod) == 0 || cell->attributes[ID::submod].bits.size() == 0) {
 | 
			
		||||
					cell->attributes.erase(ID::submod);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				std::string submod_str = cell->attributes["\\submod"].decode_string();
 | 
			
		||||
				cell->attributes.erase("\\submod");
 | 
			
		||||
				std::string submod_str = cell->attributes[ID::submod].decode_string();
 | 
			
		||||
				cell->attributes.erase(ID::submod);
 | 
			
		||||
 | 
			
		||||
				if (submodules.count(submod_str) == 0) {
 | 
			
		||||
					submodules[submod_str].name = submod_str;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,7 +64,7 @@ struct UniquifyPass : public Pass {
 | 
			
		|||
 | 
			
		||||
			for (auto module : design->selected_modules())
 | 
			
		||||
			{
 | 
			
		||||
				if (!module->get_bool_attribute("\\unique") && !module->get_bool_attribute("\\top"))
 | 
			
		||||
				if (!module->get_bool_attribute(ID::unique) && !module->get_bool_attribute(ID::top))
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				for (auto cell : module->selected_cells())
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +78,7 @@ struct UniquifyPass : public Pass {
 | 
			
		|||
					if (tmod->get_blackbox_attribute())
 | 
			
		||||
						continue;
 | 
			
		||||
 | 
			
		||||
					if (tmod->get_bool_attribute("\\unique") && newname == tmod->name)
 | 
			
		||||
					if (tmod->get_bool_attribute(ID::unique) && newname == tmod->name)
 | 
			
		||||
						continue;
 | 
			
		||||
 | 
			
		||||
					log("Creating module %s from %s.\n", log_id(newname), log_id(tmod));
 | 
			
		||||
| 
						 | 
				
			
			@ -86,9 +86,9 @@ struct UniquifyPass : public Pass {
 | 
			
		|||
					auto smod = tmod->clone();
 | 
			
		||||
					smod->name = newname;
 | 
			
		||||
					cell->type = newname;
 | 
			
		||||
					smod->set_bool_attribute("\\unique");
 | 
			
		||||
					if (smod->attributes.count("\\hdlname") == 0)
 | 
			
		||||
						smod->attributes["\\hdlname"] = string(log_id(tmod->name));
 | 
			
		||||
					smod->set_bool_attribute(ID::unique);
 | 
			
		||||
					if (smod->attributes.count(ID::hdlname) == 0)
 | 
			
		||||
						smod->attributes[ID::hdlname] = string(log_id(tmod->name));
 | 
			
		||||
					design->add(smod);
 | 
			
		||||
 | 
			
		||||
					did_something = true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -105,11 +105,11 @@ struct rules_t
 | 
			
		|||
				log_error("Bram %s variants %d and %d have different values for 'groups'.\n", log_id(name), variant, other.variant);
 | 
			
		||||
 | 
			
		||||
			if (abits != other.abits)
 | 
			
		||||
				variant_params["\\CFG_ABITS"] = abits;
 | 
			
		||||
				variant_params[ID::CFG_ABITS] = abits;
 | 
			
		||||
			if (dbits != other.dbits)
 | 
			
		||||
				variant_params["\\CFG_DBITS"] = dbits;
 | 
			
		||||
				variant_params[ID::CFG_DBITS] = dbits;
 | 
			
		||||
			if (init != other.init)
 | 
			
		||||
				variant_params["\\CFG_INIT"] = init;
 | 
			
		||||
				variant_params[ID::CFG_INIT] = init;
 | 
			
		||||
 | 
			
		||||
			for (int i = 0; i < groups; i++)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -414,44 +414,44 @@ bool replace_cell(Cell *cell, const rules_t &rules, const rules_t::bram_t &bram,
 | 
			
		|||
	log("    Mapping to bram type %s (variant %d):\n", log_id(bram.name), bram.variant);
 | 
			
		||||
	// bram.dump_config();
 | 
			
		||||
 | 
			
		||||
	int mem_size = cell->getParam("\\SIZE").as_int();
 | 
			
		||||
	int mem_abits = cell->getParam("\\ABITS").as_int();
 | 
			
		||||
	int mem_width = cell->getParam("\\WIDTH").as_int();
 | 
			
		||||
	// int mem_offset = cell->getParam("\\OFFSET").as_int();
 | 
			
		||||
	int mem_size = cell->getParam(ID::SIZE).as_int();
 | 
			
		||||
	int mem_abits = cell->getParam(ID::ABITS).as_int();
 | 
			
		||||
	int mem_width = cell->getParam(ID::WIDTH).as_int();
 | 
			
		||||
	// int mem_offset = cell->getParam(ID::OFFSET).as_int();
 | 
			
		||||
 | 
			
		||||
	bool cell_init = !SigSpec(cell->getParam("\\INIT")).is_fully_undef();
 | 
			
		||||
	bool cell_init = !SigSpec(cell->getParam(ID::INIT)).is_fully_undef();
 | 
			
		||||
	vector<Const> initdata;
 | 
			
		||||
 | 
			
		||||
	if (cell_init) {
 | 
			
		||||
		Const initparam = cell->getParam("\\INIT");
 | 
			
		||||
		Const initparam = cell->getParam(ID::INIT);
 | 
			
		||||
		initdata.reserve(mem_size);
 | 
			
		||||
		for (int i=0; i < mem_size; i++)
 | 
			
		||||
			initdata.push_back(initparam.extract(mem_width*i, mem_width, State::Sx));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	int wr_ports = cell->getParam("\\WR_PORTS").as_int();
 | 
			
		||||
	auto wr_clken = SigSpec(cell->getParam("\\WR_CLK_ENABLE"));
 | 
			
		||||
	auto wr_clkpol = SigSpec(cell->getParam("\\WR_CLK_POLARITY"));
 | 
			
		||||
	int wr_ports = cell->getParam(ID::WR_PORTS).as_int();
 | 
			
		||||
	auto wr_clken = SigSpec(cell->getParam(ID::WR_CLK_ENABLE));
 | 
			
		||||
	auto wr_clkpol = SigSpec(cell->getParam(ID::WR_CLK_POLARITY));
 | 
			
		||||
	wr_clken.extend_u0(wr_ports);
 | 
			
		||||
	wr_clkpol.extend_u0(wr_ports);
 | 
			
		||||
 | 
			
		||||
	SigSpec wr_en = cell->getPort("\\WR_EN");
 | 
			
		||||
	SigSpec wr_clk = cell->getPort("\\WR_CLK");
 | 
			
		||||
	SigSpec wr_data = cell->getPort("\\WR_DATA");
 | 
			
		||||
	SigSpec wr_addr = cell->getPort("\\WR_ADDR");
 | 
			
		||||
	SigSpec wr_en = cell->getPort(ID::WR_EN);
 | 
			
		||||
	SigSpec wr_clk = cell->getPort(ID::WR_CLK);
 | 
			
		||||
	SigSpec wr_data = cell->getPort(ID::WR_DATA);
 | 
			
		||||
	SigSpec wr_addr = cell->getPort(ID::WR_ADDR);
 | 
			
		||||
 | 
			
		||||
	int rd_ports = cell->getParam("\\RD_PORTS").as_int();
 | 
			
		||||
	auto rd_clken = SigSpec(cell->getParam("\\RD_CLK_ENABLE"));
 | 
			
		||||
	auto rd_clkpol = SigSpec(cell->getParam("\\RD_CLK_POLARITY"));
 | 
			
		||||
	auto rd_transp = SigSpec(cell->getParam("\\RD_TRANSPARENT"));
 | 
			
		||||
	int rd_ports = cell->getParam(ID::RD_PORTS).as_int();
 | 
			
		||||
	auto rd_clken = SigSpec(cell->getParam(ID::RD_CLK_ENABLE));
 | 
			
		||||
	auto rd_clkpol = SigSpec(cell->getParam(ID::RD_CLK_POLARITY));
 | 
			
		||||
	auto rd_transp = SigSpec(cell->getParam(ID::RD_TRANSPARENT));
 | 
			
		||||
	rd_clken.extend_u0(rd_ports);
 | 
			
		||||
	rd_clkpol.extend_u0(rd_ports);
 | 
			
		||||
	rd_transp.extend_u0(rd_ports);
 | 
			
		||||
 | 
			
		||||
	SigSpec rd_en = cell->getPort("\\RD_EN");
 | 
			
		||||
	SigSpec rd_clk = cell->getPort("\\RD_CLK");
 | 
			
		||||
	SigSpec rd_data = cell->getPort("\\RD_DATA");
 | 
			
		||||
	SigSpec rd_addr = cell->getPort("\\RD_ADDR");
 | 
			
		||||
	SigSpec rd_en = cell->getPort(ID::RD_EN);
 | 
			
		||||
	SigSpec rd_clk = cell->getPort(ID::RD_CLK);
 | 
			
		||||
	SigSpec rd_data = cell->getPort(ID::RD_DATA);
 | 
			
		||||
	SigSpec rd_addr = cell->getPort(ID::RD_ADDR);
 | 
			
		||||
 | 
			
		||||
	if (match.shuffle_enable && bram.dbits >= portinfos.at(match.shuffle_enable - 'A').enable*2 && portinfos.at(match.shuffle_enable - 'A').enable > 0 && wr_ports > 0)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -915,7 +915,7 @@ grow_read_ports:;
 | 
			
		|||
						else
 | 
			
		||||
							initparam[i*bram.dbits+j] = padding;
 | 
			
		||||
				}
 | 
			
		||||
				c->setParam("\\INIT", initparam);
 | 
			
		||||
				c->setParam(ID::INIT, initparam);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for (auto &pi : portinfos)
 | 
			
		||||
| 
						 | 
				
			
			@ -1048,14 +1048,14 @@ void handle_cell(Cell *cell, const rules_t &rules)
 | 
			
		|||
{
 | 
			
		||||
	log("Processing %s.%s:\n", log_id(cell->module), log_id(cell));
 | 
			
		||||
 | 
			
		||||
	bool cell_init = !SigSpec(cell->getParam("\\INIT")).is_fully_undef();
 | 
			
		||||
	bool cell_init = !SigSpec(cell->getParam(ID::INIT)).is_fully_undef();
 | 
			
		||||
 | 
			
		||||
	dict<string, int> match_properties;
 | 
			
		||||
	match_properties["words"]  = cell->getParam("\\SIZE").as_int();
 | 
			
		||||
	match_properties["abits"]  = cell->getParam("\\ABITS").as_int();
 | 
			
		||||
	match_properties["dbits"]  = cell->getParam("\\WIDTH").as_int();
 | 
			
		||||
	match_properties["wports"] = cell->getParam("\\WR_PORTS").as_int();
 | 
			
		||||
	match_properties["rports"] = cell->getParam("\\RD_PORTS").as_int();
 | 
			
		||||
	match_properties["words"]  = cell->getParam(ID::SIZE).as_int();
 | 
			
		||||
	match_properties["abits"]  = cell->getParam(ID::ABITS).as_int();
 | 
			
		||||
	match_properties["dbits"]  = cell->getParam(ID::WIDTH).as_int();
 | 
			
		||||
	match_properties["wports"] = cell->getParam(ID::WR_PORTS).as_int();
 | 
			
		||||
	match_properties["rports"] = cell->getParam(ID::RD_PORTS).as_int();
 | 
			
		||||
	match_properties["bits"]   = match_properties["words"] * match_properties["dbits"];
 | 
			
		||||
	match_properties["ports"]  = match_properties["wports"] + match_properties["rports"];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1357,7 +1357,7 @@ struct MemoryBramPass : public Pass {
 | 
			
		|||
 | 
			
		||||
		for (auto mod : design->selected_modules())
 | 
			
		||||
		for (auto cell : mod->selected_cells())
 | 
			
		||||
			if (cell->type == "$mem")
 | 
			
		||||
			if (cell->type == ID($mem))
 | 
			
		||||
				handle_cell(cell, rules);
 | 
			
		||||
	}
 | 
			
		||||
} MemoryBramPass;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,11 +25,11 @@ PRIVATE_NAMESPACE_BEGIN
 | 
			
		|||
 | 
			
		||||
bool memcells_cmp(Cell *a, Cell *b)
 | 
			
		||||
{
 | 
			
		||||
	if (a->type == "$memrd" && b->type == "$memrd")
 | 
			
		||||
	if (a->type == ID($memrd) && b->type == ID($memrd))
 | 
			
		||||
		return a->name < b->name;
 | 
			
		||||
	if (a->type == "$memrd" || b->type == "$memrd")
 | 
			
		||||
		return (a->type == "$memrd") < (b->type == "$memrd");
 | 
			
		||||
	return a->parameters.at("\\PRIORITY").as_int() < b->parameters.at("\\PRIORITY").as_int();
 | 
			
		||||
	if (a->type == ID($memrd) || b->type == ID($memrd))
 | 
			
		||||
		return (a->type == ID($memrd)) < (b->type == ID($memrd));
 | 
			
		||||
	return a->parameters.at(ID::PRIORITY).as_int() < b->parameters.at(ID::PRIORITY).as_int();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Cell *handle_memory(Module *module, RTLIL::Memory *memory)
 | 
			
		||||
| 
						 | 
				
			
			@ -62,8 +62,8 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
 | 
			
		|||
 | 
			
		||||
	for (auto &cell_it : module->cells_) {
 | 
			
		||||
		Cell *cell = cell_it.second;
 | 
			
		||||
		if (cell->type.in("$memrd", "$memwr", "$meminit") && memory->name == cell->parameters["\\MEMID"].decode_string()) {
 | 
			
		||||
			SigSpec addr = sigmap(cell->getPort("\\ADDR"));
 | 
			
		||||
		if (cell->type.in(ID($memrd), ID($memwr), ID($meminit)) && memory->name == cell->parameters[ID::MEMID].decode_string()) {
 | 
			
		||||
			SigSpec addr = sigmap(cell->getPort(ID::ADDR));
 | 
			
		||||
			for (int i = 0; i < GetSize(addr); i++)
 | 
			
		||||
				if (addr[i] != State::S0)
 | 
			
		||||
					addr_bits = std::max(addr_bits, i+1);
 | 
			
		||||
| 
						 | 
				
			
			@ -90,10 +90,10 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
 | 
			
		|||
	{
 | 
			
		||||
		log("  %s (%s)\n", log_id(cell), log_id(cell->type));
 | 
			
		||||
 | 
			
		||||
		if (cell->type == "$meminit")
 | 
			
		||||
		if (cell->type == ID($meminit))
 | 
			
		||||
		{
 | 
			
		||||
			SigSpec addr = sigmap(cell->getPort("\\ADDR"));
 | 
			
		||||
			SigSpec data = sigmap(cell->getPort("\\DATA"));
 | 
			
		||||
			SigSpec addr = sigmap(cell->getPort(ID::ADDR));
 | 
			
		||||
			SigSpec data = sigmap(cell->getPort(ID::DATA));
 | 
			
		||||
 | 
			
		||||
			if (!addr.is_fully_const())
 | 
			
		||||
				log_error("Non-constant address %s in memory initialization %s.\n", log_signal(addr), log_id(cell));
 | 
			
		||||
| 
						 | 
				
			
			@ -112,14 +112,14 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
 | 
			
		|||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (cell->type == "$memwr")
 | 
			
		||||
		if (cell->type == ID($memwr))
 | 
			
		||||
		{
 | 
			
		||||
			SigSpec clk = sigmap(cell->getPort("\\CLK"));
 | 
			
		||||
			SigSpec clk_enable = SigSpec(cell->parameters["\\CLK_ENABLE"]);
 | 
			
		||||
			SigSpec clk_polarity = SigSpec(cell->parameters["\\CLK_POLARITY"]);
 | 
			
		||||
			SigSpec addr = sigmap(cell->getPort("\\ADDR"));
 | 
			
		||||
			SigSpec data = sigmap(cell->getPort("\\DATA"));
 | 
			
		||||
			SigSpec en = sigmap(cell->getPort("\\EN"));
 | 
			
		||||
			SigSpec clk = sigmap(cell->getPort(ID::CLK));
 | 
			
		||||
			SigSpec clk_enable = SigSpec(cell->parameters[ID::CLK_ENABLE]);
 | 
			
		||||
			SigSpec clk_polarity = SigSpec(cell->parameters[ID::CLK_POLARITY]);
 | 
			
		||||
			SigSpec addr = sigmap(cell->getPort(ID::ADDR));
 | 
			
		||||
			SigSpec data = sigmap(cell->getPort(ID::DATA));
 | 
			
		||||
			SigSpec en = sigmap(cell->getPort(ID::EN));
 | 
			
		||||
 | 
			
		||||
			if (!en.is_fully_zero())
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -142,15 +142,15 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
 | 
			
		|||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (cell->type == "$memrd")
 | 
			
		||||
		if (cell->type == ID($memrd))
 | 
			
		||||
		{
 | 
			
		||||
			SigSpec clk = sigmap(cell->getPort("\\CLK"));
 | 
			
		||||
			SigSpec clk_enable = SigSpec(cell->parameters["\\CLK_ENABLE"]);
 | 
			
		||||
			SigSpec clk_polarity = SigSpec(cell->parameters["\\CLK_POLARITY"]);
 | 
			
		||||
			SigSpec transparent = SigSpec(cell->parameters["\\TRANSPARENT"]);
 | 
			
		||||
			SigSpec addr = sigmap(cell->getPort("\\ADDR"));
 | 
			
		||||
			SigSpec data = sigmap(cell->getPort("\\DATA"));
 | 
			
		||||
			SigSpec en = sigmap(cell->getPort("\\EN"));
 | 
			
		||||
			SigSpec clk = sigmap(cell->getPort(ID::CLK));
 | 
			
		||||
			SigSpec clk_enable = SigSpec(cell->parameters[ID::CLK_ENABLE]);
 | 
			
		||||
			SigSpec clk_polarity = SigSpec(cell->parameters[ID::CLK_POLARITY]);
 | 
			
		||||
			SigSpec transparent = SigSpec(cell->parameters[ID::TRANSPARENT]);
 | 
			
		||||
			SigSpec addr = sigmap(cell->getPort(ID::ADDR));
 | 
			
		||||
			SigSpec data = sigmap(cell->getPort(ID::DATA));
 | 
			
		||||
			SigSpec en = sigmap(cell->getPort(ID::EN));
 | 
			
		||||
 | 
			
		||||
			if (!en.is_fully_zero())
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -178,13 +178,13 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
 | 
			
		|||
	std::stringstream sstr;
 | 
			
		||||
	sstr << "$mem$" << memory->name.str() << "$" << (autoidx++);
 | 
			
		||||
 | 
			
		||||
	Cell *mem = module->addCell(sstr.str(), "$mem");
 | 
			
		||||
	mem->parameters["\\MEMID"] = Const(memory->name.str());
 | 
			
		||||
	mem->parameters["\\WIDTH"] = Const(memory->width);
 | 
			
		||||
	mem->parameters["\\OFFSET"] = Const(memory->start_offset);
 | 
			
		||||
	mem->parameters["\\SIZE"] = Const(memory->size);
 | 
			
		||||
	mem->parameters["\\ABITS"] = Const(addr_bits);
 | 
			
		||||
	mem->parameters["\\INIT"] = init_data;
 | 
			
		||||
	Cell *mem = module->addCell(sstr.str(), ID($mem));
 | 
			
		||||
	mem->parameters[ID::MEMID] = Const(memory->name.str());
 | 
			
		||||
	mem->parameters[ID::WIDTH] = Const(memory->width);
 | 
			
		||||
	mem->parameters[ID::OFFSET] = Const(memory->start_offset);
 | 
			
		||||
	mem->parameters[ID::SIZE] = Const(memory->size);
 | 
			
		||||
	mem->parameters[ID::ABITS] = Const(addr_bits);
 | 
			
		||||
	mem->parameters[ID::INIT] = init_data;
 | 
			
		||||
 | 
			
		||||
	log_assert(sig_wr_clk.size() == wr_ports);
 | 
			
		||||
	log_assert(sig_wr_clk_enable.size() == wr_ports && sig_wr_clk_enable.is_fully_const());
 | 
			
		||||
| 
						 | 
				
			
			@ -193,14 +193,14 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
 | 
			
		|||
	log_assert(sig_wr_data.size() == wr_ports * memory->width);
 | 
			
		||||
	log_assert(sig_wr_en.size() == wr_ports * memory->width);
 | 
			
		||||
 | 
			
		||||
	mem->parameters["\\WR_PORTS"] = Const(wr_ports);
 | 
			
		||||
	mem->parameters["\\WR_CLK_ENABLE"] = wr_ports ? sig_wr_clk_enable.as_const() : State::S0;
 | 
			
		||||
	mem->parameters["\\WR_CLK_POLARITY"] = wr_ports ? sig_wr_clk_polarity.as_const() : State::S0;
 | 
			
		||||
	mem->parameters[ID::WR_PORTS] = Const(wr_ports);
 | 
			
		||||
	mem->parameters[ID::WR_CLK_ENABLE] = wr_ports ? sig_wr_clk_enable.as_const() : State::S0;
 | 
			
		||||
	mem->parameters[ID::WR_CLK_POLARITY] = wr_ports ? sig_wr_clk_polarity.as_const() : State::S0;
 | 
			
		||||
 | 
			
		||||
	mem->setPort("\\WR_CLK", sig_wr_clk);
 | 
			
		||||
	mem->setPort("\\WR_ADDR", sig_wr_addr);
 | 
			
		||||
	mem->setPort("\\WR_DATA", sig_wr_data);
 | 
			
		||||
	mem->setPort("\\WR_EN", sig_wr_en);
 | 
			
		||||
	mem->setPort(ID::WR_CLK, sig_wr_clk);
 | 
			
		||||
	mem->setPort(ID::WR_ADDR, sig_wr_addr);
 | 
			
		||||
	mem->setPort(ID::WR_DATA, sig_wr_data);
 | 
			
		||||
	mem->setPort(ID::WR_EN, sig_wr_en);
 | 
			
		||||
 | 
			
		||||
	log_assert(sig_rd_clk.size() == rd_ports);
 | 
			
		||||
	log_assert(sig_rd_clk_enable.size() == rd_ports && sig_rd_clk_enable.is_fully_const());
 | 
			
		||||
| 
						 | 
				
			
			@ -208,15 +208,15 @@ Cell *handle_memory(Module *module, RTLIL::Memory *memory)
 | 
			
		|||
	log_assert(sig_rd_addr.size() == rd_ports * addr_bits);
 | 
			
		||||
	log_assert(sig_rd_data.size() == rd_ports * memory->width);
 | 
			
		||||
 | 
			
		||||
	mem->parameters["\\RD_PORTS"] = Const(rd_ports);
 | 
			
		||||
	mem->parameters["\\RD_CLK_ENABLE"] = rd_ports ? sig_rd_clk_enable.as_const() : State::S0;
 | 
			
		||||
	mem->parameters["\\RD_CLK_POLARITY"] = rd_ports ? sig_rd_clk_polarity.as_const() : State::S0;
 | 
			
		||||
	mem->parameters["\\RD_TRANSPARENT"] = rd_ports ? sig_rd_transparent.as_const() : State::S0;
 | 
			
		||||
	mem->parameters[ID::RD_PORTS] = Const(rd_ports);
 | 
			
		||||
	mem->parameters[ID::RD_CLK_ENABLE] = rd_ports ? sig_rd_clk_enable.as_const() : State::S0;
 | 
			
		||||
	mem->parameters[ID::RD_CLK_POLARITY] = rd_ports ? sig_rd_clk_polarity.as_const() : State::S0;
 | 
			
		||||
	mem->parameters[ID::RD_TRANSPARENT] = rd_ports ? sig_rd_transparent.as_const() : State::S0;
 | 
			
		||||
 | 
			
		||||
	mem->setPort("\\RD_CLK", sig_rd_clk);
 | 
			
		||||
	mem->setPort("\\RD_ADDR", sig_rd_addr);
 | 
			
		||||
	mem->setPort("\\RD_DATA", sig_rd_data);
 | 
			
		||||
	mem->setPort("\\RD_EN", sig_rd_en);
 | 
			
		||||
	mem->setPort(ID::RD_CLK, sig_rd_clk);
 | 
			
		||||
	mem->setPort(ID::RD_ADDR, sig_rd_addr);
 | 
			
		||||
	mem->setPort(ID::RD_DATA, sig_rd_data);
 | 
			
		||||
	mem->setPort(ID::RD_EN, sig_rd_en);
 | 
			
		||||
 | 
			
		||||
	// Copy attributes from RTLIL memory to $mem
 | 
			
		||||
	for (auto attr : memory->attributes)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,10 +39,10 @@ struct MemoryDffWorker
 | 
			
		|||
	MemoryDffWorker(Module *module) : module(module), sigmap(module)
 | 
			
		||||
	{
 | 
			
		||||
		for (auto wire : module->wires()) {
 | 
			
		||||
			if (wire->attributes.count("\\init") == 0)
 | 
			
		||||
			if (wire->attributes.count(ID::init) == 0)
 | 
			
		||||
				continue;
 | 
			
		||||
			SigSpec sig = sigmap(wire);
 | 
			
		||||
			Const initval = wire->attributes.at("\\init");
 | 
			
		||||
			Const initval = wire->attributes.at(ID::init);
 | 
			
		||||
			for (int i = 0; i < GetSize(sig) && i < GetSize(initval); i++)
 | 
			
		||||
				if (initval[i] == State::S0 || initval[i] == State::S1)
 | 
			
		||||
					init_bits.insert(sig[i]);
 | 
			
		||||
| 
						 | 
				
			
			@ -66,8 +66,8 @@ struct MemoryDffWorker
 | 
			
		|||
				if (after && forward_merged_dffs.count(cell))
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				SigSpec this_clk = cell->getPort("\\CLK");
 | 
			
		||||
				bool this_clk_polarity = cell->parameters["\\CLK_POLARITY"].as_bool();
 | 
			
		||||
				SigSpec this_clk = cell->getPort(ID::CLK);
 | 
			
		||||
				bool this_clk_polarity = cell->parameters[ID::CLK_POLARITY].as_bool();
 | 
			
		||||
 | 
			
		||||
				if (invbits.count(this_clk)) {
 | 
			
		||||
					this_clk = invbits.at(this_clk);
 | 
			
		||||
| 
						 | 
				
			
			@ -81,10 +81,10 @@ struct MemoryDffWorker
 | 
			
		|||
						continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				RTLIL::SigSpec q_norm = cell->getPort(after ? "\\D" : "\\Q");
 | 
			
		||||
				RTLIL::SigSpec q_norm = cell->getPort(after ? ID::D : ID::Q);
 | 
			
		||||
				sigmap.apply(q_norm);
 | 
			
		||||
 | 
			
		||||
				RTLIL::SigSpec d = q_norm.extract(bit, &cell->getPort(after ? "\\Q" : "\\D"));
 | 
			
		||||
				RTLIL::SigSpec d = q_norm.extract(bit, &cell->getPort(after ? ID::Q : ID::D));
 | 
			
		||||
				if (d.size() != 1)
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -113,19 +113,19 @@ struct MemoryDffWorker
 | 
			
		|||
		bool clk_polarity = 0;
 | 
			
		||||
		candidate_dffs.clear();
 | 
			
		||||
 | 
			
		||||
		RTLIL::SigSpec sig_addr = cell->getPort("\\ADDR");
 | 
			
		||||
		RTLIL::SigSpec sig_addr = cell->getPort(ID::ADDR);
 | 
			
		||||
		if (!find_sig_before_dff(sig_addr, clk, clk_polarity)) {
 | 
			
		||||
			log("no (compatible) $dff for address input found.\n");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		RTLIL::SigSpec sig_data = cell->getPort("\\DATA");
 | 
			
		||||
		RTLIL::SigSpec sig_data = cell->getPort(ID::DATA);
 | 
			
		||||
		if (!find_sig_before_dff(sig_data, clk, clk_polarity)) {
 | 
			
		||||
			log("no (compatible) $dff for data input found.\n");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		RTLIL::SigSpec sig_en = cell->getPort("\\EN");
 | 
			
		||||
		RTLIL::SigSpec sig_en = cell->getPort(ID::EN);
 | 
			
		||||
		if (!find_sig_before_dff(sig_en, clk, clk_polarity)) {
 | 
			
		||||
			log("no (compatible) $dff for enable input found.\n");
 | 
			
		||||
			return;
 | 
			
		||||
| 
						 | 
				
			
			@ -136,12 +136,12 @@ struct MemoryDffWorker
 | 
			
		|||
			for (auto cell : candidate_dffs)
 | 
			
		||||
				forward_merged_dffs.insert(cell);
 | 
			
		||||
 | 
			
		||||
			cell->setPort("\\CLK", clk);
 | 
			
		||||
			cell->setPort("\\ADDR", sig_addr);
 | 
			
		||||
			cell->setPort("\\DATA", sig_data);
 | 
			
		||||
			cell->setPort("\\EN", sig_en);
 | 
			
		||||
			cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
 | 
			
		||||
			cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
 | 
			
		||||
			cell->setPort(ID::CLK, clk);
 | 
			
		||||
			cell->setPort(ID::ADDR, sig_addr);
 | 
			
		||||
			cell->setPort(ID::DATA, sig_data);
 | 
			
		||||
			cell->setPort(ID::EN, sig_en);
 | 
			
		||||
			cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1);
 | 
			
		||||
			cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity);
 | 
			
		||||
 | 
			
		||||
			log("merged $dff to cell.\n");
 | 
			
		||||
			return;
 | 
			
		||||
| 
						 | 
				
			
			@ -161,10 +161,10 @@ struct MemoryDffWorker
 | 
			
		|||
		RTLIL::SigSpec new_sig = module->addWire(sstr.str(), sig.size());
 | 
			
		||||
 | 
			
		||||
		for (auto cell : module->cells())
 | 
			
		||||
			if (cell->type == "$dff") {
 | 
			
		||||
				RTLIL::SigSpec new_q = cell->getPort("\\Q");
 | 
			
		||||
			if (cell->type == ID($dff)) {
 | 
			
		||||
				RTLIL::SigSpec new_q = cell->getPort(ID::Q);
 | 
			
		||||
				new_q.replace(sig, new_sig);
 | 
			
		||||
				cell->setPort("\\Q", new_q);
 | 
			
		||||
				cell->setPort(ID::Q, new_q);
 | 
			
		||||
			}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -175,7 +175,7 @@ struct MemoryDffWorker
 | 
			
		|||
		bool clk_polarity = 0;
 | 
			
		||||
 | 
			
		||||
		RTLIL::SigSpec clk_data = RTLIL::SigSpec(RTLIL::State::Sx);
 | 
			
		||||
		RTLIL::SigSpec sig_data = cell->getPort("\\DATA");
 | 
			
		||||
		RTLIL::SigSpec sig_data = cell->getPort(ID::DATA);
 | 
			
		||||
 | 
			
		||||
		for (auto bit : sigmap(sig_data))
 | 
			
		||||
			if (sigbit_users_count[bit] > 1)
 | 
			
		||||
| 
						 | 
				
			
			@ -189,9 +189,9 @@ struct MemoryDffWorker
 | 
			
		|||
			do {
 | 
			
		||||
				bool enable_invert = mux_cells_a.count(sig_data) != 0;
 | 
			
		||||
				Cell *mux = enable_invert ? mux_cells_a.at(sig_data) : mux_cells_b.at(sig_data);
 | 
			
		||||
				check_q.push_back(sigmap(mux->getPort(enable_invert ? "\\B" : "\\A")));
 | 
			
		||||
				sig_data = sigmap(mux->getPort("\\Y"));
 | 
			
		||||
				en.append(enable_invert ? module->LogicNot(NEW_ID, mux->getPort("\\S")) : mux->getPort("\\S"));
 | 
			
		||||
				check_q.push_back(sigmap(mux->getPort(enable_invert ? ID::B : ID::A)));
 | 
			
		||||
				sig_data = sigmap(mux->getPort(ID::Y));
 | 
			
		||||
				en.append(enable_invert ? module->LogicNot(NEW_ID, mux->getPort(ID::S)) : mux->getPort(ID::S));
 | 
			
		||||
			} while (mux_cells_a.count(sig_data) || mux_cells_b.count(sig_data));
 | 
			
		||||
 | 
			
		||||
			for (auto bit : sig_data)
 | 
			
		||||
| 
						 | 
				
			
			@ -202,12 +202,12 @@ struct MemoryDffWorker
 | 
			
		|||
					std::all_of(check_q.begin(), check_q.end(), [&](const SigSpec &cq) {return cq == sig_data; }))
 | 
			
		||||
			{
 | 
			
		||||
				disconnect_dff(sig_data);
 | 
			
		||||
				cell->setPort("\\CLK", clk_data);
 | 
			
		||||
				cell->setPort("\\EN", en.size() > 1 ? module->ReduceAnd(NEW_ID, en) : en);
 | 
			
		||||
				cell->setPort("\\DATA", sig_data);
 | 
			
		||||
				cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
 | 
			
		||||
				cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
 | 
			
		||||
				cell->parameters["\\TRANSPARENT"] = RTLIL::Const(0);
 | 
			
		||||
				cell->setPort(ID::CLK, clk_data);
 | 
			
		||||
				cell->setPort(ID::EN, en.size() > 1 ? module->ReduceAnd(NEW_ID, en) : en);
 | 
			
		||||
				cell->setPort(ID::DATA, sig_data);
 | 
			
		||||
				cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1);
 | 
			
		||||
				cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity);
 | 
			
		||||
				cell->parameters[ID::TRANSPARENT] = RTLIL::Const(0);
 | 
			
		||||
				log("merged data $dff with rd enable to cell.\n");
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -217,12 +217,12 @@ struct MemoryDffWorker
 | 
			
		|||
			if (find_sig_before_dff(sig_data, clk_data, clk_polarity, true) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx))
 | 
			
		||||
			{
 | 
			
		||||
				disconnect_dff(sig_data);
 | 
			
		||||
				cell->setPort("\\CLK", clk_data);
 | 
			
		||||
				cell->setPort("\\EN", State::S1);
 | 
			
		||||
				cell->setPort("\\DATA", sig_data);
 | 
			
		||||
				cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
 | 
			
		||||
				cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
 | 
			
		||||
				cell->parameters["\\TRANSPARENT"] = RTLIL::Const(0);
 | 
			
		||||
				cell->setPort(ID::CLK, clk_data);
 | 
			
		||||
				cell->setPort(ID::EN, State::S1);
 | 
			
		||||
				cell->setPort(ID::DATA, sig_data);
 | 
			
		||||
				cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1);
 | 
			
		||||
				cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity);
 | 
			
		||||
				cell->parameters[ID::TRANSPARENT] = RTLIL::Const(0);
 | 
			
		||||
				log("merged data $dff to cell.\n");
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -230,16 +230,16 @@ struct MemoryDffWorker
 | 
			
		|||
 | 
			
		||||
	skip_ff_after_read_merging:;
 | 
			
		||||
		RTLIL::SigSpec clk_addr = RTLIL::SigSpec(RTLIL::State::Sx);
 | 
			
		||||
		RTLIL::SigSpec sig_addr = cell->getPort("\\ADDR");
 | 
			
		||||
		RTLIL::SigSpec sig_addr = cell->getPort(ID::ADDR);
 | 
			
		||||
		if (find_sig_before_dff(sig_addr, clk_addr, clk_polarity) &&
 | 
			
		||||
				clk_addr != RTLIL::SigSpec(RTLIL::State::Sx))
 | 
			
		||||
		{
 | 
			
		||||
			cell->setPort("\\CLK", clk_addr);
 | 
			
		||||
			cell->setPort("\\EN", State::S1);
 | 
			
		||||
			cell->setPort("\\ADDR", sig_addr);
 | 
			
		||||
			cell->parameters["\\CLK_ENABLE"] = RTLIL::Const(1);
 | 
			
		||||
			cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity);
 | 
			
		||||
			cell->parameters["\\TRANSPARENT"] = RTLIL::Const(1);
 | 
			
		||||
			cell->setPort(ID::CLK, clk_addr);
 | 
			
		||||
			cell->setPort(ID::EN, State::S1);
 | 
			
		||||
			cell->setPort(ID::ADDR, sig_addr);
 | 
			
		||||
			cell->parameters[ID::CLK_ENABLE] = RTLIL::Const(1);
 | 
			
		||||
			cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity);
 | 
			
		||||
			cell->parameters[ID::TRANSPARENT] = RTLIL::Const(1);
 | 
			
		||||
			log("merged address $dff to cell.\n");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -256,18 +256,18 @@ struct MemoryDffWorker
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		for (auto cell : module->cells()) {
 | 
			
		||||
			if (cell->type == "$dff")
 | 
			
		||||
			if (cell->type == ID($dff))
 | 
			
		||||
				dff_cells.push_back(cell);
 | 
			
		||||
			if (cell->type == "$mux") {
 | 
			
		||||
				mux_cells_a[sigmap(cell->getPort("\\A"))] = cell;
 | 
			
		||||
				mux_cells_b[sigmap(cell->getPort("\\B"))] = cell;
 | 
			
		||||
			if (cell->type == ID($mux)) {
 | 
			
		||||
				mux_cells_a[sigmap(cell->getPort(ID::A))] = cell;
 | 
			
		||||
				mux_cells_b[sigmap(cell->getPort(ID::B))] = cell;
 | 
			
		||||
			}
 | 
			
		||||
			if (cell->type.in("$not", "$_NOT_") || (cell->type == "$logic_not" && GetSize(cell->getPort("\\A")) == 1)) {
 | 
			
		||||
				SigSpec sig_a = cell->getPort("\\A");
 | 
			
		||||
				SigSpec sig_y = cell->getPort("\\Y");
 | 
			
		||||
				if (cell->type == "$not")
 | 
			
		||||
					sig_a.extend_u0(GetSize(sig_y), cell->getParam("\\A_SIGNED").as_bool());
 | 
			
		||||
				if (cell->type == "$logic_not")
 | 
			
		||||
			if (cell->type.in(ID($not), ID($_NOT_)) || (cell->type == ID($logic_not) && GetSize(cell->getPort(ID::A)) == 1)) {
 | 
			
		||||
				SigSpec sig_a = cell->getPort(ID::A);
 | 
			
		||||
				SigSpec sig_y = cell->getPort(ID::Y);
 | 
			
		||||
				if (cell->type == ID($not))
 | 
			
		||||
					sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool());
 | 
			
		||||
				if (cell->type == ID($logic_not))
 | 
			
		||||
					sig_y.extend_u0(1);
 | 
			
		||||
				for (int i = 0; i < GetSize(sig_y); i++)
 | 
			
		||||
					invbits[sig_y[i]] = sig_a[i];
 | 
			
		||||
| 
						 | 
				
			
			@ -279,12 +279,12 @@ struct MemoryDffWorker
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		for (auto cell : module->selected_cells())
 | 
			
		||||
			if (cell->type == "$memwr" && !cell->parameters["\\CLK_ENABLE"].as_bool())
 | 
			
		||||
			if (cell->type == ID($memwr) && !cell->parameters[ID::CLK_ENABLE].as_bool())
 | 
			
		||||
				handle_wr_cell(cell);
 | 
			
		||||
 | 
			
		||||
		if (!flag_wr_only)
 | 
			
		||||
			for (auto cell : module->selected_cells())
 | 
			
		||||
				if (cell->type == "$memrd" && !cell->parameters["\\CLK_ENABLE"].as_bool())
 | 
			
		||||
				if (cell->type == ID($memrd) && !cell->parameters[ID::CLK_ENABLE].as_bool())
 | 
			
		||||
					handle_rd_cell(cell);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,15 +81,15 @@ struct MemoryMapWorker
 | 
			
		|||
		std::set<int> static_ports;
 | 
			
		||||
		std::map<int, RTLIL::SigSpec> static_cells_map;
 | 
			
		||||
 | 
			
		||||
		int wr_ports = cell->parameters["\\WR_PORTS"].as_int();
 | 
			
		||||
		int rd_ports = cell->parameters["\\RD_PORTS"].as_int();
 | 
			
		||||
		int wr_ports = cell->parameters[ID::WR_PORTS].as_int();
 | 
			
		||||
		int rd_ports = cell->parameters[ID::RD_PORTS].as_int();
 | 
			
		||||
 | 
			
		||||
		int mem_size = cell->parameters["\\SIZE"].as_int();
 | 
			
		||||
		int mem_width = cell->parameters["\\WIDTH"].as_int();
 | 
			
		||||
		int mem_offset = cell->parameters["\\OFFSET"].as_int();
 | 
			
		||||
		int mem_abits = cell->parameters["\\ABITS"].as_int();
 | 
			
		||||
		int mem_size = cell->parameters[ID::SIZE].as_int();
 | 
			
		||||
		int mem_width = cell->parameters[ID::WIDTH].as_int();
 | 
			
		||||
		int mem_offset = cell->parameters[ID::OFFSET].as_int();
 | 
			
		||||
		int mem_abits = cell->parameters[ID::ABITS].as_int();
 | 
			
		||||
 | 
			
		||||
		SigSpec init_data = cell->getParam("\\INIT");
 | 
			
		||||
		SigSpec init_data = cell->getParam(ID::INIT);
 | 
			
		||||
		init_data.extend_u0(mem_size*mem_width, true);
 | 
			
		||||
 | 
			
		||||
		// delete unused memory cell
 | 
			
		||||
| 
						 | 
				
			
			@ -99,22 +99,22 @@ struct MemoryMapWorker
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		// all write ports must share the same clock
 | 
			
		||||
		RTLIL::SigSpec clocks = cell->getPort("\\WR_CLK");
 | 
			
		||||
		RTLIL::Const clocks_pol = cell->parameters["\\WR_CLK_POLARITY"];
 | 
			
		||||
		RTLIL::Const clocks_en = cell->parameters["\\WR_CLK_ENABLE"];
 | 
			
		||||
		RTLIL::SigSpec clocks = cell->getPort(ID::WR_CLK);
 | 
			
		||||
		RTLIL::Const clocks_pol = cell->parameters[ID::WR_CLK_POLARITY];
 | 
			
		||||
		RTLIL::Const clocks_en = cell->parameters[ID::WR_CLK_ENABLE];
 | 
			
		||||
		clocks_pol.bits.resize(wr_ports);
 | 
			
		||||
		clocks_en.bits.resize(wr_ports);
 | 
			
		||||
		RTLIL::SigSpec refclock;
 | 
			
		||||
		RTLIL::State refclock_pol = RTLIL::State::Sx;
 | 
			
		||||
		for (int i = 0; i < clocks.size(); i++) {
 | 
			
		||||
			RTLIL::SigSpec wr_en = cell->getPort("\\WR_EN").extract(i * mem_width, mem_width);
 | 
			
		||||
			RTLIL::SigSpec wr_en = cell->getPort(ID::WR_EN).extract(i * mem_width, mem_width);
 | 
			
		||||
			if (wr_en.is_fully_const() && !wr_en.as_bool()) {
 | 
			
		||||
				static_ports.insert(i);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
			if (clocks_en.bits[i] != RTLIL::State::S1) {
 | 
			
		||||
				RTLIL::SigSpec wr_addr = cell->getPort("\\WR_ADDR").extract(i*mem_abits, mem_abits);
 | 
			
		||||
				RTLIL::SigSpec wr_data = cell->getPort("\\WR_DATA").extract(i*mem_width, mem_width);
 | 
			
		||||
				RTLIL::SigSpec wr_addr = cell->getPort(ID::WR_ADDR).extract(i*mem_abits, mem_abits);
 | 
			
		||||
				RTLIL::SigSpec wr_data = cell->getPort(ID::WR_DATA).extract(i*mem_width, mem_width);
 | 
			
		||||
				if (wr_addr.is_fully_const()) {
 | 
			
		||||
					// FIXME: Actually we should check for wr_en.is_fully_const() also and
 | 
			
		||||
					// create a $adff cell with this ports wr_en input as reset pin when wr_en
 | 
			
		||||
| 
						 | 
				
			
			@ -155,21 +155,21 @@ struct MemoryMapWorker
 | 
			
		|||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				RTLIL::Cell *c = module->addCell(genid(cell->name, "", i), "$dff");
 | 
			
		||||
				c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"];
 | 
			
		||||
				RTLIL::Cell *c = module->addCell(genid(cell->name, "", i), ID($dff));
 | 
			
		||||
				c->parameters[ID::WIDTH] = cell->parameters[ID::WIDTH];
 | 
			
		||||
				if (clocks_pol.bits.size() > 0) {
 | 
			
		||||
					c->parameters["\\CLK_POLARITY"] = RTLIL::Const(clocks_pol.bits[0]);
 | 
			
		||||
					c->setPort("\\CLK", clocks.extract(0, 1));
 | 
			
		||||
					c->parameters[ID::CLK_POLARITY] = RTLIL::Const(clocks_pol.bits[0]);
 | 
			
		||||
					c->setPort(ID::CLK, clocks.extract(0, 1));
 | 
			
		||||
				} else {
 | 
			
		||||
					c->parameters["\\CLK_POLARITY"] = RTLIL::Const(RTLIL::State::S1);
 | 
			
		||||
					c->setPort("\\CLK", RTLIL::SigSpec(RTLIL::State::S0));
 | 
			
		||||
					c->parameters[ID::CLK_POLARITY] = RTLIL::Const(RTLIL::State::S1);
 | 
			
		||||
					c->setPort(ID::CLK, RTLIL::SigSpec(RTLIL::State::S0));
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				RTLIL::Wire *w_in = module->addWire(genid(cell->name, "", i, "$d"), mem_width);
 | 
			
		||||
				data_reg_in.push_back(RTLIL::SigSpec(w_in));
 | 
			
		||||
				c->setPort("\\D", data_reg_in.back());
 | 
			
		||||
				c->setPort(ID::D, data_reg_in.back());
 | 
			
		||||
 | 
			
		||||
				std::string w_out_name = stringf("%s[%d]", cell->parameters["\\MEMID"].decode_string().c_str(), i);
 | 
			
		||||
				std::string w_out_name = stringf("%s[%d]", cell->parameters[ID::MEMID].decode_string().c_str(), i);
 | 
			
		||||
				if (module->wires_.count(w_out_name) > 0)
 | 
			
		||||
					w_out_name = genid(cell->name, "", i, "$q");
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -177,10 +177,10 @@ struct MemoryMapWorker
 | 
			
		|||
				SigSpec w_init = init_data.extract(i*mem_width, mem_width);
 | 
			
		||||
 | 
			
		||||
				if (!w_init.is_fully_undef())
 | 
			
		||||
					w_out->attributes["\\init"] = w_init.as_const();
 | 
			
		||||
					w_out->attributes[ID::init] = w_init.as_const();
 | 
			
		||||
 | 
			
		||||
				data_reg_out.push_back(RTLIL::SigSpec(w_out));
 | 
			
		||||
				c->setPort("\\Q", data_reg_out.back());
 | 
			
		||||
				c->setPort(ID::Q, data_reg_out.back());
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -188,55 +188,55 @@ struct MemoryMapWorker
 | 
			
		|||
 | 
			
		||||
		int count_dff = 0, count_mux = 0, count_wrmux = 0;
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < cell->parameters["\\RD_PORTS"].as_int(); i++)
 | 
			
		||||
		for (int i = 0; i < cell->parameters[ID::RD_PORTS].as_int(); i++)
 | 
			
		||||
		{
 | 
			
		||||
			RTLIL::SigSpec rd_addr = cell->getPort("\\RD_ADDR").extract(i*mem_abits, mem_abits);
 | 
			
		||||
			RTLIL::SigSpec rd_addr = cell->getPort(ID::RD_ADDR).extract(i*mem_abits, mem_abits);
 | 
			
		||||
 | 
			
		||||
			if (mem_offset)
 | 
			
		||||
				rd_addr = module->Sub(NEW_ID, rd_addr, SigSpec(mem_offset, GetSize(rd_addr)));
 | 
			
		||||
 | 
			
		||||
			std::vector<RTLIL::SigSpec> rd_signals;
 | 
			
		||||
			rd_signals.push_back(cell->getPort("\\RD_DATA").extract(i*mem_width, mem_width));
 | 
			
		||||
			rd_signals.push_back(cell->getPort(ID::RD_DATA).extract(i*mem_width, mem_width));
 | 
			
		||||
 | 
			
		||||
			if (cell->parameters["\\RD_CLK_ENABLE"].bits[i] == RTLIL::State::S1)
 | 
			
		||||
			if (cell->parameters[ID::RD_CLK_ENABLE].bits[i] == RTLIL::State::S1)
 | 
			
		||||
			{
 | 
			
		||||
				RTLIL::Cell *dff_cell = nullptr;
 | 
			
		||||
 | 
			
		||||
				if (cell->parameters["\\RD_TRANSPARENT"].bits[i] == RTLIL::State::S1)
 | 
			
		||||
				if (cell->parameters[ID::RD_TRANSPARENT].bits[i] == RTLIL::State::S1)
 | 
			
		||||
				{
 | 
			
		||||
					dff_cell = module->addCell(genid(cell->name, "$rdreg", i), "$dff");
 | 
			
		||||
					dff_cell->parameters["\\WIDTH"] = RTLIL::Const(mem_abits);
 | 
			
		||||
					dff_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]);
 | 
			
		||||
					dff_cell->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1));
 | 
			
		||||
					dff_cell->setPort("\\D", rd_addr);
 | 
			
		||||
					dff_cell = module->addCell(genid(cell->name, "$rdreg", i), ID($dff));
 | 
			
		||||
					dff_cell->parameters[ID::WIDTH] = RTLIL::Const(mem_abits);
 | 
			
		||||
					dff_cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(cell->parameters[ID::RD_CLK_POLARITY].bits[i]);
 | 
			
		||||
					dff_cell->setPort(ID::CLK, cell->getPort(ID::RD_CLK).extract(i, 1));
 | 
			
		||||
					dff_cell->setPort(ID::D, rd_addr);
 | 
			
		||||
					count_dff++;
 | 
			
		||||
 | 
			
		||||
					RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$q"), mem_abits);
 | 
			
		||||
 | 
			
		||||
					dff_cell->setPort("\\Q", RTLIL::SigSpec(w));
 | 
			
		||||
					dff_cell->setPort(ID::Q, RTLIL::SigSpec(w));
 | 
			
		||||
					rd_addr = RTLIL::SigSpec(w);
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					dff_cell = module->addCell(genid(cell->name, "$rdreg", i), "$dff");
 | 
			
		||||
					dff_cell->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"];
 | 
			
		||||
					dff_cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(cell->parameters["\\RD_CLK_POLARITY"].bits[i]);
 | 
			
		||||
					dff_cell->setPort("\\CLK", cell->getPort("\\RD_CLK").extract(i, 1));
 | 
			
		||||
					dff_cell->setPort("\\Q", rd_signals.back());
 | 
			
		||||
					dff_cell = module->addCell(genid(cell->name, "$rdreg", i), ID($dff));
 | 
			
		||||
					dff_cell->parameters[ID::WIDTH] = cell->parameters[ID::WIDTH];
 | 
			
		||||
					dff_cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(cell->parameters[ID::RD_CLK_POLARITY].bits[i]);
 | 
			
		||||
					dff_cell->setPort(ID::CLK, cell->getPort(ID::RD_CLK).extract(i, 1));
 | 
			
		||||
					dff_cell->setPort(ID::Q, rd_signals.back());
 | 
			
		||||
					count_dff++;
 | 
			
		||||
 | 
			
		||||
					RTLIL::Wire *w = module->addWire(genid(cell->name, "$rdreg", i, "$d"), mem_width);
 | 
			
		||||
 | 
			
		||||
					rd_signals.clear();
 | 
			
		||||
					rd_signals.push_back(RTLIL::SigSpec(w));
 | 
			
		||||
					dff_cell->setPort("\\D", rd_signals.back());
 | 
			
		||||
					dff_cell->setPort(ID::D, rd_signals.back());
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				SigBit en_bit = cell->getPort("\\RD_EN").extract(i);
 | 
			
		||||
				SigBit en_bit = cell->getPort(ID::RD_EN).extract(i);
 | 
			
		||||
				if (en_bit != State::S1) {
 | 
			
		||||
					SigSpec new_d = module->Mux(genid(cell->name, "$rdenmux", i),
 | 
			
		||||
							dff_cell->getPort("\\Q"), dff_cell->getPort("\\D"), en_bit);
 | 
			
		||||
					dff_cell->setPort("\\D", new_d);
 | 
			
		||||
							dff_cell->getPort(ID::Q), dff_cell->getPort(ID::D), en_bit);
 | 
			
		||||
					dff_cell->setPort(ID::D, new_d);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -246,17 +246,17 @@ struct MemoryMapWorker
 | 
			
		|||
 | 
			
		||||
				for (size_t k = 0; k < rd_signals.size(); k++)
 | 
			
		||||
				{
 | 
			
		||||
					RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdmux", i, "", j, "", k), "$mux");
 | 
			
		||||
					c->parameters["\\WIDTH"] = cell->parameters["\\WIDTH"];
 | 
			
		||||
					c->setPort("\\Y", rd_signals[k]);
 | 
			
		||||
					c->setPort("\\S", rd_addr.extract(mem_abits-j-1, 1));
 | 
			
		||||
					RTLIL::Cell *c = module->addCell(genid(cell->name, "$rdmux", i, "", j, "", k), ID($mux));
 | 
			
		||||
					c->parameters[ID::WIDTH] = cell->parameters[ID::WIDTH];
 | 
			
		||||
					c->setPort(ID::Y, rd_signals[k]);
 | 
			
		||||
					c->setPort(ID::S, rd_addr.extract(mem_abits-j-1, 1));
 | 
			
		||||
					count_mux++;
 | 
			
		||||
 | 
			
		||||
					c->setPort("\\A", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$a"), mem_width));
 | 
			
		||||
					c->setPort("\\B", module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$b"), mem_width));
 | 
			
		||||
					c->setPort(ID::A, module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$a"), mem_width));
 | 
			
		||||
					c->setPort(ID::B, module->addWire(genid(cell->name, "$rdmux", i, "", j, "", k, "$b"), mem_width));
 | 
			
		||||
 | 
			
		||||
					next_rd_signals.push_back(c->getPort("\\A"));
 | 
			
		||||
					next_rd_signals.push_back(c->getPort("\\B"));
 | 
			
		||||
					next_rd_signals.push_back(c->getPort(ID::A));
 | 
			
		||||
					next_rd_signals.push_back(c->getPort(ID::B));
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				next_rd_signals.swap(rd_signals);
 | 
			
		||||
| 
						 | 
				
			
			@ -275,11 +275,11 @@ struct MemoryMapWorker
 | 
			
		|||
 | 
			
		||||
			RTLIL::SigSpec sig = data_reg_out[i];
 | 
			
		||||
 | 
			
		||||
			for (int j = 0; j < cell->parameters["\\WR_PORTS"].as_int(); j++)
 | 
			
		||||
			for (int j = 0; j < cell->parameters[ID::WR_PORTS].as_int(); j++)
 | 
			
		||||
			{
 | 
			
		||||
				RTLIL::SigSpec wr_addr = cell->getPort("\\WR_ADDR").extract(j*mem_abits, mem_abits);
 | 
			
		||||
				RTLIL::SigSpec wr_data = cell->getPort("\\WR_DATA").extract(j*mem_width, mem_width);
 | 
			
		||||
				RTLIL::SigSpec wr_en = cell->getPort("\\WR_EN").extract(j*mem_width, mem_width);
 | 
			
		||||
				RTLIL::SigSpec wr_addr = cell->getPort(ID::WR_ADDR).extract(j*mem_abits, mem_abits);
 | 
			
		||||
				RTLIL::SigSpec wr_data = cell->getPort(ID::WR_DATA).extract(j*mem_width, mem_width);
 | 
			
		||||
				RTLIL::SigSpec wr_en = cell->getPort(ID::WR_EN).extract(j*mem_width, mem_width);
 | 
			
		||||
 | 
			
		||||
				if (mem_offset)
 | 
			
		||||
					wr_addr = module->Sub(NEW_ID, wr_addr, SigSpec(mem_offset, GetSize(wr_addr)));
 | 
			
		||||
| 
						 | 
				
			
			@ -303,27 +303,27 @@ struct MemoryMapWorker
 | 
			
		|||
 | 
			
		||||
					if (wr_bit != State::S1)
 | 
			
		||||
					{
 | 
			
		||||
						RTLIL::Cell *c = module->addCell(genid(cell->name, "$wren", i, "", j, "", wr_offset), "$and");
 | 
			
		||||
						c->parameters["\\A_SIGNED"] = RTLIL::Const(0);
 | 
			
		||||
						c->parameters["\\B_SIGNED"] = RTLIL::Const(0);
 | 
			
		||||
						c->parameters["\\A_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
						c->parameters["\\B_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
						c->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
						c->setPort("\\A", w);
 | 
			
		||||
						c->setPort("\\B", wr_bit);
 | 
			
		||||
						RTLIL::Cell *c = module->addCell(genid(cell->name, "$wren", i, "", j, "", wr_offset), ID($and));
 | 
			
		||||
						c->parameters[ID::A_SIGNED] = RTLIL::Const(0);
 | 
			
		||||
						c->parameters[ID::B_SIGNED] = RTLIL::Const(0);
 | 
			
		||||
						c->parameters[ID::A_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
						c->parameters[ID::B_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
						c->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
						c->setPort(ID::A, w);
 | 
			
		||||
						c->setPort(ID::B, wr_bit);
 | 
			
		||||
 | 
			
		||||
						w = module->addWire(genid(cell->name, "$wren", i, "", j, "", wr_offset, "$y"));
 | 
			
		||||
						c->setPort("\\Y", RTLIL::SigSpec(w));
 | 
			
		||||
						c->setPort(ID::Y, RTLIL::SigSpec(w));
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					RTLIL::Cell *c = module->addCell(genid(cell->name, "$wrmux", i, "", j, "", wr_offset), "$mux");
 | 
			
		||||
					c->parameters["\\WIDTH"] = wr_width;
 | 
			
		||||
					c->setPort("\\A", sig.extract(wr_offset, wr_width));
 | 
			
		||||
					c->setPort("\\B", wr_data.extract(wr_offset, wr_width));
 | 
			
		||||
					c->setPort("\\S", RTLIL::SigSpec(w));
 | 
			
		||||
					RTLIL::Cell *c = module->addCell(genid(cell->name, "$wrmux", i, "", j, "", wr_offset), ID($mux));
 | 
			
		||||
					c->parameters[ID::WIDTH] = wr_width;
 | 
			
		||||
					c->setPort(ID::A, sig.extract(wr_offset, wr_width));
 | 
			
		||||
					c->setPort(ID::B, wr_data.extract(wr_offset, wr_width));
 | 
			
		||||
					c->setPort(ID::S, RTLIL::SigSpec(w));
 | 
			
		||||
 | 
			
		||||
					w = module->addWire(genid(cell->name, "$wrmux", i, "", j, "", wr_offset, "$y"), wr_width);
 | 
			
		||||
					c->setPort("\\Y", w);
 | 
			
		||||
					c->setPort(ID::Y, w);
 | 
			
		||||
 | 
			
		||||
					sig.replace(wr_offset, w);
 | 
			
		||||
					wr_offset += wr_width;
 | 
			
		||||
| 
						 | 
				
			
			@ -343,7 +343,7 @@ struct MemoryMapWorker
 | 
			
		|||
	{
 | 
			
		||||
		std::vector<RTLIL::Cell*> cells;
 | 
			
		||||
		for (auto cell : module->selected_cells())
 | 
			
		||||
			if (cell->type == "$mem" && design->selected(module, cell))
 | 
			
		||||
			if (cell->type == ID($mem))
 | 
			
		||||
				cells.push_back(cell);
 | 
			
		||||
		for (auto cell : cells)
 | 
			
		||||
			handle_cell(cell);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,18 +47,18 @@ struct MemoryMemxPass : public Pass {
 | 
			
		|||
			vector<Cell*> mem_port_cells;
 | 
			
		||||
 | 
			
		||||
			for (auto cell : module->selected_cells())
 | 
			
		||||
				if (cell->type.in("$memrd", "$memwr"))
 | 
			
		||||
				if (cell->type.in(ID($memrd), ID($memwr)))
 | 
			
		||||
					mem_port_cells.push_back(cell);
 | 
			
		||||
 | 
			
		||||
			for (auto cell : mem_port_cells)
 | 
			
		||||
			{
 | 
			
		||||
				IdString memid = cell->getParam("\\MEMID").decode_string();
 | 
			
		||||
				IdString memid = cell->getParam(ID::MEMID).decode_string();
 | 
			
		||||
				RTLIL::Memory *mem = module->memories.at(memid);
 | 
			
		||||
 | 
			
		||||
				int lowest_addr = mem->start_offset;
 | 
			
		||||
				int highest_addr = mem->start_offset + mem->size - 1;
 | 
			
		||||
 | 
			
		||||
				SigSpec addr = cell->getPort("\\ADDR");
 | 
			
		||||
				SigSpec addr = cell->getPort(ID::ADDR);
 | 
			
		||||
				addr.extend_u0(32);
 | 
			
		||||
 | 
			
		||||
				SigSpec addr_ok = module->Nex(NEW_ID, module->ReduceXor(NEW_ID, addr), module->ReduceXor(NEW_ID, {addr, State::S1}));
 | 
			
		||||
| 
						 | 
				
			
			@ -66,23 +66,23 @@ struct MemoryMemxPass : public Pass {
 | 
			
		|||
					addr_ok = module->LogicAnd(NEW_ID, addr_ok, module->Ge(NEW_ID, addr, lowest_addr));
 | 
			
		||||
				addr_ok = module->LogicAnd(NEW_ID, addr_ok, module->Le(NEW_ID, addr, highest_addr));
 | 
			
		||||
 | 
			
		||||
				if (cell->type == "$memrd")
 | 
			
		||||
				if (cell->type == ID($memrd))
 | 
			
		||||
				{
 | 
			
		||||
					if (cell->getParam("\\CLK_ENABLE").as_bool())
 | 
			
		||||
					if (cell->getParam(ID::CLK_ENABLE).as_bool())
 | 
			
		||||
						log_error("Cell %s.%s (%s) has an enabled clock. Clocked $memrd cells are not supported by memory_memx!\n",
 | 
			
		||||
								log_id(module), log_id(cell), log_id(cell->type));
 | 
			
		||||
 | 
			
		||||
					SigSpec rdata = cell->getPort("\\DATA");
 | 
			
		||||
					SigSpec rdata = cell->getPort(ID::DATA);
 | 
			
		||||
					Wire *raw_rdata = module->addWire(NEW_ID, GetSize(rdata));
 | 
			
		||||
					module->addMux(NEW_ID, SigSpec(State::Sx, GetSize(rdata)), raw_rdata, addr_ok, rdata);
 | 
			
		||||
					cell->setPort("\\DATA", raw_rdata);
 | 
			
		||||
					cell->setPort(ID::DATA, raw_rdata);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (cell->type == "$memwr")
 | 
			
		||||
				if (cell->type == ID($memwr))
 | 
			
		||||
				{
 | 
			
		||||
					SigSpec en = cell->getPort("\\EN");
 | 
			
		||||
					SigSpec en = cell->getPort(ID::EN);
 | 
			
		||||
					en = module->And(NEW_ID, en, addr_ok.repeat(GetSize(en)));
 | 
			
		||||
					cell->setPort("\\EN", en);
 | 
			
		||||
					cell->setPort(ID::EN, en);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,19 +52,19 @@ struct MemoryNordffPass : public Pass {
 | 
			
		|||
		for (auto module : design->selected_modules())
 | 
			
		||||
		for (auto cell : vector<Cell*>(module->selected_cells()))
 | 
			
		||||
		{
 | 
			
		||||
			if (cell->type != "$mem")
 | 
			
		||||
			if (cell->type != ID($mem))
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			int rd_ports = cell->getParam("\\RD_PORTS").as_int();
 | 
			
		||||
			int abits = cell->getParam("\\ABITS").as_int();
 | 
			
		||||
			int width = cell->getParam("\\WIDTH").as_int();
 | 
			
		||||
			int rd_ports = cell->getParam(ID::RD_PORTS).as_int();
 | 
			
		||||
			int abits = cell->getParam(ID::ABITS).as_int();
 | 
			
		||||
			int width = cell->getParam(ID::WIDTH).as_int();
 | 
			
		||||
 | 
			
		||||
			SigSpec rd_addr = cell->getPort("\\RD_ADDR");
 | 
			
		||||
			SigSpec rd_data = cell->getPort("\\RD_DATA");
 | 
			
		||||
			SigSpec rd_clk = cell->getPort("\\RD_CLK");
 | 
			
		||||
			SigSpec rd_en = cell->getPort("\\RD_EN");
 | 
			
		||||
			Const rd_clk_enable = cell->getParam("\\RD_CLK_ENABLE");
 | 
			
		||||
			Const rd_clk_polarity = cell->getParam("\\RD_CLK_POLARITY");
 | 
			
		||||
			SigSpec rd_addr = cell->getPort(ID::RD_ADDR);
 | 
			
		||||
			SigSpec rd_data = cell->getPort(ID::RD_DATA);
 | 
			
		||||
			SigSpec rd_clk = cell->getPort(ID::RD_CLK);
 | 
			
		||||
			SigSpec rd_en = cell->getPort(ID::RD_EN);
 | 
			
		||||
			Const rd_clk_enable = cell->getParam(ID::RD_CLK_ENABLE);
 | 
			
		||||
			Const rd_clk_polarity = cell->getParam(ID::RD_CLK_POLARITY);
 | 
			
		||||
 | 
			
		||||
			for (int i = 0; i < rd_ports; i++)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -72,11 +72,11 @@ struct MemoryNordffPass : public Pass {
 | 
			
		|||
 | 
			
		||||
				if (clk_enable)
 | 
			
		||||
				{
 | 
			
		||||
					bool clk_polarity = cell->getParam("\\RD_CLK_POLARITY")[i] == State::S1;
 | 
			
		||||
					bool transparent = cell->getParam("\\RD_TRANSPARENT")[i] == State::S1;
 | 
			
		||||
					bool clk_polarity = cell->getParam(ID::RD_CLK_POLARITY)[i] == State::S1;
 | 
			
		||||
					bool transparent = cell->getParam(ID::RD_TRANSPARENT)[i] == State::S1;
 | 
			
		||||
 | 
			
		||||
					SigSpec clk = cell->getPort("\\RD_CLK")[i] ;
 | 
			
		||||
					SigSpec en = cell->getPort("\\RD_EN")[i];
 | 
			
		||||
					SigSpec clk = cell->getPort(ID::RD_CLK)[i] ;
 | 
			
		||||
					SigSpec en = cell->getPort(ID::RD_EN)[i];
 | 
			
		||||
					Cell *c;
 | 
			
		||||
 | 
			
		||||
					if (transparent)
 | 
			
		||||
| 
						 | 
				
			
			@ -108,12 +108,12 @@ struct MemoryNordffPass : public Pass {
 | 
			
		|||
				rd_clk_polarity[i] = State::S1;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			cell->setPort("\\RD_ADDR", rd_addr);
 | 
			
		||||
			cell->setPort("\\RD_DATA", rd_data);
 | 
			
		||||
			cell->setPort("\\RD_CLK", rd_clk);
 | 
			
		||||
			cell->setPort("\\RD_EN", rd_en);
 | 
			
		||||
			cell->setParam("\\RD_CLK_ENABLE", rd_clk_enable);
 | 
			
		||||
			cell->setParam("\\RD_CLK_POLARITY", rd_clk_polarity);
 | 
			
		||||
			cell->setPort(ID::RD_ADDR, rd_addr);
 | 
			
		||||
			cell->setPort(ID::RD_DATA, rd_data);
 | 
			
		||||
			cell->setPort(ID::RD_CLK, rd_clk);
 | 
			
		||||
			cell->setPort(ID::RD_EN, rd_en);
 | 
			
		||||
			cell->setParam(ID::RD_CLK_ENABLE, rd_clk_enable);
 | 
			
		||||
			cell->setParam(ID::RD_CLK_POLARITY, rd_clk_polarity);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
} MemoryNordffPass;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,11 +27,11 @@ PRIVATE_NAMESPACE_BEGIN
 | 
			
		|||
 | 
			
		||||
bool memcells_cmp(RTLIL::Cell *a, RTLIL::Cell *b)
 | 
			
		||||
{
 | 
			
		||||
	if (a->type == "$memrd" && b->type == "$memrd")
 | 
			
		||||
	if (a->type == ID($memrd) && b->type == ID($memrd))
 | 
			
		||||
		return a->name < b->name;
 | 
			
		||||
	if (a->type == "$memrd" || b->type == "$memrd")
 | 
			
		||||
		return (a->type == "$memrd") < (b->type == "$memrd");
 | 
			
		||||
	return a->parameters.at("\\PRIORITY").as_int() < b->parameters.at("\\PRIORITY").as_int();
 | 
			
		||||
	if (a->type == ID($memrd) || b->type == ID($memrd))
 | 
			
		||||
		return (a->type == ID($memrd)) < (b->type == ID($memrd));
 | 
			
		||||
	return a->parameters.at(ID::PRIORITY).as_int() < b->parameters.at(ID::PRIORITY).as_int();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct MemoryShareWorker
 | 
			
		||||
| 
						 | 
				
			
			@ -64,18 +64,18 @@ struct MemoryShareWorker
 | 
			
		|||
		RTLIL::Cell *cell = sig_to_mux.at(sig).first;
 | 
			
		||||
		int bit_idx = sig_to_mux.at(sig).second;
 | 
			
		||||
 | 
			
		||||
		std::vector<RTLIL::SigBit> sig_a = sigmap(cell->getPort("\\A"));
 | 
			
		||||
		std::vector<RTLIL::SigBit> sig_b = sigmap(cell->getPort("\\B"));
 | 
			
		||||
		std::vector<RTLIL::SigBit> sig_s = sigmap(cell->getPort("\\S"));
 | 
			
		||||
		std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort("\\Y"));
 | 
			
		||||
		std::vector<RTLIL::SigBit> sig_a = sigmap(cell->getPort(ID::A));
 | 
			
		||||
		std::vector<RTLIL::SigBit> sig_b = sigmap(cell->getPort(ID::B));
 | 
			
		||||
		std::vector<RTLIL::SigBit> sig_s = sigmap(cell->getPort(ID::S));
 | 
			
		||||
		std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort(ID::Y));
 | 
			
		||||
		log_assert(sig_y.at(bit_idx) == sig);
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < int(sig_s.size()); i++)
 | 
			
		||||
			if (state.count(sig_s[i]) && state.at(sig_s[i]) == true) {
 | 
			
		||||
				if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), state, conditions)) {
 | 
			
		||||
					RTLIL::SigSpec new_b = cell->getPort("\\B");
 | 
			
		||||
					RTLIL::SigSpec new_b = cell->getPort(ID::B);
 | 
			
		||||
					new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx);
 | 
			
		||||
					cell->setPort("\\B", new_b);
 | 
			
		||||
					cell->setPort(ID::B, new_b);
 | 
			
		||||
				}
 | 
			
		||||
				return false;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -90,9 +90,9 @@ struct MemoryShareWorker
 | 
			
		|||
			new_state[sig_s[i]] = true;
 | 
			
		||||
 | 
			
		||||
			if (find_data_feedback(async_rd_bits, sig_b.at(bit_idx + i*sig_y.size()), new_state, conditions)) {
 | 
			
		||||
				RTLIL::SigSpec new_b = cell->getPort("\\B");
 | 
			
		||||
				RTLIL::SigSpec new_b = cell->getPort(ID::B);
 | 
			
		||||
				new_b.replace(bit_idx + i*sig_y.size(), RTLIL::State::Sx);
 | 
			
		||||
				cell->setPort("\\B", new_b);
 | 
			
		||||
				cell->setPort(ID::B, new_b);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -101,9 +101,9 @@ struct MemoryShareWorker
 | 
			
		|||
			new_state[sig_s[i]] = false;
 | 
			
		||||
 | 
			
		||||
		if (find_data_feedback(async_rd_bits, sig_a.at(bit_idx), new_state, conditions)) {
 | 
			
		||||
			RTLIL::SigSpec new_a = cell->getPort("\\A");
 | 
			
		||||
			RTLIL::SigSpec new_a = cell->getPort(ID::A);
 | 
			
		||||
			new_a.replace(bit_idx, RTLIL::State::Sx);
 | 
			
		||||
			cell->setPort("\\A", new_a);
 | 
			
		||||
			cell->setPort(ID::A, new_a);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -155,12 +155,12 @@ struct MemoryShareWorker
 | 
			
		|||
		{
 | 
			
		||||
			bool ignore_data_port = false;
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in("$mux", "$pmux"))
 | 
			
		||||
			if (cell->type.in(ID($mux), ID($pmux)))
 | 
			
		||||
			{
 | 
			
		||||
				std::vector<RTLIL::SigBit> sig_a = sigmap(cell->getPort("\\A"));
 | 
			
		||||
				std::vector<RTLIL::SigBit> sig_b = sigmap(cell->getPort("\\B"));
 | 
			
		||||
				std::vector<RTLIL::SigBit> sig_s = sigmap(cell->getPort("\\S"));
 | 
			
		||||
				std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort("\\Y"));
 | 
			
		||||
				std::vector<RTLIL::SigBit> sig_a = sigmap(cell->getPort(ID::A));
 | 
			
		||||
				std::vector<RTLIL::SigBit> sig_b = sigmap(cell->getPort(ID::B));
 | 
			
		||||
				std::vector<RTLIL::SigBit> sig_s = sigmap(cell->getPort(ID::S));
 | 
			
		||||
				std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort(ID::Y));
 | 
			
		||||
 | 
			
		||||
				non_feedback_nets.insert(sig_s.begin(), sig_s.end());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -173,13 +173,13 @@ struct MemoryShareWorker
 | 
			
		|||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in("$memwr", "$memrd") &&
 | 
			
		||||
					cell->parameters.at("\\MEMID").decode_string() == memid)
 | 
			
		||||
			if (cell->type.in(ID($memwr), ID($memrd)) &&
 | 
			
		||||
					cell->parameters.at(ID::MEMID).decode_string() == memid)
 | 
			
		||||
				ignore_data_port = true;
 | 
			
		||||
 | 
			
		||||
			for (auto conn : cell->connections())
 | 
			
		||||
			{
 | 
			
		||||
				if (ignore_data_port && conn.first == "\\DATA")
 | 
			
		||||
				if (ignore_data_port && conn.first == ID::DATA)
 | 
			
		||||
					continue;
 | 
			
		||||
				std::vector<RTLIL::SigBit> bits = sigmap(conn.second);
 | 
			
		||||
				non_feedback_nets.insert(bits.begin(), bits.end());
 | 
			
		||||
| 
						 | 
				
			
			@ -204,11 +204,11 @@ struct MemoryShareWorker
 | 
			
		|||
 | 
			
		||||
		for (auto cell : rd_ports)
 | 
			
		||||
		{
 | 
			
		||||
			if (cell->parameters.at("\\CLK_ENABLE").as_bool())
 | 
			
		||||
			if (cell->parameters.at(ID::CLK_ENABLE).as_bool())
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			RTLIL::SigSpec sig_addr = sigmap(cell->getPort("\\ADDR"));
 | 
			
		||||
			std::vector<RTLIL::SigBit> sig_data = sigmap(cell->getPort("\\DATA"));
 | 
			
		||||
			RTLIL::SigSpec sig_addr = sigmap(cell->getPort(ID::ADDR));
 | 
			
		||||
			std::vector<RTLIL::SigBit> sig_data = sigmap(cell->getPort(ID::DATA));
 | 
			
		||||
 | 
			
		||||
			for (int i = 0; i < int(sig_data.size()); i++)
 | 
			
		||||
				if (non_feedback_nets.count(sig_data[i]))
 | 
			
		||||
| 
						 | 
				
			
			@ -228,14 +228,14 @@ struct MemoryShareWorker
 | 
			
		|||
 | 
			
		||||
		for (auto cell : wr_ports)
 | 
			
		||||
		{
 | 
			
		||||
			RTLIL::SigSpec sig_addr = sigmap_xmux(cell->getPort("\\ADDR"));
 | 
			
		||||
			RTLIL::SigSpec sig_addr = sigmap_xmux(cell->getPort(ID::ADDR));
 | 
			
		||||
			if (!async_rd_bits.count(sig_addr))
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			log("  Analyzing write port %s.\n", log_id(cell));
 | 
			
		||||
 | 
			
		||||
			std::vector<RTLIL::SigBit> cell_data = cell->getPort("\\DATA");
 | 
			
		||||
			std::vector<RTLIL::SigBit> cell_en = cell->getPort("\\EN");
 | 
			
		||||
			std::vector<RTLIL::SigBit> cell_data = cell->getPort(ID::DATA);
 | 
			
		||||
			std::vector<RTLIL::SigBit> cell_en = cell->getPort(ID::EN);
 | 
			
		||||
 | 
			
		||||
			int created_conditions = 0;
 | 
			
		||||
			for (int i = 0; i < int(cell_data.size()); i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -250,7 +250,7 @@ struct MemoryShareWorker
 | 
			
		|||
 | 
			
		||||
			if (created_conditions) {
 | 
			
		||||
				log("    Added enable logic for %d different cases.\n", created_conditions);
 | 
			
		||||
				cell->setPort("\\EN", cell_en);
 | 
			
		||||
				cell->setPort(ID::EN, cell_en);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -368,15 +368,15 @@ struct MemoryShareWorker
 | 
			
		|||
		for (int i = 0; i < int(wr_ports.size()); i++)
 | 
			
		||||
		{
 | 
			
		||||
			RTLIL::Cell *cell = wr_ports.at(i);
 | 
			
		||||
			RTLIL::SigSpec addr = sigmap_xmux(cell->getPort("\\ADDR"));
 | 
			
		||||
			RTLIL::SigSpec addr = sigmap_xmux(cell->getPort(ID::ADDR));
 | 
			
		||||
 | 
			
		||||
			if (cell->parameters.at("\\CLK_ENABLE").as_bool() != cache_clk_enable ||
 | 
			
		||||
					(cache_clk_enable && (sigmap(cell->getPort("\\CLK")) != cache_clk ||
 | 
			
		||||
					cell->parameters.at("\\CLK_POLARITY").as_bool() != cache_clk_polarity)))
 | 
			
		||||
			if (cell->parameters.at(ID::CLK_ENABLE).as_bool() != cache_clk_enable ||
 | 
			
		||||
					(cache_clk_enable && (sigmap(cell->getPort(ID::CLK)) != cache_clk ||
 | 
			
		||||
					cell->parameters.at(ID::CLK_POLARITY).as_bool() != cache_clk_polarity)))
 | 
			
		||||
			{
 | 
			
		||||
				cache_clk_enable = cell->parameters.at("\\CLK_ENABLE").as_bool();
 | 
			
		||||
				cache_clk_polarity = cell->parameters.at("\\CLK_POLARITY").as_bool();
 | 
			
		||||
				cache_clk = sigmap(cell->getPort("\\CLK"));
 | 
			
		||||
				cache_clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool();
 | 
			
		||||
				cache_clk_polarity = cell->parameters.at(ID::CLK_POLARITY).as_bool();
 | 
			
		||||
				cache_clk = sigmap(cell->getPort(ID::CLK));
 | 
			
		||||
				last_port_by_addr.clear();
 | 
			
		||||
 | 
			
		||||
				if (cache_clk_enable)
 | 
			
		||||
| 
						 | 
				
			
			@ -388,7 +388,7 @@ struct MemoryShareWorker
 | 
			
		|||
			log("    Port %d (%s) has addr %s.\n", i, log_id(cell), log_signal(addr));
 | 
			
		||||
 | 
			
		||||
			log("      Active bits: ");
 | 
			
		||||
			std::vector<RTLIL::SigBit> en_bits = sigmap(cell->getPort("\\EN"));
 | 
			
		||||
			std::vector<RTLIL::SigBit> en_bits = sigmap(cell->getPort(ID::EN));
 | 
			
		||||
			active_bits_on_port.push_back(std::vector<bool>(en_bits.size()));
 | 
			
		||||
			for (int k = int(en_bits.size())-1; k >= 0; k--) {
 | 
			
		||||
				active_bits_on_port[i][k] = en_bits[k].wire != NULL || en_bits[k].data != RTLIL::State::S0;
 | 
			
		||||
| 
						 | 
				
			
			@ -410,13 +410,13 @@ struct MemoryShareWorker
 | 
			
		|||
 | 
			
		||||
				// Force this ports addr input to addr directly (skip don't care muxes)
 | 
			
		||||
 | 
			
		||||
				cell->setPort("\\ADDR", addr);
 | 
			
		||||
				cell->setPort(ID::ADDR, addr);
 | 
			
		||||
 | 
			
		||||
				// If any of the ports between `last_i' and `i' write to the same address, this
 | 
			
		||||
				// will have priority over whatever `last_i` wrote. So we need to revisit those
 | 
			
		||||
				// ports and mask the EN bits accordingly.
 | 
			
		||||
 | 
			
		||||
				RTLIL::SigSpec merged_en = sigmap(wr_ports[last_i]->getPort("\\EN"));
 | 
			
		||||
				RTLIL::SigSpec merged_en = sigmap(wr_ports[last_i]->getPort(ID::EN));
 | 
			
		||||
 | 
			
		||||
				for (int j = last_i+1; j < i; j++)
 | 
			
		||||
				{
 | 
			
		||||
| 
						 | 
				
			
			@ -431,20 +431,20 @@ struct MemoryShareWorker
 | 
			
		|||
				found_overlapping_bits_i_j:
 | 
			
		||||
						log("      Creating collosion-detect logic for port %d.\n", j);
 | 
			
		||||
						RTLIL::SigSpec is_same_addr = module->addWire(NEW_ID);
 | 
			
		||||
						module->addEq(NEW_ID, addr, wr_ports[j]->getPort("\\ADDR"), is_same_addr);
 | 
			
		||||
						merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->getPort("\\EN")));
 | 
			
		||||
						module->addEq(NEW_ID, addr, wr_ports[j]->getPort(ID::ADDR), is_same_addr);
 | 
			
		||||
						merged_en = mask_en_grouped(is_same_addr, merged_en, sigmap(wr_ports[j]->getPort(ID::EN)));
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Then we need to merge the (masked) EN and the DATA signals.
 | 
			
		||||
 | 
			
		||||
				RTLIL::SigSpec merged_data = wr_ports[last_i]->getPort("\\DATA");
 | 
			
		||||
				RTLIL::SigSpec merged_data = wr_ports[last_i]->getPort(ID::DATA);
 | 
			
		||||
				if (found_overlapping_bits) {
 | 
			
		||||
					log("      Creating logic for merging DATA and EN ports.\n");
 | 
			
		||||
					merge_en_data(merged_en, merged_data, sigmap(cell->getPort("\\EN")), sigmap(cell->getPort("\\DATA")));
 | 
			
		||||
					merge_en_data(merged_en, merged_data, sigmap(cell->getPort(ID::EN)), sigmap(cell->getPort(ID::DATA)));
 | 
			
		||||
				} else {
 | 
			
		||||
					RTLIL::SigSpec cell_en = sigmap(cell->getPort("\\EN"));
 | 
			
		||||
					RTLIL::SigSpec cell_data = sigmap(cell->getPort("\\DATA"));
 | 
			
		||||
					RTLIL::SigSpec cell_en = sigmap(cell->getPort(ID::EN));
 | 
			
		||||
					RTLIL::SigSpec cell_data = sigmap(cell->getPort(ID::DATA));
 | 
			
		||||
					for (int k = 0; k < int(en_bits.size()); k++)
 | 
			
		||||
						if (!active_bits_on_port[last_i][k]) {
 | 
			
		||||
							merged_en.replace(k, cell_en.extract(k, 1));
 | 
			
		||||
| 
						 | 
				
			
			@ -454,14 +454,14 @@ struct MemoryShareWorker
 | 
			
		|||
 | 
			
		||||
				// Connect the new EN and DATA signals and remove the old write port.
 | 
			
		||||
 | 
			
		||||
				cell->setPort("\\EN", merged_en);
 | 
			
		||||
				cell->setPort("\\DATA", merged_data);
 | 
			
		||||
				cell->setPort(ID::EN, merged_en);
 | 
			
		||||
				cell->setPort(ID::DATA, merged_data);
 | 
			
		||||
 | 
			
		||||
				module->remove(wr_ports[last_i]);
 | 
			
		||||
				wr_ports[last_i] = NULL;
 | 
			
		||||
 | 
			
		||||
				log("      Active bits: ");
 | 
			
		||||
				std::vector<RTLIL::SigBit> en_bits = sigmap(cell->getPort("\\EN"));
 | 
			
		||||
				std::vector<RTLIL::SigBit> en_bits = sigmap(cell->getPort(ID::EN));
 | 
			
		||||
				active_bits_on_port.push_back(std::vector<bool>(en_bits.size()));
 | 
			
		||||
				for (int k = int(en_bits.size())-1; k >= 0; k--)
 | 
			
		||||
					log("%c", active_bits_on_port[i][k] ? '1' : '0');
 | 
			
		||||
| 
						 | 
				
			
			@ -500,7 +500,7 @@ struct MemoryShareWorker
 | 
			
		|||
		std::set<int> considered_port_pairs;
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < int(wr_ports.size()); i++) {
 | 
			
		||||
			std::vector<RTLIL::SigBit> bits = modwalker.sigmap(wr_ports[i]->getPort("\\EN"));
 | 
			
		||||
			std::vector<RTLIL::SigBit> bits = modwalker.sigmap(wr_ports[i]->getPort(ID::EN));
 | 
			
		||||
			for (auto bit : bits)
 | 
			
		||||
				if (bit == RTLIL::State::S1)
 | 
			
		||||
					goto port_is_always_active;
 | 
			
		||||
| 
						 | 
				
			
			@ -519,13 +519,13 @@ struct MemoryShareWorker
 | 
			
		|||
		{
 | 
			
		||||
			RTLIL::Cell *cell = wr_ports.at(i);
 | 
			
		||||
 | 
			
		||||
			if (cell->parameters.at("\\CLK_ENABLE").as_bool() != cache_clk_enable ||
 | 
			
		||||
					(cache_clk_enable && (sigmap(cell->getPort("\\CLK")) != cache_clk ||
 | 
			
		||||
					cell->parameters.at("\\CLK_POLARITY").as_bool() != cache_clk_polarity)))
 | 
			
		||||
			if (cell->parameters.at(ID::CLK_ENABLE).as_bool() != cache_clk_enable ||
 | 
			
		||||
					(cache_clk_enable && (sigmap(cell->getPort(ID::CLK)) != cache_clk ||
 | 
			
		||||
					cell->parameters.at(ID::CLK_POLARITY).as_bool() != cache_clk_polarity)))
 | 
			
		||||
			{
 | 
			
		||||
				cache_clk_enable = cell->parameters.at("\\CLK_ENABLE").as_bool();
 | 
			
		||||
				cache_clk_polarity = cell->parameters.at("\\CLK_POLARITY").as_bool();
 | 
			
		||||
				cache_clk = sigmap(cell->getPort("\\CLK"));
 | 
			
		||||
				cache_clk_enable = cell->parameters.at(ID::CLK_ENABLE).as_bool();
 | 
			
		||||
				cache_clk_polarity = cell->parameters.at(ID::CLK_POLARITY).as_bool();
 | 
			
		||||
				cache_clk = sigmap(cell->getPort(ID::CLK));
 | 
			
		||||
			}
 | 
			
		||||
			else if (i > 0 && considered_ports.count(i-1) && considered_ports.count(i))
 | 
			
		||||
				considered_port_pairs.insert(i);
 | 
			
		||||
| 
						 | 
				
			
			@ -554,7 +554,7 @@ struct MemoryShareWorker
 | 
			
		|||
		for (int i = 0; i < int(wr_ports.size()); i++)
 | 
			
		||||
			if (considered_port_pairs.count(i) || considered_port_pairs.count(i+1))
 | 
			
		||||
			{
 | 
			
		||||
				RTLIL::SigSpec sig = modwalker.sigmap(wr_ports[i]->getPort("\\EN"));
 | 
			
		||||
				RTLIL::SigSpec sig = modwalker.sigmap(wr_ports[i]->getPort(ID::EN));
 | 
			
		||||
				port_to_sat_variable[i] = ez->expression(ez->OpOr, satgen.importSigSpec(sig));
 | 
			
		||||
 | 
			
		||||
				std::vector<RTLIL::SigBit> bits = sig;
 | 
			
		||||
| 
						 | 
				
			
			@ -564,7 +564,7 @@ struct MemoryShareWorker
 | 
			
		|||
		while (!bits_queue.empty())
 | 
			
		||||
		{
 | 
			
		||||
			for (auto bit : bits_queue)
 | 
			
		||||
				if (bit.wire && bit.wire->get_bool_attribute("\\onehot"))
 | 
			
		||||
				if (bit.wire && bit.wire->get_bool_attribute(ID::onehot))
 | 
			
		||||
					one_hot_wires.insert(bit.wire);
 | 
			
		||||
 | 
			
		||||
			pool<ModWalker::PortBit> portbits;
 | 
			
		||||
| 
						 | 
				
			
			@ -609,13 +609,13 @@ struct MemoryShareWorker
 | 
			
		|||
			log("  Merging port %d into port %d.\n", i-1, i);
 | 
			
		||||
			port_to_sat_variable.at(i) = ez->OR(port_to_sat_variable.at(i-1), port_to_sat_variable.at(i));
 | 
			
		||||
 | 
			
		||||
			RTLIL::SigSpec last_addr = wr_ports[i-1]->getPort("\\ADDR");
 | 
			
		||||
			RTLIL::SigSpec last_data = wr_ports[i-1]->getPort("\\DATA");
 | 
			
		||||
			std::vector<RTLIL::SigBit> last_en = modwalker.sigmap(wr_ports[i-1]->getPort("\\EN"));
 | 
			
		||||
			RTLIL::SigSpec last_addr = wr_ports[i-1]->getPort(ID::ADDR);
 | 
			
		||||
			RTLIL::SigSpec last_data = wr_ports[i-1]->getPort(ID::DATA);
 | 
			
		||||
			std::vector<RTLIL::SigBit> last_en = modwalker.sigmap(wr_ports[i-1]->getPort(ID::EN));
 | 
			
		||||
 | 
			
		||||
			RTLIL::SigSpec this_addr = wr_ports[i]->getPort("\\ADDR");
 | 
			
		||||
			RTLIL::SigSpec this_data = wr_ports[i]->getPort("\\DATA");
 | 
			
		||||
			std::vector<RTLIL::SigBit> this_en = modwalker.sigmap(wr_ports[i]->getPort("\\EN"));
 | 
			
		||||
			RTLIL::SigSpec this_addr = wr_ports[i]->getPort(ID::ADDR);
 | 
			
		||||
			RTLIL::SigSpec this_data = wr_ports[i]->getPort(ID::DATA);
 | 
			
		||||
			std::vector<RTLIL::SigBit> this_en = modwalker.sigmap(wr_ports[i]->getPort(ID::EN));
 | 
			
		||||
 | 
			
		||||
			RTLIL::SigBit this_en_active = module->ReduceOr(NEW_ID, this_en);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -624,9 +624,9 @@ struct MemoryShareWorker
 | 
			
		|||
			else
 | 
			
		||||
				this_addr.extend_u0(GetSize(last_addr));
 | 
			
		||||
 | 
			
		||||
			wr_ports[i]->setParam("\\ABITS", GetSize(this_addr));
 | 
			
		||||
			wr_ports[i]->setPort("\\ADDR", module->Mux(NEW_ID, last_addr, this_addr, this_en_active));
 | 
			
		||||
			wr_ports[i]->setPort("\\DATA", module->Mux(NEW_ID, last_data, this_data, this_en_active));
 | 
			
		||||
			wr_ports[i]->setParam(ID::ABITS, GetSize(this_addr));
 | 
			
		||||
			wr_ports[i]->setPort(ID::ADDR, module->Mux(NEW_ID, last_addr, this_addr, this_en_active));
 | 
			
		||||
			wr_ports[i]->setPort(ID::DATA, module->Mux(NEW_ID, last_data, this_data, this_en_active));
 | 
			
		||||
 | 
			
		||||
			std::map<std::pair<RTLIL::SigBit, RTLIL::SigBit>, int> groups_en;
 | 
			
		||||
			RTLIL::SigSpec grouped_last_en, grouped_this_en, en;
 | 
			
		||||
| 
						 | 
				
			
			@ -644,7 +644,7 @@ struct MemoryShareWorker
 | 
			
		|||
			}
 | 
			
		||||
 | 
			
		||||
			module->addMux(NEW_ID, grouped_last_en, grouped_this_en, this_en_active, grouped_en);
 | 
			
		||||
			wr_ports[i]->setPort("\\EN", en);
 | 
			
		||||
			wr_ports[i]->setPort(ID::EN, en);
 | 
			
		||||
 | 
			
		||||
			module->remove(wr_ports[i-1]);
 | 
			
		||||
			wr_ports[i-1] = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -679,26 +679,26 @@ struct MemoryShareWorker
 | 
			
		|||
		sigmap_xmux = sigmap;
 | 
			
		||||
		for (auto cell : module->cells())
 | 
			
		||||
		{
 | 
			
		||||
			if (cell->type == "$memrd")
 | 
			
		||||
				memindex[cell->parameters.at("\\MEMID").decode_string()].first.push_back(cell);
 | 
			
		||||
			if (cell->type == ID($memrd))
 | 
			
		||||
				memindex[cell->parameters.at(ID::MEMID).decode_string()].first.push_back(cell);
 | 
			
		||||
 | 
			
		||||
			if (cell->type == "$memwr")
 | 
			
		||||
				memindex[cell->parameters.at("\\MEMID").decode_string()].second.push_back(cell);
 | 
			
		||||
			if (cell->type == ID($memwr))
 | 
			
		||||
				memindex[cell->parameters.at(ID::MEMID).decode_string()].second.push_back(cell);
 | 
			
		||||
 | 
			
		||||
			if (cell->type == "$mux")
 | 
			
		||||
			if (cell->type == ID($mux))
 | 
			
		||||
			{
 | 
			
		||||
				RTLIL::SigSpec sig_a = sigmap_xmux(cell->getPort("\\A"));
 | 
			
		||||
				RTLIL::SigSpec sig_b = sigmap_xmux(cell->getPort("\\B"));
 | 
			
		||||
				RTLIL::SigSpec sig_a = sigmap_xmux(cell->getPort(ID::A));
 | 
			
		||||
				RTLIL::SigSpec sig_b = sigmap_xmux(cell->getPort(ID::B));
 | 
			
		||||
 | 
			
		||||
				if (sig_a.is_fully_undef())
 | 
			
		||||
					sigmap_xmux.add(cell->getPort("\\Y"), sig_b);
 | 
			
		||||
					sigmap_xmux.add(cell->getPort(ID::Y), sig_b);
 | 
			
		||||
				else if (sig_b.is_fully_undef())
 | 
			
		||||
					sigmap_xmux.add(cell->getPort("\\Y"), sig_a);
 | 
			
		||||
					sigmap_xmux.add(cell->getPort(ID::Y), sig_a);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in("$mux", "$pmux"))
 | 
			
		||||
			if (cell->type.in(ID($mux), ID($pmux)))
 | 
			
		||||
			{
 | 
			
		||||
				std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort("\\Y"));
 | 
			
		||||
				std::vector<RTLIL::SigBit> sig_y = sigmap(cell->getPort(ID::Y));
 | 
			
		||||
				for (int i = 0; i < int(sig_y.size()); i++)
 | 
			
		||||
					sig_to_mux[sig_y[i]] = std::pair<RTLIL::Cell*, int>(cell, i);
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -712,16 +712,16 @@ struct MemoryShareWorker
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		cone_ct.setup_internals();
 | 
			
		||||
		cone_ct.cell_types.erase("$mul");
 | 
			
		||||
		cone_ct.cell_types.erase("$mod");
 | 
			
		||||
		cone_ct.cell_types.erase("$div");
 | 
			
		||||
		cone_ct.cell_types.erase("$pow");
 | 
			
		||||
		cone_ct.cell_types.erase("$shl");
 | 
			
		||||
		cone_ct.cell_types.erase("$shr");
 | 
			
		||||
		cone_ct.cell_types.erase("$sshl");
 | 
			
		||||
		cone_ct.cell_types.erase("$sshr");
 | 
			
		||||
		cone_ct.cell_types.erase("$shift");
 | 
			
		||||
		cone_ct.cell_types.erase("$shiftx");
 | 
			
		||||
		cone_ct.cell_types.erase(ID($mul));
 | 
			
		||||
		cone_ct.cell_types.erase(ID($mod));
 | 
			
		||||
		cone_ct.cell_types.erase(ID($div));
 | 
			
		||||
		cone_ct.cell_types.erase(ID($pow));
 | 
			
		||||
		cone_ct.cell_types.erase(ID($shl));
 | 
			
		||||
		cone_ct.cell_types.erase(ID($shr));
 | 
			
		||||
		cone_ct.cell_types.erase(ID($sshl));
 | 
			
		||||
		cone_ct.cell_types.erase(ID($sshr));
 | 
			
		||||
		cone_ct.cell_types.erase(ID($shift));
 | 
			
		||||
		cone_ct.cell_types.erase(ID($shiftx));
 | 
			
		||||
 | 
			
		||||
		modwalker.setup(module, &cone_ct);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,53 +31,53 @@ void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory)
 | 
			
		|||
	log("Creating $memrd and $memwr for memory `%s' in module `%s':\n",
 | 
			
		||||
			memory->name.c_str(), module->name.c_str());
 | 
			
		||||
 | 
			
		||||
	RTLIL::IdString mem_name = RTLIL::escape_id(memory->parameters.at("\\MEMID").decode_string());
 | 
			
		||||
	RTLIL::IdString mem_name = RTLIL::escape_id(memory->parameters.at(ID::MEMID).decode_string());
 | 
			
		||||
 | 
			
		||||
	while (module->memories.count(mem_name) != 0)
 | 
			
		||||
		mem_name = mem_name.str() + stringf("_%d", autoidx++);
 | 
			
		||||
 | 
			
		||||
	RTLIL::Memory *mem = new RTLIL::Memory;
 | 
			
		||||
	mem->name = mem_name;
 | 
			
		||||
	mem->width = memory->parameters.at("\\WIDTH").as_int();
 | 
			
		||||
	mem->start_offset = memory->parameters.at("\\OFFSET").as_int();
 | 
			
		||||
	mem->size = memory->parameters.at("\\SIZE").as_int();
 | 
			
		||||
	mem->width = memory->parameters.at(ID::WIDTH).as_int();
 | 
			
		||||
	mem->start_offset = memory->parameters.at(ID::OFFSET).as_int();
 | 
			
		||||
	mem->size = memory->parameters.at(ID::SIZE).as_int();
 | 
			
		||||
	module->memories[mem_name] = mem;
 | 
			
		||||
 | 
			
		||||
	int abits = memory->parameters.at("\\ABITS").as_int();
 | 
			
		||||
	int num_rd_ports = memory->parameters.at("\\RD_PORTS").as_int();
 | 
			
		||||
	int num_wr_ports = memory->parameters.at("\\WR_PORTS").as_int();
 | 
			
		||||
	int abits = memory->parameters.at(ID::ABITS).as_int();
 | 
			
		||||
	int num_rd_ports = memory->parameters.at(ID::RD_PORTS).as_int();
 | 
			
		||||
	int num_wr_ports = memory->parameters.at(ID::WR_PORTS).as_int();
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < num_rd_ports; i++)
 | 
			
		||||
	{
 | 
			
		||||
		RTLIL::Cell *cell = module->addCell(NEW_ID, "$memrd");
 | 
			
		||||
		cell->parameters["\\MEMID"] = mem_name.str();
 | 
			
		||||
		cell->parameters["\\ABITS"] = memory->parameters.at("\\ABITS");
 | 
			
		||||
		cell->parameters["\\WIDTH"] = memory->parameters.at("\\WIDTH");
 | 
			
		||||
		cell->parameters["\\CLK_ENABLE"] = RTLIL::SigSpec(memory->parameters.at("\\RD_CLK_ENABLE")).extract(i, 1).as_const();
 | 
			
		||||
		cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\RD_CLK_POLARITY")).extract(i, 1).as_const();
 | 
			
		||||
		cell->parameters["\\TRANSPARENT"] = RTLIL::SigSpec(memory->parameters.at("\\RD_TRANSPARENT")).extract(i, 1).as_const();
 | 
			
		||||
		cell->setPort("\\CLK", memory->getPort("\\RD_CLK").extract(i, 1));
 | 
			
		||||
		cell->setPort("\\EN", memory->getPort("\\RD_EN").extract(i, 1));
 | 
			
		||||
		cell->setPort("\\ADDR", memory->getPort("\\RD_ADDR").extract(i*abits, abits));
 | 
			
		||||
		cell->setPort("\\DATA", memory->getPort("\\RD_DATA").extract(i*mem->width, mem->width));
 | 
			
		||||
		RTLIL::Cell *cell = module->addCell(NEW_ID, ID($memrd));
 | 
			
		||||
		cell->parameters[ID::MEMID] = mem_name.str();
 | 
			
		||||
		cell->parameters[ID::ABITS] = memory->parameters.at(ID::ABITS);
 | 
			
		||||
		cell->parameters[ID::WIDTH] = memory->parameters.at(ID::WIDTH);
 | 
			
		||||
		cell->parameters[ID::CLK_ENABLE] = RTLIL::SigSpec(memory->parameters.at(ID::RD_CLK_ENABLE)).extract(i, 1).as_const();
 | 
			
		||||
		cell->parameters[ID::CLK_POLARITY] = RTLIL::SigSpec(memory->parameters.at(ID::RD_CLK_POLARITY)).extract(i, 1).as_const();
 | 
			
		||||
		cell->parameters[ID::TRANSPARENT] = RTLIL::SigSpec(memory->parameters.at(ID::RD_TRANSPARENT)).extract(i, 1).as_const();
 | 
			
		||||
		cell->setPort(ID::CLK, memory->getPort(ID::RD_CLK).extract(i, 1));
 | 
			
		||||
		cell->setPort(ID::EN, memory->getPort(ID::RD_EN).extract(i, 1));
 | 
			
		||||
		cell->setPort(ID::ADDR, memory->getPort(ID::RD_ADDR).extract(i*abits, abits));
 | 
			
		||||
		cell->setPort(ID::DATA, memory->getPort(ID::RD_DATA).extract(i*mem->width, mem->width));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (int i = 0; i < num_wr_ports; i++)
 | 
			
		||||
	{
 | 
			
		||||
		RTLIL::Cell *cell = module->addCell(NEW_ID, "$memwr");
 | 
			
		||||
		cell->parameters["\\MEMID"] = mem_name.str();
 | 
			
		||||
		cell->parameters["\\ABITS"] = memory->parameters.at("\\ABITS");
 | 
			
		||||
		cell->parameters["\\WIDTH"] = memory->parameters.at("\\WIDTH");
 | 
			
		||||
		cell->parameters["\\CLK_ENABLE"] = RTLIL::SigSpec(memory->parameters.at("\\WR_CLK_ENABLE")).extract(i, 1).as_const();
 | 
			
		||||
		cell->parameters["\\CLK_POLARITY"] = RTLIL::SigSpec(memory->parameters.at("\\WR_CLK_POLARITY")).extract(i, 1).as_const();
 | 
			
		||||
		cell->parameters["\\PRIORITY"] = i;
 | 
			
		||||
		cell->setPort("\\CLK", memory->getPort("\\WR_CLK").extract(i, 1));
 | 
			
		||||
		cell->setPort("\\EN", memory->getPort("\\WR_EN").extract(i*mem->width, mem->width));
 | 
			
		||||
		cell->setPort("\\ADDR", memory->getPort("\\WR_ADDR").extract(i*abits, abits));
 | 
			
		||||
		cell->setPort("\\DATA", memory->getPort("\\WR_DATA").extract(i*mem->width, mem->width));
 | 
			
		||||
		RTLIL::Cell *cell = module->addCell(NEW_ID, ID($memwr));
 | 
			
		||||
		cell->parameters[ID::MEMID] = mem_name.str();
 | 
			
		||||
		cell->parameters[ID::ABITS] = memory->parameters.at(ID::ABITS);
 | 
			
		||||
		cell->parameters[ID::WIDTH] = memory->parameters.at(ID::WIDTH);
 | 
			
		||||
		cell->parameters[ID::CLK_ENABLE] = RTLIL::SigSpec(memory->parameters.at(ID::WR_CLK_ENABLE)).extract(i, 1).as_const();
 | 
			
		||||
		cell->parameters[ID::CLK_POLARITY] = RTLIL::SigSpec(memory->parameters.at(ID::WR_CLK_POLARITY)).extract(i, 1).as_const();
 | 
			
		||||
		cell->parameters[ID::PRIORITY] = i;
 | 
			
		||||
		cell->setPort(ID::CLK, memory->getPort(ID::WR_CLK).extract(i, 1));
 | 
			
		||||
		cell->setPort(ID::EN, memory->getPort(ID::WR_EN).extract(i*mem->width, mem->width));
 | 
			
		||||
		cell->setPort(ID::ADDR, memory->getPort(ID::WR_ADDR).extract(i*abits, abits));
 | 
			
		||||
		cell->setPort(ID::DATA, memory->getPort(ID::WR_DATA).extract(i*mem->width, mem->width));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Const initval = memory->parameters.at("\\INIT");
 | 
			
		||||
	Const initval = memory->parameters.at(ID::INIT);
 | 
			
		||||
	RTLIL::Cell *last_init_cell = nullptr;
 | 
			
		||||
	SigSpec last_init_data;
 | 
			
		||||
	int last_init_addr=0;
 | 
			
		||||
| 
						 | 
				
			
			@ -90,19 +90,19 @@ void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory)
 | 
			
		|||
		continue;
 | 
			
		||||
	found_non_undef_initval:
 | 
			
		||||
		if (last_init_cell && last_init_addr+1 == i/mem->width) {
 | 
			
		||||
			last_init_cell->parameters["\\WORDS"] = last_init_cell->parameters["\\WORDS"].as_int() + 1;
 | 
			
		||||
			last_init_cell->parameters[ID::WORDS] = last_init_cell->parameters[ID::WORDS].as_int() + 1;
 | 
			
		||||
			last_init_data.append(val);
 | 
			
		||||
			last_init_addr++;
 | 
			
		||||
		} else {
 | 
			
		||||
			if (last_init_cell)
 | 
			
		||||
				last_init_cell->setPort("\\DATA", last_init_data);
 | 
			
		||||
			RTLIL::Cell *cell = module->addCell(NEW_ID, "$meminit");
 | 
			
		||||
			cell->parameters["\\MEMID"] = mem_name.str();
 | 
			
		||||
			cell->parameters["\\ABITS"] = memory->parameters.at("\\ABITS");
 | 
			
		||||
			cell->parameters["\\WIDTH"] = memory->parameters.at("\\WIDTH");
 | 
			
		||||
			cell->parameters["\\WORDS"] = 1;
 | 
			
		||||
			cell->parameters["\\PRIORITY"] = i/mem->width;
 | 
			
		||||
			cell->setPort("\\ADDR", SigSpec(i/mem->width, abits));
 | 
			
		||||
				last_init_cell->setPort(ID::DATA, last_init_data);
 | 
			
		||||
			RTLIL::Cell *cell = module->addCell(NEW_ID, ID($meminit));
 | 
			
		||||
			cell->parameters[ID::MEMID] = mem_name.str();
 | 
			
		||||
			cell->parameters[ID::ABITS] = memory->parameters.at(ID::ABITS);
 | 
			
		||||
			cell->parameters[ID::WIDTH] = memory->parameters.at(ID::WIDTH);
 | 
			
		||||
			cell->parameters[ID::WORDS] = 1;
 | 
			
		||||
			cell->parameters[ID::PRIORITY] = i/mem->width;
 | 
			
		||||
			cell->setPort(ID::ADDR, SigSpec(i/mem->width, abits));
 | 
			
		||||
			last_init_cell = cell;
 | 
			
		||||
			last_init_addr = i/mem->width;
 | 
			
		||||
			last_init_data = val;
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +110,7 @@ void handle_memory(RTLIL::Module *module, RTLIL::Cell *memory)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if (last_init_cell)
 | 
			
		||||
		last_init_cell->setPort("\\DATA", last_init_data);
 | 
			
		||||
		last_init_cell->setPort(ID::DATA, last_init_data);
 | 
			
		||||
 | 
			
		||||
	module->remove(memory);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -119,7 +119,7 @@ void handle_module(RTLIL::Design *design, RTLIL::Module *module)
 | 
			
		|||
{
 | 
			
		||||
	std::vector<RTLIL::IdString> memcells;
 | 
			
		||||
	for (auto &cell_it : module->cells_)
 | 
			
		||||
		if (cell_it.second->type == "$mem" && design->selected(module, cell_it.second))
 | 
			
		||||
		if (cell_it.second->type == ID($mem) && design->selected(module, cell_it.second))
 | 
			
		||||
			memcells.push_back(cell_it.first);
 | 
			
		||||
	for (auto &it : memcells)
 | 
			
		||||
		handle_memory(module, module->cells_.at(it));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -208,8 +208,8 @@ struct MuxpackWorker
 | 
			
		|||
			{
 | 
			
		||||
				Cell *prev_cell = sig_chain_prev.at(a_sig);
 | 
			
		||||
				log_assert(prev_cell);
 | 
			
		||||
				SigSpec s_sig = sigmap(cell->getPort(ID(S)));
 | 
			
		||||
				s_sig.append(sigmap(prev_cell->getPort(ID(S))));
 | 
			
		||||
				SigSpec s_sig = sigmap(cell->getPort(ID::S));
 | 
			
		||||
				s_sig.append(sigmap(prev_cell->getPort(ID::S)));
 | 
			
		||||
				if (!excl_db.query(s_sig))
 | 
			
		||||
					goto start_cell;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -271,26 +271,26 @@ struct MuxpackWorker
 | 
			
		|||
 | 
			
		||||
			first_cell->type = ID($pmux);
 | 
			
		||||
			SigSpec b_sig = first_cell->getPort(ID::B);
 | 
			
		||||
			SigSpec s_sig = first_cell->getPort(ID(S));
 | 
			
		||||
			SigSpec s_sig = first_cell->getPort(ID::S);
 | 
			
		||||
 | 
			
		||||
			for (int i = 1; i < cases; i++) {
 | 
			
		||||
				Cell* prev_cell = chain[cursor+i-1];
 | 
			
		||||
				Cell* cursor_cell = chain[cursor+i];
 | 
			
		||||
				if (sigmap(prev_cell->getPort(ID::Y)) == sigmap(cursor_cell->getPort(ID::A))) {
 | 
			
		||||
					b_sig.append(cursor_cell->getPort(ID::B));
 | 
			
		||||
					s_sig.append(cursor_cell->getPort(ID(S)));
 | 
			
		||||
					s_sig.append(cursor_cell->getPort(ID::S));
 | 
			
		||||
				}
 | 
			
		||||
				else {
 | 
			
		||||
					log_assert(cursor_cell->type == ID($mux));
 | 
			
		||||
					b_sig.append(cursor_cell->getPort(ID::A));
 | 
			
		||||
					s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort(ID(S))));
 | 
			
		||||
					s_sig.append(module->LogicNot(NEW_ID, cursor_cell->getPort(ID::S)));
 | 
			
		||||
				}
 | 
			
		||||
				remove_cells.insert(cursor_cell);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			first_cell->setPort(ID::B, b_sig);
 | 
			
		||||
			first_cell->setPort(ID(S), s_sig);
 | 
			
		||||
			first_cell->setParam(ID(S_WIDTH), GetSize(s_sig));
 | 
			
		||||
			first_cell->setPort(ID::S, s_sig);
 | 
			
		||||
			first_cell->setParam(ID::S_WIDTH, GetSize(s_sig));
 | 
			
		||||
			first_cell->setPort(ID::Y, last_cell->getPort(ID::Y));
 | 
			
		||||
 | 
			
		||||
			cursor += cases;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -183,8 +183,8 @@ void rmunused_module_cells(Module *module, bool verbose)
 | 
			
		|||
int count_nontrivial_wire_attrs(RTLIL::Wire *w)
 | 
			
		||||
{
 | 
			
		||||
	int count = w->attributes.size();
 | 
			
		||||
	count -= w->attributes.count(ID(src));
 | 
			
		||||
	count -= w->attributes.count(ID(unused_bits));
 | 
			
		||||
	count -= w->attributes.count(ID::src);
 | 
			
		||||
	count -= w->attributes.count(ID::unused_bits);
 | 
			
		||||
	return count;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -317,12 +317,12 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
 | 
			
		|||
		log_assert(GetSize(s1) == GetSize(s2));
 | 
			
		||||
 | 
			
		||||
		Const initval;
 | 
			
		||||
		if (wire->attributes.count(ID(init)))
 | 
			
		||||
			initval = wire->attributes.at(ID(init));
 | 
			
		||||
		if (wire->attributes.count(ID::init))
 | 
			
		||||
			initval = wire->attributes.at(ID::init);
 | 
			
		||||
		if (GetSize(initval) != GetSize(wire))
 | 
			
		||||
			initval.bits.resize(GetSize(wire), State::Sx);
 | 
			
		||||
		if (initval.is_fully_undef())
 | 
			
		||||
			wire->attributes.erase(ID(init));
 | 
			
		||||
			wire->attributes.erase(ID::init);
 | 
			
		||||
 | 
			
		||||
		if (GetSize(wire) == 0) {
 | 
			
		||||
			// delete zero-width wires, unless they are module ports
 | 
			
		||||
| 
						 | 
				
			
			@ -363,9 +363,9 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
 | 
			
		|||
				}
 | 
			
		||||
			if (new_conn.first.size() > 0) {
 | 
			
		||||
				if (initval.is_fully_undef())
 | 
			
		||||
					wire->attributes.erase(ID(init));
 | 
			
		||||
					wire->attributes.erase(ID::init);
 | 
			
		||||
				else
 | 
			
		||||
					wire->attributes.at(ID(init)) = initval;
 | 
			
		||||
					wire->attributes.at(ID::init) = initval;
 | 
			
		||||
				used_signals.add(new_conn.first);
 | 
			
		||||
				used_signals.add(new_conn.second);
 | 
			
		||||
				module->connect(new_conn);
 | 
			
		||||
| 
						 | 
				
			
			@ -383,11 +383,11 @@ bool rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
 | 
			
		|||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if (unused_bits.empty() || wire->port_id != 0)
 | 
			
		||||
					wire->attributes.erase(ID(unused_bits));
 | 
			
		||||
					wire->attributes.erase(ID::unused_bits);
 | 
			
		||||
				else
 | 
			
		||||
					wire->attributes[ID(unused_bits)] = RTLIL::Const(unused_bits);
 | 
			
		||||
					wire->attributes[ID::unused_bits] = RTLIL::Const(unused_bits);
 | 
			
		||||
			} else {
 | 
			
		||||
				wire->attributes.erase(ID(unused_bits));
 | 
			
		||||
				wire->attributes.erase(ID::unused_bits);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -419,18 +419,18 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose)
 | 
			
		|||
	dict<SigBit, State> qbits;
 | 
			
		||||
 | 
			
		||||
	for (auto cell : module->cells())
 | 
			
		||||
		if (fftypes.cell_known(cell->type) && cell->hasPort(ID(Q)))
 | 
			
		||||
		if (fftypes.cell_known(cell->type) && cell->hasPort(ID::Q))
 | 
			
		||||
		{
 | 
			
		||||
			SigSpec sig = cell->getPort(ID(Q));
 | 
			
		||||
			SigSpec sig = cell->getPort(ID::Q);
 | 
			
		||||
 | 
			
		||||
			for (int i = 0; i < GetSize(sig); i++)
 | 
			
		||||
			{
 | 
			
		||||
				SigBit bit = sig[i];
 | 
			
		||||
 | 
			
		||||
				if (bit.wire == nullptr || bit.wire->attributes.count(ID(init)) == 0)
 | 
			
		||||
				if (bit.wire == nullptr || bit.wire->attributes.count(ID::init) == 0)
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				Const init = bit.wire->attributes.at(ID(init));
 | 
			
		||||
				Const init = bit.wire->attributes.at(ID::init);
 | 
			
		||||
 | 
			
		||||
				if (i >= GetSize(init) || init[i] == State::Sx || init[i] == State::Sz)
 | 
			
		||||
					continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -445,10 +445,10 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose)
 | 
			
		|||
		if (!purge_mode && wire->name[0] == '\\')
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if (wire->attributes.count(ID(init)) == 0)
 | 
			
		||||
		if (wire->attributes.count(ID::init) == 0)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		Const init = wire->attributes.at(ID(init));
 | 
			
		||||
		Const init = wire->attributes.at(ID::init);
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < GetSize(wire) && i < GetSize(init); i++)
 | 
			
		||||
		{
 | 
			
		||||
| 
						 | 
				
			
			@ -471,7 +471,7 @@ bool rmunused_module_init(RTLIL::Module *module, bool purge_mode, bool verbose)
 | 
			
		|||
		if (verbose)
 | 
			
		||||
			log_debug("  removing redundant init attribute on %s.\n", log_id(wire));
 | 
			
		||||
 | 
			
		||||
		wire->attributes.erase(ID(init));
 | 
			
		||||
		wire->attributes.erase(ID::init);
 | 
			
		||||
		did_something = true;
 | 
			
		||||
	next_wire:;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -487,7 +487,7 @@ void rmunused_module(RTLIL::Module *module, bool purge_mode, bool verbose, bool
 | 
			
		|||
	std::vector<RTLIL::Cell*> delcells;
 | 
			
		||||
	for (auto cell : module->cells())
 | 
			
		||||
		if (cell->type.in(ID($pos), ID($_BUF_)) && !cell->has_keep_attr()) {
 | 
			
		||||
			bool is_signed = cell->type == ID($pos) && cell->getParam(ID(A_SIGNED)).as_bool();
 | 
			
		||||
			bool is_signed = cell->type == ID($pos) && cell->getParam(ID::A_SIGNED).as_bool();
 | 
			
		||||
			RTLIL::SigSpec a = cell->getPort(ID::A);
 | 
			
		||||
			RTLIL::SigSpec y = cell->getPort(ID::Y);
 | 
			
		||||
			a.extend_u0(GetSize(y), is_signed);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,9 +50,9 @@ void replace_undriven(RTLIL::Module *module, const CellTypes &ct)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	for (auto wire : module->wires()) {
 | 
			
		||||
		if (wire->attributes.count(ID(init))) {
 | 
			
		||||
		if (wire->attributes.count(ID::init)) {
 | 
			
		||||
			SigSpec sig = sigmap(wire);
 | 
			
		||||
			Const initval = wire->attributes.at(ID(init));
 | 
			
		||||
			Const initval = wire->attributes.at(ID::init);
 | 
			
		||||
			for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++) {
 | 
			
		||||
				if (initval[i] == State::S0 || initval[i] == State::S1)
 | 
			
		||||
					initbits[sig[i]] = make_pair(wire, initval[i]);
 | 
			
		||||
| 
						 | 
				
			
			@ -98,18 +98,18 @@ void replace_undriven(RTLIL::Module *module, const CellTypes &ct)
 | 
			
		|||
 | 
			
		||||
		for (auto wire : revisit_initwires) {
 | 
			
		||||
			SigSpec sig = sm2(wire);
 | 
			
		||||
			Const initval = wire->attributes.at(ID(init));
 | 
			
		||||
			Const initval = wire->attributes.at(ID::init);
 | 
			
		||||
			for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++) {
 | 
			
		||||
				if (SigBit(initval[i]) == sig[i])
 | 
			
		||||
					initval[i] = State::Sx;
 | 
			
		||||
			}
 | 
			
		||||
			if (initval.is_fully_undef()) {
 | 
			
		||||
				log_debug("Removing init attribute from %s/%s.\n", log_id(module), log_id(wire));
 | 
			
		||||
				wire->attributes.erase(ID(init));
 | 
			
		||||
				wire->attributes.erase(ID::init);
 | 
			
		||||
				did_something = true;
 | 
			
		||||
			} else if (initval != wire->attributes.at(ID(init))) {
 | 
			
		||||
			} else if (initval != wire->attributes.at(ID::init)) {
 | 
			
		||||
				log_debug("Updating init attribute on %s/%s: %s\n", log_id(module), log_id(wire), log_signal(initval));
 | 
			
		||||
				wire->attributes[ID(init)] = initval;
 | 
			
		||||
				wire->attributes[ID::init] = initval;
 | 
			
		||||
				did_something = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -136,7 +136,7 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ
 | 
			
		|||
{
 | 
			
		||||
	IdString b_name = cell->hasPort(ID::B) ? ID::B : ID::A;
 | 
			
		||||
 | 
			
		||||
	bool a_signed = cell->parameters.at(ID(A_SIGNED)).as_bool();
 | 
			
		||||
	bool a_signed = cell->parameters.at(ID::A_SIGNED).as_bool();
 | 
			
		||||
	bool b_signed = cell->parameters.at(b_name.str() + "_SIGNED").as_bool();
 | 
			
		||||
 | 
			
		||||
	RTLIL::SigSpec sig_a = sigmap(cell->getPort(ID::A));
 | 
			
		||||
| 
						 | 
				
			
			@ -209,17 +209,17 @@ bool group_cell_inputs(RTLIL::Module *module, RTLIL::Cell *cell, bool commutativ
 | 
			
		|||
		RTLIL::Cell *c = module->addCell(NEW_ID, cell->type);
 | 
			
		||||
 | 
			
		||||
		c->setPort(ID::A, new_a);
 | 
			
		||||
		c->parameters[ID(A_WIDTH)] = new_a.size();
 | 
			
		||||
		c->parameters[ID(A_SIGNED)] = false;
 | 
			
		||||
		c->parameters[ID::A_WIDTH] = new_a.size();
 | 
			
		||||
		c->parameters[ID::A_SIGNED] = false;
 | 
			
		||||
 | 
			
		||||
		if (b_name == ID::B) {
 | 
			
		||||
			c->setPort(ID::B, new_b);
 | 
			
		||||
			c->parameters[ID(B_WIDTH)] = new_b.size();
 | 
			
		||||
			c->parameters[ID(B_SIGNED)] = false;
 | 
			
		||||
			c->parameters[ID::B_WIDTH] = new_b.size();
 | 
			
		||||
			c->parameters[ID::B_SIGNED] = false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		c->setPort(ID::Y, new_y);
 | 
			
		||||
		c->parameters[ID(Y_WIDTH)] = new_y->width;
 | 
			
		||||
		c->parameters[ID::Y_WIDTH] = new_y->width;
 | 
			
		||||
		c->check();
 | 
			
		||||
 | 
			
		||||
		module->connect(new_conn);
 | 
			
		||||
| 
						 | 
				
			
			@ -372,7 +372,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
				invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID::A));
 | 
			
		||||
			if (cell->type.in(ID($mux), ID($_MUX_)) &&
 | 
			
		||||
					cell->getPort(ID::A) == SigSpec(State::S1) && cell->getPort(ID::B) == SigSpec(State::S0))
 | 
			
		||||
				invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID(S)));
 | 
			
		||||
				invert_map[assign_map(cell->getPort(ID::Y))] = assign_map(cell->getPort(ID::S));
 | 
			
		||||
			if (ct_combinational.cell_known(cell->type))
 | 
			
		||||
				for (auto &conn : cell->connections()) {
 | 
			
		||||
					RTLIL::SigSpec sig = assign_map(conn.second);
 | 
			
		||||
| 
						 | 
				
			
			@ -401,36 +401,36 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
		if (clkinv)
 | 
			
		||||
		{
 | 
			
		||||
			if (cell->type.in(ID($dff), ID($dffe), ID($dffsr), ID($adff), ID($fsm), ID($memrd), ID($memwr)))
 | 
			
		||||
				handle_polarity_inv(cell, ID(CLK), ID(CLK_POLARITY), assign_map, invert_map);
 | 
			
		||||
				handle_polarity_inv(cell, ID::CLK, ID::CLK_POLARITY, assign_map, invert_map);
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in(ID($sr), ID($dffsr), ID($dlatchsr))) {
 | 
			
		||||
				handle_polarity_inv(cell, ID(SET), ID(SET_POLARITY), assign_map, invert_map);
 | 
			
		||||
				handle_polarity_inv(cell, ID(CLR), ID(CLR_POLARITY), assign_map, invert_map);
 | 
			
		||||
				handle_polarity_inv(cell, ID::SET, ID::SET_POLARITY, assign_map, invert_map);
 | 
			
		||||
				handle_polarity_inv(cell, ID::CLR, ID::CLR_POLARITY, assign_map, invert_map);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in(ID($dffe), ID($dlatch), ID($dlatchsr)))
 | 
			
		||||
				handle_polarity_inv(cell, ID(EN), ID(EN_POLARITY), assign_map, invert_map);
 | 
			
		||||
				handle_polarity_inv(cell, ID::EN, ID::EN_POLARITY, assign_map, invert_map);
 | 
			
		||||
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_SR_N?_", "$_SR_P?_", ID(S), assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_SR_?N_", "$_SR_?P_", ID(R), assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_SR_N?_", "$_SR_P?_", ID::S, assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_SR_?N_", "$_SR_?P_", ID::R, assign_map, invert_map);
 | 
			
		||||
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFF_N_", "$_DFF_P_", ID(C), assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFF_N_", "$_DFF_P_", ID::C, assign_map, invert_map);
 | 
			
		||||
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFFE_N?_", "$_DFFE_P?_", ID(C), assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFFE_?N_", "$_DFFE_?P_", ID(E), assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFFE_N?_", "$_DFFE_P?_", ID::C, assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFFE_?N_", "$_DFFE_?P_", ID::E, assign_map, invert_map);
 | 
			
		||||
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFF_N??_", "$_DFF_P??_", ID(C), assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFF_?N?_", "$_DFF_?P?_", ID(R), assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFF_N??_", "$_DFF_P??_", ID::C, assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFF_?N?_", "$_DFF_?P?_", ID::R, assign_map, invert_map);
 | 
			
		||||
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFFSR_N??_", "$_DFFSR_P??_", ID(C), assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFFSR_?N?_", "$_DFFSR_?P?_", ID(S), assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFFSR_??N_", "$_DFFSR_??P_", ID(R), assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFFSR_N??_", "$_DFFSR_P??_", ID::C, assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFFSR_?N?_", "$_DFFSR_?P?_", ID::S, assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DFFSR_??N_", "$_DFFSR_??P_", ID::R, assign_map, invert_map);
 | 
			
		||||
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DLATCH_N_", "$_DLATCH_P_", ID(E), assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DLATCH_N_", "$_DLATCH_P_", ID::E, assign_map, invert_map);
 | 
			
		||||
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DLATCHSR_N??_", "$_DLATCHSR_P??_", ID(E), assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DLATCHSR_?N?_", "$_DLATCHSR_?P?_", ID(S), assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DLATCHSR_??N_", "$_DLATCHSR_??P_", ID(R), assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DLATCHSR_N??_", "$_DLATCHSR_P??_", ID::E, assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DLATCHSR_?N?_", "$_DLATCHSR_?P?_", ID::S, assign_map, invert_map);
 | 
			
		||||
			handle_clkpol_celltype_swap(cell, "$_DLATCHSR_??N_", "$_DLATCHSR_??P_", ID::R, assign_map, invert_map);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool detect_const_and = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -439,13 +439,13 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
		if (cell->type.in(ID($reduce_and), ID($_AND_)))
 | 
			
		||||
			detect_const_and = true;
 | 
			
		||||
 | 
			
		||||
		if (cell->type.in(ID($and), ID($logic_and)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool())
 | 
			
		||||
		if (cell->type.in(ID($and), ID($logic_and)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID::A_SIGNED).as_bool())
 | 
			
		||||
			detect_const_and = true;
 | 
			
		||||
 | 
			
		||||
		if (cell->type.in(ID($reduce_or), ID($reduce_bool), ID($_OR_)))
 | 
			
		||||
			detect_const_or = true;
 | 
			
		||||
 | 
			
		||||
		if (cell->type.in(ID($or), ID($logic_or)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool())
 | 
			
		||||
		if (cell->type.in(ID($or), ID($logic_or)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID::A_SIGNED).as_bool())
 | 
			
		||||
			detect_const_or = true;
 | 
			
		||||
 | 
			
		||||
		if (detect_const_and || detect_const_or)
 | 
			
		||||
| 
						 | 
				
			
			@ -495,7 +495,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (cell->type.in(ID($_XOR_), ID($_XNOR_)) || (cell->type.in(ID($xor), ID($xnor)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID(A_SIGNED)).as_bool()))
 | 
			
		||||
		if (cell->type.in(ID($_XOR_), ID($_XNOR_)) || (cell->type.in(ID($xor), ID($xnor)) && GetSize(cell->getPort(ID::A)) == 1 && GetSize(cell->getPort(ID::B)) == 1 && !cell->getParam(ID::A_SIGNED).as_bool()))
 | 
			
		||||
		{
 | 
			
		||||
			SigBit sig_a = assign_map(cell->getPort(ID::A));
 | 
			
		||||
			SigBit sig_b = assign_map(cell->getPort(ID::B));
 | 
			
		||||
| 
						 | 
				
			
			@ -518,7 +518,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
					SigSpec sig_y;
 | 
			
		||||
					if (cell->type == ID($xnor)) {
 | 
			
		||||
						sig_y = (sig_b == State::S1 ? sig_a : module->Not(NEW_ID, sig_a).as_bit());
 | 
			
		||||
						int width = cell->getParam(ID(Y_WIDTH)).as_int();
 | 
			
		||||
						int width = cell->getParam(ID::Y_WIDTH).as_int();
 | 
			
		||||
						sig_y.append(RTLIL::Const(State::S1, width-1));
 | 
			
		||||
					}
 | 
			
		||||
					else if (cell->type == ID($_XNOR_))
 | 
			
		||||
| 
						 | 
				
			
			@ -571,7 +571,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
					log_debug("Replacing port A of %s cell `%s' in module `%s' with shorter expression: %s -> %s\n",
 | 
			
		||||
							cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_sig_a));
 | 
			
		||||
					cell->setPort(ID::A, new_sig_a);
 | 
			
		||||
					cell->parameters.at(ID(A_WIDTH)) = GetSize(new_sig_a);
 | 
			
		||||
					cell->parameters.at(ID::A_WIDTH) = GetSize(new_sig_a);
 | 
			
		||||
					did_something = true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -594,7 +594,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
					log_debug("Replacing port B of %s cell `%s' in module `%s' with shorter expression: %s -> %s\n",
 | 
			
		||||
							cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_sig_b));
 | 
			
		||||
					cell->setPort(ID::B, new_sig_b);
 | 
			
		||||
					cell->parameters.at(ID(B_WIDTH)) = GetSize(new_sig_b);
 | 
			
		||||
					cell->parameters.at(ID::B_WIDTH) = GetSize(new_sig_b);
 | 
			
		||||
					did_something = true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -620,7 +620,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
					log_debug("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n",
 | 
			
		||||
							cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a));
 | 
			
		||||
					cell->setPort(ID::A, sig_a = new_a);
 | 
			
		||||
					cell->parameters.at(ID(A_WIDTH)) = 1;
 | 
			
		||||
					cell->parameters.at(ID::A_WIDTH) = 1;
 | 
			
		||||
					did_something = true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -646,7 +646,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
					log_debug("Replacing port A of %s cell `%s' in module `%s' with constant driver: %s -> %s\n",
 | 
			
		||||
							cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_a), log_signal(new_a));
 | 
			
		||||
					cell->setPort(ID::A, sig_a = new_a);
 | 
			
		||||
					cell->parameters.at(ID(A_WIDTH)) = 1;
 | 
			
		||||
					cell->parameters.at(ID::A_WIDTH) = 1;
 | 
			
		||||
					did_something = true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -672,7 +672,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
					log_debug("Replacing port B of %s cell `%s' in module `%s' with constant driver: %s -> %s\n",
 | 
			
		||||
							cell->type.c_str(), cell->name.c_str(), module->name.c_str(), log_signal(sig_b), log_signal(new_b));
 | 
			
		||||
					cell->setPort(ID::B, sig_b = new_b);
 | 
			
		||||
					cell->parameters.at(ID(B_WIDTH)) = 1;
 | 
			
		||||
					cell->parameters.at(ID::B_WIDTH) = 1;
 | 
			
		||||
					did_something = true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -711,11 +711,11 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
			{
 | 
			
		||||
				RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
 | 
			
		||||
				RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
 | 
			
		||||
				RTLIL::SigBit sig_ci = assign_map(cell->getPort(ID(CI)));
 | 
			
		||||
				RTLIL::SigBit sig_bi = assign_map(cell->getPort(ID(BI)));
 | 
			
		||||
				RTLIL::SigSpec sig_x = cell->getPort(ID(X));
 | 
			
		||||
				RTLIL::SigBit sig_ci = assign_map(cell->getPort(ID::CI));
 | 
			
		||||
				RTLIL::SigBit sig_bi = assign_map(cell->getPort(ID::BI));
 | 
			
		||||
				RTLIL::SigSpec sig_x = cell->getPort(ID::X);
 | 
			
		||||
				RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
 | 
			
		||||
				RTLIL::SigSpec sig_co = cell->getPort(ID(CO));
 | 
			
		||||
				RTLIL::SigSpec sig_co = cell->getPort(ID::CO);
 | 
			
		||||
 | 
			
		||||
				bool sub = (sig_ci == State::S1 && sig_bi == State::S1);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -750,9 +750,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
					cover("opt.opt_expr.fine.$alu");
 | 
			
		||||
					cell->setPort(ID::A, sig_a.extract_end(i));
 | 
			
		||||
					cell->setPort(ID::B, sig_b.extract_end(i));
 | 
			
		||||
					cell->setPort(ID(X), sig_x.extract_end(i));
 | 
			
		||||
					cell->setPort(ID::X, sig_x.extract_end(i));
 | 
			
		||||
					cell->setPort(ID::Y, sig_y.extract_end(i));
 | 
			
		||||
					cell->setPort(ID(CO), sig_co.extract_end(i));
 | 
			
		||||
					cell->setPort(ID::CO, sig_co.extract_end(i));
 | 
			
		||||
					cell->fixup_parameters();
 | 
			
		||||
					did_something = true;
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -804,7 +804,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
				cover_list("opt.opt_expr.trim", "$shiftx", "$shift", cell->type.str());
 | 
			
		||||
				sig_a.remove(width, GetSize(sig_a)-width);
 | 
			
		||||
				cell->setPort(ID::A, sig_a);
 | 
			
		||||
				cell->setParam(ID(A_WIDTH), width);
 | 
			
		||||
				cell->setParam(ID::A_WIDTH, width);
 | 
			
		||||
				did_something = true;
 | 
			
		||||
				goto next_cell;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -817,13 +817,13 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
			goto next_cell;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (cell->type.in(ID($_MUX_), ID($mux)) && invert_map.count(assign_map(cell->getPort(ID(S)))) != 0) {
 | 
			
		||||
		if (cell->type.in(ID($_MUX_), ID($mux)) && invert_map.count(assign_map(cell->getPort(ID::S))) != 0) {
 | 
			
		||||
			cover_list("opt.opt_expr.invert.muxsel", "$_MUX_", "$mux", cell->type.str());
 | 
			
		||||
			log_debug("Optimizing away select inverter for %s cell `%s' in module `%s'.\n", log_id(cell->type), log_id(cell), log_id(module));
 | 
			
		||||
			RTLIL::SigSpec tmp = cell->getPort(ID::A);
 | 
			
		||||
			cell->setPort(ID::A, cell->getPort(ID::B));
 | 
			
		||||
			cell->setPort(ID::B, tmp);
 | 
			
		||||
			cell->setPort(ID(S), invert_map.at(assign_map(cell->getPort(ID(S)))));
 | 
			
		||||
			cell->setPort(ID::S, invert_map.at(assign_map(cell->getPort(ID::S))));
 | 
			
		||||
			did_something = true;
 | 
			
		||||
			goto next_cell;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -889,7 +889,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
 | 
			
		||||
		if (cell->type == ID($_MUX_)) {
 | 
			
		||||
			RTLIL::SigSpec input;
 | 
			
		||||
			input.append(cell->getPort(ID(S)));
 | 
			
		||||
			input.append(cell->getPort(ID::S));
 | 
			
		||||
			input.append(cell->getPort(ID::B));
 | 
			
		||||
			input.append(cell->getPort(ID::A));
 | 
			
		||||
			assign_map.apply(input);
 | 
			
		||||
| 
						 | 
				
			
			@ -903,7 +903,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
				cell->type = ID($_NOT_);
 | 
			
		||||
				cell->setPort(ID::A, input.extract(0, 1));
 | 
			
		||||
				cell->unsetPort(ID::B);
 | 
			
		||||
				cell->unsetPort(ID(S));
 | 
			
		||||
				cell->unsetPort(ID::S);
 | 
			
		||||
				goto next_cell;
 | 
			
		||||
			}
 | 
			
		||||
			if (input.match("11 ")) ACTION_DO_Y(1);
 | 
			
		||||
| 
						 | 
				
			
			@ -919,7 +919,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		if (cell->type.in(ID($_TBUF_), ID($tribuf))) {
 | 
			
		||||
			RTLIL::SigSpec input = cell->getPort(cell->type == ID($_TBUF_) ? ID(E) : ID(EN));
 | 
			
		||||
			RTLIL::SigSpec input = cell->getPort(cell->type == ID($_TBUF_) ? ID::E : ID::EN);
 | 
			
		||||
			RTLIL::SigSpec a = cell->getPort(ID::A);
 | 
			
		||||
			assign_map.apply(input);
 | 
			
		||||
			assign_map.apply(a);
 | 
			
		||||
| 
						 | 
				
			
			@ -940,10 +940,10 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
			RTLIL::SigSpec a = cell->getPort(ID::A);
 | 
			
		||||
			RTLIL::SigSpec b = cell->getPort(ID::B);
 | 
			
		||||
 | 
			
		||||
			if (cell->parameters[ID(A_WIDTH)].as_int() != cell->parameters[ID(B_WIDTH)].as_int()) {
 | 
			
		||||
				int width = max(cell->parameters[ID(A_WIDTH)].as_int(), cell->parameters[ID(B_WIDTH)].as_int());
 | 
			
		||||
				a.extend_u0(width, cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool());
 | 
			
		||||
				b.extend_u0(width, cell->parameters[ID(A_SIGNED)].as_bool() && cell->parameters[ID(B_SIGNED)].as_bool());
 | 
			
		||||
			if (cell->parameters[ID::A_WIDTH].as_int() != cell->parameters[ID::B_WIDTH].as_int()) {
 | 
			
		||||
				int width = max(cell->parameters[ID::A_WIDTH].as_int(), cell->parameters[ID::B_WIDTH].as_int());
 | 
			
		||||
				a.extend_u0(width, cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool());
 | 
			
		||||
				b.extend_u0(width, cell->parameters[ID::A_SIGNED].as_bool() && cell->parameters[ID::B_SIGNED].as_bool());
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			RTLIL::SigSpec new_a, new_b;
 | 
			
		||||
| 
						 | 
				
			
			@ -953,7 +953,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
				if (a[i].wire == NULL && b[i].wire == NULL && a[i] != b[i] && a[i].data <= RTLIL::State::S1 && b[i].data <= RTLIL::State::S1) {
 | 
			
		||||
					cover_list("opt.opt_expr.eqneq.isneq", "$eq", "$ne", "$eqx", "$nex", cell->type.str());
 | 
			
		||||
					RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type.in(ID($eq), ID($eqx)) ?  RTLIL::State::S0 : RTLIL::State::S1);
 | 
			
		||||
					new_y.extend_u0(cell->parameters[ID(Y_WIDTH)].as_int(), false);
 | 
			
		||||
					new_y.extend_u0(cell->parameters[ID::Y_WIDTH].as_int(), false);
 | 
			
		||||
					replace_cell(assign_map, module, cell, "isneq", ID::Y, new_y);
 | 
			
		||||
					goto next_cell;
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -966,7 +966,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
			if (new_a.size() == 0) {
 | 
			
		||||
				cover_list("opt.opt_expr.eqneq.empty", "$eq", "$ne", "$eqx", "$nex", cell->type.str());
 | 
			
		||||
				RTLIL::SigSpec new_y = RTLIL::SigSpec(cell->type.in(ID($eq), ID($eqx)) ?  RTLIL::State::S1 : RTLIL::State::S0);
 | 
			
		||||
				new_y.extend_u0(cell->parameters[ID(Y_WIDTH)].as_int(), false);
 | 
			
		||||
				new_y.extend_u0(cell->parameters[ID::Y_WIDTH].as_int(), false);
 | 
			
		||||
				replace_cell(assign_map, module, cell, "empty", ID::Y, new_y);
 | 
			
		||||
				goto next_cell;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -975,13 +975,13 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
				cover_list("opt.opt_expr.eqneq.resize", "$eq", "$ne", "$eqx", "$nex", cell->type.str());
 | 
			
		||||
				cell->setPort(ID::A, new_a);
 | 
			
		||||
				cell->setPort(ID::B, new_b);
 | 
			
		||||
				cell->parameters[ID(A_WIDTH)] = new_a.size();
 | 
			
		||||
				cell->parameters[ID(B_WIDTH)] = new_b.size();
 | 
			
		||||
				cell->parameters[ID::A_WIDTH] = new_a.size();
 | 
			
		||||
				cell->parameters[ID::B_WIDTH] = new_b.size();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (cell->type.in(ID($eq), ID($ne)) && cell->parameters[ID(Y_WIDTH)].as_int() == 1 &&
 | 
			
		||||
				cell->parameters[ID(A_WIDTH)].as_int() == 1 && cell->parameters[ID(B_WIDTH)].as_int() == 1)
 | 
			
		||||
		if (cell->type.in(ID($eq), ID($ne)) && cell->parameters[ID::Y_WIDTH].as_int() == 1 &&
 | 
			
		||||
				cell->parameters[ID::A_WIDTH].as_int() == 1 && cell->parameters[ID::B_WIDTH].as_int() == 1)
 | 
			
		||||
		{
 | 
			
		||||
			RTLIL::SigSpec a = assign_map(cell->getPort(ID::A));
 | 
			
		||||
			RTLIL::SigSpec b = assign_map(cell->getPort(ID::B));
 | 
			
		||||
| 
						 | 
				
			
			@ -1005,8 +1005,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
					cover_list("opt.opt_expr.eqneq.isnot", "$eq", "$ne", cell->type.str());
 | 
			
		||||
					log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module));
 | 
			
		||||
					cell->type = ID($not);
 | 
			
		||||
					cell->parameters.erase(ID(B_WIDTH));
 | 
			
		||||
					cell->parameters.erase(ID(B_SIGNED));
 | 
			
		||||
					cell->parameters.erase(ID::B_WIDTH);
 | 
			
		||||
					cell->parameters.erase(ID::B_SIGNED);
 | 
			
		||||
					cell->unsetPort(ID::B);
 | 
			
		||||
					did_something = true;
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -1023,29 +1023,29 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
			cell->type = cell->type == ID($eq) ? ID($logic_not) : ID($reduce_bool);
 | 
			
		||||
			if (assign_map(cell->getPort(ID::A)).is_fully_zero()) {
 | 
			
		||||
				cell->setPort(ID::A, cell->getPort(ID::B));
 | 
			
		||||
				cell->setParam(ID(A_SIGNED), cell->getParam(ID(B_SIGNED)));
 | 
			
		||||
				cell->setParam(ID(A_WIDTH), cell->getParam(ID(B_WIDTH)));
 | 
			
		||||
				cell->setParam(ID::A_SIGNED, cell->getParam(ID::B_SIGNED));
 | 
			
		||||
				cell->setParam(ID::A_WIDTH, cell->getParam(ID::B_WIDTH));
 | 
			
		||||
			}
 | 
			
		||||
			cell->unsetPort(ID::B);
 | 
			
		||||
			cell->unsetParam(ID(B_SIGNED));
 | 
			
		||||
			cell->unsetParam(ID(B_WIDTH));
 | 
			
		||||
			cell->unsetParam(ID::B_SIGNED);
 | 
			
		||||
			cell->unsetParam(ID::B_WIDTH);
 | 
			
		||||
			did_something = true;
 | 
			
		||||
			goto next_cell;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr), ID($shift), ID($shiftx)) && assign_map(cell->getPort(ID::B)).is_fully_const())
 | 
			
		||||
		{
 | 
			
		||||
			bool sign_ext = cell->type == ID($sshr) && cell->getParam(ID(A_SIGNED)).as_bool();
 | 
			
		||||
			int shift_bits = assign_map(cell->getPort(ID::B)).as_int(cell->type.in(ID($shift), ID($shiftx)) && cell->getParam(ID(B_SIGNED)).as_bool());
 | 
			
		||||
			bool sign_ext = cell->type == ID($sshr) && cell->getParam(ID::A_SIGNED).as_bool();
 | 
			
		||||
			int shift_bits = assign_map(cell->getPort(ID::B)).as_int(cell->type.in(ID($shift), ID($shiftx)) && cell->getParam(ID::B_SIGNED).as_bool());
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in(ID($shl), ID($sshl)))
 | 
			
		||||
				shift_bits *= -1;
 | 
			
		||||
 | 
			
		||||
			RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
 | 
			
		||||
			RTLIL::SigSpec sig_y(cell->type == ID($shiftx) ? RTLIL::State::Sx : RTLIL::State::S0, cell->getParam(ID(Y_WIDTH)).as_int());
 | 
			
		||||
			RTLIL::SigSpec sig_y(cell->type == ID($shiftx) ? RTLIL::State::Sx : RTLIL::State::S0, cell->getParam(ID::Y_WIDTH).as_int());
 | 
			
		||||
 | 
			
		||||
			if (GetSize(sig_a) < GetSize(sig_y))
 | 
			
		||||
				sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID(A_SIGNED)).as_bool());
 | 
			
		||||
				sig_a.extend_u0(GetSize(sig_y), cell->getParam(ID::A_SIGNED).as_bool());
 | 
			
		||||
 | 
			
		||||
			for (int i = 0; i < GetSize(sig_y); i++) {
 | 
			
		||||
				int idx = i + shift_bits;
 | 
			
		||||
| 
						 | 
				
			
			@ -1081,8 +1081,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
				bool sub = cell->type == ID($sub);
 | 
			
		||||
 | 
			
		||||
				if (cell->type == ID($alu)) {
 | 
			
		||||
					RTLIL::SigBit sig_ci = assign_map(cell->getPort(ID(CI)));
 | 
			
		||||
					RTLIL::SigBit sig_bi = assign_map(cell->getPort(ID(BI)));
 | 
			
		||||
					RTLIL::SigBit sig_ci = assign_map(cell->getPort(ID::CI));
 | 
			
		||||
					RTLIL::SigBit sig_bi = assign_map(cell->getPort(ID::BI));
 | 
			
		||||
 | 
			
		||||
					sub = (sig_ci == State::S1 && sig_bi == State::S1);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1112,10 +1112,10 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
				RTLIL::SigSpec a = assign_map(cell->getPort(ID::A));
 | 
			
		||||
				RTLIL::SigSpec b = assign_map(cell->getPort(ID::B));
 | 
			
		||||
 | 
			
		||||
				if (a.is_fully_const() && is_one_or_minus_one(a.as_const(), cell->getParam(ID(A_SIGNED)).as_bool(), arith_inverse))
 | 
			
		||||
				if (a.is_fully_const() && is_one_or_minus_one(a.as_const(), cell->getParam(ID::A_SIGNED).as_bool(), arith_inverse))
 | 
			
		||||
					identity_wrt_b = true;
 | 
			
		||||
				else
 | 
			
		||||
				if (b.is_fully_const() && is_one_or_minus_one(b.as_const(), cell->getParam(ID(B_SIGNED)).as_bool(), arith_inverse))
 | 
			
		||||
				if (b.is_fully_const() && is_one_or_minus_one(b.as_const(), cell->getParam(ID::B_SIGNED).as_bool(), arith_inverse))
 | 
			
		||||
					identity_wrt_a = true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1138,25 +1138,25 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
					cell->type.c_str(), cell->name.c_str(), module->name.c_str(), identity_wrt_a ? 'A' : 'B');
 | 
			
		||||
 | 
			
		||||
				if (cell->type == ID($alu)) {
 | 
			
		||||
					int y_width = GetSize(cell->getPort(ID(Y)));
 | 
			
		||||
					module->connect(cell->getPort(ID(X)), RTLIL::Const(State::S0, y_width));
 | 
			
		||||
					module->connect(cell->getPort(ID(CO)), RTLIL::Const(State::S0, y_width));
 | 
			
		||||
					cell->unsetPort(ID(BI));
 | 
			
		||||
					cell->unsetPort(ID(CI));
 | 
			
		||||
					cell->unsetPort(ID(X));
 | 
			
		||||
					cell->unsetPort(ID(CO));
 | 
			
		||||
					int y_width = GetSize(cell->getPort(ID::Y));
 | 
			
		||||
					module->connect(cell->getPort(ID::X), RTLIL::Const(State::S0, y_width));
 | 
			
		||||
					module->connect(cell->getPort(ID::CO), RTLIL::Const(State::S0, y_width));
 | 
			
		||||
					cell->unsetPort(ID::BI);
 | 
			
		||||
					cell->unsetPort(ID::CI);
 | 
			
		||||
					cell->unsetPort(ID::X);
 | 
			
		||||
					cell->unsetPort(ID::CO);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (!identity_wrt_a) {
 | 
			
		||||
					cell->setPort(ID::A, cell->getPort(ID::B));
 | 
			
		||||
					cell->setParam(ID(A_WIDTH), cell->getParam(ID(B_WIDTH)));
 | 
			
		||||
					cell->setParam(ID(A_SIGNED), cell->getParam(ID(B_SIGNED)));
 | 
			
		||||
					cell->setParam(ID::A_WIDTH, cell->getParam(ID::B_WIDTH));
 | 
			
		||||
					cell->setParam(ID::A_SIGNED, cell->getParam(ID::B_SIGNED));
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				cell->type = arith_inverse ? ID($neg) : ID($pos);
 | 
			
		||||
				cell->unsetPort(ID::B);
 | 
			
		||||
				cell->parameters.erase(ID(B_WIDTH));
 | 
			
		||||
				cell->parameters.erase(ID(B_SIGNED));
 | 
			
		||||
				cell->parameters.erase(ID::B_WIDTH);
 | 
			
		||||
				cell->parameters.erase(ID::B_SIGNED);
 | 
			
		||||
				cell->check();
 | 
			
		||||
 | 
			
		||||
				did_something = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -1167,7 +1167,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
		if (mux_bool && cell->type.in(ID($mux), ID($_MUX_)) &&
 | 
			
		||||
				cell->getPort(ID::A) == State::S0 && cell->getPort(ID::B) == State::S1) {
 | 
			
		||||
			cover_list("opt.opt_expr.mux_bool", "$mux", "$_MUX_", cell->type.str());
 | 
			
		||||
			replace_cell(assign_map, module, cell, "mux_bool", ID::Y, cell->getPort(ID(S)));
 | 
			
		||||
			replace_cell(assign_map, module, cell, "mux_bool", ID::Y, cell->getPort(ID::S));
 | 
			
		||||
			goto next_cell;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1175,15 +1175,15 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
				cell->getPort(ID::A) == State::S1 && cell->getPort(ID::B) == State::S0) {
 | 
			
		||||
			cover_list("opt.opt_expr.mux_invert", "$mux", "$_MUX_", cell->type.str());
 | 
			
		||||
			log_debug("Replacing %s cell `%s' in module `%s' with inverter.\n", log_id(cell->type), log_id(cell), log_id(module));
 | 
			
		||||
			cell->setPort(ID::A, cell->getPort(ID(S)));
 | 
			
		||||
			cell->setPort(ID::A, cell->getPort(ID::S));
 | 
			
		||||
			cell->unsetPort(ID::B);
 | 
			
		||||
			cell->unsetPort(ID(S));
 | 
			
		||||
			cell->unsetPort(ID::S);
 | 
			
		||||
			if (cell->type == ID($mux)) {
 | 
			
		||||
				Const width = cell->parameters[ID(WIDTH)];
 | 
			
		||||
				cell->parameters[ID(A_WIDTH)] = width;
 | 
			
		||||
				cell->parameters[ID(Y_WIDTH)] = width;
 | 
			
		||||
				cell->parameters[ID(A_SIGNED)] = 0;
 | 
			
		||||
				cell->parameters.erase(ID(WIDTH));
 | 
			
		||||
				Const width = cell->parameters[ID::WIDTH];
 | 
			
		||||
				cell->parameters[ID::A_WIDTH] = width;
 | 
			
		||||
				cell->parameters[ID::Y_WIDTH] = width;
 | 
			
		||||
				cell->parameters[ID::A_SIGNED] = 0;
 | 
			
		||||
				cell->parameters.erase(ID::WIDTH);
 | 
			
		||||
				cell->type = ID($not);
 | 
			
		||||
			} else
 | 
			
		||||
				cell->type = ID($_NOT_);
 | 
			
		||||
| 
						 | 
				
			
			@ -1194,16 +1194,16 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
		if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::A) == State::S0) {
 | 
			
		||||
			cover_list("opt.opt_expr.mux_and", "$mux", "$_MUX_", cell->type.str());
 | 
			
		||||
			log_debug("Replacing %s cell `%s' in module `%s' with and-gate.\n", log_id(cell->type), log_id(cell), log_id(module));
 | 
			
		||||
			cell->setPort(ID::A, cell->getPort(ID(S)));
 | 
			
		||||
			cell->unsetPort(ID(S));
 | 
			
		||||
			cell->setPort(ID::A, cell->getPort(ID::S));
 | 
			
		||||
			cell->unsetPort(ID::S);
 | 
			
		||||
			if (cell->type == ID($mux)) {
 | 
			
		||||
				Const width = cell->parameters[ID(WIDTH)];
 | 
			
		||||
				cell->parameters[ID(A_WIDTH)] = width;
 | 
			
		||||
				cell->parameters[ID(B_WIDTH)] = width;
 | 
			
		||||
				cell->parameters[ID(Y_WIDTH)] = width;
 | 
			
		||||
				cell->parameters[ID(A_SIGNED)] = 0;
 | 
			
		||||
				cell->parameters[ID(B_SIGNED)] = 0;
 | 
			
		||||
				cell->parameters.erase(ID(WIDTH));
 | 
			
		||||
				Const width = cell->parameters[ID::WIDTH];
 | 
			
		||||
				cell->parameters[ID::A_WIDTH] = width;
 | 
			
		||||
				cell->parameters[ID::B_WIDTH] = width;
 | 
			
		||||
				cell->parameters[ID::Y_WIDTH] = width;
 | 
			
		||||
				cell->parameters[ID::A_SIGNED] = 0;
 | 
			
		||||
				cell->parameters[ID::B_SIGNED] = 0;
 | 
			
		||||
				cell->parameters.erase(ID::WIDTH);
 | 
			
		||||
				cell->type = ID($and);
 | 
			
		||||
			} else
 | 
			
		||||
				cell->type = ID($_AND_);
 | 
			
		||||
| 
						 | 
				
			
			@ -1214,16 +1214,16 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
		if (consume_x && mux_bool && cell->type.in(ID($mux), ID($_MUX_)) && cell->getPort(ID::B) == State::S1) {
 | 
			
		||||
			cover_list("opt.opt_expr.mux_or", "$mux", "$_MUX_", cell->type.str());
 | 
			
		||||
			log_debug("Replacing %s cell `%s' in module `%s' with or-gate.\n", log_id(cell->type), log_id(cell), log_id(module));
 | 
			
		||||
			cell->setPort(ID::B, cell->getPort(ID(S)));
 | 
			
		||||
			cell->unsetPort(ID(S));
 | 
			
		||||
			cell->setPort(ID::B, cell->getPort(ID::S));
 | 
			
		||||
			cell->unsetPort(ID::S);
 | 
			
		||||
			if (cell->type == ID($mux)) {
 | 
			
		||||
				Const width = cell->parameters[ID(WIDTH)];
 | 
			
		||||
				cell->parameters[ID(A_WIDTH)] = width;
 | 
			
		||||
				cell->parameters[ID(B_WIDTH)] = width;
 | 
			
		||||
				cell->parameters[ID(Y_WIDTH)] = width;
 | 
			
		||||
				cell->parameters[ID(A_SIGNED)] = 0;
 | 
			
		||||
				cell->parameters[ID(B_SIGNED)] = 0;
 | 
			
		||||
				cell->parameters.erase(ID(WIDTH));
 | 
			
		||||
				Const width = cell->parameters[ID::WIDTH];
 | 
			
		||||
				cell->parameters[ID::A_WIDTH] = width;
 | 
			
		||||
				cell->parameters[ID::B_WIDTH] = width;
 | 
			
		||||
				cell->parameters[ID::Y_WIDTH] = width;
 | 
			
		||||
				cell->parameters[ID::A_SIGNED] = 0;
 | 
			
		||||
				cell->parameters[ID::B_SIGNED] = 0;
 | 
			
		||||
				cell->parameters.erase(ID::WIDTH);
 | 
			
		||||
				cell->type = ID($or);
 | 
			
		||||
			} else
 | 
			
		||||
				cell->type = ID($_OR_);
 | 
			
		||||
| 
						 | 
				
			
			@ -1235,14 +1235,14 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
			RTLIL::SigSpec new_a, new_b, new_s;
 | 
			
		||||
			int width = GetSize(cell->getPort(ID::A));
 | 
			
		||||
			if ((cell->getPort(ID::A).is_fully_undef() && cell->getPort(ID::B).is_fully_undef()) ||
 | 
			
		||||
					cell->getPort(ID(S)).is_fully_undef()) {
 | 
			
		||||
					cell->getPort(ID::S).is_fully_undef()) {
 | 
			
		||||
				cover_list("opt.opt_expr.mux_undef", "$mux", "$pmux", cell->type.str());
 | 
			
		||||
				replace_cell(assign_map, module, cell, "mux_undef", ID::Y, cell->getPort(ID::A));
 | 
			
		||||
				goto next_cell;
 | 
			
		||||
			}
 | 
			
		||||
			for (int i = 0; i < cell->getPort(ID(S)).size(); i++) {
 | 
			
		||||
			for (int i = 0; i < cell->getPort(ID::S).size(); i++) {
 | 
			
		||||
				RTLIL::SigSpec old_b = cell->getPort(ID::B).extract(i*width, width);
 | 
			
		||||
				RTLIL::SigSpec old_s = cell->getPort(ID(S)).extract(i, 1);
 | 
			
		||||
				RTLIL::SigSpec old_s = cell->getPort(ID::S).extract(i, 1);
 | 
			
		||||
				if (old_b.is_fully_undef() || old_s.is_fully_undef())
 | 
			
		||||
					continue;
 | 
			
		||||
				new_b.append(old_b);
 | 
			
		||||
| 
						 | 
				
			
			@ -1264,48 +1264,48 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
				replace_cell(assign_map, module, cell, "mux_sel01", ID::Y, new_s);
 | 
			
		||||
				goto next_cell;
 | 
			
		||||
			}
 | 
			
		||||
			if (cell->getPort(ID(S)).size() != new_s.size()) {
 | 
			
		||||
			if (cell->getPort(ID::S).size() != new_s.size()) {
 | 
			
		||||
				cover_list("opt.opt_expr.mux_reduce", "$mux", "$pmux", cell->type.str());
 | 
			
		||||
				log_debug("Optimized away %d select inputs of %s cell `%s' in module `%s'.\n",
 | 
			
		||||
						GetSize(cell->getPort(ID(S))) - GetSize(new_s), log_id(cell->type), log_id(cell), log_id(module));
 | 
			
		||||
						GetSize(cell->getPort(ID::S)) - GetSize(new_s), log_id(cell->type), log_id(cell), log_id(module));
 | 
			
		||||
				cell->setPort(ID::A, new_a);
 | 
			
		||||
				cell->setPort(ID::B, new_b);
 | 
			
		||||
				cell->setPort(ID(S), new_s);
 | 
			
		||||
				cell->setPort(ID::S, new_s);
 | 
			
		||||
				if (new_s.size() > 1) {
 | 
			
		||||
					cell->type = ID($pmux);
 | 
			
		||||
					cell->parameters[ID(S_WIDTH)] = new_s.size();
 | 
			
		||||
					cell->parameters[ID::S_WIDTH] = new_s.size();
 | 
			
		||||
				} else {
 | 
			
		||||
					cell->type = ID($mux);
 | 
			
		||||
					cell->parameters.erase(ID(S_WIDTH));
 | 
			
		||||
					cell->parameters.erase(ID::S_WIDTH);
 | 
			
		||||
				}
 | 
			
		||||
				did_something = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
#define FOLD_1ARG_CELL(_t) \
 | 
			
		||||
		if (cell->type == "$" #_t) { \
 | 
			
		||||
		if (cell->type == ID($##_t)) { \
 | 
			
		||||
			RTLIL::SigSpec a = cell->getPort(ID::A); \
 | 
			
		||||
			assign_map.apply(a); \
 | 
			
		||||
			if (a.is_fully_const()) { \
 | 
			
		||||
				RTLIL::Const dummy_arg(RTLIL::State::S0, 1); \
 | 
			
		||||
				RTLIL::SigSpec y(RTLIL::const_ ## _t(a.as_const(), dummy_arg, \
 | 
			
		||||
						cell->parameters[ID(A_SIGNED)].as_bool(), false, \
 | 
			
		||||
						cell->parameters[ID(Y_WIDTH)].as_int())); \
 | 
			
		||||
						cell->parameters[ID::A_SIGNED].as_bool(), false, \
 | 
			
		||||
						cell->parameters[ID::Y_WIDTH].as_int())); \
 | 
			
		||||
				cover("opt.opt_expr.const.$" #_t); \
 | 
			
		||||
				replace_cell(assign_map, module, cell, stringf("%s", log_signal(a)), ID::Y, y); \
 | 
			
		||||
				goto next_cell; \
 | 
			
		||||
			} \
 | 
			
		||||
		}
 | 
			
		||||
#define FOLD_2ARG_CELL(_t) \
 | 
			
		||||
		if (cell->type == "$" #_t) { \
 | 
			
		||||
		if (cell->type == ID($##_t)) { \
 | 
			
		||||
			RTLIL::SigSpec a = cell->getPort(ID::A); \
 | 
			
		||||
			RTLIL::SigSpec b = cell->getPort(ID::B); \
 | 
			
		||||
			assign_map.apply(a), assign_map.apply(b); \
 | 
			
		||||
			if (a.is_fully_const() && b.is_fully_const()) { \
 | 
			
		||||
				RTLIL::SigSpec y(RTLIL::const_ ## _t(a.as_const(), b.as_const(), \
 | 
			
		||||
						cell->parameters[ID(A_SIGNED)].as_bool(), \
 | 
			
		||||
						cell->parameters[ID(B_SIGNED)].as_bool(), \
 | 
			
		||||
						cell->parameters[ID(Y_WIDTH)].as_int())); \
 | 
			
		||||
						cell->parameters[ID::A_SIGNED].as_bool(), \
 | 
			
		||||
						cell->parameters[ID::B_SIGNED].as_bool(), \
 | 
			
		||||
						cell->parameters[ID::Y_WIDTH].as_int())); \
 | 
			
		||||
				cover("opt.opt_expr.const.$" #_t); \
 | 
			
		||||
				replace_cell(assign_map, module, cell, stringf("%s, %s", log_signal(a), log_signal(b)), ID::Y, y); \
 | 
			
		||||
				goto next_cell; \
 | 
			
		||||
| 
						 | 
				
			
			@ -1354,7 +1354,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
 | 
			
		||||
		// be very conservative with optimizing $mux cells as we do not want to break mux trees
 | 
			
		||||
		if (cell->type == ID($mux)) {
 | 
			
		||||
			RTLIL::SigSpec input = assign_map(cell->getPort(ID(S)));
 | 
			
		||||
			RTLIL::SigSpec input = assign_map(cell->getPort(ID::S));
 | 
			
		||||
			RTLIL::SigSpec inA = assign_map(cell->getPort(ID::A));
 | 
			
		||||
			RTLIL::SigSpec inB = assign_map(cell->getPort(ID::B));
 | 
			
		||||
			if (input.is_fully_const())
 | 
			
		||||
| 
						 | 
				
			
			@ -1365,8 +1365,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
 | 
			
		||||
		if (!keepdc && cell->type == ID($mul))
 | 
			
		||||
		{
 | 
			
		||||
			bool a_signed = cell->parameters[ID(A_SIGNED)].as_bool();
 | 
			
		||||
			bool b_signed = cell->parameters[ID(B_SIGNED)].as_bool();
 | 
			
		||||
			bool a_signed = cell->parameters[ID::A_SIGNED].as_bool();
 | 
			
		||||
			bool b_signed = cell->parameters[ID::B_SIGNED].as_bool();
 | 
			
		||||
			bool swapped_ab = false;
 | 
			
		||||
 | 
			
		||||
			RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
 | 
			
		||||
| 
						 | 
				
			
			@ -1407,8 +1407,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
 | 
			
		||||
						if (!swapped_ab) {
 | 
			
		||||
							cell->setPort(ID::A, cell->getPort(ID::B));
 | 
			
		||||
							cell->parameters.at(ID(A_WIDTH)) = cell->parameters.at(ID(B_WIDTH));
 | 
			
		||||
							cell->parameters.at(ID(A_SIGNED)) = cell->parameters.at(ID(B_SIGNED));
 | 
			
		||||
							cell->parameters.at(ID::A_WIDTH) = cell->parameters.at(ID::B_WIDTH);
 | 
			
		||||
							cell->parameters.at(ID::A_SIGNED) = cell->parameters.at(ID::B_SIGNED);
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
						std::vector<RTLIL::SigBit> new_b = RTLIL::SigSpec(i, 6);
 | 
			
		||||
| 
						 | 
				
			
			@ -1417,8 +1417,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
							new_b.pop_back();
 | 
			
		||||
 | 
			
		||||
						cell->type = ID($shl);
 | 
			
		||||
						cell->parameters[ID(B_WIDTH)] = GetSize(new_b);
 | 
			
		||||
						cell->parameters[ID(B_SIGNED)] = false;
 | 
			
		||||
						cell->parameters[ID::B_WIDTH] = GetSize(new_b);
 | 
			
		||||
						cell->parameters[ID::B_SIGNED] = false;
 | 
			
		||||
						cell->setPort(ID::B, new_b);
 | 
			
		||||
						cell->check();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1430,7 +1430,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
 | 
			
		||||
		if (!keepdc && cell->type.in(ID($div), ID($mod)))
 | 
			
		||||
		{
 | 
			
		||||
			bool b_signed = cell->parameters[ID(B_SIGNED)].as_bool();
 | 
			
		||||
			bool b_signed = cell->parameters[ID::B_SIGNED].as_bool();
 | 
			
		||||
			SigSpec sig_b = assign_map(cell->getPort(ID::B));
 | 
			
		||||
			SigSpec sig_y = assign_map(cell->getPort(ID::Y));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1468,8 +1468,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
								new_b.pop_back();
 | 
			
		||||
 | 
			
		||||
							cell->type = ID($shr);
 | 
			
		||||
							cell->parameters[ID(B_WIDTH)] = GetSize(new_b);
 | 
			
		||||
							cell->parameters[ID(B_SIGNED)] = false;
 | 
			
		||||
							cell->parameters[ID::B_WIDTH] = GetSize(new_b);
 | 
			
		||||
							cell->parameters[ID::B_SIGNED] = false;
 | 
			
		||||
							cell->setPort(ID::B, new_b);
 | 
			
		||||
							cell->check();
 | 
			
		||||
						}
 | 
			
		||||
| 
						 | 
				
			
			@ -1486,7 +1486,7 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
								new_b.push_back(State::S0);
 | 
			
		||||
 | 
			
		||||
							cell->type = ID($and);
 | 
			
		||||
							cell->parameters[ID(B_WIDTH)] = GetSize(new_b);
 | 
			
		||||
							cell->parameters[ID::B_WIDTH] = GetSize(new_b);
 | 
			
		||||
							cell->setPort(ID::B, new_b);
 | 
			
		||||
							cell->check();
 | 
			
		||||
						}
 | 
			
		||||
| 
						 | 
				
			
			@ -1507,10 +1507,10 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
			contradiction_cache.promote(State::S0);
 | 
			
		||||
			contradiction_cache.promote(State::S1);
 | 
			
		||||
 | 
			
		||||
			int a_width = cell->getParam(ID(A_WIDTH)).as_int();
 | 
			
		||||
			int b_width = cell->getParam(ID(B_WIDTH)).as_int();
 | 
			
		||||
			int a_width = cell->getParam(ID::A_WIDTH).as_int();
 | 
			
		||||
			int b_width = cell->getParam(ID::B_WIDTH).as_int();
 | 
			
		||||
 | 
			
		||||
			bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
 | 
			
		||||
			bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
 | 
			
		||||
			int width = is_signed ? std::min(a_width, b_width) : std::max(a_width, b_width);
 | 
			
		||||
 | 
			
		||||
			SigSpec sig_a = cell->getPort(ID::A);
 | 
			
		||||
| 
						 | 
				
			
			@ -1564,8 +1564,8 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
 | 
			
		||||
				cell->setPort(ID::A, sig_a);
 | 
			
		||||
				cell->setPort(ID::B, sig_b);
 | 
			
		||||
				cell->setParam(ID(A_WIDTH), GetSize(sig_a));
 | 
			
		||||
				cell->setParam(ID(B_WIDTH), GetSize(sig_b));
 | 
			
		||||
				cell->setParam(ID::A_WIDTH, GetSize(sig_a));
 | 
			
		||||
				cell->setParam(ID::B_WIDTH, GetSize(sig_b));
 | 
			
		||||
 | 
			
		||||
				did_something = true;
 | 
			
		||||
				goto next_cell;
 | 
			
		||||
| 
						 | 
				
			
			@ -1578,9 +1578,9 @@ void replace_const_cells(RTLIL::Design *design, RTLIL::Module *module, bool cons
 | 
			
		|||
			IdString cmp_type = cell->type;
 | 
			
		||||
			SigSpec var_sig = cell->getPort(ID::A);
 | 
			
		||||
			SigSpec const_sig = cell->getPort(ID::B);
 | 
			
		||||
			int var_width = cell->parameters[ID(A_WIDTH)].as_int();
 | 
			
		||||
			int const_width = cell->parameters[ID(B_WIDTH)].as_int();
 | 
			
		||||
			bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
 | 
			
		||||
			int var_width = cell->parameters[ID::A_WIDTH].as_int();
 | 
			
		||||
			int const_width = cell->parameters[ID::B_WIDTH].as_int();
 | 
			
		||||
			bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
 | 
			
		||||
 | 
			
		||||
			if (!const_sig.is_fully_const())
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,8 +41,8 @@ struct OptLutWorker
 | 
			
		|||
	bool evaluate_lut(RTLIL::Cell *lut, dict<SigBit, bool> inputs)
 | 
			
		||||
	{
 | 
			
		||||
		SigSpec lut_input = sigmap(lut->getPort(ID::A));
 | 
			
		||||
		int lut_width = lut->getParam(ID(WIDTH)).as_int();
 | 
			
		||||
		Const lut_table = lut->getParam(ID(LUT));
 | 
			
		||||
		int lut_width = lut->getParam(ID::WIDTH).as_int();
 | 
			
		||||
		Const lut_table = lut->getParam(ID::LUT);
 | 
			
		||||
		int lut_index = 0;
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < lut_width; i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -107,7 +107,7 @@ struct OptLutWorker
 | 
			
		|||
				if (lut_output.wire->get_bool_attribute(ID::keep))
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				int lut_width = cell->getParam(ID(WIDTH)).as_int();
 | 
			
		||||
				int lut_width = cell->getParam(ID::WIDTH).as_int();
 | 
			
		||||
				SigSpec lut_input = cell->getPort(ID::A);
 | 
			
		||||
				int lut_arity = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -305,7 +305,7 @@ struct OptLutWorker
 | 
			
		|||
			auto lutA = worklist.pop();
 | 
			
		||||
			SigSpec lutA_input = sigmap(lutA->getPort(ID::A));
 | 
			
		||||
			SigSpec lutA_output = sigmap(lutA->getPort(ID::Y)[0]);
 | 
			
		||||
			int lutA_width = lutA->getParam(ID(WIDTH)).as_int();
 | 
			
		||||
			int lutA_width = lutA->getParam(ID::WIDTH).as_int();
 | 
			
		||||
			int lutA_arity = luts_arity[lutA];
 | 
			
		||||
			pool<int> &lutA_dlogic_inputs = luts_dlogic_inputs[lutA];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -323,7 +323,7 @@ struct OptLutWorker
 | 
			
		|||
					auto lutB = port.cell;
 | 
			
		||||
					SigSpec lutB_input = sigmap(lutB->getPort(ID::A));
 | 
			
		||||
					SigSpec lutB_output = sigmap(lutB->getPort(ID::Y)[0]);
 | 
			
		||||
					int lutB_width = lutB->getParam(ID(WIDTH)).as_int();
 | 
			
		||||
					int lutB_width = lutB->getParam(ID::WIDTH).as_int();
 | 
			
		||||
					int lutB_arity = luts_arity[lutB];
 | 
			
		||||
					pool<int> &lutB_dlogic_inputs = luts_dlogic_inputs[lutB];
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -372,7 +372,7 @@ struct OptLutWorker
 | 
			
		|||
						log_debug("  Not combining LUTs into cell A (combined LUT wider than cell A).\n");
 | 
			
		||||
					else if (lutB_dlogic_inputs.size() > 0)
 | 
			
		||||
						log_debug("  Not combining LUTs into cell A (cell B is connected to dedicated logic).\n");
 | 
			
		||||
					else if (lutB->get_bool_attribute(ID(lut_keep)))
 | 
			
		||||
					else if (lutB->get_bool_attribute(ID::lut_keep))
 | 
			
		||||
						log_debug("  Not combining LUTs into cell A (cell B has attribute \\lut_keep).\n");
 | 
			
		||||
					else
 | 
			
		||||
						combine_mask |= COMBINE_A;
 | 
			
		||||
| 
						 | 
				
			
			@ -380,7 +380,7 @@ struct OptLutWorker
 | 
			
		|||
						log_debug("  Not combining LUTs into cell B (combined LUT wider than cell B).\n");
 | 
			
		||||
					else if (lutA_dlogic_inputs.size() > 0)
 | 
			
		||||
						log_debug("  Not combining LUTs into cell B (cell A is connected to dedicated logic).\n");
 | 
			
		||||
					else if (lutA->get_bool_attribute(ID(lut_keep)))
 | 
			
		||||
					else if (lutA->get_bool_attribute(ID::lut_keep))
 | 
			
		||||
						log_debug("  Not combining LUTs into cell B (cell A has attribute \\lut_keep).\n");
 | 
			
		||||
					else
 | 
			
		||||
						combine_mask |= COMBINE_B;
 | 
			
		||||
| 
						 | 
				
			
			@ -440,7 +440,7 @@ struct OptLutWorker
 | 
			
		|||
							lutR_unique.insert(bit);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					int lutM_width = lutM->getParam(ID(WIDTH)).as_int();
 | 
			
		||||
					int lutM_width = lutM->getParam(ID::WIDTH).as_int();
 | 
			
		||||
					SigSpec lutM_input = sigmap(lutM->getPort(ID::A));
 | 
			
		||||
					std::vector<SigBit> lutM_new_inputs;
 | 
			
		||||
					for (int i = 0; i < lutM_width; i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -482,11 +482,11 @@ struct OptLutWorker
 | 
			
		|||
						lutM_new_table[eval] = (RTLIL::State) evaluate_lut(lutB, eval_inputs);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					log_debug("  Cell A truth table: %s.\n", lutA->getParam(ID(LUT)).as_string().c_str());
 | 
			
		||||
					log_debug("  Cell B truth table: %s.\n", lutB->getParam(ID(LUT)).as_string().c_str());
 | 
			
		||||
					log_debug("  Cell A truth table: %s.\n", lutA->getParam(ID::LUT).as_string().c_str());
 | 
			
		||||
					log_debug("  Cell B truth table: %s.\n", lutB->getParam(ID::LUT).as_string().c_str());
 | 
			
		||||
					log_debug("  Merged truth table: %s.\n", lutM_new_table.as_string().c_str());
 | 
			
		||||
 | 
			
		||||
					lutM->setParam(ID(LUT), lutM_new_table);
 | 
			
		||||
					lutM->setParam(ID::LUT, lutM_new_table);
 | 
			
		||||
					lutM->setPort(ID::A, lutM_new_inputs);
 | 
			
		||||
					lutM->setPort(ID::Y, lutB_output);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -80,7 +80,7 @@ struct OptLutInsPass : public Pass {
 | 
			
		|||
						continue;
 | 
			
		||||
					inputs = cell->getPort(ID::A).bits();
 | 
			
		||||
					output = cell->getPort(ID::Y);
 | 
			
		||||
					lut = cell->getParam(ID(LUT));
 | 
			
		||||
					lut = cell->getParam(ID::LUT);
 | 
			
		||||
				} else if (techname == "xilinx" || techname == "gowin") {
 | 
			
		||||
					if (cell->type == ID(LUT1)) {
 | 
			
		||||
						inputs = {
 | 
			
		||||
| 
						 | 
				
			
			@ -125,20 +125,20 @@ struct OptLutInsPass : public Pass {
 | 
			
		|||
						// Not a LUT.
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
					lut = cell->getParam(ID(INIT));
 | 
			
		||||
					lut = cell->getParam(ID::INIT);
 | 
			
		||||
					if (techname == "xilinx")
 | 
			
		||||
						output = cell->getPort(ID(O));
 | 
			
		||||
						output = cell->getPort(ID::O);
 | 
			
		||||
					else
 | 
			
		||||
						output = cell->getPort(ID(F));
 | 
			
		||||
						output = cell->getPort(ID::F);
 | 
			
		||||
				} else if (techname == "ecp5") {
 | 
			
		||||
					if (cell->type == ID(LUT4)) {
 | 
			
		||||
						inputs = {
 | 
			
		||||
							cell->getPort(ID::A),
 | 
			
		||||
							cell->getPort(ID::B),
 | 
			
		||||
							cell->getPort(ID(C)),
 | 
			
		||||
							cell->getPort(ID(D)),
 | 
			
		||||
							cell->getPort(ID::C),
 | 
			
		||||
							cell->getPort(ID::D),
 | 
			
		||||
						};
 | 
			
		||||
						lut = cell->getParam(ID(INIT));
 | 
			
		||||
						lut = cell->getParam(ID::INIT);
 | 
			
		||||
						output = cell->getPort(ID(Z));
 | 
			
		||||
						ignore_const = true;
 | 
			
		||||
					} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -217,19 +217,19 @@ struct OptLutInsPass : public Pass {
 | 
			
		|||
					module->connect(output, new_lut[0]);
 | 
			
		||||
				} else {
 | 
			
		||||
					if (techname == "") {
 | 
			
		||||
						cell->setParam(ID(LUT), new_lut);
 | 
			
		||||
						cell->setParam(ID(WIDTH), GetSize(new_inputs));
 | 
			
		||||
						cell->setParam(ID::LUT, new_lut);
 | 
			
		||||
						cell->setParam(ID::WIDTH, GetSize(new_inputs));
 | 
			
		||||
						cell->setPort(ID::A, new_inputs);
 | 
			
		||||
					} else if (techname == "ecp5") {
 | 
			
		||||
						log_assert(GetSize(new_inputs) == 4);
 | 
			
		||||
						cell->setParam(ID(INIT), new_lut);
 | 
			
		||||
						cell->setParam(ID::INIT, new_lut);
 | 
			
		||||
						cell->setPort(ID::A, new_inputs[0]);
 | 
			
		||||
						cell->setPort(ID::B, new_inputs[1]);
 | 
			
		||||
						cell->setPort(ID(C), new_inputs[2]);
 | 
			
		||||
						cell->setPort(ID(D), new_inputs[3]);
 | 
			
		||||
						cell->setPort(ID::C, new_inputs[2]);
 | 
			
		||||
						cell->setPort(ID::D, new_inputs[3]);
 | 
			
		||||
					} else {
 | 
			
		||||
						// xilinx, gowin
 | 
			
		||||
						cell->setParam(ID(INIT), new_lut);
 | 
			
		||||
						cell->setParam(ID::INIT, new_lut);
 | 
			
		||||
						if (techname == "xilinx")
 | 
			
		||||
							log_assert(GetSize(new_inputs) <= 6);
 | 
			
		||||
						else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,17 +45,17 @@ struct OptMemWorker
 | 
			
		|||
		for (auto cell : module->cells())
 | 
			
		||||
		{
 | 
			
		||||
			if (cell->type == ID($memrd)) {
 | 
			
		||||
				IdString id = cell->getParam(ID(MEMID)).decode_string();
 | 
			
		||||
				IdString id = cell->getParam(ID::MEMID).decode_string();
 | 
			
		||||
				memrd.at(id).push_back(cell->name);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cell->type == ID($memwr)) {
 | 
			
		||||
				IdString id = cell->getParam(ID(MEMID)).decode_string();
 | 
			
		||||
				IdString id = cell->getParam(ID::MEMID).decode_string();
 | 
			
		||||
				memwr.at(id).push_back(cell->name);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cell->type == ID($meminit)) {
 | 
			
		||||
				IdString id = cell->getParam(ID(MEMID)).decode_string();
 | 
			
		||||
				IdString id = cell->getParam(ID::MEMID).decode_string();
 | 
			
		||||
				meminit.at(id).push_back(cell->name);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,7 +44,7 @@ struct OptMergeWorker
 | 
			
		|||
 | 
			
		||||
	static void sort_pmux_conn(dict<RTLIL::IdString, RTLIL::SigSpec> &conn)
 | 
			
		||||
	{
 | 
			
		||||
		SigSpec sig_s = conn.at(ID(S));
 | 
			
		||||
		SigSpec sig_s = conn.at(ID::S);
 | 
			
		||||
		SigSpec sig_b = conn.at(ID::B);
 | 
			
		||||
 | 
			
		||||
		int s_width = GetSize(sig_s);
 | 
			
		||||
| 
						 | 
				
			
			@ -56,11 +56,11 @@ struct OptMergeWorker
 | 
			
		|||
 | 
			
		||||
		std::sort(sb_pairs.begin(), sb_pairs.end());
 | 
			
		||||
 | 
			
		||||
		conn[ID(S)] = SigSpec();
 | 
			
		||||
		conn[ID::S] = SigSpec();
 | 
			
		||||
		conn[ID::B] = SigSpec();
 | 
			
		||||
 | 
			
		||||
		for (auto &it : sb_pairs) {
 | 
			
		||||
			conn[ID(S)].append(it.first);
 | 
			
		||||
			conn[ID::S].append(it.first);
 | 
			
		||||
			conn[ID::B].append(it.second);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -110,7 +110,7 @@ struct OptMergeWorker
 | 
			
		|||
			alt_conn = *conn;
 | 
			
		||||
			assign_map.apply(alt_conn.at(ID::A));
 | 
			
		||||
			assign_map.apply(alt_conn.at(ID::B));
 | 
			
		||||
			assign_map.apply(alt_conn.at(ID(S)));
 | 
			
		||||
			assign_map.apply(alt_conn.at(ID::S));
 | 
			
		||||
			sort_pmux_conn(alt_conn);
 | 
			
		||||
			conn = &alt_conn;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -118,9 +118,9 @@ struct OptMergeWorker
 | 
			
		|||
		for (auto &it : *conn) {
 | 
			
		||||
			RTLIL::SigSpec sig;
 | 
			
		||||
			if (cell->output(it.first)) {
 | 
			
		||||
				if (it.first == ID(Q) && (cell->type.begins_with("$dff") || cell->type.begins_with("$dlatch") ||
 | 
			
		||||
				if (it.first == ID::Q && (cell->type.begins_with("$dff") || cell->type.begins_with("$dlatch") ||
 | 
			
		||||
							cell->type.begins_with("$_DFF") || cell->type.begins_with("$_DLATCH") || cell->type.begins_with("$_SR_") ||
 | 
			
		||||
							cell->type.in("$adff", "$sr", "$ff", "$_FF_"))) {
 | 
			
		||||
							cell->type.in(ID($adff), ID($sr), ID($ff), ID($_FF_)))) {
 | 
			
		||||
					// For the 'Q' output of state elements,
 | 
			
		||||
					//   use its (* init *) attribute value
 | 
			
		||||
					for (const auto &b : dff_init_map(it.second))
 | 
			
		||||
| 
						 | 
				
			
			@ -175,9 +175,9 @@ struct OptMergeWorker
 | 
			
		|||
 | 
			
		||||
		for (const auto &it : cell1->connections_) {
 | 
			
		||||
			if (cell1->output(it.first)) {
 | 
			
		||||
				if (it.first == ID(Q) && (cell1->type.begins_with("$dff") || cell1->type.begins_with("$dlatch") ||
 | 
			
		||||
				if (it.first == ID::Q && (cell1->type.begins_with("$dff") || cell1->type.begins_with("$dlatch") ||
 | 
			
		||||
						cell1->type.begins_with("$_DFF") || cell1->type.begins_with("$_DLATCH") || cell1->type.begins_with("$_SR_") ||
 | 
			
		||||
						cell1->type.in("$adff", "$sr", "$ff", "$_FF_"))) {
 | 
			
		||||
						cell1->type.in(ID($adff), ID($sr), ID($ff), ID($_FF_)))) {
 | 
			
		||||
					// For the 'Q' output of state elements,
 | 
			
		||||
					//   use the (* init *) attribute value
 | 
			
		||||
					auto &sig1 = conn1[it.first];
 | 
			
		||||
| 
						 | 
				
			
			@ -253,8 +253,8 @@ struct OptMergeWorker
 | 
			
		|||
 | 
			
		||||
		dff_init_map.set(module);
 | 
			
		||||
		for (auto &it : module->wires_)
 | 
			
		||||
			if (it.second->attributes.count(ID(init)) != 0) {
 | 
			
		||||
				Const initval = it.second->attributes.at(ID(init));
 | 
			
		||||
			if (it.second->attributes.count(ID::init) != 0) {
 | 
			
		||||
				Const initval = it.second->attributes.at(ID::init);
 | 
			
		||||
				for (int i = 0; i < GetSize(initval) && i < GetSize(it.second); i++)
 | 
			
		||||
					if (initval[i] == State::S0 || initval[i] == State::S1)
 | 
			
		||||
						dff_init_map.add(SigBit(it.second, i), initval[i]);
 | 
			
		||||
| 
						 | 
				
			
			@ -300,11 +300,11 @@ struct OptMergeWorker
 | 
			
		|||
								module->connect(RTLIL::SigSig(it.second, other_sig));
 | 
			
		||||
								assign_map.add(it.second, other_sig);
 | 
			
		||||
 | 
			
		||||
								if (it.first == ID(Q) && (cell->type.begins_with("$dff") || cell->type.begins_with("$dlatch") ||
 | 
			
		||||
								if (it.first == ID::Q && (cell->type.begins_with("$dff") || cell->type.begins_with("$dlatch") ||
 | 
			
		||||
											cell->type.begins_with("$_DFF") || cell->type.begins_with("$_DLATCH") || cell->type.begins_with("$_SR_") ||
 | 
			
		||||
											cell->type.in("$adff", "$sr", "$ff", "$_FF_"))) {
 | 
			
		||||
											cell->type.in(ID($adff), ID($sr), ID($ff), ID($_FF_)))) {
 | 
			
		||||
									for (auto c : it.second.chunks()) {
 | 
			
		||||
										auto jt = c.wire->attributes.find(ID(init));
 | 
			
		||||
										auto jt = c.wire->attributes.find(ID::init);
 | 
			
		||||
										if (jt == c.wire->attributes.end())
 | 
			
		||||
											continue;
 | 
			
		||||
										for (int i = c.offset; i < c.offset + c.width; i++)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -88,7 +88,7 @@ struct OptMuxtreeWorker
 | 
			
		|||
			{
 | 
			
		||||
				RTLIL::SigSpec sig_a = cell->getPort(ID::A);
 | 
			
		||||
				RTLIL::SigSpec sig_b = cell->getPort(ID::B);
 | 
			
		||||
				RTLIL::SigSpec sig_s = cell->getPort(ID(S));
 | 
			
		||||
				RTLIL::SigSpec sig_s = cell->getPort(ID::S);
 | 
			
		||||
				RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
 | 
			
		||||
 | 
			
		||||
				muxinfo_t muxinfo;
 | 
			
		||||
| 
						 | 
				
			
			@ -229,7 +229,7 @@ struct OptMuxtreeWorker
 | 
			
		|||
 | 
			
		||||
			RTLIL::SigSpec sig_a = mi.cell->getPort(ID::A);
 | 
			
		||||
			RTLIL::SigSpec sig_b = mi.cell->getPort(ID::B);
 | 
			
		||||
			RTLIL::SigSpec sig_s = mi.cell->getPort(ID(S));
 | 
			
		||||
			RTLIL::SigSpec sig_s = mi.cell->getPort(ID::S);
 | 
			
		||||
			RTLIL::SigSpec sig_y = mi.cell->getPort(ID::Y);
 | 
			
		||||
 | 
			
		||||
			RTLIL::SigSpec sig_ports = sig_b;
 | 
			
		||||
| 
						 | 
				
			
			@ -257,12 +257,12 @@ struct OptMuxtreeWorker
 | 
			
		|||
 | 
			
		||||
				mi.cell->setPort(ID::A, new_sig_a);
 | 
			
		||||
				mi.cell->setPort(ID::B, new_sig_b);
 | 
			
		||||
				mi.cell->setPort(ID(S), new_sig_s);
 | 
			
		||||
				mi.cell->setPort(ID::S, new_sig_s);
 | 
			
		||||
				if (GetSize(new_sig_s) == 1) {
 | 
			
		||||
					mi.cell->type = ID($mux);
 | 
			
		||||
					mi.cell->parameters.erase(ID(S_WIDTH));
 | 
			
		||||
					mi.cell->parameters.erase(ID::S_WIDTH);
 | 
			
		||||
				} else {
 | 
			
		||||
					mi.cell->parameters[ID(S_WIDTH)] = RTLIL::Const(GetSize(new_sig_s));
 | 
			
		||||
					mi.cell->parameters[ID::S_WIDTH] = RTLIL::Const(GetSize(new_sig_s));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -366,7 +366,7 @@ struct OptMuxtreeWorker
 | 
			
		|||
		idict<int> ctrl_bits;
 | 
			
		||||
		if (portname == ID::B)
 | 
			
		||||
			width = GetSize(muxinfo.cell->getPort(ID::A));
 | 
			
		||||
		for (int bit : sig2bits(muxinfo.cell->getPort(ID(S)), false))
 | 
			
		||||
		for (int bit : sig2bits(muxinfo.cell->getPort(ID::S), false))
 | 
			
		||||
			ctrl_bits(bit);
 | 
			
		||||
 | 
			
		||||
		int port_idx = 0, port_off = 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -96,7 +96,7 @@ struct OptReduceWorker
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		cell->setPort(ID::A, new_sig_a);
 | 
			
		||||
		cell->parameters[ID(A_WIDTH)] = RTLIL::Const(new_sig_a.size());
 | 
			
		||||
		cell->parameters[ID::A_WIDTH] = RTLIL::Const(new_sig_a.size());
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -104,7 +104,7 @@ struct OptReduceWorker
 | 
			
		|||
	{
 | 
			
		||||
		RTLIL::SigSpec sig_a = assign_map(cell->getPort(ID::A));
 | 
			
		||||
		RTLIL::SigSpec sig_b = assign_map(cell->getPort(ID::B));
 | 
			
		||||
		RTLIL::SigSpec sig_s = assign_map(cell->getPort(ID(S)));
 | 
			
		||||
		RTLIL::SigSpec sig_s = assign_map(cell->getPort(ID::S));
 | 
			
		||||
 | 
			
		||||
		RTLIL::SigSpec new_sig_b, new_sig_s;
 | 
			
		||||
		pool<RTLIL::SigSpec> handled_sig;
 | 
			
		||||
| 
						 | 
				
			
			@ -127,9 +127,9 @@ struct OptReduceWorker
 | 
			
		|||
			{
 | 
			
		||||
				RTLIL::Cell *reduce_or_cell = module->addCell(NEW_ID, ID($reduce_or));
 | 
			
		||||
				reduce_or_cell->setPort(ID::A, this_s);
 | 
			
		||||
				reduce_or_cell->parameters[ID(A_SIGNED)] = RTLIL::Const(0);
 | 
			
		||||
				reduce_or_cell->parameters[ID(A_WIDTH)] = RTLIL::Const(this_s.size());
 | 
			
		||||
				reduce_or_cell->parameters[ID(Y_WIDTH)] = RTLIL::Const(1);
 | 
			
		||||
				reduce_or_cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
 | 
			
		||||
				reduce_or_cell->parameters[ID::A_WIDTH] = RTLIL::Const(this_s.size());
 | 
			
		||||
				reduce_or_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
 | 
			
		||||
				RTLIL::Wire *reduce_or_wire = module->addWire(NEW_ID);
 | 
			
		||||
				this_s = RTLIL::SigSpec(reduce_or_wire);
 | 
			
		||||
| 
						 | 
				
			
			@ -156,12 +156,12 @@ struct OptReduceWorker
 | 
			
		|||
		else
 | 
			
		||||
		{
 | 
			
		||||
			cell->setPort(ID::B, new_sig_b);
 | 
			
		||||
			cell->setPort(ID(S), new_sig_s);
 | 
			
		||||
			cell->setPort(ID::S, new_sig_s);
 | 
			
		||||
			if (new_sig_s.size() > 1) {
 | 
			
		||||
				cell->parameters[ID(S_WIDTH)] = RTLIL::Const(new_sig_s.size());
 | 
			
		||||
				cell->parameters[ID::S_WIDTH] = RTLIL::Const(new_sig_s.size());
 | 
			
		||||
			} else {
 | 
			
		||||
				cell->type = ID($mux);
 | 
			
		||||
				cell->parameters.erase(ID(S_WIDTH));
 | 
			
		||||
				cell->parameters.erase(ID::S_WIDTH);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -222,14 +222,14 @@ struct OptReduceWorker
 | 
			
		|||
			}
 | 
			
		||||
 | 
			
		||||
			cell->setPort(ID::B, RTLIL::SigSpec());
 | 
			
		||||
			for (int i = 1; i <= cell->getPort(ID(S)).size(); i++)
 | 
			
		||||
			for (int i = 1; i <= cell->getPort(ID::S).size(); i++)
 | 
			
		||||
				for (auto &in_tuple : consolidated_in_tuples) {
 | 
			
		||||
					RTLIL::SigSpec new_b = cell->getPort(ID::B);
 | 
			
		||||
					new_b.append(in_tuple.at(i));
 | 
			
		||||
					cell->setPort(ID::B, new_b);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
			cell->parameters[ID(WIDTH)] = RTLIL::Const(new_sig_y.size());
 | 
			
		||||
			cell->parameters[ID::WIDTH] = RTLIL::Const(new_sig_y.size());
 | 
			
		||||
			cell->setPort(ID::Y, new_sig_y);
 | 
			
		||||
 | 
			
		||||
			log("      New ports: A=%s, B=%s, Y=%s\n", log_signal(cell->getPort(ID::A)),
 | 
			
		||||
| 
						 | 
				
			
			@ -255,14 +255,14 @@ struct OptReduceWorker
 | 
			
		|||
		for (auto &cell_it : module->cells_) {
 | 
			
		||||
			RTLIL::Cell *cell = cell_it.second;
 | 
			
		||||
			if (cell->type == ID($mem))
 | 
			
		||||
				mem_wren_sigs.add(assign_map(cell->getPort(ID(WR_EN))));
 | 
			
		||||
				mem_wren_sigs.add(assign_map(cell->getPort(ID::WR_EN)));
 | 
			
		||||
			if (cell->type == ID($memwr))
 | 
			
		||||
				mem_wren_sigs.add(assign_map(cell->getPort(ID(EN))));
 | 
			
		||||
				mem_wren_sigs.add(assign_map(cell->getPort(ID::EN)));
 | 
			
		||||
		}
 | 
			
		||||
		for (auto &cell_it : module->cells_) {
 | 
			
		||||
			RTLIL::Cell *cell = cell_it.second;
 | 
			
		||||
			if (cell->type == ID($dff) && mem_wren_sigs.check_any(assign_map(cell->getPort(ID(Q)))))
 | 
			
		||||
				mem_wren_sigs.add(assign_map(cell->getPort(ID(D))));
 | 
			
		||||
			if (cell->type == ID($dff) && mem_wren_sigs.check_any(assign_map(cell->getPort(ID::Q))))
 | 
			
		||||
				mem_wren_sigs.add(assign_map(cell->getPort(ID::D)));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool keep_expanding_mem_wren_sigs = true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,7 +41,7 @@ void remove_init_attr(SigSpec sig)
 | 
			
		|||
	for (auto bit : assign_map(sig))
 | 
			
		||||
		if (init_attributes.count(bit))
 | 
			
		||||
			for (auto wbit : init_attributes.at(bit))
 | 
			
		||||
				wbit.wire->attributes.at(ID(init))[wbit.offset] = State::Sx;
 | 
			
		||||
				wbit.wire->attributes.at(ID::init)[wbit.offset] = State::Sx;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
 | 
			
		||||
| 
						 | 
				
			
			@ -49,17 +49,17 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
 | 
			
		|||
	SigSpec sig_set, sig_clr;
 | 
			
		||||
	State pol_set, pol_clr;
 | 
			
		||||
 | 
			
		||||
	if (cell->hasPort(ID(S)))
 | 
			
		||||
		sig_set = cell->getPort(ID(S));
 | 
			
		||||
	if (cell->hasPort(ID::S))
 | 
			
		||||
		sig_set = cell->getPort(ID::S);
 | 
			
		||||
 | 
			
		||||
	if (cell->hasPort(ID(R)))
 | 
			
		||||
		sig_clr = cell->getPort(ID(R));
 | 
			
		||||
	if (cell->hasPort(ID::R))
 | 
			
		||||
		sig_clr = cell->getPort(ID::R);
 | 
			
		||||
 | 
			
		||||
	if (cell->hasPort(ID(SET)))
 | 
			
		||||
		sig_set = cell->getPort(ID(SET));
 | 
			
		||||
	if (cell->hasPort(ID::SET))
 | 
			
		||||
		sig_set = cell->getPort(ID::SET);
 | 
			
		||||
 | 
			
		||||
	if (cell->hasPort(ID(CLR)))
 | 
			
		||||
		sig_clr = cell->getPort(ID(CLR));
 | 
			
		||||
	if (cell->hasPort(ID::CLR))
 | 
			
		||||
		sig_clr = cell->getPort(ID::CLR);
 | 
			
		||||
 | 
			
		||||
	log_assert(GetSize(sig_set) == GetSize(sig_clr));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -72,16 +72,16 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
 | 
			
		|||
		pol_clr = cell->type[13] == 'P' ? State::S1 : State::S0;
 | 
			
		||||
	} else
 | 
			
		||||
	if (cell->type.in(ID($dffsr), ID($dlatchsr))) {
 | 
			
		||||
		pol_set = cell->parameters[ID(SET_POLARITY)].as_bool() ? State::S1 : State::S0;
 | 
			
		||||
		pol_clr = cell->parameters[ID(CLR_POLARITY)].as_bool() ? State::S1 : State::S0;
 | 
			
		||||
		pol_set = cell->parameters[ID::SET_POLARITY].as_bool() ? State::S1 : State::S0;
 | 
			
		||||
		pol_clr = cell->parameters[ID::CLR_POLARITY].as_bool() ? State::S1 : State::S0;
 | 
			
		||||
	} else
 | 
			
		||||
		log_abort();
 | 
			
		||||
 | 
			
		||||
	State npol_set = pol_set == State::S0 ? State::S1 : State::S0;
 | 
			
		||||
	State npol_clr = pol_clr == State::S0 ? State::S1 : State::S0;
 | 
			
		||||
 | 
			
		||||
	SigSpec sig_d = cell->getPort(ID(D));
 | 
			
		||||
	SigSpec sig_q = cell->getPort(ID(Q));
 | 
			
		||||
	SigSpec sig_d = cell->getPort(ID::D);
 | 
			
		||||
	SigSpec sig_q = cell->getPort(ID::Q);
 | 
			
		||||
 | 
			
		||||
	bool did_something = false;
 | 
			
		||||
	bool proper_sr = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -139,18 +139,18 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
 | 
			
		|||
 | 
			
		||||
	if (cell->type.in(ID($dffsr), ID($dlatchsr)))
 | 
			
		||||
	{
 | 
			
		||||
		cell->setParam(ID(WIDTH), GetSize(sig_d));
 | 
			
		||||
		cell->setPort(ID(SET), sig_set);
 | 
			
		||||
		cell->setPort(ID(CLR), sig_clr);
 | 
			
		||||
		cell->setPort(ID(D), sig_d);
 | 
			
		||||
		cell->setPort(ID(Q), sig_q);
 | 
			
		||||
		cell->setParam(ID::WIDTH, GetSize(sig_d));
 | 
			
		||||
		cell->setPort(ID::SET, sig_set);
 | 
			
		||||
		cell->setPort(ID::CLR, sig_clr);
 | 
			
		||||
		cell->setPort(ID::D, sig_d);
 | 
			
		||||
		cell->setPort(ID::Q, sig_q);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		cell->setPort(ID(S), sig_set);
 | 
			
		||||
		cell->setPort(ID(R), sig_clr);
 | 
			
		||||
		cell->setPort(ID(D), sig_d);
 | 
			
		||||
		cell->setPort(ID(Q), sig_q);
 | 
			
		||||
		cell->setPort(ID::S, sig_set);
 | 
			
		||||
		cell->setPort(ID::R, sig_clr);
 | 
			
		||||
		cell->setPort(ID::D, sig_d);
 | 
			
		||||
		cell->setPort(ID::Q, sig_q);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (proper_sr)
 | 
			
		||||
| 
						 | 
				
			
			@ -171,24 +171,24 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
 | 
			
		|||
			log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), "$adff", log_id(mod));
 | 
			
		||||
 | 
			
		||||
			cell->type = ID($adff);
 | 
			
		||||
			cell->setParam(ID(ARST_POLARITY), unified_pol);
 | 
			
		||||
			cell->setParam(ID(ARST_VALUE), reset_val);
 | 
			
		||||
			cell->setPort(ID(ARST), sig_reset);
 | 
			
		||||
			cell->setParam(ID::ARST_POLARITY, unified_pol);
 | 
			
		||||
			cell->setParam(ID::ARST_VALUE, reset_val);
 | 
			
		||||
			cell->setPort(ID::ARST, sig_reset);
 | 
			
		||||
 | 
			
		||||
			cell->unsetParam(ID(SET_POLARITY));
 | 
			
		||||
			cell->unsetParam(ID(CLR_POLARITY));
 | 
			
		||||
			cell->unsetPort(ID(SET));
 | 
			
		||||
			cell->unsetPort(ID(CLR));
 | 
			
		||||
			cell->unsetParam(ID::SET_POLARITY);
 | 
			
		||||
			cell->unsetParam(ID::CLR_POLARITY);
 | 
			
		||||
			cell->unsetPort(ID::SET);
 | 
			
		||||
			cell->unsetPort(ID::CLR);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), "$dff", log_id(mod));
 | 
			
		||||
 | 
			
		||||
			cell->type = ID($dff);
 | 
			
		||||
			cell->unsetParam(ID(SET_POLARITY));
 | 
			
		||||
			cell->unsetParam(ID(CLR_POLARITY));
 | 
			
		||||
			cell->unsetPort(ID(SET));
 | 
			
		||||
			cell->unsetPort(ID(CLR));
 | 
			
		||||
			cell->unsetParam(ID::SET_POLARITY);
 | 
			
		||||
			cell->unsetParam(ID::CLR_POLARITY);
 | 
			
		||||
			cell->unsetPort(ID::SET);
 | 
			
		||||
			cell->unsetPort(ID::CLR);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
| 
						 | 
				
			
			@ -208,8 +208,8 @@ bool handle_dffsr(RTLIL::Module *mod, RTLIL::Cell *cell)
 | 
			
		|||
		log("Converting %s (%s) to %s in module %s.\n", log_id(cell), log_id(cell->type), log_id(new_type), log_id(mod));
 | 
			
		||||
 | 
			
		||||
		cell->type = new_type;
 | 
			
		||||
		cell->unsetPort(ID(S));
 | 
			
		||||
		cell->unsetPort(ID(R));
 | 
			
		||||
		cell->unsetPort(ID::S);
 | 
			
		||||
		cell->unsetPort(ID::R);
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -223,17 +223,17 @@ bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch)
 | 
			
		|||
	State on_state, off_state;
 | 
			
		||||
 | 
			
		||||
	if (dlatch->type == ID($dlatch)) {
 | 
			
		||||
		sig_e = assign_map(dlatch->getPort(ID(EN)));
 | 
			
		||||
		on_state = dlatch->getParam(ID(EN_POLARITY)).as_bool() ? State::S1 : State::S0;
 | 
			
		||||
		off_state = dlatch->getParam(ID(EN_POLARITY)).as_bool() ? State::S0 : State::S1;
 | 
			
		||||
		sig_e = assign_map(dlatch->getPort(ID::EN));
 | 
			
		||||
		on_state = dlatch->getParam(ID::EN_POLARITY).as_bool() ? State::S1 : State::S0;
 | 
			
		||||
		off_state = dlatch->getParam(ID::EN_POLARITY).as_bool() ? State::S0 : State::S1;
 | 
			
		||||
	} else
 | 
			
		||||
	if (dlatch->type == ID($_DLATCH_P_)) {
 | 
			
		||||
		sig_e = assign_map(dlatch->getPort(ID(E)));
 | 
			
		||||
		sig_e = assign_map(dlatch->getPort(ID::E));
 | 
			
		||||
		on_state = State::S1;
 | 
			
		||||
		off_state = State::S0;
 | 
			
		||||
	} else
 | 
			
		||||
	if (dlatch->type == ID($_DLATCH_N_)) {
 | 
			
		||||
		sig_e = assign_map(dlatch->getPort(ID(E)));
 | 
			
		||||
		sig_e = assign_map(dlatch->getPort(ID::E));
 | 
			
		||||
		on_state = State::S0;
 | 
			
		||||
		off_state = State::S1;
 | 
			
		||||
	} else
 | 
			
		||||
| 
						 | 
				
			
			@ -242,15 +242,15 @@ bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch)
 | 
			
		|||
	if (sig_e == off_state)
 | 
			
		||||
	{
 | 
			
		||||
		RTLIL::Const val_init;
 | 
			
		||||
		for (auto bit : dff_init_map(dlatch->getPort(ID(Q))))
 | 
			
		||||
		for (auto bit : dff_init_map(dlatch->getPort(ID::Q)))
 | 
			
		||||
			val_init.bits.push_back(bit.wire == NULL ? bit.data : State::Sx);
 | 
			
		||||
		mod->connect(dlatch->getPort(ID(Q)), val_init);
 | 
			
		||||
		mod->connect(dlatch->getPort(ID::Q), val_init);
 | 
			
		||||
		goto delete_dlatch;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (sig_e == on_state)
 | 
			
		||||
	{
 | 
			
		||||
		mod->connect(dlatch->getPort(ID(Q)), dlatch->getPort(ID(D)));
 | 
			
		||||
		mod->connect(dlatch->getPort(ID::Q), dlatch->getPort(ID::D));
 | 
			
		||||
		goto delete_dlatch;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -258,7 +258,7 @@ bool handle_dlatch(RTLIL::Module *mod, RTLIL::Cell *dlatch)
 | 
			
		|||
 | 
			
		||||
delete_dlatch:
 | 
			
		||||
	log("Removing %s (%s) from module %s.\n", log_id(dlatch), log_id(dlatch->type), log_id(mod));
 | 
			
		||||
	remove_init_attr(dlatch->getPort(ID(Q)));
 | 
			
		||||
	remove_init_attr(dlatch->getPort(ID::Q));
 | 
			
		||||
	mod->remove(dlatch);
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -269,23 +269,23 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
 | 
			
		|||
	RTLIL::Const val_cp, val_rp, val_rv, val_ep;
 | 
			
		||||
 | 
			
		||||
	if (dff->type == ID($_FF_)) {
 | 
			
		||||
		sig_d = dff->getPort(ID(D));
 | 
			
		||||
		sig_q = dff->getPort(ID(Q));
 | 
			
		||||
		sig_d = dff->getPort(ID::D);
 | 
			
		||||
		sig_q = dff->getPort(ID::Q);
 | 
			
		||||
	}
 | 
			
		||||
	else if (dff->type == ID($_DFF_N_) || dff->type == ID($_DFF_P_)) {
 | 
			
		||||
		sig_d = dff->getPort(ID(D));
 | 
			
		||||
		sig_q = dff->getPort(ID(Q));
 | 
			
		||||
		sig_c = dff->getPort(ID(C));
 | 
			
		||||
		sig_d = dff->getPort(ID::D);
 | 
			
		||||
		sig_q = dff->getPort(ID::Q);
 | 
			
		||||
		sig_c = dff->getPort(ID::C);
 | 
			
		||||
		val_cp = RTLIL::Const(dff->type == ID($_DFF_P_), 1);
 | 
			
		||||
	}
 | 
			
		||||
	else if (dff->type.begins_with("$_DFF_") && dff->type.compare(9, 1, "_") == 0 &&
 | 
			
		||||
			(dff->type[6] == 'N' || dff->type[6] == 'P') &&
 | 
			
		||||
			(dff->type[7] == 'N' || dff->type[7] == 'P') &&
 | 
			
		||||
			(dff->type[8] == '0' || dff->type[8] == '1')) {
 | 
			
		||||
		sig_d = dff->getPort(ID(D));
 | 
			
		||||
		sig_q = dff->getPort(ID(Q));
 | 
			
		||||
		sig_c = dff->getPort(ID(C));
 | 
			
		||||
		sig_r = dff->getPort(ID(R));
 | 
			
		||||
		sig_d = dff->getPort(ID::D);
 | 
			
		||||
		sig_q = dff->getPort(ID::Q);
 | 
			
		||||
		sig_c = dff->getPort(ID::C);
 | 
			
		||||
		sig_r = dff->getPort(ID::R);
 | 
			
		||||
		val_cp = RTLIL::Const(dff->type[6] == 'P', 1);
 | 
			
		||||
		val_rp = RTLIL::Const(dff->type[7] == 'P', 1);
 | 
			
		||||
		val_rv = RTLIL::Const(dff->type[8] == '1', 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -293,39 +293,39 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
 | 
			
		|||
	else if (dff->type.begins_with("$_DFFE_") && dff->type.compare(9, 1, "_") == 0 &&
 | 
			
		||||
			(dff->type[7] == 'N' || dff->type[7] == 'P') &&
 | 
			
		||||
			(dff->type[8] == 'N' || dff->type[8] == 'P')) {
 | 
			
		||||
		sig_d = dff->getPort(ID(D));
 | 
			
		||||
		sig_q = dff->getPort(ID(Q));
 | 
			
		||||
		sig_c = dff->getPort(ID(C));
 | 
			
		||||
		sig_e = dff->getPort(ID(E));
 | 
			
		||||
		sig_d = dff->getPort(ID::D);
 | 
			
		||||
		sig_q = dff->getPort(ID::Q);
 | 
			
		||||
		sig_c = dff->getPort(ID::C);
 | 
			
		||||
		sig_e = dff->getPort(ID::E);
 | 
			
		||||
		val_cp = RTLIL::Const(dff->type[7] == 'P', 1);
 | 
			
		||||
		val_ep = RTLIL::Const(dff->type[8] == 'P', 1);
 | 
			
		||||
	}
 | 
			
		||||
	else if (dff->type == ID($ff)) {
 | 
			
		||||
		sig_d = dff->getPort(ID(D));
 | 
			
		||||
		sig_q = dff->getPort(ID(Q));
 | 
			
		||||
		sig_d = dff->getPort(ID::D);
 | 
			
		||||
		sig_q = dff->getPort(ID::Q);
 | 
			
		||||
	}
 | 
			
		||||
	else if (dff->type == ID($dff)) {
 | 
			
		||||
		sig_d = dff->getPort(ID(D));
 | 
			
		||||
		sig_q = dff->getPort(ID(Q));
 | 
			
		||||
		sig_c = dff->getPort(ID(CLK));
 | 
			
		||||
		val_cp = RTLIL::Const(dff->parameters[ID(CLK_POLARITY)].as_bool(), 1);
 | 
			
		||||
		sig_d = dff->getPort(ID::D);
 | 
			
		||||
		sig_q = dff->getPort(ID::Q);
 | 
			
		||||
		sig_c = dff->getPort(ID::CLK);
 | 
			
		||||
		val_cp = RTLIL::Const(dff->parameters[ID::CLK_POLARITY].as_bool(), 1);
 | 
			
		||||
	}
 | 
			
		||||
	else if (dff->type == ID($dffe)) {
 | 
			
		||||
		sig_e = dff->getPort(ID(EN));
 | 
			
		||||
		sig_d = dff->getPort(ID(D));
 | 
			
		||||
		sig_q = dff->getPort(ID(Q));
 | 
			
		||||
		sig_c = dff->getPort(ID(CLK));
 | 
			
		||||
		val_cp = RTLIL::Const(dff->parameters[ID(CLK_POLARITY)].as_bool(), 1);
 | 
			
		||||
		val_ep = RTLIL::Const(dff->parameters[ID(EN_POLARITY)].as_bool(), 1);
 | 
			
		||||
		sig_e = dff->getPort(ID::EN);
 | 
			
		||||
		sig_d = dff->getPort(ID::D);
 | 
			
		||||
		sig_q = dff->getPort(ID::Q);
 | 
			
		||||
		sig_c = dff->getPort(ID::CLK);
 | 
			
		||||
		val_cp = RTLIL::Const(dff->parameters[ID::CLK_POLARITY].as_bool(), 1);
 | 
			
		||||
		val_ep = RTLIL::Const(dff->parameters[ID::EN_POLARITY].as_bool(), 1);
 | 
			
		||||
	}
 | 
			
		||||
	else if (dff->type == ID($adff)) {
 | 
			
		||||
		sig_d = dff->getPort(ID(D));
 | 
			
		||||
		sig_q = dff->getPort(ID(Q));
 | 
			
		||||
		sig_c = dff->getPort(ID(CLK));
 | 
			
		||||
		sig_r = dff->getPort(ID(ARST));
 | 
			
		||||
		val_cp = RTLIL::Const(dff->parameters[ID(CLK_POLARITY)].as_bool(), 1);
 | 
			
		||||
		val_rp = RTLIL::Const(dff->parameters[ID(ARST_POLARITY)].as_bool(), 1);
 | 
			
		||||
		val_rv = dff->parameters[ID(ARST_VALUE)];
 | 
			
		||||
		sig_d = dff->getPort(ID::D);
 | 
			
		||||
		sig_q = dff->getPort(ID::Q);
 | 
			
		||||
		sig_c = dff->getPort(ID::CLK);
 | 
			
		||||
		sig_r = dff->getPort(ID::ARST);
 | 
			
		||||
		val_cp = RTLIL::Const(dff->parameters[ID::CLK_POLARITY].as_bool(), 1);
 | 
			
		||||
		val_rp = RTLIL::Const(dff->parameters[ID::ARST_POLARITY].as_bool(), 1);
 | 
			
		||||
		val_rv = dff->parameters[ID::ARST_VALUE];
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		log_abort();
 | 
			
		||||
| 
						 | 
				
			
			@ -422,15 +422,15 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
 | 
			
		|||
 | 
			
		||||
		if (dff->type == ID($adff)) {
 | 
			
		||||
			dff->type = ID($dff);
 | 
			
		||||
			dff->unsetPort(ID(ARST));
 | 
			
		||||
			dff->unsetParam(ID(ARST_POLARITY));
 | 
			
		||||
			dff->unsetParam(ID(ARST_VALUE));
 | 
			
		||||
			dff->unsetPort(ID::ARST);
 | 
			
		||||
			dff->unsetParam(ID::ARST_POLARITY);
 | 
			
		||||
			dff->unsetParam(ID::ARST_VALUE);
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		log_assert(dff->type.begins_with("$_DFF_"));
 | 
			
		||||
		dff->type = stringf("$_DFF_%c_", + dff->type[6]);
 | 
			
		||||
		dff->unsetPort(ID(R));
 | 
			
		||||
		dff->unsetPort(ID::R);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// If enable signal is present, and is fully constant
 | 
			
		||||
| 
						 | 
				
			
			@ -447,14 +447,14 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
 | 
			
		|||
 | 
			
		||||
		if (dff->type == ID($dffe)) {
 | 
			
		||||
			dff->type = ID($dff);
 | 
			
		||||
			dff->unsetPort(ID(EN));
 | 
			
		||||
			dff->unsetParam(ID(EN_POLARITY));
 | 
			
		||||
			dff->unsetPort(ID::EN);
 | 
			
		||||
			dff->unsetParam(ID::EN_POLARITY);
 | 
			
		||||
			return true;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		log_assert(dff->type.begins_with("$_DFFE_"));
 | 
			
		||||
		dff->type = stringf("$_DFF_%c_", + dff->type[7]);
 | 
			
		||||
		dff->unsetPort(ID(E));
 | 
			
		||||
		dff->unsetPort(ID::E);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (sat && has_init && (!sig_r.size() || val_init == val_rv))
 | 
			
		||||
| 
						 | 
				
			
			@ -509,9 +509,9 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
 | 
			
		|||
				log("Setting constant %d-bit at position %d on %s (%s) from module %s.\n", sigbit_init_val ? 1 : 0,
 | 
			
		||||
						position, log_id(dff), log_id(dff->type), log_id(mod));
 | 
			
		||||
 | 
			
		||||
				SigSpec tmp = dff->getPort(ID(D));
 | 
			
		||||
				SigSpec tmp = dff->getPort(ID::D);
 | 
			
		||||
				tmp[position] = sigbit_init_val;
 | 
			
		||||
				dff->setPort(ID(D), tmp);
 | 
			
		||||
				dff->setPort(ID::D, tmp);
 | 
			
		||||
 | 
			
		||||
				removed_sigbits = true;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -528,7 +528,7 @@ bool handle_dff(RTLIL::Module *mod, RTLIL::Cell *dff)
 | 
			
		|||
 | 
			
		||||
delete_dff:
 | 
			
		||||
	log("Removing %s (%s) from module %s.\n", log_id(dff), log_id(dff->type), log_id(mod));
 | 
			
		||||
	remove_init_attr(dff->getPort(ID(Q)));
 | 
			
		||||
	remove_init_attr(dff->getPort(ID::Q));
 | 
			
		||||
	mod->remove(dff);
 | 
			
		||||
 | 
			
		||||
	for (auto &entry : bit2driver)
 | 
			
		||||
| 
						 | 
				
			
			@ -588,8 +588,8 @@ struct OptRmdffPass : public Pass {
 | 
			
		|||
 | 
			
		||||
			for (auto wire : module->wires())
 | 
			
		||||
			{
 | 
			
		||||
				if (wire->attributes.count(ID(init)) != 0) {
 | 
			
		||||
					Const initval = wire->attributes.at(ID(init));
 | 
			
		||||
				if (wire->attributes.count(ID::init) != 0) {
 | 
			
		||||
					Const initval = wire->attributes.at(ID::init);
 | 
			
		||||
					for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++)
 | 
			
		||||
						if (initval[i] == State::S0 || initval[i] == State::S1)
 | 
			
		||||
							dff_init_map.add(SigBit(wire, i), initval[i]);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -98,8 +98,8 @@ struct ExtSigSpec {
 | 
			
		|||
bool cell_supported(RTLIL::Cell *cell)
 | 
			
		||||
{
 | 
			
		||||
	if (cell->type.in(ID($alu))) {
 | 
			
		||||
		RTLIL::SigSpec sig_bi = cell->getPort(ID(BI));
 | 
			
		||||
		RTLIL::SigSpec sig_ci = cell->getPort(ID(CI));
 | 
			
		||||
		RTLIL::SigSpec sig_bi = cell->getPort(ID::BI);
 | 
			
		||||
		RTLIL::SigSpec sig_ci = cell->getPort(ID::CI);
 | 
			
		||||
 | 
			
		||||
		if (sig_bi.is_fully_const() && sig_ci.is_fully_const() && sig_bi == sig_ci)
 | 
			
		||||
			return true;
 | 
			
		||||
| 
						 | 
				
			
			@ -139,7 +139,7 @@ RTLIL::IdString decode_port_semantics(RTLIL::Cell *cell, RTLIL::IdString port_na
 | 
			
		|||
RTLIL::SigSpec decode_port_sign(RTLIL::Cell *cell, RTLIL::IdString port_name) {
 | 
			
		||||
 | 
			
		||||
	if (cell->type == ID($alu) && port_name == ID::B)
 | 
			
		||||
		return cell->getPort(ID(BI));
 | 
			
		||||
		return cell->getPort(ID::BI);
 | 
			
		||||
	else if (cell->type == ID($sub) && port_name == ID::B)
 | 
			
		||||
		return RTLIL::Const(1, 1);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -190,7 +190,7 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<
 | 
			
		|||
	auto shared_op = ports[0].op;
 | 
			
		||||
 | 
			
		||||
	if (std::any_of(muxed_operands.begin(), muxed_operands.end(), [&](ExtSigSpec &op) { return op.sign != muxed_operands[0].sign; }))
 | 
			
		||||
        max_width = std::max(max_width, shared_op->getParam(ID(Y_WIDTH)).as_int());
 | 
			
		||||
        max_width = std::max(max_width, shared_op->getParam(ID::Y_WIDTH).as_int());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	for (auto &operand : muxed_operands)
 | 
			
		||||
| 
						 | 
				
			
			@ -210,7 +210,7 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<
 | 
			
		|||
	RTLIL::SigSpec mux_y = mux->getPort(ID::Y);
 | 
			
		||||
	RTLIL::SigSpec mux_a = mux->getPort(ID::A);
 | 
			
		||||
	RTLIL::SigSpec mux_b = mux->getPort(ID::B);
 | 
			
		||||
	RTLIL::SigSpec mux_s = mux->getPort(ID(S));
 | 
			
		||||
	RTLIL::SigSpec mux_s = mux->getPort(ID::S);
 | 
			
		||||
 | 
			
		||||
	RTLIL::SigSpec shared_pmux_a = RTLIL::Const(RTLIL::State::Sx, max_width);
 | 
			
		||||
	RTLIL::SigSpec shared_pmux_b;
 | 
			
		||||
| 
						 | 
				
			
			@ -237,7 +237,7 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<
 | 
			
		|||
	mux->setPort(ID::A, mux_a);
 | 
			
		||||
	mux->setPort(ID::B, mux_b);
 | 
			
		||||
	mux->setPort(ID::Y, mux_y);
 | 
			
		||||
	mux->setPort(ID(S), mux_s);
 | 
			
		||||
	mux->setPort(ID::S, mux_s);
 | 
			
		||||
 | 
			
		||||
	for (const auto &op : muxed_operands)
 | 
			
		||||
		shared_pmux_b.append(op.sig);
 | 
			
		||||
| 
						 | 
				
			
			@ -245,26 +245,26 @@ void merge_operators(RTLIL::Module *module, RTLIL::Cell *mux, const std::vector<
 | 
			
		|||
	auto mux_to_oper = module->Pmux(NEW_ID, shared_pmux_a, shared_pmux_b, shared_pmux_s);
 | 
			
		||||
 | 
			
		||||
	if (shared_op->type.in(ID($alu))) {
 | 
			
		||||
		RTLIL::SigSpec alu_x = shared_op->getPort(ID(X));
 | 
			
		||||
		RTLIL::SigSpec alu_co = shared_op->getPort(ID(CO));
 | 
			
		||||
		RTLIL::SigSpec alu_x = shared_op->getPort(ID::X);
 | 
			
		||||
		RTLIL::SigSpec alu_co = shared_op->getPort(ID::CO);
 | 
			
		||||
 | 
			
		||||
		shared_op->setPort(ID(X), alu_x.extract(0, conn_width));
 | 
			
		||||
		shared_op->setPort(ID(CO), alu_co.extract(0, conn_width));
 | 
			
		||||
		shared_op->setPort(ID::X, alu_x.extract(0, conn_width));
 | 
			
		||||
		shared_op->setPort(ID::CO, alu_co.extract(0, conn_width));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	bool is_fine = shared_op->type.in(FINE_BITWISE_OPS);
 | 
			
		||||
 | 
			
		||||
	if (!is_fine)
 | 
			
		||||
		shared_op->setParam(ID(Y_WIDTH), conn_width);
 | 
			
		||||
		shared_op->setParam(ID::Y_WIDTH, conn_width);
 | 
			
		||||
 | 
			
		||||
	if (decode_port(shared_op, ID::A, &assign_map) == operand) {
 | 
			
		||||
		shared_op->setPort(ID::B, mux_to_oper);
 | 
			
		||||
		if (!is_fine)
 | 
			
		||||
			shared_op->setParam(ID(B_WIDTH), max_width);
 | 
			
		||||
			shared_op->setParam(ID::B_WIDTH, max_width);
 | 
			
		||||
	} else {
 | 
			
		||||
		shared_op->setPort(ID::A, mux_to_oper);
 | 
			
		||||
		if (!is_fine)
 | 
			
		||||
			shared_op->setParam(ID(A_WIDTH), max_width);
 | 
			
		||||
			shared_op->setParam(ID::A_WIDTH, max_width);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -452,7 +452,7 @@ dict<RTLIL::SigSpec, OpMuxConn> find_valid_op_mux_conns(RTLIL::Module *module, d
 | 
			
		|||
 | 
			
		||||
	for (auto cell : module->cells()) {
 | 
			
		||||
		if (cell->type.in(ID($mux), ID($_MUX_), ID($pmux))) {
 | 
			
		||||
			remove_connected_ops(cell->getPort(ID(S)));
 | 
			
		||||
			remove_connected_ops(cell->getPort(ID::S));
 | 
			
		||||
			find_op_mux_conns(cell);
 | 
			
		||||
		} else {
 | 
			
		||||
			for (auto &conn : cell->connections())
 | 
			
		||||
| 
						 | 
				
			
			@ -510,7 +510,7 @@ struct OptSharePass : public Pass {
 | 
			
		|||
					continue;
 | 
			
		||||
 | 
			
		||||
				if (cell->type == ID($alu)) {
 | 
			
		||||
					for (RTLIL::IdString port_name : {ID(X), ID(CO)}) {
 | 
			
		||||
					for (RTLIL::IdString port_name : {ID::X, ID::CO}) {
 | 
			
		||||
						auto mux_insig = assign_map(cell->getPort(port_name));
 | 
			
		||||
						outsig_to_operator[mux_insig] = cell;
 | 
			
		||||
						for (auto outbit : mux_insig)
 | 
			
		||||
| 
						 | 
				
			
			@ -552,7 +552,7 @@ struct OptSharePass : public Pass {
 | 
			
		|||
					if (p.mux->type.in(ID($mux), ID($_MUX_)))
 | 
			
		||||
						mux_port_num = 2;
 | 
			
		||||
					else
 | 
			
		||||
						mux_port_num = p.mux->getPort(ID(S)).size();
 | 
			
		||||
						mux_port_num = p.mux->getPort(ID::S).size();
 | 
			
		||||
 | 
			
		||||
					mux_port_conns.resize(mux_port_num);
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ struct OnehotDatabase
 | 
			
		|||
 | 
			
		||||
		for (auto wire : module->wires())
 | 
			
		||||
		{
 | 
			
		||||
			auto it = wire->attributes.find(ID(init));
 | 
			
		||||
			auto it = wire->attributes.find(ID::init);
 | 
			
		||||
			if (it == wire->attributes.end())
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -65,10 +65,10 @@ struct OnehotDatabase
 | 
			
		|||
 | 
			
		||||
			if (cell->type.in(ID($adff), ID($dff), ID($dffe), ID($dlatch), ID($ff)))
 | 
			
		||||
			{
 | 
			
		||||
				output = cell->getPort(ID(Q));
 | 
			
		||||
				output = cell->getPort(ID::Q);
 | 
			
		||||
				if (cell->type == ID($adff))
 | 
			
		||||
					inputs.push_back(cell->getParam(ID(ARST_VALUE)));
 | 
			
		||||
				inputs.push_back(cell->getPort(ID(D)));
 | 
			
		||||
					inputs.push_back(cell->getParam(ID::ARST_VALUE));
 | 
			
		||||
				inputs.push_back(cell->getPort(ID::D));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in(ID($mux), ID($pmux)))
 | 
			
		||||
| 
						 | 
				
			
			@ -299,16 +299,16 @@ struct Pmux2ShiftxPass : public Pass {
 | 
			
		|||
					SigSpec A = sigmap(cell->getPort(ID::A));
 | 
			
		||||
					SigSpec B = sigmap(cell->getPort(ID::B));
 | 
			
		||||
 | 
			
		||||
					int a_width = cell->getParam(ID(A_WIDTH)).as_int();
 | 
			
		||||
					int b_width = cell->getParam(ID(B_WIDTH)).as_int();
 | 
			
		||||
					int a_width = cell->getParam(ID::A_WIDTH).as_int();
 | 
			
		||||
					int b_width = cell->getParam(ID::B_WIDTH).as_int();
 | 
			
		||||
 | 
			
		||||
					if (a_width < b_width) {
 | 
			
		||||
						bool a_signed = cell->getParam(ID(A_SIGNED)).as_int();
 | 
			
		||||
						bool a_signed = cell->getParam(ID::A_SIGNED).as_int();
 | 
			
		||||
						A.extend_u0(b_width, a_signed);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if (b_width < a_width) {
 | 
			
		||||
						bool b_signed = cell->getParam(ID(B_SIGNED)).as_int();
 | 
			
		||||
						bool b_signed = cell->getParam(ID::B_SIGNED).as_int();
 | 
			
		||||
						B.extend_u0(a_width, b_signed);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -368,7 +368,7 @@ struct Pmux2ShiftxPass : public Pass {
 | 
			
		|||
					continue;
 | 
			
		||||
 | 
			
		||||
				string src = cell->get_src_attribute();
 | 
			
		||||
				int width = cell->getParam(ID(WIDTH)).as_int();
 | 
			
		||||
				int width = cell->getParam(ID::WIDTH).as_int();
 | 
			
		||||
				int width_bits = ceil_log2(width);
 | 
			
		||||
				int extwidth = width;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -379,7 +379,7 @@ struct Pmux2ShiftxPass : public Pass {
 | 
			
		|||
 | 
			
		||||
				SigSpec A = cell->getPort(ID::A);
 | 
			
		||||
				SigSpec B = cell->getPort(ID::B);
 | 
			
		||||
				SigSpec S = sigmap(cell->getPort(ID(S)));
 | 
			
		||||
				SigSpec S = sigmap(cell->getPort(ID::S));
 | 
			
		||||
				for (int i = 0; i < GetSize(S); i++)
 | 
			
		||||
				{
 | 
			
		||||
					if (!eqdb.count(S[i]))
 | 
			
		||||
| 
						 | 
				
			
			@ -400,7 +400,7 @@ struct Pmux2ShiftxPass : public Pass {
 | 
			
		|||
					log("  data width: %d (next power-of-2 = %d, log2 = %d)\n", width, extwidth, width_bits);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				SigSpec updated_S = cell->getPort(ID(S));
 | 
			
		||||
				SigSpec updated_S = cell->getPort(ID::S);
 | 
			
		||||
				SigSpec updated_B = cell->getPort(ID::B);
 | 
			
		||||
 | 
			
		||||
				while (!seldb.empty())
 | 
			
		||||
| 
						 | 
				
			
			@ -727,9 +727,9 @@ struct Pmux2ShiftxPass : public Pass {
 | 
			
		|||
				}
 | 
			
		||||
 | 
			
		||||
				// update $pmux cell
 | 
			
		||||
				cell->setPort(ID(S), updated_S);
 | 
			
		||||
				cell->setPort(ID::S, updated_S);
 | 
			
		||||
				cell->setPort(ID::B, updated_B);
 | 
			
		||||
				cell->setParam(ID(S_WIDTH), GetSize(updated_S));
 | 
			
		||||
				cell->setParam(ID::S_WIDTH, GetSize(updated_S));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -785,16 +785,16 @@ struct OnehotPass : public Pass {
 | 
			
		|||
				SigSpec A = sigmap(cell->getPort(ID::A));
 | 
			
		||||
				SigSpec B = sigmap(cell->getPort(ID::B));
 | 
			
		||||
 | 
			
		||||
				int a_width = cell->getParam(ID(A_WIDTH)).as_int();
 | 
			
		||||
				int b_width = cell->getParam(ID(B_WIDTH)).as_int();
 | 
			
		||||
				int a_width = cell->getParam(ID::A_WIDTH).as_int();
 | 
			
		||||
				int b_width = cell->getParam(ID::B_WIDTH).as_int();
 | 
			
		||||
 | 
			
		||||
				if (a_width < b_width) {
 | 
			
		||||
					bool a_signed = cell->getParam(ID(A_SIGNED)).as_int();
 | 
			
		||||
					bool a_signed = cell->getParam(ID::A_SIGNED).as_int();
 | 
			
		||||
					A.extend_u0(b_width, a_signed);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (b_width < a_width) {
 | 
			
		||||
					bool b_signed = cell->getParam(ID(B_SIGNED)).as_int();
 | 
			
		||||
					bool b_signed = cell->getParam(ID::B_SIGNED).as_int();
 | 
			
		||||
					B.extend_u0(a_width, b_signed);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,7 +90,7 @@ struct ShareWorker
 | 
			
		|||
 | 
			
		||||
			for (auto &pbit : portbits) {
 | 
			
		||||
				if (pbit.cell->type == ID($mux) || pbit.cell->type == ID($pmux)) {
 | 
			
		||||
					pool<RTLIL::SigBit> bits = modwalker.sigmap(pbit.cell->getPort(ID(S))).to_sigbit_pool();
 | 
			
		||||
					pool<RTLIL::SigBit> bits = modwalker.sigmap(pbit.cell->getPort(ID::S)).to_sigbit_pool();
 | 
			
		||||
					terminal_bits.insert(bits.begin(), bits.end());
 | 
			
		||||
					queue_bits.insert(bits.begin(), bits.end());
 | 
			
		||||
					visited_cells.insert(pbit.cell);
 | 
			
		||||
| 
						 | 
				
			
			@ -331,7 +331,7 @@ struct ShareWorker
 | 
			
		|||
			supercell_aux->insert(module->addPos(NEW_ID, sig_y, c1->getPort(ID::Y)));
 | 
			
		||||
			supercell_aux->insert(module->addPos(NEW_ID, sig_y, c2->getPort(ID::Y)));
 | 
			
		||||
 | 
			
		||||
			supercell->setParam(ID(Y_WIDTH), width);
 | 
			
		||||
			supercell->setParam(ID::Y_WIDTH, width);
 | 
			
		||||
			supercell->setPort(ID::Y, sig_y);
 | 
			
		||||
 | 
			
		||||
			supermacc.optimize(width);
 | 
			
		||||
| 
						 | 
				
			
			@ -369,21 +369,21 @@ struct ShareWorker
 | 
			
		|||
			}
 | 
			
		||||
 | 
			
		||||
			if (cell->type == ID($memrd)) {
 | 
			
		||||
				if (cell->parameters.at(ID(CLK_ENABLE)).as_bool())
 | 
			
		||||
				if (cell->parameters.at(ID::CLK_ENABLE).as_bool())
 | 
			
		||||
					continue;
 | 
			
		||||
				if (config.opt_aggressive || !modwalker.sigmap(cell->getPort(ID(ADDR))).is_fully_const())
 | 
			
		||||
				if (config.opt_aggressive || !modwalker.sigmap(cell->getPort(ID::ADDR)).is_fully_const())
 | 
			
		||||
					shareable_cells.insert(cell);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in(ID($mul), ID($div), ID($mod))) {
 | 
			
		||||
				if (config.opt_aggressive || cell->parameters.at(ID(Y_WIDTH)).as_int() >= 4)
 | 
			
		||||
				if (config.opt_aggressive || cell->parameters.at(ID::Y_WIDTH).as_int() >= 4)
 | 
			
		||||
					shareable_cells.insert(cell);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in(ID($shl), ID($shr), ID($sshl), ID($sshr))) {
 | 
			
		||||
				if (config.opt_aggressive || cell->parameters.at(ID(Y_WIDTH)).as_int() >= 8)
 | 
			
		||||
				if (config.opt_aggressive || cell->parameters.at(ID::Y_WIDTH).as_int() >= 8)
 | 
			
		||||
					shareable_cells.insert(cell);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -403,7 +403,7 @@ struct ShareWorker
 | 
			
		|||
 | 
			
		||||
		if (c1->type == ID($memrd))
 | 
			
		||||
		{
 | 
			
		||||
			if (c1->parameters.at(ID(MEMID)).decode_string() != c2->parameters.at(ID(MEMID)).decode_string())
 | 
			
		||||
			if (c1->parameters.at(ID::MEMID).decode_string() != c2->parameters.at(ID::MEMID).decode_string())
 | 
			
		||||
				return false;
 | 
			
		||||
 | 
			
		||||
			return true;
 | 
			
		||||
| 
						 | 
				
			
			@ -413,11 +413,11 @@ struct ShareWorker
 | 
			
		|||
		{
 | 
			
		||||
			if (!config.opt_aggressive)
 | 
			
		||||
			{
 | 
			
		||||
				int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int();
 | 
			
		||||
				int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int();
 | 
			
		||||
				int a1_width = c1->parameters.at(ID::A_WIDTH).as_int();
 | 
			
		||||
				int y1_width = c1->parameters.at(ID::Y_WIDTH).as_int();
 | 
			
		||||
 | 
			
		||||
				int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int();
 | 
			
		||||
				int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int();
 | 
			
		||||
				int a2_width = c2->parameters.at(ID::A_WIDTH).as_int();
 | 
			
		||||
				int y2_width = c2->parameters.at(ID::Y_WIDTH).as_int();
 | 
			
		||||
 | 
			
		||||
				if (max(a1_width, a2_width) > 2 * min(a1_width, a2_width)) return false;
 | 
			
		||||
				if (max(y1_width, y2_width) > 2 * min(y1_width, y2_width)) return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -430,13 +430,13 @@ struct ShareWorker
 | 
			
		|||
		{
 | 
			
		||||
			if (!config.opt_aggressive)
 | 
			
		||||
			{
 | 
			
		||||
				int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int();
 | 
			
		||||
				int b1_width = c1->parameters.at(ID(B_WIDTH)).as_int();
 | 
			
		||||
				int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int();
 | 
			
		||||
				int a1_width = c1->parameters.at(ID::A_WIDTH).as_int();
 | 
			
		||||
				int b1_width = c1->parameters.at(ID::B_WIDTH).as_int();
 | 
			
		||||
				int y1_width = c1->parameters.at(ID::Y_WIDTH).as_int();
 | 
			
		||||
 | 
			
		||||
				int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int();
 | 
			
		||||
				int b2_width = c2->parameters.at(ID(B_WIDTH)).as_int();
 | 
			
		||||
				int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int();
 | 
			
		||||
				int a2_width = c2->parameters.at(ID::A_WIDTH).as_int();
 | 
			
		||||
				int b2_width = c2->parameters.at(ID::B_WIDTH).as_int();
 | 
			
		||||
				int y2_width = c2->parameters.at(ID::Y_WIDTH).as_int();
 | 
			
		||||
 | 
			
		||||
				if (max(a1_width, a2_width) > 2 * min(a1_width, a2_width)) return false;
 | 
			
		||||
				if (max(b1_width, b2_width) > 2 * min(b1_width, b2_width)) return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -450,13 +450,13 @@ struct ShareWorker
 | 
			
		|||
		{
 | 
			
		||||
			if (!config.opt_aggressive)
 | 
			
		||||
			{
 | 
			
		||||
				int a1_width = c1->parameters.at(ID(A_WIDTH)).as_int();
 | 
			
		||||
				int b1_width = c1->parameters.at(ID(B_WIDTH)).as_int();
 | 
			
		||||
				int y1_width = c1->parameters.at(ID(Y_WIDTH)).as_int();
 | 
			
		||||
				int a1_width = c1->parameters.at(ID::A_WIDTH).as_int();
 | 
			
		||||
				int b1_width = c1->parameters.at(ID::B_WIDTH).as_int();
 | 
			
		||||
				int y1_width = c1->parameters.at(ID::Y_WIDTH).as_int();
 | 
			
		||||
 | 
			
		||||
				int a2_width = c2->parameters.at(ID(A_WIDTH)).as_int();
 | 
			
		||||
				int b2_width = c2->parameters.at(ID(B_WIDTH)).as_int();
 | 
			
		||||
				int y2_width = c2->parameters.at(ID(Y_WIDTH)).as_int();
 | 
			
		||||
				int a2_width = c2->parameters.at(ID::A_WIDTH).as_int();
 | 
			
		||||
				int b2_width = c2->parameters.at(ID::B_WIDTH).as_int();
 | 
			
		||||
				int y2_width = c2->parameters.at(ID::Y_WIDTH).as_int();
 | 
			
		||||
 | 
			
		||||
				int min1_width = min(a1_width, b1_width);
 | 
			
		||||
				int max1_width = max(a1_width, b1_width);
 | 
			
		||||
| 
						 | 
				
			
			@ -510,21 +510,21 @@ struct ShareWorker
 | 
			
		|||
 | 
			
		||||
		if (config.generic_uni_ops.count(c1->type))
 | 
			
		||||
		{
 | 
			
		||||
			if (c1->parameters.at(ID(A_SIGNED)).as_bool() != c2->parameters.at(ID(A_SIGNED)).as_bool())
 | 
			
		||||
			if (c1->parameters.at(ID::A_SIGNED).as_bool() != c2->parameters.at(ID::A_SIGNED).as_bool())
 | 
			
		||||
			{
 | 
			
		||||
				RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1;
 | 
			
		||||
				RTLIL::Cell *unsigned_cell = c1->parameters.at(ID::A_SIGNED).as_bool() ? c2 : c1;
 | 
			
		||||
				if (unsigned_cell->getPort(ID::A).to_sigbit_vector().back() != RTLIL::State::S0) {
 | 
			
		||||
					unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1;
 | 
			
		||||
					unsigned_cell->parameters.at(ID::A_WIDTH) = unsigned_cell->parameters.at(ID::A_WIDTH).as_int() + 1;
 | 
			
		||||
					RTLIL::SigSpec new_a = unsigned_cell->getPort(ID::A);
 | 
			
		||||
					new_a.append(RTLIL::State::S0);
 | 
			
		||||
					unsigned_cell->setPort(ID::A, new_a);
 | 
			
		||||
				}
 | 
			
		||||
				unsigned_cell->parameters.at(ID(A_SIGNED)) = true;
 | 
			
		||||
				unsigned_cell->parameters.at(ID::A_SIGNED) = true;
 | 
			
		||||
				unsigned_cell->check();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			bool a_signed = c1->parameters.at(ID(A_SIGNED)).as_bool();
 | 
			
		||||
			log_assert(a_signed == c2->parameters.at(ID(A_SIGNED)).as_bool());
 | 
			
		||||
			bool a_signed = c1->parameters.at(ID::A_SIGNED).as_bool();
 | 
			
		||||
			log_assert(a_signed == c2->parameters.at(ID::A_SIGNED).as_bool());
 | 
			
		||||
 | 
			
		||||
			RTLIL::SigSpec a1 = c1->getPort(ID::A);
 | 
			
		||||
			RTLIL::SigSpec y1 = c1->getPort(ID::Y);
 | 
			
		||||
| 
						 | 
				
			
			@ -544,9 +544,9 @@ struct ShareWorker
 | 
			
		|||
			RTLIL::Wire *y = module->addWire(NEW_ID, y_width);
 | 
			
		||||
 | 
			
		||||
			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type);
 | 
			
		||||
			supercell->parameters[ID(A_SIGNED)] = a_signed;
 | 
			
		||||
			supercell->parameters[ID(A_WIDTH)] = a_width;
 | 
			
		||||
			supercell->parameters[ID(Y_WIDTH)] = y_width;
 | 
			
		||||
			supercell->parameters[ID::A_SIGNED] = a_signed;
 | 
			
		||||
			supercell->parameters[ID::A_WIDTH] = a_width;
 | 
			
		||||
			supercell->parameters[ID::Y_WIDTH] = y_width;
 | 
			
		||||
			supercell->setPort(ID::A, a);
 | 
			
		||||
			supercell->setPort(ID::Y, y);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -563,11 +563,11 @@ struct ShareWorker
 | 
			
		|||
 | 
			
		||||
			if (config.generic_cbin_ops.count(c1->type))
 | 
			
		||||
			{
 | 
			
		||||
				int score_unflipped = max(c1->parameters.at(ID(A_WIDTH)).as_int(), c2->parameters.at(ID(A_WIDTH)).as_int()) +
 | 
			
		||||
						max(c1->parameters.at(ID(B_WIDTH)).as_int(), c2->parameters.at(ID(B_WIDTH)).as_int());
 | 
			
		||||
				int score_unflipped = max(c1->parameters.at(ID::A_WIDTH).as_int(), c2->parameters.at(ID::A_WIDTH).as_int()) +
 | 
			
		||||
						max(c1->parameters.at(ID::B_WIDTH).as_int(), c2->parameters.at(ID::B_WIDTH).as_int());
 | 
			
		||||
 | 
			
		||||
				int score_flipped = max(c1->parameters.at(ID(A_WIDTH)).as_int(), c2->parameters.at(ID(B_WIDTH)).as_int()) +
 | 
			
		||||
						max(c1->parameters.at(ID(B_WIDTH)).as_int(), c2->parameters.at(ID(A_WIDTH)).as_int());
 | 
			
		||||
				int score_flipped = max(c1->parameters.at(ID::A_WIDTH).as_int(), c2->parameters.at(ID::B_WIDTH).as_int()) +
 | 
			
		||||
						max(c1->parameters.at(ID::B_WIDTH).as_int(), c2->parameters.at(ID::A_WIDTH).as_int());
 | 
			
		||||
 | 
			
		||||
				if (score_flipped < score_unflipped)
 | 
			
		||||
				{
 | 
			
		||||
| 
						 | 
				
			
			@ -575,36 +575,36 @@ struct ShareWorker
 | 
			
		|||
					c2->setPort(ID::A, c2->getPort(ID::B));
 | 
			
		||||
					c2->setPort(ID::B, tmp);
 | 
			
		||||
 | 
			
		||||
					std::swap(c2->parameters.at(ID(A_WIDTH)), c2->parameters.at(ID(B_WIDTH)));
 | 
			
		||||
					std::swap(c2->parameters.at(ID(A_SIGNED)), c2->parameters.at(ID(B_SIGNED)));
 | 
			
		||||
					std::swap(c2->parameters.at(ID::A_WIDTH), c2->parameters.at(ID::B_WIDTH));
 | 
			
		||||
					std::swap(c2->parameters.at(ID::A_SIGNED), c2->parameters.at(ID::B_SIGNED));
 | 
			
		||||
					modified_src_cells = true;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (c1->parameters.at(ID(A_SIGNED)).as_bool() != c2->parameters.at(ID(A_SIGNED)).as_bool())
 | 
			
		||||
			if (c1->parameters.at(ID::A_SIGNED).as_bool() != c2->parameters.at(ID::A_SIGNED).as_bool())
 | 
			
		||||
 | 
			
		||||
			{
 | 
			
		||||
				RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(A_SIGNED)).as_bool() ? c2 : c1;
 | 
			
		||||
				RTLIL::Cell *unsigned_cell = c1->parameters.at(ID::A_SIGNED).as_bool() ? c2 : c1;
 | 
			
		||||
				if (unsigned_cell->getPort(ID::A).to_sigbit_vector().back() != RTLIL::State::S0) {
 | 
			
		||||
					unsigned_cell->parameters.at(ID(A_WIDTH)) = unsigned_cell->parameters.at(ID(A_WIDTH)).as_int() + 1;
 | 
			
		||||
					unsigned_cell->parameters.at(ID::A_WIDTH) = unsigned_cell->parameters.at(ID::A_WIDTH).as_int() + 1;
 | 
			
		||||
					RTLIL::SigSpec new_a = unsigned_cell->getPort(ID::A);
 | 
			
		||||
					new_a.append(RTLIL::State::S0);
 | 
			
		||||
					unsigned_cell->setPort(ID::A, new_a);
 | 
			
		||||
				}
 | 
			
		||||
				unsigned_cell->parameters.at(ID(A_SIGNED)) = true;
 | 
			
		||||
				unsigned_cell->parameters.at(ID::A_SIGNED) = true;
 | 
			
		||||
				modified_src_cells = true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (c1->parameters.at(ID(B_SIGNED)).as_bool() != c2->parameters.at(ID(B_SIGNED)).as_bool())
 | 
			
		||||
			if (c1->parameters.at(ID::B_SIGNED).as_bool() != c2->parameters.at(ID::B_SIGNED).as_bool())
 | 
			
		||||
			{
 | 
			
		||||
				RTLIL::Cell *unsigned_cell = c1->parameters.at(ID(B_SIGNED)).as_bool() ? c2 : c1;
 | 
			
		||||
				RTLIL::Cell *unsigned_cell = c1->parameters.at(ID::B_SIGNED).as_bool() ? c2 : c1;
 | 
			
		||||
				if (unsigned_cell->getPort(ID::B).to_sigbit_vector().back() != RTLIL::State::S0) {
 | 
			
		||||
					unsigned_cell->parameters.at(ID(B_WIDTH)) = unsigned_cell->parameters.at(ID(B_WIDTH)).as_int() + 1;
 | 
			
		||||
					unsigned_cell->parameters.at(ID::B_WIDTH) = unsigned_cell->parameters.at(ID::B_WIDTH).as_int() + 1;
 | 
			
		||||
					RTLIL::SigSpec new_b = unsigned_cell->getPort(ID::B);
 | 
			
		||||
					new_b.append(RTLIL::State::S0);
 | 
			
		||||
					unsigned_cell->setPort(ID::B, new_b);
 | 
			
		||||
				}
 | 
			
		||||
				unsigned_cell->parameters.at(ID(B_SIGNED)) = true;
 | 
			
		||||
				unsigned_cell->parameters.at(ID::B_SIGNED) = true;
 | 
			
		||||
				modified_src_cells = true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -613,11 +613,11 @@ struct ShareWorker
 | 
			
		|||
				c2->check();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			bool a_signed = c1->parameters.at(ID(A_SIGNED)).as_bool();
 | 
			
		||||
			bool b_signed = c1->parameters.at(ID(B_SIGNED)).as_bool();
 | 
			
		||||
			bool a_signed = c1->parameters.at(ID::A_SIGNED).as_bool();
 | 
			
		||||
			bool b_signed = c1->parameters.at(ID::B_SIGNED).as_bool();
 | 
			
		||||
 | 
			
		||||
			log_assert(a_signed == c2->parameters.at(ID(A_SIGNED)).as_bool());
 | 
			
		||||
			log_assert(b_signed == c2->parameters.at(ID(B_SIGNED)).as_bool());
 | 
			
		||||
			log_assert(a_signed == c2->parameters.at(ID::A_SIGNED).as_bool());
 | 
			
		||||
			log_assert(b_signed == c2->parameters.at(ID::B_SIGNED).as_bool());
 | 
			
		||||
 | 
			
		||||
			if (c1->type == ID($shl) || c1->type == ID($shr) || c1->type == ID($sshl) || c1->type == ID($sshr))
 | 
			
		||||
				b_signed = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -664,32 +664,32 @@ struct ShareWorker
 | 
			
		|||
			RTLIL::Wire *co = c1->type == ID($alu) ? module->addWire(NEW_ID, y_width) : nullptr;
 | 
			
		||||
 | 
			
		||||
			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1->type);
 | 
			
		||||
			supercell->parameters[ID(A_SIGNED)] = a_signed;
 | 
			
		||||
			supercell->parameters[ID(B_SIGNED)] = b_signed;
 | 
			
		||||
			supercell->parameters[ID(A_WIDTH)] = a_width;
 | 
			
		||||
			supercell->parameters[ID(B_WIDTH)] = b_width;
 | 
			
		||||
			supercell->parameters[ID(Y_WIDTH)] = y_width;
 | 
			
		||||
			supercell->parameters[ID::A_SIGNED] = a_signed;
 | 
			
		||||
			supercell->parameters[ID::B_SIGNED] = b_signed;
 | 
			
		||||
			supercell->parameters[ID::A_WIDTH] = a_width;
 | 
			
		||||
			supercell->parameters[ID::B_WIDTH] = b_width;
 | 
			
		||||
			supercell->parameters[ID::Y_WIDTH] = y_width;
 | 
			
		||||
			supercell->setPort(ID::A, a);
 | 
			
		||||
			supercell->setPort(ID::B, b);
 | 
			
		||||
			supercell->setPort(ID::Y, y);
 | 
			
		||||
			if (c1->type == ID($alu)) {
 | 
			
		||||
				RTLIL::Wire *ci = module->addWire(NEW_ID), *bi = module->addWire(NEW_ID);
 | 
			
		||||
				supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID(CI)), c1->getPort(ID(CI)), act, ci));
 | 
			
		||||
				supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID(BI)), c1->getPort(ID(BI)), act, bi));
 | 
			
		||||
				supercell->setPort(ID(CI), ci);
 | 
			
		||||
				supercell->setPort(ID(BI), bi);
 | 
			
		||||
				supercell->setPort(ID(CO), co);
 | 
			
		||||
				supercell->setPort(ID(X), x);
 | 
			
		||||
				supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID::CI), c1->getPort(ID::CI), act, ci));
 | 
			
		||||
				supercell_aux.insert(module->addMux(NEW_ID, c2->getPort(ID::BI), c1->getPort(ID::BI), act, bi));
 | 
			
		||||
				supercell->setPort(ID::CI, ci);
 | 
			
		||||
				supercell->setPort(ID::BI, bi);
 | 
			
		||||
				supercell->setPort(ID::CO, co);
 | 
			
		||||
				supercell->setPort(ID::X, x);
 | 
			
		||||
			}
 | 
			
		||||
			supercell->check();
 | 
			
		||||
 | 
			
		||||
			supercell_aux.insert(module->addPos(NEW_ID, y, y1));
 | 
			
		||||
			supercell_aux.insert(module->addPos(NEW_ID, y, y2));
 | 
			
		||||
			if (c1->type == ID($alu)) {
 | 
			
		||||
				supercell_aux.insert(module->addPos(NEW_ID, co, c1->getPort(ID(CO))));
 | 
			
		||||
				supercell_aux.insert(module->addPos(NEW_ID, co, c2->getPort(ID(CO))));
 | 
			
		||||
				supercell_aux.insert(module->addPos(NEW_ID, x, c1->getPort(ID(X))));
 | 
			
		||||
				supercell_aux.insert(module->addPos(NEW_ID, x, c2->getPort(ID(X))));
 | 
			
		||||
				supercell_aux.insert(module->addPos(NEW_ID, co, c1->getPort(ID::CO)));
 | 
			
		||||
				supercell_aux.insert(module->addPos(NEW_ID, co, c2->getPort(ID::CO)));
 | 
			
		||||
				supercell_aux.insert(module->addPos(NEW_ID, x, c1->getPort(ID::X)));
 | 
			
		||||
				supercell_aux.insert(module->addPos(NEW_ID, x, c2->getPort(ID::X)));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			supercell_aux.insert(supercell);
 | 
			
		||||
| 
						 | 
				
			
			@ -708,15 +708,15 @@ struct ShareWorker
 | 
			
		|||
		if (c1->type == ID($memrd))
 | 
			
		||||
		{
 | 
			
		||||
			RTLIL::Cell *supercell = module->addCell(NEW_ID, c1);
 | 
			
		||||
			RTLIL::SigSpec addr1 = c1->getPort(ID(ADDR));
 | 
			
		||||
			RTLIL::SigSpec addr2 = c2->getPort(ID(ADDR));
 | 
			
		||||
			RTLIL::SigSpec addr1 = c1->getPort(ID::ADDR);
 | 
			
		||||
			RTLIL::SigSpec addr2 = c2->getPort(ID::ADDR);
 | 
			
		||||
			if (GetSize(addr1) < GetSize(addr2))
 | 
			
		||||
				addr1.extend_u0(GetSize(addr2));
 | 
			
		||||
			else
 | 
			
		||||
				addr2.extend_u0(GetSize(addr1));
 | 
			
		||||
			supercell->setPort(ID(ADDR), addr1 != addr2 ? module->Mux(NEW_ID, addr2, addr1, act) : addr1);
 | 
			
		||||
			supercell->parameters[ID(ABITS)] = RTLIL::Const(GetSize(addr1));
 | 
			
		||||
			supercell_aux.insert(module->addPos(NEW_ID, supercell->getPort(ID(DATA)), c2->getPort(ID(DATA))));
 | 
			
		||||
			supercell->setPort(ID::ADDR, addr1 != addr2 ? module->Mux(NEW_ID, addr2, addr1, act) : addr1);
 | 
			
		||||
			supercell->parameters[ID::ABITS] = RTLIL::Const(GetSize(addr1));
 | 
			
		||||
			supercell_aux.insert(module->addPos(NEW_ID, supercell->getPort(ID::DATA), c2->getPort(ID::DATA)));
 | 
			
		||||
			supercell_aux.insert(supercell);
 | 
			
		||||
			return supercell;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -747,8 +747,8 @@ struct ShareWorker
 | 
			
		|||
		modwalker.get_consumers(pbits, modwalker.cell_outputs[cell]);
 | 
			
		||||
 | 
			
		||||
		for (auto &bit : pbits) {
 | 
			
		||||
			if ((bit.cell->type == ID($mux) || bit.cell->type == ID($pmux)) && bit.port == ID(S))
 | 
			
		||||
				forbidden_controls_cache[cell].insert(bit.cell->getPort(ID(S)).extract(bit.offset, 1));
 | 
			
		||||
			if ((bit.cell->type == ID($mux) || bit.cell->type == ID($pmux)) && bit.port == ID::S)
 | 
			
		||||
				forbidden_controls_cache[cell].insert(bit.cell->getPort(ID::S).extract(bit.offset, 1));
 | 
			
		||||
			consumer_cells.insert(bit.cell);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -890,10 +890,10 @@ struct ShareWorker
 | 
			
		|||
			bool used_in_a = false;
 | 
			
		||||
			std::set<int> used_in_b_parts;
 | 
			
		||||
 | 
			
		||||
			int width = c->parameters.at(ID(WIDTH)).as_int();
 | 
			
		||||
			int width = c->parameters.at(ID::WIDTH).as_int();
 | 
			
		||||
			std::vector<RTLIL::SigBit> sig_a = modwalker.sigmap(c->getPort(ID::A));
 | 
			
		||||
			std::vector<RTLIL::SigBit> sig_b = modwalker.sigmap(c->getPort(ID::B));
 | 
			
		||||
			std::vector<RTLIL::SigBit> sig_s = modwalker.sigmap(c->getPort(ID(S)));
 | 
			
		||||
			std::vector<RTLIL::SigBit> sig_s = modwalker.sigmap(c->getPort(ID::S));
 | 
			
		||||
 | 
			
		||||
			for (auto &bit : sig_a)
 | 
			
		||||
				if (cell_out_bits.count(bit))
 | 
			
		||||
| 
						 | 
				
			
			@ -1171,8 +1171,8 @@ struct ShareWorker
 | 
			
		|||
 | 
			
		||||
		for (auto cell : module->cells())
 | 
			
		||||
			if (cell->type == ID($pmux))
 | 
			
		||||
				for (auto bit : cell->getPort(ID(S)))
 | 
			
		||||
				for (auto other_bit : cell->getPort(ID(S)))
 | 
			
		||||
				for (auto bit : cell->getPort(ID::S))
 | 
			
		||||
				for (auto other_bit : cell->getPort(ID::S))
 | 
			
		||||
					if (bit < other_bit)
 | 
			
		||||
						exclusive_ctrls.push_back(std::pair<RTLIL::SigBit, RTLIL::SigBit>(bit, other_bit));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -65,7 +65,7 @@ struct WreduceWorker
 | 
			
		|||
 | 
			
		||||
		SigSpec sig_a = mi.sigmap(cell->getPort(ID::A));
 | 
			
		||||
		SigSpec sig_b = mi.sigmap(cell->getPort(ID::B));
 | 
			
		||||
		SigSpec sig_s = mi.sigmap(cell->getPort(ID(S)));
 | 
			
		||||
		SigSpec sig_s = mi.sigmap(cell->getPort(ID::S));
 | 
			
		||||
		SigSpec sig_y = mi.sigmap(cell->getPort(ID::Y));
 | 
			
		||||
		std::vector<SigBit> bits_removed;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -141,8 +141,8 @@ struct WreduceWorker
 | 
			
		|||
	{
 | 
			
		||||
		// Reduce size of FF if inputs are just sign/zero extended or output bit is not used
 | 
			
		||||
 | 
			
		||||
		SigSpec sig_d = mi.sigmap(cell->getPort(ID(D)));
 | 
			
		||||
		SigSpec sig_q = mi.sigmap(cell->getPort(ID(Q)));
 | 
			
		||||
		SigSpec sig_d = mi.sigmap(cell->getPort(ID::D));
 | 
			
		||||
		SigSpec sig_q = mi.sigmap(cell->getPort(ID::Q));
 | 
			
		||||
		bool is_adff = (cell->type == ID($adff));
 | 
			
		||||
		Const initval, arst_value;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -151,8 +151,8 @@ struct WreduceWorker
 | 
			
		|||
		if (width_before == 0)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		if (cell->parameters.count(ID(ARST_VALUE))) {
 | 
			
		||||
			arst_value = cell->parameters[ID(ARST_VALUE)];
 | 
			
		||||
		if (cell->parameters.count(ID::ARST_VALUE)) {
 | 
			
		||||
			arst_value = cell->parameters[ID::ARST_VALUE];
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		bool zero_ext = sig_d[GetSize(sig_d)-1] == State::S0;
 | 
			
		||||
| 
						 | 
				
			
			@ -220,13 +220,13 @@ struct WreduceWorker
 | 
			
		|||
			work_queue_bits.insert(bit);
 | 
			
		||||
 | 
			
		||||
		// Narrow ARST_VALUE parameter to new size.
 | 
			
		||||
		if (cell->parameters.count(ID(ARST_VALUE))) {
 | 
			
		||||
		if (cell->parameters.count(ID::ARST_VALUE)) {
 | 
			
		||||
			arst_value.bits.resize(GetSize(sig_q));
 | 
			
		||||
			cell->setParam(ID(ARST_VALUE), arst_value);
 | 
			
		||||
			cell->setParam(ID::ARST_VALUE, arst_value);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		cell->setPort(ID(D), sig_d);
 | 
			
		||||
		cell->setPort(ID(Q), sig_q);
 | 
			
		||||
		cell->setPort(ID::D, sig_d);
 | 
			
		||||
		cell->setPort(ID::Q, sig_q);
 | 
			
		||||
		cell->fixup_parameters();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -306,8 +306,8 @@ struct WreduceWorker
 | 
			
		|||
					GetSize(sig_b) > 0 && sig_b[GetSize(sig_b)-1] == State::S0) {
 | 
			
		||||
				log("Converting cell %s.%s (%s) from signed to unsigned.\n",
 | 
			
		||||
						log_id(module), log_id(cell), log_id(cell->type));
 | 
			
		||||
				cell->setParam(ID(A_SIGNED), 0);
 | 
			
		||||
				cell->setParam(ID(B_SIGNED), 0);
 | 
			
		||||
				cell->setParam(ID::A_SIGNED, 0);
 | 
			
		||||
				cell->setParam(ID::B_SIGNED, 0);
 | 
			
		||||
				port_a_signed = false;
 | 
			
		||||
				port_b_signed = false;
 | 
			
		||||
				did_something = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -319,7 +319,7 @@ struct WreduceWorker
 | 
			
		|||
			if (GetSize(sig_a) > 0 && sig_a[GetSize(sig_a)-1] == State::S0) {
 | 
			
		||||
				log("Converting cell %s.%s (%s) from signed to unsigned.\n",
 | 
			
		||||
						log_id(module), log_id(cell), log_id(cell->type));
 | 
			
		||||
				cell->setParam(ID(A_SIGNED), 0);
 | 
			
		||||
				cell->setParam(ID::A_SIGNED, 0);
 | 
			
		||||
				port_a_signed = false;
 | 
			
		||||
				did_something = true;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -349,7 +349,7 @@ struct WreduceWorker
 | 
			
		|||
 | 
			
		||||
		if (cell->type.in(ID($pos), ID($add), ID($mul), ID($and), ID($or), ID($xor), ID($sub)))
 | 
			
		||||
		{
 | 
			
		||||
			bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool() || cell->type == ID($sub);
 | 
			
		||||
			bool is_signed = cell->getParam(ID::A_SIGNED).as_bool() || cell->type == ID($sub);
 | 
			
		||||
 | 
			
		||||
			int a_size = 0, b_size = 0;
 | 
			
		||||
			if (cell->hasPort(ID::A)) a_size = GetSize(cell->getPort(ID::A));
 | 
			
		||||
| 
						 | 
				
			
			@ -392,8 +392,8 @@ struct WreduceWorker
 | 
			
		|||
	static int count_nontrivial_wire_attrs(RTLIL::Wire *w)
 | 
			
		||||
	{
 | 
			
		||||
		int count = w->attributes.size();
 | 
			
		||||
		count -= w->attributes.count(ID(src));
 | 
			
		||||
		count -= w->attributes.count(ID(unused_bits));
 | 
			
		||||
		count -= w->attributes.count(ID::src);
 | 
			
		||||
		count -= w->attributes.count(ID::unused_bits);
 | 
			
		||||
		return count;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -406,8 +406,8 @@ struct WreduceWorker
 | 
			
		|||
			if (w->get_bool_attribute(ID::keep))
 | 
			
		||||
				for (auto bit : mi.sigmap(w))
 | 
			
		||||
					keep_bits.insert(bit);
 | 
			
		||||
			if (w->attributes.count(ID(init))) {
 | 
			
		||||
				Const initval = w->attributes.at(ID(init));
 | 
			
		||||
			if (w->attributes.count(ID::init)) {
 | 
			
		||||
				Const initval = w->attributes.at(ID::init);
 | 
			
		||||
				SigSpec initsig = init_attr_sigmap(w);
 | 
			
		||||
				int width = std::min(GetSize(initval), GetSize(initsig));
 | 
			
		||||
				for (int i = 0; i < width; i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -464,8 +464,8 @@ struct WreduceWorker
 | 
			
		|||
 | 
			
		||||
		if (!remove_init_bits.empty()) {
 | 
			
		||||
			for (auto w : module->wires()) {
 | 
			
		||||
				if (w->attributes.count(ID(init))) {
 | 
			
		||||
					Const initval = w->attributes.at(ID(init));
 | 
			
		||||
				if (w->attributes.count(ID::init)) {
 | 
			
		||||
					Const initval = w->attributes.at(ID::init);
 | 
			
		||||
					Const new_initval(State::Sx, GetSize(w));
 | 
			
		||||
					SigSpec initsig = init_attr_sigmap(w);
 | 
			
		||||
					int width = std::min(GetSize(initval), GetSize(initsig));
 | 
			
		||||
| 
						 | 
				
			
			@ -473,7 +473,7 @@ struct WreduceWorker
 | 
			
		|||
						if (!remove_init_bits.count(initsig[i]))
 | 
			
		||||
							new_initval[i] = initval[i];
 | 
			
		||||
					}
 | 
			
		||||
					w->attributes.at(ID(init)) = new_initval;
 | 
			
		||||
					w->attributes.at(ID::init) = new_initval;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -539,7 +539,7 @@ struct WreducePass : public Pass {
 | 
			
		|||
					SigSpec sig = c->getPort(ID::Y);
 | 
			
		||||
					if (!sig.has_const()) {
 | 
			
		||||
						c->setPort(ID::Y, sig[0]);
 | 
			
		||||
						c->setParam(ID(Y_WIDTH), 1);
 | 
			
		||||
						c->setParam(ID::Y_WIDTH, 1);
 | 
			
		||||
						sig.remove(0);
 | 
			
		||||
						module->connect(sig, Const(0, GetSize(sig)));
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			@ -549,7 +549,7 @@ struct WreducePass : public Pass {
 | 
			
		|||
				{
 | 
			
		||||
					SigSpec A = c->getPort(ID::A);
 | 
			
		||||
					int original_a_width = GetSize(A);
 | 
			
		||||
					if (c->getParam(ID(A_SIGNED)).as_bool()) {
 | 
			
		||||
					if (c->getParam(ID::A_SIGNED).as_bool()) {
 | 
			
		||||
						while (GetSize(A) > 1 && A[GetSize(A)-1] == State::S0 && A[GetSize(A)-2] == State::S0)
 | 
			
		||||
							A.remove(GetSize(A)-1, 1);
 | 
			
		||||
					} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -560,12 +560,12 @@ struct WreducePass : public Pass {
 | 
			
		|||
						log("Removed top %d bits (of %d) from port A of cell %s.%s (%s).\n",
 | 
			
		||||
								original_a_width-GetSize(A), original_a_width, log_id(module), log_id(c), log_id(c->type));
 | 
			
		||||
						c->setPort(ID::A, A);
 | 
			
		||||
						c->setParam(ID(A_WIDTH), GetSize(A));
 | 
			
		||||
						c->setParam(ID::A_WIDTH, GetSize(A));
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					SigSpec B = c->getPort(ID::B);
 | 
			
		||||
					int original_b_width = GetSize(B);
 | 
			
		||||
					if (c->getParam(ID(B_SIGNED)).as_bool()) {
 | 
			
		||||
					if (c->getParam(ID::B_SIGNED).as_bool()) {
 | 
			
		||||
						while (GetSize(B) > 1 && B[GetSize(B)-1] == State::S0 && B[GetSize(B)-2] == State::S0)
 | 
			
		||||
							B.remove(GetSize(B)-1, 1);
 | 
			
		||||
					} else {
 | 
			
		||||
| 
						 | 
				
			
			@ -576,23 +576,23 @@ struct WreducePass : public Pass {
 | 
			
		|||
						log("Removed top %d bits (of %d) from port B of cell %s.%s (%s).\n",
 | 
			
		||||
								original_b_width-GetSize(B), original_b_width, log_id(module), log_id(c), log_id(c->type));
 | 
			
		||||
						c->setPort(ID::B, B);
 | 
			
		||||
						c->setParam(ID(B_WIDTH), GetSize(B));
 | 
			
		||||
						c->setParam(ID::B_WIDTH, GetSize(B));
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (!opt_memx && c->type.in(ID($memrd), ID($memwr), ID($meminit))) {
 | 
			
		||||
					IdString memid = c->getParam(ID(MEMID)).decode_string();
 | 
			
		||||
					IdString memid = c->getParam(ID::MEMID).decode_string();
 | 
			
		||||
					RTLIL::Memory *mem = module->memories.at(memid);
 | 
			
		||||
					if (mem->start_offset >= 0) {
 | 
			
		||||
						int cur_addrbits = c->getParam(ID(ABITS)).as_int();
 | 
			
		||||
						int cur_addrbits = c->getParam(ID::ABITS).as_int();
 | 
			
		||||
						int max_addrbits = ceil_log2(mem->start_offset + mem->size);
 | 
			
		||||
						if (cur_addrbits > max_addrbits) {
 | 
			
		||||
							log("Removed top %d address bits (of %d) from memory %s port %s.%s (%s).\n",
 | 
			
		||||
									cur_addrbits-max_addrbits, cur_addrbits,
 | 
			
		||||
									c->type == ID($memrd) ? "read" : c->type == ID($memwr) ? "write" : "init",
 | 
			
		||||
									log_id(module), log_id(c), log_id(memid));
 | 
			
		||||
							c->setParam(ID(ABITS), max_addrbits);
 | 
			
		||||
							c->setPort(ID(ADDR), c->getPort(ID(ADDR)).extract(0, max_addrbits));
 | 
			
		||||
							c->setParam(ID::ABITS, max_addrbits);
 | 
			
		||||
							c->setPort(ID::ADDR, c->getPort(ID::ADDR).extract(0, max_addrbits));
 | 
			
		||||
						}
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,11 +73,11 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
 | 
			
		|||
 | 
			
		||||
	// SB_MAC16 Input Interface
 | 
			
		||||
	SigSpec A = st.sigA;
 | 
			
		||||
	A.extend_u0(16, st.mul->parameters.at(ID(A_SIGNED), State::S0).as_bool());
 | 
			
		||||
	A.extend_u0(16, st.mul->parameters.at(ID::A_SIGNED, State::S0).as_bool());
 | 
			
		||||
	log_assert(GetSize(A) == 16);
 | 
			
		||||
 | 
			
		||||
	SigSpec B = st.sigB;
 | 
			
		||||
	B.extend_u0(16, st.mul->parameters.at(ID(B_SIGNED), State::S0).as_bool());
 | 
			
		||||
	B.extend_u0(16, st.mul->parameters.at(ID::B_SIGNED, State::S0).as_bool());
 | 
			
		||||
	log_assert(GetSize(B) == 16);
 | 
			
		||||
 | 
			
		||||
	SigSpec CD = st.sigCD;
 | 
			
		||||
| 
						 | 
				
			
			@ -88,8 +88,8 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
 | 
			
		|||
 | 
			
		||||
	cell->setPort(ID::A, A);
 | 
			
		||||
	cell->setPort(ID::B, B);
 | 
			
		||||
	cell->setPort(ID(C), CD.extract(16, 16));
 | 
			
		||||
	cell->setPort(ID(D), CD.extract(0, 16));
 | 
			
		||||
	cell->setPort(ID::C, CD.extract(16, 16));
 | 
			
		||||
	cell->setPort(ID::D, CD.extract(0, 16));
 | 
			
		||||
 | 
			
		||||
	cell->setParam(ID(A_REG), st.ffA ? State::S1 : State::S0);
 | 
			
		||||
	cell->setParam(ID(B_REG), st.ffB ? State::S1 : State::S0);
 | 
			
		||||
| 
						 | 
				
			
			@ -98,15 +98,15 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
 | 
			
		|||
 | 
			
		||||
	SigSpec AHOLD, BHOLD, CDHOLD;
 | 
			
		||||
	if (st.ffAholdmux)
 | 
			
		||||
		AHOLD = st.ffAholdpol ? st.ffAholdmux->getPort(ID(S)) : pm.module->Not(NEW_ID, st.ffAholdmux->getPort(ID(S)));
 | 
			
		||||
		AHOLD = st.ffAholdpol ? st.ffAholdmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffAholdmux->getPort(ID::S));
 | 
			
		||||
	else
 | 
			
		||||
		AHOLD = State::S0;
 | 
			
		||||
	if (st.ffBholdmux)
 | 
			
		||||
		BHOLD = st.ffBholdpol ? st.ffBholdmux->getPort(ID(S)) : pm.module->Not(NEW_ID, st.ffBholdmux->getPort(ID(S)));
 | 
			
		||||
		BHOLD = st.ffBholdpol ? st.ffBholdmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffBholdmux->getPort(ID::S));
 | 
			
		||||
	else
 | 
			
		||||
		BHOLD = State::S0;
 | 
			
		||||
	if (st.ffCDholdmux)
 | 
			
		||||
		CDHOLD = st.ffCDholdpol ? st.ffCDholdmux->getPort(ID(S)) : pm.module->Not(NEW_ID, st.ffCDholdmux->getPort(ID(S)));
 | 
			
		||||
		CDHOLD = st.ffCDholdpol ? st.ffCDholdmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffCDholdmux->getPort(ID::S));
 | 
			
		||||
	else
 | 
			
		||||
		CDHOLD = State::S0;
 | 
			
		||||
	cell->setPort(ID(AHOLD), AHOLD);
 | 
			
		||||
| 
						 | 
				
			
			@ -116,11 +116,11 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
 | 
			
		|||
 | 
			
		||||
	SigSpec IRSTTOP, IRSTBOT;
 | 
			
		||||
	if (st.ffArstmux)
 | 
			
		||||
		IRSTTOP = st.ffArstpol ? st.ffArstmux->getPort(ID(S)) : pm.module->Not(NEW_ID, st.ffArstmux->getPort(ID(S)));
 | 
			
		||||
		IRSTTOP = st.ffArstpol ? st.ffArstmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffArstmux->getPort(ID::S));
 | 
			
		||||
	else
 | 
			
		||||
		IRSTTOP = State::S0;
 | 
			
		||||
	if (st.ffBrstmux)
 | 
			
		||||
		IRSTBOT = st.ffBrstpol ? st.ffBrstmux->getPort(ID(S)) : pm.module->Not(NEW_ID, st.ffBrstmux->getPort(ID(S)));
 | 
			
		||||
		IRSTBOT = st.ffBrstpol ? st.ffBrstmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffBrstmux->getPort(ID::S));
 | 
			
		||||
	else
 | 
			
		||||
		IRSTBOT = State::S0;
 | 
			
		||||
	cell->setPort(ID(IRSTTOP), IRSTTOP);
 | 
			
		||||
| 
						 | 
				
			
			@ -128,7 +128,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
 | 
			
		|||
 | 
			
		||||
	if (st.clock != SigBit())
 | 
			
		||||
	{
 | 
			
		||||
		cell->setPort(ID(CLK), st.clock);
 | 
			
		||||
		cell->setPort(ID::CLK, st.clock);
 | 
			
		||||
		cell->setPort(ID(CE), State::S1);
 | 
			
		||||
		cell->setParam(ID(NEG_TRIGGER), st.clock_pol ? State::S0 : State::S1);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -156,7 +156,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
 | 
			
		|||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		cell->setPort(ID(CLK), State::S0);
 | 
			
		||||
		cell->setPort(ID::CLK, State::S0);
 | 
			
		||||
		cell->setPort(ID(CE), State::S0);
 | 
			
		||||
		cell->setParam(ID(NEG_TRIGGER), State::S0);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -166,7 +166,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
 | 
			
		|||
	cell->setPort(ID(SIGNEXTIN), State::Sx);
 | 
			
		||||
	cell->setPort(ID(SIGNEXTOUT), pm.module->addWire(NEW_ID));
 | 
			
		||||
 | 
			
		||||
	cell->setPort(ID(CI), State::Sx);
 | 
			
		||||
	cell->setPort(ID::CI, State::Sx);
 | 
			
		||||
 | 
			
		||||
	cell->setPort(ID(ACCUMCI), State::Sx);
 | 
			
		||||
	cell->setPort(ID(ACCUMCO), pm.module->addWire(NEW_ID));
 | 
			
		||||
| 
						 | 
				
			
			@ -178,19 +178,19 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
 | 
			
		|||
	if (O_width == 33) {
 | 
			
		||||
		log_assert(st.add);
 | 
			
		||||
		// If we have a signed multiply-add, then perform sign extension
 | 
			
		||||
		if (st.add->getParam(ID(A_SIGNED)).as_bool() && st.add->getParam(ID(B_SIGNED)).as_bool())
 | 
			
		||||
		if (st.add->getParam(ID::A_SIGNED).as_bool() && st.add->getParam(ID::B_SIGNED).as_bool())
 | 
			
		||||
			pm.module->connect(O[32], O[31]);
 | 
			
		||||
		else
 | 
			
		||||
			cell->setPort(ID(CO), O[32]);
 | 
			
		||||
			cell->setPort(ID::CO, O[32]);
 | 
			
		||||
		O.remove(O_width-1);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		cell->setPort(ID(CO), pm.module->addWire(NEW_ID));
 | 
			
		||||
		cell->setPort(ID::CO, pm.module->addWire(NEW_ID));
 | 
			
		||||
	log_assert(GetSize(O) <= 32);
 | 
			
		||||
	if (GetSize(O) < 32)
 | 
			
		||||
		O.append(pm.module->addWire(NEW_ID, 32-GetSize(O)));
 | 
			
		||||
 | 
			
		||||
	cell->setPort(ID(O), O);
 | 
			
		||||
	cell->setPort(ID::O, O);
 | 
			
		||||
 | 
			
		||||
	bool accum = false;
 | 
			
		||||
	if (st.add) {
 | 
			
		||||
| 
						 | 
				
			
			@ -208,7 +208,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
 | 
			
		|||
 | 
			
		||||
	SigSpec OHOLD;
 | 
			
		||||
	if (st.ffOholdmux)
 | 
			
		||||
		OHOLD = st.ffOholdpol ? st.ffOholdmux->getPort(ID(S)) : pm.module->Not(NEW_ID, st.ffOholdmux->getPort(ID(S)));
 | 
			
		||||
		OHOLD = st.ffOholdpol ? st.ffOholdmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffOholdmux->getPort(ID::S));
 | 
			
		||||
	else
 | 
			
		||||
		OHOLD = State::S0;
 | 
			
		||||
	cell->setPort(ID(OHOLDTOP), OHOLD);
 | 
			
		||||
| 
						 | 
				
			
			@ -216,7 +216,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
 | 
			
		|||
 | 
			
		||||
	SigSpec ORST;
 | 
			
		||||
	if (st.ffOrstmux)
 | 
			
		||||
		ORST = st.ffOrstpol ? st.ffOrstmux->getPort(ID(S)) : pm.module->Not(NEW_ID, st.ffOrstmux->getPort(ID(S)));
 | 
			
		||||
		ORST = st.ffOrstpol ? st.ffOrstmux->getPort(ID::S) : pm.module->Not(NEW_ID, st.ffOrstmux->getPort(ID::S));
 | 
			
		||||
	else
 | 
			
		||||
		ORST = State::S0;
 | 
			
		||||
	cell->setPort(ID(ORSTTOP), ORST);
 | 
			
		||||
| 
						 | 
				
			
			@ -225,9 +225,9 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
 | 
			
		|||
	SigSpec acc_reset = State::S0;
 | 
			
		||||
	if (st.mux) {
 | 
			
		||||
		if (st.muxAB == ID::A)
 | 
			
		||||
			acc_reset = st.mux->getPort(ID(S));
 | 
			
		||||
			acc_reset = st.mux->getPort(ID::S);
 | 
			
		||||
		else
 | 
			
		||||
			acc_reset = pm.module->Not(NEW_ID, st.mux->getPort(ID(S)));
 | 
			
		||||
			acc_reset = pm.module->Not(NEW_ID, st.mux->getPort(ID::S));
 | 
			
		||||
	}
 | 
			
		||||
	cell->setPort(ID(OLOADTOP), acc_reset);
 | 
			
		||||
	cell->setPort(ID(OLOADBOT), acc_reset);
 | 
			
		||||
| 
						 | 
				
			
			@ -248,8 +248,8 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
 | 
			
		|||
	cell->setParam(ID(BOTADDSUB_CARRYSELECT), Const(0, 2));
 | 
			
		||||
 | 
			
		||||
	cell->setParam(ID(MODE_8x8), State::S0);
 | 
			
		||||
	cell->setParam(ID(A_SIGNED), st.mul->parameters.at(ID(A_SIGNED), State::S0).as_bool());
 | 
			
		||||
	cell->setParam(ID(B_SIGNED), st.mul->parameters.at(ID(B_SIGNED), State::S0).as_bool());
 | 
			
		||||
	cell->setParam(ID::A_SIGNED, st.mul->parameters.at(ID::A_SIGNED, State::S0).as_bool());
 | 
			
		||||
	cell->setParam(ID::B_SIGNED, st.mul->parameters.at(ID::B_SIGNED, State::S0).as_bool());
 | 
			
		||||
 | 
			
		||||
	if (st.ffO) {
 | 
			
		||||
		if (st.o_lo)
 | 
			
		||||
| 
						 | 
				
			
			@ -257,7 +257,7 @@ void create_ice40_dsp(ice40_dsp_pm &pm)
 | 
			
		|||
		else
 | 
			
		||||
			cell->setParam(ID(TOPOUTPUT_SELECT), Const(1, 2));
 | 
			
		||||
 | 
			
		||||
		st.ffO->connections_.at(ID(Q)).replace(O, pm.module->addWire(NEW_ID, GetSize(O)));
 | 
			
		||||
		st.ffO->connections_.at(ID::Q).replace(O, pm.module->addWire(NEW_ID, GetSize(O)));
 | 
			
		||||
		cell->setParam(ID(BOTOUTPUT_SELECT), Const(1, 2));
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,26 +37,26 @@ void create_ice40_wrapcarry(ice40_wrapcarry_pm &pm)
 | 
			
		|||
 | 
			
		||||
	log("  replacing SB_LUT + SB_CARRY with $__ICE40_CARRY_WRAPPER cell.\n");
 | 
			
		||||
 | 
			
		||||
	Cell *cell = pm.module->addCell(NEW_ID, "$__ICE40_CARRY_WRAPPER");
 | 
			
		||||
	Cell *cell = pm.module->addCell(NEW_ID, ID($__ICE40_CARRY_WRAPPER));
 | 
			
		||||
	pm.module->swap_names(cell, st.carry);
 | 
			
		||||
 | 
			
		||||
	cell->setPort("\\A", st.carry->getPort("\\I0"));
 | 
			
		||||
	cell->setPort("\\B", st.carry->getPort("\\I1"));
 | 
			
		||||
	auto CI = st.carry->getPort("\\CI");
 | 
			
		||||
	cell->setPort("\\CI", CI);
 | 
			
		||||
	cell->setPort("\\CO", st.carry->getPort("\\CO"));
 | 
			
		||||
	cell->setPort(ID::A, st.carry->getPort(ID(I0)));
 | 
			
		||||
	cell->setPort(ID::B, st.carry->getPort(ID(I1)));
 | 
			
		||||
	auto CI = st.carry->getPort(ID::CI);
 | 
			
		||||
	cell->setPort(ID::CI, CI);
 | 
			
		||||
	cell->setPort(ID::CO, st.carry->getPort(ID::CO));
 | 
			
		||||
 | 
			
		||||
	cell->setPort("\\I0", st.lut->getPort("\\I0"));
 | 
			
		||||
	auto I3 = st.lut->getPort("\\I3");
 | 
			
		||||
	cell->setPort(ID(I0), st.lut->getPort(ID(I0)));
 | 
			
		||||
	auto I3 = st.lut->getPort(ID(I3));
 | 
			
		||||
	if (pm.sigmap(CI) == pm.sigmap(I3)) {
 | 
			
		||||
		cell->setParam("\\I3_IS_CI", State::S1);
 | 
			
		||||
		cell->setParam(ID(I3_IS_CI), State::S1);
 | 
			
		||||
		I3 = State::Sx;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		cell->setParam("\\I3_IS_CI", State::S0);
 | 
			
		||||
	cell->setPort("\\I3", I3);
 | 
			
		||||
	cell->setPort("\\O", st.lut->getPort("\\O"));
 | 
			
		||||
	cell->setParam("\\LUT", st.lut->getParam("\\LUT_INIT"));
 | 
			
		||||
		cell->setParam(ID(I3_IS_CI), State::S0);
 | 
			
		||||
	cell->setPort(ID(I3), I3);
 | 
			
		||||
	cell->setPort(ID::O, st.lut->getPort(ID::O));
 | 
			
		||||
	cell->setParam(ID::LUT, st.lut->getParam(ID(LUT_INIT)));
 | 
			
		||||
 | 
			
		||||
	for (const auto &a : st.carry->attributes)
 | 
			
		||||
		cell->attributes[stringf("\\SB_CARRY.%s", a.first.c_str())] = a.second;
 | 
			
		||||
| 
						 | 
				
			
			@ -117,18 +117,18 @@ struct Ice40WrapCarryPass : public Pass {
 | 
			
		|||
						continue;
 | 
			
		||||
 | 
			
		||||
					auto carry = module->addCell(NEW_ID, ID(SB_CARRY));
 | 
			
		||||
					carry->setPort(ID(I0), cell->getPort(ID(A)));
 | 
			
		||||
					carry->setPort(ID(I1), cell->getPort(ID(B)));
 | 
			
		||||
					carry->setPort(ID(CI), cell->getPort(ID(CI)));
 | 
			
		||||
					carry->setPort(ID(CO), cell->getPort(ID(CO)));
 | 
			
		||||
					carry->setPort(ID(I0), cell->getPort(ID::A));
 | 
			
		||||
					carry->setPort(ID(I1), cell->getPort(ID::B));
 | 
			
		||||
					carry->setPort(ID::CI, cell->getPort(ID::CI));
 | 
			
		||||
					carry->setPort(ID::CO, cell->getPort(ID::CO));
 | 
			
		||||
					module->swap_names(carry, cell);
 | 
			
		||||
					auto lut_name = cell->attributes.at(ID(SB_LUT4.name), Const(NEW_ID.str())).decode_string();
 | 
			
		||||
					auto lut = module->addCell(lut_name, ID($lut));
 | 
			
		||||
					lut->setParam(ID(WIDTH), 4);
 | 
			
		||||
					lut->setParam(ID(LUT), cell->getParam(ID(LUT)));
 | 
			
		||||
					auto I3 = cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID(CI) : ID(I3));
 | 
			
		||||
					lut->setPort(ID(A), { I3, cell->getPort(ID(B)), cell->getPort(ID(A)), cell->getPort(ID(I0)) });
 | 
			
		||||
					lut->setPort(ID(Y), cell->getPort(ID(O)));
 | 
			
		||||
					lut->setParam(ID::WIDTH, 4);
 | 
			
		||||
					lut->setParam(ID::LUT, cell->getParam(ID::LUT));
 | 
			
		||||
					auto I3 = cell->getPort(cell->getParam(ID(I3_IS_CI)).as_bool() ? ID::CI : ID(I3));
 | 
			
		||||
					lut->setPort(ID::A, { I3, cell->getPort(ID::B), cell->getPort(ID::A), cell->getPort(ID(I0)) });
 | 
			
		||||
					lut->setPort(ID::Y, cell->getPort(ID::O));
 | 
			
		||||
 | 
			
		||||
					Const src;
 | 
			
		||||
					for (const auto &a : cell->attributes)
 | 
			
		||||
| 
						 | 
				
			
			@ -136,16 +136,16 @@ struct Ice40WrapCarryPass : public Pass {
 | 
			
		|||
							carry->attributes[a.first.c_str() + strlen("\\SB_CARRY.")] = a.second;
 | 
			
		||||
						else if (a.first.begins_with("\\SB_LUT4.\\"))
 | 
			
		||||
							lut->attributes[a.first.c_str() + strlen("\\SB_LUT4.")] = a.second;
 | 
			
		||||
						else if (a.first == ID(src))
 | 
			
		||||
						else if (a.first == ID::src)
 | 
			
		||||
							src = a.second;
 | 
			
		||||
						else if (a.first.in(ID(SB_LUT4.name), ID::keep, ID(module_not_derived)))
 | 
			
		||||
						else if (a.first.in(ID(SB_LUT4.name), ID::keep, ID::module_not_derived))
 | 
			
		||||
							continue;
 | 
			
		||||
						else
 | 
			
		||||
							log_abort();
 | 
			
		||||
 | 
			
		||||
					if (!src.empty()) {
 | 
			
		||||
						carry->attributes.insert(std::make_pair(ID(src), src));
 | 
			
		||||
						lut->attributes.insert(std::make_pair(ID(src), src));
 | 
			
		||||
						carry->attributes.insert(std::make_pair(ID::src, src));
 | 
			
		||||
						lut->attributes.insert(std::make_pair(ID::src, src));
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					module->remove(cell);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -87,7 +87,7 @@ struct PeepoptPass : public Pass {
 | 
			
		|||
				peepopt_pm pm(module);
 | 
			
		||||
 | 
			
		||||
				for (auto w : module->wires()) {
 | 
			
		||||
					auto it = w->attributes.find(ID(init));
 | 
			
		||||
					auto it = w->attributes.find(ID::init);
 | 
			
		||||
					if (it != w->attributes.end()) {
 | 
			
		||||
						SigSpec sig = pm.sigmap(w);
 | 
			
		||||
						Const val = it->second;
 | 
			
		||||
| 
						 | 
				
			
			@ -109,7 +109,7 @@ struct PeepoptPass : public Pass {
 | 
			
		|||
				pm.run_dffmux();
 | 
			
		||||
 | 
			
		||||
				for (auto w : module->wires()) {
 | 
			
		||||
					auto it = w->attributes.find(ID(init));
 | 
			
		||||
					auto it = w->attributes.find(ID::init);
 | 
			
		||||
					if (it != w->attributes.end()) {
 | 
			
		||||
						SigSpec sig = pm.sigmap(w);
 | 
			
		||||
						Const &val = it->second;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,16 +40,16 @@ void reduce_chain(test_pmgen_pm &pm)
 | 
			
		|||
	log("Found chain of length %d (%s):\n", GetSize(ud.longest_chain), log_id(st.first->type));
 | 
			
		||||
 | 
			
		||||
	SigSpec A;
 | 
			
		||||
	SigSpec Y = ud.longest_chain.front().first->getPort(ID(Y));
 | 
			
		||||
	SigSpec Y = ud.longest_chain.front().first->getPort(ID::Y);
 | 
			
		||||
	auto last_cell = ud.longest_chain.back().first;
 | 
			
		||||
 | 
			
		||||
	for (auto it : ud.longest_chain) {
 | 
			
		||||
		auto cell = it.first;
 | 
			
		||||
		if (cell == last_cell) {
 | 
			
		||||
			A.append(cell->getPort(ID(A)));
 | 
			
		||||
			A.append(cell->getPort(ID(B)));
 | 
			
		||||
			A.append(cell->getPort(ID::A));
 | 
			
		||||
			A.append(cell->getPort(ID::B));
 | 
			
		||||
		} else {
 | 
			
		||||
			A.append(cell->getPort(it.second == ID(A) ? ID(B) : ID(A)));
 | 
			
		||||
			A.append(cell->getPort(it.second == ID::A ? ID::B : ID::A));
 | 
			
		||||
		}
 | 
			
		||||
		log("    %s\n", log_id(cell));
 | 
			
		||||
		pm.autoremove(cell);
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +78,7 @@ void reduce_tree(test_pmgen_pm &pm)
 | 
			
		|||
		return;
 | 
			
		||||
 | 
			
		||||
	SigSpec A = ud.leaves;
 | 
			
		||||
	SigSpec Y = st.first->getPort(ID(Y));
 | 
			
		||||
	SigSpec Y = st.first->getPort(ID::Y);
 | 
			
		||||
	pm.autoremove(st.first);
 | 
			
		||||
 | 
			
		||||
	log("Found %s tree with %d leaves for %s (%s).\n", log_id(st.first->type),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ static Cell* addDsp(Module *module) {
 | 
			
		|||
	cell->setParam(ID(USE_SIMD), Const("ONE48"));
 | 
			
		||||
	cell->setParam(ID(USE_DPORT), Const("FALSE"));
 | 
			
		||||
 | 
			
		||||
	cell->setPort(ID(D), Const(0, 25));
 | 
			
		||||
	cell->setPort(ID::D, Const(0, 25));
 | 
			
		||||
	cell->setPort(ID(INMODE), Const(0, 5));
 | 
			
		||||
	cell->setPort(ID(ALUMODE), Const(0, 4));
 | 
			
		||||
	cell->setPort(ID(OPMODE), Const(0, 7));
 | 
			
		||||
| 
						 | 
				
			
			@ -72,15 +72,15 @@ void xilinx_simd_pack(Module *module, const std::vector<Cell*> &selected_cells)
 | 
			
		|||
	for (auto cell : selected_cells) {
 | 
			
		||||
		if (!cell->type.in(ID($add), ID($sub)))
 | 
			
		||||
			continue;
 | 
			
		||||
		SigSpec Y = cell->getPort(ID(Y));
 | 
			
		||||
		SigSpec Y = cell->getPort(ID::Y);
 | 
			
		||||
		if (!Y.is_chunk())
 | 
			
		||||
			continue;
 | 
			
		||||
		if (!Y.as_chunk().wire->get_strpool_attribute(ID(use_dsp)).count("simd"))
 | 
			
		||||
			continue;
 | 
			
		||||
		if (GetSize(Y) > 25)
 | 
			
		||||
			continue;
 | 
			
		||||
		SigSpec A = cell->getPort(ID(A));
 | 
			
		||||
		SigSpec B = cell->getPort(ID(B));
 | 
			
		||||
		SigSpec A = cell->getPort(ID::A);
 | 
			
		||||
		SigSpec B = cell->getPort(ID::B);
 | 
			
		||||
		if (GetSize(Y) <= 13) {
 | 
			
		||||
			if (GetSize(A) > 12)
 | 
			
		||||
				continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -106,11 +106,11 @@ void xilinx_simd_pack(Module *module, const std::vector<Cell*> &selected_cells)
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	auto f12 = [module](SigSpec &AB, SigSpec &C, SigSpec &P, SigSpec &CARRYOUT, Cell *lane) {
 | 
			
		||||
		SigSpec A = lane->getPort(ID(A));
 | 
			
		||||
		SigSpec B = lane->getPort(ID(B));
 | 
			
		||||
		SigSpec Y = lane->getPort(ID(Y));
 | 
			
		||||
		A.extend_u0(12, lane->getParam(ID(A_SIGNED)).as_bool());
 | 
			
		||||
		B.extend_u0(12, lane->getParam(ID(B_SIGNED)).as_bool());
 | 
			
		||||
		SigSpec A = lane->getPort(ID::A);
 | 
			
		||||
		SigSpec B = lane->getPort(ID::B);
 | 
			
		||||
		SigSpec Y = lane->getPort(ID::Y);
 | 
			
		||||
		A.extend_u0(12, lane->getParam(ID::A_SIGNED).as_bool());
 | 
			
		||||
		B.extend_u0(12, lane->getParam(ID::B_SIGNED).as_bool());
 | 
			
		||||
		AB.append(A);
 | 
			
		||||
		C.append(B);
 | 
			
		||||
		if (GetSize(Y) < 13)
 | 
			
		||||
| 
						 | 
				
			
			@ -174,10 +174,10 @@ void xilinx_simd_pack(Module *module, const std::vector<Cell*> &selected_cells)
 | 
			
		|||
			log_assert(GetSize(C) == 48);
 | 
			
		||||
			log_assert(GetSize(P) == 48);
 | 
			
		||||
			log_assert(GetSize(CARRYOUT) == 4);
 | 
			
		||||
			cell->setPort(ID(A), AB.extract(18, 30));
 | 
			
		||||
			cell->setPort(ID(B), AB.extract(0, 18));
 | 
			
		||||
			cell->setPort(ID(C), C);
 | 
			
		||||
			cell->setPort(ID(P), P);
 | 
			
		||||
			cell->setPort(ID::A, AB.extract(18, 30));
 | 
			
		||||
			cell->setPort(ID::B, AB.extract(0, 18));
 | 
			
		||||
			cell->setPort(ID::C, C);
 | 
			
		||||
			cell->setPort(ID::P, P);
 | 
			
		||||
			cell->setPort(ID(CARRYOUT), CARRYOUT);
 | 
			
		||||
			if (lane1->type == ID($sub))
 | 
			
		||||
				cell->setPort(ID(ALUMODE), Const::from_string("0011"));
 | 
			
		||||
| 
						 | 
				
			
			@ -194,11 +194,11 @@ void xilinx_simd_pack(Module *module, const std::vector<Cell*> &selected_cells)
 | 
			
		|||
	g12(simd12_sub);
 | 
			
		||||
 | 
			
		||||
	auto f24 = [module](SigSpec &AB, SigSpec &C, SigSpec &P, SigSpec &CARRYOUT, Cell *lane) {
 | 
			
		||||
		SigSpec A = lane->getPort(ID(A));
 | 
			
		||||
		SigSpec B = lane->getPort(ID(B));
 | 
			
		||||
		SigSpec Y = lane->getPort(ID(Y));
 | 
			
		||||
		A.extend_u0(24, lane->getParam(ID(A_SIGNED)).as_bool());
 | 
			
		||||
		B.extend_u0(24, lane->getParam(ID(B_SIGNED)).as_bool());
 | 
			
		||||
		SigSpec A = lane->getPort(ID::A);
 | 
			
		||||
		SigSpec B = lane->getPort(ID::B);
 | 
			
		||||
		SigSpec Y = lane->getPort(ID::Y);
 | 
			
		||||
		A.extend_u0(24, lane->getParam(ID::A_SIGNED).as_bool());
 | 
			
		||||
		B.extend_u0(24, lane->getParam(ID::B_SIGNED).as_bool());
 | 
			
		||||
		C.append(A);
 | 
			
		||||
		AB.append(B);
 | 
			
		||||
		if (GetSize(Y) < 25)
 | 
			
		||||
| 
						 | 
				
			
			@ -238,10 +238,10 @@ void xilinx_simd_pack(Module *module, const std::vector<Cell*> &selected_cells)
 | 
			
		|||
			log_assert(GetSize(C) == 48);
 | 
			
		||||
			log_assert(GetSize(P) == 48);
 | 
			
		||||
			log_assert(GetSize(CARRYOUT) == 4);
 | 
			
		||||
			cell->setPort(ID(A), AB.extract(18, 30));
 | 
			
		||||
			cell->setPort(ID(B), AB.extract(0, 18));
 | 
			
		||||
			cell->setPort(ID(C), C);
 | 
			
		||||
			cell->setPort(ID(P), P);
 | 
			
		||||
			cell->setPort(ID::A, AB.extract(18, 30));
 | 
			
		||||
			cell->setPort(ID::B, AB.extract(0, 18));
 | 
			
		||||
			cell->setPort(ID::C, C);
 | 
			
		||||
			cell->setPort(ID::P, P);
 | 
			
		||||
			cell->setPort(ID(CARRYOUT), CARRYOUT);
 | 
			
		||||
			if (lane1->type == ID($sub))
 | 
			
		||||
				cell->setPort(ID(ALUMODE), Const::from_string("0011"));
 | 
			
		||||
| 
						 | 
				
			
			@ -280,19 +280,19 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
 | 
			
		|||
 | 
			
		||||
	if (st.preAdd) {
 | 
			
		||||
		log("  preadder %s (%s)\n", log_id(st.preAdd), log_id(st.preAdd->type));
 | 
			
		||||
		bool A_SIGNED = st.preAdd->getParam(ID(A_SIGNED)).as_bool();
 | 
			
		||||
		bool D_SIGNED = st.preAdd->getParam(ID(B_SIGNED)).as_bool();
 | 
			
		||||
		if (st.sigA == st.preAdd->getPort(ID(B)))
 | 
			
		||||
		bool A_SIGNED = st.preAdd->getParam(ID::A_SIGNED).as_bool();
 | 
			
		||||
		bool D_SIGNED = st.preAdd->getParam(ID::B_SIGNED).as_bool();
 | 
			
		||||
		if (st.sigA == st.preAdd->getPort(ID::B))
 | 
			
		||||
			std::swap(A_SIGNED, D_SIGNED);
 | 
			
		||||
		st.sigA.extend_u0(30, A_SIGNED);
 | 
			
		||||
		st.sigD.extend_u0(25, D_SIGNED);
 | 
			
		||||
		cell->setPort(ID(A), st.sigA);
 | 
			
		||||
		cell->setPort(ID(D), st.sigD);
 | 
			
		||||
		cell->setPort(ID::A, st.sigA);
 | 
			
		||||
		cell->setPort(ID::D, st.sigD);
 | 
			
		||||
		cell->setPort(ID(INMODE), Const::from_string("00100"));
 | 
			
		||||
 | 
			
		||||
		if (st.ffAD) {
 | 
			
		||||
			if (st.ffADcemux) {
 | 
			
		||||
				SigSpec S = st.ffADcemux->getPort(ID(S));
 | 
			
		||||
				SigSpec S = st.ffADcemux->getPort(ID::S);
 | 
			
		||||
				cell->setPort(ID(CEAD), st.ffADcepol ? S : pm.module->Not(NEW_ID, S));
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
| 
						 | 
				
			
			@ -310,7 +310,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
 | 
			
		|||
		SigSpec &opmode = cell->connections_.at(ID(OPMODE));
 | 
			
		||||
		if (st.postAddMux) {
 | 
			
		||||
			log_assert(st.ffP);
 | 
			
		||||
			opmode[4] = st.postAddMux->getPort(ID(S));
 | 
			
		||||
			opmode[4] = st.postAddMux->getPort(ID::S);
 | 
			
		||||
			pm.autoremove(st.postAddMux);
 | 
			
		||||
		}
 | 
			
		||||
		else if (st.ffP && st.sigC == st.sigP)
 | 
			
		||||
| 
						 | 
				
			
			@ -321,11 +321,11 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
 | 
			
		|||
		opmode[5] = State::S1;
 | 
			
		||||
 | 
			
		||||
		if (opmode[4] != State::S0) {
 | 
			
		||||
			if (st.postAddMuxAB == ID(A))
 | 
			
		||||
				st.sigC.extend_u0(48, st.postAdd->getParam(ID(B_SIGNED)).as_bool());
 | 
			
		||||
			if (st.postAddMuxAB == ID::A)
 | 
			
		||||
				st.sigC.extend_u0(48, st.postAdd->getParam(ID::B_SIGNED).as_bool());
 | 
			
		||||
			else
 | 
			
		||||
				st.sigC.extend_u0(48, st.postAdd->getParam(ID(A_SIGNED)).as_bool());
 | 
			
		||||
			cell->setPort(ID(C), st.sigC);
 | 
			
		||||
				st.sigC.extend_u0(48, st.postAdd->getParam(ID::A_SIGNED).as_bool());
 | 
			
		||||
			cell->setPort(ID::C, st.sigC);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		pm.autoremove(st.postAdd);
 | 
			
		||||
| 
						 | 
				
			
			@ -337,7 +337,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
 | 
			
		|||
		cell->setParam(ID(SEL_MASK), Const("MASK"));
 | 
			
		||||
 | 
			
		||||
		if (st.overflow->type == ID($ge)) {
 | 
			
		||||
			Const B = st.overflow->getPort(ID(B)).as_const();
 | 
			
		||||
			Const B = st.overflow->getPort(ID::B).as_const();
 | 
			
		||||
			log_assert(std::count(B.bits.begin(), B.bits.end(), State::S1) == 1);
 | 
			
		||||
			// Since B is an exact power of 2, subtract 1
 | 
			
		||||
			//   by inverting all bits up until hitting
 | 
			
		||||
| 
						 | 
				
			
			@ -352,7 +352,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
 | 
			
		|||
 | 
			
		||||
			cell->setParam(ID(MASK), B);
 | 
			
		||||
			cell->setParam(ID(PATTERN), Const(0, 48));
 | 
			
		||||
			cell->setPort(ID(OVERFLOW), st.overflow->getPort(ID(Y)));
 | 
			
		||||
			cell->setPort(ID(OVERFLOW), st.overflow->getPort(ID::Y));
 | 
			
		||||
		}
 | 
			
		||||
		else log_abort();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -361,29 +361,29 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
 | 
			
		|||
 | 
			
		||||
	if (st.clock != SigBit())
 | 
			
		||||
	{
 | 
			
		||||
		cell->setPort(ID(CLK), st.clock);
 | 
			
		||||
		cell->setPort(ID::CLK, st.clock);
 | 
			
		||||
 | 
			
		||||
		auto f = [&pm,cell](SigSpec &A, Cell* ff, Cell* cemux, bool cepol, IdString ceport, Cell* rstmux, bool rstpol, IdString rstport) {
 | 
			
		||||
			SigSpec D = ff->getPort(ID(D));
 | 
			
		||||
			SigSpec Q = pm.sigmap(ff->getPort(ID(Q)));
 | 
			
		||||
			SigSpec D = ff->getPort(ID::D);
 | 
			
		||||
			SigSpec Q = pm.sigmap(ff->getPort(ID::Q));
 | 
			
		||||
			if (!A.empty())
 | 
			
		||||
				A.replace(Q, D);
 | 
			
		||||
			if (rstmux) {
 | 
			
		||||
				SigSpec Y = rstmux->getPort(ID(Y));
 | 
			
		||||
				SigSpec AB = rstmux->getPort(rstpol ? ID(A) : ID(B));
 | 
			
		||||
				SigSpec Y = rstmux->getPort(ID::Y);
 | 
			
		||||
				SigSpec AB = rstmux->getPort(rstpol ? ID::A : ID::B);
 | 
			
		||||
				if (!A.empty())
 | 
			
		||||
					A.replace(Y, AB);
 | 
			
		||||
				if (rstport != IdString()) {
 | 
			
		||||
					SigSpec S = rstmux->getPort(ID(S));
 | 
			
		||||
					SigSpec S = rstmux->getPort(ID::S);
 | 
			
		||||
					cell->setPort(rstport, rstpol ? S : pm.module->Not(NEW_ID, S));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if (rstport != IdString())
 | 
			
		||||
				cell->setPort(rstport, State::S0);
 | 
			
		||||
			if (cemux) {
 | 
			
		||||
				SigSpec Y = cemux->getPort(ID(Y));
 | 
			
		||||
				SigSpec BA = cemux->getPort(cepol ? ID(B) : ID(A));
 | 
			
		||||
				SigSpec S = cemux->getPort(ID(S));
 | 
			
		||||
				SigSpec Y = cemux->getPort(ID::Y);
 | 
			
		||||
				SigSpec BA = cemux->getPort(cepol ? ID::B : ID::A);
 | 
			
		||||
				SigSpec S = cemux->getPort(ID::S);
 | 
			
		||||
				if (!A.empty())
 | 
			
		||||
					A.replace(Y, BA);
 | 
			
		||||
				cell->setPort(ceport, cepol ? S : pm.module->Not(NEW_ID, S));
 | 
			
		||||
| 
						 | 
				
			
			@ -392,7 +392,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
 | 
			
		|||
				cell->setPort(ceport, State::S1);
 | 
			
		||||
 | 
			
		||||
			for (auto c : Q.chunks()) {
 | 
			
		||||
				auto it = c.wire->attributes.find(ID(init));
 | 
			
		||||
				auto it = c.wire->attributes.find(ID::init);
 | 
			
		||||
				if (it == c.wire->attributes.end())
 | 
			
		||||
					continue;
 | 
			
		||||
				for (int i = c.offset; i < c.offset+c.width; i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -403,7 +403,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
 | 
			
		|||
		};
 | 
			
		||||
 | 
			
		||||
		if (st.ffA2) {
 | 
			
		||||
			SigSpec A = cell->getPort(ID(A));
 | 
			
		||||
			SigSpec A = cell->getPort(ID::A);
 | 
			
		||||
			f(A, st.ffA2, st.ffA2cemux, st.ffA2cepol, ID(CEA2), st.ffA2rstmux, st.ffArstpol, ID(RSTA));
 | 
			
		||||
			if (st.ffA1) {
 | 
			
		||||
				f(A, st.ffA1, st.ffA1cemux, st.ffA1cepol, ID(CEA1), st.ffA1rstmux, st.ffArstpol, IdString());
 | 
			
		||||
| 
						 | 
				
			
			@ -415,10 +415,10 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
 | 
			
		|||
				cell->setParam(ID(ACASCREG), 1);
 | 
			
		||||
			}
 | 
			
		||||
			pm.add_siguser(A, cell);
 | 
			
		||||
			cell->setPort(ID(A), A);
 | 
			
		||||
			cell->setPort(ID::A, A);
 | 
			
		||||
		}
 | 
			
		||||
		if (st.ffB2) {
 | 
			
		||||
			SigSpec B = cell->getPort(ID(B));
 | 
			
		||||
			SigSpec B = cell->getPort(ID::B);
 | 
			
		||||
			f(B, st.ffB2, st.ffB2cemux, st.ffB2cepol, ID(CEB2), st.ffB2rstmux, st.ffBrstpol, ID(RSTB));
 | 
			
		||||
			if (st.ffB1) {
 | 
			
		||||
				f(B, st.ffB1, st.ffB1cemux, st.ffB1cepol, ID(CEB1), st.ffB1rstmux, st.ffBrstpol, IdString());
 | 
			
		||||
| 
						 | 
				
			
			@ -430,25 +430,25 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
 | 
			
		|||
				cell->setParam(ID(BCASCREG), 1);
 | 
			
		||||
			}
 | 
			
		||||
			pm.add_siguser(B, cell);
 | 
			
		||||
			cell->setPort(ID(B), B);
 | 
			
		||||
			cell->setPort(ID::B, B);
 | 
			
		||||
		}
 | 
			
		||||
		if (st.ffD) {
 | 
			
		||||
			SigSpec D = cell->getPort(ID(D));
 | 
			
		||||
			SigSpec D = cell->getPort(ID::D);
 | 
			
		||||
			f(D, st.ffD, st.ffDcemux, st.ffDcepol, ID(CED), st.ffDrstmux, st.ffDrstpol, ID(RSTD));
 | 
			
		||||
			pm.add_siguser(D, cell);
 | 
			
		||||
			cell->setPort(ID(D), D);
 | 
			
		||||
			cell->setPort(ID::D, D);
 | 
			
		||||
			cell->setParam(ID(DREG), 1);
 | 
			
		||||
		}
 | 
			
		||||
		if (st.ffM) {
 | 
			
		||||
			SigSpec M; // unused
 | 
			
		||||
			f(M, st.ffM, st.ffMcemux, st.ffMcepol, ID(CEM), st.ffMrstmux, st.ffMrstpol, ID(RSTM));
 | 
			
		||||
			st.ffM->connections_.at(ID(Q)).replace(st.sigM, pm.module->addWire(NEW_ID, GetSize(st.sigM)));
 | 
			
		||||
			st.ffM->connections_.at(ID::Q).replace(st.sigM, pm.module->addWire(NEW_ID, GetSize(st.sigM)));
 | 
			
		||||
			cell->setParam(ID(MREG), State::S1);
 | 
			
		||||
		}
 | 
			
		||||
		if (st.ffP) {
 | 
			
		||||
			SigSpec P; // unused
 | 
			
		||||
			f(P, st.ffP, st.ffPcemux, st.ffPcepol, ID(CEP), st.ffPrstmux, st.ffPrstpol, ID(RSTP));
 | 
			
		||||
			st.ffP->connections_.at(ID(Q)).replace(st.sigP, pm.module->addWire(NEW_ID, GetSize(st.sigP)));
 | 
			
		||||
			st.ffP->connections_.at(ID::Q).replace(st.sigP, pm.module->addWire(NEW_ID, GetSize(st.sigP)));
 | 
			
		||||
			cell->setParam(ID(PREG), State::S1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -483,7 +483,7 @@ void xilinx_dsp_pack(xilinx_dsp_pm &pm)
 | 
			
		|||
	SigSpec P = st.sigP;
 | 
			
		||||
	if (GetSize(P) < 48)
 | 
			
		||||
		P.append(pm.module->addWire(NEW_ID, 48-GetSize(P)));
 | 
			
		||||
	cell->setPort(ID(P), P);
 | 
			
		||||
	cell->setPort(ID::P, P);
 | 
			
		||||
 | 
			
		||||
	pm.blacklist(cell);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -511,12 +511,12 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
 | 
			
		|||
 | 
			
		||||
	if (st.preAdd) {
 | 
			
		||||
		log("  preadder %s (%s)\n", log_id(st.preAdd), log_id(st.preAdd->type));
 | 
			
		||||
		bool D_SIGNED = st.preAdd->getParam(ID(A_SIGNED)).as_bool();
 | 
			
		||||
		bool B_SIGNED = st.preAdd->getParam(ID(B_SIGNED)).as_bool();
 | 
			
		||||
		bool D_SIGNED = st.preAdd->getParam(ID::A_SIGNED).as_bool();
 | 
			
		||||
		bool B_SIGNED = st.preAdd->getParam(ID::B_SIGNED).as_bool();
 | 
			
		||||
		st.sigB.extend_u0(18, B_SIGNED);
 | 
			
		||||
		st.sigD.extend_u0(18, D_SIGNED);
 | 
			
		||||
		cell->setPort(ID(B), st.sigB);
 | 
			
		||||
		cell->setPort(ID(D), st.sigD);
 | 
			
		||||
		cell->setPort(ID::B, st.sigB);
 | 
			
		||||
		cell->setPort(ID::D, st.sigD);
 | 
			
		||||
		opmode[4] = State::S1;
 | 
			
		||||
		if (st.preAdd->type == ID($add))
 | 
			
		||||
			opmode[6] = State::S0;
 | 
			
		||||
| 
						 | 
				
			
			@ -532,7 +532,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
 | 
			
		|||
 | 
			
		||||
		if (st.postAddMux) {
 | 
			
		||||
			log_assert(st.ffP);
 | 
			
		||||
			opmode[2] = st.postAddMux->getPort(ID(S));
 | 
			
		||||
			opmode[2] = st.postAddMux->getPort(ID::S);
 | 
			
		||||
			pm.autoremove(st.postAddMux);
 | 
			
		||||
		}
 | 
			
		||||
		else if (st.ffP && st.sigC == st.sigP)
 | 
			
		||||
| 
						 | 
				
			
			@ -542,11 +542,11 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
 | 
			
		|||
		opmode[3] = State::S1;
 | 
			
		||||
 | 
			
		||||
		if (opmode[2] != State::S0) {
 | 
			
		||||
			if (st.postAddMuxAB == ID(A))
 | 
			
		||||
				st.sigC.extend_u0(48, st.postAdd->getParam(ID(B_SIGNED)).as_bool());
 | 
			
		||||
			if (st.postAddMuxAB == ID::A)
 | 
			
		||||
				st.sigC.extend_u0(48, st.postAdd->getParam(ID::B_SIGNED).as_bool());
 | 
			
		||||
			else
 | 
			
		||||
				st.sigC.extend_u0(48, st.postAdd->getParam(ID(A_SIGNED)).as_bool());
 | 
			
		||||
			cell->setPort(ID(C), st.sigC);
 | 
			
		||||
				st.sigC.extend_u0(48, st.postAdd->getParam(ID::A_SIGNED).as_bool());
 | 
			
		||||
			cell->setPort(ID::C, st.sigC);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		pm.autoremove(st.postAdd);
 | 
			
		||||
| 
						 | 
				
			
			@ -554,29 +554,29 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
 | 
			
		|||
 | 
			
		||||
	if (st.clock != SigBit())
 | 
			
		||||
	{
 | 
			
		||||
		cell->setPort(ID(CLK), st.clock);
 | 
			
		||||
		cell->setPort(ID::CLK, st.clock);
 | 
			
		||||
 | 
			
		||||
		auto f = [&pm,cell](SigSpec &A, Cell* ff, Cell* cemux, bool cepol, IdString ceport, Cell* rstmux, bool rstpol, IdString rstport) {
 | 
			
		||||
			SigSpec D = ff->getPort(ID(D));
 | 
			
		||||
			SigSpec Q = pm.sigmap(ff->getPort(ID(Q)));
 | 
			
		||||
			SigSpec D = ff->getPort(ID::D);
 | 
			
		||||
			SigSpec Q = pm.sigmap(ff->getPort(ID::Q));
 | 
			
		||||
			if (!A.empty())
 | 
			
		||||
				A.replace(Q, D);
 | 
			
		||||
			if (rstmux) {
 | 
			
		||||
				SigSpec Y = rstmux->getPort(ID(Y));
 | 
			
		||||
				SigSpec AB = rstmux->getPort(rstpol ? ID(A) : ID(B));
 | 
			
		||||
				SigSpec Y = rstmux->getPort(ID::Y);
 | 
			
		||||
				SigSpec AB = rstmux->getPort(rstpol ? ID::A : ID::B);
 | 
			
		||||
				if (!A.empty())
 | 
			
		||||
					A.replace(Y, AB);
 | 
			
		||||
				if (rstport != IdString()) {
 | 
			
		||||
					SigSpec S = rstmux->getPort(ID(S));
 | 
			
		||||
					SigSpec S = rstmux->getPort(ID::S);
 | 
			
		||||
					cell->setPort(rstport, rstpol ? S : pm.module->Not(NEW_ID, S));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if (rstport != IdString())
 | 
			
		||||
				cell->setPort(rstport, State::S0);
 | 
			
		||||
			if (cemux) {
 | 
			
		||||
				SigSpec Y = cemux->getPort(ID(Y));
 | 
			
		||||
				SigSpec BA = cemux->getPort(cepol ? ID(B) : ID(A));
 | 
			
		||||
				SigSpec S = cemux->getPort(ID(S));
 | 
			
		||||
				SigSpec Y = cemux->getPort(ID::Y);
 | 
			
		||||
				SigSpec BA = cemux->getPort(cepol ? ID::B : ID::A);
 | 
			
		||||
				SigSpec S = cemux->getPort(ID::S);
 | 
			
		||||
				if (!A.empty())
 | 
			
		||||
					A.replace(Y, BA);
 | 
			
		||||
				cell->setPort(ceport, cepol ? S : pm.module->Not(NEW_ID, S));
 | 
			
		||||
| 
						 | 
				
			
			@ -585,7 +585,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
 | 
			
		|||
				cell->setPort(ceport, State::S1);
 | 
			
		||||
 | 
			
		||||
			for (auto c : Q.chunks()) {
 | 
			
		||||
				auto it = c.wire->attributes.find(ID(init));
 | 
			
		||||
				auto it = c.wire->attributes.find(ID::init);
 | 
			
		||||
				if (it == c.wire->attributes.end())
 | 
			
		||||
					continue;
 | 
			
		||||
				for (int i = c.offset; i < c.offset+c.width; i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -596,7 +596,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
 | 
			
		|||
		};
 | 
			
		||||
 | 
			
		||||
		if (st.ffA0 || st.ffA1) {
 | 
			
		||||
			SigSpec A = cell->getPort(ID(A));
 | 
			
		||||
			SigSpec A = cell->getPort(ID::A);
 | 
			
		||||
			if (st.ffA1) {
 | 
			
		||||
				f(A, st.ffA1, st.ffA1cemux, st.ffAcepol, ID(CEA), st.ffA1rstmux, st.ffArstpol, ID(RSTA));
 | 
			
		||||
				cell->setParam(ID(A1REG), 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -606,10 +606,10 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
 | 
			
		|||
				cell->setParam(ID(A0REG), 1);
 | 
			
		||||
			}
 | 
			
		||||
			pm.add_siguser(A, cell);
 | 
			
		||||
			cell->setPort(ID(A), A);
 | 
			
		||||
			cell->setPort(ID::A, A);
 | 
			
		||||
		}
 | 
			
		||||
		if (st.ffB0 || st.ffB1) {
 | 
			
		||||
			SigSpec B = cell->getPort(ID(B));
 | 
			
		||||
			SigSpec B = cell->getPort(ID::B);
 | 
			
		||||
			if (st.ffB1) {
 | 
			
		||||
				f(B, st.ffB1, st.ffB1cemux, st.ffBcepol, ID(CEB), st.ffB1rstmux, st.ffBrstpol, ID(RSTB));
 | 
			
		||||
				cell->setParam(ID(B1REG), 1);
 | 
			
		||||
| 
						 | 
				
			
			@ -619,25 +619,25 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
 | 
			
		|||
				cell->setParam(ID(B0REG), 1);
 | 
			
		||||
			}
 | 
			
		||||
			pm.add_siguser(B, cell);
 | 
			
		||||
			cell->setPort(ID(B), B);
 | 
			
		||||
			cell->setPort(ID::B, B);
 | 
			
		||||
		}
 | 
			
		||||
		if (st.ffD) {
 | 
			
		||||
			SigSpec D = cell->getPort(ID(D));
 | 
			
		||||
			SigSpec D = cell->getPort(ID::D);
 | 
			
		||||
			f(D, st.ffD, st.ffDcemux, st.ffDcepol, ID(CED), st.ffDrstmux, st.ffDrstpol, ID(RSTD));
 | 
			
		||||
			pm.add_siguser(D, cell);
 | 
			
		||||
			cell->setPort(ID(D), D);
 | 
			
		||||
			cell->setPort(ID::D, D);
 | 
			
		||||
			cell->setParam(ID(DREG), 1);
 | 
			
		||||
		}
 | 
			
		||||
		if (st.ffM) {
 | 
			
		||||
			SigSpec M; // unused
 | 
			
		||||
			f(M, st.ffM, st.ffMcemux, st.ffMcepol, ID(CEM), st.ffMrstmux, st.ffMrstpol, ID(RSTM));
 | 
			
		||||
			st.ffM->connections_.at(ID(Q)).replace(st.sigM, pm.module->addWire(NEW_ID, GetSize(st.sigM)));
 | 
			
		||||
			st.ffM->connections_.at(ID::Q).replace(st.sigM, pm.module->addWire(NEW_ID, GetSize(st.sigM)));
 | 
			
		||||
			cell->setParam(ID(MREG), State::S1);
 | 
			
		||||
		}
 | 
			
		||||
		if (st.ffP) {
 | 
			
		||||
			SigSpec P; // unused
 | 
			
		||||
			f(P, st.ffP, st.ffPcemux, st.ffPcepol, ID(CEP), st.ffPrstmux, st.ffPrstpol, ID(RSTP));
 | 
			
		||||
			st.ffP->connections_.at(ID(Q)).replace(st.sigP, pm.module->addWire(NEW_ID, GetSize(st.sigP)));
 | 
			
		||||
			st.ffP->connections_.at(ID::Q).replace(st.sigP, pm.module->addWire(NEW_ID, GetSize(st.sigP)));
 | 
			
		||||
			cell->setParam(ID(PREG), State::S1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -667,7 +667,7 @@ void xilinx_dsp48a_pack(xilinx_dsp48a_pm &pm)
 | 
			
		|||
	SigSpec P = st.sigP;
 | 
			
		||||
	if (GetSize(P) < 48)
 | 
			
		||||
		P.append(pm.module->addWire(NEW_ID, 48-GetSize(P)));
 | 
			
		||||
	cell->setPort(ID(P), P);
 | 
			
		||||
	cell->setPort(ID::P, P);
 | 
			
		||||
 | 
			
		||||
	pm.blacklist(cell);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -683,29 +683,29 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm)
 | 
			
		|||
 | 
			
		||||
	if (st.clock != SigBit())
 | 
			
		||||
	{
 | 
			
		||||
		cell->setPort(ID(CLK), st.clock);
 | 
			
		||||
		cell->setPort(ID::CLK, st.clock);
 | 
			
		||||
 | 
			
		||||
		auto f = [&pm,cell](SigSpec &A, Cell* ff, Cell* cemux, bool cepol, IdString ceport, Cell* rstmux, bool rstpol, IdString rstport) {
 | 
			
		||||
			SigSpec D = ff->getPort(ID(D));
 | 
			
		||||
			SigSpec Q = pm.sigmap(ff->getPort(ID(Q)));
 | 
			
		||||
			SigSpec D = ff->getPort(ID::D);
 | 
			
		||||
			SigSpec Q = pm.sigmap(ff->getPort(ID::Q));
 | 
			
		||||
			if (!A.empty())
 | 
			
		||||
				A.replace(Q, D);
 | 
			
		||||
			if (rstmux) {
 | 
			
		||||
				SigSpec Y = rstmux->getPort(ID(Y));
 | 
			
		||||
				SigSpec AB = rstmux->getPort(rstpol ? ID(A) : ID(B));
 | 
			
		||||
				SigSpec Y = rstmux->getPort(ID::Y);
 | 
			
		||||
				SigSpec AB = rstmux->getPort(rstpol ? ID::A : ID::B);
 | 
			
		||||
				if (!A.empty())
 | 
			
		||||
					A.replace(Y, AB);
 | 
			
		||||
				if (rstport != IdString()) {
 | 
			
		||||
					SigSpec S = rstmux->getPort(ID(S));
 | 
			
		||||
					SigSpec S = rstmux->getPort(ID::S);
 | 
			
		||||
					cell->setPort(rstport, rstpol ? S : pm.module->Not(NEW_ID, S));
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			else if (rstport != IdString())
 | 
			
		||||
				cell->setPort(rstport, State::S0);
 | 
			
		||||
			if (cemux) {
 | 
			
		||||
				SigSpec Y = cemux->getPort(ID(Y));
 | 
			
		||||
				SigSpec BA = cemux->getPort(cepol ? ID(B) : ID(A));
 | 
			
		||||
				SigSpec S = cemux->getPort(ID(S));
 | 
			
		||||
				SigSpec Y = cemux->getPort(ID::Y);
 | 
			
		||||
				SigSpec BA = cemux->getPort(cepol ? ID::B : ID::A);
 | 
			
		||||
				SigSpec S = cemux->getPort(ID::S);
 | 
			
		||||
				if (!A.empty())
 | 
			
		||||
					A.replace(Y, BA);
 | 
			
		||||
				cell->setPort(ceport, cepol ? S : pm.module->Not(NEW_ID, S));
 | 
			
		||||
| 
						 | 
				
			
			@ -714,7 +714,7 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm)
 | 
			
		|||
				cell->setPort(ceport, State::S1);
 | 
			
		||||
 | 
			
		||||
			for (auto c : Q.chunks()) {
 | 
			
		||||
				auto it = c.wire->attributes.find(ID(init));
 | 
			
		||||
				auto it = c.wire->attributes.find(ID::init);
 | 
			
		||||
				if (it == c.wire->attributes.end())
 | 
			
		||||
					continue;
 | 
			
		||||
				for (int i = c.offset; i < c.offset+c.width; i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -725,10 +725,10 @@ void xilinx_dsp_packC(xilinx_dsp_CREG_pm &pm)
 | 
			
		|||
		};
 | 
			
		||||
 | 
			
		||||
		if (st.ffC) {
 | 
			
		||||
			SigSpec C = cell->getPort(ID(C));
 | 
			
		||||
			SigSpec C = cell->getPort(ID::C);
 | 
			
		||||
			f(C, st.ffC, st.ffCcemux, st.ffCcepol, ID(CEC), st.ffCrstmux, st.ffCrstpol, ID(RSTC));
 | 
			
		||||
			pm.add_siguser(C, cell);
 | 
			
		||||
			cell->setPort(ID(C), C);
 | 
			
		||||
			cell->setPort(ID::C, C);
 | 
			
		||||
			cell->setParam(ID(CREG), 1);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,9 +36,9 @@ void run_fixed(xilinx_srl_pm &pm)
 | 
			
		|||
	for (auto cell : ud.longest_chain) {
 | 
			
		||||
		log_debug("    %s\n", log_id(cell));
 | 
			
		||||
		if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_))) {
 | 
			
		||||
			SigBit Q = cell->getPort(ID(Q));
 | 
			
		||||
			SigBit Q = cell->getPort(ID::Q);
 | 
			
		||||
			log_assert(Q.wire);
 | 
			
		||||
			auto it = Q.wire->attributes.find(ID(init));
 | 
			
		||||
			auto it = Q.wire->attributes.find(ID::init);
 | 
			
		||||
			if (it != Q.wire->attributes.end()) {
 | 
			
		||||
				auto &i = it->second[Q.offset];
 | 
			
		||||
				initval.append(i);
 | 
			
		||||
| 
						 | 
				
			
			@ -48,7 +48,7 @@ void run_fixed(xilinx_srl_pm &pm)
 | 
			
		|||
				initval.append(State::Sx);
 | 
			
		||||
		}
 | 
			
		||||
		else if (cell->type.in(ID(FDRE), ID(FDRE_1))) {
 | 
			
		||||
			if (cell->parameters.at(ID(INIT), State::S0).as_bool())
 | 
			
		||||
			if (cell->parameters.at(ID::INIT, State::S0).as_bool())
 | 
			
		||||
				initval.append(State::S1);
 | 
			
		||||
			else
 | 
			
		||||
				initval.append(State::S0);
 | 
			
		||||
| 
						 | 
				
			
			@ -64,11 +64,11 @@ void run_fixed(xilinx_srl_pm &pm)
 | 
			
		|||
	pm.module->swap_names(c, first_cell);
 | 
			
		||||
 | 
			
		||||
	if (first_cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), ID(FDRE), ID(FDRE_1))) {
 | 
			
		||||
		c->setParam(ID(DEPTH), GetSize(ud.longest_chain));
 | 
			
		||||
		c->setParam(ID(INIT), initval.as_const());
 | 
			
		||||
		c->setParam(ID::DEPTH, GetSize(ud.longest_chain));
 | 
			
		||||
		c->setParam(ID::INIT, initval.as_const());
 | 
			
		||||
		if (first_cell->type.in(ID($_DFF_P_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
 | 
			
		||||
			c->setParam(ID(CLKPOL), 1);
 | 
			
		||||
		else if (first_cell->type.in(ID($_DFF_N_), ID($DFFE_NN_), ID($_DFFE_NP_), ID(FDRE_1)))
 | 
			
		||||
		else if (first_cell->type.in(ID($_DFF_N_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID(FDRE_1)))
 | 
			
		||||
			c->setParam(ID(CLKPOL), 0);
 | 
			
		||||
		else if (first_cell->type.in(ID(FDRE))) {
 | 
			
		||||
			if (!first_cell->parameters.at(ID(IS_C_INVERTED), State::S0).as_bool())
 | 
			
		||||
| 
						 | 
				
			
			@ -85,16 +85,16 @@ void run_fixed(xilinx_srl_pm &pm)
 | 
			
		|||
		else
 | 
			
		||||
			c->setParam(ID(ENPOL), 2);
 | 
			
		||||
 | 
			
		||||
		c->setPort(ID(C), first_cell->getPort(ID(C)));
 | 
			
		||||
		c->setPort(ID(D), first_cell->getPort(ID(D)));
 | 
			
		||||
		c->setPort(ID(Q), last_cell->getPort(ID(Q)));
 | 
			
		||||
		c->setPort(ID(L), GetSize(ud.longest_chain)-1);
 | 
			
		||||
		c->setPort(ID::C, first_cell->getPort(ID::C));
 | 
			
		||||
		c->setPort(ID::D, first_cell->getPort(ID::D));
 | 
			
		||||
		c->setPort(ID::Q, last_cell->getPort(ID::Q));
 | 
			
		||||
		c->setPort(ID::L, GetSize(ud.longest_chain)-1);
 | 
			
		||||
		if (first_cell->type.in(ID($_DFF_N_), ID($_DFF_P_)))
 | 
			
		||||
			c->setPort(ID(E), State::S1);
 | 
			
		||||
			c->setPort(ID::E, State::S1);
 | 
			
		||||
		else if (first_cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
 | 
			
		||||
			c->setPort(ID(E), first_cell->getPort(ID(E)));
 | 
			
		||||
			c->setPort(ID::E, first_cell->getPort(ID::E));
 | 
			
		||||
		else if (first_cell->type.in(ID(FDRE), ID(FDRE_1)))
 | 
			
		||||
			c->setPort(ID(E), first_cell->getPort(ID(CE)));
 | 
			
		||||
			c->setPort(ID::E, first_cell->getPort(ID(CE)));
 | 
			
		||||
		else
 | 
			
		||||
			log_abort();
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -117,9 +117,9 @@ void run_variable(xilinx_srl_pm &pm)
 | 
			
		|||
		auto slice = i.second;
 | 
			
		||||
		log_debug("    %s\n", log_id(cell));
 | 
			
		||||
		if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), ID($dff), ID($dffe))) {
 | 
			
		||||
			SigBit Q = cell->getPort(ID(Q))[slice];
 | 
			
		||||
			SigBit Q = cell->getPort(ID::Q)[slice];
 | 
			
		||||
			log_assert(Q.wire);
 | 
			
		||||
			auto it = Q.wire->attributes.find(ID(init));
 | 
			
		||||
			auto it = Q.wire->attributes.find(ID::init);
 | 
			
		||||
			if (it != Q.wire->attributes.end()) {
 | 
			
		||||
				auto &i = it->second[Q.offset];
 | 
			
		||||
				initval.append(i);
 | 
			
		||||
| 
						 | 
				
			
			@ -140,15 +140,15 @@ void run_variable(xilinx_srl_pm &pm)
 | 
			
		|||
	pm.module->swap_names(c, first_cell);
 | 
			
		||||
 | 
			
		||||
	if (first_cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_), ID($dff), ID($dffe))) {
 | 
			
		||||
		c->setParam(ID(DEPTH), GetSize(ud.chain));
 | 
			
		||||
		c->setParam(ID(INIT), initval.as_const());
 | 
			
		||||
		c->setParam(ID::DEPTH, GetSize(ud.chain));
 | 
			
		||||
		c->setParam(ID::INIT, initval.as_const());
 | 
			
		||||
		Const clkpol, enpol;
 | 
			
		||||
		if (first_cell->type.in(ID($_DFF_P_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
 | 
			
		||||
			clkpol = 1;
 | 
			
		||||
		else if (first_cell->type.in(ID($_DFF_N_), ID($DFFE_NN_), ID($_DFFE_NP_)))
 | 
			
		||||
		else if (first_cell->type.in(ID($_DFF_N_), ID($_DFFE_NN_), ID($_DFFE_NP_)))
 | 
			
		||||
			clkpol = 0;
 | 
			
		||||
		else if (first_cell->type.in(ID($dff), ID($dffe)))
 | 
			
		||||
			clkpol = first_cell->getParam(ID(CLK_POLARITY));
 | 
			
		||||
			clkpol = first_cell->getParam(ID::CLK_POLARITY);
 | 
			
		||||
		else
 | 
			
		||||
			log_abort();
 | 
			
		||||
		if (first_cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)))
 | 
			
		||||
| 
						 | 
				
			
			@ -156,27 +156,27 @@ void run_variable(xilinx_srl_pm &pm)
 | 
			
		|||
		else if (first_cell->type.in(ID($_DFFE_NN_), ID($_DFFE_PN_)))
 | 
			
		||||
			enpol = 0;
 | 
			
		||||
		else if (first_cell->type.in(ID($dffe)))
 | 
			
		||||
			enpol = first_cell->getParam(ID(EN_POLARITY));
 | 
			
		||||
			enpol = first_cell->getParam(ID::EN_POLARITY);
 | 
			
		||||
		else
 | 
			
		||||
			enpol = 2;
 | 
			
		||||
		c->setParam(ID(CLKPOL), clkpol);
 | 
			
		||||
		c->setParam(ID(ENPOL), enpol);
 | 
			
		||||
 | 
			
		||||
		if (first_cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
 | 
			
		||||
			c->setPort(ID(C), first_cell->getPort(ID(C)));
 | 
			
		||||
			c->setPort(ID::C, first_cell->getPort(ID::C));
 | 
			
		||||
		else if (first_cell->type.in(ID($dff), ID($dffe)))
 | 
			
		||||
			c->setPort(ID(C), first_cell->getPort(ID(CLK)));
 | 
			
		||||
			c->setPort(ID::C, first_cell->getPort(ID::CLK));
 | 
			
		||||
		else
 | 
			
		||||
			log_abort();
 | 
			
		||||
		c->setPort(ID(D), first_cell->getPort(ID(D))[first_slice]);
 | 
			
		||||
		c->setPort(ID(Q), st.shiftx->getPort(ID(Y)));
 | 
			
		||||
		c->setPort(ID(L), st.shiftx->getPort(ID(B)));
 | 
			
		||||
		c->setPort(ID::D, first_cell->getPort(ID::D)[first_slice]);
 | 
			
		||||
		c->setPort(ID::Q, st.shiftx->getPort(ID::Y));
 | 
			
		||||
		c->setPort(ID::L, st.shiftx->getPort(ID::B));
 | 
			
		||||
		if (first_cell->type.in(ID($_DFF_N_), ID($_DFF_P_), ID($dff)))
 | 
			
		||||
			c->setPort(ID(E), State::S1);
 | 
			
		||||
			c->setPort(ID::E, State::S1);
 | 
			
		||||
		else if (first_cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
 | 
			
		||||
			c->setPort(ID(E), first_cell->getPort(ID(E)));
 | 
			
		||||
			c->setPort(ID::E, first_cell->getPort(ID::E));
 | 
			
		||||
		else if (first_cell->type.in(ID($dffe)))
 | 
			
		||||
			c->setPort(ID(E), first_cell->getPort(ID(EN)));
 | 
			
		||||
			c->setPort(ID::E, first_cell->getPort(ID::EN));
 | 
			
		||||
		else
 | 
			
		||||
			log_abort();
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,45 +39,45 @@ bool check_signal(RTLIL::Module *mod, RTLIL::SigSpec signal, RTLIL::SigSpec ref,
 | 
			
		|||
 | 
			
		||||
	for (auto cell : mod->cells())
 | 
			
		||||
	{
 | 
			
		||||
		if (cell->type == "$reduce_or" && cell->getPort("\\Y") == signal)
 | 
			
		||||
			return check_signal(mod, cell->getPort("\\A"), ref, polarity);
 | 
			
		||||
		if (cell->type == ID($reduce_or) && cell->getPort(ID::Y) == signal)
 | 
			
		||||
			return check_signal(mod, cell->getPort(ID::A), ref, polarity);
 | 
			
		||||
 | 
			
		||||
		if (cell->type == "$reduce_bool" && cell->getPort("\\Y") == signal)
 | 
			
		||||
			return check_signal(mod, cell->getPort("\\A"), ref, polarity);
 | 
			
		||||
		if (cell->type == ID($reduce_bool) && cell->getPort(ID::Y) == signal)
 | 
			
		||||
			return check_signal(mod, cell->getPort(ID::A), ref, polarity);
 | 
			
		||||
 | 
			
		||||
		if (cell->type == "$logic_not" && cell->getPort("\\Y") == signal) {
 | 
			
		||||
		if (cell->type == ID($logic_not) && cell->getPort(ID::Y) == signal) {
 | 
			
		||||
			polarity = !polarity;
 | 
			
		||||
			return check_signal(mod, cell->getPort("\\A"), ref, polarity);
 | 
			
		||||
			return check_signal(mod, cell->getPort(ID::A), ref, polarity);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (cell->type == "$not" && cell->getPort("\\Y") == signal) {
 | 
			
		||||
		if (cell->type == ID($not) && cell->getPort(ID::Y) == signal) {
 | 
			
		||||
			polarity = !polarity;
 | 
			
		||||
			return check_signal(mod, cell->getPort("\\A"), ref, polarity);
 | 
			
		||||
			return check_signal(mod, cell->getPort(ID::A), ref, polarity);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (cell->type.in("$eq", "$eqx") && cell->getPort("\\Y") == signal) {
 | 
			
		||||
			if (cell->getPort("\\A").is_fully_const()) {
 | 
			
		||||
				if (!cell->getPort("\\A").as_bool())
 | 
			
		||||
		if (cell->type.in(ID($eq), ID($eqx)) && cell->getPort(ID::Y) == signal) {
 | 
			
		||||
			if (cell->getPort(ID::A).is_fully_const()) {
 | 
			
		||||
				if (!cell->getPort(ID::A).as_bool())
 | 
			
		||||
					polarity = !polarity;
 | 
			
		||||
				return check_signal(mod, cell->getPort("\\B"), ref, polarity);
 | 
			
		||||
				return check_signal(mod, cell->getPort(ID::B), ref, polarity);
 | 
			
		||||
			}
 | 
			
		||||
			if (cell->getPort("\\B").is_fully_const()) {
 | 
			
		||||
				if (!cell->getPort("\\B").as_bool())
 | 
			
		||||
			if (cell->getPort(ID::B).is_fully_const()) {
 | 
			
		||||
				if (!cell->getPort(ID::B).as_bool())
 | 
			
		||||
					polarity = !polarity;
 | 
			
		||||
				return check_signal(mod, cell->getPort("\\A"), ref, polarity);
 | 
			
		||||
				return check_signal(mod, cell->getPort(ID::A), ref, polarity);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (cell->type.in("$ne", "$nex") && cell->getPort("\\Y") == signal) {
 | 
			
		||||
			if (cell->getPort("\\A").is_fully_const()) {
 | 
			
		||||
				if (cell->getPort("\\A").as_bool())
 | 
			
		||||
		if (cell->type.in(ID($ne), ID($nex)) && cell->getPort(ID::Y) == signal) {
 | 
			
		||||
			if (cell->getPort(ID::A).is_fully_const()) {
 | 
			
		||||
				if (cell->getPort(ID::A).as_bool())
 | 
			
		||||
					polarity = !polarity;
 | 
			
		||||
				return check_signal(mod, cell->getPort("\\B"), ref, polarity);
 | 
			
		||||
				return check_signal(mod, cell->getPort(ID::B), ref, polarity);
 | 
			
		||||
			}
 | 
			
		||||
			if (cell->getPort("\\B").is_fully_const()) {
 | 
			
		||||
				if (cell->getPort("\\B").as_bool())
 | 
			
		||||
			if (cell->getPort(ID::B).is_fully_const()) {
 | 
			
		||||
				if (cell->getPort(ID::B).as_bool())
 | 
			
		||||
					polarity = !polarity;
 | 
			
		||||
				return check_signal(mod, cell->getPort("\\A"), ref, polarity);
 | 
			
		||||
				return check_signal(mod, cell->getPort(ID::A), ref, polarity);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -261,8 +261,8 @@ struct ProcArstPass : public Pass {
 | 
			
		|||
							for (auto &act : sync->actions) {
 | 
			
		||||
								RTLIL::SigSpec arst_sig, arst_val;
 | 
			
		||||
								for (auto &chunk : act.first.chunks())
 | 
			
		||||
									if (chunk.wire && chunk.wire->attributes.count("\\init")) {
 | 
			
		||||
										RTLIL::SigSpec value = chunk.wire->attributes.at("\\init");
 | 
			
		||||
									if (chunk.wire && chunk.wire->attributes.count(ID::init)) {
 | 
			
		||||
										RTLIL::SigSpec value = chunk.wire->attributes.at(ID::init);
 | 
			
		||||
										value.extend_u0(chunk.wire->width, false);
 | 
			
		||||
										arst_sig.append(chunk);
 | 
			
		||||
										arst_val.append(value.extract(chunk.offset, chunk.width));
 | 
			
		||||
| 
						 | 
				
			
			@ -285,7 +285,7 @@ struct ProcArstPass : public Pass {
 | 
			
		|||
			}
 | 
			
		||||
 | 
			
		||||
		for (auto wire : delete_initattr_wires)
 | 
			
		||||
			wire->attributes.erase("\\init");
 | 
			
		||||
			wire->attributes.erase(ID::init);
 | 
			
		||||
	}
 | 
			
		||||
} ProcArstPass;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,69 +75,69 @@ void gen_dffsr_complex(RTLIL::Module *mod, RTLIL::SigSpec sig_d, RTLIL::SigSpec
 | 
			
		|||
				log_abort();
 | 
			
		||||
 | 
			
		||||
		if (sync_low_signals.size() > 1) {
 | 
			
		||||
			RTLIL::Cell *cell = mod->addCell(NEW_ID, "$reduce_or");
 | 
			
		||||
			cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
 | 
			
		||||
			cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size());
 | 
			
		||||
			cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
			cell->setPort("\\A", sync_low_signals);
 | 
			
		||||
			cell->setPort("\\Y", sync_low_signals = mod->addWire(NEW_ID));
 | 
			
		||||
			RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($reduce_or));
 | 
			
		||||
			cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
 | 
			
		||||
			cell->parameters[ID::A_WIDTH] = RTLIL::Const(sync_low_signals.size());
 | 
			
		||||
			cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
			cell->setPort(ID::A, sync_low_signals);
 | 
			
		||||
			cell->setPort(ID::Y, sync_low_signals = mod->addWire(NEW_ID));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sync_low_signals.size() > 0) {
 | 
			
		||||
			RTLIL::Cell *cell = mod->addCell(NEW_ID, "$not");
 | 
			
		||||
			cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
 | 
			
		||||
			cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_low_signals.size());
 | 
			
		||||
			cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
			cell->setPort("\\A", sync_low_signals);
 | 
			
		||||
			cell->setPort("\\Y", mod->addWire(NEW_ID));
 | 
			
		||||
			sync_high_signals.append(cell->getPort("\\Y"));
 | 
			
		||||
			RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($not));
 | 
			
		||||
			cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
 | 
			
		||||
			cell->parameters[ID::A_WIDTH] = RTLIL::Const(sync_low_signals.size());
 | 
			
		||||
			cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
			cell->setPort(ID::A, sync_low_signals);
 | 
			
		||||
			cell->setPort(ID::Y, mod->addWire(NEW_ID));
 | 
			
		||||
			sync_high_signals.append(cell->getPort(ID::Y));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (sync_high_signals.size() > 1) {
 | 
			
		||||
			RTLIL::Cell *cell = mod->addCell(NEW_ID, "$reduce_or");
 | 
			
		||||
			cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
 | 
			
		||||
			cell->parameters["\\A_WIDTH"] = RTLIL::Const(sync_high_signals.size());
 | 
			
		||||
			cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
			cell->setPort("\\A", sync_high_signals);
 | 
			
		||||
			cell->setPort("\\Y", sync_high_signals = mod->addWire(NEW_ID));
 | 
			
		||||
			RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($reduce_or));
 | 
			
		||||
			cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
 | 
			
		||||
			cell->parameters[ID::A_WIDTH] = RTLIL::Const(sync_high_signals.size());
 | 
			
		||||
			cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
			cell->setPort(ID::A, sync_high_signals);
 | 
			
		||||
			cell->setPort(ID::Y, sync_high_signals = mod->addWire(NEW_ID));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		RTLIL::Cell *inv_cell = mod->addCell(NEW_ID, "$not");
 | 
			
		||||
		inv_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
 | 
			
		||||
		inv_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig_d.size());
 | 
			
		||||
		inv_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_d.size());
 | 
			
		||||
		inv_cell->setPort("\\A", sync_value);
 | 
			
		||||
		inv_cell->setPort("\\Y", sync_value_inv = mod->addWire(NEW_ID, sig_d.size()));
 | 
			
		||||
		RTLIL::Cell *inv_cell = mod->addCell(NEW_ID, ID($not));
 | 
			
		||||
		inv_cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
 | 
			
		||||
		inv_cell->parameters[ID::A_WIDTH] = RTLIL::Const(sig_d.size());
 | 
			
		||||
		inv_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(sig_d.size());
 | 
			
		||||
		inv_cell->setPort(ID::A, sync_value);
 | 
			
		||||
		inv_cell->setPort(ID::Y, sync_value_inv = mod->addWire(NEW_ID, sig_d.size()));
 | 
			
		||||
 | 
			
		||||
		RTLIL::Cell *mux_set_cell = mod->addCell(NEW_ID, "$mux");
 | 
			
		||||
		mux_set_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size());
 | 
			
		||||
		mux_set_cell->setPort("\\A", sig_sr_set);
 | 
			
		||||
		mux_set_cell->setPort("\\B", sync_value);
 | 
			
		||||
		mux_set_cell->setPort("\\S", sync_high_signals);
 | 
			
		||||
		mux_set_cell->setPort("\\Y", sig_sr_set = mod->addWire(NEW_ID, sig_d.size()));
 | 
			
		||||
		RTLIL::Cell *mux_set_cell = mod->addCell(NEW_ID, ID($mux));
 | 
			
		||||
		mux_set_cell->parameters[ID::WIDTH] = RTLIL::Const(sig_d.size());
 | 
			
		||||
		mux_set_cell->setPort(ID::A, sig_sr_set);
 | 
			
		||||
		mux_set_cell->setPort(ID::B, sync_value);
 | 
			
		||||
		mux_set_cell->setPort(ID::S, sync_high_signals);
 | 
			
		||||
		mux_set_cell->setPort(ID::Y, sig_sr_set = mod->addWire(NEW_ID, sig_d.size()));
 | 
			
		||||
 | 
			
		||||
		RTLIL::Cell *mux_clr_cell = mod->addCell(NEW_ID, "$mux");
 | 
			
		||||
		mux_clr_cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size());
 | 
			
		||||
		mux_clr_cell->setPort("\\A", sig_sr_clr);
 | 
			
		||||
		mux_clr_cell->setPort("\\B", sync_value_inv);
 | 
			
		||||
		mux_clr_cell->setPort("\\S", sync_high_signals);
 | 
			
		||||
		mux_clr_cell->setPort("\\Y", sig_sr_clr = mod->addWire(NEW_ID, sig_d.size()));
 | 
			
		||||
		RTLIL::Cell *mux_clr_cell = mod->addCell(NEW_ID, ID($mux));
 | 
			
		||||
		mux_clr_cell->parameters[ID::WIDTH] = RTLIL::Const(sig_d.size());
 | 
			
		||||
		mux_clr_cell->setPort(ID::A, sig_sr_clr);
 | 
			
		||||
		mux_clr_cell->setPort(ID::B, sync_value_inv);
 | 
			
		||||
		mux_clr_cell->setPort(ID::S, sync_high_signals);
 | 
			
		||||
		mux_clr_cell->setPort(ID::Y, sig_sr_clr = mod->addWire(NEW_ID, sig_d.size()));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	std::stringstream sstr;
 | 
			
		||||
	sstr << "$procdff$" << (autoidx++);
 | 
			
		||||
 | 
			
		||||
	RTLIL::Cell *cell = mod->addCell(sstr.str(), "$dffsr");
 | 
			
		||||
	RTLIL::Cell *cell = mod->addCell(sstr.str(), ID($dffsr));
 | 
			
		||||
	cell->attributes = proc->attributes;
 | 
			
		||||
	cell->parameters["\\WIDTH"] = RTLIL::Const(sig_d.size());
 | 
			
		||||
	cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1);
 | 
			
		||||
	cell->parameters["\\SET_POLARITY"] = RTLIL::Const(true, 1);
 | 
			
		||||
	cell->parameters["\\CLR_POLARITY"] = RTLIL::Const(true, 1);
 | 
			
		||||
	cell->setPort("\\D", sig_d);
 | 
			
		||||
	cell->setPort("\\Q", sig_q);
 | 
			
		||||
	cell->setPort("\\CLK", clk);
 | 
			
		||||
	cell->setPort("\\SET", sig_sr_set);
 | 
			
		||||
	cell->setPort("\\CLR", sig_sr_clr);
 | 
			
		||||
	cell->parameters[ID::WIDTH] = RTLIL::Const(sig_d.size());
 | 
			
		||||
	cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity, 1);
 | 
			
		||||
	cell->parameters[ID::SET_POLARITY] = RTLIL::Const(true, 1);
 | 
			
		||||
	cell->parameters[ID::CLR_POLARITY] = RTLIL::Const(true, 1);
 | 
			
		||||
	cell->setPort(ID::D, sig_d);
 | 
			
		||||
	cell->setPort(ID::Q, sig_q);
 | 
			
		||||
	cell->setPort(ID::CLK, clk);
 | 
			
		||||
	cell->setPort(ID::SET, sig_sr_set);
 | 
			
		||||
	cell->setPort(ID::CLR, sig_sr_clr);
 | 
			
		||||
 | 
			
		||||
	log("  created %s cell `%s' with %s edge clock and multiple level-sensitive resets.\n",
 | 
			
		||||
			cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative");
 | 
			
		||||
| 
						 | 
				
			
			@ -153,38 +153,38 @@ void gen_dffsr(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::SigSpec sig_set
 | 
			
		|||
	RTLIL::SigSpec sig_sr_set = mod->addWire(NEW_ID, sig_in.size());
 | 
			
		||||
	RTLIL::SigSpec sig_sr_clr = mod->addWire(NEW_ID, sig_in.size());
 | 
			
		||||
 | 
			
		||||
	RTLIL::Cell *inv_set = mod->addCell(NEW_ID, "$not");
 | 
			
		||||
	inv_set->parameters["\\A_SIGNED"] = RTLIL::Const(0);
 | 
			
		||||
	inv_set->parameters["\\A_WIDTH"] = RTLIL::Const(sig_in.size());
 | 
			
		||||
	inv_set->parameters["\\Y_WIDTH"] = RTLIL::Const(sig_in.size());
 | 
			
		||||
	inv_set->setPort("\\A", sig_set);
 | 
			
		||||
	inv_set->setPort("\\Y", sig_set_inv);
 | 
			
		||||
	RTLIL::Cell *inv_set = mod->addCell(NEW_ID, ID($not));
 | 
			
		||||
	inv_set->parameters[ID::A_SIGNED] = RTLIL::Const(0);
 | 
			
		||||
	inv_set->parameters[ID::A_WIDTH] = RTLIL::Const(sig_in.size());
 | 
			
		||||
	inv_set->parameters[ID::Y_WIDTH] = RTLIL::Const(sig_in.size());
 | 
			
		||||
	inv_set->setPort(ID::A, sig_set);
 | 
			
		||||
	inv_set->setPort(ID::Y, sig_set_inv);
 | 
			
		||||
 | 
			
		||||
	RTLIL::Cell *mux_sr_set = mod->addCell(NEW_ID, "$mux");
 | 
			
		||||
	mux_sr_set->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size());
 | 
			
		||||
	mux_sr_set->setPort(set_polarity ? "\\A" : "\\B", RTLIL::Const(0, sig_in.size()));
 | 
			
		||||
	mux_sr_set->setPort(set_polarity ? "\\B" : "\\A", sig_set);
 | 
			
		||||
	mux_sr_set->setPort("\\Y", sig_sr_set);
 | 
			
		||||
	mux_sr_set->setPort("\\S", set);
 | 
			
		||||
	RTLIL::Cell *mux_sr_set = mod->addCell(NEW_ID, ID($mux));
 | 
			
		||||
	mux_sr_set->parameters[ID::WIDTH] = RTLIL::Const(sig_in.size());
 | 
			
		||||
	mux_sr_set->setPort(set_polarity ? ID::A : ID::B, RTLIL::Const(0, sig_in.size()));
 | 
			
		||||
	mux_sr_set->setPort(set_polarity ? ID::B : ID::A, sig_set);
 | 
			
		||||
	mux_sr_set->setPort(ID::Y, sig_sr_set);
 | 
			
		||||
	mux_sr_set->setPort(ID::S, set);
 | 
			
		||||
 | 
			
		||||
	RTLIL::Cell *mux_sr_clr = mod->addCell(NEW_ID, "$mux");
 | 
			
		||||
	mux_sr_clr->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size());
 | 
			
		||||
	mux_sr_clr->setPort(set_polarity ? "\\A" : "\\B", RTLIL::Const(0, sig_in.size()));
 | 
			
		||||
	mux_sr_clr->setPort(set_polarity ? "\\B" : "\\A", sig_set_inv);
 | 
			
		||||
	mux_sr_clr->setPort("\\Y", sig_sr_clr);
 | 
			
		||||
	mux_sr_clr->setPort("\\S", set);
 | 
			
		||||
	RTLIL::Cell *mux_sr_clr = mod->addCell(NEW_ID, ID($mux));
 | 
			
		||||
	mux_sr_clr->parameters[ID::WIDTH] = RTLIL::Const(sig_in.size());
 | 
			
		||||
	mux_sr_clr->setPort(set_polarity ? ID::A : ID::B, RTLIL::Const(0, sig_in.size()));
 | 
			
		||||
	mux_sr_clr->setPort(set_polarity ? ID::B : ID::A, sig_set_inv);
 | 
			
		||||
	mux_sr_clr->setPort(ID::Y, sig_sr_clr);
 | 
			
		||||
	mux_sr_clr->setPort(ID::S, set);
 | 
			
		||||
 | 
			
		||||
	RTLIL::Cell *cell = mod->addCell(sstr.str(), "$dffsr");
 | 
			
		||||
	RTLIL::Cell *cell = mod->addCell(sstr.str(), ID($dffsr));
 | 
			
		||||
	cell->attributes = proc->attributes;
 | 
			
		||||
	cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size());
 | 
			
		||||
	cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1);
 | 
			
		||||
	cell->parameters["\\SET_POLARITY"] = RTLIL::Const(true, 1);
 | 
			
		||||
	cell->parameters["\\CLR_POLARITY"] = RTLIL::Const(true, 1);
 | 
			
		||||
	cell->setPort("\\D", sig_in);
 | 
			
		||||
	cell->setPort("\\Q", sig_out);
 | 
			
		||||
	cell->setPort("\\CLK", clk);
 | 
			
		||||
	cell->setPort("\\SET", sig_sr_set);
 | 
			
		||||
	cell->setPort("\\CLR", sig_sr_clr);
 | 
			
		||||
	cell->parameters[ID::WIDTH] = RTLIL::Const(sig_in.size());
 | 
			
		||||
	cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity, 1);
 | 
			
		||||
	cell->parameters[ID::SET_POLARITY] = RTLIL::Const(true, 1);
 | 
			
		||||
	cell->parameters[ID::CLR_POLARITY] = RTLIL::Const(true, 1);
 | 
			
		||||
	cell->setPort(ID::D, sig_in);
 | 
			
		||||
	cell->setPort(ID::Q, sig_out);
 | 
			
		||||
	cell->setPort(ID::CLK, clk);
 | 
			
		||||
	cell->setPort(ID::SET, sig_sr_set);
 | 
			
		||||
	cell->setPort(ID::CLR, sig_sr_clr);
 | 
			
		||||
 | 
			
		||||
	log("  created %s cell `%s' with %s edge clock and %s level non-const reset.\n", cell->type.c_str(), cell->name.c_str(),
 | 
			
		||||
			clk_polarity ? "positive" : "negative", set_polarity ? "positive" : "negative");
 | 
			
		||||
| 
						 | 
				
			
			@ -196,24 +196,24 @@ void gen_dff(RTLIL::Module *mod, RTLIL::SigSpec sig_in, RTLIL::Const val_rst, RT
 | 
			
		|||
	std::stringstream sstr;
 | 
			
		||||
	sstr << "$procdff$" << (autoidx++);
 | 
			
		||||
 | 
			
		||||
	RTLIL::Cell *cell = mod->addCell(sstr.str(), clk.empty() ? "$ff" : arst ? "$adff" : "$dff");
 | 
			
		||||
	RTLIL::Cell *cell = mod->addCell(sstr.str(), clk.empty() ? ID($ff) : arst ? ID($adff) : ID($dff));
 | 
			
		||||
	cell->attributes = proc->attributes;
 | 
			
		||||
 | 
			
		||||
	cell->parameters["\\WIDTH"] = RTLIL::Const(sig_in.size());
 | 
			
		||||
	cell->parameters[ID::WIDTH] = RTLIL::Const(sig_in.size());
 | 
			
		||||
	if (arst) {
 | 
			
		||||
		cell->parameters["\\ARST_POLARITY"] = RTLIL::Const(arst_polarity, 1);
 | 
			
		||||
		cell->parameters["\\ARST_VALUE"] = val_rst;
 | 
			
		||||
		cell->parameters[ID::ARST_POLARITY] = RTLIL::Const(arst_polarity, 1);
 | 
			
		||||
		cell->parameters[ID::ARST_VALUE] = val_rst;
 | 
			
		||||
	}
 | 
			
		||||
	if (!clk.empty()) {
 | 
			
		||||
		cell->parameters["\\CLK_POLARITY"] = RTLIL::Const(clk_polarity, 1);
 | 
			
		||||
		cell->parameters[ID::CLK_POLARITY] = RTLIL::Const(clk_polarity, 1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cell->setPort("\\D", sig_in);
 | 
			
		||||
	cell->setPort("\\Q", sig_out);
 | 
			
		||||
	cell->setPort(ID::D, sig_in);
 | 
			
		||||
	cell->setPort(ID::Q, sig_out);
 | 
			
		||||
	if (arst)
 | 
			
		||||
		cell->setPort("\\ARST", *arst);
 | 
			
		||||
		cell->setPort(ID::ARST, *arst);
 | 
			
		||||
	if (!clk.empty())
 | 
			
		||||
		cell->setPort("\\CLK", clk);
 | 
			
		||||
		cell->setPort(ID::CLK, clk);
 | 
			
		||||
 | 
			
		||||
	if (!clk.empty())
 | 
			
		||||
		log("  created %s cell `%s' with %s edge clock", cell->type.c_str(), cell->name.c_str(), clk_polarity ? "positive" : "negative");
 | 
			
		||||
| 
						 | 
				
			
			@ -303,15 +303,15 @@ void proc_dff(RTLIL::Module *mod, RTLIL::Process *proc, ConstEval &ce)
 | 
			
		|||
				}
 | 
			
		||||
				log_assert(inputs.size() == compare.size());
 | 
			
		||||
 | 
			
		||||
				RTLIL::Cell *cell = mod->addCell(NEW_ID, "$ne");
 | 
			
		||||
				cell->parameters["\\A_SIGNED"] = RTLIL::Const(false, 1);
 | 
			
		||||
				cell->parameters["\\B_SIGNED"] = RTLIL::Const(false, 1);
 | 
			
		||||
				cell->parameters["\\A_WIDTH"] = RTLIL::Const(inputs.size());
 | 
			
		||||
				cell->parameters["\\B_WIDTH"] = RTLIL::Const(inputs.size());
 | 
			
		||||
				cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
				cell->setPort("\\A", inputs);
 | 
			
		||||
				cell->setPort("\\B", compare);
 | 
			
		||||
				cell->setPort("\\Y", sync_level->signal);
 | 
			
		||||
				RTLIL::Cell *cell = mod->addCell(NEW_ID, ID($ne));
 | 
			
		||||
				cell->parameters[ID::A_SIGNED] = RTLIL::Const(false, 1);
 | 
			
		||||
				cell->parameters[ID::B_SIGNED] = RTLIL::Const(false, 1);
 | 
			
		||||
				cell->parameters[ID::A_WIDTH] = RTLIL::Const(inputs.size());
 | 
			
		||||
				cell->parameters[ID::B_WIDTH] = RTLIL::Const(inputs.size());
 | 
			
		||||
				cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
				cell->setPort(ID::A, inputs);
 | 
			
		||||
				cell->setPort(ID::B, compare);
 | 
			
		||||
				cell->setPort(ID::Y, sync_level->signal);
 | 
			
		||||
 | 
			
		||||
				many_async_rules.clear();
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,16 +42,16 @@ struct proc_dlatch_db_t
 | 
			
		|||
	{
 | 
			
		||||
		for (auto cell : module->cells())
 | 
			
		||||
		{
 | 
			
		||||
			if (cell->type.in("$mux", "$pmux"))
 | 
			
		||||
			if (cell->type.in(ID($mux), ID($pmux)))
 | 
			
		||||
			{
 | 
			
		||||
				auto sig_y = sigmap(cell->getPort("\\Y"));
 | 
			
		||||
				auto sig_y = sigmap(cell->getPort(ID::Y));
 | 
			
		||||
				for (int i = 0; i < GetSize(sig_y); i++)
 | 
			
		||||
					mux_drivers[sig_y[i]] = pair<Cell*, int>(cell, i);
 | 
			
		||||
 | 
			
		||||
				pool<SigBit> mux_srcbits_pool;
 | 
			
		||||
				for (auto bit : sigmap(cell->getPort("\\A")))
 | 
			
		||||
				for (auto bit : sigmap(cell->getPort(ID::A)))
 | 
			
		||||
					mux_srcbits_pool.insert(bit);
 | 
			
		||||
				for (auto bit : sigmap(cell->getPort("\\B")))
 | 
			
		||||
				for (auto bit : sigmap(cell->getPort(ID::B)))
 | 
			
		||||
					mux_srcbits_pool.insert(bit);
 | 
			
		||||
 | 
			
		||||
				vector<SigBit> mux_srcbits_vec;
 | 
			
		||||
| 
						 | 
				
			
			@ -180,9 +180,9 @@ struct proc_dlatch_db_t
 | 
			
		|||
		Cell *cell = it->second.first;
 | 
			
		||||
		int index = it->second.second;
 | 
			
		||||
 | 
			
		||||
		SigSpec sig_a = sigmap(cell->getPort("\\A"));
 | 
			
		||||
		SigSpec sig_b = sigmap(cell->getPort("\\B"));
 | 
			
		||||
		SigSpec sig_s = sigmap(cell->getPort("\\S"));
 | 
			
		||||
		SigSpec sig_a = sigmap(cell->getPort(ID::A));
 | 
			
		||||
		SigSpec sig_b = sigmap(cell->getPort(ID::B));
 | 
			
		||||
		SigSpec sig_s = sigmap(cell->getPort(ID::S));
 | 
			
		||||
		int width = GetSize(sig_a);
 | 
			
		||||
 | 
			
		||||
		pool<int> children;
 | 
			
		||||
| 
						 | 
				
			
			@ -190,9 +190,9 @@ struct proc_dlatch_db_t
 | 
			
		|||
		int n = find_mux_feedback(sig_a[index], needle, set_undef);
 | 
			
		||||
		if (n != false_node) {
 | 
			
		||||
			if (set_undef && sig_a[index] == needle) {
 | 
			
		||||
				SigSpec sig = cell->getPort("\\A");
 | 
			
		||||
				SigSpec sig = cell->getPort(ID::A);
 | 
			
		||||
				sig[index] = State::Sx;
 | 
			
		||||
				cell->setPort("\\A", sig);
 | 
			
		||||
				cell->setPort(ID::A, sig);
 | 
			
		||||
			}
 | 
			
		||||
			for (int i = 0; i < GetSize(sig_s); i++)
 | 
			
		||||
				n = make_inner(sig_s[i], State::S0, n);
 | 
			
		||||
| 
						 | 
				
			
			@ -203,9 +203,9 @@ struct proc_dlatch_db_t
 | 
			
		|||
			n = find_mux_feedback(sig_b[i*width + index], needle, set_undef);
 | 
			
		||||
			if (n != false_node) {
 | 
			
		||||
				if (set_undef && sig_b[i*width + index] == needle) {
 | 
			
		||||
					SigSpec sig = cell->getPort("\\B");
 | 
			
		||||
					SigSpec sig = cell->getPort(ID::B);
 | 
			
		||||
					sig[i*width + index] = State::Sx;
 | 
			
		||||
					cell->setPort("\\B", sig);
 | 
			
		||||
					cell->setPort(ID::B, sig);
 | 
			
		||||
				}
 | 
			
		||||
				children.insert(make_inner(sig_s[i], State::S1, n));
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -257,9 +257,9 @@ struct proc_dlatch_db_t
 | 
			
		|||
 | 
			
		||||
	void fixup_mux(Cell *cell)
 | 
			
		||||
	{
 | 
			
		||||
		SigSpec sig_a = cell->getPort("\\A");
 | 
			
		||||
		SigSpec sig_b = cell->getPort("\\B");
 | 
			
		||||
		SigSpec sig_s = cell->getPort("\\S");
 | 
			
		||||
		SigSpec sig_a = cell->getPort(ID::A);
 | 
			
		||||
		SigSpec sig_b = cell->getPort(ID::B);
 | 
			
		||||
		SigSpec sig_s = cell->getPort(ID::S);
 | 
			
		||||
		SigSpec sig_any_valid_b;
 | 
			
		||||
 | 
			
		||||
		SigSpec sig_new_b, sig_new_s;
 | 
			
		||||
| 
						 | 
				
			
			@ -278,18 +278,18 @@ struct proc_dlatch_db_t
 | 
			
		|||
		}
 | 
			
		||||
 | 
			
		||||
		if (sig_a.is_fully_undef() && !sig_any_valid_b.empty())
 | 
			
		||||
			cell->setPort("\\A", sig_any_valid_b);
 | 
			
		||||
			cell->setPort(ID::A, sig_any_valid_b);
 | 
			
		||||
 | 
			
		||||
		if (GetSize(sig_new_s) == 1) {
 | 
			
		||||
			cell->type = "$mux";
 | 
			
		||||
			cell->unsetParam("\\S_WIDTH");
 | 
			
		||||
			cell->type = ID($mux);
 | 
			
		||||
			cell->unsetParam(ID::S_WIDTH);
 | 
			
		||||
		} else {
 | 
			
		||||
			cell->type = "$pmux";
 | 
			
		||||
			cell->setParam("\\S_WIDTH", GetSize(sig_new_s));
 | 
			
		||||
			cell->type = ID($pmux);
 | 
			
		||||
			cell->setParam(ID::S_WIDTH, GetSize(sig_new_s));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		cell->setPort("\\B", sig_new_b);
 | 
			
		||||
		cell->setPort("\\S", sig_new_s);
 | 
			
		||||
		cell->setPort(ID::B, sig_new_b);
 | 
			
		||||
		cell->setPort(ID::S, sig_new_s);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	void fixup_muxes()
 | 
			
		||||
| 
						 | 
				
			
			@ -317,7 +317,7 @@ struct proc_dlatch_db_t
 | 
			
		|||
			pool<Cell*> next_queue;
 | 
			
		||||
 | 
			
		||||
			for (auto cell : queue) {
 | 
			
		||||
				if (cell->type.in("$mux", "$pmux"))
 | 
			
		||||
				if (cell->type.in(ID($mux), ID($pmux)))
 | 
			
		||||
					fixup_mux(cell);
 | 
			
		||||
				for (auto bit : upstream_cell2net[cell])
 | 
			
		||||
					for (auto cell : upstream_net2cell[bit])
 | 
			
		||||
| 
						 | 
				
			
			@ -349,7 +349,7 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc)
 | 
			
		|||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (proc->get_bool_attribute(ID(always_ff)))
 | 
			
		||||
		if (proc->get_bool_attribute(ID::always_ff))
 | 
			
		||||
			log_error("Found non edge/level sensitive event in always_ff process `%s.%s'.\n",
 | 
			
		||||
					db.module->name.c_str(), proc->name.c_str());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -387,7 +387,7 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc)
 | 
			
		|||
	int offset = 0;
 | 
			
		||||
	for (auto chunk : nolatches_bits.first.chunks()) {
 | 
			
		||||
		SigSpec lhs = chunk, rhs = nolatches_bits.second.extract(offset, chunk.width);
 | 
			
		||||
		if (proc->get_bool_attribute(ID(always_latch)))
 | 
			
		||||
		if (proc->get_bool_attribute(ID::always_latch))
 | 
			
		||||
			log_error("No latch inferred for signal `%s.%s' from always_latch process `%s.%s'.\n",
 | 
			
		||||
					db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str());
 | 
			
		||||
		else
 | 
			
		||||
| 
						 | 
				
			
			@ -418,7 +418,7 @@ void proc_dlatch(proc_dlatch_db_t &db, RTLIL::Process *proc)
 | 
			
		|||
			cell->set_src_attribute(src);
 | 
			
		||||
			db.generated_dlatches.insert(cell);
 | 
			
		||||
 | 
			
		||||
			if (proc->get_bool_attribute(ID(always_comb)))
 | 
			
		||||
			if (proc->get_bool_attribute(ID::always_comb))
 | 
			
		||||
				log_error("Latch inferred for signal `%s.%s' from always_comb process `%s.%s'.\n",
 | 
			
		||||
						db.module->name.c_str(), log_signal(lhs), db.module->name.c_str(), proc->name.c_str());
 | 
			
		||||
			else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,7 +54,7 @@ void proc_init(RTLIL::Module *mod, SigMap &sigmap, RTLIL::Process *proc)
 | 
			
		|||
							log_cmd_error("Non-const initialization value: %s = %s\n", log_signal(lhs_c), log_signal(valuesig));
 | 
			
		||||
 | 
			
		||||
						Const value = valuesig.as_const();
 | 
			
		||||
						Const &wireinit = lhs_c.wire->attributes["\\init"];
 | 
			
		||||
						Const &wireinit = lhs_c.wire->attributes[ID::init];
 | 
			
		||||
 | 
			
		||||
						while (GetSize(wireinit.bits) < lhs_c.wire->width)
 | 
			
		||||
							wireinit.bits.push_back(State::Sx);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -147,7 +147,7 @@ struct SnippetSwCache
 | 
			
		|||
void apply_attrs(RTLIL::Cell *cell, const RTLIL::SwitchRule *sw, const RTLIL::CaseRule *cs)
 | 
			
		||||
{
 | 
			
		||||
	cell->attributes = sw->attributes;
 | 
			
		||||
	cell->add_strpool_attribute("\\src", cs->get_strpool_attribute("\\src"));
 | 
			
		||||
	cell->add_strpool_attribute(ID::src, cs->get_strpool_attribute(ID::src));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector<RTLIL::SigSpec> &compare, RTLIL::SwitchRule *sw, RTLIL::CaseRule *cs, bool ifxmode)
 | 
			
		||||
| 
						 | 
				
			
			@ -178,19 +178,19 @@ RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
 | 
			
		|||
		else
 | 
			
		||||
		{
 | 
			
		||||
			// create compare cell
 | 
			
		||||
			RTLIL::Cell *eq_cell = mod->addCell(stringf("%s_CMP%d", sstr.str().c_str(), cmp_wire->width), ifxmode ? "$eqx" : "$eq");
 | 
			
		||||
			RTLIL::Cell *eq_cell = mod->addCell(stringf("%s_CMP%d", sstr.str().c_str(), cmp_wire->width), ifxmode ? ID($eqx) : ID($eq));
 | 
			
		||||
			apply_attrs(eq_cell, sw, cs);
 | 
			
		||||
 | 
			
		||||
			eq_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
 | 
			
		||||
			eq_cell->parameters["\\B_SIGNED"] = RTLIL::Const(0);
 | 
			
		||||
			eq_cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
 | 
			
		||||
			eq_cell->parameters[ID::B_SIGNED] = RTLIL::Const(0);
 | 
			
		||||
 | 
			
		||||
			eq_cell->parameters["\\A_WIDTH"] = RTLIL::Const(sig.size());
 | 
			
		||||
			eq_cell->parameters["\\B_WIDTH"] = RTLIL::Const(comp.size());
 | 
			
		||||
			eq_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
			eq_cell->parameters[ID::A_WIDTH] = RTLIL::Const(sig.size());
 | 
			
		||||
			eq_cell->parameters[ID::B_WIDTH] = RTLIL::Const(comp.size());
 | 
			
		||||
			eq_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
 | 
			
		||||
			eq_cell->setPort("\\A", sig);
 | 
			
		||||
			eq_cell->setPort("\\B", comp);
 | 
			
		||||
			eq_cell->setPort("\\Y", RTLIL::SigSpec(cmp_wire, cmp_wire->width++));
 | 
			
		||||
			eq_cell->setPort(ID::A, sig);
 | 
			
		||||
			eq_cell->setPort(ID::B, comp);
 | 
			
		||||
			eq_cell->setPort(ID::Y, RTLIL::SigSpec(cmp_wire, cmp_wire->width++));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -204,15 +204,15 @@ RTLIL::SigSpec gen_cmp(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
 | 
			
		|||
		ctrl_wire = mod->addWire(sstr.str() + "_CTRL");
 | 
			
		||||
 | 
			
		||||
		// reduce cmp vector to one logic signal
 | 
			
		||||
		RTLIL::Cell *any_cell = mod->addCell(sstr.str() + "_ANY", "$reduce_or");
 | 
			
		||||
		RTLIL::Cell *any_cell = mod->addCell(sstr.str() + "_ANY", ID($reduce_or));
 | 
			
		||||
		apply_attrs(any_cell, sw, cs);
 | 
			
		||||
 | 
			
		||||
		any_cell->parameters["\\A_SIGNED"] = RTLIL::Const(0);
 | 
			
		||||
		any_cell->parameters["\\A_WIDTH"] = RTLIL::Const(cmp_wire->width);
 | 
			
		||||
		any_cell->parameters["\\Y_WIDTH"] = RTLIL::Const(1);
 | 
			
		||||
		any_cell->parameters[ID::A_SIGNED] = RTLIL::Const(0);
 | 
			
		||||
		any_cell->parameters[ID::A_WIDTH] = RTLIL::Const(cmp_wire->width);
 | 
			
		||||
		any_cell->parameters[ID::Y_WIDTH] = RTLIL::Const(1);
 | 
			
		||||
 | 
			
		||||
		any_cell->setPort("\\A", cmp_wire);
 | 
			
		||||
		any_cell->setPort("\\Y", RTLIL::SigSpec(ctrl_wire));
 | 
			
		||||
		any_cell->setPort(ID::A, cmp_wire);
 | 
			
		||||
		any_cell->setPort(ID::Y, RTLIL::SigSpec(ctrl_wire));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return RTLIL::SigSpec(ctrl_wire);
 | 
			
		||||
| 
						 | 
				
			
			@ -239,14 +239,14 @@ RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
 | 
			
		|||
	RTLIL::Wire *result_wire = mod->addWire(sstr.str() + "_Y", when_signal.size());
 | 
			
		||||
 | 
			
		||||
	// create the multiplexer itself
 | 
			
		||||
	RTLIL::Cell *mux_cell = mod->addCell(sstr.str(), "$mux");
 | 
			
		||||
	RTLIL::Cell *mux_cell = mod->addCell(sstr.str(), ID($mux));
 | 
			
		||||
	apply_attrs(mux_cell, sw, cs);
 | 
			
		||||
 | 
			
		||||
	mux_cell->parameters["\\WIDTH"] = RTLIL::Const(when_signal.size());
 | 
			
		||||
	mux_cell->setPort("\\A", else_signal);
 | 
			
		||||
	mux_cell->setPort("\\B", when_signal);
 | 
			
		||||
	mux_cell->setPort("\\S", ctrl_sig);
 | 
			
		||||
	mux_cell->setPort("\\Y", RTLIL::SigSpec(result_wire));
 | 
			
		||||
	mux_cell->parameters[ID::WIDTH] = RTLIL::Const(when_signal.size());
 | 
			
		||||
	mux_cell->setPort(ID::A, else_signal);
 | 
			
		||||
	mux_cell->setPort(ID::B, when_signal);
 | 
			
		||||
	mux_cell->setPort(ID::S, ctrl_sig);
 | 
			
		||||
	mux_cell->setPort(ID::Y, RTLIL::SigSpec(result_wire));
 | 
			
		||||
 | 
			
		||||
	last_mux_cell = mux_cell;
 | 
			
		||||
	return RTLIL::SigSpec(result_wire);
 | 
			
		||||
| 
						 | 
				
			
			@ -255,24 +255,24 @@ RTLIL::SigSpec gen_mux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const s
 | 
			
		|||
void append_pmux(RTLIL::Module *mod, const RTLIL::SigSpec &signal, const std::vector<RTLIL::SigSpec> &compare, RTLIL::SigSpec when_signal, RTLIL::Cell *last_mux_cell, RTLIL::SwitchRule *sw, RTLIL::CaseRule *cs, bool ifxmode)
 | 
			
		||||
{
 | 
			
		||||
	log_assert(last_mux_cell != NULL);
 | 
			
		||||
	log_assert(when_signal.size() == last_mux_cell->getPort("\\A").size());
 | 
			
		||||
	log_assert(when_signal.size() == last_mux_cell->getPort(ID::A).size());
 | 
			
		||||
 | 
			
		||||
	if (when_signal == last_mux_cell->getPort("\\A"))
 | 
			
		||||
	if (when_signal == last_mux_cell->getPort(ID::A))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	RTLIL::SigSpec ctrl_sig = gen_cmp(mod, signal, compare, sw, cs, ifxmode);
 | 
			
		||||
	log_assert(ctrl_sig.size() == 1);
 | 
			
		||||
	last_mux_cell->type = "$pmux";
 | 
			
		||||
	last_mux_cell->type = ID($pmux);
 | 
			
		||||
 | 
			
		||||
	RTLIL::SigSpec new_s = last_mux_cell->getPort("\\S");
 | 
			
		||||
	RTLIL::SigSpec new_s = last_mux_cell->getPort(ID::S);
 | 
			
		||||
	new_s.append(ctrl_sig);
 | 
			
		||||
	last_mux_cell->setPort("\\S", new_s);
 | 
			
		||||
	last_mux_cell->setPort(ID::S, new_s);
 | 
			
		||||
 | 
			
		||||
	RTLIL::SigSpec new_b = last_mux_cell->getPort("\\B");
 | 
			
		||||
	RTLIL::SigSpec new_b = last_mux_cell->getPort(ID::B);
 | 
			
		||||
	new_b.append(when_signal);
 | 
			
		||||
	last_mux_cell->setPort("\\B", new_b);
 | 
			
		||||
	last_mux_cell->setPort(ID::B, new_b);
 | 
			
		||||
 | 
			
		||||
	last_mux_cell->parameters["\\S_WIDTH"] = last_mux_cell->getPort("\\S").size();
 | 
			
		||||
	last_mux_cell->parameters[ID::S_WIDTH] = last_mux_cell->getPort(ID::S).size();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const pool<SigBit> &get_full_case_bits(SnippetSwCache &swcache, RTLIL::SwitchRule *sw)
 | 
			
		||||
| 
						 | 
				
			
			@ -281,7 +281,7 @@ const pool<SigBit> &get_full_case_bits(SnippetSwCache &swcache, RTLIL::SwitchRul
 | 
			
		|||
	{
 | 
			
		||||
		pool<SigBit> bits;
 | 
			
		||||
 | 
			
		||||
		if (sw->get_bool_attribute("\\full_case"))
 | 
			
		||||
		if (sw->get_bool_attribute(ID::full_case))
 | 
			
		||||
		{
 | 
			
		||||
			bool first_case = true;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -337,7 +337,7 @@ RTLIL::SigSpec signal_to_mux_tree(RTLIL::Module *mod, SnippetSwCache &swcache, d
 | 
			
		|||
		std::vector<int> pgroups(sw->cases.size());
 | 
			
		||||
		bool is_simple_parallel_case = true;
 | 
			
		||||
 | 
			
		||||
		if (!sw->get_bool_attribute("\\parallel_case")) {
 | 
			
		||||
		if (!sw->get_bool_attribute(ID::parallel_case)) {
 | 
			
		||||
			if (!swpara.count(sw)) {
 | 
			
		||||
				pool<Const> case_values;
 | 
			
		||||
				for (size_t i = 0; i < sw->cases.size(); i++) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,7 +38,7 @@ struct PruneWorker
 | 
			
		|||
	pool<RTLIL::SigBit> do_switch(RTLIL::SwitchRule *sw, pool<RTLIL::SigBit> assigned, pool<RTLIL::SigBit> &affected)
 | 
			
		||||
	{
 | 
			
		||||
		pool<RTLIL::SigBit> all_assigned;
 | 
			
		||||
		bool full_case = sw->get_bool_attribute("\\full_case");
 | 
			
		||||
		bool full_case = sw->get_bool_attribute(ID::full_case);
 | 
			
		||||
		bool first = true;
 | 
			
		||||
		for (auto it : sw->cases) {
 | 
			
		||||
			if (it->compare.empty())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,8 +62,8 @@ void proc_rmdead(RTLIL::SwitchRule *sw, int &counter, int &full_case_counter)
 | 
			
		|||
			pool.take_all();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (pool.empty() && !sw->get_bool_attribute("\\full_case")) {
 | 
			
		||||
		sw->set_bool_attribute("\\full_case");
 | 
			
		||||
	if (pool.empty() && !sw->get_bool_attribute(ID::full_case)) {
 | 
			
		||||
		sw->set_bool_attribute(ID::full_case);
 | 
			
		||||
		full_case_counter++;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,14 +52,14 @@ struct AssertpmuxWorker
 | 
			
		|||
 | 
			
		||||
		for (auto cell : module->cells())
 | 
			
		||||
		{
 | 
			
		||||
			if (cell->type.in("$mux", "$pmux"))
 | 
			
		||||
			if (cell->type.in(ID($mux), ID($pmux)))
 | 
			
		||||
			{
 | 
			
		||||
				int width = cell->getParam("\\WIDTH").as_int();
 | 
			
		||||
				int numports = cell->type == "$mux" ? 2 : cell->getParam("\\S_WIDTH").as_int() + 1;
 | 
			
		||||
				int width = cell->getParam(ID::WIDTH).as_int();
 | 
			
		||||
				int numports = cell->type == ID($mux) ? 2 : cell->getParam(ID::S_WIDTH).as_int() + 1;
 | 
			
		||||
 | 
			
		||||
				SigSpec sig_a = sigmap(cell->getPort("\\A"));
 | 
			
		||||
				SigSpec sig_b = sigmap(cell->getPort("\\B"));
 | 
			
		||||
				SigSpec sig_s = sigmap(cell->getPort("\\S"));
 | 
			
		||||
				SigSpec sig_a = sigmap(cell->getPort(ID::A));
 | 
			
		||||
				SigSpec sig_b = sigmap(cell->getPort(ID::B));
 | 
			
		||||
				SigSpec sig_s = sigmap(cell->getPort(ID::S));
 | 
			
		||||
 | 
			
		||||
				for (int i = 0; i < numports; i++) {
 | 
			
		||||
					SigSpec bits = i == 0 ? sig_a : sig_b.extract(width*(i-1), width);
 | 
			
		||||
| 
						 | 
				
			
			@ -98,12 +98,12 @@ struct AssertpmuxWorker
 | 
			
		|||
 | 
			
		||||
				if (muxport_actsignal.count(muxport) == 0) {
 | 
			
		||||
					if (portidx == 0)
 | 
			
		||||
						muxport_actsignal[muxport] = module->LogicNot(NEW_ID, cell->getPort("\\S"));
 | 
			
		||||
						muxport_actsignal[muxport] = module->LogicNot(NEW_ID, cell->getPort(ID::S));
 | 
			
		||||
					else
 | 
			
		||||
						muxport_actsignal[muxport] = cell->getPort("\\S")[portidx-1];
 | 
			
		||||
						muxport_actsignal[muxport] = cell->getPort(ID::S)[portidx-1];
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				output.append(module->LogicAnd(NEW_ID, muxport_actsignal.at(muxport), get_bit_activation(cell->getPort("\\Y")[bitidx])));
 | 
			
		||||
				output.append(module->LogicAnd(NEW_ID, muxport_actsignal.at(muxport), get_bit_activation(cell->getPort(ID::Y)[bitidx])));
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			output.sort_and_unify();
 | 
			
		||||
| 
						 | 
				
			
			@ -148,10 +148,10 @@ struct AssertpmuxWorker
 | 
			
		|||
	{
 | 
			
		||||
		log("Adding assert for $pmux cell %s.%s.\n", log_id(module), log_id(pmux));
 | 
			
		||||
 | 
			
		||||
		int swidth = pmux->getParam("\\S_WIDTH").as_int();
 | 
			
		||||
		int swidth = pmux->getParam(ID::S_WIDTH).as_int();
 | 
			
		||||
		int cntbits = ceil_log2(swidth+1);
 | 
			
		||||
 | 
			
		||||
		SigSpec sel = pmux->getPort("\\S");
 | 
			
		||||
		SigSpec sel = pmux->getPort(ID::S);
 | 
			
		||||
		SigSpec cnt(State::S0, cntbits);
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < swidth; i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -164,7 +164,7 @@ struct AssertpmuxWorker
 | 
			
		|||
			assert_en.append(module->LogicNot(NEW_ID, module->Initstate(NEW_ID)));
 | 
			
		||||
 | 
			
		||||
		if (!flag_always)
 | 
			
		||||
			assert_en.append(get_activation(pmux->getPort("\\Y")));
 | 
			
		||||
			assert_en.append(get_activation(pmux->getPort(ID::Y)));
 | 
			
		||||
 | 
			
		||||
		if (GetSize(assert_en) == 0)
 | 
			
		||||
			assert_en = State::S1;
 | 
			
		||||
| 
						 | 
				
			
			@ -174,8 +174,8 @@ struct AssertpmuxWorker
 | 
			
		|||
 | 
			
		||||
		Cell *assert_cell = module->addAssert(NEW_ID, assert_a, assert_en);
 | 
			
		||||
 | 
			
		||||
		if (pmux->attributes.count("\\src") != 0)
 | 
			
		||||
			assert_cell->attributes["\\src"] = pmux->attributes.at("\\src");
 | 
			
		||||
		if (pmux->attributes.count(ID::src) != 0)
 | 
			
		||||
			assert_cell->attributes[ID::src] = pmux->attributes.at(ID::src);
 | 
			
		||||
	}
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -227,7 +227,7 @@ struct AssertpmuxPass : public Pass {
 | 
			
		|||
			vector<Cell*> pmux_cells;
 | 
			
		||||
 | 
			
		||||
			for (auto cell : module->selected_cells())
 | 
			
		||||
				if (cell->type == "$pmux")
 | 
			
		||||
				if (cell->type == ID($pmux))
 | 
			
		||||
					pmux_cells.push_back(cell);
 | 
			
		||||
 | 
			
		||||
			for (auto cell : pmux_cells)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -66,9 +66,9 @@ struct Async2syncPass : public Pass {
 | 
			
		|||
			pool<SigBit> del_initbits;
 | 
			
		||||
 | 
			
		||||
			for (auto wire : module->wires())
 | 
			
		||||
				if (wire->attributes.count("\\init") > 0)
 | 
			
		||||
				if (wire->attributes.count(ID::init) > 0)
 | 
			
		||||
				{
 | 
			
		||||
					Const initval = wire->attributes.at("\\init");
 | 
			
		||||
					Const initval = wire->attributes.at(ID::init);
 | 
			
		||||
					SigSpec initsig = sigmap(wire);
 | 
			
		||||
 | 
			
		||||
					for (int i = 0; i < GetSize(initval) && i < GetSize(initsig); i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -78,16 +78,16 @@ struct Async2syncPass : public Pass {
 | 
			
		|||
 | 
			
		||||
			for (auto cell : vector<Cell*>(module->selected_cells()))
 | 
			
		||||
			{
 | 
			
		||||
				if (cell->type.in("$adff"))
 | 
			
		||||
				if (cell->type.in(ID($adff)))
 | 
			
		||||
				{
 | 
			
		||||
					// bool clk_pol = cell->parameters["\\CLK_POLARITY"].as_bool();
 | 
			
		||||
					bool arst_pol = cell->parameters["\\ARST_POLARITY"].as_bool();
 | 
			
		||||
					Const arst_val = cell->parameters["\\ARST_VALUE"];
 | 
			
		||||
					// bool clk_pol = cell->parameters[ID::CLK_POLARITY].as_bool();
 | 
			
		||||
					bool arst_pol = cell->parameters[ID::ARST_POLARITY].as_bool();
 | 
			
		||||
					Const arst_val = cell->parameters[ID::ARST_VALUE];
 | 
			
		||||
 | 
			
		||||
					// SigSpec sig_clk = cell->getPort("\\CLK");
 | 
			
		||||
					SigSpec sig_arst = cell->getPort("\\ARST");
 | 
			
		||||
					SigSpec sig_d = cell->getPort("\\D");
 | 
			
		||||
					SigSpec sig_q = cell->getPort("\\Q");
 | 
			
		||||
					// SigSpec sig_clk = cell->getPort(ID::CLK);
 | 
			
		||||
					SigSpec sig_arst = cell->getPort(ID::ARST);
 | 
			
		||||
					SigSpec sig_d = cell->getPort(ID::D);
 | 
			
		||||
					SigSpec sig_q = cell->getPort(ID::Q);
 | 
			
		||||
 | 
			
		||||
					log("Replacing %s.%s (%s): ARST=%s, D=%s, Q=%s\n",
 | 
			
		||||
							log_id(module), log_id(cell), log_id(cell->type),
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +102,7 @@ struct Async2syncPass : public Pass {
 | 
			
		|||
 | 
			
		||||
					Wire *new_d = module->addWire(NEW_ID, GetSize(sig_d));
 | 
			
		||||
					Wire *new_q = module->addWire(NEW_ID, GetSize(sig_q));
 | 
			
		||||
					new_q->attributes["\\init"] = init_val;
 | 
			
		||||
					new_q->attributes[ID::init] = init_val;
 | 
			
		||||
 | 
			
		||||
					if (arst_pol) {
 | 
			
		||||
						module->addMux(NEW_ID, sig_d, arst_val, sig_arst, new_d);
 | 
			
		||||
| 
						 | 
				
			
			@ -112,26 +112,26 @@ struct Async2syncPass : public Pass {
 | 
			
		|||
						module->addMux(NEW_ID, arst_val, new_q, sig_arst, sig_q);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					cell->setPort("\\D", new_d);
 | 
			
		||||
					cell->setPort("\\Q", new_q);
 | 
			
		||||
					cell->unsetPort("\\ARST");
 | 
			
		||||
					cell->unsetParam("\\ARST_POLARITY");
 | 
			
		||||
					cell->unsetParam("\\ARST_VALUE");
 | 
			
		||||
					cell->type = "$dff";
 | 
			
		||||
					cell->setPort(ID::D, new_d);
 | 
			
		||||
					cell->setPort(ID::Q, new_q);
 | 
			
		||||
					cell->unsetPort(ID::ARST);
 | 
			
		||||
					cell->unsetParam(ID::ARST_POLARITY);
 | 
			
		||||
					cell->unsetParam(ID::ARST_VALUE);
 | 
			
		||||
					cell->type = ID($dff);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (cell->type.in("$dffsr"))
 | 
			
		||||
				if (cell->type.in(ID($dffsr)))
 | 
			
		||||
				{
 | 
			
		||||
					// bool clk_pol = cell->parameters["\\CLK_POLARITY"].as_bool();
 | 
			
		||||
					bool set_pol = cell->parameters["\\SET_POLARITY"].as_bool();
 | 
			
		||||
					bool clr_pol = cell->parameters["\\CLR_POLARITY"].as_bool();
 | 
			
		||||
					// bool clk_pol = cell->parameters[ID::CLK_POLARITY].as_bool();
 | 
			
		||||
					bool set_pol = cell->parameters[ID::SET_POLARITY].as_bool();
 | 
			
		||||
					bool clr_pol = cell->parameters[ID::CLR_POLARITY].as_bool();
 | 
			
		||||
 | 
			
		||||
					// SigSpec sig_clk = cell->getPort("\\CLK");
 | 
			
		||||
					SigSpec sig_set = cell->getPort("\\SET");
 | 
			
		||||
					SigSpec sig_clr = cell->getPort("\\CLR");
 | 
			
		||||
					SigSpec sig_d = cell->getPort("\\D");
 | 
			
		||||
					SigSpec sig_q = cell->getPort("\\Q");
 | 
			
		||||
					// SigSpec sig_clk = cell->getPort(ID::CLK);
 | 
			
		||||
					SigSpec sig_set = cell->getPort(ID::SET);
 | 
			
		||||
					SigSpec sig_clr = cell->getPort(ID::CLR);
 | 
			
		||||
					SigSpec sig_d = cell->getPort(ID::D);
 | 
			
		||||
					SigSpec sig_q = cell->getPort(ID::Q);
 | 
			
		||||
 | 
			
		||||
					log("Replacing %s.%s (%s): SET=%s, CLR=%s, D=%s, Q=%s\n",
 | 
			
		||||
							log_id(module), log_id(cell), log_id(cell->type),
 | 
			
		||||
| 
						 | 
				
			
			@ -146,7 +146,7 @@ struct Async2syncPass : public Pass {
 | 
			
		|||
 | 
			
		||||
					Wire *new_d = module->addWire(NEW_ID, GetSize(sig_d));
 | 
			
		||||
					Wire *new_q = module->addWire(NEW_ID, GetSize(sig_q));
 | 
			
		||||
					new_q->attributes["\\init"] = init_val;
 | 
			
		||||
					new_q->attributes[ID::init] = init_val;
 | 
			
		||||
 | 
			
		||||
					if (!set_pol)
 | 
			
		||||
						sig_set = module->Not(NEW_ID, sig_set);
 | 
			
		||||
| 
						 | 
				
			
			@ -160,23 +160,23 @@ struct Async2syncPass : public Pass {
 | 
			
		|||
					tmp = module->Or(NEW_ID, new_q, sig_set);
 | 
			
		||||
					module->addAnd(NEW_ID, tmp, sig_clr, sig_q);
 | 
			
		||||
 | 
			
		||||
					cell->setPort("\\D", new_d);
 | 
			
		||||
					cell->setPort("\\Q", new_q);
 | 
			
		||||
					cell->unsetPort("\\SET");
 | 
			
		||||
					cell->unsetPort("\\CLR");
 | 
			
		||||
					cell->unsetParam("\\SET_POLARITY");
 | 
			
		||||
					cell->unsetParam("\\CLR_POLARITY");
 | 
			
		||||
					cell->type = "$dff";
 | 
			
		||||
					cell->setPort(ID::D, new_d);
 | 
			
		||||
					cell->setPort(ID::Q, new_q);
 | 
			
		||||
					cell->unsetPort(ID::SET);
 | 
			
		||||
					cell->unsetPort(ID::CLR);
 | 
			
		||||
					cell->unsetParam(ID::SET_POLARITY);
 | 
			
		||||
					cell->unsetParam(ID::CLR_POLARITY);
 | 
			
		||||
					cell->type = ID($dff);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (cell->type.in("$dlatch"))
 | 
			
		||||
				if (cell->type.in(ID($dlatch)))
 | 
			
		||||
				{
 | 
			
		||||
					bool en_pol = cell->parameters["\\EN_POLARITY"].as_bool();
 | 
			
		||||
					bool en_pol = cell->parameters[ID::EN_POLARITY].as_bool();
 | 
			
		||||
 | 
			
		||||
					SigSpec sig_en = cell->getPort("\\EN");
 | 
			
		||||
					SigSpec sig_d = cell->getPort("\\D");
 | 
			
		||||
					SigSpec sig_q = cell->getPort("\\Q");
 | 
			
		||||
					SigSpec sig_en = cell->getPort(ID::EN);
 | 
			
		||||
					SigSpec sig_d = cell->getPort(ID::D);
 | 
			
		||||
					SigSpec sig_q = cell->getPort(ID::Q);
 | 
			
		||||
 | 
			
		||||
					log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n",
 | 
			
		||||
							log_id(module), log_id(cell), log_id(cell->type),
 | 
			
		||||
| 
						 | 
				
			
			@ -190,7 +190,7 @@ struct Async2syncPass : public Pass {
 | 
			
		|||
					}
 | 
			
		||||
 | 
			
		||||
					Wire *new_q = module->addWire(NEW_ID, GetSize(sig_q));
 | 
			
		||||
					new_q->attributes["\\init"] = init_val;
 | 
			
		||||
					new_q->attributes[ID::init] = init_val;
 | 
			
		||||
 | 
			
		||||
					if (en_pol) {
 | 
			
		||||
						module->addMux(NEW_ID, new_q, sig_d, sig_en, sig_q);
 | 
			
		||||
| 
						 | 
				
			
			@ -198,20 +198,20 @@ struct Async2syncPass : public Pass {
 | 
			
		|||
						module->addMux(NEW_ID, sig_d, new_q, sig_en, sig_q);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					cell->setPort("\\D", sig_q);
 | 
			
		||||
					cell->setPort("\\Q", new_q);
 | 
			
		||||
					cell->unsetPort("\\EN");
 | 
			
		||||
					cell->unsetParam("\\EN_POLARITY");
 | 
			
		||||
					cell->type = "$ff";
 | 
			
		||||
					cell->setPort(ID::D, sig_q);
 | 
			
		||||
					cell->setPort(ID::Q, new_q);
 | 
			
		||||
					cell->unsetPort(ID::EN);
 | 
			
		||||
					cell->unsetParam(ID::EN_POLARITY);
 | 
			
		||||
					cell->type = ID($ff);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			for (auto wire : module->wires())
 | 
			
		||||
				if (wire->attributes.count("\\init") > 0)
 | 
			
		||||
				if (wire->attributes.count(ID::init) > 0)
 | 
			
		||||
				{
 | 
			
		||||
					bool delete_initattr = true;
 | 
			
		||||
					Const initval = wire->attributes.at("\\init");
 | 
			
		||||
					Const initval = wire->attributes.at(ID::init);
 | 
			
		||||
					SigSpec initsig = sigmap(wire);
 | 
			
		||||
 | 
			
		||||
					for (int i = 0; i < GetSize(initval) && i < GetSize(initsig); i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -221,9 +221,9 @@ struct Async2syncPass : public Pass {
 | 
			
		|||
							delete_initattr = false;
 | 
			
		||||
 | 
			
		||||
					if (delete_initattr)
 | 
			
		||||
						wire->attributes.erase("\\init");
 | 
			
		||||
						wire->attributes.erase(ID::init);
 | 
			
		||||
					else
 | 
			
		||||
						wire->attributes.at("\\init") = initval;
 | 
			
		||||
						wire->attributes.at(ID::init) = initval;
 | 
			
		||||
				}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,9 +60,9 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
			pool<SigBit> del_initbits;
 | 
			
		||||
 | 
			
		||||
			for (auto wire : module->wires())
 | 
			
		||||
				if (wire->attributes.count("\\init") > 0)
 | 
			
		||||
				if (wire->attributes.count(ID::init) > 0)
 | 
			
		||||
				{
 | 
			
		||||
					Const initval = wire->attributes.at("\\init");
 | 
			
		||||
					Const initval = wire->attributes.at(ID::init);
 | 
			
		||||
					SigSpec initsig = sigmap(wire);
 | 
			
		||||
 | 
			
		||||
					for (int i = 0; i < GetSize(initval) && i < GetSize(initsig); i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -72,26 +72,26 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
 | 
			
		||||
			for (auto cell : vector<Cell*>(module->selected_cells()))
 | 
			
		||||
			{
 | 
			
		||||
				if (cell->type.in("$mem"))
 | 
			
		||||
				if (cell->type.in(ID($mem)))
 | 
			
		||||
				{
 | 
			
		||||
					int abits = cell->getParam("\\ABITS").as_int();
 | 
			
		||||
					int width = cell->getParam("\\WIDTH").as_int();
 | 
			
		||||
					int rd_ports = cell->getParam("\\RD_PORTS").as_int();
 | 
			
		||||
					int wr_ports = cell->getParam("\\WR_PORTS").as_int();
 | 
			
		||||
					int abits = cell->getParam(ID::ABITS).as_int();
 | 
			
		||||
					int width = cell->getParam(ID::WIDTH).as_int();
 | 
			
		||||
					int rd_ports = cell->getParam(ID::RD_PORTS).as_int();
 | 
			
		||||
					int wr_ports = cell->getParam(ID::WR_PORTS).as_int();
 | 
			
		||||
 | 
			
		||||
					for (int i = 0; i < rd_ports; i++) {
 | 
			
		||||
						if (cell->getParam("\\RD_CLK_ENABLE").extract(i).as_bool())
 | 
			
		||||
						if (cell->getParam(ID::RD_CLK_ENABLE).extract(i).as_bool())
 | 
			
		||||
							log_error("Read port %d of memory %s.%s is clocked. This is not supported by \"clk2fflogic\"! "
 | 
			
		||||
									"Call \"memory\" with -nordff to avoid this error.\n", i, log_id(cell), log_id(module));
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					Const wr_clk_en_param = cell->getParam("\\WR_CLK_ENABLE");
 | 
			
		||||
					Const wr_clk_pol_param = cell->getParam("\\WR_CLK_POLARITY");
 | 
			
		||||
					Const wr_clk_en_param = cell->getParam(ID::WR_CLK_ENABLE);
 | 
			
		||||
					Const wr_clk_pol_param = cell->getParam(ID::WR_CLK_POLARITY);
 | 
			
		||||
 | 
			
		||||
					SigSpec wr_clk_port = cell->getPort("\\WR_CLK");
 | 
			
		||||
					SigSpec wr_en_port = cell->getPort("\\WR_EN");
 | 
			
		||||
					SigSpec wr_addr_port = cell->getPort("\\WR_ADDR");
 | 
			
		||||
					SigSpec wr_data_port = cell->getPort("\\WR_DATA");
 | 
			
		||||
					SigSpec wr_clk_port = cell->getPort(ID::WR_CLK);
 | 
			
		||||
					SigSpec wr_en_port = cell->getPort(ID::WR_EN);
 | 
			
		||||
					SigSpec wr_addr_port = cell->getPort(ID::WR_ADDR);
 | 
			
		||||
					SigSpec wr_data_port = cell->getPort(ID::WR_DATA);
 | 
			
		||||
 | 
			
		||||
					for (int wport = 0; wport < wr_ports; wport++)
 | 
			
		||||
					{
 | 
			
		||||
| 
						 | 
				
			
			@ -111,7 +111,7 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
								log_signal(addr), log_signal(data));
 | 
			
		||||
 | 
			
		||||
						Wire *past_clk = module->addWire(NEW_ID);
 | 
			
		||||
						past_clk->attributes["\\init"] = clkpol ? State::S1 : State::S0;
 | 
			
		||||
						past_clk->attributes[ID::init] = clkpol ? State::S1 : State::S0;
 | 
			
		||||
						module->addFf(NEW_ID, clk, past_clk);
 | 
			
		||||
 | 
			
		||||
						SigSpec clock_edge_pattern;
 | 
			
		||||
| 
						 | 
				
			
			@ -144,22 +144,22 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
						wr_clk_pol_param[wport] = State::S0;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					cell->setParam("\\WR_CLK_ENABLE", wr_clk_en_param);
 | 
			
		||||
					cell->setParam("\\WR_CLK_POLARITY", wr_clk_pol_param);
 | 
			
		||||
					cell->setParam(ID::WR_CLK_ENABLE, wr_clk_en_param);
 | 
			
		||||
					cell->setParam(ID::WR_CLK_POLARITY, wr_clk_pol_param);
 | 
			
		||||
 | 
			
		||||
					cell->setPort("\\WR_CLK", wr_clk_port);
 | 
			
		||||
					cell->setPort("\\WR_EN", wr_en_port);
 | 
			
		||||
					cell->setPort("\\WR_ADDR", wr_addr_port);
 | 
			
		||||
					cell->setPort("\\WR_DATA", wr_data_port);
 | 
			
		||||
					cell->setPort(ID::WR_CLK, wr_clk_port);
 | 
			
		||||
					cell->setPort(ID::WR_EN, wr_en_port);
 | 
			
		||||
					cell->setPort(ID::WR_ADDR, wr_addr_port);
 | 
			
		||||
					cell->setPort(ID::WR_DATA, wr_data_port);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (cell->type.in("$dlatch", "$dlatchsr"))
 | 
			
		||||
				if (cell->type.in(ID($dlatch), ID($dlatchsr)))
 | 
			
		||||
				{
 | 
			
		||||
					bool enpol = cell->parameters["\\EN_POLARITY"].as_bool();
 | 
			
		||||
					bool enpol = cell->parameters[ID::EN_POLARITY].as_bool();
 | 
			
		||||
 | 
			
		||||
					SigSpec sig_en = cell->getPort("\\EN");
 | 
			
		||||
					SigSpec sig_d = cell->getPort("\\D");
 | 
			
		||||
					SigSpec sig_q = cell->getPort("\\Q");
 | 
			
		||||
					SigSpec sig_en = cell->getPort(ID::EN);
 | 
			
		||||
					SigSpec sig_d = cell->getPort(ID::D);
 | 
			
		||||
					SigSpec sig_q = cell->getPort(ID::Q);
 | 
			
		||||
 | 
			
		||||
					log("Replacing %s.%s (%s): EN=%s, D=%s, Q=%s\n",
 | 
			
		||||
							log_id(module), log_id(cell), log_id(cell->type),
 | 
			
		||||
| 
						 | 
				
			
			@ -168,7 +168,7 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
					Wire *past_q = module->addWire(NEW_ID, GetSize(sig_q));
 | 
			
		||||
					module->addFf(NEW_ID, sig_q, past_q);
 | 
			
		||||
 | 
			
		||||
					if (cell->type == "$dlatch")
 | 
			
		||||
					if (cell->type == ID($dlatch))
 | 
			
		||||
					{
 | 
			
		||||
						if (enpol)
 | 
			
		||||
							module->addMux(NEW_ID, past_q, sig_d, sig_en, sig_q);
 | 
			
		||||
| 
						 | 
				
			
			@ -183,13 +183,13 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
						else
 | 
			
		||||
							t = module->Mux(NEW_ID, sig_d, past_q, sig_en);
 | 
			
		||||
 | 
			
		||||
						SigSpec s = cell->getPort("\\SET");
 | 
			
		||||
						if (!cell->parameters["\\SET_POLARITY"].as_bool())
 | 
			
		||||
						SigSpec s = cell->getPort(ID::SET);
 | 
			
		||||
						if (!cell->parameters[ID::SET_POLARITY].as_bool())
 | 
			
		||||
							s = module->Not(NEW_ID, s);
 | 
			
		||||
						t = module->Or(NEW_ID, t, s);
 | 
			
		||||
 | 
			
		||||
						SigSpec c = cell->getPort("\\CLR");
 | 
			
		||||
						if (cell->parameters["\\CLR_POLARITY"].as_bool())
 | 
			
		||||
						SigSpec c = cell->getPort(ID::CLR);
 | 
			
		||||
						if (cell->parameters[ID::CLR_POLARITY].as_bool())
 | 
			
		||||
							c = module->Not(NEW_ID, c);
 | 
			
		||||
						module->addAnd(NEW_ID, t, c, sig_q);
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			@ -208,13 +208,13 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
					}
 | 
			
		||||
 | 
			
		||||
					if (assign_initval)
 | 
			
		||||
						past_q->attributes["\\init"] = initval;
 | 
			
		||||
						past_q->attributes[ID::init] = initval;
 | 
			
		||||
 | 
			
		||||
					module->remove(cell);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				bool word_dff = cell->type.in("$dff", "$adff", "$dffsr");
 | 
			
		||||
				bool word_dff = cell->type.in(ID($dff), ID($adff), ID($dffsr));
 | 
			
		||||
				if (word_dff || cell->type.in(ID($_DFF_N_), ID($_DFF_P_),
 | 
			
		||||
						ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_),
 | 
			
		||||
						ID($_DFF_PP0_), ID($_DFF_PP1_), ID($_DFF_PN0_), ID($_DFF_PN1_),
 | 
			
		||||
| 
						 | 
				
			
			@ -224,8 +224,8 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
					bool clkpol;
 | 
			
		||||
					SigSpec clk;
 | 
			
		||||
					if (word_dff) {
 | 
			
		||||
						clkpol = cell->parameters["\\CLK_POLARITY"].as_bool();
 | 
			
		||||
						clk = cell->getPort("\\CLK");
 | 
			
		||||
						clkpol = cell->parameters[ID::CLK_POLARITY].as_bool();
 | 
			
		||||
						clk = cell->getPort(ID::CLK);
 | 
			
		||||
					}
 | 
			
		||||
					else {
 | 
			
		||||
						if (cell->type.in(ID($_DFF_P_), ID($_DFF_N_),
 | 
			
		||||
| 
						 | 
				
			
			@ -236,19 +236,19 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
									ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_)))
 | 
			
		||||
							clkpol = cell->type[8] == 'P';
 | 
			
		||||
						else log_abort();
 | 
			
		||||
						clk = cell->getPort("\\C");
 | 
			
		||||
						clk = cell->getPort(ID::C);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					Wire *past_clk = module->addWire(NEW_ID);
 | 
			
		||||
					past_clk->attributes["\\init"] = clkpol ? State::S1 : State::S0;
 | 
			
		||||
					past_clk->attributes[ID::init] = clkpol ? State::S1 : State::S0;
 | 
			
		||||
 | 
			
		||||
					if (word_dff)
 | 
			
		||||
						module->addFf(NEW_ID, clk, past_clk);
 | 
			
		||||
					else
 | 
			
		||||
						module->addFfGate(NEW_ID, clk, past_clk);
 | 
			
		||||
 | 
			
		||||
					SigSpec sig_d = cell->getPort("\\D");
 | 
			
		||||
					SigSpec sig_q = cell->getPort("\\Q");
 | 
			
		||||
					SigSpec sig_d = cell->getPort(ID::D);
 | 
			
		||||
					SigSpec sig_q = cell->getPort(ID::Q);
 | 
			
		||||
 | 
			
		||||
					log("Replacing %s.%s (%s): CLK=%s, D=%s, Q=%s\n",
 | 
			
		||||
							log_id(module), log_id(cell), log_id(cell->type),
 | 
			
		||||
| 
						 | 
				
			
			@ -277,20 +277,20 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
						module->addFfGate(NEW_ID, sig_q, past_q);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					if (cell->type == "$adff")
 | 
			
		||||
					if (cell->type == ID($adff))
 | 
			
		||||
					{
 | 
			
		||||
						SigSpec arst = cell->getPort("\\ARST");
 | 
			
		||||
						SigSpec arst = cell->getPort(ID::ARST);
 | 
			
		||||
						SigSpec qval = module->Mux(NEW_ID, past_q, past_d, clock_edge);
 | 
			
		||||
						Const rstval = cell->parameters["\\ARST_VALUE"];
 | 
			
		||||
						Const rstval = cell->parameters[ID::ARST_VALUE];
 | 
			
		||||
 | 
			
		||||
						Wire *past_arst = module->addWire(NEW_ID);
 | 
			
		||||
						module->addFf(NEW_ID, arst, past_arst);
 | 
			
		||||
						if (cell->parameters["\\ARST_POLARITY"].as_bool())
 | 
			
		||||
						if (cell->parameters[ID::ARST_POLARITY].as_bool())
 | 
			
		||||
							arst = module->LogicOr(NEW_ID, arst, past_arst);
 | 
			
		||||
						else
 | 
			
		||||
							arst = module->LogicAnd(NEW_ID, arst, past_arst);
 | 
			
		||||
 | 
			
		||||
						if (cell->parameters["\\ARST_POLARITY"].as_bool())
 | 
			
		||||
						if (cell->parameters[ID::ARST_POLARITY].as_bool())
 | 
			
		||||
							module->addMux(NEW_ID, qval, rstval, arst, sig_q);
 | 
			
		||||
						else
 | 
			
		||||
							module->addMux(NEW_ID, rstval, qval, arst, sig_q);
 | 
			
		||||
| 
						 | 
				
			
			@ -299,7 +299,7 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
					if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_),
 | 
			
		||||
						ID($_DFF_PP0_), ID($_DFF_PP1_), ID($_DFF_PN0_), ID($_DFF_PN1_)))
 | 
			
		||||
					{
 | 
			
		||||
						SigSpec arst = cell->getPort("\\R");
 | 
			
		||||
						SigSpec arst = cell->getPort(ID::R);
 | 
			
		||||
						SigSpec qval = module->MuxGate(NEW_ID, past_q, past_d, clock_edge);
 | 
			
		||||
						SigBit rstval = (cell->type[8] == '1');
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -316,16 +316,16 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
							module->addMuxGate(NEW_ID, rstval, qval, arst, sig_q);
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					if (cell->type == "$dffsr")
 | 
			
		||||
					if (cell->type == ID($dffsr))
 | 
			
		||||
					{
 | 
			
		||||
						SigSpec qval = module->Mux(NEW_ID, past_q, past_d, clock_edge);
 | 
			
		||||
						SigSpec setval = cell->getPort("\\SET");
 | 
			
		||||
						SigSpec clrval = cell->getPort("\\CLR");
 | 
			
		||||
						SigSpec setval = cell->getPort(ID::SET);
 | 
			
		||||
						SigSpec clrval = cell->getPort(ID::CLR);
 | 
			
		||||
 | 
			
		||||
						if (!cell->parameters["\\SET_POLARITY"].as_bool())
 | 
			
		||||
						if (!cell->parameters[ID::SET_POLARITY].as_bool())
 | 
			
		||||
							setval = module->Not(NEW_ID, setval);
 | 
			
		||||
 | 
			
		||||
						if (cell->parameters["\\CLR_POLARITY"].as_bool())
 | 
			
		||||
						if (cell->parameters[ID::CLR_POLARITY].as_bool())
 | 
			
		||||
							clrval = module->Not(NEW_ID, clrval);
 | 
			
		||||
 | 
			
		||||
						qval = module->Or(NEW_ID, qval, setval);
 | 
			
		||||
| 
						 | 
				
			
			@ -336,8 +336,8 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
						ID($_DFFSR_PNN_), ID($_DFFSR_PNP_), ID($_DFFSR_PPN_), ID($_DFFSR_PPP_)))
 | 
			
		||||
					{
 | 
			
		||||
						SigSpec qval = module->MuxGate(NEW_ID, past_q, past_d, clock_edge);
 | 
			
		||||
						SigSpec setval = cell->getPort("\\S");
 | 
			
		||||
						SigSpec clrval = cell->getPort("\\R");
 | 
			
		||||
						SigSpec setval = cell->getPort(ID::S);
 | 
			
		||||
						SigSpec clrval = cell->getPort(ID::R);
 | 
			
		||||
 | 
			
		||||
						if (cell->type[9] != 'P')
 | 
			
		||||
							setval = module->Not(NEW_ID, setval);
 | 
			
		||||
| 
						 | 
				
			
			@ -348,7 +348,7 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
						qval = module->OrGate(NEW_ID, qval, setval);
 | 
			
		||||
						module->addAndGate(NEW_ID, qval, clrval, sig_q);
 | 
			
		||||
					}
 | 
			
		||||
					else if (cell->type == "$dff")
 | 
			
		||||
					else if (cell->type == ID($dff))
 | 
			
		||||
					{
 | 
			
		||||
						module->addMux(NEW_ID, past_q, past_d, clock_edge, sig_q);
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			@ -371,8 +371,8 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
					}
 | 
			
		||||
 | 
			
		||||
					if (assign_initval) {
 | 
			
		||||
						past_d->attributes["\\init"] = initval;
 | 
			
		||||
						past_q->attributes["\\init"] = initval;
 | 
			
		||||
						past_d->attributes[ID::init] = initval;
 | 
			
		||||
						past_q->attributes[ID::init] = initval;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					module->remove(cell);
 | 
			
		||||
| 
						 | 
				
			
			@ -381,10 +381,10 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
			}
 | 
			
		||||
 | 
			
		||||
			for (auto wire : module->wires())
 | 
			
		||||
				if (wire->attributes.count("\\init") > 0)
 | 
			
		||||
				if (wire->attributes.count(ID::init) > 0)
 | 
			
		||||
				{
 | 
			
		||||
					bool delete_initattr = true;
 | 
			
		||||
					Const initval = wire->attributes.at("\\init");
 | 
			
		||||
					Const initval = wire->attributes.at(ID::init);
 | 
			
		||||
					SigSpec initsig = sigmap(wire);
 | 
			
		||||
 | 
			
		||||
					for (int i = 0; i < GetSize(initval) && i < GetSize(initsig); i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -394,9 +394,9 @@ struct Clk2fflogicPass : public Pass {
 | 
			
		|||
							delete_initattr = false;
 | 
			
		||||
 | 
			
		||||
					if (delete_initattr)
 | 
			
		||||
						wire->attributes.erase("\\init");
 | 
			
		||||
						wire->attributes.erase(ID::init);
 | 
			
		||||
					else
 | 
			
		||||
						wire->attributes.at("\\init") = initval;
 | 
			
		||||
						wire->attributes.at(ID::init) = initval;
 | 
			
		||||
				}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -75,7 +75,7 @@ struct CutpointPass : public Pass {
 | 
			
		|||
			pool<SigBit> cutpoint_bits;
 | 
			
		||||
 | 
			
		||||
			for (auto cell : module->selected_cells()) {
 | 
			
		||||
				if (cell->type == "$anyseq")
 | 
			
		||||
				if (cell->type == ID($anyseq))
 | 
			
		||||
					continue;
 | 
			
		||||
				log("Removing cell %s.%s, making all cell outputs cutpoints.\n", log_id(module), log_id(cell));
 | 
			
		||||
				for (auto &conn : cell->connections()) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -153,11 +153,11 @@ struct VlogHammerReporter
 | 
			
		|||
 | 
			
		||||
		ez->assume(satgen.signals_eq(recorded_set_vars, recorded_set_vals));
 | 
			
		||||
 | 
			
		||||
		std::vector<int> y_vec = satgen.importDefSigSpec(module->wire("\\y"));
 | 
			
		||||
		std::vector<int> y_vec = satgen.importDefSigSpec(module->wire(ID(y)));
 | 
			
		||||
		std::vector<bool> y_values;
 | 
			
		||||
 | 
			
		||||
		if (model_undef) {
 | 
			
		||||
			std::vector<int> y_undef_vec = satgen.importUndefSigSpec(module->wire("\\y"));
 | 
			
		||||
			std::vector<int> y_undef_vec = satgen.importUndefSigSpec(module->wire(ID(y)));
 | 
			
		||||
			y_vec.insert(y_vec.end(), y_undef_vec.begin(), y_undef_vec.end());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -268,10 +268,10 @@ struct VlogHammerReporter
 | 
			
		|||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (module->wire("\\y") == nullptr)
 | 
			
		||||
				if (module->wire(ID(y)) == nullptr)
 | 
			
		||||
					log_error("No output wire (y) found in module %s!\n", log_id(module->name));
 | 
			
		||||
 | 
			
		||||
				RTLIL::SigSpec sig(module->wire("\\y"));
 | 
			
		||||
				RTLIL::SigSpec sig(module->wire(ID(y)));
 | 
			
		||||
				RTLIL::SigSpec undef;
 | 
			
		||||
 | 
			
		||||
				while (!ce.eval(sig, undef)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,8 +86,8 @@ void find_dff_wires(std::set<RTLIL::IdString> &dff_wires, RTLIL::Module *module)
 | 
			
		|||
	SigPool dffsignals;
 | 
			
		||||
 | 
			
		||||
	for (auto cell : module->cells()) {
 | 
			
		||||
		if (ct.cell_known(cell->type) && cell->hasPort("\\Q"))
 | 
			
		||||
			dffsignals.add(sigmap(cell->getPort("\\Q")));
 | 
			
		||||
		if (ct.cell_known(cell->type) && cell->hasPort(ID::Q))
 | 
			
		||||
			dffsignals.add(sigmap(cell->getPort(ID::Q)));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (auto w : module->wires()) {
 | 
			
		||||
| 
						 | 
				
			
			@ -112,11 +112,11 @@ void create_dff_dq_map(std::map<RTLIL::IdString, dff_map_info_t> &map, RTLIL::Mo
 | 
			
		|||
		info.arst_value = RTLIL::State::Sm;
 | 
			
		||||
		info.cell = cell;
 | 
			
		||||
 | 
			
		||||
		if (info.cell->type == "$dff") {
 | 
			
		||||
			info.bit_clk = sigmap(info.cell->getPort("\\CLK")).as_bit();
 | 
			
		||||
			info.clk_polarity = info.cell->parameters.at("\\CLK_POLARITY").as_bool();
 | 
			
		||||
			std::vector<RTLIL::SigBit> sig_d = sigmap(info.cell->getPort("\\D")).to_sigbit_vector();
 | 
			
		||||
			std::vector<RTLIL::SigBit> sig_q = sigmap(info.cell->getPort("\\Q")).to_sigbit_vector();
 | 
			
		||||
		if (info.cell->type == ID($dff)) {
 | 
			
		||||
			info.bit_clk = sigmap(info.cell->getPort(ID::CLK)).as_bit();
 | 
			
		||||
			info.clk_polarity = info.cell->parameters.at(ID::CLK_POLARITY).as_bool();
 | 
			
		||||
			std::vector<RTLIL::SigBit> sig_d = sigmap(info.cell->getPort(ID::D)).to_sigbit_vector();
 | 
			
		||||
			std::vector<RTLIL::SigBit> sig_q = sigmap(info.cell->getPort(ID::Q)).to_sigbit_vector();
 | 
			
		||||
			for (size_t i = 0; i < sig_d.size(); i++) {
 | 
			
		||||
				info.bit_d = sig_d.at(i);
 | 
			
		||||
				bit_info[sig_q.at(i)] = info;
 | 
			
		||||
| 
						 | 
				
			
			@ -124,14 +124,14 @@ void create_dff_dq_map(std::map<RTLIL::IdString, dff_map_info_t> &map, RTLIL::Mo
 | 
			
		|||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (info.cell->type == "$adff") {
 | 
			
		||||
			info.bit_clk = sigmap(info.cell->getPort("\\CLK")).as_bit();
 | 
			
		||||
			info.bit_arst = sigmap(info.cell->getPort("\\ARST")).as_bit();
 | 
			
		||||
			info.clk_polarity = info.cell->parameters.at("\\CLK_POLARITY").as_bool();
 | 
			
		||||
			info.arst_polarity = info.cell->parameters.at("\\ARST_POLARITY").as_bool();
 | 
			
		||||
			std::vector<RTLIL::SigBit> sig_d = sigmap(info.cell->getPort("\\D")).to_sigbit_vector();
 | 
			
		||||
			std::vector<RTLIL::SigBit> sig_q = sigmap(info.cell->getPort("\\Q")).to_sigbit_vector();
 | 
			
		||||
			std::vector<RTLIL::State> arst_value = info.cell->parameters.at("\\ARST_VALUE").bits;
 | 
			
		||||
		if (info.cell->type == ID($adff)) {
 | 
			
		||||
			info.bit_clk = sigmap(info.cell->getPort(ID::CLK)).as_bit();
 | 
			
		||||
			info.bit_arst = sigmap(info.cell->getPort(ID::ARST)).as_bit();
 | 
			
		||||
			info.clk_polarity = info.cell->parameters.at(ID::CLK_POLARITY).as_bool();
 | 
			
		||||
			info.arst_polarity = info.cell->parameters.at(ID::ARST_POLARITY).as_bool();
 | 
			
		||||
			std::vector<RTLIL::SigBit> sig_d = sigmap(info.cell->getPort(ID::D)).to_sigbit_vector();
 | 
			
		||||
			std::vector<RTLIL::SigBit> sig_q = sigmap(info.cell->getPort(ID::Q)).to_sigbit_vector();
 | 
			
		||||
			std::vector<RTLIL::State> arst_value = info.cell->parameters.at(ID::ARST_VALUE).bits;
 | 
			
		||||
			for (size_t i = 0; i < sig_d.size(); i++) {
 | 
			
		||||
				info.bit_d = sig_d.at(i);
 | 
			
		||||
				info.arst_value = arst_value.at(i);
 | 
			
		||||
| 
						 | 
				
			
			@ -140,22 +140,22 @@ void create_dff_dq_map(std::map<RTLIL::IdString, dff_map_info_t> &map, RTLIL::Mo
 | 
			
		|||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (info.cell->type.in("$_DFF_N_", "$_DFF_P_")) {
 | 
			
		||||
			info.bit_clk = sigmap(info.cell->getPort("\\C")).as_bit();
 | 
			
		||||
			info.clk_polarity = info.cell->type == "$_DFF_P_";
 | 
			
		||||
			info.bit_d = sigmap(info.cell->getPort("\\D")).as_bit();
 | 
			
		||||
			bit_info[sigmap(info.cell->getPort("\\Q")).as_bit()] = info;
 | 
			
		||||
		if (info.cell->type.in(ID($_DFF_N_), ID($_DFF_P_))) {
 | 
			
		||||
			info.bit_clk = sigmap(info.cell->getPort(ID::C)).as_bit();
 | 
			
		||||
			info.clk_polarity = info.cell->type == ID($_DFF_P_);
 | 
			
		||||
			info.bit_d = sigmap(info.cell->getPort(ID::D)).as_bit();
 | 
			
		||||
			bit_info[sigmap(info.cell->getPort(ID::Q)).as_bit()] = info;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (info.cell->type.size() == 10 && info.cell->type.begins_with("$_DFF_")) {
 | 
			
		||||
			info.bit_clk = sigmap(info.cell->getPort("\\C")).as_bit();
 | 
			
		||||
			info.bit_arst = sigmap(info.cell->getPort("\\R")).as_bit();
 | 
			
		||||
			info.bit_clk = sigmap(info.cell->getPort(ID::C)).as_bit();
 | 
			
		||||
			info.bit_arst = sigmap(info.cell->getPort(ID::R)).as_bit();
 | 
			
		||||
			info.clk_polarity = info.cell->type[6] == 'P';
 | 
			
		||||
			info.arst_polarity = info.cell->type[7] == 'P';
 | 
			
		||||
			info.arst_value = info.cell->type[0] == '1' ? RTLIL::State::S1 : RTLIL::State::S0;
 | 
			
		||||
			info.bit_d = sigmap(info.cell->getPort("\\D")).as_bit();
 | 
			
		||||
			bit_info[sigmap(info.cell->getPort("\\Q")).as_bit()] = info;
 | 
			
		||||
			info.bit_d = sigmap(info.cell->getPort(ID::D)).as_bit();
 | 
			
		||||
			bit_info[sigmap(info.cell->getPort(ID::Q)).as_bit()] = info;
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -526,11 +526,11 @@ struct ExposePass : public Pass {
 | 
			
		|||
 | 
			
		||||
				for (auto &cell_name : info.cells) {
 | 
			
		||||
					RTLIL::Cell *cell = module->cell(cell_name);
 | 
			
		||||
					std::vector<RTLIL::SigBit> cell_q_bits = sigmap(cell->getPort("\\Q")).to_sigbit_vector();
 | 
			
		||||
					std::vector<RTLIL::SigBit> cell_q_bits = sigmap(cell->getPort(ID::Q)).to_sigbit_vector();
 | 
			
		||||
					for (auto &bit : cell_q_bits)
 | 
			
		||||
						if (wire_bits_set.count(bit))
 | 
			
		||||
							bit = RTLIL::SigBit(wire_dummy_q, wire_dummy_q->width++);
 | 
			
		||||
					cell->setPort("\\Q", cell_q_bits);
 | 
			
		||||
					cell->setPort(ID::Q, cell_q_bits);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				RTLIL::Wire *wire_q = add_new_wire(module, wire->name.str() + sep + "q", wire->width);
 | 
			
		||||
| 
						 | 
				
			
			@ -558,12 +558,12 @@ struct ExposePass : public Pass {
 | 
			
		|||
				if (info.clk_polarity) {
 | 
			
		||||
					module->connect(RTLIL::SigSig(wire_c, info.sig_clk));
 | 
			
		||||
				} else {
 | 
			
		||||
					RTLIL::Cell *c = module->addCell(NEW_ID, "$not");
 | 
			
		||||
					c->parameters["\\A_SIGNED"] = 0;
 | 
			
		||||
					c->parameters["\\A_WIDTH"] = 1;
 | 
			
		||||
					c->parameters["\\Y_WIDTH"] = 1;
 | 
			
		||||
					c->setPort("\\A", info.sig_clk);
 | 
			
		||||
					c->setPort("\\Y", wire_c);
 | 
			
		||||
					RTLIL::Cell *c = module->addCell(NEW_ID, ID($not));
 | 
			
		||||
					c->parameters[ID::A_SIGNED] = 0;
 | 
			
		||||
					c->parameters[ID::A_WIDTH] = 1;
 | 
			
		||||
					c->parameters[ID::Y_WIDTH] = 1;
 | 
			
		||||
					c->setPort(ID::A, info.sig_clk);
 | 
			
		||||
					c->setPort(ID::Y, wire_c);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				if (info.sig_arst != RTLIL::State::Sm)
 | 
			
		||||
| 
						 | 
				
			
			@ -574,12 +574,12 @@ struct ExposePass : public Pass {
 | 
			
		|||
					if (info.arst_polarity) {
 | 
			
		||||
						module->connect(RTLIL::SigSig(wire_r, info.sig_arst));
 | 
			
		||||
					} else {
 | 
			
		||||
						RTLIL::Cell *c = module->addCell(NEW_ID, "$not");
 | 
			
		||||
						c->parameters["\\A_SIGNED"] = 0;
 | 
			
		||||
						c->parameters["\\A_WIDTH"] = 1;
 | 
			
		||||
						c->parameters["\\Y_WIDTH"] = 1;
 | 
			
		||||
						c->setPort("\\A", info.sig_arst);
 | 
			
		||||
						c->setPort("\\Y", wire_r);
 | 
			
		||||
						RTLIL::Cell *c = module->addCell(NEW_ID, ID($not));
 | 
			
		||||
						c->parameters[ID::A_SIGNED] = 0;
 | 
			
		||||
						c->parameters[ID::A_WIDTH] = 1;
 | 
			
		||||
						c->parameters[ID::Y_WIDTH] = 1;
 | 
			
		||||
						c->setPort(ID::A, info.sig_arst);
 | 
			
		||||
						c->setPort(ID::Y, wire_r);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					RTLIL::Wire *wire_v = add_new_wire(module, wire->name.str() + sep + "v", wire->width);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -43,7 +43,7 @@ struct FmcombineWorker
 | 
			
		|||
 | 
			
		||||
	FmcombineWorker(Design *design, IdString orig_type, const opts_t &opts) :
 | 
			
		||||
			opts(opts), design(design), original(design->module(orig_type)),
 | 
			
		||||
			orig_type(orig_type), combined_type("$fmcombine" + orig_type.str())
 | 
			
		||||
			orig_type(orig_type), combined_type(stringf("$fmcombine%s", orig_type.c_str()))
 | 
			
		||||
	{
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +106,7 @@ struct FmcombineWorker
 | 
			
		|||
 | 
			
		||||
		for (auto cell : original->cells()) {
 | 
			
		||||
			if (design->module(cell->type) == nullptr) {
 | 
			
		||||
				if (opts.anyeq && cell->type.in("$anyseq", "$anyconst")) {
 | 
			
		||||
				if (opts.anyeq && cell->type.in(ID($anyseq), ID($anyconst))) {
 | 
			
		||||
					Cell *gold = import_prim_cell(cell, "_gold");
 | 
			
		||||
					for (auto &conn : cell->connections())
 | 
			
		||||
						module->connect(import_sig(conn.second, "_gate"), gold->getPort(conn.first));
 | 
			
		||||
| 
						 | 
				
			
			@ -114,10 +114,10 @@ struct FmcombineWorker
 | 
			
		|||
					Cell *gold = import_prim_cell(cell, "_gold");
 | 
			
		||||
					Cell *gate = import_prim_cell(cell, "_gate");
 | 
			
		||||
					if (opts.initeq) {
 | 
			
		||||
						if (cell->type.in("$ff", "$dff", "$dffe",
 | 
			
		||||
								"$dffsr", "$adff", "$dlatch", "$dlatchsr")) {
 | 
			
		||||
							SigSpec gold_q = gold->getPort("\\Q");
 | 
			
		||||
							SigSpec gate_q = gate->getPort("\\Q");
 | 
			
		||||
						if (cell->type.in(ID($ff), ID($dff), ID($dffe),
 | 
			
		||||
								ID($dffsr), ID($adff), ID($dlatch), ID($dlatchsr))) {
 | 
			
		||||
							SigSpec gold_q = gold->getPort(ID::Q);
 | 
			
		||||
							SigSpec gate_q = gate->getPort(ID::Q);
 | 
			
		||||
							SigSpec en = module->Initstate(NEW_ID);
 | 
			
		||||
							SigSpec eq = module->Eq(NEW_ID, gold_q, gate_q);
 | 
			
		||||
							module->addAssume(NEW_ID, eq, en);
 | 
			
		||||
| 
						 | 
				
			
			@ -359,7 +359,7 @@ struct FmcombinePass : public Pass {
 | 
			
		|||
 | 
			
		||||
		Cell *cell = module->addCell(combined_cell_name, worker.combined_type);
 | 
			
		||||
		cell->attributes = gold_cell->attributes;
 | 
			
		||||
		cell->add_strpool_attribute("\\src", gate_cell->get_strpool_attribute("\\src"));
 | 
			
		||||
		cell->add_strpool_attribute(ID::src, gate_cell->get_strpool_attribute(ID::src));
 | 
			
		||||
 | 
			
		||||
		log("Combining cells %s and %s in module %s into new cell %s.\n", log_id(gold_cell), log_id(gate_cell), log_id(module), log_id(cell));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -147,7 +147,7 @@ struct FminitPass : public Pass {
 | 
			
		|||
					SigSpec insig = i > 0 ? ctrlsig.at(i-1) : State::S0;
 | 
			
		||||
 | 
			
		||||
					Wire *outwire = module->addWire(NEW_ID);
 | 
			
		||||
					outwire->attributes[ID(init)] = i > 0 ? State::S0 : State::S1;
 | 
			
		||||
					outwire->attributes[ID::init] = i > 0 ? State::S0 : State::S1;
 | 
			
		||||
 | 
			
		||||
					if (clksig.empty())
 | 
			
		||||
						module->addFf(NEW_ID, insig, outwire);
 | 
			
		||||
| 
						 | 
				
			
			@ -161,7 +161,7 @@ struct FminitPass : public Pass {
 | 
			
		|||
				if (i+1 == GetSize(it.second) && ctrlsig_latched[i].empty())
 | 
			
		||||
				{
 | 
			
		||||
					Wire *ffwire = module->addWire(NEW_ID);
 | 
			
		||||
					ffwire->attributes[ID(init)] = State::S0;
 | 
			
		||||
					ffwire->attributes[ID::init] = State::S0;
 | 
			
		||||
					SigSpec outsig = module->Or(NEW_ID, ffwire, ctrlsig[i]);
 | 
			
		||||
 | 
			
		||||
					if (clksig.empty())
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -635,8 +635,8 @@ struct FreduceWorker
 | 
			
		|||
				batches.push_back(outputs);
 | 
			
		||||
				bits_full_total += outputs.size();
 | 
			
		||||
			}
 | 
			
		||||
			if (inv_mode && cell->type == "$_NOT_")
 | 
			
		||||
				inv_pairs.insert(std::pair<RTLIL::SigBit, RTLIL::SigBit>(sigmap(cell->getPort("\\A")), sigmap(cell->getPort("\\Y"))));
 | 
			
		||||
			if (inv_mode && cell->type == ID($_NOT_))
 | 
			
		||||
				inv_pairs.insert(std::pair<RTLIL::SigBit, RTLIL::SigBit>(sigmap(cell->getPort(ID::A)), sigmap(cell->getPort(ID::Y))));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		int bits_count = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -731,9 +731,9 @@ struct FreduceWorker
 | 
			
		|||
					{
 | 
			
		||||
						inv_sig = module->addWire(NEW_ID);
 | 
			
		||||
 | 
			
		||||
						RTLIL::Cell *inv_cell = module->addCell(NEW_ID, "$_NOT_");
 | 
			
		||||
						inv_cell->setPort("\\A", grp[0].bit);
 | 
			
		||||
						inv_cell->setPort("\\Y", inv_sig);
 | 
			
		||||
						RTLIL::Cell *inv_cell = module->addCell(NEW_ID, ID($_NOT_));
 | 
			
		||||
						inv_cell->setPort(ID::A, grp[0].bit);
 | 
			
		||||
						inv_cell->setPort(ID::Y, inv_sig);
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					module->connect(RTLIL::SigSig(grp[i].bit, inv_sig));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -116,8 +116,8 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL:
 | 
			
		|||
	miter_module->name = miter_name;
 | 
			
		||||
	design->add(miter_module);
 | 
			
		||||
 | 
			
		||||
	RTLIL::Cell *gold_cell = miter_module->addCell("\\gold", gold_name);
 | 
			
		||||
	RTLIL::Cell *gate_cell = miter_module->addCell("\\gate", gate_name);
 | 
			
		||||
	RTLIL::Cell *gold_cell = miter_module->addCell(ID(gold), gold_name);
 | 
			
		||||
	RTLIL::Cell *gate_cell = miter_module->addCell(ID(gate), gate_name);
 | 
			
		||||
 | 
			
		||||
	RTLIL::SigSpec all_conditions;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -149,63 +149,63 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL:
 | 
			
		|||
			{
 | 
			
		||||
				RTLIL::SigSpec gold_x = miter_module->addWire(NEW_ID, w_gold->width);
 | 
			
		||||
				for (int i = 0; i < w_gold->width; i++) {
 | 
			
		||||
					RTLIL::Cell *eqx_cell = miter_module->addCell(NEW_ID, "$eqx");
 | 
			
		||||
					eqx_cell->parameters["\\A_WIDTH"] = 1;
 | 
			
		||||
					eqx_cell->parameters["\\B_WIDTH"] = 1;
 | 
			
		||||
					eqx_cell->parameters["\\Y_WIDTH"] = 1;
 | 
			
		||||
					eqx_cell->parameters["\\A_SIGNED"] = 0;
 | 
			
		||||
					eqx_cell->parameters["\\B_SIGNED"] = 0;
 | 
			
		||||
					eqx_cell->setPort("\\A", RTLIL::SigSpec(w_gold, i));
 | 
			
		||||
					eqx_cell->setPort("\\B", RTLIL::State::Sx);
 | 
			
		||||
					eqx_cell->setPort("\\Y", gold_x.extract(i, 1));
 | 
			
		||||
					RTLIL::Cell *eqx_cell = miter_module->addCell(NEW_ID, ID($eqx));
 | 
			
		||||
					eqx_cell->parameters[ID::A_WIDTH] = 1;
 | 
			
		||||
					eqx_cell->parameters[ID::B_WIDTH] = 1;
 | 
			
		||||
					eqx_cell->parameters[ID::Y_WIDTH] = 1;
 | 
			
		||||
					eqx_cell->parameters[ID::A_SIGNED] = 0;
 | 
			
		||||
					eqx_cell->parameters[ID::B_SIGNED] = 0;
 | 
			
		||||
					eqx_cell->setPort(ID::A, RTLIL::SigSpec(w_gold, i));
 | 
			
		||||
					eqx_cell->setPort(ID::B, RTLIL::State::Sx);
 | 
			
		||||
					eqx_cell->setPort(ID::Y, gold_x.extract(i, 1));
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				RTLIL::SigSpec gold_masked = miter_module->addWire(NEW_ID, w_gold->width);
 | 
			
		||||
				RTLIL::SigSpec gate_masked = miter_module->addWire(NEW_ID, w_gate->width);
 | 
			
		||||
 | 
			
		||||
				RTLIL::Cell *or_gold_cell = miter_module->addCell(NEW_ID, "$or");
 | 
			
		||||
				or_gold_cell->parameters["\\A_WIDTH"] = w_gold->width;
 | 
			
		||||
				or_gold_cell->parameters["\\B_WIDTH"] = w_gold->width;
 | 
			
		||||
				or_gold_cell->parameters["\\Y_WIDTH"] = w_gold->width;
 | 
			
		||||
				or_gold_cell->parameters["\\A_SIGNED"] = 0;
 | 
			
		||||
				or_gold_cell->parameters["\\B_SIGNED"] = 0;
 | 
			
		||||
				or_gold_cell->setPort("\\A", w_gold);
 | 
			
		||||
				or_gold_cell->setPort("\\B", gold_x);
 | 
			
		||||
				or_gold_cell->setPort("\\Y", gold_masked);
 | 
			
		||||
				RTLIL::Cell *or_gold_cell = miter_module->addCell(NEW_ID, ID($or));
 | 
			
		||||
				or_gold_cell->parameters[ID::A_WIDTH] = w_gold->width;
 | 
			
		||||
				or_gold_cell->parameters[ID::B_WIDTH] = w_gold->width;
 | 
			
		||||
				or_gold_cell->parameters[ID::Y_WIDTH] = w_gold->width;
 | 
			
		||||
				or_gold_cell->parameters[ID::A_SIGNED] = 0;
 | 
			
		||||
				or_gold_cell->parameters[ID::B_SIGNED] = 0;
 | 
			
		||||
				or_gold_cell->setPort(ID::A, w_gold);
 | 
			
		||||
				or_gold_cell->setPort(ID::B, gold_x);
 | 
			
		||||
				or_gold_cell->setPort(ID::Y, gold_masked);
 | 
			
		||||
 | 
			
		||||
				RTLIL::Cell *or_gate_cell = miter_module->addCell(NEW_ID, "$or");
 | 
			
		||||
				or_gate_cell->parameters["\\A_WIDTH"] = w_gate->width;
 | 
			
		||||
				or_gate_cell->parameters["\\B_WIDTH"] = w_gate->width;
 | 
			
		||||
				or_gate_cell->parameters["\\Y_WIDTH"] = w_gate->width;
 | 
			
		||||
				or_gate_cell->parameters["\\A_SIGNED"] = 0;
 | 
			
		||||
				or_gate_cell->parameters["\\B_SIGNED"] = 0;
 | 
			
		||||
				or_gate_cell->setPort("\\A", w_gate);
 | 
			
		||||
				or_gate_cell->setPort("\\B", gold_x);
 | 
			
		||||
				or_gate_cell->setPort("\\Y", gate_masked);
 | 
			
		||||
				RTLIL::Cell *or_gate_cell = miter_module->addCell(NEW_ID, ID($or));
 | 
			
		||||
				or_gate_cell->parameters[ID::A_WIDTH] = w_gate->width;
 | 
			
		||||
				or_gate_cell->parameters[ID::B_WIDTH] = w_gate->width;
 | 
			
		||||
				or_gate_cell->parameters[ID::Y_WIDTH] = w_gate->width;
 | 
			
		||||
				or_gate_cell->parameters[ID::A_SIGNED] = 0;
 | 
			
		||||
				or_gate_cell->parameters[ID::B_SIGNED] = 0;
 | 
			
		||||
				or_gate_cell->setPort(ID::A, w_gate);
 | 
			
		||||
				or_gate_cell->setPort(ID::B, gold_x);
 | 
			
		||||
				or_gate_cell->setPort(ID::Y, gate_masked);
 | 
			
		||||
 | 
			
		||||
				RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx");
 | 
			
		||||
				eq_cell->parameters["\\A_WIDTH"] = w_gold->width;
 | 
			
		||||
				eq_cell->parameters["\\B_WIDTH"] = w_gate->width;
 | 
			
		||||
				eq_cell->parameters["\\Y_WIDTH"] = 1;
 | 
			
		||||
				eq_cell->parameters["\\A_SIGNED"] = 0;
 | 
			
		||||
				eq_cell->parameters["\\B_SIGNED"] = 0;
 | 
			
		||||
				eq_cell->setPort("\\A", gold_masked);
 | 
			
		||||
				eq_cell->setPort("\\B", gate_masked);
 | 
			
		||||
				eq_cell->setPort("\\Y", miter_module->addWire(NEW_ID));
 | 
			
		||||
				this_condition = eq_cell->getPort("\\Y");
 | 
			
		||||
				RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, ID($eqx));
 | 
			
		||||
				eq_cell->parameters[ID::A_WIDTH] = w_gold->width;
 | 
			
		||||
				eq_cell->parameters[ID::B_WIDTH] = w_gate->width;
 | 
			
		||||
				eq_cell->parameters[ID::Y_WIDTH] = 1;
 | 
			
		||||
				eq_cell->parameters[ID::A_SIGNED] = 0;
 | 
			
		||||
				eq_cell->parameters[ID::B_SIGNED] = 0;
 | 
			
		||||
				eq_cell->setPort(ID::A, gold_masked);
 | 
			
		||||
				eq_cell->setPort(ID::B, gate_masked);
 | 
			
		||||
				eq_cell->setPort(ID::Y, miter_module->addWire(NEW_ID));
 | 
			
		||||
				this_condition = eq_cell->getPort(ID::Y);
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, "$eqx");
 | 
			
		||||
				eq_cell->parameters["\\A_WIDTH"] = w_gold->width;
 | 
			
		||||
				eq_cell->parameters["\\B_WIDTH"] = w_gate->width;
 | 
			
		||||
				eq_cell->parameters["\\Y_WIDTH"] = 1;
 | 
			
		||||
				eq_cell->parameters["\\A_SIGNED"] = 0;
 | 
			
		||||
				eq_cell->parameters["\\B_SIGNED"] = 0;
 | 
			
		||||
				eq_cell->setPort("\\A", w_gold);
 | 
			
		||||
				eq_cell->setPort("\\B", w_gate);
 | 
			
		||||
				eq_cell->setPort("\\Y", miter_module->addWire(NEW_ID));
 | 
			
		||||
				this_condition = eq_cell->getPort("\\Y");
 | 
			
		||||
				RTLIL::Cell *eq_cell = miter_module->addCell(NEW_ID, ID($eqx));
 | 
			
		||||
				eq_cell->parameters[ID::A_WIDTH] = w_gold->width;
 | 
			
		||||
				eq_cell->parameters[ID::B_WIDTH] = w_gate->width;
 | 
			
		||||
				eq_cell->parameters[ID::Y_WIDTH] = 1;
 | 
			
		||||
				eq_cell->parameters[ID::A_SIGNED] = 0;
 | 
			
		||||
				eq_cell->parameters[ID::B_SIGNED] = 0;
 | 
			
		||||
				eq_cell->setPort(ID::A, w_gold);
 | 
			
		||||
				eq_cell->setPort(ID::B, w_gate);
 | 
			
		||||
				eq_cell->setPort(ID::Y, miter_module->addWire(NEW_ID));
 | 
			
		||||
				this_condition = eq_cell->getPort(ID::Y);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (flag_make_outcmp)
 | 
			
		||||
| 
						 | 
				
			
			@ -220,31 +220,31 @@ void create_miter_equiv(struct Pass *that, std::vector<std::string> args, RTLIL:
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if (all_conditions.size() != 1) {
 | 
			
		||||
		RTLIL::Cell *reduce_cell = miter_module->addCell(NEW_ID, "$reduce_and");
 | 
			
		||||
		reduce_cell->parameters["\\A_WIDTH"] = all_conditions.size();
 | 
			
		||||
		reduce_cell->parameters["\\Y_WIDTH"] = 1;
 | 
			
		||||
		reduce_cell->parameters["\\A_SIGNED"] = 0;
 | 
			
		||||
		reduce_cell->setPort("\\A", all_conditions);
 | 
			
		||||
		reduce_cell->setPort("\\Y", miter_module->addWire(NEW_ID));
 | 
			
		||||
		all_conditions = reduce_cell->getPort("\\Y");
 | 
			
		||||
		RTLIL::Cell *reduce_cell = miter_module->addCell(NEW_ID, ID($reduce_and));
 | 
			
		||||
		reduce_cell->parameters[ID::A_WIDTH] = all_conditions.size();
 | 
			
		||||
		reduce_cell->parameters[ID::Y_WIDTH] = 1;
 | 
			
		||||
		reduce_cell->parameters[ID::A_SIGNED] = 0;
 | 
			
		||||
		reduce_cell->setPort(ID::A, all_conditions);
 | 
			
		||||
		reduce_cell->setPort(ID::Y, miter_module->addWire(NEW_ID));
 | 
			
		||||
		all_conditions = reduce_cell->getPort(ID::Y);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (flag_make_assert) {
 | 
			
		||||
		RTLIL::Cell *assert_cell = miter_module->addCell(NEW_ID, "$assert");
 | 
			
		||||
		assert_cell->setPort("\\A", all_conditions);
 | 
			
		||||
		assert_cell->setPort("\\EN", State::S1);
 | 
			
		||||
		RTLIL::Cell *assert_cell = miter_module->addCell(NEW_ID, ID($assert));
 | 
			
		||||
		assert_cell->setPort(ID::A, all_conditions);
 | 
			
		||||
		assert_cell->setPort(ID::EN, State::S1);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	RTLIL::Wire *w_trigger = miter_module->addWire("\\trigger");
 | 
			
		||||
	RTLIL::Wire *w_trigger = miter_module->addWire(ID(trigger));
 | 
			
		||||
	w_trigger->port_output = true;
 | 
			
		||||
 | 
			
		||||
	RTLIL::Cell *not_cell = miter_module->addCell(NEW_ID, "$not");
 | 
			
		||||
	not_cell->parameters["\\A_WIDTH"] = all_conditions.size();
 | 
			
		||||
	not_cell->parameters["\\A_WIDTH"] = all_conditions.size();
 | 
			
		||||
	not_cell->parameters["\\Y_WIDTH"] = w_trigger->width;
 | 
			
		||||
	not_cell->parameters["\\A_SIGNED"] = 0;
 | 
			
		||||
	not_cell->setPort("\\A", all_conditions);
 | 
			
		||||
	not_cell->setPort("\\Y", w_trigger);
 | 
			
		||||
	RTLIL::Cell *not_cell = miter_module->addCell(NEW_ID, ID($not));
 | 
			
		||||
	not_cell->parameters[ID::A_WIDTH] = all_conditions.size();
 | 
			
		||||
	not_cell->parameters[ID::A_WIDTH] = all_conditions.size();
 | 
			
		||||
	not_cell->parameters[ID::Y_WIDTH] = w_trigger->width;
 | 
			
		||||
	not_cell->parameters[ID::A_SIGNED] = 0;
 | 
			
		||||
	not_cell->setPort(ID::A, all_conditions);
 | 
			
		||||
	not_cell->setPort(ID::Y, w_trigger);
 | 
			
		||||
 | 
			
		||||
	miter_module->fixup_ports();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -298,7 +298,7 @@ void create_miter_assert(struct Pass *that, std::vector<std::string> args, RTLIL
 | 
			
		|||
		for (auto wire : module->wires())
 | 
			
		||||
			wire->port_output = false;
 | 
			
		||||
 | 
			
		||||
	Wire *trigger = module->addWire("\\trigger");
 | 
			
		||||
	Wire *trigger = module->addWire(ID(trigger));
 | 
			
		||||
	trigger->port_output = true;
 | 
			
		||||
	module->fixup_ports();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -312,13 +312,13 @@ void create_miter_assert(struct Pass *that, std::vector<std::string> args, RTLIL
 | 
			
		|||
	vector<Cell*> cell_list = module->cells();
 | 
			
		||||
	for (auto cell : cell_list)
 | 
			
		||||
	{
 | 
			
		||||
		if (!cell->type.in("$assert", "$assume"))
 | 
			
		||||
		if (!cell->type.in(ID($assert), ID($assume)))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		SigBit is_active = module->Nex(NEW_ID, cell->getPort("\\A"), State::S1);
 | 
			
		||||
		SigBit is_enabled = module->Eqx(NEW_ID, cell->getPort("\\EN"), State::S1);
 | 
			
		||||
		SigBit is_active = module->Nex(NEW_ID, cell->getPort(ID::A), State::S1);
 | 
			
		||||
		SigBit is_enabled = module->Eqx(NEW_ID, cell->getPort(ID::EN), State::S1);
 | 
			
		||||
 | 
			
		||||
		if (cell->type == "$assert") {
 | 
			
		||||
		if (cell->type == ID($assert)) {
 | 
			
		||||
			assert_signals.append(module->And(NEW_ID, is_active, is_enabled));
 | 
			
		||||
		} else {
 | 
			
		||||
			assume_signals.append(module->And(NEW_ID, is_active, is_enabled));
 | 
			
		||||
| 
						 | 
				
			
			@ -334,7 +334,7 @@ void create_miter_assert(struct Pass *that, std::vector<std::string> args, RTLIL
 | 
			
		|||
	else
 | 
			
		||||
	{
 | 
			
		||||
		Wire *assume_q = module->addWire(NEW_ID);
 | 
			
		||||
		assume_q->attributes["\\init"] = State::S0;
 | 
			
		||||
		assume_q->attributes[ID::init] = State::S0;
 | 
			
		||||
		assume_signals.append(assume_q);
 | 
			
		||||
 | 
			
		||||
		SigSpec assume_nok = module->ReduceOr(NEW_ID, assume_signals);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -439,7 +439,7 @@ void mutate_list(Design *design, const mutate_opts_t &opts, const string &filena
 | 
			
		|||
		dict<SigBit, int> bit_user_cnt;
 | 
			
		||||
 | 
			
		||||
		for (auto wire : module->wires()) {
 | 
			
		||||
			if (wire->name[0] == '\\' && wire->attributes.count("\\src"))
 | 
			
		||||
			if (wire->name[0] == '\\' && wire->attributes.count(ID::src))
 | 
			
		||||
				sigmap.add(wire);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -489,12 +489,12 @@ void mutate_list(Design *design, const mutate_opts_t &opts, const string &filena
 | 
			
		|||
					entry.port = conn.first;
 | 
			
		||||
					entry.portbit = i;
 | 
			
		||||
 | 
			
		||||
					for (auto &s : cell->get_strpool_attribute("\\src"))
 | 
			
		||||
					for (auto &s : cell->get_strpool_attribute(ID::src))
 | 
			
		||||
						entry.src.insert(s);
 | 
			
		||||
 | 
			
		||||
					SigBit bit = sigmap(conn.second[i]);
 | 
			
		||||
					if (bit.wire && bit.wire->name[0] == '\\' && (cell->output(conn.first) || bit_user_cnt[bit] == 1)) {
 | 
			
		||||
						for (auto &s : bit.wire->get_strpool_attribute("\\src"))
 | 
			
		||||
						for (auto &s : bit.wire->get_strpool_attribute(ID::src))
 | 
			
		||||
							entry.src.insert(s);
 | 
			
		||||
						entry.wire = bit.wire->name;
 | 
			
		||||
						entry.wirebit = bit.offset;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -258,11 +258,11 @@ struct SatHelper
 | 
			
		|||
 | 
			
		||||
			for (auto &it : module->wires_)
 | 
			
		||||
			{
 | 
			
		||||
				if (it.second->attributes.count("\\init") == 0)
 | 
			
		||||
				if (it.second->attributes.count(ID::init) == 0)
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				RTLIL::SigSpec lhs = sigmap(it.second);
 | 
			
		||||
				RTLIL::SigSpec rhs = it.second->attributes.at("\\init");
 | 
			
		||||
				RTLIL::SigSpec rhs = it.second->attributes.at(ID::init);
 | 
			
		||||
				log_assert(lhs.size() == rhs.size());
 | 
			
		||||
 | 
			
		||||
				RTLIL::SigSpec removed_bits;
 | 
			
		||||
| 
						 | 
				
			
			@ -518,9 +518,9 @@ struct SatHelper
 | 
			
		|||
				} else {
 | 
			
		||||
					for (auto &d : drivers)
 | 
			
		||||
					for (auto &p : d->connections()) {
 | 
			
		||||
						if (d->type == "$dff" && p.first == "\\CLK")
 | 
			
		||||
						if (d->type == ID($dff) && p.first == ID::CLK)
 | 
			
		||||
							continue;
 | 
			
		||||
						if (d->type.begins_with("$_DFF_") && p.first == "\\C")
 | 
			
		||||
						if (d->type.begins_with("$_DFF_") && p.first == ID::C)
 | 
			
		||||
							continue;
 | 
			
		||||
						queued_signals.add(handled_signals.remove(sigmap(p.second)));
 | 
			
		||||
					}
 | 
			
		||||
| 
						 | 
				
			
			@ -675,9 +675,9 @@ struct SatHelper
 | 
			
		|||
		strftime(stime, sizeof(stime), "%c", now);
 | 
			
		||||
 | 
			
		||||
		std::string module_fname = "unknown";
 | 
			
		||||
		auto apos = module->attributes.find("\\src");
 | 
			
		||||
		auto apos = module->attributes.find(ID::src);
 | 
			
		||||
		if(apos != module->attributes.end())
 | 
			
		||||
			module_fname = module->attributes["\\src"].decode_string();
 | 
			
		||||
			module_fname = module->attributes[ID::src].decode_string();
 | 
			
		||||
 | 
			
		||||
		fprintf(f, "$date\n");
 | 
			
		||||
		fprintf(f, "    %s\n", stime);
 | 
			
		||||
| 
						 | 
				
			
			@ -1354,8 +1354,8 @@ struct SatPass : public Pass {
 | 
			
		|||
		if (show_regs) {
 | 
			
		||||
			pool<Wire*> reg_wires;
 | 
			
		||||
			for (auto cell : module->cells()) {
 | 
			
		||||
				if (cell->type == "$dff" || cell->type.begins_with("$_DFF_"))
 | 
			
		||||
					for (auto bit : cell->getPort("\\Q"))
 | 
			
		||||
				if (cell->type == ID($dff) || cell->type.begins_with("$_DFF_"))
 | 
			
		||||
					for (auto bit : cell->getPort(ID::Q))
 | 
			
		||||
						if (bit.wire)
 | 
			
		||||
							reg_wires.insert(bit.wire);
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -108,8 +108,8 @@ struct SimInstance
 | 
			
		|||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (wire->attributes.count("\\init")) {
 | 
			
		||||
				Const initval = wire->attributes.at("\\init");
 | 
			
		||||
			if (wire->attributes.count(ID::init)) {
 | 
			
		||||
				Const initval = wire->attributes.at(ID::init);
 | 
			
		||||
				for (int i = 0; i < GetSize(sig) && i < GetSize(initval); i++)
 | 
			
		||||
					if (initval[i] == State::S0 || initval[i] == State::S1) {
 | 
			
		||||
						state_nets[sig[i]] = initval[i];
 | 
			
		||||
| 
						 | 
				
			
			@ -132,24 +132,24 @@ struct SimInstance
 | 
			
		|||
						upd_cells[bit].insert(cell);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in("$dff")) {
 | 
			
		||||
			if (cell->type.in(ID($dff))) {
 | 
			
		||||
				ff_state_t ff;
 | 
			
		||||
				ff.past_clock = State::Sx;
 | 
			
		||||
				ff.past_d = Const(State::Sx, cell->getParam("\\WIDTH").as_int());
 | 
			
		||||
				ff.past_d = Const(State::Sx, cell->getParam(ID::WIDTH).as_int());
 | 
			
		||||
				ff_database[cell] = ff;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cell->type == "$mem")
 | 
			
		||||
			if (cell->type == ID($mem))
 | 
			
		||||
			{
 | 
			
		||||
				mem_state_t mem;
 | 
			
		||||
 | 
			
		||||
				mem.past_wr_clk = Const(State::Sx, GetSize(cell->getPort("\\WR_CLK")));
 | 
			
		||||
				mem.past_wr_en = Const(State::Sx, GetSize(cell->getPort("\\WR_EN")));
 | 
			
		||||
				mem.past_wr_addr = Const(State::Sx, GetSize(cell->getPort("\\WR_ADDR")));
 | 
			
		||||
				mem.past_wr_data = Const(State::Sx, GetSize(cell->getPort("\\WR_DATA")));
 | 
			
		||||
				mem.past_wr_clk = Const(State::Sx, GetSize(cell->getPort(ID::WR_CLK)));
 | 
			
		||||
				mem.past_wr_en = Const(State::Sx, GetSize(cell->getPort(ID::WR_EN)));
 | 
			
		||||
				mem.past_wr_addr = Const(State::Sx, GetSize(cell->getPort(ID::WR_ADDR)));
 | 
			
		||||
				mem.past_wr_data = Const(State::Sx, GetSize(cell->getPort(ID::WR_DATA)));
 | 
			
		||||
 | 
			
		||||
				mem.data = cell->getParam("\\INIT");
 | 
			
		||||
				int sz = cell->getParam("\\SIZE").as_int() * cell->getParam("\\WIDTH").as_int();
 | 
			
		||||
				mem.data = cell->getParam(ID::INIT);
 | 
			
		||||
				int sz = cell->getParam(ID::SIZE).as_int() * cell->getParam(ID::WIDTH).as_int();
 | 
			
		||||
 | 
			
		||||
				if (GetSize(mem.data) > sz)
 | 
			
		||||
					mem.data.bits.resize(sz);
 | 
			
		||||
| 
						 | 
				
			
			@ -160,7 +160,7 @@ struct SimInstance
 | 
			
		|||
				mem_database[cell] = mem;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in("$assert", "$cover", "$assume")) {
 | 
			
		||||
			if (cell->type.in(ID($assert), ID($cover), ID($assume))) {
 | 
			
		||||
				formal_database.insert(cell);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -173,7 +173,7 @@ struct SimInstance
 | 
			
		|||
				ff_state_t &ff = it.second;
 | 
			
		||||
				zinit(ff.past_d);
 | 
			
		||||
 | 
			
		||||
				SigSpec qsig = cell->getPort("\\Q");
 | 
			
		||||
				SigSpec qsig = cell->getPort(ID::Q);
 | 
			
		||||
				Const qdata = get_state(qsig);
 | 
			
		||||
				zinit(qdata);
 | 
			
		||||
				set_state(qsig, qdata);
 | 
			
		||||
| 
						 | 
				
			
			@ -256,18 +256,18 @@ struct SimInstance
 | 
			
		|||
		{
 | 
			
		||||
			mem_state_t &mem = mem_database.at(cell);
 | 
			
		||||
 | 
			
		||||
			int num_rd_ports = cell->getParam("\\RD_PORTS").as_int();
 | 
			
		||||
			int num_rd_ports = cell->getParam(ID::RD_PORTS).as_int();
 | 
			
		||||
 | 
			
		||||
			int size = cell->getParam("\\SIZE").as_int();
 | 
			
		||||
			int offset = cell->getParam("\\OFFSET").as_int();
 | 
			
		||||
			int abits = cell->getParam("\\ABITS").as_int();
 | 
			
		||||
			int width = cell->getParam("\\WIDTH").as_int();
 | 
			
		||||
			int size = cell->getParam(ID::SIZE).as_int();
 | 
			
		||||
			int offset = cell->getParam(ID::OFFSET).as_int();
 | 
			
		||||
			int abits = cell->getParam(ID::ABITS).as_int();
 | 
			
		||||
			int width = cell->getParam(ID::WIDTH).as_int();
 | 
			
		||||
 | 
			
		||||
			if (cell->getParam("\\RD_CLK_ENABLE").as_bool())
 | 
			
		||||
			if (cell->getParam(ID::RD_CLK_ENABLE).as_bool())
 | 
			
		||||
				log_error("Memory %s.%s has clocked read ports. Run 'memory' with -nordff.\n", log_id(module), log_id(cell));
 | 
			
		||||
 | 
			
		||||
			SigSpec rd_addr_sig = cell->getPort("\\RD_ADDR");
 | 
			
		||||
			SigSpec rd_data_sig = cell->getPort("\\RD_DATA");
 | 
			
		||||
			SigSpec rd_addr_sig = cell->getPort(ID::RD_ADDR);
 | 
			
		||||
			SigSpec rd_data_sig = cell->getPort(ID::RD_DATA);
 | 
			
		||||
 | 
			
		||||
			for (int port_idx = 0; port_idx < num_rd_ports; port_idx++)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -303,19 +303,19 @@ struct SimInstance
 | 
			
		|||
			RTLIL::SigSpec sig_a, sig_b, sig_c, sig_d, sig_s, sig_y;
 | 
			
		||||
			bool has_a, has_b, has_c, has_d, has_s, has_y;
 | 
			
		||||
 | 
			
		||||
			has_a = cell->hasPort("\\A");
 | 
			
		||||
			has_b = cell->hasPort("\\B");
 | 
			
		||||
			has_c = cell->hasPort("\\C");
 | 
			
		||||
			has_d = cell->hasPort("\\D");
 | 
			
		||||
			has_s = cell->hasPort("\\S");
 | 
			
		||||
			has_y = cell->hasPort("\\Y");
 | 
			
		||||
			has_a = cell->hasPort(ID::A);
 | 
			
		||||
			has_b = cell->hasPort(ID::B);
 | 
			
		||||
			has_c = cell->hasPort(ID::C);
 | 
			
		||||
			has_d = cell->hasPort(ID::D);
 | 
			
		||||
			has_s = cell->hasPort(ID::S);
 | 
			
		||||
			has_y = cell->hasPort(ID::Y);
 | 
			
		||||
 | 
			
		||||
			if (has_a) sig_a = cell->getPort("\\A");
 | 
			
		||||
			if (has_b) sig_b = cell->getPort("\\B");
 | 
			
		||||
			if (has_c) sig_c = cell->getPort("\\C");
 | 
			
		||||
			if (has_d) sig_d = cell->getPort("\\D");
 | 
			
		||||
			if (has_s) sig_s = cell->getPort("\\S");
 | 
			
		||||
			if (has_y) sig_y = cell->getPort("\\Y");
 | 
			
		||||
			if (has_a) sig_a = cell->getPort(ID::A);
 | 
			
		||||
			if (has_b) sig_b = cell->getPort(ID::B);
 | 
			
		||||
			if (has_c) sig_c = cell->getPort(ID::C);
 | 
			
		||||
			if (has_d) sig_d = cell->getPort(ID::D);
 | 
			
		||||
			if (has_s) sig_s = cell->getPort(ID::S);
 | 
			
		||||
			if (has_y) sig_y = cell->getPort(ID::Y);
 | 
			
		||||
 | 
			
		||||
			if (shared->debug)
 | 
			
		||||
				log("[%s] eval %s (%s)\n", hiername().c_str(), log_id(cell), log_id(cell->type));
 | 
			
		||||
| 
						 | 
				
			
			@ -403,16 +403,16 @@ struct SimInstance
 | 
			
		|||
			Cell *cell = it.first;
 | 
			
		||||
			ff_state_t &ff = it.second;
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in("$dff"))
 | 
			
		||||
			if (cell->type.in(ID($dff)))
 | 
			
		||||
			{
 | 
			
		||||
				bool clkpol = cell->getParam("\\CLK_POLARITY").as_bool();
 | 
			
		||||
				State current_clock = get_state(cell->getPort("\\CLK"))[0];
 | 
			
		||||
				bool clkpol = cell->getParam(ID::CLK_POLARITY).as_bool();
 | 
			
		||||
				State current_clock = get_state(cell->getPort(ID::CLK))[0];
 | 
			
		||||
 | 
			
		||||
				if (clkpol ? (ff.past_clock == State::S1 || current_clock != State::S1) :
 | 
			
		||||
						(ff.past_clock == State::S0 || current_clock != State::S0))
 | 
			
		||||
					continue;
 | 
			
		||||
 | 
			
		||||
				if (set_state(cell->getPort("\\Q"), ff.past_d))
 | 
			
		||||
				if (set_state(cell->getPort(ID::Q), ff.past_d))
 | 
			
		||||
					did_something = true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -422,16 +422,16 @@ struct SimInstance
 | 
			
		|||
			Cell *cell = it.first;
 | 
			
		||||
			mem_state_t &mem = it.second;
 | 
			
		||||
 | 
			
		||||
			int num_wr_ports = cell->getParam("\\WR_PORTS").as_int();
 | 
			
		||||
			int num_wr_ports = cell->getParam(ID::WR_PORTS).as_int();
 | 
			
		||||
 | 
			
		||||
			int size = cell->getParam("\\SIZE").as_int();
 | 
			
		||||
			int offset = cell->getParam("\\OFFSET").as_int();
 | 
			
		||||
			int abits = cell->getParam("\\ABITS").as_int();
 | 
			
		||||
			int width = cell->getParam("\\WIDTH").as_int();
 | 
			
		||||
			int size = cell->getParam(ID::SIZE).as_int();
 | 
			
		||||
			int offset = cell->getParam(ID::OFFSET).as_int();
 | 
			
		||||
			int abits = cell->getParam(ID::ABITS).as_int();
 | 
			
		||||
			int width = cell->getParam(ID::WIDTH).as_int();
 | 
			
		||||
 | 
			
		||||
			Const wr_clk_enable = cell->getParam("\\WR_CLK_ENABLE");
 | 
			
		||||
			Const wr_clk_polarity = cell->getParam("\\WR_CLK_POLARITY");
 | 
			
		||||
			Const current_wr_clk  = get_state(cell->getPort("\\WR_CLK"));
 | 
			
		||||
			Const wr_clk_enable = cell->getParam(ID::WR_CLK_ENABLE);
 | 
			
		||||
			Const wr_clk_polarity = cell->getParam(ID::WR_CLK_POLARITY);
 | 
			
		||||
			Const current_wr_clk  = get_state(cell->getPort(ID::WR_CLK));
 | 
			
		||||
 | 
			
		||||
			for (int port_idx = 0; port_idx < num_wr_ports; port_idx++)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -439,9 +439,9 @@ struct SimInstance
 | 
			
		|||
 | 
			
		||||
				if (wr_clk_enable[port_idx] == State::S0)
 | 
			
		||||
				{
 | 
			
		||||
					addr = get_state(cell->getPort("\\WR_ADDR").extract(port_idx*abits, abits));
 | 
			
		||||
					data = get_state(cell->getPort("\\WR_DATA").extract(port_idx*width, width));
 | 
			
		||||
					enable = get_state(cell->getPort("\\WR_EN").extract(port_idx*width, width));
 | 
			
		||||
					addr = get_state(cell->getPort(ID::WR_ADDR).extract(port_idx*abits, abits));
 | 
			
		||||
					data = get_state(cell->getPort(ID::WR_DATA).extract(port_idx*width, width));
 | 
			
		||||
					enable = get_state(cell->getPort(ID::WR_EN).extract(port_idx*width, width));
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
| 
						 | 
				
			
			@ -485,9 +485,9 @@ struct SimInstance
 | 
			
		|||
			Cell *cell = it.first;
 | 
			
		||||
			ff_state_t &ff = it.second;
 | 
			
		||||
 | 
			
		||||
			if (cell->type.in("$dff")) {
 | 
			
		||||
				ff.past_clock = get_state(cell->getPort("\\CLK"))[0];
 | 
			
		||||
				ff.past_d = get_state(cell->getPort("\\D"));
 | 
			
		||||
			if (cell->type.in(ID($dff))) {
 | 
			
		||||
				ff.past_clock = get_state(cell->getPort(ID::CLK))[0];
 | 
			
		||||
				ff.past_d = get_state(cell->getPort(ID::D));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -496,28 +496,28 @@ struct SimInstance
 | 
			
		|||
			Cell *cell = it.first;
 | 
			
		||||
			mem_state_t &mem = it.second;
 | 
			
		||||
 | 
			
		||||
			mem.past_wr_clk  = get_state(cell->getPort("\\WR_CLK"));
 | 
			
		||||
			mem.past_wr_en   = get_state(cell->getPort("\\WR_EN"));
 | 
			
		||||
			mem.past_wr_addr = get_state(cell->getPort("\\WR_ADDR"));
 | 
			
		||||
			mem.past_wr_data = get_state(cell->getPort("\\WR_DATA"));
 | 
			
		||||
			mem.past_wr_clk  = get_state(cell->getPort(ID::WR_CLK));
 | 
			
		||||
			mem.past_wr_en   = get_state(cell->getPort(ID::WR_EN));
 | 
			
		||||
			mem.past_wr_addr = get_state(cell->getPort(ID::WR_ADDR));
 | 
			
		||||
			mem.past_wr_data = get_state(cell->getPort(ID::WR_DATA));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (auto cell : formal_database)
 | 
			
		||||
		{
 | 
			
		||||
			string label = log_id(cell);
 | 
			
		||||
			if (cell->attributes.count("\\src"))
 | 
			
		||||
				label = cell->attributes.at("\\src").decode_string();
 | 
			
		||||
			if (cell->attributes.count(ID::src))
 | 
			
		||||
				label = cell->attributes.at(ID::src).decode_string();
 | 
			
		||||
 | 
			
		||||
			State a = get_state(cell->getPort("\\A"))[0];
 | 
			
		||||
			State en = get_state(cell->getPort("\\EN"))[0];
 | 
			
		||||
			State a = get_state(cell->getPort(ID::A))[0];
 | 
			
		||||
			State en = get_state(cell->getPort(ID::EN))[0];
 | 
			
		||||
 | 
			
		||||
			if (cell->type == "$cover" && en == State::S1 && a != State::S1)
 | 
			
		||||
			if (cell->type == ID($cover) && en == State::S1 && a != State::S1)
 | 
			
		||||
				log("Cover %s.%s (%s) reached.\n", hiername().c_str(), log_id(cell), label.c_str());
 | 
			
		||||
 | 
			
		||||
			if (cell->type == "$assume" && en == State::S1 && a != State::S1)
 | 
			
		||||
			if (cell->type == ID($assume) && en == State::S1 && a != State::S1)
 | 
			
		||||
				log("Assumption %s.%s (%s) failed.\n", hiername().c_str(), log_id(cell), label.c_str());
 | 
			
		||||
 | 
			
		||||
			if (cell->type == "$assert" && en == State::S1 && a != State::S1)
 | 
			
		||||
			if (cell->type == ID($assert) && en == State::S1 && a != State::S1)
 | 
			
		||||
				log_warning("Assert %s.%s (%s) failed.\n", hiername().c_str(), log_id(cell), label.c_str());
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -533,22 +533,22 @@ struct SimInstance
 | 
			
		|||
		wbmods.insert(module);
 | 
			
		||||
 | 
			
		||||
		for (auto wire : module->wires())
 | 
			
		||||
			wire->attributes.erase("\\init");
 | 
			
		||||
			wire->attributes.erase(ID::init);
 | 
			
		||||
 | 
			
		||||
		for (auto &it : ff_database)
 | 
			
		||||
		{
 | 
			
		||||
			Cell *cell = it.first;
 | 
			
		||||
			SigSpec sig_q = cell->getPort("\\Q");
 | 
			
		||||
			SigSpec sig_q = cell->getPort(ID::Q);
 | 
			
		||||
			Const initval = get_state(sig_q);
 | 
			
		||||
 | 
			
		||||
			for (int i = 0; i < GetSize(sig_q); i++)
 | 
			
		||||
			{
 | 
			
		||||
				Wire *w = sig_q[i].wire;
 | 
			
		||||
 | 
			
		||||
				if (w->attributes.count("\\init") == 0)
 | 
			
		||||
					w->attributes["\\init"] = Const(State::Sx, GetSize(w));
 | 
			
		||||
				if (w->attributes.count(ID::init) == 0)
 | 
			
		||||
					w->attributes[ID::init] = Const(State::Sx, GetSize(w));
 | 
			
		||||
 | 
			
		||||
				w->attributes["\\init"][sig_q[i].offset] = initval[i];
 | 
			
		||||
				w->attributes[ID::init][sig_q[i].offset] = initval[i];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -564,7 +564,7 @@ struct SimInstance
 | 
			
		|||
				initval.bits.pop_back();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			cell->setParam("\\INIT", initval);
 | 
			
		||||
			cell->setParam(ID::INIT, initval);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		for (auto it : children)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -170,7 +170,7 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
 | 
			
		|||
	{
 | 
			
		||||
		if (clk_polarity != (cell->type == ID($_DFF_P_)))
 | 
			
		||||
			return;
 | 
			
		||||
		if (clk_sig != assign_map(cell->getPort(ID(C))))
 | 
			
		||||
		if (clk_sig != assign_map(cell->getPort(ID::C)))
 | 
			
		||||
			return;
 | 
			
		||||
		if (GetSize(en_sig) != 0)
 | 
			
		||||
			return;
 | 
			
		||||
| 
						 | 
				
			
			@ -183,17 +183,17 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
 | 
			
		|||
			return;
 | 
			
		||||
		if (en_polarity != cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_)))
 | 
			
		||||
			return;
 | 
			
		||||
		if (clk_sig != assign_map(cell->getPort(ID(C))))
 | 
			
		||||
		if (clk_sig != assign_map(cell->getPort(ID::C)))
 | 
			
		||||
			return;
 | 
			
		||||
		if (en_sig != assign_map(cell->getPort(ID(E))))
 | 
			
		||||
		if (en_sig != assign_map(cell->getPort(ID::E)))
 | 
			
		||||
			return;
 | 
			
		||||
		goto matching_dff;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (0) {
 | 
			
		||||
	matching_dff:
 | 
			
		||||
		RTLIL::SigSpec sig_d = cell->getPort(ID(D));
 | 
			
		||||
		RTLIL::SigSpec sig_q = cell->getPort(ID(Q));
 | 
			
		||||
		RTLIL::SigSpec sig_d = cell->getPort(ID::D);
 | 
			
		||||
		RTLIL::SigSpec sig_q = cell->getPort(ID::Q);
 | 
			
		||||
 | 
			
		||||
		if (keepff)
 | 
			
		||||
			for (auto &c : sig_q.chunks())
 | 
			
		||||
| 
						 | 
				
			
			@ -263,7 +263,7 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
 | 
			
		|||
	{
 | 
			
		||||
		RTLIL::SigSpec sig_a = cell->getPort(ID::A);
 | 
			
		||||
		RTLIL::SigSpec sig_b = cell->getPort(ID::B);
 | 
			
		||||
		RTLIL::SigSpec sig_s = cell->getPort(ID(S));
 | 
			
		||||
		RTLIL::SigSpec sig_s = cell->getPort(ID::S);
 | 
			
		||||
		RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
 | 
			
		||||
 | 
			
		||||
		assign_map.apply(sig_a);
 | 
			
		||||
| 
						 | 
				
			
			@ -285,7 +285,7 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
 | 
			
		|||
	{
 | 
			
		||||
		RTLIL::SigSpec sig_a = cell->getPort(ID::A);
 | 
			
		||||
		RTLIL::SigSpec sig_b = cell->getPort(ID::B);
 | 
			
		||||
		RTLIL::SigSpec sig_c = cell->getPort(ID(C));
 | 
			
		||||
		RTLIL::SigSpec sig_c = cell->getPort(ID::C);
 | 
			
		||||
		RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
 | 
			
		||||
 | 
			
		||||
		assign_map.apply(sig_a);
 | 
			
		||||
| 
						 | 
				
			
			@ -307,8 +307,8 @@ void extract_cell(RTLIL::Cell *cell, bool keepff)
 | 
			
		|||
	{
 | 
			
		||||
		RTLIL::SigSpec sig_a = cell->getPort(ID::A);
 | 
			
		||||
		RTLIL::SigSpec sig_b = cell->getPort(ID::B);
 | 
			
		||||
		RTLIL::SigSpec sig_c = cell->getPort(ID(C));
 | 
			
		||||
		RTLIL::SigSpec sig_d = cell->getPort(ID(D));
 | 
			
		||||
		RTLIL::SigSpec sig_c = cell->getPort(ID::C);
 | 
			
		||||
		RTLIL::SigSpec sig_d = cell->getPort(ID::D);
 | 
			
		||||
		RTLIL::SigSpec sig_y = cell->getPort(ID::Y);
 | 
			
		||||
 | 
			
		||||
		assign_map.apply(sig_a);
 | 
			
		||||
| 
						 | 
				
			
			@ -1032,9 +1032,9 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
			RTLIL::Wire *w = it.second;
 | 
			
		||||
			RTLIL::Wire *orig_wire = nullptr;
 | 
			
		||||
			RTLIL::Wire *wire = module->addWire(remap_name(w->name, &orig_wire));
 | 
			
		||||
			if (orig_wire != nullptr && orig_wire->attributes.count(ID(src)))
 | 
			
		||||
				wire->attributes[ID(src)] = orig_wire->attributes[ID(src)];
 | 
			
		||||
			if (markgroups) wire->attributes[ID(abcgroup)] = map_autoidx;
 | 
			
		||||
			if (orig_wire != nullptr && orig_wire->attributes.count(ID::src))
 | 
			
		||||
				wire->attributes[ID::src] = orig_wire->attributes[ID::src];
 | 
			
		||||
			if (markgroups) wire->attributes[ID::abcgroup] = map_autoidx;
 | 
			
		||||
			design->select(module, wire);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1060,7 +1060,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
				}
 | 
			
		||||
				if (c->type == ID(NOT)) {
 | 
			
		||||
					RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_NOT_));
 | 
			
		||||
					if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
 | 
			
		||||
					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
 | 
			
		||||
					cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
 | 
			
		||||
					design->select(module, cell);
 | 
			
		||||
| 
						 | 
				
			
			@ -1068,7 +1068,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
				}
 | 
			
		||||
				if (c->type.in(ID(AND), ID(OR), ID(XOR), ID(NAND), ID(NOR), ID(XNOR), ID(ANDNOT), ID(ORNOT))) {
 | 
			
		||||
					RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
 | 
			
		||||
					if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
 | 
			
		||||
					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
 | 
			
		||||
					cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
 | 
			
		||||
| 
						 | 
				
			
			@ -1077,89 +1077,89 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
				}
 | 
			
		||||
				if (c->type.in(ID(MUX), ID(NMUX))) {
 | 
			
		||||
					RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
 | 
			
		||||
					if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
 | 
			
		||||
					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
 | 
			
		||||
					cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::S, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::S).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
 | 
			
		||||
					design->select(module, cell);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				if (c->type == ID(MUX4)) {
 | 
			
		||||
					RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX4_));
 | 
			
		||||
					if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
 | 
			
		||||
					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
 | 
			
		||||
					cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::C, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::C).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::S, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::S).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::T, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::T).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
 | 
			
		||||
					design->select(module, cell);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				if (c->type == ID(MUX8)) {
 | 
			
		||||
					RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX8_));
 | 
			
		||||
					if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
 | 
			
		||||
					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
 | 
			
		||||
					cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(E)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(F), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(F)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(G), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(G)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(H), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(H)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(U)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::C, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::C).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::E, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::E).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::F, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::F).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::G, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::G).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::H, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::H).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::S, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::S).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::T, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::T).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::U, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::U).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
 | 
			
		||||
					design->select(module, cell);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				if (c->type == ID(MUX16)) {
 | 
			
		||||
					RTLIL::Cell *cell = module->addCell(remap_name(c->name), ID($_MUX16_));
 | 
			
		||||
					if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
 | 
			
		||||
					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
 | 
			
		||||
					cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(E), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(E)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(F), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(F)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(G), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(G)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(H), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(H)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(I), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(I)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(J), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(J)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(K), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(K)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(L), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(L)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(M), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(M)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(N), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(N)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(O), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(O)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(P), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(P)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(S), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(S)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(T), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(T)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(U), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(U)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(V), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(V)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::C, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::C).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::E, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::E).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::F, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::F).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::G, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::G).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::H, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::H).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::I, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::I).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::J, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::J).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::K, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::K).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::L, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::L).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::M, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::M).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::N, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::N).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::O, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::O).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::P, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::P).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::S, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::S).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::T, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::T).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::U, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::U).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::V, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::V).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
 | 
			
		||||
					design->select(module, cell);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				if (c->type.in(ID(AOI3), ID(OAI3))) {
 | 
			
		||||
					RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
 | 
			
		||||
					if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
 | 
			
		||||
					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
 | 
			
		||||
					cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::C, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::C).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
 | 
			
		||||
					design->select(module, cell);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				if (c->type.in(ID(AOI4), ID(OAI4))) {
 | 
			
		||||
					RTLIL::Cell *cell = module->addCell(remap_name(c->name), stringf("$_%s_", c->type.c_str()+1));
 | 
			
		||||
					if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
 | 
			
		||||
					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
 | 
			
		||||
					cell->setPort(ID::A, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::B, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::B).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(C), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(C)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::C, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::C).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::Y, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)]));
 | 
			
		||||
					design->select(module, cell);
 | 
			
		||||
					continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -1172,12 +1172,12 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
					} else {
 | 
			
		||||
						log_assert(en_sig.size() == 1);
 | 
			
		||||
						cell = module->addCell(remap_name(c->name), stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
 | 
			
		||||
						cell->setPort(ID(E), en_sig);
 | 
			
		||||
						cell->setPort(ID::E, en_sig);
 | 
			
		||||
					}
 | 
			
		||||
					if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
 | 
			
		||||
					cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(Q), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Q)).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID(C), clk_sig);
 | 
			
		||||
					if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
 | 
			
		||||
					cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::Q, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Q).as_wire()->name)]));
 | 
			
		||||
					cell->setPort(ID::C, clk_sig);
 | 
			
		||||
					design->select(module, cell);
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			@ -1201,17 +1201,17 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
				} else {
 | 
			
		||||
					log_assert(en_sig.size() == 1);
 | 
			
		||||
					cell = module->addCell(remap_name(c->name), stringf("$_DFFE_%c%c_", clk_polarity ? 'P' : 'N', en_polarity ? 'P' : 'N'));
 | 
			
		||||
					cell->setPort(ID(E), en_sig);
 | 
			
		||||
					cell->setPort(ID::E, en_sig);
 | 
			
		||||
				}
 | 
			
		||||
				if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
 | 
			
		||||
				cell->setPort(ID(D), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(D)).as_wire()->name)]));
 | 
			
		||||
				cell->setPort(ID(Q), RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID(Q)).as_wire()->name)]));
 | 
			
		||||
				cell->setPort(ID(C), clk_sig);
 | 
			
		||||
				if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
 | 
			
		||||
				cell->setPort(ID::D, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::D).as_wire()->name)]));
 | 
			
		||||
				cell->setPort(ID::Q, RTLIL::SigSpec(module->wires_[remap_name(c->getPort(ID::Q).as_wire()->name)]));
 | 
			
		||||
				cell->setPort(ID::C, clk_sig);
 | 
			
		||||
				design->select(module, cell);
 | 
			
		||||
				continue;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (c->type == ID($lut) && GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID(LUT)).as_int() == 2) {
 | 
			
		||||
			if (c->type == ID($lut) && GetSize(c->getPort(ID::A)) == 1 && c->getParam(ID::LUT).as_int() == 2) {
 | 
			
		||||
				SigSpec my_a = module->wires_[remap_name(c->getPort(ID::A).as_wire()->name)];
 | 
			
		||||
				SigSpec my_y = module->wires_[remap_name(c->getPort(ID::Y).as_wire()->name)];
 | 
			
		||||
				module->connect(my_y, my_a);
 | 
			
		||||
| 
						 | 
				
			
			@ -1219,7 +1219,7 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
			}
 | 
			
		||||
 | 
			
		||||
			RTLIL::Cell *cell = module->addCell(remap_name(c->name), c->type);
 | 
			
		||||
			if (markgroups) cell->attributes[ID(abcgroup)] = map_autoidx;
 | 
			
		||||
			if (markgroups) cell->attributes[ID::abcgroup] = map_autoidx;
 | 
			
		||||
			cell->parameters = c->parameters;
 | 
			
		||||
			for (auto &conn : c->connections()) {
 | 
			
		||||
				RTLIL::SigSpec newsig;
 | 
			
		||||
| 
						 | 
				
			
			@ -1244,10 +1244,10 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin
 | 
			
		|||
 | 
			
		||||
		if (recover_init)
 | 
			
		||||
			for (auto wire : mapped_mod->wires()) {
 | 
			
		||||
				if (wire->attributes.count(ID(init))) {
 | 
			
		||||
				if (wire->attributes.count(ID::init)) {
 | 
			
		||||
					Wire *w = module->wires_[remap_name(wire->name)];
 | 
			
		||||
					log_assert(w->attributes.count(ID(init)) == 0);
 | 
			
		||||
					w->attributes[ID(init)] = wire->attributes.at(ID(init));
 | 
			
		||||
					log_assert(w->attributes.count(ID::init) == 0);
 | 
			
		||||
					w->attributes[ID::init] = wire->attributes.at(ID::init);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1869,9 +1869,9 @@ struct AbcPass : public Pass {
 | 
			
		|||
			signal_init.clear();
 | 
			
		||||
 | 
			
		||||
			for (Wire *wire : mod->wires())
 | 
			
		||||
				if (wire->attributes.count(ID(init))) {
 | 
			
		||||
				if (wire->attributes.count(ID::init)) {
 | 
			
		||||
					SigSpec initsig = assign_map(wire);
 | 
			
		||||
					Const initval = wire->attributes.at(ID(init));
 | 
			
		||||
					Const initval = wire->attributes.at(ID::init);
 | 
			
		||||
					for (int i = 0; i < GetSize(initsig) && i < GetSize(initval); i++)
 | 
			
		||||
						switch (initval[i]) {
 | 
			
		||||
							case State::S0:
 | 
			
		||||
| 
						 | 
				
			
			@ -1930,14 +1930,14 @@ struct AbcPass : public Pass {
 | 
			
		|||
 | 
			
		||||
				if (cell->type.in(ID($_DFF_N_), ID($_DFF_P_)))
 | 
			
		||||
				{
 | 
			
		||||
					key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID(C))), true, RTLIL::SigSpec());
 | 
			
		||||
					key = clkdomain_t(cell->type == ID($_DFF_P_), assign_map(cell->getPort(ID::C)), true, RTLIL::SigSpec());
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				if (cell->type.in(ID($_DFFE_NN_), ID($_DFFE_NP_), ID($_DFFE_PN_), ID($_DFFE_PP_)))
 | 
			
		||||
				{
 | 
			
		||||
					bool this_clk_pol = cell->type.in(ID($_DFFE_PN_), ID($_DFFE_PP_));
 | 
			
		||||
					bool this_en_pol = cell->type.in(ID($_DFFE_NP_), ID($_DFFE_PP_));
 | 
			
		||||
					key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID(C))), this_en_pol, assign_map(cell->getPort(ID(E))));
 | 
			
		||||
					key = clkdomain_t(this_clk_pol, assign_map(cell->getPort(ID::C)), this_en_pol, assign_map(cell->getPort(ID::E)));
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
					continue;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -318,7 +318,7 @@ struct Abc9Pass : public ScriptPass
 | 
			
		|||
						log("Skipping module %s as it contains processes.\n", log_id(mod));
 | 
			
		||||
						continue;
 | 
			
		||||
					}
 | 
			
		||||
					log_assert(!mod->attributes.count(ID(abc9_box_id)));
 | 
			
		||||
					log_assert(!mod->attributes.count(ID::abc9_box_id));
 | 
			
		||||
 | 
			
		||||
					log_push();
 | 
			
		||||
					active_design->selection().select(mod);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,8 +41,8 @@ void check(RTLIL::Design *design)
 | 
			
		|||
		if (m->name.begins_with("$paramod"))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		auto flop = m->get_bool_attribute(ID(abc9_flop));
 | 
			
		||||
		auto it = m->attributes.find(ID(abc9_box_id));
 | 
			
		||||
		auto flop = m->get_bool_attribute(ID::abc9_flop);
 | 
			
		||||
		auto it = m->attributes.find(ID::abc9_box_id);
 | 
			
		||||
		if (!flop) {
 | 
			
		||||
			if (it == m->attributes.end())
 | 
			
		||||
				continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -59,7 +59,7 @@ void check(RTLIL::Design *design)
 | 
			
		|||
		for (const auto &port_name : m->ports) {
 | 
			
		||||
			auto w = m->wire(port_name);
 | 
			
		||||
			log_assert(w);
 | 
			
		||||
			if (w->get_bool_attribute("\\abc9_carry")) {
 | 
			
		||||
			if (w->get_bool_attribute(ID::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));
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +99,7 @@ void mark_scc(RTLIL::Module *module)
 | 
			
		|||
	//   write_xaiger to break this wire into PI and POs)
 | 
			
		||||
	pool<RTLIL::Const> ids_seen;
 | 
			
		||||
	for (auto cell : module->cells()) {
 | 
			
		||||
		auto it = cell->attributes.find(ID(abc9_scc_id));
 | 
			
		||||
		auto it = cell->attributes.find(ID::abc9_scc_id);
 | 
			
		||||
		if (it == cell->attributes.end())
 | 
			
		||||
			continue;
 | 
			
		||||
		auto id = it->second;
 | 
			
		||||
| 
						 | 
				
			
			@ -111,7 +111,7 @@ void mark_scc(RTLIL::Module *module)
 | 
			
		|||
			if (c.second.is_fully_const()) continue;
 | 
			
		||||
			if (cell->output(c.first)) {
 | 
			
		||||
				Wire *w = module->addWire(NEW_ID, GetSize(c.second));
 | 
			
		||||
				w->set_bool_attribute(ID(abc9_scc));
 | 
			
		||||
				w->set_bool_attribute(ID::abc9_scc);
 | 
			
		||||
				module->connect(w, c.second);
 | 
			
		||||
				c.second = w;
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -130,7 +130,7 @@ void prep_dff(RTLIL::Module *module)
 | 
			
		|||
	dict<clkdomain_t, int> clk_to_mergeability;
 | 
			
		||||
 | 
			
		||||
	for (auto cell : module->cells()) {
 | 
			
		||||
		if (cell->type != "$__ABC9_FF_")
 | 
			
		||||
		if (cell->type != ID($__ABC9_FF_))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		Wire *abc9_clock_wire = module->wire(stringf("%s.clock", cell->name.c_str()));
 | 
			
		||||
| 
						 | 
				
			
			@ -141,7 +141,7 @@ void prep_dff(RTLIL::Module *module)
 | 
			
		|||
		clkdomain_t key(abc9_clock);
 | 
			
		||||
 | 
			
		||||
		auto r = clk_to_mergeability.insert(std::make_pair(abc9_clock, clk_to_mergeability.size() + 1));
 | 
			
		||||
		auto r2  = cell->attributes.insert(ID(abc9_mergeability));;
 | 
			
		||||
		auto r2  = cell->attributes.insert(ID::abc9_mergeability);
 | 
			
		||||
		log_assert(r2.second);
 | 
			
		||||
		r2.first->second = r.first->second;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -152,20 +152,20 @@ void prep_dff(RTLIL::Module *module)
 | 
			
		|||
 | 
			
		||||
		dict<SigSpec, SigSpec> replace;
 | 
			
		||||
		for (auto cell : holes_module->cells().to_vector()) {
 | 
			
		||||
			if (!cell->type.in("$_DFF_N_", "$_DFF_NN0_", "$_DFF_NN1_", "$_DFF_NP0_", "$_DFF_NP1_",
 | 
			
		||||
						"$_DFF_P_", "$_DFF_PN0_", "$_DFF_PN1", "$_DFF_PP0_", "$_DFF_PP1_"))
 | 
			
		||||
			if (!cell->type.in(ID($_DFF_N_), ID($_DFF_NN0_), ID($_DFF_NN1_), ID($_DFF_NP0_), ID($_DFF_NP1_),
 | 
			
		||||
						ID($_DFF_P_), ID($_DFF_PN0_), ID($_DFF_PN1), ID($_DFF_PP0_), ID($_DFF_PP1_)))
 | 
			
		||||
				continue;
 | 
			
		||||
			SigBit D = cell->getPort("\\D");
 | 
			
		||||
			SigBit Q = cell->getPort("\\Q");
 | 
			
		||||
			SigBit D = cell->getPort(ID::D);
 | 
			
		||||
			SigBit Q = cell->getPort(ID::Q);
 | 
			
		||||
			// Emulate async control embedded inside $_DFF_* cell with mux in front of D
 | 
			
		||||
			if (cell->type.in("$_DFF_NN0_", "$_DFF_PN0_"))
 | 
			
		||||
				D = holes_module->MuxGate(NEW_ID, State::S0, D, cell->getPort("\\R"));
 | 
			
		||||
			else if (cell->type.in("$_DFF_NN1_", "$_DFF_PN1_"))
 | 
			
		||||
				D = holes_module->MuxGate(NEW_ID, State::S1, D, cell->getPort("\\R"));
 | 
			
		||||
			else if (cell->type.in("$_DFF_NP0_", "$_DFF_PP0_"))
 | 
			
		||||
				D = holes_module->MuxGate(NEW_ID, D, State::S0, cell->getPort("\\R"));
 | 
			
		||||
			else if (cell->type.in("$_DFF_NP1_", "$_DFF_PP1_"))
 | 
			
		||||
				D = holes_module->MuxGate(NEW_ID, D, State::S1, cell->getPort("\\R"));
 | 
			
		||||
			if (cell->type.in(ID($_DFF_NN0_), ID($_DFF_PN0_)))
 | 
			
		||||
				D = holes_module->MuxGate(NEW_ID, State::S0, D, cell->getPort(ID::R));
 | 
			
		||||
			else if (cell->type.in(ID($_DFF_NN1_), ID($_DFF_PN1_)))
 | 
			
		||||
				D = holes_module->MuxGate(NEW_ID, State::S1, D, cell->getPort(ID::R));
 | 
			
		||||
			else if (cell->type.in(ID($_DFF_NP0_), ID($_DFF_PP0_)))
 | 
			
		||||
				D = holes_module->MuxGate(NEW_ID, D, State::S0, cell->getPort(ID::R));
 | 
			
		||||
			else if (cell->type.in(ID($_DFF_NP1_), ID($_DFF_PP1_)))
 | 
			
		||||
				D = holes_module->MuxGate(NEW_ID, D, State::S1, cell->getPort(ID::R));
 | 
			
		||||
			// Remove the $_DFF_* cell from what needs to be a combinatorial box
 | 
			
		||||
			holes_module->remove(cell);
 | 
			
		||||
			Wire *port;
 | 
			
		||||
| 
						 | 
				
			
			@ -208,17 +208,17 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
 | 
			
		|||
	dict<IdString, std::vector<IdString>> box_ports;
 | 
			
		||||
 | 
			
		||||
	for (auto cell : module->cells()) {
 | 
			
		||||
		if (cell->type == "$__ABC9_FF_")
 | 
			
		||||
		if (cell->type == ID($__ABC9_FF_))
 | 
			
		||||
			continue;
 | 
			
		||||
		if (cell->has_keep_attr())
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		auto inst_module = module->design->module(cell->type);
 | 
			
		||||
		bool abc9_flop = inst_module && inst_module->get_bool_attribute("\\abc9_flop");
 | 
			
		||||
		bool abc9_flop = inst_module && inst_module->get_bool_attribute(ID::abc9_flop);
 | 
			
		||||
		if (abc9_flop && !dff)
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		if ((inst_module && inst_module->get_bool_attribute("\\abc9_box")) || abc9_flop) {
 | 
			
		||||
		if ((inst_module && inst_module->get_bool_attribute(ID::abc9_box)) || abc9_flop) {
 | 
			
		||||
			auto r = box_ports.insert(cell->type);
 | 
			
		||||
			if (r.second) {
 | 
			
		||||
				// Make carry in the last PI, and carry out the last PO
 | 
			
		||||
| 
						 | 
				
			
			@ -227,7 +227,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
 | 
			
		|||
				for (const auto &port_name : inst_module->ports) {
 | 
			
		||||
					auto w = inst_module->wire(port_name);
 | 
			
		||||
					log_assert(w);
 | 
			
		||||
					if (w->get_bool_attribute("\\abc9_carry")) {
 | 
			
		||||
					if (w->get_bool_attribute(ID::abc9_carry)) {
 | 
			
		||||
						log_assert(w->port_input != w->port_output);
 | 
			
		||||
						if (w->port_input)
 | 
			
		||||
							carry_in = port_name;
 | 
			
		||||
| 
						 | 
				
			
			@ -289,7 +289,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
 | 
			
		|||
 | 
			
		||||
	RTLIL::Module *holes_module = design->addModule(stringf("%s$holes", module->name.c_str()));
 | 
			
		||||
	log_assert(holes_module);
 | 
			
		||||
	holes_module->set_bool_attribute("\\abc9_holes");
 | 
			
		||||
	holes_module->set_bool_attribute(ID::abc9_holes);
 | 
			
		||||
 | 
			
		||||
	dict<IdString, Cell*> cell_cache;
 | 
			
		||||
	TimingInfo timing;
 | 
			
		||||
| 
						 | 
				
			
			@ -300,10 +300,10 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
 | 
			
		|||
		log_assert(cell);
 | 
			
		||||
 | 
			
		||||
		RTLIL::Module* box_module = design->module(cell->type);
 | 
			
		||||
		if (!box_module || (!box_module->get_bool_attribute("\\abc9_box") && !box_module->get_bool_attribute("\\abc9_flop")))
 | 
			
		||||
		if (!box_module || (!box_module->get_bool_attribute(ID::abc9_box) && !box_module->get_bool_attribute(ID::abc9_flop)))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		cell->attributes["\\abc9_box_seq"] = box_count++;
 | 
			
		||||
		cell->attributes[ID::abc9_box_seq] = box_count++;
 | 
			
		||||
 | 
			
		||||
		IdString derived_type = box_module->derive(design, cell->parameters);
 | 
			
		||||
		box_module = design->module(derived_type);
 | 
			
		||||
| 
						 | 
				
			
			@ -314,7 +314,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
 | 
			
		|||
			if (box_module->has_processes())
 | 
			
		||||
				Pass::call_on_module(design, box_module, "proc");
 | 
			
		||||
 | 
			
		||||
			if (box_module->get_bool_attribute("\\whitebox")) {
 | 
			
		||||
			if (box_module->get_bool_attribute(ID::whitebox)) {
 | 
			
		||||
				holes_cell = holes_module->addCell(cell->name, derived_type);
 | 
			
		||||
 | 
			
		||||
				if (box_module->has_processes())
 | 
			
		||||
| 
						 | 
				
			
			@ -345,7 +345,7 @@ void prep_xaiger(RTLIL::Module *module, bool dff)
 | 
			
		|||
 | 
			
		||||
				// For flops only, create an extra 1-bit input that drives a new wire
 | 
			
		||||
				//   called "<cell>.abc9_ff.Q" that is used below
 | 
			
		||||
				if (box_module->get_bool_attribute("\\abc9_flop")) {
 | 
			
		||||
				if (box_module->get_bool_attribute(ID::abc9_flop)) {
 | 
			
		||||
					box_inputs++;
 | 
			
		||||
					Wire *holes_wire = holes_module->wire(stringf("\\i%d", box_inputs));
 | 
			
		||||
					if (!holes_wire) {
 | 
			
		||||
| 
						 | 
				
			
			@ -402,13 +402,13 @@ void prep_delays(RTLIL::Design *design, bool dff_mode)
 | 
			
		|||
				continue;
 | 
			
		||||
			if (!inst_module->get_blackbox_attribute())
 | 
			
		||||
				continue;
 | 
			
		||||
			if (inst_module->attributes.count(ID(abc9_box)))
 | 
			
		||||
			if (inst_module->attributes.count(ID::abc9_box))
 | 
			
		||||
				continue;
 | 
			
		||||
			IdString derived_type = inst_module->derive(design, cell->parameters);
 | 
			
		||||
			inst_module = design->module(derived_type);
 | 
			
		||||
			log_assert(inst_module);
 | 
			
		||||
 | 
			
		||||
			if (dff_mode && inst_module->get_bool_attribute(ID(abc9_flop))) {
 | 
			
		||||
			if (dff_mode && inst_module->get_bool_attribute(ID::abc9_flop)) {
 | 
			
		||||
				flops.insert(inst_module);
 | 
			
		||||
				continue; // do not add $__ABC9_DELAY boxes to flops
 | 
			
		||||
				//   as delays will be captured in the flop box
 | 
			
		||||
| 
						 | 
				
			
			@ -451,9 +451,9 @@ void prep_delays(RTLIL::Design *design, bool dff_mode)
 | 
			
		|||
				}
 | 
			
		||||
#endif
 | 
			
		||||
				auto box = module->addCell(NEW_ID, ID($__ABC9_DELAY));
 | 
			
		||||
				box->setPort(ID(I), conn.second[i]);
 | 
			
		||||
				box->setPort(ID(O), O[i]);
 | 
			
		||||
				box->setParam(ID(DELAY), d);
 | 
			
		||||
				box->setPort(ID::I, conn.second[i]);
 | 
			
		||||
				box->setPort(ID::O, O[i]);
 | 
			
		||||
				box->setParam(ID::DELAY, d);
 | 
			
		||||
				conn.second[i] = O[i];
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -466,7 +466,7 @@ void prep_lut(RTLIL::Design *design, int maxlut)
 | 
			
		|||
 | 
			
		||||
	std::vector<std::tuple<int, IdString, int, std::vector<int>>> table;
 | 
			
		||||
	for (auto module : design->modules()) {
 | 
			
		||||
		auto it = module->attributes.find(ID(abc9_lut));
 | 
			
		||||
		auto it = module->attributes.find(ID::abc9_lut);
 | 
			
		||||
		if (it == module->attributes.end())
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -527,7 +527,7 @@ void prep_box(RTLIL::Design *design, bool dff_mode)
 | 
			
		|||
	std::stringstream ss;
 | 
			
		||||
	int abc9_box_id = 1;
 | 
			
		||||
	for (auto module : design->modules()) {
 | 
			
		||||
		auto it = module->attributes.find(ID(abc9_box_id));
 | 
			
		||||
		auto it = module->attributes.find(ID::abc9_box_id);
 | 
			
		||||
		if (it == module->attributes.end())
 | 
			
		||||
			continue;
 | 
			
		||||
		abc9_box_id = std::max(abc9_box_id, it->second.as_int());
 | 
			
		||||
| 
						 | 
				
			
			@ -535,9 +535,9 @@ void prep_box(RTLIL::Design *design, bool dff_mode)
 | 
			
		|||
 | 
			
		||||
	dict<IdString,std::vector<IdString>> box_ports;
 | 
			
		||||
	for (auto module : design->modules()) {
 | 
			
		||||
		auto abc9_flop = module->get_bool_attribute(ID(abc9_flop));
 | 
			
		||||
		auto abc9_flop = module->get_bool_attribute(ID::abc9_flop);
 | 
			
		||||
		if (abc9_flop) {
 | 
			
		||||
			auto r = module->attributes.insert(ID(abc9_box_id));
 | 
			
		||||
			auto r = module->attributes.insert(ID::abc9_box_id);
 | 
			
		||||
			if (!r.second)
 | 
			
		||||
				continue;
 | 
			
		||||
			r.first->second = abc9_box_id++;
 | 
			
		||||
| 
						 | 
				
			
			@ -604,10 +604,10 @@ void prep_box(RTLIL::Design *design, bool dff_mode)
 | 
			
		|||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			if (!module->attributes.erase(ID(abc9_box)))
 | 
			
		||||
			if (!module->attributes.erase(ID::abc9_box))
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			auto r = module->attributes.insert(ID(abc9_box_id));
 | 
			
		||||
			auto r = module->attributes.insert(ID::abc9_box_id);
 | 
			
		||||
			if (!r.second)
 | 
			
		||||
				continue;
 | 
			
		||||
			r.first->second = abc9_box_id++;
 | 
			
		||||
| 
						 | 
				
			
			@ -621,7 +621,7 @@ void prep_box(RTLIL::Design *design, bool dff_mode)
 | 
			
		|||
			for (const auto &port_name : module->ports) {
 | 
			
		||||
				auto w = module->wire(port_name);
 | 
			
		||||
				log_assert(w);
 | 
			
		||||
				if (w->get_bool_attribute("\\abc9_carry")) {
 | 
			
		||||
				if (w->get_bool_attribute(ID::abc9_carry)) {
 | 
			
		||||
					log_assert(w->port_input != w->port_output);
 | 
			
		||||
					if (w->port_input)
 | 
			
		||||
						carry_in = port_name;
 | 
			
		||||
| 
						 | 
				
			
			@ -650,7 +650,7 @@ void prep_box(RTLIL::Design *design, bool dff_mode)
 | 
			
		|||
					outputs.emplace_back(wire, i);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		ss << log_id(module) << " " << module->attributes.at(ID(abc9_box_id)).as_int();
 | 
			
		||||
		ss << log_id(module) << " " << module->attributes.at(ID::abc9_box_id).as_int();
 | 
			
		||||
		ss << " " << (module->get_bool_attribute(ID::whitebox) ? "1" : "0");
 | 
			
		||||
		ss << " " << GetSize(inputs) << " " << GetSize(outputs) << std::endl;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -727,7 +727,7 @@ void reintegrate(RTLIL::Module *module)
 | 
			
		|||
	dict<IdString,std::vector<IdString>> box_ports;
 | 
			
		||||
 | 
			
		||||
	for (auto m : design->modules()) {
 | 
			
		||||
		if (!m->attributes.count(ID(abc9_box_id)))
 | 
			
		||||
		if (!m->attributes.count(ID::abc9_box_id))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		auto r = box_ports.insert(m->name);
 | 
			
		||||
| 
						 | 
				
			
			@ -740,7 +740,7 @@ void reintegrate(RTLIL::Module *module)
 | 
			
		|||
		for (const auto &port_name : m->ports) {
 | 
			
		||||
			auto w = m->wire(port_name);
 | 
			
		||||
			log_assert(w);
 | 
			
		||||
			if (w->get_bool_attribute("\\abc9_carry")) {
 | 
			
		||||
			if (w->get_bool_attribute(ID::abc9_carry)) {
 | 
			
		||||
				log_assert(w->port_input != w->port_output);
 | 
			
		||||
				if (w->port_input)
 | 
			
		||||
					carry_in = port_name;
 | 
			
		||||
| 
						 | 
				
			
			@ -763,7 +763,7 @@ void reintegrate(RTLIL::Module *module)
 | 
			
		|||
			continue;
 | 
			
		||||
		if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_)))
 | 
			
		||||
			module->remove(cell);
 | 
			
		||||
		else if (cell->attributes.erase("\\abc9_box_seq"))
 | 
			
		||||
		else if (cell->attributes.erase(ID::abc9_box_seq))
 | 
			
		||||
			boxes.emplace_back(cell);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -874,7 +874,7 @@ void reintegrate(RTLIL::Module *module)
 | 
			
		|||
			IdString derived_type = box_module->derive(design, existing_cell->parameters);
 | 
			
		||||
			RTLIL::Module* derived_module = design->module(derived_type);
 | 
			
		||||
			log_assert(derived_module);
 | 
			
		||||
			log_assert(mapped_cell->type == stringf("$__boxid%d", derived_module->attributes.at("\\abc9_box_id").as_int()));
 | 
			
		||||
			log_assert(mapped_cell->type == stringf("$__boxid%d", derived_module->attributes.at(ID::abc9_box_id).as_int()));
 | 
			
		||||
			mapped_cell->type = existing_cell->type;
 | 
			
		||||
 | 
			
		||||
			RTLIL::Cell *cell = module->addCell(remap_name(mapped_cell->name), mapped_cell->type);
 | 
			
		||||
| 
						 | 
				
			
			@ -882,16 +882,16 @@ void reintegrate(RTLIL::Module *module)
 | 
			
		|||
			cell->attributes = existing_cell->attributes;
 | 
			
		||||
			module->swap_names(cell, existing_cell);
 | 
			
		||||
 | 
			
		||||
			auto jt = mapped_cell->connections_.find("\\i");
 | 
			
		||||
			auto jt = mapped_cell->connections_.find(ID(i));
 | 
			
		||||
			log_assert(jt != mapped_cell->connections_.end());
 | 
			
		||||
			SigSpec inputs = std::move(jt->second);
 | 
			
		||||
			mapped_cell->connections_.erase(jt);
 | 
			
		||||
			jt = mapped_cell->connections_.find("\\o");
 | 
			
		||||
			jt = mapped_cell->connections_.find(ID(o));
 | 
			
		||||
			log_assert(jt != mapped_cell->connections_.end());
 | 
			
		||||
			SigSpec outputs = std::move(jt->second);
 | 
			
		||||
			mapped_cell->connections_.erase(jt);
 | 
			
		||||
 | 
			
		||||
			auto abc9_flop = box_module->attributes.count("\\abc9_flop");
 | 
			
		||||
			auto abc9_flop = box_module->attributes.count(ID::abc9_flop);
 | 
			
		||||
			if (!abc9_flop) {
 | 
			
		||||
				for (const auto &i : inputs)
 | 
			
		||||
					bit_users[i].insert(mapped_cell->name);
 | 
			
		||||
| 
						 | 
				
			
			@ -966,7 +966,7 @@ void reintegrate(RTLIL::Module *module)
 | 
			
		|||
		RTLIL::Wire *mapped_wire = mapped_mod->wire(port);
 | 
			
		||||
		RTLIL::Wire *wire = module->wire(port);
 | 
			
		||||
		log_assert(wire);
 | 
			
		||||
		wire->attributes.erase(ID(abc9_scc));
 | 
			
		||||
		wire->attributes.erase(ID::abc9_scc);
 | 
			
		||||
 | 
			
		||||
		RTLIL::Wire *remap_wire = module->wire(remap_name(port));
 | 
			
		||||
		RTLIL::SigSpec signal(wire, 0, GetSize(remap_wire));
 | 
			
		||||
| 
						 | 
				
			
			@ -1033,7 +1033,7 @@ void reintegrate(RTLIL::Module *module)
 | 
			
		|||
		// Push downstream LUTs past inverter
 | 
			
		||||
		for (auto sink_cell : jt->second) {
 | 
			
		||||
			SigSpec A = sink_cell->getPort(ID::A);
 | 
			
		||||
			RTLIL::Const mask = sink_cell->getParam(ID(LUT));
 | 
			
		||||
			RTLIL::Const mask = sink_cell->getParam(ID::LUT);
 | 
			
		||||
			int index = 0;
 | 
			
		||||
			for (; index < GetSize(A); index++)
 | 
			
		||||
				if (A[index] == a_bit)
 | 
			
		||||
| 
						 | 
				
			
			@ -1047,7 +1047,7 @@ void reintegrate(RTLIL::Module *module)
 | 
			
		|||
			}
 | 
			
		||||
			A[index] = y_bit;
 | 
			
		||||
			sink_cell->setPort(ID::A, A);
 | 
			
		||||
			sink_cell->setParam(ID(LUT), mask);
 | 
			
		||||
			sink_cell->setParam(ID::LUT, mask);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// Since we have rewritten all sinks (which we know
 | 
			
		||||
| 
						 | 
				
			
			@ -1056,7 +1056,7 @@ void reintegrate(RTLIL::Module *module)
 | 
			
		|||
		// that the original driving LUT will become dangling
 | 
			
		||||
		// and get cleaned away
 | 
			
		||||
clone_lut:
 | 
			
		||||
		driver_mask = driver_lut->getParam(ID(LUT));
 | 
			
		||||
		driver_mask = driver_lut->getParam(ID::LUT);
 | 
			
		||||
		for (auto &b : driver_mask.bits) {
 | 
			
		||||
			if (b == RTLIL::State::S0) b = RTLIL::State::S1;
 | 
			
		||||
			else if (b == RTLIL::State::S1) b = RTLIL::State::S0;
 | 
			
		||||
| 
						 | 
				
			
			@ -1228,7 +1228,7 @@ struct Abc9OpsPass : public Pass {
 | 
			
		|||
			prep_box(design, dff_mode);
 | 
			
		||||
 | 
			
		||||
		for (auto mod : design->selected_modules()) {
 | 
			
		||||
			if (mod->get_bool_attribute("\\abc9_holes"))
 | 
			
		||||
			if (mod->get_bool_attribute(ID::abc9_holes))
 | 
			
		||||
				continue;
 | 
			
		||||
 | 
			
		||||
			if (mod->processes.size() > 0) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,7 +72,7 @@ struct AlumaccWorker
 | 
			
		|||
 | 
			
		||||
		RTLIL::SigSpec get_eq() {
 | 
			
		||||
			if (GetSize(cached_eq) == 0)
 | 
			
		||||
				cached_eq = alu_cell->module->ReduceAnd(NEW_ID, alu_cell->getPort(ID(X)), false, alu_cell->get_src_attribute());
 | 
			
		||||
				cached_eq = alu_cell->module->ReduceAnd(NEW_ID, alu_cell->getPort(ID::X), false, alu_cell->get_src_attribute());
 | 
			
		||||
			return cached_eq;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -84,7 +84,7 @@ struct AlumaccWorker
 | 
			
		|||
 | 
			
		||||
		RTLIL::SigSpec get_cf() {
 | 
			
		||||
			if (GetSize(cached_cf) == 0) {
 | 
			
		||||
				cached_cf = alu_cell->getPort(ID(CO));
 | 
			
		||||
				cached_cf = alu_cell->getPort(ID::CO);
 | 
			
		||||
				log_assert(GetSize(cached_cf) >= 1);
 | 
			
		||||
				cached_cf = alu_cell->module->Not(NEW_ID, cached_cf[GetSize(cached_cf)-1], false, alu_cell->get_src_attribute());
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -93,7 +93,7 @@ struct AlumaccWorker
 | 
			
		|||
 | 
			
		||||
		RTLIL::SigSpec get_of() {
 | 
			
		||||
			if (GetSize(cached_of) == 0) {
 | 
			
		||||
				cached_of = {alu_cell->getPort(ID(CO)), alu_cell->getPort(ID(CI))};
 | 
			
		||||
				cached_of = {alu_cell->getPort(ID::CO), alu_cell->getPort(ID::CI)};
 | 
			
		||||
				log_assert(GetSize(cached_of) >= 2);
 | 
			
		||||
				cached_of = alu_cell->module->Xor(NEW_ID, cached_of[GetSize(cached_of)-1], cached_of[GetSize(cached_of)-2]);
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -154,7 +154,7 @@ struct AlumaccWorker
 | 
			
		|||
			if (cell->type.in(ID($pos), ID($neg)))
 | 
			
		||||
			{
 | 
			
		||||
				new_port.in_a = sigmap(cell->getPort(ID::A));
 | 
			
		||||
				new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
 | 
			
		||||
				new_port.is_signed = cell->getParam(ID::A_SIGNED).as_bool();
 | 
			
		||||
				new_port.do_subtract = cell->type == ID($neg);
 | 
			
		||||
				n->macc.ports.push_back(new_port);
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -162,12 +162,12 @@ struct AlumaccWorker
 | 
			
		|||
			if (cell->type.in(ID($add), ID($sub)))
 | 
			
		||||
			{
 | 
			
		||||
				new_port.in_a = sigmap(cell->getPort(ID::A));
 | 
			
		||||
				new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
 | 
			
		||||
				new_port.is_signed = cell->getParam(ID::A_SIGNED).as_bool();
 | 
			
		||||
				new_port.do_subtract = false;
 | 
			
		||||
				n->macc.ports.push_back(new_port);
 | 
			
		||||
 | 
			
		||||
				new_port.in_a = sigmap(cell->getPort(ID::B));
 | 
			
		||||
				new_port.is_signed = cell->getParam(ID(B_SIGNED)).as_bool();
 | 
			
		||||
				new_port.is_signed = cell->getParam(ID::B_SIGNED).as_bool();
 | 
			
		||||
				new_port.do_subtract = cell->type == ID($sub);
 | 
			
		||||
				n->macc.ports.push_back(new_port);
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -176,7 +176,7 @@ struct AlumaccWorker
 | 
			
		|||
			{
 | 
			
		||||
				new_port.in_a = sigmap(cell->getPort(ID::A));
 | 
			
		||||
				new_port.in_b = sigmap(cell->getPort(ID::B));
 | 
			
		||||
				new_port.is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
 | 
			
		||||
				new_port.is_signed = cell->getParam(ID::A_SIGNED).as_bool();
 | 
			
		||||
				new_port.do_subtract = false;
 | 
			
		||||
				n->macc.ports.push_back(new_port);
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -399,7 +399,7 @@ struct AlumaccWorker
 | 
			
		|||
 | 
			
		||||
			bool cmp_less = cell->type.in(ID($lt), ID($le));
 | 
			
		||||
			bool cmp_equal = cell->type.in(ID($le), ID($ge));
 | 
			
		||||
			bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
 | 
			
		||||
			bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
 | 
			
		||||
 | 
			
		||||
			RTLIL::SigSpec A = sigmap(cell->getPort(ID::A));
 | 
			
		||||
			RTLIL::SigSpec B = sigmap(cell->getPort(ID::B));
 | 
			
		||||
| 
						 | 
				
			
			@ -439,7 +439,7 @@ struct AlumaccWorker
 | 
			
		|||
		for (auto cell : eq_cells)
 | 
			
		||||
		{
 | 
			
		||||
			bool cmp_equal = cell->type.in(ID($eq), ID($eqx));
 | 
			
		||||
			bool is_signed = cell->getParam(ID(A_SIGNED)).as_bool();
 | 
			
		||||
			bool is_signed = cell->getParam(ID::A_SIGNED).as_bool();
 | 
			
		||||
 | 
			
		||||
			RTLIL::SigSpec A = sigmap(cell->getPort(ID::A));
 | 
			
		||||
			RTLIL::SigSpec B = sigmap(cell->getPort(ID::B));
 | 
			
		||||
| 
						 | 
				
			
			@ -495,11 +495,11 @@ struct AlumaccWorker
 | 
			
		|||
 | 
			
		||||
			n->alu_cell->setPort(ID::A, n->a);
 | 
			
		||||
			n->alu_cell->setPort(ID::B, n->b);
 | 
			
		||||
			n->alu_cell->setPort(ID(CI), GetSize(n->c) ? n->c : State::S0);
 | 
			
		||||
			n->alu_cell->setPort(ID(BI), n->invert_b ? State::S1 : State::S0);
 | 
			
		||||
			n->alu_cell->setPort(ID::CI, GetSize(n->c) ? n->c : State::S0);
 | 
			
		||||
			n->alu_cell->setPort(ID::BI, n->invert_b ? State::S1 : State::S0);
 | 
			
		||||
			n->alu_cell->setPort(ID::Y, n->y);
 | 
			
		||||
			n->alu_cell->setPort(ID(X), module->addWire(NEW_ID, GetSize(n->y)));
 | 
			
		||||
			n->alu_cell->setPort(ID(CO), module->addWire(NEW_ID, GetSize(n->y)));
 | 
			
		||||
			n->alu_cell->setPort(ID::X, module->addWire(NEW_ID, GetSize(n->y)));
 | 
			
		||||
			n->alu_cell->setPort(ID::CO, module->addWire(NEW_ID, GetSize(n->y)));
 | 
			
		||||
			n->alu_cell->fixup_parameters(n->is_signed, n->is_signed);
 | 
			
		||||
 | 
			
		||||
			for (auto &it : n->cmp)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -129,13 +129,13 @@ struct ClkbufmapPass : public Pass {
 | 
			
		|||
			if (module->get_blackbox_attribute()) {
 | 
			
		||||
				for (auto port : module->ports) {
 | 
			
		||||
					auto wire = module->wire(port);
 | 
			
		||||
					if (wire->get_bool_attribute("\\clkbuf_driver"))
 | 
			
		||||
					if (wire->get_bool_attribute(ID::clkbuf_driver))
 | 
			
		||||
						for (int i = 0; i < GetSize(wire); i++)
 | 
			
		||||
							buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
 | 
			
		||||
					if (wire->get_bool_attribute("\\clkbuf_sink"))
 | 
			
		||||
					if (wire->get_bool_attribute(ID::clkbuf_sink))
 | 
			
		||||
						for (int i = 0; i < GetSize(wire); i++)
 | 
			
		||||
							sink_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
 | 
			
		||||
					auto it = wire->attributes.find("\\clkbuf_inv");
 | 
			
		||||
					auto it = wire->attributes.find(ID::clkbuf_inv);
 | 
			
		||||
					if (it != wire->attributes.end()) {
 | 
			
		||||
						IdString in_name = RTLIL::escape_id(it->second.decode_string());
 | 
			
		||||
						for (int i = 0; i < GetSize(wire); i++) {
 | 
			
		||||
| 
						 | 
				
			
			@ -215,7 +215,7 @@ struct ClkbufmapPass : public Pass {
 | 
			
		|||
				if (wire->port_input && wire->port_output)
 | 
			
		||||
					continue;
 | 
			
		||||
				bool process_wire = module->selected(wire);
 | 
			
		||||
				if (!select && wire->get_bool_attribute("\\clkbuf_inhibit"))
 | 
			
		||||
				if (!select && wire->get_bool_attribute(ID::clkbuf_inhibit))
 | 
			
		||||
					process_wire = false;
 | 
			
		||||
				if (!process_wire) {
 | 
			
		||||
					// This wire is supposed to be bypassed, so make sure we don't buffer it in
 | 
			
		||||
| 
						 | 
				
			
			@ -238,7 +238,7 @@ struct ClkbufmapPass : public Pass {
 | 
			
		|||
							buf_ports.insert(make_pair(module->name, make_pair(wire->name, i)));
 | 
			
		||||
					} else if (!sink_wire_bits.count(mapped_wire_bit)) {
 | 
			
		||||
						// Nothing to do.
 | 
			
		||||
					} else if (driven_wire_bits.count(wire_bit) || (wire->port_input && module->get_bool_attribute("\\top"))) {
 | 
			
		||||
					} else if (driven_wire_bits.count(wire_bit) || (wire->port_input && module->get_bool_attribute(ID::top))) {
 | 
			
		||||
						// Clock network not yet buffered, driven by one of
 | 
			
		||||
						// our cells or a top-level input -- buffer it.
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -247,7 +247,7 @@ struct ClkbufmapPass : public Pass {
 | 
			
		|||
						Wire *iwire = module->addWire(NEW_ID);
 | 
			
		||||
						cell->setPort(RTLIL::escape_id(buf_portname), mapped_wire_bit);
 | 
			
		||||
						cell->setPort(RTLIL::escape_id(buf_portname2), iwire);
 | 
			
		||||
						if (wire->port_input && !inpad_celltype.empty() && module->get_bool_attribute("\\top")) {
 | 
			
		||||
						if (wire->port_input && !inpad_celltype.empty() && module->get_bool_attribute(ID::top)) {
 | 
			
		||||
							log("Inserting %s on %s.%s[%d].\n", inpad_celltype.c_str(), log_id(module), log_id(wire), i);
 | 
			
		||||
							RTLIL::Cell *cell2 = module->addCell(NEW_ID, RTLIL::escape_id(inpad_celltype));
 | 
			
		||||
							cell2->setPort(RTLIL::escape_id(inpad_portname), iwire);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -88,7 +88,7 @@ struct Dff2dffeWorker
 | 
			
		|||
		cell_int_t mux_cell_int = bit2mux.at(d);
 | 
			
		||||
		RTLIL::SigSpec sig_a = sigmap(mux_cell_int.first->getPort(ID::A));
 | 
			
		||||
		RTLIL::SigSpec sig_b = sigmap(mux_cell_int.first->getPort(ID::B));
 | 
			
		||||
		RTLIL::SigSpec sig_s = sigmap(mux_cell_int.first->getPort(ID(S)));
 | 
			
		||||
		RTLIL::SigSpec sig_s = sigmap(mux_cell_int.first->getPort(ID::S));
 | 
			
		||||
		int width = GetSize(sig_a), index = mux_cell_int.second;
 | 
			
		||||
 | 
			
		||||
		for (int i = 0; i < GetSize(sig_s); i++)
 | 
			
		||||
| 
						 | 
				
			
			@ -185,8 +185,8 @@ struct Dff2dffeWorker
 | 
			
		|||
 | 
			
		||||
	void handle_dff_cell(RTLIL::Cell *dff_cell)
 | 
			
		||||
	{
 | 
			
		||||
		RTLIL::SigSpec sig_d = sigmap(dff_cell->getPort(ID(D)));
 | 
			
		||||
		RTLIL::SigSpec sig_q = sigmap(dff_cell->getPort(ID(Q)));
 | 
			
		||||
		RTLIL::SigSpec sig_d = sigmap(dff_cell->getPort(ID::D));
 | 
			
		||||
		RTLIL::SigSpec sig_q = sigmap(dff_cell->getPort(ID::Q));
 | 
			
		||||
 | 
			
		||||
		std::map<patterns_t, std::set<int>> grouped_patterns;
 | 
			
		||||
		std::set<int> remaining_indices;
 | 
			
		||||
| 
						 | 
				
			
			@ -208,15 +208,15 @@ struct Dff2dffeWorker
 | 
			
		|||
			}
 | 
			
		||||
			if (!direct_dict.empty()) {
 | 
			
		||||
				log("  converting %s cell %s to %s for %s -> %s.\n", log_id(dff_cell->type), log_id(dff_cell), log_id(direct_dict.at(dff_cell->type)), log_signal(new_sig_d), log_signal(new_sig_q));
 | 
			
		||||
				dff_cell->setPort(ID(E), make_patterns_logic(it.first, true));
 | 
			
		||||
				dff_cell->setPort(ID::E, make_patterns_logic(it.first, true));
 | 
			
		||||
				dff_cell->type = direct_dict.at(dff_cell->type);
 | 
			
		||||
			} else
 | 
			
		||||
			if (dff_cell->type == ID($dff)) {
 | 
			
		||||
				RTLIL::Cell *new_cell = module->addDffe(NEW_ID, dff_cell->getPort(ID(CLK)), make_patterns_logic(it.first, false),
 | 
			
		||||
						new_sig_d, new_sig_q, dff_cell->getParam(ID(CLK_POLARITY)).as_bool(), true);
 | 
			
		||||
				RTLIL::Cell *new_cell = module->addDffe(NEW_ID, dff_cell->getPort(ID::CLK), make_patterns_logic(it.first, false),
 | 
			
		||||
						new_sig_d, new_sig_q, dff_cell->getParam(ID::CLK_POLARITY).as_bool(), true);
 | 
			
		||||
				log("  created $dffe cell %s for %s -> %s.\n", log_id(new_cell), log_signal(new_sig_d), log_signal(new_sig_q));
 | 
			
		||||
			} else {
 | 
			
		||||
				RTLIL::Cell *new_cell = module->addDffeGate(NEW_ID, dff_cell->getPort(ID(C)), make_patterns_logic(it.first, true),
 | 
			
		||||
				RTLIL::Cell *new_cell = module->addDffeGate(NEW_ID, dff_cell->getPort(ID::C), make_patterns_logic(it.first, true),
 | 
			
		||||
						new_sig_d, new_sig_q, dff_cell->type == ID($_DFF_P_), true);
 | 
			
		||||
				log("  created %s cell %s for %s -> %s.\n", log_id(new_cell->type), log_id(new_cell), log_signal(new_sig_d), log_signal(new_sig_q));
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -235,9 +235,9 @@ struct Dff2dffeWorker
 | 
			
		|||
				new_sig_d.append(sig_d[i]);
 | 
			
		||||
				new_sig_q.append(sig_q[i]);
 | 
			
		||||
			}
 | 
			
		||||
			dff_cell->setPort(ID(D), new_sig_d);
 | 
			
		||||
			dff_cell->setPort(ID(Q), new_sig_q);
 | 
			
		||||
			dff_cell->setParam(ID(WIDTH), GetSize(remaining_indices));
 | 
			
		||||
			dff_cell->setPort(ID::D, new_sig_d);
 | 
			
		||||
			dff_cell->setPort(ID::Q, new_sig_q);
 | 
			
		||||
			dff_cell->setParam(ID::WIDTH, GetSize(remaining_indices));
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -361,19 +361,19 @@ struct Dff2dffePass : public Pass {
 | 
			
		|||
								for (auto cell_other : mod->selected_cells()) {
 | 
			
		||||
									if (cell_other->type != cell->type)
 | 
			
		||||
										continue;
 | 
			
		||||
									if (sigmap(cell->getPort(ID(EN))) == sigmap(cell_other->getPort(ID(EN))))
 | 
			
		||||
									if (sigmap(cell->getPort(ID::EN)) == sigmap(cell_other->getPort(ID::EN)))
 | 
			
		||||
										ce_use++;
 | 
			
		||||
								}
 | 
			
		||||
								if (ce_use >= min_ce_use)
 | 
			
		||||
									continue;
 | 
			
		||||
							}
 | 
			
		||||
 | 
			
		||||
							RTLIL::SigSpec tmp = mod->addWire(NEW_ID, GetSize(cell->getPort(ID(D))));
 | 
			
		||||
							mod->addDff(NEW_ID, cell->getPort(ID(CLK)), tmp, cell->getPort(ID(Q)), cell->getParam(ID(CLK_POLARITY)).as_bool());
 | 
			
		||||
							if (cell->getParam(ID(EN_POLARITY)).as_bool())
 | 
			
		||||
								mod->addMux(NEW_ID, cell->getPort(ID(Q)), cell->getPort(ID(D)), cell->getPort(ID(EN)), tmp);
 | 
			
		||||
							RTLIL::SigSpec tmp = mod->addWire(NEW_ID, GetSize(cell->getPort(ID::D)));
 | 
			
		||||
							mod->addDff(NEW_ID, cell->getPort(ID::CLK), tmp, cell->getPort(ID::Q), cell->getParam(ID::CLK_POLARITY).as_bool());
 | 
			
		||||
							if (cell->getParam(ID::EN_POLARITY).as_bool())
 | 
			
		||||
								mod->addMux(NEW_ID, cell->getPort(ID::Q), cell->getPort(ID::D), cell->getPort(ID::EN), tmp);
 | 
			
		||||
							else
 | 
			
		||||
								mod->addMux(NEW_ID, cell->getPort(ID(D)), cell->getPort(ID(Q)), cell->getPort(ID(EN)), tmp);
 | 
			
		||||
								mod->addMux(NEW_ID, cell->getPort(ID::D), cell->getPort(ID::Q), cell->getPort(ID::EN), tmp);
 | 
			
		||||
							mod->remove(cell);
 | 
			
		||||
							continue;
 | 
			
		||||
						}
 | 
			
		||||
| 
						 | 
				
			
			@ -383,7 +383,7 @@ struct Dff2dffePass : public Pass {
 | 
			
		|||
								for (auto cell_other : mod->selected_cells()) {
 | 
			
		||||
									if (cell_other->type != cell->type)
 | 
			
		||||
										continue;
 | 
			
		||||
									if (sigmap(cell->getPort(ID(E))) == sigmap(cell_other->getPort(ID(E))))
 | 
			
		||||
									if (sigmap(cell->getPort(ID::E)) == sigmap(cell_other->getPort(ID::E)))
 | 
			
		||||
										ce_use++;
 | 
			
		||||
								}
 | 
			
		||||
								if (ce_use >= min_ce_use)
 | 
			
		||||
| 
						 | 
				
			
			@ -393,11 +393,11 @@ struct Dff2dffePass : public Pass {
 | 
			
		|||
							bool clk_pol = cell->type.compare(7, 1, "P") == 0;
 | 
			
		||||
							bool en_pol = cell->type.compare(8, 1, "P") == 0;
 | 
			
		||||
							RTLIL::SigSpec tmp = mod->addWire(NEW_ID);
 | 
			
		||||
							mod->addDff(NEW_ID, cell->getPort(ID(C)), tmp, cell->getPort(ID(Q)), clk_pol);
 | 
			
		||||
							mod->addDff(NEW_ID, cell->getPort(ID::C), tmp, cell->getPort(ID::Q), clk_pol);
 | 
			
		||||
							if (en_pol)
 | 
			
		||||
								mod->addMux(NEW_ID, cell->getPort(ID(Q)), cell->getPort(ID(D)), cell->getPort(ID(E)), tmp);
 | 
			
		||||
								mod->addMux(NEW_ID, cell->getPort(ID::Q), cell->getPort(ID::D), cell->getPort(ID::E), tmp);
 | 
			
		||||
							else
 | 
			
		||||
								mod->addMux(NEW_ID, cell->getPort(ID(D)), cell->getPort(ID(Q)), cell->getPort(ID(E)), tmp);
 | 
			
		||||
								mod->addMux(NEW_ID, cell->getPort(ID::D), cell->getPort(ID::Q), cell->getPort(ID::E), tmp);
 | 
			
		||||
							mod->remove(cell);
 | 
			
		||||
							continue;
 | 
			
		||||
						}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,7 +90,7 @@ struct Dff2dffsPass : public Pass {
 | 
			
		|||
 | 
			
		||||
			for (auto cell : ff_cells)
 | 
			
		||||
			{
 | 
			
		||||
				SigSpec sig_d = cell->getPort(ID(D));
 | 
			
		||||
				SigSpec sig_d = cell->getPort(ID::D);
 | 
			
		||||
 | 
			
		||||
				if (GetSize(sig_d) < 1)
 | 
			
		||||
					continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -103,7 +103,7 @@ struct Dff2dffsPass : public Pass {
 | 
			
		|||
				Cell *mux_cell = sr_muxes.at(bit_d);
 | 
			
		||||
				SigBit bit_a = sigmap(mux_cell->getPort(ID::A));
 | 
			
		||||
				SigBit bit_b = sigmap(mux_cell->getPort(ID::B));
 | 
			
		||||
				SigBit bit_s = sigmap(mux_cell->getPort(ID(S)));
 | 
			
		||||
				SigBit bit_s = sigmap(mux_cell->getPort(ID::S));
 | 
			
		||||
 | 
			
		||||
				SigBit sr_val, sr_sig;
 | 
			
		||||
				bool invert_sr;
 | 
			
		||||
| 
						 | 
				
			
			@ -120,9 +120,9 @@ struct Dff2dffsPass : public Pass {
 | 
			
		|||
				}
 | 
			
		||||
 | 
			
		||||
				if (match_init) {
 | 
			
		||||
					SigBit bit_q = cell->getPort(ID(Q));
 | 
			
		||||
					SigBit bit_q = cell->getPort(ID::Q);
 | 
			
		||||
					if (bit_q.wire) {
 | 
			
		||||
						auto it = bit_q.wire->attributes.find(ID(init));
 | 
			
		||||
						auto it = bit_q.wire->attributes.find(ID::init);
 | 
			
		||||
						if (it != bit_q.wire->attributes.end()) {
 | 
			
		||||
							auto init_val = it->second[bit_q.offset];
 | 
			
		||||
							if (init_val == State::S1 && sr_val != State::S1)
 | 
			
		||||
| 
						 | 
				
			
			@ -155,8 +155,8 @@ struct Dff2dffsPass : public Pass {
 | 
			
		|||
						else cell->type = ID($__DFFS_PP0_);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				cell->setPort(ID(R), sr_sig);
 | 
			
		||||
				cell->setPort(ID(D), bit_d);
 | 
			
		||||
				cell->setPort(ID::R, sr_sig);
 | 
			
		||||
				cell->setPort(ID::D, bit_d);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -99,8 +99,8 @@ struct DffinitPass : public Pass {
 | 
			
		|||
			pool<SigBit> used_bits;
 | 
			
		||||
 | 
			
		||||
			for (auto wire : module->selected_wires()) {
 | 
			
		||||
				if (wire->attributes.count(ID(init))) {
 | 
			
		||||
					Const value = wire->attributes.at(ID(init));
 | 
			
		||||
				if (wire->attributes.count(ID::init)) {
 | 
			
		||||
					Const value = wire->attributes.at(ID::init);
 | 
			
		||||
					for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++)
 | 
			
		||||
						if (value[i] != State::Sx)
 | 
			
		||||
							init_bits[sigmap(SigBit(wire, i))] = value[i];
 | 
			
		||||
| 
						 | 
				
			
			@ -161,8 +161,8 @@ struct DffinitPass : public Pass {
 | 
			
		|||
			}
 | 
			
		||||
 | 
			
		||||
			for (auto wire : module->selected_wires())
 | 
			
		||||
				if (wire->attributes.count(ID(init))) {
 | 
			
		||||
					Const &value = wire->attributes.at(ID(init));
 | 
			
		||||
				if (wire->attributes.count(ID::init)) {
 | 
			
		||||
					Const &value = wire->attributes.at(ID::init);
 | 
			
		||||
					bool do_cleanup = true;
 | 
			
		||||
					for (int i = 0; i < min(GetSize(value), GetSize(wire)); i++) {
 | 
			
		||||
						SigBit bit = sigmap(SigBit(wire, i));
 | 
			
		||||
| 
						 | 
				
			
			@ -173,7 +173,7 @@ struct DffinitPass : public Pass {
 | 
			
		|||
					}
 | 
			
		||||
					if (do_cleanup) {
 | 
			
		||||
						log("Removing init attribute from wire %s.%s.\n", log_id(module), log_id(wire));
 | 
			
		||||
						wire->attributes.erase(ID(init));
 | 
			
		||||
						wire->attributes.erase(ID::init);
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,15 +27,15 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
 | 
			
		|||
{
 | 
			
		||||
	if (cell->type == ID($dffsr))
 | 
			
		||||
	{
 | 
			
		||||
		int width = cell->getParam(ID(WIDTH)).as_int();
 | 
			
		||||
		bool setpol = cell->getParam(ID(SET_POLARITY)).as_bool();
 | 
			
		||||
		bool clrpol = cell->getParam(ID(CLR_POLARITY)).as_bool();
 | 
			
		||||
		int width = cell->getParam(ID::WIDTH).as_int();
 | 
			
		||||
		bool setpol = cell->getParam(ID::SET_POLARITY).as_bool();
 | 
			
		||||
		bool clrpol = cell->getParam(ID::CLR_POLARITY).as_bool();
 | 
			
		||||
 | 
			
		||||
		SigBit setunused = setpol ? State::S0 : State::S1;
 | 
			
		||||
		SigBit clrunused = clrpol ? State::S0 : State::S1;
 | 
			
		||||
 | 
			
		||||
		SigSpec setsig = sigmap(cell->getPort(ID(SET)));
 | 
			
		||||
		SigSpec clrsig = sigmap(cell->getPort(ID(CLR)));
 | 
			
		||||
		SigSpec setsig = sigmap(cell->getPort(ID::SET));
 | 
			
		||||
		SigSpec clrsig = sigmap(cell->getPort(ID::CLR));
 | 
			
		||||
 | 
			
		||||
		Const reset_val;
 | 
			
		||||
		SigSpec setctrl, clrctrl;
 | 
			
		||||
| 
						 | 
				
			
			@ -78,19 +78,19 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
 | 
			
		|||
		log("Converting %s cell %s.%s to $adff.\n", log_id(cell->type), log_id(module), log_id(cell));
 | 
			
		||||
 | 
			
		||||
		if (GetSize(setctrl) == 1) {
 | 
			
		||||
			cell->setPort(ID(ARST), setctrl);
 | 
			
		||||
			cell->setParam(ID(ARST_POLARITY), setpol);
 | 
			
		||||
			cell->setPort(ID::ARST, setctrl);
 | 
			
		||||
			cell->setParam(ID::ARST_POLARITY, setpol);
 | 
			
		||||
		} else {
 | 
			
		||||
			cell->setPort(ID(ARST), clrctrl);
 | 
			
		||||
			cell->setParam(ID(ARST_POLARITY), clrpol);
 | 
			
		||||
			cell->setPort(ID::ARST, clrctrl);
 | 
			
		||||
			cell->setParam(ID::ARST_POLARITY, clrpol);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		cell->type = ID($adff);
 | 
			
		||||
		cell->unsetPort(ID(SET));
 | 
			
		||||
		cell->unsetPort(ID(CLR));
 | 
			
		||||
		cell->setParam(ID(ARST_VALUE), reset_val);
 | 
			
		||||
		cell->unsetParam(ID(SET_POLARITY));
 | 
			
		||||
		cell->unsetParam(ID(CLR_POLARITY));
 | 
			
		||||
		cell->unsetPort(ID::SET);
 | 
			
		||||
		cell->unsetPort(ID::CLR);
 | 
			
		||||
		cell->setParam(ID::ARST_VALUE, reset_val);
 | 
			
		||||
		cell->unsetParam(ID::SET_POLARITY);
 | 
			
		||||
		cell->unsetParam(ID::CLR_POLARITY);
 | 
			
		||||
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -102,8 +102,8 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
 | 
			
		|||
		char setpol = cell->type.c_str()[9];
 | 
			
		||||
		char clrpol = cell->type.c_str()[10];
 | 
			
		||||
 | 
			
		||||
		SigBit setbit = sigmap(cell->getPort(ID(S)));
 | 
			
		||||
		SigBit clrbit = sigmap(cell->getPort(ID(R)));
 | 
			
		||||
		SigBit setbit = sigmap(cell->getPort(ID::S));
 | 
			
		||||
		SigBit clrbit = sigmap(cell->getPort(ID::R));
 | 
			
		||||
 | 
			
		||||
		SigBit setunused = setpol == 'P' ? State::S0 : State::S1;
 | 
			
		||||
		SigBit clrunused = clrpol == 'P' ? State::S0 : State::S1;
 | 
			
		||||
| 
						 | 
				
			
			@ -112,14 +112,14 @@ void dffsr_worker(SigMap &sigmap, Module *module, Cell *cell)
 | 
			
		|||
 | 
			
		||||
		if (setbit == setunused) {
 | 
			
		||||
			cell->type = stringf("$_DFF_%c%c0_", clkpol, clrpol);
 | 
			
		||||
			cell->unsetPort(ID(S));
 | 
			
		||||
			cell->unsetPort(ID::S);
 | 
			
		||||
			goto converted_gate;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (clrbit == clrunused) {
 | 
			
		||||
			cell->type = stringf("$_DFF_%c%c1_", clkpol, setpol);
 | 
			
		||||
			cell->setPort(ID(R), cell->getPort(ID(S)));
 | 
			
		||||
			cell->unsetPort(ID(S));
 | 
			
		||||
			cell->setPort(ID::R, cell->getPort(ID::S));
 | 
			
		||||
			cell->unsetPort(ID::S);
 | 
			
		||||
			goto converted_gate;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -135,9 +135,9 @@ void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
 | 
			
		|||
{
 | 
			
		||||
	if (cell->type == ID($adff))
 | 
			
		||||
	{
 | 
			
		||||
		bool rstpol = cell->getParam(ID(ARST_POLARITY)).as_bool();
 | 
			
		||||
		bool rstpol = cell->getParam(ID::ARST_POLARITY).as_bool();
 | 
			
		||||
		SigBit rstunused = rstpol ? State::S0 : State::S1;
 | 
			
		||||
		SigSpec rstsig = sigmap(cell->getPort(ID(ARST)));
 | 
			
		||||
		SigSpec rstsig = sigmap(cell->getPort(ID::ARST));
 | 
			
		||||
 | 
			
		||||
		if (rstsig != rstunused)
 | 
			
		||||
			return;
 | 
			
		||||
| 
						 | 
				
			
			@ -145,9 +145,9 @@ void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
 | 
			
		|||
		log("Converting %s cell %s.%s to $dff.\n", log_id(cell->type), log_id(module), log_id(cell));
 | 
			
		||||
 | 
			
		||||
		cell->type = ID($dff);
 | 
			
		||||
		cell->unsetPort(ID(ARST));
 | 
			
		||||
		cell->unsetParam(ID(ARST_VALUE));
 | 
			
		||||
		cell->unsetParam(ID(ARST_POLARITY));
 | 
			
		||||
		cell->unsetPort(ID::ARST);
 | 
			
		||||
		cell->unsetParam(ID::ARST_VALUE);
 | 
			
		||||
		cell->unsetParam(ID::ARST_POLARITY);
 | 
			
		||||
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -158,7 +158,7 @@ void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
 | 
			
		|||
		char clkpol = cell->type.c_str()[6];
 | 
			
		||||
		char rstpol = cell->type.c_str()[7];
 | 
			
		||||
 | 
			
		||||
		SigBit rstbit = sigmap(cell->getPort(ID(R)));
 | 
			
		||||
		SigBit rstbit = sigmap(cell->getPort(ID::R));
 | 
			
		||||
		SigBit rstunused = rstpol == 'P' ? State::S0 : State::S1;
 | 
			
		||||
 | 
			
		||||
		if (rstbit != rstunused)
 | 
			
		||||
| 
						 | 
				
			
			@ -168,7 +168,7 @@ void adff_worker(SigMap &sigmap, Module *module, Cell *cell)
 | 
			
		|||
		log("Converting %s cell %s.%s to %s.\n", log_id(cell->type), log_id(module), log_id(cell), log_id(newtype));
 | 
			
		||||
 | 
			
		||||
		cell->type = newtype;
 | 
			
		||||
		cell->unsetPort(ID(R));
 | 
			
		||||
		cell->unsetPort(ID::R);
 | 
			
		||||
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,36 +58,36 @@ public:
 | 
			
		|||
			return value;
 | 
			
		||||
 | 
			
		||||
	#define param_bool(_n) if (param == _n) return value.as_bool();
 | 
			
		||||
		param_bool(ID(ARST_POLARITY));
 | 
			
		||||
		param_bool(ID(A_SIGNED));
 | 
			
		||||
		param_bool(ID(B_SIGNED));
 | 
			
		||||
		param_bool(ID(CLK_ENABLE));
 | 
			
		||||
		param_bool(ID(CLK_POLARITY));
 | 
			
		||||
		param_bool(ID(CLR_POLARITY));
 | 
			
		||||
		param_bool(ID(EN_POLARITY));
 | 
			
		||||
		param_bool(ID(SET_POLARITY));
 | 
			
		||||
		param_bool(ID(TRANSPARENT));
 | 
			
		||||
		param_bool(ID::ARST_POLARITY);
 | 
			
		||||
		param_bool(ID::A_SIGNED);
 | 
			
		||||
		param_bool(ID::B_SIGNED);
 | 
			
		||||
		param_bool(ID::CLK_ENABLE);
 | 
			
		||||
		param_bool(ID::CLK_POLARITY);
 | 
			
		||||
		param_bool(ID::CLR_POLARITY);
 | 
			
		||||
		param_bool(ID::EN_POLARITY);
 | 
			
		||||
		param_bool(ID::SET_POLARITY);
 | 
			
		||||
		param_bool(ID::TRANSPARENT);
 | 
			
		||||
	#undef param_bool
 | 
			
		||||
 | 
			
		||||
	#define param_int(_n) if (param == _n) return value.as_int();
 | 
			
		||||
		param_int(ID(ABITS))
 | 
			
		||||
		param_int(ID(A_WIDTH))
 | 
			
		||||
		param_int(ID(B_WIDTH))
 | 
			
		||||
		param_int(ID(CTRL_IN_WIDTH))
 | 
			
		||||
		param_int(ID(CTRL_OUT_WIDTH))
 | 
			
		||||
		param_int(ID(OFFSET))
 | 
			
		||||
		param_int(ID(PRIORITY))
 | 
			
		||||
		param_int(ID(RD_PORTS))
 | 
			
		||||
		param_int(ID(SIZE))
 | 
			
		||||
		param_int(ID(STATE_BITS))
 | 
			
		||||
		param_int(ID(STATE_NUM))
 | 
			
		||||
		param_int(ID(STATE_NUM_LOG2))
 | 
			
		||||
		param_int(ID(STATE_RST))
 | 
			
		||||
		param_int(ID(S_WIDTH))
 | 
			
		||||
		param_int(ID(TRANS_NUM))
 | 
			
		||||
		param_int(ID(WIDTH))
 | 
			
		||||
		param_int(ID(WR_PORTS))
 | 
			
		||||
		param_int(ID(Y_WIDTH))
 | 
			
		||||
		param_int(ID::ABITS)
 | 
			
		||||
		param_int(ID::A_WIDTH)
 | 
			
		||||
		param_int(ID::B_WIDTH)
 | 
			
		||||
		param_int(ID::CTRL_IN_WIDTH)
 | 
			
		||||
		param_int(ID::CTRL_OUT_WIDTH)
 | 
			
		||||
		param_int(ID::OFFSET)
 | 
			
		||||
		param_int(ID::PRIORITY)
 | 
			
		||||
		param_int(ID::RD_PORTS)
 | 
			
		||||
		param_int(ID::SIZE)
 | 
			
		||||
		param_int(ID::STATE_BITS)
 | 
			
		||||
		param_int(ID::STATE_NUM)
 | 
			
		||||
		param_int(ID::STATE_NUM_LOG2)
 | 
			
		||||
		param_int(ID::STATE_RST)
 | 
			
		||||
		param_int(ID::S_WIDTH)
 | 
			
		||||
		param_int(ID::TRANS_NUM)
 | 
			
		||||
		param_int(ID::WIDTH)
 | 
			
		||||
		param_int(ID::WR_PORTS)
 | 
			
		||||
		param_int(ID::Y_WIDTH)
 | 
			
		||||
	#undef param_int
 | 
			
		||||
 | 
			
		||||
		return value;
 | 
			
		||||
| 
						 | 
				
			
			@ -341,10 +341,10 @@ RTLIL::Cell *replace(RTLIL::Module *needle, RTLIL::Module *haystack, SubCircuit:
 | 
			
		|||
bool compareSortNeedleList(RTLIL::Module *left, RTLIL::Module *right)
 | 
			
		||||
{
 | 
			
		||||
	int left_idx = 0, right_idx = 0;
 | 
			
		||||
	if (left->attributes.count(ID(extract_order)) > 0)
 | 
			
		||||
		left_idx = left->attributes.at(ID(extract_order)).as_int();
 | 
			
		||||
	if (right->attributes.count(ID(extract_order)) > 0)
 | 
			
		||||
		right_idx = right->attributes.at(ID(extract_order)).as_int();
 | 
			
		||||
	if (left->attributes.count(ID::extract_order) > 0)
 | 
			
		||||
		left_idx = left->attributes.at(ID::extract_order).as_int();
 | 
			
		||||
	if (right->attributes.count(ID::extract_order) > 0)
 | 
			
		||||
		right_idx = right->attributes.at(ID::extract_order).as_int();
 | 
			
		||||
	if (left_idx != right_idx)
 | 
			
		||||
		return left_idx < right_idx;
 | 
			
		||||
	return left->name < right->name;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -131,23 +131,23 @@ int counter_tryextract(
 | 
			
		|||
	SigMap& sigmap = index.sigmap;
 | 
			
		||||
 | 
			
		||||
	//Both inputs must be unsigned, so don't extract anything with a signed input
 | 
			
		||||
	bool a_sign = cell->getParam(ID(A_SIGNED)).as_bool();
 | 
			
		||||
	bool b_sign = cell->getParam(ID(B_SIGNED)).as_bool();
 | 
			
		||||
	bool a_sign = cell->getParam(ID::A_SIGNED).as_bool();
 | 
			
		||||
	bool b_sign = cell->getParam(ID::B_SIGNED).as_bool();
 | 
			
		||||
	if(a_sign || b_sign)
 | 
			
		||||
		return 3;
 | 
			
		||||
 | 
			
		||||
	//CO and X must be unconnected (exactly one connection to each port)
 | 
			
		||||
	if(!is_unconnected(sigmap(cell->getPort(ID(CO))), index))
 | 
			
		||||
	if(!is_unconnected(sigmap(cell->getPort(ID::CO)), index))
 | 
			
		||||
		return 7;
 | 
			
		||||
	if(!is_unconnected(sigmap(cell->getPort(ID(X))), index))
 | 
			
		||||
	if(!is_unconnected(sigmap(cell->getPort(ID::X)), index))
 | 
			
		||||
		return 8;
 | 
			
		||||
 | 
			
		||||
	//true if $alu is performing A - B, else A + B
 | 
			
		||||
	bool alu_is_subtract;
 | 
			
		||||
 | 
			
		||||
	//BI and CI must be both constant 0 or both constant 1 as well
 | 
			
		||||
	const RTLIL::SigSpec bi_port = sigmap(cell->getPort(ID(BI)));
 | 
			
		||||
	const RTLIL::SigSpec ci_port = sigmap(cell->getPort(ID(CI)));
 | 
			
		||||
	const RTLIL::SigSpec bi_port = sigmap(cell->getPort(ID::BI));
 | 
			
		||||
	const RTLIL::SigSpec ci_port = sigmap(cell->getPort(ID::CI));
 | 
			
		||||
	if(bi_port.is_fully_const() && bi_port.as_int() == 1 &&
 | 
			
		||||
		ci_port.is_fully_const() && ci_port.as_int() == 1)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -169,8 +169,8 @@ int counter_tryextract(
 | 
			
		|||
 | 
			
		||||
	if(alu_is_subtract)
 | 
			
		||||
	{
 | 
			
		||||
		const int a_width = cell->getParam(ID(A_WIDTH)).as_int();
 | 
			
		||||
		const int b_width = cell->getParam(ID(B_WIDTH)).as_int();
 | 
			
		||||
		const int a_width = cell->getParam(ID::A_WIDTH).as_int();
 | 
			
		||||
		const int b_width = cell->getParam(ID::B_WIDTH).as_int();
 | 
			
		||||
		const RTLIL::SigSpec b_port = sigmap(cell->getPort(ID::B));
 | 
			
		||||
 | 
			
		||||
		// down, cnt <= cnt - 1
 | 
			
		||||
| 
						 | 
				
			
			@ -197,8 +197,8 @@ int counter_tryextract(
 | 
			
		|||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		const int a_width = cell->getParam(ID(A_WIDTH)).as_int();
 | 
			
		||||
		const int b_width = cell->getParam(ID(B_WIDTH)).as_int();
 | 
			
		||||
		const int a_width = cell->getParam(ID::A_WIDTH).as_int();
 | 
			
		||||
		const int b_width = cell->getParam(ID::B_WIDTH).as_int();
 | 
			
		||||
		const RTLIL::SigSpec a_port = sigmap(cell->getPort(ID::A));
 | 
			
		||||
		const RTLIL::SigSpec b_port = sigmap(cell->getPort(ID::B));
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -245,9 +245,9 @@ int counter_tryextract(
 | 
			
		|||
	//Check if counter is an appropriate size
 | 
			
		||||
	int count_width;
 | 
			
		||||
	if (alu_port_use_a)
 | 
			
		||||
		count_width = cell->getParam(ID(A_WIDTH)).as_int();
 | 
			
		||||
		count_width = cell->getParam(ID::A_WIDTH).as_int();
 | 
			
		||||
	else
 | 
			
		||||
		count_width = cell->getParam(ID(B_WIDTH)).as_int();
 | 
			
		||||
		count_width = cell->getParam(ID::B_WIDTH).as_int();
 | 
			
		||||
	extract.width = count_width;
 | 
			
		||||
	if( (count_width < settings.minwidth) || (count_width > settings.maxwidth) )
 | 
			
		||||
		return 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -283,7 +283,7 @@ int counter_tryextract(
 | 
			
		|||
 | 
			
		||||
	//S connection of the mux must come from an inverter if down, eq if up
 | 
			
		||||
	//(need not be the only load)
 | 
			
		||||
	const RTLIL::SigSpec muxsel = sigmap(count_mux->getPort(ID(S)));
 | 
			
		||||
	const RTLIL::SigSpec muxsel = sigmap(count_mux->getPort(ID::S));
 | 
			
		||||
	extract.outsig = muxsel;
 | 
			
		||||
	pool<Cell*> muxsel_conns = get_other_cells(muxsel, index, count_mux);
 | 
			
		||||
	Cell* overflow_cell = NULL;
 | 
			
		||||
| 
						 | 
				
			
			@ -293,7 +293,7 @@ int counter_tryextract(
 | 
			
		|||
			continue;
 | 
			
		||||
		if(!extract.count_is_up && c->type != ID($logic_not))
 | 
			
		||||
			continue;
 | 
			
		||||
		if(!is_full_bus(muxsel, index, c, ID::Y, count_mux, ID(S), true))
 | 
			
		||||
		if(!is_full_bus(muxsel, index, c, ID::Y, count_mux, ID::S, true))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		overflow_cell = c;
 | 
			
		||||
| 
						 | 
				
			
			@ -324,17 +324,17 @@ int counter_tryextract(
 | 
			
		|||
			return 24;
 | 
			
		||||
		count_reg = *cey_loads.begin();
 | 
			
		||||
 | 
			
		||||
		if(sigmap(cemux->getPort(ID::Y)) != sigmap(count_reg->getPort(ID(D))))
 | 
			
		||||
		if(sigmap(cemux->getPort(ID::Y)) != sigmap(count_reg->getPort(ID::D)))
 | 
			
		||||
			return 24;
 | 
			
		||||
		//Mux should have A driven by count Q, and B by muxy
 | 
			
		||||
		//if A and B are swapped, CE polarity is inverted
 | 
			
		||||
		if(sigmap(cemux->getPort(ID::B)) == muxy && 
 | 
			
		||||
			sigmap(cemux->getPort(ID::A)) == sigmap(count_reg->getPort(ID(Q))))
 | 
			
		||||
			sigmap(cemux->getPort(ID::A)) == sigmap(count_reg->getPort(ID::Q)))
 | 
			
		||||
		{
 | 
			
		||||
			extract.ce_inverted = false;
 | 
			
		||||
		}
 | 
			
		||||
		else if(sigmap(cemux->getPort(ID::A)) == muxy && 
 | 
			
		||||
				sigmap(cemux->getPort(ID::B)) == sigmap(count_reg->getPort(ID(Q))))
 | 
			
		||||
				sigmap(cemux->getPort(ID::B)) == sigmap(count_reg->getPort(ID::Q)))
 | 
			
		||||
		{
 | 
			
		||||
			extract.ce_inverted = true;
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -345,7 +345,7 @@ int counter_tryextract(
 | 
			
		|||
 | 
			
		||||
		//Select of the mux is our clock enable
 | 
			
		||||
		extract.has_ce = true;
 | 
			
		||||
		extract.ce = sigmap(cemux->getPort(ID(S)));
 | 
			
		||||
		extract.ce = sigmap(cemux->getPort(ID::S));
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		extract.has_ce = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -361,10 +361,10 @@ int counter_tryextract(
 | 
			
		|||
		extract.has_reset = true;
 | 
			
		||||
 | 
			
		||||
		//Check polarity of reset - we may have to add an inverter later on!
 | 
			
		||||
		extract.rst_inverted = (count_reg->getParam(ID(ARST_POLARITY)).as_int() != 1);
 | 
			
		||||
		extract.rst_inverted = (count_reg->getParam(ID::ARST_POLARITY).as_int() != 1);
 | 
			
		||||
 | 
			
		||||
		//Verify ARST_VALUE is zero or full scale
 | 
			
		||||
		int rst_value = count_reg->getParam(ID(ARST_VALUE)).as_int();
 | 
			
		||||
		int rst_value = count_reg->getParam(ID::ARST_VALUE).as_int();
 | 
			
		||||
		if(rst_value == 0)
 | 
			
		||||
			extract.rst_to_max = false;
 | 
			
		||||
		else if(rst_value == extract.count_value)
 | 
			
		||||
| 
						 | 
				
			
			@ -373,7 +373,7 @@ int counter_tryextract(
 | 
			
		|||
			return 23;
 | 
			
		||||
 | 
			
		||||
		//Save the reset
 | 
			
		||||
		extract.rst = sigmap(count_reg->getPort(ID(ARST)));
 | 
			
		||||
		extract.rst = sigmap(count_reg->getPort(ID::ARST));
 | 
			
		||||
	}
 | 
			
		||||
	//TODO: support synchronous reset
 | 
			
		||||
	else
 | 
			
		||||
| 
						 | 
				
			
			@ -386,10 +386,10 @@ int counter_tryextract(
 | 
			
		|||
			return 16;
 | 
			
		||||
		if(extract.ce_inverted && !is_full_bus(muxy, index, count_mux, ID::Y, cemux, ID::A))
 | 
			
		||||
			return 16;
 | 
			
		||||
		if(!is_full_bus(cey, index, cemux, ID::Y, count_reg, ID(D)))
 | 
			
		||||
		if(!is_full_bus(cey, index, cemux, ID::Y, count_reg, ID::D))
 | 
			
		||||
			return 16;
 | 
			
		||||
	}
 | 
			
		||||
	else if(!is_full_bus(muxy, index, count_mux, ID::Y, count_reg, ID(D)))
 | 
			
		||||
	else if(!is_full_bus(muxy, index, count_mux, ID::Y, count_reg, ID::D))
 | 
			
		||||
		return 16;
 | 
			
		||||
 | 
			
		||||
	//TODO: Verify count_reg CLK_POLARITY is 1
 | 
			
		||||
| 
						 | 
				
			
			@ -397,7 +397,7 @@ int counter_tryextract(
 | 
			
		|||
	//Register output must have exactly two loads, the inverter and ALU
 | 
			
		||||
	//(unless we have a parallel output!)
 | 
			
		||||
	//If we have a clock enable, 3 is OK
 | 
			
		||||
	const RTLIL::SigSpec qport = count_reg->getPort(ID(Q));
 | 
			
		||||
	const RTLIL::SigSpec qport = count_reg->getPort(ID::Q);
 | 
			
		||||
	extract.poutsig = qport;
 | 
			
		||||
	extract.has_pout = false;
 | 
			
		||||
	const RTLIL::SigSpec cnout = sigmap(qport);
 | 
			
		||||
| 
						 | 
				
			
			@ -450,12 +450,12 @@ int counter_tryextract(
 | 
			
		|||
	}
 | 
			
		||||
	if(!extract.count_is_up)
 | 
			
		||||
	{
 | 
			
		||||
		if(!is_full_bus(cnout, index, count_reg, ID(Q), overflow_cell, ID::A, true))
 | 
			
		||||
		if(!is_full_bus(cnout, index, count_reg, ID::Q, overflow_cell, ID::A, true))
 | 
			
		||||
			return 18;
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
		if(is_full_bus(cnout, index, count_reg, ID(Q), overflow_cell, ID::A, true))
 | 
			
		||||
		if(is_full_bus(cnout, index, count_reg, ID::Q, overflow_cell, ID::A, true))
 | 
			
		||||
		{
 | 
			
		||||
			// B must be the overflow value
 | 
			
		||||
			const RTLIL::SigSpec overflow = sigmap(overflow_cell->getPort(ID::B));
 | 
			
		||||
| 
						 | 
				
			
			@ -463,7 +463,7 @@ int counter_tryextract(
 | 
			
		|||
				return 12;
 | 
			
		||||
			extract.count_value = overflow.as_int();
 | 
			
		||||
		}
 | 
			
		||||
		else if(is_full_bus(cnout, index, count_reg, ID(Q), overflow_cell, ID::B, true))
 | 
			
		||||
		else if(is_full_bus(cnout, index, count_reg, ID::Q, overflow_cell, ID::B, true))
 | 
			
		||||
		{
 | 
			
		||||
			// A must be the overflow value
 | 
			
		||||
			const RTLIL::SigSpec overflow = sigmap(overflow_cell->getPort(ID::A));
 | 
			
		||||
| 
						 | 
				
			
			@ -476,21 +476,21 @@ int counter_tryextract(
 | 
			
		|||
			return 18;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if(alu_port_use_a && !is_full_bus(cnout, index, count_reg, ID(Q), cell, ID::A, true))
 | 
			
		||||
	if(alu_port_use_a && !is_full_bus(cnout, index, count_reg, ID::Q, cell, ID::A, true))
 | 
			
		||||
		return 19;
 | 
			
		||||
	if(!alu_port_use_a && !is_full_bus(cnout, index, count_reg, ID(Q), cell, ID::B, true))
 | 
			
		||||
	if(!alu_port_use_a && !is_full_bus(cnout, index, count_reg, ID::Q, cell, ID::B, true))
 | 
			
		||||
		return 19;
 | 
			
		||||
 | 
			
		||||
	//Look up the clock from the register
 | 
			
		||||
	extract.clk = sigmap(count_reg->getPort(ID(CLK)));
 | 
			
		||||
	extract.clk = sigmap(count_reg->getPort(ID::CLK));
 | 
			
		||||
 | 
			
		||||
	if(!extract.count_is_up)
 | 
			
		||||
	{
 | 
			
		||||
		//Register output net must have an INIT attribute equal to the count value
 | 
			
		||||
		extract.rwire = cnout.as_wire();
 | 
			
		||||
		if(extract.rwire->attributes.find(ID(init)) == extract.rwire->attributes.end())
 | 
			
		||||
		if(extract.rwire->attributes.find(ID::init) == extract.rwire->attributes.end())
 | 
			
		||||
			return 20;
 | 
			
		||||
		int rinit = extract.rwire->attributes[ID(init)].as_int();
 | 
			
		||||
		int rinit = extract.rwire->attributes[ID::init].as_int();
 | 
			
		||||
		if(rinit != extract.count_value)
 | 
			
		||||
			return 21;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -498,9 +498,9 @@ int counter_tryextract(
 | 
			
		|||
	{
 | 
			
		||||
		//Register output net must not have an INIT attribute or it must be zero
 | 
			
		||||
		extract.rwire = cnout.as_wire();
 | 
			
		||||
		if(extract.rwire->attributes.find(ID(init)) == extract.rwire->attributes.end())
 | 
			
		||||
		if(extract.rwire->attributes.find(ID::init) == extract.rwire->attributes.end())
 | 
			
		||||
			return 0;
 | 
			
		||||
		int rinit = extract.rwire->attributes[ID(init)].as_int();
 | 
			
		||||
		int rinit = extract.rwire->attributes[ID::init].as_int();
 | 
			
		||||
		if(rinit != 0)
 | 
			
		||||
			return 21;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -534,7 +534,7 @@ void counter_worker(
 | 
			
		|||
	RTLIL::Wire* port_wire = port.as_wire();
 | 
			
		||||
	bool force_extract = false;
 | 
			
		||||
	bool never_extract = false;
 | 
			
		||||
	string count_reg_src = port_wire->attributes[ID(src)].decode_string().c_str();
 | 
			
		||||
	string count_reg_src = port_wire->attributes[ID::src].decode_string().c_str();
 | 
			
		||||
	if(port_wire->attributes.find(ID(COUNT_EXTRACT)) != port_wire->attributes.end())
 | 
			
		||||
	{
 | 
			
		||||
		pool<string> sa = port_wire->get_strpool_attribute(ID(COUNT_EXTRACT));
 | 
			
		||||
| 
						 | 
				
			
			@ -618,16 +618,16 @@ void counter_worker(
 | 
			
		|||
	//Wipe all of the old connections to the ALU
 | 
			
		||||
	cell->unsetPort(ID::A);
 | 
			
		||||
	cell->unsetPort(ID::B);
 | 
			
		||||
	cell->unsetPort(ID(BI));
 | 
			
		||||
	cell->unsetPort(ID(CI));
 | 
			
		||||
	cell->unsetPort(ID(CO));
 | 
			
		||||
	cell->unsetPort(ID(X));
 | 
			
		||||
	cell->unsetPort(ID::BI);
 | 
			
		||||
	cell->unsetPort(ID::CI);
 | 
			
		||||
	cell->unsetPort(ID::CO);
 | 
			
		||||
	cell->unsetPort(ID::X);
 | 
			
		||||
	cell->unsetPort(ID::Y);
 | 
			
		||||
	cell->unsetParam(ID(A_SIGNED));
 | 
			
		||||
	cell->unsetParam(ID(A_WIDTH));
 | 
			
		||||
	cell->unsetParam(ID(B_SIGNED));
 | 
			
		||||
	cell->unsetParam(ID(B_WIDTH));
 | 
			
		||||
	cell->unsetParam(ID(Y_WIDTH));
 | 
			
		||||
	cell->unsetParam(ID::A_SIGNED);
 | 
			
		||||
	cell->unsetParam(ID::A_WIDTH);
 | 
			
		||||
	cell->unsetParam(ID::B_SIGNED);
 | 
			
		||||
	cell->unsetParam(ID::B_WIDTH);
 | 
			
		||||
	cell->unsetParam(ID::Y_WIDTH);
 | 
			
		||||
 | 
			
		||||
	//Change the cell type
 | 
			
		||||
	cell->type = ID($__COUNT_);
 | 
			
		||||
| 
						 | 
				
			
			@ -657,8 +657,8 @@ void counter_worker(
 | 
			
		|||
	//Hook up other stuff
 | 
			
		||||
	//cell->setParam(ID(CLKIN_DIVIDE), RTLIL::Const(1));
 | 
			
		||||
	cell->setParam(ID(COUNT_TO), RTLIL::Const(extract.count_value));
 | 
			
		||||
	cell->setParam(ID(WIDTH), RTLIL::Const(extract.width));
 | 
			
		||||
	cell->setPort(ID(CLK), extract.clk);
 | 
			
		||||
	cell->setParam(ID::WIDTH, RTLIL::Const(extract.width));
 | 
			
		||||
	cell->setPort(ID::CLK, extract.clk);
 | 
			
		||||
	cell->setPort(ID(OUT), extract.outsig);
 | 
			
		||||
 | 
			
		||||
	//Hook up clock enable
 | 
			
		||||
| 
						 | 
				
			
			@ -747,7 +747,7 @@ void counter_worker(
 | 
			
		|||
		int newbits = ceil(log2(extract.count_value));
 | 
			
		||||
		if(extract.width != newbits)
 | 
			
		||||
		{
 | 
			
		||||
			cell->setParam(ID(WIDTH), RTLIL::Const(newbits));
 | 
			
		||||
			cell->setParam(ID::WIDTH, RTLIL::Const(newbits));
 | 
			
		||||
			log("    Optimizing out %d unused high-order bits (new width is %d)\n",
 | 
			
		||||
				extract.width - newbits,
 | 
			
		||||
				newbits);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -262,7 +262,7 @@ struct ExtractFaWorker
 | 
			
		|||
			pool<SigBit> new_leaves = leaves;
 | 
			
		||||
 | 
			
		||||
			new_leaves.erase(bit);
 | 
			
		||||
			for (auto port : {ID::A, ID::B, ID(C), ID(D)}) {
 | 
			
		||||
			for (auto port : {ID::A, ID::B, ID::C, ID::D}) {
 | 
			
		||||
				if (!cell->hasPort(port))
 | 
			
		||||
					continue;
 | 
			
		||||
				auto bit = sigmap(SigBit(cell->getPort(port)));
 | 
			
		||||
| 
						 | 
				
			
			@ -395,18 +395,18 @@ struct ExtractFaWorker
 | 
			
		|||
				else
 | 
			
		||||
				{
 | 
			
		||||
					Cell *cell = module->addCell(NEW_ID, ID($fa));
 | 
			
		||||
					cell->setParam(ID(WIDTH), 1);
 | 
			
		||||
					cell->setParam(ID::WIDTH, 1);
 | 
			
		||||
 | 
			
		||||
					log("      Created $fa cell %s.\n", log_id(cell));
 | 
			
		||||
 | 
			
		||||
					cell->setPort(ID::A, f3i.inv_a ? module->NotGate(NEW_ID, A) : A);
 | 
			
		||||
					cell->setPort(ID::B, f3i.inv_b ? module->NotGate(NEW_ID, B) : B);
 | 
			
		||||
					cell->setPort(ID(C), f3i.inv_c ? module->NotGate(NEW_ID, C) : C);
 | 
			
		||||
					cell->setPort(ID::C, f3i.inv_c ? module->NotGate(NEW_ID, C) : C);
 | 
			
		||||
 | 
			
		||||
					X = module->addWire(NEW_ID);
 | 
			
		||||
					Y = module->addWire(NEW_ID);
 | 
			
		||||
 | 
			
		||||
					cell->setPort(ID(X), X);
 | 
			
		||||
					cell->setPort(ID::X, X);
 | 
			
		||||
					cell->setPort(ID::Y, Y);
 | 
			
		||||
 | 
			
		||||
					facache[fakey] = make_tuple(X, Y, cell);
 | 
			
		||||
| 
						 | 
				
			
			@ -501,18 +501,18 @@ struct ExtractFaWorker
 | 
			
		|||
				else
 | 
			
		||||
				{
 | 
			
		||||
					Cell *cell = module->addCell(NEW_ID, ID($fa));
 | 
			
		||||
					cell->setParam(ID(WIDTH), 1);
 | 
			
		||||
					cell->setParam(ID::WIDTH, 1);
 | 
			
		||||
 | 
			
		||||
					log("      Created $fa cell %s.\n", log_id(cell));
 | 
			
		||||
 | 
			
		||||
					cell->setPort(ID::A, f2i.inv_a ? module->NotGate(NEW_ID, A) : A);
 | 
			
		||||
					cell->setPort(ID::B, f2i.inv_b ? module->NotGate(NEW_ID, B) : B);
 | 
			
		||||
					cell->setPort(ID(C), State::S0);
 | 
			
		||||
					cell->setPort(ID::C, State::S0);
 | 
			
		||||
 | 
			
		||||
					X = module->addWire(NEW_ID);
 | 
			
		||||
					Y = module->addWire(NEW_ID);
 | 
			
		||||
 | 
			
		||||
					cell->setPort(ID(X), X);
 | 
			
		||||
					cell->setPort(ID::X, X);
 | 
			
		||||
					cell->setPort(ID::Y, Y);
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -294,9 +294,9 @@ struct ExtractReducePass : public Pass
 | 
			
		|||
							gt == GateType::And ? ID($reduce_and) :
 | 
			
		||||
							gt == GateType::Or ? ID($reduce_or) :
 | 
			
		||||
							gt == GateType::Xor ? ID($reduce_xor) : "");
 | 
			
		||||
						new_reduce_cell->setParam(ID(A_SIGNED), 0);
 | 
			
		||||
						new_reduce_cell->setParam(ID(A_WIDTH), input.size());
 | 
			
		||||
						new_reduce_cell->setParam(ID(Y_WIDTH), 1);
 | 
			
		||||
						new_reduce_cell->setParam(ID::A_SIGNED, 0);
 | 
			
		||||
						new_reduce_cell->setParam(ID::A_WIDTH, input.size());
 | 
			
		||||
						new_reduce_cell->setParam(ID::Y_WIDTH, 1);
 | 
			
		||||
						new_reduce_cell->setPort(ID::A, input);
 | 
			
		||||
						new_reduce_cell->setPort(ID::Y, output);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,7 +90,7 @@ struct ExtractinvPass : public Pass {
 | 
			
		|||
				auto cell_wire = cell_module->wire(port.first);
 | 
			
		||||
				if (!cell_wire)
 | 
			
		||||
					continue;
 | 
			
		||||
				auto it = cell_wire->attributes.find("\\invertible_pin");
 | 
			
		||||
				auto it = cell_wire->attributes.find(ID::invertible_pin);
 | 
			
		||||
				if (it == cell_wire->attributes.end())
 | 
			
		||||
					continue;
 | 
			
		||||
				IdString param_name = RTLIL::escape_id(it->second.decode_string());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1413,7 +1413,7 @@ struct FlowmapWorker
 | 
			
		|||
			for (auto gate_node : lut_gates[node])
 | 
			
		||||
			{
 | 
			
		||||
				auto gate_origin = node_origins[gate_node];
 | 
			
		||||
				lut->add_strpool_attribute(ID(src), gate_origin.cell->get_strpool_attribute(ID(src)));
 | 
			
		||||
				lut->add_strpool_attribute(ID::src, gate_origin.cell->get_strpool_attribute(ID::src));
 | 
			
		||||
				packed_count++;
 | 
			
		||||
			}
 | 
			
		||||
			lut_count++;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue