mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Move implementation to constmap and add test
This commit is contained in:
		
							parent
							
								
									1113c8c95a
								
							
						
					
					
						commit
						7bbdf6049a
					
				
					 4 changed files with 129 additions and 38 deletions
				
			
		|  | @ -53,6 +53,7 @@ OBJS += passes/techmap/flowmap.o | |||
| OBJS += passes/techmap/extractinv.o | ||||
| OBJS += passes/techmap/cellmatch.o | ||||
| OBJS += passes/techmap/clockgate.o | ||||
| OBJS += passes/techmap/constmap.o | ||||
| endif | ||||
| 
 | ||||
| ifeq ($(DISABLE_SPAWN),0) | ||||
|  |  | |||
							
								
								
									
										82
									
								
								passes/techmap/constmap.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								passes/techmap/constmap.cc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,82 @@ | |||
| /*
 | ||||
|  *  yosys -- Yosys Open SYnthesis Suite | ||||
|  * | ||||
|  *  Copyright (C) 2025  King Lok Chung <king.chung@manchester.ac.uk> | ||||
|  * | ||||
|  *  Permission to use, copy, modify, and/or distribute this software for any | ||||
|  *  purpose with or without fee is hereby granted, provided that the above | ||||
|  *  copyright notice and this permission notice appear in all copies. | ||||
|  * | ||||
|  *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||
|  *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||
|  *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||
|  *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||
|  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||
|  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||||
|  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||
|  * | ||||
|  */ | ||||
| 
 | ||||
| #include "kernel/register.h" | ||||
| #include "kernel/rtlil.h" | ||||
| #include "kernel/log.h" | ||||
| 
 | ||||
| USING_YOSYS_NAMESPACE | ||||
| PRIVATE_NAMESPACE_BEGIN | ||||
| 
 | ||||
| static std::string celltype, cell_portname, cell_paramname; | ||||
| 
 | ||||
| static RTLIL::Module *module; | ||||
| static RTLIL::SigChunk value; | ||||
| 
 | ||||
| void constmap_worker(RTLIL::SigSpec &sig) | ||||
| { | ||||
| 	if (sig.is_fully_const()){ | ||||
| 		value = module->addWire(NEW_ID, sig.size()); | ||||
| 		RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(celltype)); | ||||
| 		cell->setParam(RTLIL::escape_id(cell_paramname), sig.as_const()); | ||||
| 		cell->setPort(RTLIL::escape_id(cell_portname), value); | ||||
| 		sig = value; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| struct ConstmapPass : public Pass { | ||||
| 	ConstmapPass() : Pass("constmap", "technology mapping of coarse constant value") { } | ||||
| 	void help() override | ||||
| 	{ | ||||
| 		log("\n"); | ||||
| 		log("    constmap [options] [selection]\n"); | ||||
| 		log("\n"); | ||||
| 		log("Map constants to a driver cell.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -cell <celltype> <portname> <paramname>\n"); | ||||
| 		log("        Replace constant bits with this cell.\n"); | ||||
| 		log("        The value of the constant will be stored to the parameter specified.\n"); | ||||
| 		log("\n"); | ||||
| 	} | ||||
| 	void execute(std::vector<std::string> args, RTLIL::Design *design) override | ||||
| 	{ | ||||
| 		log_header(design, "Executing CONSTMAP pass (mapping to constant driver).\n"); | ||||
| 
 | ||||
| 		size_t argidx; | ||||
| 		for (argidx = 1; argidx < args.size(); argidx++) | ||||
| 		{ | ||||
| 			if (args[argidx] == "-cell" && argidx+3 < args.size()){ | ||||
| 				celltype = args[++argidx]; | ||||
| 				cell_portname = args[++argidx]; | ||||
| 				cell_paramname = args[++argidx]; | ||||
| 				continue; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 		extra_args(args, argidx, design); | ||||
| 
 | ||||
| 		for (auto mod : design->selected_modules()) | ||||
| 		{ | ||||
| 			module = mod; | ||||
| 			module->rewrite_sigspecs(constmap_worker); | ||||
| 		} | ||||
| 	} | ||||
| } HilomapPass; | ||||
| 
 | ||||
| PRIVATE_NAMESPACE_END | ||||
|  | @ -26,41 +26,29 @@ PRIVATE_NAMESPACE_BEGIN | |||
| 
 | ||||
| static std::string hicell_celltype, hicell_portname; | ||||
| static std::string locell_celltype, locell_portname; | ||||
| static std::string fullcell_celltype, fullcell_portname, fullcell_paramname; | ||||
| static bool singleton_mode; | ||||
| static bool multi_bit; | ||||
| 
 | ||||
| static RTLIL::Module *module; | ||||
| static RTLIL::SigBit last_hi, last_lo; | ||||
| static RTLIL::SigChunk value; | ||||
| 
 | ||||
| void hilomap_worker(RTLIL::SigSpec &sig) | ||||
| { | ||||
| 	if (multi_bit && sig.is_fully_const()){ | ||||
| 		value = module->addWire(NEW_ID, sig.size()); | ||||
| 		RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(fullcell_celltype)); | ||||
| 		cell->setParam(RTLIL::escape_id(fullcell_paramname), sig.as_const()); | ||||
| 		cell->setPort(RTLIL::escape_id(fullcell_portname), value); | ||||
| 		sig = value; | ||||
| 	} | ||||
| 	else{ | ||||
| 		for (auto &bit : sig) { | ||||
| 			if (bit == RTLIL::State::S1 && !hicell_celltype.empty()) { | ||||
| 				if (!singleton_mode || last_hi == RTLIL::State::Sm) { | ||||
| 					last_hi = module->addWire(NEW_ID); | ||||
| 					RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(hicell_celltype)); | ||||
| 					cell->setPort(RTLIL::escape_id(hicell_portname), last_hi); | ||||
| 				} | ||||
| 				bit = last_hi; | ||||
| 	for (auto &bit : sig) { | ||||
| 		if (bit == RTLIL::State::S1 && !hicell_celltype.empty()) { | ||||
| 			if (!singleton_mode || last_hi == RTLIL::State::Sm) { | ||||
| 				last_hi = module->addWire(NEW_ID); | ||||
| 				RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(hicell_celltype)); | ||||
| 				cell->setPort(RTLIL::escape_id(hicell_portname), last_hi); | ||||
| 			} | ||||
| 			if (bit == RTLIL::State::S0 && !locell_celltype.empty()) { | ||||
| 				if (!singleton_mode || last_lo == RTLIL::State::Sm) { | ||||
| 					last_lo = module->addWire(NEW_ID); | ||||
| 					RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(locell_celltype)); | ||||
| 					cell->setPort(RTLIL::escape_id(locell_portname), last_lo); | ||||
| 				} | ||||
| 				bit = last_lo; | ||||
| 			bit = last_hi; | ||||
| 		} | ||||
| 		if (bit == RTLIL::State::S0 && !locell_celltype.empty()) { | ||||
| 			if (!singleton_mode || last_lo == RTLIL::State::Sm) { | ||||
| 				last_lo = module->addWire(NEW_ID); | ||||
| 				RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(locell_celltype)); | ||||
| 				cell->setPort(RTLIL::escape_id(locell_portname), last_lo); | ||||
| 			} | ||||
| 			bit = last_lo; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -80,10 +68,6 @@ struct HilomapPass : public Pass { | |||
| 		log("    -locell <celltype> <portname>\n"); | ||||
| 		log("        Replace constant lo bits with this cell.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -wrap <celltype> <portname> <paramname>\n"); | ||||
| 		log("        Replace constant bits with this cell.\n"); | ||||
| 		log("        The value of the constant will be stored to the parameter specified.\n"); | ||||
| 		log("\n"); | ||||
| 		log("    -singleton\n"); | ||||
| 		log("        Create only one hi/lo cell and connect all constant bits\n"); | ||||
| 		log("        to that cell. Per default a separate cell is created for\n"); | ||||
|  | @ -99,7 +83,7 @@ struct HilomapPass : public Pass { | |||
| 		locell_celltype = std::string(); | ||||
| 		locell_portname = std::string(); | ||||
| 		singleton_mode = false; | ||||
| 		multi_bit = false; | ||||
| 
 | ||||
| 		size_t argidx; | ||||
| 		for (argidx = 1; argidx < args.size(); argidx++) | ||||
| 		{ | ||||
|  | @ -113,13 +97,6 @@ struct HilomapPass : public Pass { | |||
| 				locell_portname = args[++argidx]; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-wrap" && argidx+3 < args.size()){ | ||||
| 				fullcell_celltype = args[++argidx]; | ||||
| 				fullcell_portname = args[++argidx]; | ||||
| 				fullcell_paramname = args[++argidx]; | ||||
| 				multi_bit = true; | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (args[argidx] == "-singleton") { | ||||
| 				singleton_mode = true; | ||||
| 				continue; | ||||
|  |  | |||
							
								
								
									
										31
									
								
								tests/techmap/constmap.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								tests/techmap/constmap.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,31 @@ | |||
| read_verilog << EOT | ||||
| 
 | ||||
| module test(); | ||||
|   wire [31:0] in; | ||||
|   wire [31:0] out; | ||||
|   assign out = in + 16; | ||||
| endmodule | ||||
| 
 | ||||
| EOT | ||||
| 
 | ||||
| constmap -cell const_cell O value | ||||
| select -assert-count 1 t:const_cell | ||||
| select -assert-count 1 r:value=16 | ||||
| 
 | ||||
| design -reset | ||||
| read_verilog << EOT | ||||
| 
 | ||||
| module test(); | ||||
|   wire [31:0] in; | ||||
|   wire [31:0] out1; | ||||
|   wire [31:0] out2; | ||||
|   assign out1 = in + 16; | ||||
|   assign out2 = in + 32; | ||||
| endmodule | ||||
| 
 | ||||
| EOT | ||||
| 
 | ||||
| constmap -cell const_cell O value | ||||
| select -assert-count 2 t:const_cell | ||||
| select -assert-count 1 r:value=16 | ||||
| select -assert-count 1 r:value=32 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue