diff options
Diffstat (limited to 'passes')
| -rw-r--r-- | passes/techmap/simplemap.cc | 31 | ||||
| -rw-r--r-- | passes/tests/test_cell.cc | 40 | 
2 files changed, 69 insertions, 2 deletions
| diff --git a/passes/techmap/simplemap.cc b/passes/techmap/simplemap.cc index 777e80142..0fb647344 100644 --- a/passes/techmap/simplemap.cc +++ b/passes/techmap/simplemap.cc @@ -321,6 +321,36 @@ void simplemap_lut(RTLIL::Module *module, RTLIL::Cell *cell)  	module->connect(cell->getPort("\\Y"), lut_data);  } +void simplemap_sop(RTLIL::Module *module, RTLIL::Cell *cell) +{ +	SigSpec ctrl = cell->getPort("\\A"); +	SigSpec table = cell->getParam("\\TABLE"); + +	int width = cell->getParam("\\WIDTH").as_int(); +	int depth = cell->getParam("\\DEPTH").as_int(); +	table.extend_u0(2 * width * depth); + +	SigSpec products; + +	for (int i = 0; i < depth; i++) { +		SigSpec in, pat; +		for (int j = 0; j < width; j++) { +			if (table[2*i*width + 2*j + 0] == State::S1) { +				in.append(ctrl[j]); +				pat.append(State::S0); +			} +			if (table[2*i*width + 2*j + 1] == State::S1) { +				in.append(ctrl[j]); +				pat.append(State::S1); +			} +		} + +		products.append(GetSize(in) > 0 ? module->Eq(NEW_ID, in, pat) : State::S1); +	} + +	module->connect(cell->getPort("\\Y"), module->ReduceOr(NEW_ID, products)); +} +  void simplemap_slice(RTLIL::Module *module, RTLIL::Cell *cell)  {  	int offset = cell->parameters.at("\\OFFSET").as_int(); @@ -498,6 +528,7 @@ void simplemap_get_mappers(std::map<RTLIL::IdString, void(*)(RTLIL::Module*, RTL  	mappers["$mux"]         = simplemap_mux;  	mappers["$tribuf"]      = simplemap_tribuf;  	mappers["$lut"]         = simplemap_lut; +	mappers["$sop"]         = simplemap_sop;  	mappers["$slice"]       = simplemap_slice;  	mappers["$concat"]      = simplemap_concat;  	mappers["$sr"]          = simplemap_sr; diff --git a/passes/tests/test_cell.cc b/passes/tests/test_cell.cc index a8fcac9bc..8b800d414 100644 --- a/passes/tests/test_cell.cc +++ b/passes/tests/test_cell.cc @@ -164,6 +164,41 @@ static void create_gold_module(RTLIL::Design *design, RTLIL::IdString cell_type,  		cell->setParam("\\LUT", config.as_const());  	} +	if (cell_type == "$sop") +	{ +		int width = 1 + xorshift32(8); +		int depth = 1 + xorshift32(8); + +		wire = module->addWire("\\A"); +		wire->width = width; +		wire->port_input = true; +		cell->setPort("\\A", wire); + +		wire = module->addWire("\\Y"); +		wire->port_output = true; +		cell->setPort("\\Y", wire); + +		RTLIL::SigSpec config; +		for (int i = 0; i < width*depth; i++) +			switch (xorshift32(3)) { +				case 0: +					config.append(RTLIL::S1); +					config.append(RTLIL::S0); +					break; +				case 1: +					config.append(RTLIL::S0); +					config.append(RTLIL::S1); +					break; +				case 2: +					config.append(RTLIL::S0); +					config.append(RTLIL::S0); +					break; +			} + +		cell->setParam("\\DEPTH", depth); +		cell->setParam("\\TABLE", config.as_const()); +	} +  	if (cell_type_flags.find('A') != std::string::npos) {  		wire = module->addWire("\\A");  		wire->width = 1 + xorshift32(8); @@ -534,7 +569,7 @@ struct TestCellPass : public Pass {  		log("        pass this option to techmap.\n");  		log("\n");  		log("    -simlib\n"); -		log("        use \"techmap -map +/simlib.v -max_iter 2 -autoproc\"\n"); +		log("        use \"techmap -D SIMLIB_NOCHECKS -map +/simlib.v -max_iter 2 -autoproc\"\n");  		log("\n");  		log("    -aigmap\n");  		log("        instead of calling \"techmap\", call \"aigmap\"\n"); @@ -604,7 +639,7 @@ struct TestCellPass : public Pass {  				continue;  			}  			if (args[argidx] == "-simlib") { -				techmap_cmd = "techmap -map +/simlib.v -max_iter 2 -autoproc"; +				techmap_cmd = "techmap -D SIMLIB_NOCHECKS -map +/simlib.v -max_iter 2 -autoproc";  				continue;  			}  			if (args[argidx] == "-aigmap") { @@ -697,6 +732,7 @@ struct TestCellPass : public Pass {  		// cell_types["$assert"] = "A";  		cell_types["$lut"] = "*"; +		cell_types["$sop"] = "*";  		cell_types["$alu"] = "ABSY";  		cell_types["$lcu"] = "*";  		cell_types["$macc"] = "*"; | 
