mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 11:42:30 +00:00 
			
		
		
		
	Added $macc SAT model
This commit is contained in:
		
							parent
							
								
									680eaaac41
								
							
						
					
					
						commit
						fa64942018
					
				
					 4 changed files with 83 additions and 11 deletions
				
			
		|  | @ -23,6 +23,7 @@ | ||||||
| #include "kernel/rtlil.h" | #include "kernel/rtlil.h" | ||||||
| #include "kernel/sigtools.h" | #include "kernel/sigtools.h" | ||||||
| #include "kernel/celltypes.h" | #include "kernel/celltypes.h" | ||||||
|  | #include "kernel/macc.h" | ||||||
| 
 | 
 | ||||||
| #include "libs/ezsat/ezminisat.h" | #include "libs/ezsat/ezminisat.h" | ||||||
| typedef ezMiniSAT ezDefaultSAT; | typedef ezMiniSAT ezDefaultSAT; | ||||||
|  | @ -762,6 +763,76 @@ struct SatGen | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		if (cell->type == "$macc") | ||||||
|  | 		{ | ||||||
|  | 			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); | ||||||
|  | 			std::vector<int> b = importDefSigSpec(cell->getPort("\\B"), timestep); | ||||||
|  | 			std::vector<int> y = importDefSigSpec(cell->getPort("\\Y"), timestep); | ||||||
|  | 
 | ||||||
|  | 			Macc macc; | ||||||
|  | 			macc.from_cell(cell); | ||||||
|  | 
 | ||||||
|  | 			std::vector<int> tmp(SIZE(y), ez->FALSE); | ||||||
|  | 
 | ||||||
|  | 			for (auto &port : macc.ports) | ||||||
|  | 			{ | ||||||
|  | 				std::vector<int> in_a = importDefSigSpec(port.in_a, timestep); | ||||||
|  | 				std::vector<int> in_b = importDefSigSpec(port.in_b, timestep); | ||||||
|  | 
 | ||||||
|  | 				while (SIZE(in_a) < SIZE(y)) | ||||||
|  | 					in_a.push_back(port.is_signed && !in_a.empty() ? in_a.back() : ez->FALSE); | ||||||
|  | 				in_a.resize(SIZE(y)); | ||||||
|  | 
 | ||||||
|  | 				if (SIZE(in_b)) | ||||||
|  | 				{ | ||||||
|  | 					while (SIZE(in_b) < SIZE(y)) | ||||||
|  | 						in_b.push_back(port.is_signed && !in_b.empty() ? in_b.back() : ez->FALSE); | ||||||
|  | 					in_b.resize(SIZE(y)); | ||||||
|  | 
 | ||||||
|  | 					for (int i = 0; i < SIZE(in_b); i++) { | ||||||
|  | 						std::vector<int> shifted_a(in_a.size(), ez->FALSE); | ||||||
|  | 						for (int j = i; j < int(in_a.size()); j++) | ||||||
|  | 							shifted_a.at(j) = in_a.at(j-i); | ||||||
|  | 						if (port.do_subtract) | ||||||
|  | 							tmp = ez->vec_ite(in_b.at(i), ez->vec_sub(tmp, shifted_a), tmp); | ||||||
|  | 						else | ||||||
|  | 							tmp = ez->vec_ite(in_b.at(i), ez->vec_add(tmp, shifted_a), tmp); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				else | ||||||
|  | 				{ | ||||||
|  | 					if (port.do_subtract) | ||||||
|  | 						tmp = ez->vec_sub(tmp, in_a); | ||||||
|  | 					else | ||||||
|  | 						tmp = ez->vec_add(tmp, in_a); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			for (int i = 0; i < SIZE(b); i++) { | ||||||
|  | 				std::vector<int> val(SIZE(y), ez->FALSE); | ||||||
|  | 				val.at(0) = b.at(i); | ||||||
|  | 				tmp = ez->vec_add(tmp, val); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (model_undef) | ||||||
|  | 			{ | ||||||
|  | 				std::vector<int> undef_a = importUndefSigSpec(cell->getPort("\\A"), timestep); | ||||||
|  | 				std::vector<int> undef_b = importUndefSigSpec(cell->getPort("\\B"), timestep); | ||||||
|  | 
 | ||||||
|  | 				int undef_any_a = ez->expression(ezSAT::OpOr, undef_a); | ||||||
|  | 				int undef_any_b = ez->expression(ezSAT::OpOr, undef_b); | ||||||
|  | 
 | ||||||
|  | 				std::vector<int> undef_y = importUndefSigSpec(cell->getPort("\\Y"), timestep); | ||||||
|  | 				ez->assume(ez->vec_eq(undef_y, std::vector<int>(SIZE(y), ez->OR(undef_any_a, undef_any_b)))); | ||||||
|  | 
 | ||||||
|  | 				undefGating(y, tmp, undef_y); | ||||||
|  | 			} | ||||||
|  | 			else | ||||||
|  | 				ez->assume(ez->vec_eq(y, tmp)); | ||||||
|  | 
 | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		if (cell->type == "$div" || cell->type == "$mod") | 		if (cell->type == "$div" || cell->type == "$mod") | ||||||
| 		{ | 		{ | ||||||
| 			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); | 			std::vector<int> a = importDefSigSpec(cell->getPort("\\A"), timestep); | ||||||
|  |  | ||||||
|  | @ -42,9 +42,9 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, | ||||||
| 	if (cell_type == "$macc") | 	if (cell_type == "$macc") | ||||||
| 	{ | 	{ | ||||||
| 		Macc macc; | 		Macc macc; | ||||||
| 		int width = 1 + xorshift32(16); | 		int width = 1 + xorshift32(8); | ||||||
| 		int depth = 1 + xorshift32(6); | 		int depth = 1 + xorshift32(6); | ||||||
| 		int mulbits = 0; | 		int mulbits_a = 0, mulbits_b = 0; | ||||||
| 
 | 
 | ||||||
| 		RTLIL::Wire *wire_a = module->addWire("\\A"); | 		RTLIL::Wire *wire_a = module->addWire("\\A"); | ||||||
| 		wire_a->width = 0; | 		wire_a->width = 0; | ||||||
|  | @ -55,10 +55,11 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type, | ||||||
| 			int size_a = xorshift32(width) + 1; | 			int size_a = xorshift32(width) + 1; | ||||||
| 			int size_b = xorshift32(width) + 1; | 			int size_b = xorshift32(width) + 1; | ||||||
| 
 | 
 | ||||||
| 			if (mulbits + size_a*size_b > 256 || xorshift32(2) == 1) | 			if (mulbits_a + size_a*size_b <= 96 && mulbits_b + size_a + size_b <= 16 && xorshift32(2) == 1) { | ||||||
|  | 				mulbits_a += size_a * size_b; | ||||||
|  | 				mulbits_b += size_a + size_b; | ||||||
|  | 			} else | ||||||
| 				size_b = 0; | 				size_b = 0; | ||||||
| 			else |  | ||||||
| 				mulbits += size_a*size_b; |  | ||||||
| 
 | 
 | ||||||
| 			Macc::port_t this_port; | 			Macc::port_t this_port; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -771,16 +771,16 @@ module \$macc (A, B, Y); | ||||||
| 	localparam integer num_abits = $clog2(A_WIDTH); | 	localparam integer num_abits = $clog2(A_WIDTH); | ||||||
| 
 | 
 | ||||||
| 	function [2*num_ports*num_abits-1:0] get_port_offsets; | 	function [2*num_ports*num_abits-1:0] get_port_offsets; | ||||||
| 		input [CONFIG_WIDTH-1:0] CONFIG; | 		input [CONFIG_WIDTH-1:0] cfg; | ||||||
| 		integer i, cursor; | 		integer i, cursor; | ||||||
| 		begin | 		begin | ||||||
| 			cursor = 0; | 			cursor = 0; | ||||||
| 			get_port_offsets = 0; | 			get_port_offsets = 0; | ||||||
| 			for (i = 0; i < num_ports; i = i+1) begin | 			for (i = 0; i < num_ports; i = i+1) begin | ||||||
| 				get_port_offsets[(2*i + 0)*num_abits +: num_abits] = cursor; | 				get_port_offsets[(2*i + 0)*num_abits +: num_abits] = cursor; | ||||||
| 				cursor = cursor + CONFIG[4 + i*(2 + 2*num_bits) + 2 +: num_bits]; | 				cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 +: num_bits]; | ||||||
| 				get_port_offsets[(2*i + 1)*num_abits +: num_abits] = cursor; | 				get_port_offsets[(2*i + 1)*num_abits +: num_abits] = cursor; | ||||||
| 				cursor = cursor + CONFIG[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]; | 				cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]; | ||||||
| 			end | 			end | ||||||
| 		end | 		end | ||||||
| 	endfunction | 	endfunction | ||||||
|  |  | ||||||
|  | @ -597,16 +597,16 @@ module \$macc (A, B, Y); | ||||||
| 	localparam integer num_abits = $clog2(A_WIDTH); | 	localparam integer num_abits = $clog2(A_WIDTH); | ||||||
| 
 | 
 | ||||||
| 	function [2*num_ports*num_abits-1:0] get_port_offsets; | 	function [2*num_ports*num_abits-1:0] get_port_offsets; | ||||||
| 		input [CONFIG_WIDTH-1:0] CONFIG; | 		input [CONFIG_WIDTH-1:0] cfg; | ||||||
| 		integer i, cursor; | 		integer i, cursor; | ||||||
| 		begin | 		begin | ||||||
| 			cursor = 0; | 			cursor = 0; | ||||||
| 			get_port_offsets = 0; | 			get_port_offsets = 0; | ||||||
| 			for (i = 0; i < num_ports; i = i+1) begin | 			for (i = 0; i < num_ports; i = i+1) begin | ||||||
| 				get_port_offsets[(2*i + 0)*num_abits +: num_abits] = cursor; | 				get_port_offsets[(2*i + 0)*num_abits +: num_abits] = cursor; | ||||||
| 				cursor = cursor + CONFIG[4 + i*(2 + 2*num_bits) + 2 +: num_bits]; | 				cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 +: num_bits]; | ||||||
| 				get_port_offsets[(2*i + 1)*num_abits +: num_abits] = cursor; | 				get_port_offsets[(2*i + 1)*num_abits +: num_abits] = cursor; | ||||||
| 				cursor = cursor + CONFIG[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]; | 				cursor = cursor + cfg[4 + i*(2 + 2*num_bits) + 2 + num_bits +: num_bits]; | ||||||
| 			end | 			end | ||||||
| 		end | 		end | ||||||
| 	endfunction | 	endfunction | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue