mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	opt_lut: refactor to use a worker. NFC.
This commit is contained in:
		
							parent
							
								
									ea4870b126
								
							
						
					
					
						commit
						e54c7e951c
					
				
					 1 changed files with 186 additions and 179 deletions
				
			
		| 
						 | 
					@ -24,223 +24,228 @@
 | 
				
			||||||
USING_YOSYS_NAMESPACE
 | 
					USING_YOSYS_NAMESPACE
 | 
				
			||||||
PRIVATE_NAMESPACE_BEGIN
 | 
					PRIVATE_NAMESPACE_BEGIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool evaluate_lut(SigMap &sigmap, RTLIL::Cell *lut, dict<SigBit, bool> inputs)
 | 
					struct OptLutWorker
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	SigSpec lut_input = sigmap(lut->getPort("\\A"));
 | 
						RTLIL::Module *module;
 | 
				
			||||||
	int lut_width = lut->getParam("\\WIDTH").as_int();
 | 
						ModIndex index;
 | 
				
			||||||
	Const lut_table = lut->getParam("\\LUT");
 | 
						SigMap sigmap;
 | 
				
			||||||
	int lut_index = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (int i = 0; i < lut_width; i++)
 | 
						bool evaluate_lut(RTLIL::Cell *lut, dict<SigBit, bool> inputs)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		SigBit input = sigmap(lut_input[i]);
 | 
							SigSpec lut_input = sigmap(lut->getPort("\\A"));
 | 
				
			||||||
		if (inputs.count(input))
 | 
							int lut_width = lut->getParam("\\WIDTH").as_int();
 | 
				
			||||||
 | 
							Const lut_table = lut->getParam("\\LUT");
 | 
				
			||||||
 | 
							int lut_index = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (int i = 0; i < lut_width; i++)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			lut_index |= inputs[input] << i;
 | 
								SigBit input = sigmap(lut_input[i]);
 | 
				
			||||||
		}
 | 
								if (inputs.count(input))
 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			lut_index |= SigSpec(lut_input[i]).as_bool() << i;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return lut_table.extract(lut_index).as_int();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static void run_lut_opts(Module *module)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	ModIndex index(module);
 | 
					 | 
				
			||||||
	SigMap sigmap(module);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	log("Discovering LUTs.\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pool<RTLIL::Cell*> luts;
 | 
					 | 
				
			||||||
	dict<RTLIL::Cell*, int> luts_arity;
 | 
					 | 
				
			||||||
	for (auto cell : module->selected_cells())
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		if (cell->type == "$lut")
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			int lut_width = cell->getParam("\\WIDTH").as_int();
 | 
					 | 
				
			||||||
			SigSpec lut_input = cell->getPort("\\A");
 | 
					 | 
				
			||||||
			int lut_arity = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			for (auto &bit : lut_input)
 | 
					 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				if (bit.wire)
 | 
									lut_index |= inputs[input] << i;
 | 
				
			||||||
					lut_arity++;
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									lut_index |= SigSpec(lut_input[i]).as_bool() << i;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					 | 
				
			||||||
			log("Found $lut cell %s.%s with WIDTH=%d implementing %d-LUT.\n", log_id(module), log_id(cell), lut_width, lut_arity);
 | 
					 | 
				
			||||||
			luts.insert(cell);
 | 
					 | 
				
			||||||
			luts_arity[cell] = lut_arity;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return lut_table.extract(lut_index).as_int();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	log("\n");
 | 
						OptLutWorker(RTLIL::Module *module) :
 | 
				
			||||||
	log("Combining LUTs.\n");
 | 
							module(module), index(module), sigmap(module)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	pool<RTLIL::Cell*> worklist = luts;
 | 
					 | 
				
			||||||
	while (worklist.size())
 | 
					 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		auto lutA = worklist.pop();
 | 
							pool<RTLIL::Cell*> luts;
 | 
				
			||||||
		SigSpec lutA_input = sigmap(lutA->getPort("\\A"));
 | 
							dict<RTLIL::Cell*, int> luts_arity;
 | 
				
			||||||
		SigSpec lutA_output = sigmap(lutA->getPort("\\Y")[0]);
 | 
					 | 
				
			||||||
		int lutA_width = lutA->getParam("\\WIDTH").as_int();
 | 
					 | 
				
			||||||
		int lutA_arity = luts_arity[lutA];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto lutA_output_ports = index.query_ports(lutA->getPort("\\Y"));
 | 
							log("Discovering LUTs.\n");
 | 
				
			||||||
		if (lutA_output_ports.size() != 2)
 | 
							for (auto cell : module->selected_cells())
 | 
				
			||||||
			continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for (auto port : lutA_output_ports)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (port.cell == lutA)
 | 
								if (cell->type == "$lut")
 | 
				
			||||||
				continue;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (luts.count(port.cell))
 | 
					 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				auto lutB = port.cell;
 | 
									int lut_width = cell->getParam("\\WIDTH").as_int();
 | 
				
			||||||
				SigSpec lutB_input = sigmap(lutB->getPort("\\A"));
 | 
									SigSpec lut_input = cell->getPort("\\A");
 | 
				
			||||||
				SigSpec lutB_output = sigmap(lutB->getPort("\\Y")[0]);
 | 
									int lut_arity = 0;
 | 
				
			||||||
				int lutB_width = lutB->getParam("\\WIDTH").as_int();
 | 
					 | 
				
			||||||
				int lutB_arity = luts_arity[lutB];
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				log("Found %s.%s (cell A) feeding %s.%s (cell B).\n", log_id(module), log_id(lutA), log_id(module), log_id(lutB));
 | 
									for (auto &bit : lut_input)
 | 
				
			||||||
 | 
					 | 
				
			||||||
				pool<SigBit> lutA_inputs;
 | 
					 | 
				
			||||||
				pool<SigBit> lutB_inputs;
 | 
					 | 
				
			||||||
				for (auto &bit : lutA_input)
 | 
					 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					if (bit.wire)
 | 
										if (bit.wire)
 | 
				
			||||||
						lutA_inputs.insert(sigmap(bit));
 | 
											lut_arity++;
 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				for (auto &bit : lutB_input)
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					if(bit.wire)
 | 
					 | 
				
			||||||
						lutB_inputs.insert(sigmap(bit));
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				pool<SigBit> common_inputs;
 | 
									log("Found $lut cell %s.%s with WIDTH=%d implementing %d-LUT.\n", log_id(module), log_id(cell), lut_width, lut_arity);
 | 
				
			||||||
				for (auto &bit : lutA_inputs)
 | 
									luts.insert(cell);
 | 
				
			||||||
				{
 | 
									luts_arity[cell] = lut_arity;
 | 
				
			||||||
					if (lutB_inputs.count(bit))
 | 
								}
 | 
				
			||||||
						common_inputs.insert(bit);
 | 
							}
 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				int lutM_arity = lutA_arity + lutB_arity - 1 - common_inputs.size();
 | 
							log("\n");
 | 
				
			||||||
				log("  Cell A is a %d-LUT. Cell B is a %d-LUT. Cells share %zu input(s) and can be merged into one %d-LUT.\n", lutA_arity, lutB_arity, common_inputs.size(), lutM_arity);
 | 
							log("Combining LUTs.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				int combine = -1;
 | 
							pool<RTLIL::Cell*> worklist = luts;
 | 
				
			||||||
				if (combine == -1)
 | 
							while (worklist.size())
 | 
				
			||||||
				{
 | 
							{
 | 
				
			||||||
					if (lutM_arity > lutA_width)
 | 
								auto lutA = worklist.pop();
 | 
				
			||||||
					{
 | 
								SigSpec lutA_input = sigmap(lutA->getPort("\\A"));
 | 
				
			||||||
						log("  Not combining LUTs into cell A (combined LUT too wide).\n");
 | 
								SigSpec lutA_output = sigmap(lutA->getPort("\\Y")[0]);
 | 
				
			||||||
					}
 | 
								int lutA_width = lutA->getParam("\\WIDTH").as_int();
 | 
				
			||||||
					else if (lutB->get_bool_attribute("\\lut_keep"))
 | 
								int lutA_arity = luts_arity[lutA];
 | 
				
			||||||
					{
 | 
					 | 
				
			||||||
						log("  Not combining LUTs into cell A (cell B has attribute \\lut_keep).\n");
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					else combine = 0;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				if (combine == -1)
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					if (lutM_arity > lutB_width)
 | 
					 | 
				
			||||||
					{
 | 
					 | 
				
			||||||
						log("  Not combining LUTs into cell B (combined LUT too wide).\n");
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					else if (lutA->get_bool_attribute("\\lut_keep"))
 | 
					 | 
				
			||||||
					{
 | 
					 | 
				
			||||||
						log("  Not combining LUTs into cell B (cell A has attribute \\lut_keep).\n");
 | 
					 | 
				
			||||||
					}
 | 
					 | 
				
			||||||
					else combine = 1;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				RTLIL::Cell *lutM, *lutR;
 | 
								auto lutA_output_ports = index.query_ports(lutA->getPort("\\Y"));
 | 
				
			||||||
				pool<SigBit> lutM_inputs, lutR_inputs;
 | 
								if (lutA_output_ports.size() != 2)
 | 
				
			||||||
				if (combine == 0)
 | 
									continue;
 | 
				
			||||||
				{
 | 
					
 | 
				
			||||||
					log("  Combining LUTs into cell A.\n");
 | 
								for (auto port : lutA_output_ports)
 | 
				
			||||||
					lutM = lutA;
 | 
								{
 | 
				
			||||||
					lutM_inputs = lutA_inputs;
 | 
									if (port.cell == lutA)
 | 
				
			||||||
					lutR = lutB;
 | 
					 | 
				
			||||||
					lutR_inputs = lutB_inputs;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				else if (combine == 1)
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					log("  Combining LUTs into cell B.\n");
 | 
					 | 
				
			||||||
					lutM = lutB;
 | 
					 | 
				
			||||||
					lutM_inputs = lutB_inputs;
 | 
					 | 
				
			||||||
					lutR = lutA;
 | 
					 | 
				
			||||||
					lutR_inputs = lutA_inputs;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				else
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					log("  Cannot combine LUTs.\n");
 | 
					 | 
				
			||||||
					continue;
 | 
										continue;
 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				pool<SigBit> lutR_unique;
 | 
									if (luts.count(port.cell))
 | 
				
			||||||
				for (auto &bit : lutR_inputs)
 | 
					 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					if (!common_inputs.count(bit) && bit != lutA_output)
 | 
										auto lutB = port.cell;
 | 
				
			||||||
						lutR_unique.insert(bit);
 | 
										SigSpec lutB_input = sigmap(lutB->getPort("\\A"));
 | 
				
			||||||
				}
 | 
										SigSpec lutB_output = sigmap(lutB->getPort("\\Y")[0]);
 | 
				
			||||||
 | 
										int lutB_width = lutB->getParam("\\WIDTH").as_int();
 | 
				
			||||||
 | 
										int lutB_arity = luts_arity[lutB];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				int lutM_width = lutM->getParam("\\WIDTH").as_int();
 | 
										log("Found %s.%s (cell A) feeding %s.%s (cell B).\n", log_id(module), log_id(lutA), log_id(module), log_id(lutB));
 | 
				
			||||||
				SigSpec lutM_input = sigmap(lutM->getPort("\\A"));
 | 
					
 | 
				
			||||||
				std::vector<SigBit> lutM_new_inputs;
 | 
										pool<SigBit> lutA_inputs;
 | 
				
			||||||
				for (int i = 0; i < lutM_width; i++)
 | 
										pool<SigBit> lutB_inputs;
 | 
				
			||||||
				{
 | 
										for (auto &bit : lutA_input)
 | 
				
			||||||
					if ((!lutM_input[i].wire || sigmap(lutM_input[i]) == lutA_output) && lutR_unique.size())
 | 
					 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						SigBit new_input = lutR_unique.pop();
 | 
											if (bit.wire)
 | 
				
			||||||
						log("    Connecting input %d as %s.\n", i, log_signal(new_input));
 | 
												lutA_inputs.insert(sigmap(bit));
 | 
				
			||||||
						lutM_new_inputs.push_back(new_input);
 | 
					 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					else if (sigmap(lutM_input[i]) == lutA_output)
 | 
										for (auto &bit : lutB_input)
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						log("    Disconnecting input %d.\n", i);
 | 
											if(bit.wire)
 | 
				
			||||||
						lutM_new_inputs.push_back(SigBit());
 | 
												lutB_inputs.insert(sigmap(bit));
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										pool<SigBit> common_inputs;
 | 
				
			||||||
 | 
										for (auto &bit : lutA_inputs)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											if (lutB_inputs.count(bit))
 | 
				
			||||||
 | 
												common_inputs.insert(bit);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										int lutM_arity = lutA_arity + lutB_arity - 1 - common_inputs.size();
 | 
				
			||||||
 | 
										log("  Cell A is a %d-LUT. Cell B is a %d-LUT. Cells share %zu input(s) and can be merged into one %d-LUT.\n", lutA_arity, lutB_arity, common_inputs.size(), lutM_arity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										int combine = -1;
 | 
				
			||||||
 | 
										if (combine == -1)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											if (lutM_arity > lutA_width)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												log("  Not combining LUTs into cell A (combined LUT too wide).\n");
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											else if (lutB->get_bool_attribute("\\lut_keep"))
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												log("  Not combining LUTs into cell A (cell B has attribute \\lut_keep).\n");
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											else combine = 0;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (combine == -1)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											if (lutM_arity > lutB_width)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												log("  Not combining LUTs into cell B (combined LUT too wide).\n");
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											else if (lutA->get_bool_attribute("\\lut_keep"))
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												log("  Not combining LUTs into cell B (cell A has attribute \\lut_keep).\n");
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											else combine = 1;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										RTLIL::Cell *lutM, *lutR;
 | 
				
			||||||
 | 
										pool<SigBit> lutM_inputs, lutR_inputs;
 | 
				
			||||||
 | 
										if (combine == 0)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											log("  Combining LUTs into cell A.\n");
 | 
				
			||||||
 | 
											lutM = lutA;
 | 
				
			||||||
 | 
											lutM_inputs = lutA_inputs;
 | 
				
			||||||
 | 
											lutR = lutB;
 | 
				
			||||||
 | 
											lutR_inputs = lutB_inputs;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										else if (combine == 1)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											log("  Combining LUTs into cell B.\n");
 | 
				
			||||||
 | 
											lutM = lutB;
 | 
				
			||||||
 | 
											lutM_inputs = lutB_inputs;
 | 
				
			||||||
 | 
											lutR = lutA;
 | 
				
			||||||
 | 
											lutR_inputs = lutA_inputs;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					else
 | 
										else
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						log("    Leaving input %d as %s.\n", i, log_signal(lutM_input[i]));
 | 
											log("  Cannot combine LUTs.\n");
 | 
				
			||||||
						lutM_new_inputs.push_back(lutM_input[i]);
 | 
											continue;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				log_assert(lutR_unique.size() == 0);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				RTLIL::Const lutM_new_table(State::Sx, 1 << lutM_width);
 | 
										pool<SigBit> lutR_unique;
 | 
				
			||||||
				for (int eval = 0; eval < 1 << lutM_width; eval++)
 | 
										for (auto &bit : lutR_inputs)
 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					dict<SigBit, bool> eval_inputs;
 | 
					 | 
				
			||||||
					for (size_t i = 0; i < lutM_new_inputs.size(); i++)
 | 
					 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						eval_inputs[lutM_new_inputs[i]] = (eval >> i) & 1;
 | 
											if (!common_inputs.count(bit) && bit != lutA_output)
 | 
				
			||||||
 | 
												lutR_unique.insert(bit);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					eval_inputs[lutA_output] = evaluate_lut(sigmap, lutA, eval_inputs);
 | 
					
 | 
				
			||||||
					lutM_new_table[eval] = (RTLIL::State) evaluate_lut(sigmap, lutB, eval_inputs);
 | 
										int lutM_width = lutM->getParam("\\WIDTH").as_int();
 | 
				
			||||||
 | 
										SigSpec lutM_input = sigmap(lutM->getPort("\\A"));
 | 
				
			||||||
 | 
										std::vector<SigBit> lutM_new_inputs;
 | 
				
			||||||
 | 
										for (int i = 0; i < lutM_width; i++)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											if ((!lutM_input[i].wire || sigmap(lutM_input[i]) == lutA_output) && lutR_unique.size())
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												SigBit new_input = lutR_unique.pop();
 | 
				
			||||||
 | 
												log("    Connecting input %d as %s.\n", i, log_signal(new_input));
 | 
				
			||||||
 | 
												lutM_new_inputs.push_back(new_input);
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											else if (sigmap(lutM_input[i]) == lutA_output)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												log("    Disconnecting input %d.\n", i);
 | 
				
			||||||
 | 
												lutM_new_inputs.push_back(SigBit());
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											else
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												log("    Leaving input %d as %s.\n", i, log_signal(lutM_input[i]));
 | 
				
			||||||
 | 
												lutM_new_inputs.push_back(lutM_input[i]);
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										log_assert(lutR_unique.size() == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										RTLIL::Const lutM_new_table(State::Sx, 1 << lutM_width);
 | 
				
			||||||
 | 
										for (int eval = 0; eval < 1 << lutM_width; eval++)
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											dict<SigBit, bool> eval_inputs;
 | 
				
			||||||
 | 
											for (size_t i = 0; i < lutM_new_inputs.size(); i++)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												eval_inputs[lutM_new_inputs[i]] = (eval >> i) & 1;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
											eval_inputs[lutA_output] = evaluate_lut(lutA, eval_inputs);
 | 
				
			||||||
 | 
											lutM_new_table[eval] = (RTLIL::State) evaluate_lut(lutB, eval_inputs);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										log("  Old truth table: %s.\n", lutM->getParam("\\LUT").as_string().c_str());
 | 
				
			||||||
 | 
										log("  New truth table: %s.\n", lutM_new_table.as_string().c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										lutM->setParam("\\LUT", lutM_new_table);
 | 
				
			||||||
 | 
										lutM->setPort("\\A", lutM_new_inputs);
 | 
				
			||||||
 | 
										lutM->setPort("\\Y", lutB_output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										luts_arity[lutM] = lutM_arity;
 | 
				
			||||||
 | 
										luts.erase(lutR);
 | 
				
			||||||
 | 
										luts_arity.erase(lutR);
 | 
				
			||||||
 | 
										lutR->module->remove(lutR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										worklist.insert(lutM);
 | 
				
			||||||
 | 
										worklist.erase(lutR);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					 | 
				
			||||||
				log("  Old truth table: %s.\n", lutM->getParam("\\LUT").as_string().c_str());
 | 
					 | 
				
			||||||
				log("  New truth table: %s.\n", lutM_new_table.as_string().c_str());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				lutM->setParam("\\LUT", lutM_new_table);
 | 
					 | 
				
			||||||
				lutM->setPort("\\A", lutM_new_inputs);
 | 
					 | 
				
			||||||
				lutM->setPort("\\Y", lutB_output);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				luts_arity[lutM] = lutM_arity;
 | 
					 | 
				
			||||||
				luts.erase(lutR);
 | 
					 | 
				
			||||||
				luts_arity.erase(lutR);
 | 
					 | 
				
			||||||
				lutR->module->remove(lutR);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				worklist.insert(lutM);
 | 
					 | 
				
			||||||
				worklist.erase(lutR);
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct OptLutPass : public Pass {
 | 
					struct OptLutPass : public Pass {
 | 
				
			||||||
	OptLutPass() : Pass("opt_lut", "optimize LUT cells") { }
 | 
						OptLutPass() : Pass("opt_lut", "optimize LUT cells") { }
 | 
				
			||||||
| 
						 | 
					@ -267,7 +272,9 @@ struct OptLutPass : public Pass {
 | 
				
			||||||
		extra_args(args, argidx, design);
 | 
							extra_args(args, argidx, design);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (auto module : design->selected_modules())
 | 
							for (auto module : design->selected_modules())
 | 
				
			||||||
			run_lut_opts(module);
 | 
							{
 | 
				
			||||||
 | 
								OptLutWorker worker(module);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
} OptLutPass;
 | 
					} OptLutPass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue