mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Added $_MUX4_, $_MUX8_, and $_MUX16_ cell types
This commit is contained in:
		
							parent
							
								
									c52a4cdeed
								
							
						
					
					
						commit
						706631225e
					
				
					 4 changed files with 131 additions and 2 deletions
				
			
		|  | @ -95,7 +95,6 @@ struct CellTypes | ||||||
| 			"$add", "$sub", "$mul", "$div", "$mod", "$pow", | 			"$add", "$sub", "$mul", "$div", "$mod", "$pow", | ||||||
| 			"$logic_and", "$logic_or", "$concat", "$macc" | 			"$logic_and", "$logic_or", "$concat", "$macc" | ||||||
| 		}; | 		}; | ||||||
| 
 |  | ||||||
| 		IdString A = "\\A", B = "\\B", S = "\\S", Y = "\\Y"; | 		IdString A = "\\A", B = "\\B", S = "\\S", Y = "\\Y"; | ||||||
| 		IdString P = "\\P", G = "\\G", C = "\\C", X = "\\X"; | 		IdString P = "\\P", G = "\\G", C = "\\C", X = "\\X"; | ||||||
| 		IdString BI = "\\BI", CI = "\\CI", CO = "\\CO", EN = "\\EN"; | 		IdString BI = "\\BI", CI = "\\CI", CO = "\\CO", EN = "\\EN"; | ||||||
|  | @ -144,7 +143,13 @@ struct CellTypes | ||||||
| 
 | 
 | ||||||
| 	void setup_stdcells() | 	void setup_stdcells() | ||||||
| 	{ | 	{ | ||||||
| 		IdString A = "\\A", B = "\\B", C = "\\C", D = "\\D", S = "\\S", Y = "\\Y"; | 		IdString A = "\\A", B = "\\B", C = "\\C", D = "\\D"; | ||||||
|  | 		IdString E = "\\E", F = "\\F", G = "\\G", H = "\\H"; | ||||||
|  | 		IdString I = "\\I", J = "\\J", K = "\\K", L = "\\L"; | ||||||
|  | 		IdString M = "\\I", N = "\\N", O = "\\O", P = "\\P"; | ||||||
|  | 		IdString S = "\\S", T = "\\T", U = "\\U", V = "\\V"; | ||||||
|  | 		IdString Y = "\\Y"; | ||||||
|  | 
 | ||||||
| 		setup_type("$_BUF_", {A}, {Y}, true); | 		setup_type("$_BUF_", {A}, {Y}, true); | ||||||
| 		setup_type("$_NOT_", {A}, {Y}, true); | 		setup_type("$_NOT_", {A}, {Y}, true); | ||||||
| 		setup_type("$_AND_", {A, B}, {Y}, true); | 		setup_type("$_AND_", {A, B}, {Y}, true); | ||||||
|  | @ -154,6 +159,9 @@ struct CellTypes | ||||||
| 		setup_type("$_XOR_", {A, B}, {Y}, true); | 		setup_type("$_XOR_", {A, B}, {Y}, true); | ||||||
| 		setup_type("$_XNOR_", {A, B}, {Y}, true); | 		setup_type("$_XNOR_", {A, B}, {Y}, true); | ||||||
| 		setup_type("$_MUX_", {A, B, S}, {Y}, true); | 		setup_type("$_MUX_", {A, B, S}, {Y}, true); | ||||||
|  | 		setup_type("$_MUX4_", {A, B, C, D, S, T}, {Y}, true); | ||||||
|  | 		setup_type("$_MUX8_", {A, B, C, D, E, F, G, H, S, T, U}, {Y}, true); | ||||||
|  | 		setup_type("$_MUX16_", {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V}, {Y}, true); | ||||||
| 		setup_type("$_AOI3_", {A, B, C}, {Y}, true); | 		setup_type("$_AOI3_", {A, B, C}, {Y}, true); | ||||||
| 		setup_type("$_OAI3_", {A, B, C}, {Y}, true); | 		setup_type("$_OAI3_", {A, B, C}, {Y}, true); | ||||||
| 		setup_type("$_AOI4_", {A, B, C, D}, {Y}, true); | 		setup_type("$_AOI4_", {A, B, C, D}, {Y}, true); | ||||||
|  |  | ||||||
|  | @ -970,6 +970,10 @@ namespace { | ||||||
| 			if (cell->type == "$_AOI4_") { check_gate("ABCDY"); return; } | 			if (cell->type == "$_AOI4_") { check_gate("ABCDY"); return; } | ||||||
| 			if (cell->type == "$_OAI4_") { check_gate("ABCDY"); return; } | 			if (cell->type == "$_OAI4_") { check_gate("ABCDY"); return; } | ||||||
| 
 | 
 | ||||||
|  | 			if (cell->type == "$_MUX4_")  { check_gate("ABCDSTY"); return; } | ||||||
|  | 			if (cell->type == "$_MUX8_")  { check_gate("ABCDEFGHSTUY"); return; } | ||||||
|  | 			if (cell->type == "$_MUX16_") { check_gate("ABCDEFGHIJKLMNOPSTUVY"); return; } | ||||||
|  | 
 | ||||||
| 			if (cell->type == "$_SR_NN_") { check_gate("SRQ"); return; } | 			if (cell->type == "$_SR_NN_") { check_gate("SRQ"); return; } | ||||||
| 			if (cell->type == "$_SR_NP_") { check_gate("SRQ"); return; } | 			if (cell->type == "$_SR_NP_") { check_gate("SRQ"); return; } | ||||||
| 			if (cell->type == "$_SR_PN_") { check_gate("SRQ"); return; } | 			if (cell->type == "$_SR_PN_") { check_gate("SRQ"); return; } | ||||||
|  |  | ||||||
|  | @ -90,6 +90,10 @@ struct gate_t | ||||||
| 	RTLIL::SigBit bit; | 	RTLIL::SigBit bit; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | bool map_mux4; | ||||||
|  | bool map_mux8; | ||||||
|  | bool map_mux16; | ||||||
|  | 
 | ||||||
| bool markgroups; | bool markgroups; | ||||||
| int map_autoidx; | int map_autoidx; | ||||||
| SigMap assign_map; | SigMap assign_map; | ||||||
|  | @ -844,6 +848,12 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | ||||||
| 		fprintf(f, "GATE AOI4 %d Y=!((A*B)+(C*D));     PIN * INV     1 999 1 0 1 0\n", get_cell_cost("$_AOI4_")); | 		fprintf(f, "GATE AOI4 %d Y=!((A*B)+(C*D));     PIN * INV     1 999 1 0 1 0\n", get_cell_cost("$_AOI4_")); | ||||||
| 		fprintf(f, "GATE OAI4 %d Y=!((A+B)*(C+D));     PIN * INV     1 999 1 0 1 0\n", get_cell_cost("$_OAI4_")); | 		fprintf(f, "GATE OAI4 %d Y=!((A+B)*(C+D));     PIN * INV     1 999 1 0 1 0\n", get_cell_cost("$_OAI4_")); | ||||||
| 		fprintf(f, "GATE MUX  %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_MUX_")); | 		fprintf(f, "GATE MUX  %d Y=(A*B)+(S*B)+(!S*A); PIN * UNKNOWN 1 999 1 0 1 0\n", get_cell_cost("$_MUX_")); | ||||||
|  | 		if (map_mux4) | ||||||
|  | 			fprintf(f, "GATE MUX4 %d Y=(!S*!T*A)+(S*!T*B)+(!S*T*C)+(S*T*D); PIN * UNKNOWN 1 999 1 0 1 0\n", 2*get_cell_cost("$_MUX_")); | ||||||
|  | 		if (map_mux8) | ||||||
|  | 			fprintf(f, "GATE MUX8 %d Y=(!S*!T*!U*A)+(S*!T*!U*B)+(!S*T*!U*C)+(S*T*!U*D)+(!S*!T*U*E)+(S*!T*U*F)+(!S*T*U*G)+(S*T*U*H); PIN * UNKNOWN 1 999 1 0 1 0\n", 4*get_cell_cost("$_MUX_")); | ||||||
|  | 		if (map_mux16) | ||||||
|  | 			fprintf(f, "GATE MUX16 %d Y=(!S*!T*!U*!V*A)+(S*!T*!U*!V*B)+(!S*T*!U*!V*C)+(S*T*!U*!V*D)+(!S*!T*U*!V*E)+(S*!T*U*!V*F)+(!S*T*U*!V*G)+(S*T*U*!V*H)+(!S*!T*!U*V*I)+(S*!T*!U*V*J)+(!S*T*!U*V*K)+(S*T*!U*V*L)+(!S*!T*U*V*M)+(S*!T*U*V*N)+(!S*T*U*V*O)+(S*T*U*V*P); PIN * UNKNOWN 1 999 1 0 1 0\n", 8*get_cell_cost("$_MUX_")); | ||||||
| 		fclose(f); | 		fclose(f); | ||||||
| 
 | 
 | ||||||
| 		if (lut_mode) { | 		if (lut_mode) { | ||||||
|  | @ -934,6 +944,64 @@ void abc_module(RTLIL::Design *design, RTLIL::Module *current_module, std::strin | ||||||
| 					design->select(module, cell); | 					design->select(module, cell); | ||||||
| 					continue; | 					continue; | ||||||
| 				} | 				} | ||||||
|  | 				if (c->type == "\\MUX4") { | ||||||
|  | 					RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX4_"); | ||||||
|  | 					if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; | ||||||
|  | 					cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\T", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\T").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); | ||||||
|  | 					design->select(module, cell); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 				if (c->type == "\\MUX8") { | ||||||
|  | 					RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX8_"); | ||||||
|  | 					if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; | ||||||
|  | 					cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\E", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\E").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\F", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\F").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\G", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\G").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\H", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\H").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\T", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\T").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\U", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\U").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); | ||||||
|  | 					design->select(module, cell); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 				if (c->type == "\\MUX16") { | ||||||
|  | 					RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_MUX16_"); | ||||||
|  | 					if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; | ||||||
|  | 					cell->setPort("\\A", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\A").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\B", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\B").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\C", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\C").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\D", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\D").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\E", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\E").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\F", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\F").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\G", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\G").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\H", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\H").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\I", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\I").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\J", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\J").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\K", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\K").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\L", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\L").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\M", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\M").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\N", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\N").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\O", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\O").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\P", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\P").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\S", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\S").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\T", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\T").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\U", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\U").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\V", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\V").as_wire()->name)])); | ||||||
|  | 					cell->setPort("\\Y", RTLIL::SigSpec(module->wires_[remap_name(c->getPort("\\Y").as_wire()->name)])); | ||||||
|  | 					design->select(module, cell); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
| 				if (c->type == "\\AOI3" || c->type == "\\OAI3") { | 				if (c->type == "\\AOI3" || c->type == "\\OAI3") { | ||||||
| 					RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); | 					RTLIL::Cell *cell = module->addCell(remap_name(c->name), "$_" + c->type.substr(1) + "_"); | ||||||
| 					if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; | 					if (markgroups) cell->attributes["\\abcgroup"] = map_autoidx; | ||||||
|  | @ -1150,6 +1218,10 @@ struct AbcPass : public Pass { | ||||||
| 		log("        the area cost doubles with each additional input bit. the delay cost\n"); | 		log("        the area cost doubles with each additional input bit. the delay cost\n"); | ||||||
| 		log("        is still constant for all lut widths.\n"); | 		log("        is still constant for all lut widths.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | 		// log("    -mux4, -mux8, -mux16\n");
 | ||||||
|  | 		// log("        try to extract 4-input, 8-input, and/or 16-input muxes\n");
 | ||||||
|  | 		// log("        (ignored when used with -liberty or -lut)\n");
 | ||||||
|  | 		// log("\n");
 | ||||||
| 		log("    -dff\n"); | 		log("    -dff\n"); | ||||||
| 		log("        also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n"); | 		log("        also pass $_DFF_?_ and $_DFFE_??_ cells through ABC. modules with many\n"); | ||||||
| 		log("        clock domains are automatically partitioned in clock domains and each\n"); | 		log("        clock domains are automatically partitioned in clock domains and each\n"); | ||||||
|  | @ -1197,6 +1269,10 @@ struct AbcPass : public Pass { | ||||||
| 		int lut_mode = 0, lut_mode2 = 0; | 		int lut_mode = 0, lut_mode2 = 0; | ||||||
| 		markgroups = false; | 		markgroups = false; | ||||||
| 
 | 
 | ||||||
|  | 		map_mux4 = false; | ||||||
|  | 		map_mux8 = false; | ||||||
|  | 		map_mux16 = false; | ||||||
|  | 
 | ||||||
| #ifdef _WIN32 | #ifdef _WIN32 | ||||||
| 		if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\yosys-abc.exe")) | 		if (!check_file_exists(exe_file + ".exe") && check_file_exists(proc_self_dirname() + "..\\yosys-abc.exe")) | ||||||
| 			exe_file = proc_self_dirname() + "..\\yosys-abc"; | 			exe_file = proc_self_dirname() + "..\\yosys-abc"; | ||||||
|  | @ -1248,6 +1324,18 @@ struct AbcPass : public Pass { | ||||||
| 				} | 				} | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | 			if (arg == "-mux4") { | ||||||
|  | 				map_mux4 = true; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			if (arg == "-mux8") { | ||||||
|  | 				map_mux8 = true; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			if (arg == "-mux16") { | ||||||
|  | 				map_mux16 = true; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
| 			if (arg == "-fast") { | 			if (arg == "-fast") { | ||||||
| 				fast_mode = true; | 				fast_mode = true; | ||||||
| 				continue; | 				continue; | ||||||
|  |  | ||||||
|  | @ -79,6 +79,35 @@ output Y; | ||||||
| assign Y = S ? B : A; | assign Y = S ? B : A; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
|  | module \$_MUX4_ (A, B, C, D, S, T, Y); | ||||||
|  | input A, B, C, D, S, T; | ||||||
|  | output Y; | ||||||
|  | assign Y = T ? (S ? D : C) : | ||||||
|  |                (S ? B : A); | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module \$_MUX8_ (A, B, C, D, E, F, G, H, S, T, U, Y); | ||||||
|  | input A, B, C, D, E, F, G, H, S, T, U; | ||||||
|  | output Y; | ||||||
|  | assign Y = U ? T ? (S ? H : G) : | ||||||
|  |                    (S ? F : E) : | ||||||
|  |                T ? (S ? D : C) : | ||||||
|  |                    (S ? B : A); | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module \$_MUX16_ (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V, Y); | ||||||
|  | input A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V; | ||||||
|  | output Y; | ||||||
|  | assign Y = V ? U ? T ? (S ? P : O) : | ||||||
|  |                        (S ? N : M) : | ||||||
|  |                    T ? (S ? L : K) : | ||||||
|  |                        (S ? J : I) : | ||||||
|  |                U ? T ? (S ? H : G) : | ||||||
|  |                        (S ? F : E) : | ||||||
|  |                    T ? (S ? D : C) : | ||||||
|  |                        (S ? B : A); | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
| module  \$_AOI3_ (A, B, C, Y); | module  \$_AOI3_ (A, B, C, Y); | ||||||
| input A, B, C; | input A, B, C; | ||||||
| output Y; | output Y; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue