mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 19:52:31 +00:00 
			
		
		
		
	Finished refactoring counter extraction to be nice and generic. Implemented techmapping from $__COUNT_ to GP_COUNTx cells.
This commit is contained in:
		
							parent
							
								
									46b01f05bb
								
							
						
					
					
						commit
						3fc1b9f3fd
					
				
					 3 changed files with 94 additions and 12 deletions
				
			
		|  | @ -105,15 +105,20 @@ struct CounterExtraction | ||||||
| //attempt to extract a counter centered on the given adder cell
 | //attempt to extract a counter centered on the given adder cell
 | ||||||
| //For now we only support DOWN counters.
 | //For now we only support DOWN counters.
 | ||||||
| //TODO: up/down support
 | //TODO: up/down support
 | ||||||
| int counter_tryextract(ModIndex& index, Cell *cell, CounterExtraction& extract, pool<RTLIL::IdString>& parallel_cells) | int counter_tryextract( | ||||||
|  | 	ModIndex& index, | ||||||
|  | 	Cell *cell, | ||||||
|  | 	CounterExtraction& extract, | ||||||
|  | 	pool<RTLIL::IdString>& parallel_cells, | ||||||
|  | 	int maxwidth) | ||||||
| { | { | ||||||
| 	SigMap& sigmap = index.sigmap; | 	SigMap& sigmap = index.sigmap; | ||||||
| 
 | 
 | ||||||
| 	//A counter with less than 2 bits makes no sense
 | 	//A counter with less than 2 bits makes no sense
 | ||||||
| 	//TODO: configurable min/max thresholds
 | 	//TODO: configurable min threshold
 | ||||||
| 	int a_width = cell->getParam("\\A_WIDTH").as_int(); | 	int a_width = cell->getParam("\\A_WIDTH").as_int(); | ||||||
| 	extract.width = a_width; | 	extract.width = a_width; | ||||||
| 	if(a_width < 2) | 	if( (a_width < 2) || (a_width > maxwidth) ) | ||||||
| 		return 1; | 		return 1; | ||||||
| 
 | 
 | ||||||
| 	//Second input must be a single bit
 | 	//Second input must be a single bit
 | ||||||
|  | @ -287,7 +292,8 @@ void counter_worker( | ||||||
| 	unsigned int& total_counters, | 	unsigned int& total_counters, | ||||||
| 	pool<Cell*>& cells_to_remove, | 	pool<Cell*>& cells_to_remove, | ||||||
| 	pool<pair<Cell*, string>>& cells_to_rename, | 	pool<pair<Cell*, string>>& cells_to_rename, | ||||||
| 	pool<RTLIL::IdString>& parallel_cells) | 	pool<RTLIL::IdString>& parallel_cells, | ||||||
|  | 	int maxwidth) | ||||||
| { | { | ||||||
| 	SigMap& sigmap = index.sigmap; | 	SigMap& sigmap = index.sigmap; | ||||||
| 
 | 
 | ||||||
|  | @ -295,8 +301,6 @@ void counter_worker( | ||||||
| 	if (cell->type != "$alu") | 	if (cell->type != "$alu") | ||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	log("Looking at cell %s\n", cell->name.c_str()); |  | ||||||
| 
 |  | ||||||
| 	//A input is the count value. Check if it has COUNT_EXTRACT set.
 | 	//A input is the count value. Check if it has COUNT_EXTRACT set.
 | ||||||
| 	//If it's not a wire, don't even try
 | 	//If it's not a wire, don't even try
 | ||||||
| 	auto port = sigmap(cell->getPort("\\A")); | 	auto port = sigmap(cell->getPort("\\A")); | ||||||
|  | @ -336,7 +340,7 @@ void counter_worker( | ||||||
| 
 | 
 | ||||||
| 	//Attempt to extract a counter
 | 	//Attempt to extract a counter
 | ||||||
| 	CounterExtraction extract; | 	CounterExtraction extract; | ||||||
| 	int reason = counter_tryextract(index, cell, extract, parallel_cells); | 	int reason = counter_tryextract(index, cell, extract, parallel_cells, maxwidth); | ||||||
| 
 | 
 | ||||||
| 	//Nonzero code - we could not find a matchable counter.
 | 	//Nonzero code - we could not find a matchable counter.
 | ||||||
| 	//Do nothing, unless extraction was forced in which case give an error
 | 	//Do nothing, unless extraction was forced in which case give an error
 | ||||||
|  | @ -414,7 +418,7 @@ void counter_worker( | ||||||
| 	cell->unsetParam("\\Y_WIDTH"); | 	cell->unsetParam("\\Y_WIDTH"); | ||||||
| 
 | 
 | ||||||
| 	//Change the cell type
 | 	//Change the cell type
 | ||||||
| 	cell->type = "$__COUNT__"; | 	cell->type = "$__COUNT_"; | ||||||
| 
 | 
 | ||||||
| 	//Hook up resets
 | 	//Hook up resets
 | ||||||
| 	if(extract.has_reset) | 	if(extract.has_reset) | ||||||
|  | @ -432,13 +436,13 @@ void counter_worker( | ||||||
| 	//Hook up other stuff
 | 	//Hook up other stuff
 | ||||||
| 	//cell->setParam("\\CLKIN_DIVIDE", RTLIL::Const(1));
 | 	//cell->setParam("\\CLKIN_DIVIDE", RTLIL::Const(1));
 | ||||||
| 	cell->setParam("\\COUNT_TO", RTLIL::Const(extract.count_value)); | 	cell->setParam("\\COUNT_TO", RTLIL::Const(extract.count_value)); | ||||||
| 
 | 	cell->setParam("\\WIDTH", RTLIL::Const(extract.width)); | ||||||
| 	cell->setPort("\\CLK", extract.clk); | 	cell->setPort("\\CLK", extract.clk); | ||||||
| 	cell->setPort("\\OUT", extract.outsig); | 	cell->setPort("\\OUT", extract.outsig); | ||||||
| 
 | 
 | ||||||
| 	//Hook up hard-wired ports (for now CE and up/=down are not supported), default to no parallel output
 | 	//Hook up hard-wired ports (for now CE and up/=down are not supported), default to no parallel output
 | ||||||
| 	cell->setParam("\\HAS_POUT", RTLIL::Const(0)); | 	cell->setParam("\\HAS_POUT", RTLIL::Const(0)); | ||||||
| 	cell->setParam("\\HAS_CE", RTLIL::Const("NO")); | 	cell->setParam("\\HAS_CE", RTLIL::Const(0)); | ||||||
| 	cell->setParam("\\DIRECTION", RTLIL::Const("DOWN")); | 	cell->setParam("\\DIRECTION", RTLIL::Const("DOWN")); | ||||||
| 	cell->setPort("\\CE", RTLIL::Const(1)); | 	cell->setPort("\\CE", RTLIL::Const(1)); | ||||||
| 	cell->setPort("\\UP", RTLIL::Const(1)); | 	cell->setPort("\\UP", RTLIL::Const(1)); | ||||||
|  | @ -478,6 +482,8 @@ struct ExtractCounterPass : public Pass { | ||||||
| 		log("counter cells. Use a target-specific 'techmap' map file to convert those cells\n"); | 		log("counter cells. Use a target-specific 'techmap' map file to convert those cells\n"); | ||||||
| 		log("to the actual target cells.\n"); | 		log("to the actual target cells.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | 		log("    -maxwidth N\n"); | ||||||
|  | 		log("        Only extract counters up to N bits wide\n"); | ||||||
| 		log("    -pout X,Y,...\n"); | 		log("    -pout X,Y,...\n"); | ||||||
| 		log("        Only allow parallel output from the counter to the listed cell types\n"); | 		log("        Only allow parallel output from the counter to the listed cell types\n"); | ||||||
| 		log("        (if not specified, parallel outputs are not restricted)\n"); | 		log("        (if not specified, parallel outputs are not restricted)\n"); | ||||||
|  | @ -488,6 +494,7 @@ struct ExtractCounterPass : public Pass { | ||||||
| 	{ | 	{ | ||||||
| 		log_header(design, "Executing EXTRACT_COUNTER pass (find counters in netlist).\n"); | 		log_header(design, "Executing EXTRACT_COUNTER pass (find counters in netlist).\n"); | ||||||
| 
 | 
 | ||||||
|  | 		int maxwidth = 64; | ||||||
| 		size_t argidx; | 		size_t argidx; | ||||||
| 		pool<RTLIL::IdString> parallel_cells; | 		pool<RTLIL::IdString> parallel_cells; | ||||||
| 		for (argidx = 1; argidx < args.size(); argidx++) | 		for (argidx = 1; argidx < args.size(); argidx++) | ||||||
|  | @ -513,6 +520,13 @@ struct ExtractCounterPass : public Pass { | ||||||
| 						tmp += pouts[i]; | 						tmp += pouts[i]; | ||||||
| 				} | 				} | ||||||
| 				parallel_cells.insert(RTLIL::IdString(tmp)); | 				parallel_cells.insert(RTLIL::IdString(tmp)); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (args[argidx] == "-maxwidth" && argidx+1 < args.size()) | ||||||
|  | 			{ | ||||||
|  | 				maxwidth = atoi(args[++argidx].c_str()); | ||||||
|  | 				continue; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		extra_args(args, argidx, design); | 		extra_args(args, argidx, design); | ||||||
|  | @ -526,7 +540,7 @@ struct ExtractCounterPass : public Pass { | ||||||
| 
 | 
 | ||||||
| 			ModIndex index(module); | 			ModIndex index(module); | ||||||
| 			for (auto cell : module->selected_cells()) | 			for (auto cell : module->selected_cells()) | ||||||
| 				counter_worker(index, cell, total_counters, cells_to_remove, cells_to_rename, parallel_cells); | 				counter_worker(index, cell, total_counters, cells_to_remove, cells_to_rename, parallel_cells, maxwidth); | ||||||
| 
 | 
 | ||||||
| 			for(auto cell : cells_to_remove) | 			for(auto cell : cells_to_remove) | ||||||
| 			{ | 			{ | ||||||
|  |  | ||||||
|  | @ -144,3 +144,71 @@ module \$lut (A, Y); | ||||||
|     end |     end | ||||||
|   endgenerate |   endgenerate | ||||||
| endmodule | endmodule | ||||||
|  | 
 | ||||||
|  | module \$__COUNT_ (CE, CLK, OUT, POUT, RST, UP); | ||||||
|  | 
 | ||||||
|  | 	input wire CE; | ||||||
|  | 	input wire CLK; | ||||||
|  | 	output reg OUT; | ||||||
|  | 	output reg[WIDTH-1:0] POUT; | ||||||
|  | 	input wire RST; | ||||||
|  | 	input wire UP; | ||||||
|  | 
 | ||||||
|  | 	parameter COUNT_TO = 1; | ||||||
|  | 	parameter RESET_MODE = "RISING"; | ||||||
|  | 	parameter HAS_POUT = 0; | ||||||
|  | 	parameter HAS_CE = 0; | ||||||
|  | 	parameter WIDTH = 8; | ||||||
|  | 	parameter DIRECTION = "DOWN"; | ||||||
|  | 
 | ||||||
|  | 	//If we have a CE, or DIRECTION other than DOWN fail... GP_COUNTx_ADV is not supported yet | ||||||
|  | 	if(HAS_CE || (DIRECTION != "DOWN") ) begin | ||||||
|  | 		initial begin | ||||||
|  | 			$display("ERROR: \$__COUNT__ support for GP_COUNTx_ADV is not yet implemented. This counter should never have been extracted (bug in extract_counter pass?)."); | ||||||
|  | 			$finish; | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 
 | ||||||
|  | 	//If counter is more than 14 bits wide, complain (also shouldn't happen) | ||||||
|  | 	else if(WIDTH > 14) begin | ||||||
|  | 		initial begin | ||||||
|  | 			$display("ERROR: \$__COUNT__ support for cascaded counters is not yet implemented. This counter should never have been extracted (bug in extract_counter pass?)."); | ||||||
|  | 			$finish; | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 
 | ||||||
|  | 	//If counter is more than 8 bits wide and has parallel output, we have a problem | ||||||
|  | 	else if(WIDTH > 8 && HAS_POUT) begin | ||||||
|  | 		initial begin | ||||||
|  | 			$display("ERROR: \$__COUNT__ support for 9-14 bit counters with parallel output is not yet implemented. This counter should never have been extracted (bug in extract_counter pass?)."); | ||||||
|  | 			$finish; | ||||||
|  | 		end | ||||||
|  | 	end | ||||||
|  | 
 | ||||||
|  | 	//Looks like a legal counter! Do something with it | ||||||
|  | 	else if(WIDTH <= 8) begin | ||||||
|  | 		GP_COUNT8 #( | ||||||
|  | 			.COUNT_TO(COUNT_TO), | ||||||
|  | 			.RESET_MODE(RESET_MODE), | ||||||
|  | 			.CLKIN_DIVIDE(1) | ||||||
|  | 		) _TECHMAP_REPLACE_ ( | ||||||
|  | 			.CLK(CLK), | ||||||
|  | 			.RST(RST), | ||||||
|  | 			.OUT(OUT), | ||||||
|  | 			.POUT(POUT) | ||||||
|  | 		); | ||||||
|  | 	end | ||||||
|  | 
 | ||||||
|  | 	else begin | ||||||
|  | 		GP_COUNT14 #( | ||||||
|  | 			.COUNT_TO(COUNT_TO), | ||||||
|  | 			.RESET_MODE(RESET_MODE), | ||||||
|  | 			.CLKIN_DIVIDE(1) | ||||||
|  | 		) _TECHMAP_REPLACE_ ( | ||||||
|  | 			.CLK(CLK), | ||||||
|  | 			.RST(RST), | ||||||
|  | 			.OUT(OUT) | ||||||
|  | 		); | ||||||
|  | 	end | ||||||
|  | 
 | ||||||
|  | endmodule | ||||||
|  |  | ||||||
|  | @ -155,7 +155,7 @@ struct SynthGreenPAK4Pass : public ScriptPass | ||||||
| 
 | 
 | ||||||
| 		if (check_label("fine")) | 		if (check_label("fine")) | ||||||
| 		{ | 		{ | ||||||
| 			run("extract_counter"); | 			run("extract_counter -pout \\GP_DCMP,\\GP_DAC -maxwidth 14"); | ||||||
| 			run("clean"); | 			run("clean"); | ||||||
| 			run("opt -fast -mux_undef -undriven -fine"); | 			run("opt -fast -mux_undef -undriven -fine"); | ||||||
| 			run("memory_map"); | 			run("memory_map"); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue