mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	test_cell: Support more cell types
Still unsupported: - x-prop cells ($eqx, $nex, $bweqx) - wide muxes (`$_MUX16_` and friends) - $pmux Partially supported: - $bwmux is not supported in `ConstEval::eval()`, works with `-noeval` - $buf has no mapping in techmap.v so is unusable with `techmap -assert` (i.e. the default) - $pow has `_TECHMAP_FAIL_` in techmap.v, `-simlib` works for some iterations but fails for others, `-aigmap` works fine Fix `CellTypes::eval() for `$_NMUX_`. Fix `RTLIL::Cell::fixup_parameters()` for $concat and $bwmux.
This commit is contained in:
		
							parent
							
								
									833721bfc4
								
							
						
					
					
						commit
						1a3f6c9d50
					
				
					 3 changed files with 140 additions and 14 deletions
				
			
		| 
						 | 
				
			
			@ -589,6 +589,8 @@ struct CellTypes
 | 
			
		|||
	{
 | 
			
		||||
		if (cell->type.in(ID($mux), ID($_MUX_)))
 | 
			
		||||
			return const_mux(arg1, arg2, arg3);
 | 
			
		||||
		if (cell->type == ID($_NMUX_))
 | 
			
		||||
			return eval_not(const_mux(arg1, arg2, arg3));
 | 
			
		||||
		if (cell->type == ID($bwmux))
 | 
			
		||||
			return const_bwmux(arg1, arg2, arg3);
 | 
			
		||||
		if (cell->type == ID($pmux))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4063,9 +4063,9 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
 | 
			
		|||
			type.begins_with("$verific$") || type.begins_with("$array:") || type.begins_with("$extern:"))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (type == ID($buf) || type == ID($mux) || type == ID($pmux) || type == ID($bmux)) {
 | 
			
		||||
	if (type == ID($buf) || type == ID($mux) || type == ID($pmux) || type == ID($bmux) || type == ID($bwmux)) {
 | 
			
		||||
		parameters[ID::WIDTH] = GetSize(connections_[ID::Y]);
 | 
			
		||||
		if (type != ID($buf) && type != ID($mux))
 | 
			
		||||
		if (type.in(ID($pmux), ID($bmux)))
 | 
			
		||||
			parameters[ID::S_WIDTH] = GetSize(connections_[ID::S]);
 | 
			
		||||
		check();
 | 
			
		||||
		return;
 | 
			
		||||
| 
						 | 
				
			
			@ -4115,7 +4115,7 @@ void RTLIL::Cell::fixup_parameters(bool set_a_signed, bool set_b_signed)
 | 
			
		|||
		parameters[ID::B_WIDTH] = GetSize(connections_[ID::B]);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (connections_.count(ID::Y))
 | 
			
		||||
	if (connections_.count(ID::Y) && type != ID($concat))
 | 
			
		||||
		parameters[ID::Y_WIDTH] = GetSize(connections_[ID::Y]);
 | 
			
		||||
 | 
			
		||||
	if (connections_.count(ID::Q))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,6 +72,29 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
 | 
			
		|||
		cell->setPort(ID::Y, wire);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cell_type.in(ID($_MUX_), ID($_NMUX_)))
 | 
			
		||||
	{
 | 
			
		||||
		wire = module->addWire(ID::A);
 | 
			
		||||
		wire->width = 1;
 | 
			
		||||
		wire->port_input = true;
 | 
			
		||||
		cell->setPort(ID::A, wire);
 | 
			
		||||
 | 
			
		||||
		wire = module->addWire(ID::B);
 | 
			
		||||
		wire->width = 1;
 | 
			
		||||
		wire->port_input = true;
 | 
			
		||||
		cell->setPort(ID::B, wire);
 | 
			
		||||
 | 
			
		||||
		wire = module->addWire(ID::S);
 | 
			
		||||
		wire->width = 1;
 | 
			
		||||
		wire->port_input = true;
 | 
			
		||||
		cell->setPort(ID::S, wire);
 | 
			
		||||
 | 
			
		||||
		wire = module->addWire(ID::Y);
 | 
			
		||||
		wire->width = 1;
 | 
			
		||||
		wire->port_output = true;
 | 
			
		||||
		cell->setPort(ID::Y, wire);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cell_type == ID($bmux))
 | 
			
		||||
	{
 | 
			
		||||
		int width = 1 + xorshift32(8 * bloat_factor);
 | 
			
		||||
| 
						 | 
				
			
			@ -274,14 +297,19 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
 | 
			
		|||
 | 
			
		||||
	if (cell_type_flags.find('A') != std::string::npos) {
 | 
			
		||||
		wire = module->addWire(ID::A);
 | 
			
		||||
		wire->width = 1 + xorshift32(8 * bloat_factor);
 | 
			
		||||
		if (cell_type_flags.find('b') != std::string::npos)
 | 
			
		||||
			wire->width = 1;
 | 
			
		||||
		else
 | 
			
		||||
			wire->width = 1 + xorshift32(8 * bloat_factor);
 | 
			
		||||
		wire->port_input = true;
 | 
			
		||||
		cell->setPort(ID::A, wire);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cell_type_flags.find('B') != std::string::npos) {
 | 
			
		||||
		wire = module->addWire(ID::B);
 | 
			
		||||
		if (cell_type_flags.find('h') != std::string::npos)
 | 
			
		||||
		if (cell_type_flags.find('b') != std::string::npos)
 | 
			
		||||
			wire->width = 1;
 | 
			
		||||
		else if (cell_type_flags.find('h') != std::string::npos)
 | 
			
		||||
			wire->width = 1 + xorshift32(6 * bloat_factor);
 | 
			
		||||
		else
 | 
			
		||||
			wire->width = 1 + xorshift32(8 * bloat_factor);
 | 
			
		||||
| 
						 | 
				
			
			@ -289,6 +317,26 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
 | 
			
		|||
		cell->setPort(ID::B, wire);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cell_type_flags.find('C') != std::string::npos) {
 | 
			
		||||
		wire = module->addWire(ID::C);
 | 
			
		||||
		if (cell_type_flags.find('b') != std::string::npos)
 | 
			
		||||
			wire->width = 1;
 | 
			
		||||
		else
 | 
			
		||||
			wire->width = 1 + xorshift32(8 * bloat_factor);
 | 
			
		||||
		wire->port_input = true;
 | 
			
		||||
		cell->setPort(ID::C, wire);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cell_type_flags.find('D') != std::string::npos) {
 | 
			
		||||
		wire = module->addWire(ID::D);
 | 
			
		||||
		if (cell_type_flags.find('b') != std::string::npos)
 | 
			
		||||
			wire->width = 1;
 | 
			
		||||
		else
 | 
			
		||||
			wire->width = 1 + xorshift32(8 * bloat_factor);
 | 
			
		||||
		wire->port_input = true;
 | 
			
		||||
		cell->setPort(ID::D, wire);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cell_type_flags.find('S') != std::string::npos && xorshift32(2)) {
 | 
			
		||||
		if (cell_type_flags.find('A') != std::string::npos)
 | 
			
		||||
			cell->parameters[ID::A_SIGNED] = true;
 | 
			
		||||
| 
						 | 
				
			
			@ -305,7 +353,10 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
 | 
			
		|||
 | 
			
		||||
	if (cell_type_flags.find('Y') != std::string::npos) {
 | 
			
		||||
		wire = module->addWire(ID::Y);
 | 
			
		||||
		wire->width = 1 + xorshift32(8 * bloat_factor);
 | 
			
		||||
		if (cell_type_flags.find('b') != std::string::npos)
 | 
			
		||||
			wire->width = 1;
 | 
			
		||||
		else
 | 
			
		||||
			wire->width = 1 + xorshift32(8 * bloat_factor);
 | 
			
		||||
		wire->port_output = true;
 | 
			
		||||
		cell->setPort(ID::Y, wire);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -346,6 +397,55 @@ static RTLIL::Cell* create_gold_module(RTLIL::Design *design, RTLIL::IdString ce
 | 
			
		|||
		cell->setPort(ID::CO, wire);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cell_type == ID($slice))
 | 
			
		||||
	{
 | 
			
		||||
		int a_size = GetSize(cell->getPort(ID::A));
 | 
			
		||||
		int y_size = 1;
 | 
			
		||||
		if (a_size > 1)
 | 
			
		||||
			y_size += (xorshift32(8 * bloat_factor) % (a_size - 1));
 | 
			
		||||
		wire = module->addWire(ID::Y);
 | 
			
		||||
		wire->width = y_size;
 | 
			
		||||
		wire->port_output = true;
 | 
			
		||||
		cell->setPort(ID::Y, wire);
 | 
			
		||||
		if (a_size > y_size)
 | 
			
		||||
			cell->setParam(ID::OFFSET, (xorshift32(8 * bloat_factor) % (a_size - y_size)));
 | 
			
		||||
		else
 | 
			
		||||
			cell->setParam(ID::OFFSET, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cell_type == ID($concat))
 | 
			
		||||
	{
 | 
			
		||||
		wire = module->addWire(ID::Y);
 | 
			
		||||
		wire->width = GetSize(cell->getPort(ID::A)) + GetSize(cell->getPort(ID::B));
 | 
			
		||||
		wire->port_output = true;
 | 
			
		||||
		cell->setPort(ID::Y, wire);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cell_type == ID($buf))
 | 
			
		||||
	{
 | 
			
		||||
		wire = module->addWire(ID::Y);
 | 
			
		||||
		wire->width = GetSize(cell->getPort(ID::A));
 | 
			
		||||
		wire->port_output = true;
 | 
			
		||||
		cell->setPort(ID::Y, wire);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cell_type == ID($bwmux))
 | 
			
		||||
	{
 | 
			
		||||
		int a_size = GetSize(cell->getPort(ID::A));
 | 
			
		||||
		wire = module->addWire(ID::B);
 | 
			
		||||
		wire->width = a_size;
 | 
			
		||||
		wire->port_output = true;
 | 
			
		||||
		cell->setPort(ID::B, wire);
 | 
			
		||||
		wire = module->addWire(ID::S);
 | 
			
		||||
		wire->width = a_size;
 | 
			
		||||
		wire->port_output = true;
 | 
			
		||||
		cell->setPort(ID::S, wire);
 | 
			
		||||
		wire = module->addWire(ID::Y);
 | 
			
		||||
		wire->width = a_size;
 | 
			
		||||
		wire->port_output = true;
 | 
			
		||||
		cell->setPort(ID::Y, wire);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (constmode)
 | 
			
		||||
	{
 | 
			
		||||
		auto conn_list = cell->connections();
 | 
			
		||||
| 
						 | 
				
			
			@ -650,9 +750,9 @@ static void run_eval_test(RTLIL::Design *design, const CellType *ct, bool verbos
 | 
			
		|||
			// Simple (A -> Y) and (A,B -> Y) cells
 | 
			
		||||
			if (has_a && !has_c && !has_d && !has_s && !has_x && has_y)
 | 
			
		||||
				result = CellTypes::eval(cell, in_map[ID::A], in_map[ID::B], &err);
 | 
			
		||||
			// (A,B,C -> Y) cells
 | 
			
		||||
			else if (has_a && has_b && has_c && !has_d && !has_s && !has_x && has_y)
 | 
			
		||||
				result = CellTypes::eval(cell, in_map[ID::A], in_map[ID::B], in_map[ID::B], &err);
 | 
			
		||||
			// (A,B,C -> Y) and (A,B,C,D -> Y) cells
 | 
			
		||||
			else if (has_a && has_b && has_c && !has_s && !has_x && has_y)
 | 
			
		||||
				result = CellTypes::eval(cell, in_map[ID::A], in_map[ID::B], in_map[ID::C], in_map[ID::D], &err);
 | 
			
		||||
			// (A,S -> Y) cells
 | 
			
		||||
			else if (has_a && !has_b && !has_c && !has_d && has_s && !has_x && has_y)
 | 
			
		||||
				result = CellTypes::eval(cell, in_map[ID::A], in_map[ID::S], &err);
 | 
			
		||||
| 
						 | 
				
			
			@ -961,6 +1061,8 @@ struct TestCellPass : public Pass {
 | 
			
		|||
		cell_types[ID($not)] = "ASY";
 | 
			
		||||
		cell_types[ID($pos)] = "ASY";
 | 
			
		||||
		cell_types[ID($neg)] = "ASY";
 | 
			
		||||
		if (techmap_cmd.compare("techmap -assert") != 0)
 | 
			
		||||
			cell_types[ID($buf)] = "A";
 | 
			
		||||
 | 
			
		||||
		cell_types[ID($and)]  = "ABSY";
 | 
			
		||||
		cell_types[ID($or)]   = "ABSY";
 | 
			
		||||
| 
						 | 
				
			
			@ -996,7 +1098,8 @@ struct TestCellPass : public Pass {
 | 
			
		|||
		cell_types[ID($mod)] = "ABSY";
 | 
			
		||||
		cell_types[ID($divfloor)] = "ABSY";
 | 
			
		||||
		cell_types[ID($modfloor)] = "ABSY";
 | 
			
		||||
		// cell_types[ID($pow)] = "ABsY";
 | 
			
		||||
		if (nosat && techmap_cmd.compare("aigmap") == 0)
 | 
			
		||||
			cell_types[ID($pow)] = "ABsY";
 | 
			
		||||
 | 
			
		||||
		cell_types[ID($logic_not)] = "ASY";
 | 
			
		||||
		cell_types[ID($logic_and)] = "ABSY";
 | 
			
		||||
| 
						 | 
				
			
			@ -1005,12 +1108,13 @@ struct TestCellPass : public Pass {
 | 
			
		|||
		cell_types[ID($mux)] = "*";
 | 
			
		||||
		cell_types[ID($bmux)] = "*";
 | 
			
		||||
		cell_types[ID($demux)] = "*";
 | 
			
		||||
		if (edges) {
 | 
			
		||||
		if (edges)
 | 
			
		||||
			cell_types[ID($pmux)] = "*";
 | 
			
		||||
		}
 | 
			
		||||
		if (noeval)
 | 
			
		||||
			cell_types[ID($bwmux)] = "A";
 | 
			
		||||
 | 
			
		||||
		// cell_types[ID($slice)] = "A";
 | 
			
		||||
		// cell_types[ID($concat)] = "A";
 | 
			
		||||
		cell_types[ID($slice)] = "A";
 | 
			
		||||
		cell_types[ID($concat)] = "AB";
 | 
			
		||||
 | 
			
		||||
		cell_types[ID($lut)] = "*";
 | 
			
		||||
		cell_types[ID($sop)] = "*";
 | 
			
		||||
| 
						 | 
				
			
			@ -1019,6 +1123,26 @@ struct TestCellPass : public Pass {
 | 
			
		|||
		cell_types[ID($macc)] = "*";
 | 
			
		||||
		cell_types[ID($fa)] = "*";
 | 
			
		||||
 | 
			
		||||
		cell_types[ID($_BUF_)] = "AYb";
 | 
			
		||||
		cell_types[ID($_NOT_)] = "AYb";
 | 
			
		||||
		cell_types[ID($_AND_)] = "ABYb";
 | 
			
		||||
		cell_types[ID($_NAND_)] = "ABYb";
 | 
			
		||||
		cell_types[ID($_OR_)] = "ABYb";
 | 
			
		||||
		cell_types[ID($_NOR_)] = "ABYb";
 | 
			
		||||
		cell_types[ID($_XOR_)] = "ABYb";
 | 
			
		||||
		cell_types[ID($_XNOR_)] = "ABYb";
 | 
			
		||||
		cell_types[ID($_ANDNOT_)] = "ABYb";
 | 
			
		||||
		cell_types[ID($_ORNOT_)] = "ABYb";
 | 
			
		||||
		cell_types[ID($_MUX_)] = "*";
 | 
			
		||||
		cell_types[ID($_NMUX_)] = "*";
 | 
			
		||||
		// cell_types[ID($_MUX4_)] = "*";
 | 
			
		||||
		// cell_types[ID($_MUX8_)] = "*";
 | 
			
		||||
		// cell_types[ID($_MUX16_)] = "*";
 | 
			
		||||
		cell_types[ID($_AOI3_)] = "ABCYb";
 | 
			
		||||
		cell_types[ID($_OAI3_)] = "ABCYb";
 | 
			
		||||
		cell_types[ID($_AOI4_)] = "ABCDYb";
 | 
			
		||||
		cell_types[ID($_OAI4_)] = "ABCDYb";
 | 
			
		||||
 | 
			
		||||
		if (list_all) {
 | 
			
		||||
			log("test_cell supports the following cell types:\n");
 | 
			
		||||
			for (auto it : cell_types)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue