mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-27 01:39:23 +00:00 
			
		
		
		
	xilinx: use specify blocks in place of abc9_{arrival,required}
This commit is contained in:
		
							parent
							
								
									0e7c55e2a7
								
							
						
					
					
						commit
						577545488a
					
				
					 3 changed files with 670 additions and 347 deletions
				
			
		
							
								
								
									
										15
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								README.md
									
										
									
									
									
								
							|  | @ -364,25 +364,14 @@ Verilog Attributes and non-standard features | ||||||
|   it as the external-facing pin of an I/O pad, and prevents ``iopadmap`` |   it as the external-facing pin of an I/O pad, and prevents ``iopadmap`` | ||||||
|   from inserting another pad cell on it. |   from inserting another pad cell on it. | ||||||
| 
 | 
 | ||||||
| - The module attribute ``abc9_box_id`` specifies a positive integer linking a | - The module attribute ``abc9_box`` is a boolean specifying a blackbox or | ||||||
|   blackbox or whitebox definition to a corresponding entry in a `abc9` |   whitebox definition for use by `abc9`. | ||||||
|   box-file. |  | ||||||
| 
 | 
 | ||||||
| - The port attribute ``abc9_carry`` marks the carry-in (if an input port) and | - The port attribute ``abc9_carry`` marks the carry-in (if an input port) and | ||||||
|   carry-out (if output port) ports of a box. This information is necessary for |   carry-out (if output port) ports of a box. This information is necessary for | ||||||
|   `abc9` to preserve the integrity of carry-chains. Specifying this attribute |   `abc9` to preserve the integrity of carry-chains. Specifying this attribute | ||||||
|   onto a bus port will affect only its most significant bit. |   onto a bus port will affect only its most significant bit. | ||||||
| 
 | 
 | ||||||
| - The output port attribute ``abc9_arrival`` specifies an integer, or a string |  | ||||||
|   of space-separated integers to be used as the arrival time of this blackbox |  | ||||||
|   port. It can be used, for example, to specify the clk-to-Q delay of a flip- |  | ||||||
|   flop output for consideration during `abc9` techmapping. |  | ||||||
| 
 |  | ||||||
| - The input port attribute ``abc9_required`` specifies an integer, or a string |  | ||||||
|   of space-separated integers to be used as the required time of this blackbox |  | ||||||
|   port. It can be used, for example, to specify the setup-time of a flip-flop |  | ||||||
|   input for consideration during `abc9` techmapping. |  | ||||||
| 
 |  | ||||||
| - The module attribute ``abc9_flop`` is a boolean marking the module as a | - The module attribute ``abc9_flop`` is a boolean marking the module as a | ||||||
|   flip-flop. This allows `abc9` to analyse its contents in order to perform |   flip-flop. This allows `abc9` to analyse its contents in order to perform | ||||||
|   sequential synthesis. |   sequential synthesis. | ||||||
|  |  | ||||||
|  | @ -70,54 +70,6 @@ void check(RTLIL::Design *design) | ||||||
| 					carry_out = port_name; | 					carry_out = port_name; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 
 |  | ||||||
| 			auto it = w->attributes.find("\\abc9_arrival"); |  | ||||||
| 			if (it != w->attributes.end()) { |  | ||||||
| 				int count = 0; |  | ||||||
| 				if (it->second.flags == 0) { |  | ||||||
| 					if (it->second.as_int() < 0) |  | ||||||
| 						log_error("%s.%s has negative arrival value %d!\n", log_id(m), log_id(port_name), |  | ||||||
| 								it->second.as_int()); |  | ||||||
| 					count++; |  | ||||||
| 				} |  | ||||||
| 				else |  | ||||||
| 					for (const auto &tok : split_tokens(it->second.decode_string())) { |  | ||||||
| 						if (tok.find_first_not_of("0123456789") != std::string::npos) |  | ||||||
| 							log_error("%s.%s has non-integer arrival value '%s'!\n", log_id(m), log_id(port_name), |  | ||||||
| 									tok.c_str()); |  | ||||||
| 						if (atoi(tok.c_str()) < 0) |  | ||||||
| 							log_error("%s.%s has negative arrival value %s!\n", log_id(m), log_id(port_name), |  | ||||||
| 									tok.c_str()); |  | ||||||
| 						count++; |  | ||||||
| 					} |  | ||||||
| 				if (count > 1 && count != GetSize(w)) |  | ||||||
| 					log_error("%s.%s is %d bits wide but abc9_arrival = %s has %d value(s)!\n", log_id(m), log_id(port_name), |  | ||||||
| 							GetSize(w), log_signal(it->second), count); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			it = w->attributes.find("\\abc9_required"); |  | ||||||
| 			if (it != w->attributes.end()) { |  | ||||||
| 				int count = 0; |  | ||||||
| 				if (it->second.flags == 0) { |  | ||||||
| 					if (it->second.as_int() < 0) |  | ||||||
| 						log_error("%s.%s has negative required value %d!\n", log_id(m), log_id(port_name), |  | ||||||
| 								it->second.as_int()); |  | ||||||
| 					count++; |  | ||||||
| 				} |  | ||||||
| 				else |  | ||||||
| 					for (const auto &tok : split_tokens(it->second.decode_string())) { |  | ||||||
| 						if (tok.find_first_not_of("0123456789") != std::string::npos) |  | ||||||
| 							log_error("%s.%s has non-integer required value '%s'!\n", log_id(m), log_id(port_name), |  | ||||||
| 									tok.c_str()); |  | ||||||
| 						if (atoi(tok.c_str()) < 0) |  | ||||||
| 							log_error("%s.%s has negative required value %s!\n", log_id(m), log_id(port_name), |  | ||||||
| 									tok.c_str()); |  | ||||||
| 						count++; |  | ||||||
| 					} |  | ||||||
| 				if (count > 1 && count != GetSize(w)) |  | ||||||
| 					log_error("%s.%s is %d bits wide but abc9_required = %s has %d value(s)!\n", log_id(m), log_id(port_name), |  | ||||||
| 							GetSize(w), log_signal(it->second), count); |  | ||||||
| 			} |  | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (carry_in != IdString() && carry_out == IdString()) | 		if (carry_in != IdString() && carry_out == IdString()) | ||||||
|  | @ -428,16 +380,15 @@ void prep_xaiger(RTLIL::Module *module, bool dff) | ||||||
| 
 | 
 | ||||||
| void prep_delays(RTLIL::Design *design) | void prep_delays(RTLIL::Design *design) | ||||||
| { | { | ||||||
| 	pool<Module*> flops; | 	// Derive and collect all blackbox modules, and collect all blackbox instantiations
 | ||||||
|  | 	pool<Module*> derived; | ||||||
| 	std::vector<Cell*> cells; | 	std::vector<Cell*> cells; | ||||||
| 	dict<IdString,dict<IdString,std::vector<int>>> requireds_cache; |  | ||||||
| 	for (auto module : design->selected_modules()) { | 	for (auto module : design->selected_modules()) { | ||||||
| 		if (module->processes.size() > 0) { | 		if (module->processes.size() > 0) { | ||||||
| 			log("Skipping module %s as it contains processes.\n", log_id(module)); | 			log("Skipping module %s as it contains processes.\n", log_id(module)); | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		cells.clear(); |  | ||||||
| 		for (auto cell : module->cells()) { | 		for (auto cell : module->cells()) { | ||||||
| 			if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_), ID($__ABC9_DELAY))) | 			if (cell->type.in(ID($_AND_), ID($_NOT_), ID($__ABC9_FF_), ID($__ABC9_DELAY))) | ||||||
| 				continue; | 				continue; | ||||||
|  | @ -447,22 +398,141 @@ void prep_delays(RTLIL::Design *design) | ||||||
| 				continue; | 				continue; | ||||||
| 			if (!inst_module->get_blackbox_attribute()) | 			if (!inst_module->get_blackbox_attribute()) | ||||||
| 				continue; | 				continue; | ||||||
| 			if (inst_module->get_bool_attribute(ID(abc9_flop))) { | 			if (inst_module->attributes.count(ID(abc9_box))) | ||||||
|  | 				continue; | ||||||
| 			IdString derived_type = inst_module->derive(design, cell->parameters); | 			IdString derived_type = inst_module->derive(design, cell->parameters); | ||||||
| 			inst_module = design->module(derived_type); | 			inst_module = design->module(derived_type); | ||||||
| 			log_assert(inst_module); | 			log_assert(inst_module); | ||||||
| 				flops.insert(inst_module); | 			derived.insert(inst_module); | ||||||
| 				continue; // because all flop required times
 | 
 | ||||||
| 				          //   will be captured in the flop box
 |  | ||||||
| 			} |  | ||||||
| 			if (inst_module->attributes.count(ID(abc9_box))) |  | ||||||
| 				continue; |  | ||||||
| 			cells.emplace_back(cell); | 			cells.emplace_back(cell); | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// Transform all $specify3 and $specrule to abc9_{arrival,required} attributes
 | ||||||
|  | 	std::vector<Module*> flops; | ||||||
|  | 	dict<SigBit, int> arrivals, requireds; | ||||||
|  | 	pool<Wire*> ports; | ||||||
|  | 	std::stringstream ss; | ||||||
|  | 	for (auto module : derived) { | ||||||
|  | 		if (module->get_bool_attribute(ID(abc9_flop))) | ||||||
|  | 			flops.push_back(module); | ||||||
|  | 
 | ||||||
|  | 		arrivals.clear(); | ||||||
|  | 		requireds.clear(); | ||||||
|  | 		for (auto cell : module->cells()) { | ||||||
|  | 			if (cell->type == ID($specify3)) { | ||||||
|  | 				auto src = cell->getPort(ID(SRC)); | ||||||
|  | 				auto dat = cell->getPort(ID(DAT)); | ||||||
|  | 				auto dst = cell->getPort(ID(DST)); | ||||||
|  | 				for (const auto &c : src.chunks()) | ||||||
|  | 					if (!c.wire->port_input) | ||||||
|  | 						log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src)); | ||||||
|  | 				for (const auto &c : dat.chunks()) | ||||||
|  | 					if (!c.wire->port_input) | ||||||
|  | 						log_error("Module '%s' contains specify cell '%s' where DAT '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(dat)); | ||||||
|  | 				for (const auto &c : dst.chunks()) | ||||||
|  | 					if (!c.wire->port_output) | ||||||
|  | 						log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module output.\n", log_id(module), log_id(cell), log_signal(dst)); | ||||||
|  | 				if (!cell->getParam(ID(EDGE_EN)).as_bool()) | ||||||
|  | 					continue; | ||||||
|  | 				int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int(); | ||||||
|  | 				int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int(); | ||||||
|  | 				int max = std::max(rise_max,fall_max); | ||||||
|  | 				if (max < 0) { | ||||||
|  | 					log_warning("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell)); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 				for (auto d : dst) | ||||||
|  | 					arrivals[d] = std::max(arrivals[d], max); | ||||||
|  | 			} | ||||||
|  | 			else if (cell->type == ID($specrule)) { | ||||||
|  | 				auto type = cell->getParam(ID(TYPE)).decode_string(); | ||||||
|  | 				if (type != "$setup" && type != "$setuphold") | ||||||
|  | 					continue; | ||||||
|  | 				auto src = cell->getPort(ID(SRC)); | ||||||
|  | 				auto dst = cell->getPort(ID(DST)); | ||||||
|  | 				for (const auto &c : src.chunks()) | ||||||
|  | 					if (!c.wire->port_input) | ||||||
|  | 						log_error("Module '%s' contains specify cell '%s' where SRC '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(src)); | ||||||
|  | 				for (const auto &c : dst.chunks()) | ||||||
|  | 					if (!c.wire->port_input) | ||||||
|  | 						log_error("Module '%s' contains specify cell '%s' where DST '%s' is not a module input.\n", log_id(module), log_id(cell), log_signal(dst)); | ||||||
|  | 				int setup = cell->getParam(ID(T_LIMIT)).as_int(); | ||||||
|  | 				if (setup < 0) { | ||||||
|  | 					log_warning("Module '%s' contains specify cell '%s' with T_LIMIT < 0 which is currently unsupported. Ignoring.\n", log_id(module), log_id(cell)); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 				for (const auto &s : src) | ||||||
|  | 					requireds[s] = std::max(requireds[s], setup); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (arrivals.empty() && requireds.empty()) | ||||||
|  | 			continue; | ||||||
|  | 
 | ||||||
|  | 		ports.clear(); | ||||||
|  | 		for (const auto &i : arrivals) | ||||||
|  | 			ports.insert(i.first.wire); | ||||||
|  | 		for (auto wire : ports) { | ||||||
|  | 			log_assert(wire->port_output); | ||||||
|  | 			ss.str(""); | ||||||
|  | 			if (GetSize(wire) == 1) | ||||||
|  | 				wire->attributes[ID(abc9_arrival)] = arrivals.at(SigBit(wire,0)); | ||||||
|  | 			else { | ||||||
|  | 				bool first = true; | ||||||
|  | 				for (auto b : SigSpec(wire)) { | ||||||
|  | 					if (first) | ||||||
|  | 						first = false; | ||||||
|  | 					else | ||||||
|  | 						ss << " "; | ||||||
|  | 					auto it = arrivals.find(b); | ||||||
|  | 					if (it == arrivals.end()) | ||||||
|  | 						ss << "0"; | ||||||
|  | 					else | ||||||
|  | 						ss << it->second; | ||||||
|  | 				} | ||||||
|  | 				wire->attributes[ID(abc9_arrival)] = ss.str(); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		ports.clear(); | ||||||
|  | 		for (const auto &i : requireds) | ||||||
|  | 			ports.insert(i.first.wire); | ||||||
|  | 		for (auto wire : ports) { | ||||||
|  | 			log_assert(wire->port_input); | ||||||
|  | 			ss.str(""); | ||||||
|  | 			if (GetSize(wire) == 1) | ||||||
|  | 				wire->attributes[ID(abc9_required)] = requireds.at(SigBit(wire,0)); | ||||||
|  | 			else { | ||||||
|  | 				bool first = true; | ||||||
|  | 				for (auto b : SigSpec(wire)) { | ||||||
|  | 					if (first) | ||||||
|  | 						first = false; | ||||||
|  | 					else | ||||||
|  | 						ss << " "; | ||||||
|  | 					auto it = requireds.find(b); | ||||||
|  | 					if (it == requireds.end()) | ||||||
|  | 						ss << "0"; | ||||||
|  | 					else | ||||||
|  | 						ss << it->second; | ||||||
|  | 				} | ||||||
|  | 				wire->attributes[ID(abc9_required)] = ss.str(); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Insert $__ABC9_DELAY cells on all cells that instantiate blackboxes
 | ||||||
|  | 	//   with (* abc9_required *) attributes
 | ||||||
|  | 	dict<IdString,dict<IdString,std::vector<int>>> requireds_cache; | ||||||
| 	for (auto cell : cells) { | 	for (auto cell : cells) { | ||||||
|  | 		auto module = cell->module; | ||||||
| 		RTLIL::Module* inst_module = module->design->module(cell->type); | 		RTLIL::Module* inst_module = module->design->module(cell->type); | ||||||
| 		log_assert(inst_module); | 		log_assert(inst_module); | ||||||
|  | 		IdString derived_type = inst_module->derive(design, cell->parameters); | ||||||
|  | 		inst_module = design->module(derived_type); | ||||||
|  | 		log_assert(inst_module); | ||||||
|  | 
 | ||||||
| 		auto &cell_requireds = requireds_cache[cell->type]; | 		auto &cell_requireds = requireds_cache[cell->type]; | ||||||
| 		for (auto &conn : cell->connections_) { | 		for (auto &conn : cell->connections_) { | ||||||
| 			auto port_wire = inst_module->wire(conn.first); | 			auto port_wire = inst_module->wire(conn.first); | ||||||
|  | @ -508,58 +578,6 @@ void prep_delays(RTLIL::Design *design) | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	int abc9_box_id = design->scratchpad_get_int("abc9_ops.box_id"); |  | ||||||
| 	std::stringstream ss; |  | ||||||
| 	for (auto flop_module : flops) { |  | ||||||
| 		int num_inputs = 0, num_outputs = 0; |  | ||||||
| 		for (auto port_name : flop_module->ports) { |  | ||||||
| 			auto wire = flop_module->wire(port_name); |  | ||||||
| 			log_assert(GetSize(wire) == 1); |  | ||||||
| 			if (wire->port_input) num_inputs++; |  | ||||||
| 			if (wire->port_output) num_outputs++; |  | ||||||
| 		} |  | ||||||
| 		log_assert(num_outputs == 1); |  | ||||||
| 
 |  | ||||||
| 		auto r = flop_module->attributes.insert(ID(abc9_box_id)); |  | ||||||
| 		if (r.second) |  | ||||||
| 			r.first->second = ++abc9_box_id; |  | ||||||
| 
 |  | ||||||
| 		ss << log_id(flop_module) << " " << r.first->second.as_int(); |  | ||||||
| 		ss << " " << (flop_module->get_bool_attribute(ID::whitebox) ? "1" : "0"); |  | ||||||
| 		ss << " " << num_inputs+1 << " " << num_outputs << std::endl; |  | ||||||
| 
 |  | ||||||
| 		ss << "#"; |  | ||||||
| 		bool first = true; |  | ||||||
| 		for (auto port_name : flop_module->ports) { |  | ||||||
| 			auto wire = flop_module->wire(port_name); |  | ||||||
| 			if (!wire->port_input) |  | ||||||
| 				continue; |  | ||||||
| 			if (first) |  | ||||||
| 				first = false; |  | ||||||
| 			else |  | ||||||
| 				ss << " "; |  | ||||||
| 			ss << log_id(wire); |  | ||||||
| 		} |  | ||||||
| 		ss << " abc9_ff.Q" << std::endl; |  | ||||||
| 
 |  | ||||||
| 		first = true; |  | ||||||
| 		for (auto port_name : flop_module->ports) { |  | ||||||
| 			auto wire = flop_module->wire(port_name); |  | ||||||
| 			if (!wire->port_input) |  | ||||||
| 				continue; |  | ||||||
| 			if (first) |  | ||||||
| 				first = false; |  | ||||||
| 			else |  | ||||||
| 				ss << " "; |  | ||||||
| 			ss << wire->attributes.at("\\abc9_required", 0).as_int(); |  | ||||||
| 		} |  | ||||||
| 		// Last input is 'abc9_ff.Q'
 |  | ||||||
| 		ss << " 0" << std::endl << std::endl; |  | ||||||
| 	} |  | ||||||
| 	design->scratchpad_set_string("abc9_ops.box_library.flops", ss.str()); |  | ||||||
| 	design->scratchpad_set_int("abc9_ops.box_id", abc9_box_id); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void prep_lut(RTLIL::Design *design, int maxlut) | void prep_lut(RTLIL::Design *design, int maxlut) | ||||||
|  | @ -587,7 +605,10 @@ void prep_lut(RTLIL::Design *design, int maxlut) | ||||||
| 				log_assert(o == d); | 				log_assert(o == d); | ||||||
| 			int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int(); | 			int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int(); | ||||||
| 			int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int(); | 			int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int(); | ||||||
| 			specify.push_back(std::max(rise_max,fall_max)); | 			int max = std::max(rise_max,fall_max); | ||||||
|  | 			if (max < 0) | ||||||
|  | 				log_error("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0.\n", log_id(module), log_id(cell)); | ||||||
|  | 			specify.push_back(max); | ||||||
| 		} | 		} | ||||||
| 		if (maxlut && GetSize(specify) > maxlut) | 		if (maxlut && GetSize(specify) > maxlut) | ||||||
| 			continue; | 			continue; | ||||||
|  | @ -618,10 +639,57 @@ void write_lut(RTLIL::Module *module, const std::string &dst) { | ||||||
| void prep_box(RTLIL::Design *design) | void prep_box(RTLIL::Design *design) | ||||||
| { | { | ||||||
| 	std::stringstream ss; | 	std::stringstream ss; | ||||||
| 	ss << design->scratchpad_get_string("abc9_ops.box_library.flops", ss.str()); | 	int abc9_box_id = 1; | ||||||
| 
 | 	dict<IdString,std::vector<IdString>> box_ports; | ||||||
| 	int abc9_box_id = design->scratchpad_get_int("abc9_ops.box_id"); |  | ||||||
| 	for (auto module : design->modules()) { | 	for (auto module : design->modules()) { | ||||||
|  | 		if (module->get_bool_attribute(ID(abc9_flop))) { | ||||||
|  | 			int num_inputs = 0, num_outputs = 0; | ||||||
|  | 			for (auto port_name : module->ports) { | ||||||
|  | 				auto wire = module->wire(port_name); | ||||||
|  | 				log_assert(GetSize(wire) == 1); | ||||||
|  | 				if (wire->port_input) num_inputs++; | ||||||
|  | 				if (wire->port_output) num_outputs++; | ||||||
|  | 			} | ||||||
|  | 			log_assert(num_outputs == 1); | ||||||
|  | 
 | ||||||
|  | 			auto r = module->attributes.insert(ID(abc9_box_id)); | ||||||
|  | 			if (r.second) | ||||||
|  | 				r.first->second = abc9_box_id++; | ||||||
|  | 
 | ||||||
|  | 			ss << log_id(module) << " " << r.first->second.as_int(); | ||||||
|  | 			ss << " " << (module->get_bool_attribute(ID::whitebox) ? "1" : "0"); | ||||||
|  | 			ss << " " << num_inputs+1 << " " << num_outputs << std::endl; | ||||||
|  | 
 | ||||||
|  | 			ss << "#"; | ||||||
|  | 			bool first = true; | ||||||
|  | 			for (auto port_name : module->ports) { | ||||||
|  | 				auto wire = module->wire(port_name); | ||||||
|  | 				if (!wire->port_input) | ||||||
|  | 					continue; | ||||||
|  | 				if (first) | ||||||
|  | 					first = false; | ||||||
|  | 				else | ||||||
|  | 					ss << " "; | ||||||
|  | 				ss << log_id(wire); | ||||||
|  | 			} | ||||||
|  | 			ss << " abc9_ff.Q" << std::endl; | ||||||
|  | 
 | ||||||
|  | 			first = true; | ||||||
|  | 			for (auto port_name : module->ports) { | ||||||
|  | 				auto wire = module->wire(port_name); | ||||||
|  | 				if (!wire->port_input) | ||||||
|  | 					continue; | ||||||
|  | 				if (first) | ||||||
|  | 					first = false; | ||||||
|  | 				else | ||||||
|  | 					ss << " "; | ||||||
|  | 				ss << wire->attributes.at("\\abc9_required", 0).as_int(); | ||||||
|  | 			} | ||||||
|  | 			// Last input is 'abc9_ff.Q'
 | ||||||
|  | 			ss << " 0" << std::endl << std::endl; | ||||||
|  | 			continue; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		auto it = module->attributes.find(ID(abc9_box)); | 		auto it = module->attributes.find(ID(abc9_box)); | ||||||
| 		if (it == module->attributes.end()) | 		if (it == module->attributes.end()) | ||||||
| 			continue; | 			continue; | ||||||
|  | @ -631,7 +699,33 @@ void prep_box(RTLIL::Design *design) | ||||||
| 		dict<std::pair<SigBit,SigBit>, std::string> table; | 		dict<std::pair<SigBit,SigBit>, std::string> table; | ||||||
| 		std::vector<SigBit> inputs; | 		std::vector<SigBit> inputs; | ||||||
| 		std::vector<SigBit> outputs; | 		std::vector<SigBit> outputs; | ||||||
| 		for (auto port_name : module->ports) { | 
 | ||||||
|  | 		auto r = box_ports.insert(module->name); | ||||||
|  | 		if (r.second) { | ||||||
|  | 			// Make carry in the last PI, and carry out the last PO
 | ||||||
|  | 			//   since ABC requires it this way
 | ||||||
|  | 			IdString carry_in, carry_out; | ||||||
|  | 			for (const auto &port_name : module->ports) { | ||||||
|  | 				auto w = module->wire(port_name); | ||||||
|  | 				log_assert(w); | ||||||
|  | 				if (w->get_bool_attribute("\\abc9_carry")) { | ||||||
|  | 					log_assert(w->port_input != w->port_output); | ||||||
|  | 					if (w->port_input) | ||||||
|  | 						carry_in = port_name; | ||||||
|  | 					else if (w->port_output) | ||||||
|  | 						carry_out = port_name; | ||||||
|  | 				} | ||||||
|  | 				else | ||||||
|  | 					r.first->second.push_back(port_name); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (carry_in != IdString()) { | ||||||
|  | 				r.first->second.push_back(carry_in); | ||||||
|  | 				r.first->second.push_back(carry_out); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		for (auto port_name : r.first->second) { | ||||||
| 			auto wire = module->wire(port_name); | 			auto wire = module->wire(port_name); | ||||||
| 			if (wire->port_input) | 			if (wire->port_input) | ||||||
| 				for (int i = 0; i < GetSize(wire); i++) | 				for (int i = 0; i < GetSize(wire); i++) | ||||||
|  | @ -654,6 +748,9 @@ void prep_box(RTLIL::Design *design) | ||||||
| 			int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int(); | 			int rise_max = cell->getParam(ID(T_RISE_MAX)).as_int(); | ||||||
| 			int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int(); | 			int fall_max = cell->getParam(ID(T_FALL_MAX)).as_int(); | ||||||
| 			int max = std::max(rise_max,fall_max); | 			int max = std::max(rise_max,fall_max); | ||||||
|  | 			if (max < 0) | ||||||
|  | 				log_error("Module '%s' contains specify cell '%s' with T_{RISE,FALL}_MAX < 0.\n", log_id(module), log_id(cell)); | ||||||
|  | 			if (cell->getParam(ID(FULL)).as_bool()) { | ||||||
| 				for (auto s : src) | 				for (auto s : src) | ||||||
| 					for (auto d : dst) { | 					for (auto d : dst) { | ||||||
| 						auto r = table.insert(std::make_pair(s,d)); | 						auto r = table.insert(std::make_pair(s,d)); | ||||||
|  | @ -661,10 +758,19 @@ void prep_box(RTLIL::Design *design) | ||||||
| 						r.first->second = std::to_string(max); | 						r.first->second = std::to_string(max); | ||||||
| 					} | 					} | ||||||
| 			} | 			} | ||||||
| 		auto r = module->attributes.insert(ID(abc9_box_id)); | 			else { | ||||||
|  | 				log_assert(GetSize(src) == GetSize(dst)); | ||||||
|  | 				for (auto i = 0; i < GetSize(src); i++) { | ||||||
|  | 					auto r = table.insert(std::make_pair(src[i],dst[i])); | ||||||
| 					log_assert(r.second); | 					log_assert(r.second); | ||||||
| 		r.first->second = ++abc9_box_id; | 					r.first->second = std::to_string(max); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		auto r2 = module->attributes.insert(ID(abc9_box_id)); | ||||||
|  | 		log_assert(r2.second); | ||||||
| 		ss << log_id(module) << " " << abc9_box_id; | 		ss << log_id(module) << " " << abc9_box_id; | ||||||
|  | 		r2.first->second = abc9_box_id++; | ||||||
| 		ss << " " << (module->get_bool_attribute(ID::whitebox) ? "1" : "0"); | 		ss << " " << (module->get_bool_attribute(ID::whitebox) ? "1" : "0"); | ||||||
| 		ss << " " << GetSize(inputs) << " " << GetSize(outputs) << std::endl; | 		ss << " " << GetSize(inputs) << " " << GetSize(outputs) << std::endl; | ||||||
| 		bool first = true; | 		bool first = true; | ||||||
|  | @ -700,17 +806,17 @@ void prep_box(RTLIL::Design *design) | ||||||
| 		ss << std::endl; | 		ss << std::endl; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// ABC expects at least one box
 | ||||||
|  | 	if (ss.tellp() == 0) | ||||||
|  | 		ss << "(dummy) 1 0 0 0"; | ||||||
|  | 
 | ||||||
| 	design->scratchpad_set_string("abc9_ops.box_library", ss.str()); | 	design->scratchpad_set_string("abc9_ops.box_library", ss.str()); | ||||||
| 	design->scratchpad_set_int("abc9_ops.box_id", abc9_box_id); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void write_box(RTLIL::Module *module, const std::string &dst) { | void write_box(RTLIL::Module *module, const std::string &dst) { | ||||||
| 	std::ofstream ofs(dst); | 	std::ofstream ofs(dst); | ||||||
| 	log_assert(ofs.is_open()); | 	log_assert(ofs.is_open()); | ||||||
| 	ofs << module->design->scratchpad_get_string("abc9_ops.box_library"); | 	ofs << module->design->scratchpad_get_string("abc9_ops.box_library"); | ||||||
| 	// ABC expects at least one box
 |  | ||||||
| 	if (ofs.tellp() == 0) |  | ||||||
| 		ofs << "(dummy) 1 0 0 0"; |  | ||||||
| 	ofs.close(); | 	ofs.close(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -477,18 +477,14 @@ endmodule | ||||||
| 
 | 
 | ||||||
| (* abc9_flop, lib_whitebox *) | (* abc9_flop, lib_whitebox *) | ||||||
| module FDRE ( | module FDRE ( | ||||||
|   (* abc9_arrival=303 *) |  | ||||||
|   output reg Q, |   output reg Q, | ||||||
|   (* clkbuf_sink *) |   (* clkbuf_sink *) | ||||||
|   (* invertible_pin = "IS_C_INVERTED" *) |   (* invertible_pin = "IS_C_INVERTED" *) | ||||||
|   input C, |   input C, | ||||||
|   (* abc9_required=109 *) |  | ||||||
|   input CE, |   input CE, | ||||||
|   (* invertible_pin = "IS_D_INVERTED" *) |   (* invertible_pin = "IS_D_INVERTED" *) | ||||||
|   //(* abc9_required=-46 *) // Negative required times not currently supported |  | ||||||
|   input D, |   input D, | ||||||
|   (* invertible_pin = "IS_R_INVERTED" *) |   (* invertible_pin = "IS_R_INVERTED" *) | ||||||
|   (* abc9_required=404 *) |  | ||||||
|   input R |   input R | ||||||
| ); | ); | ||||||
|   parameter [0:0] INIT = 1'b0; |   parameter [0:0] INIT = 1'b0; | ||||||
|  | @ -496,44 +492,58 @@ module FDRE ( | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |   parameter [0:0] IS_D_INVERTED = 1'b0; | ||||||
|   parameter [0:0] IS_R_INVERTED = 1'b0; |   parameter [0:0] IS_R_INVERTED = 1'b0; | ||||||
|   initial Q <= INIT; |   initial Q <= INIT; | ||||||
|   generate case (|IS_C_INVERTED) |   generate | ||||||
|  |   case (|IS_C_INVERTED) | ||||||
|     1'b0: always @(posedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; |     1'b0: always @(posedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; | ||||||
|     1'b1: always @(negedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; |     1'b1: always @(negedge C) if (R == !IS_R_INVERTED) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; | ||||||
|   endcase endgenerate |   endcase | ||||||
|  |   if (!IS_C_INVERTED) | ||||||
|  |     specify | ||||||
|  |       if (CE) (posedge C => (Q : D)) = 303; | ||||||
|  |       //$setup(D , posedge C, -46); // Negative times not currently supported | ||||||
|  |       $setup(CE, posedge C, 109); | ||||||
|  |       $setup(R , posedge C, 404); | ||||||
|  |     endspecify | ||||||
|  |   else | ||||||
|  |     specify | ||||||
|  |       if (CE) (negedge C => (Q : D)) = 303; | ||||||
|  |       //if (CE) $setup(D , negedge C, -46); // Negative times not currently supported | ||||||
|  |       $setup(CE, negedge C, 109); | ||||||
|  |       $setup(R , negedge C, 404); | ||||||
|  |     endspecify | ||||||
|  |   endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| (* abc9_flop, lib_whitebox *) | (* abc9_flop, lib_whitebox *) | ||||||
| module FDRE_1 ( | module FDRE_1 ( | ||||||
|   (* abc9_arrival=303 *) |  | ||||||
|   output reg Q, |   output reg Q, | ||||||
|   (* clkbuf_sink *) |   (* clkbuf_sink *) | ||||||
|   input C, |   input C, | ||||||
|   (* abc9_required=109 *) |  | ||||||
|   input CE, |   input CE, | ||||||
|   //(* abc9_required=-46 *) // Negative required times not currently supported |  | ||||||
|   input D, |   input D, | ||||||
|   (* abc9_required=404 *) |  | ||||||
|   input R |   input R | ||||||
| ); | ); | ||||||
|   parameter [0:0] INIT = 1'b0; |   parameter [0:0] INIT = 1'b0; | ||||||
|   initial Q <= INIT; |   initial Q <= INIT; | ||||||
|   always @(negedge C) if (R) Q <= 1'b0; else if (CE) Q <= D; |   always @(negedge C) if (R) Q <= 1'b0; else if (CE) Q <= D; | ||||||
|  |   specify | ||||||
|  |     if (CE) (negedge C => (Q : D)) = 303; | ||||||
|  |     //if (CE) $setup(D , negedge C, -46); // Negative times not currently supported | ||||||
|  |     $setup(CE, negedge C, 109); | ||||||
|  |     $setup(R , negedge C, 404); | ||||||
|  |   endspecify | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| (* abc9_flop, lib_whitebox *) | (* abc9_flop, lib_whitebox *) | ||||||
| module FDSE ( | module FDSE ( | ||||||
|   (* abc9_arrival=303 *) |  | ||||||
|   output reg Q, |   output reg Q, | ||||||
|   (* clkbuf_sink *) |   (* clkbuf_sink *) | ||||||
|   (* invertible_pin = "IS_C_INVERTED" *) |   (* invertible_pin = "IS_C_INVERTED" *) | ||||||
|   input C, |   input C, | ||||||
|   (* abc9_required=109 *) |  | ||||||
|   input CE, |   input CE, | ||||||
|   (* invertible_pin = "IS_D_INVERTED" *) |   (* invertible_pin = "IS_D_INVERTED" *) | ||||||
|   //(* abc9_required=-46 *) // Negative required times not currently supported |  | ||||||
|   input D, |   input D, | ||||||
|   (* invertible_pin = "IS_S_INVERTED" *) |   (* invertible_pin = "IS_S_INVERTED" *) | ||||||
|   (* abc9_required=404 *) |  | ||||||
|   input S |   input S | ||||||
| ); | ); | ||||||
|   parameter [0:0] INIT = 1'b1; |   parameter [0:0] INIT = 1'b1; | ||||||
|  | @ -541,28 +551,46 @@ module FDSE ( | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |   parameter [0:0] IS_D_INVERTED = 1'b0; | ||||||
|   parameter [0:0] IS_S_INVERTED = 1'b0; |   parameter [0:0] IS_S_INVERTED = 1'b0; | ||||||
|   initial Q <= INIT; |   initial Q <= INIT; | ||||||
|   generate case (|IS_C_INVERTED) |   generate | ||||||
|  |   case (|IS_C_INVERTED) | ||||||
|     1'b0: always @(posedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; |     1'b0: always @(posedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; | ||||||
|     1'b1: always @(negedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; |     1'b1: always @(negedge C) if (S == !IS_S_INVERTED) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; | ||||||
|   endcase endgenerate |   endcase | ||||||
|  |   if (!IS_C_INVERTED) | ||||||
|  |     specify | ||||||
|  |       if (CE) (posedge C => (Q : D)) = 303; | ||||||
|  |       //if (CE) $setup(D , posedge C, -46); // Negative times not currently supported | ||||||
|  |       $setup(CE, posedge C, 109); | ||||||
|  |       $setup(S , posedge C, 404); | ||||||
|  |     endspecify | ||||||
|  |   else | ||||||
|  |     specify | ||||||
|  |         if (CE) (negedge C => (Q : D)) = 303; | ||||||
|  |         //if (CE) $setup(D , negedge C, -46); // Negative times not currently supported | ||||||
|  |         $setup(CE, negedge C, 109); | ||||||
|  |         $setup(S , negedge C, 404); | ||||||
|  |     endspecify | ||||||
|  |   endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| (* abc9_flop, lib_whitebox *) | (* abc9_flop, lib_whitebox *) | ||||||
| module FDSE_1 ( | module FDSE_1 ( | ||||||
|   (* abc9_arrival=303 *) |  | ||||||
|   output reg Q, |   output reg Q, | ||||||
|   (* clkbuf_sink *) |   (* clkbuf_sink *) | ||||||
|   input C, |   input C, | ||||||
|   (* abc9_required=109 *) |  | ||||||
|   input CE, |   input CE, | ||||||
|   //(* abc9_required=-46 *) // Negative required times not currently supported |  | ||||||
|   input D, |   input D, | ||||||
|   (* abc9_required=404 *) |  | ||||||
|   input S |   input S | ||||||
| ); | ); | ||||||
|   parameter [0:0] INIT = 1'b1; |   parameter [0:0] INIT = 1'b1; | ||||||
|   initial Q <= INIT; |   initial Q <= INIT; | ||||||
|   always @(negedge C) if (S) Q <= 1'b1; else if (CE) Q <= D; |   always @(negedge C) if (S) Q <= 1'b1; else if (CE) Q <= D; | ||||||
|  |   specify | ||||||
|  |     if (CE) (negedge C => (Q : D)) = 303; | ||||||
|  |     //if (CE) $setup(D , negedge C, -46); // Negative times not currently supported | ||||||
|  |     $setup(CE, negedge C, 109); | ||||||
|  |     $setup(S , negedge C, 404); | ||||||
|  |   endspecify | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDRSE ( | module FDRSE ( | ||||||
|  | @ -571,7 +599,6 @@ module FDRSE ( | ||||||
|   (* invertible_pin = "IS_C_INVERTED" *) |   (* invertible_pin = "IS_C_INVERTED" *) | ||||||
|   input C, |   input C, | ||||||
|   (* invertible_pin = "IS_CE_INVERTED" *) |   (* invertible_pin = "IS_CE_INVERTED" *) | ||||||
|   (* abc9_required=109 *) |  | ||||||
|   input CE, |   input CE, | ||||||
|   (* invertible_pin = "IS_D_INVERTED" *) |   (* invertible_pin = "IS_D_INVERTED" *) | ||||||
|   input D, |   input D, | ||||||
|  | @ -603,18 +630,14 @@ endmodule | ||||||
| 
 | 
 | ||||||
| (* abc9_flop, lib_whitebox *) | (* abc9_flop, lib_whitebox *) | ||||||
| module FDCE ( | module FDCE ( | ||||||
|   (* abc9_arrival=303 *) |  | ||||||
|   output reg Q, |   output reg Q, | ||||||
|   (* clkbuf_sink *) |   (* clkbuf_sink *) | ||||||
|   (* invertible_pin = "IS_C_INVERTED" *) |   (* invertible_pin = "IS_C_INVERTED" *) | ||||||
|   input C, |   input C, | ||||||
|   (* abc9_required=109 *) |  | ||||||
|   input CE, |   input CE, | ||||||
|   (* invertible_pin = "IS_CLR_INVERTED" *) |   (* invertible_pin = "IS_CLR_INVERTED" *) | ||||||
|   (* abc9_required=764 *) |  | ||||||
|   input CLR, |   input CLR, | ||||||
|   (* invertible_pin = "IS_D_INVERTED" *) |   (* invertible_pin = "IS_D_INVERTED" *) | ||||||
|   //(* abc9_required=-46 *) // Negative required times not currently supported |  | ||||||
|   input D |   input D | ||||||
| ); | ); | ||||||
|   parameter [0:0] INIT = 1'b0; |   parameter [0:0] INIT = 1'b0; | ||||||
|  | @ -622,46 +645,60 @@ module FDCE ( | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |   parameter [0:0] IS_D_INVERTED = 1'b0; | ||||||
|   parameter [0:0] IS_CLR_INVERTED = 1'b0; |   parameter [0:0] IS_CLR_INVERTED = 1'b0; | ||||||
|   initial Q <= INIT; |   initial Q <= INIT; | ||||||
|   generate case ({|IS_C_INVERTED, |IS_CLR_INVERTED}) |   generate | ||||||
|  |   case ({|IS_C_INVERTED, |IS_CLR_INVERTED}) | ||||||
|     2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; |     2'b00: always @(posedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; | ||||||
|     2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; |     2'b01: always @(posedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; | ||||||
|     2'b10: always @(negedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; |     2'b10: always @(negedge C, posedge CLR) if ( CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; | ||||||
|     2'b11: always @(negedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; |     2'b11: always @(negedge C, negedge CLR) if (!CLR) Q <= 1'b0; else if (CE) Q <= D ^ IS_D_INVERTED; | ||||||
|   endcase endgenerate |   endcase | ||||||
|  |   if (!IS_C_INVERTED) | ||||||
|  |     specify | ||||||
|  |       if (CE) (posedge C => (Q : D)) = 303; | ||||||
|  |       //if (CE) $setup(D  , posedge C, -46); // Negative times not currently supported | ||||||
|  |       $setup(CE , posedge C, 109); | ||||||
|  |       $setup(CLR, posedge C, 764); | ||||||
|  |     endspecify | ||||||
|  |   else | ||||||
|  |     specify | ||||||
|  |         if (CE) (negedge C => (Q : D)) = 303; | ||||||
|  |         //if (CE) $setup(D  , negedge C, -46); // Negative times not currently supported | ||||||
|  |         $setup(CE , negedge C, 109); | ||||||
|  |         $setup(CLR, negedge C, 764); | ||||||
|  |     endspecify | ||||||
|  |  endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| (* abc9_flop, lib_whitebox *) | (* abc9_flop, lib_whitebox *) | ||||||
| module FDCE_1 ( | module FDCE_1 ( | ||||||
|   (* abc9_arrival=303 *) |  | ||||||
|   output reg Q, |   output reg Q, | ||||||
|   (* clkbuf_sink *) |   (* clkbuf_sink *) | ||||||
|   input C, |   input C, | ||||||
|   (* abc9_required=109 *) |  | ||||||
|   input CE, |   input CE, | ||||||
|   (* abc9_required=764 *) |  | ||||||
|   input CLR, |   input CLR, | ||||||
|   //(* abc9_required=-46 *) // Negative required times not currently supported |  | ||||||
|   input D |   input D | ||||||
| ); | ); | ||||||
|   parameter [0:0] INIT = 1'b0; |   parameter [0:0] INIT = 1'b0; | ||||||
|   initial Q <= INIT; |   initial Q <= INIT; | ||||||
|   always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D; |   always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D; | ||||||
|  |   specify | ||||||
|  |     if (CE) (negedge C => (Q : D)) = 303; | ||||||
|  |     //if (CE) $setup(D  , negedge C, -46); // Negative times not currently supported | ||||||
|  |     $setup(CE , negedge C, 109); | ||||||
|  |     $setup(CLR, negedge C, 764); | ||||||
|  |   endspecify | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| (* abc9_flop, lib_whitebox *) | (* abc9_flop, lib_whitebox *) | ||||||
| module FDPE ( | module FDPE ( | ||||||
|   (* abc9_arrival=303 *) |  | ||||||
|   output reg Q, |   output reg Q, | ||||||
|   (* clkbuf_sink *) |   (* clkbuf_sink *) | ||||||
|   (* invertible_pin = "IS_C_INVERTED" *) |   (* invertible_pin = "IS_C_INVERTED" *) | ||||||
|   input C, |   input C, | ||||||
|   (* abc9_required=109 *) |  | ||||||
|   input CE, |   input CE, | ||||||
|   (* invertible_pin = "IS_D_INVERTED" *) |   (* invertible_pin = "IS_D_INVERTED" *) | ||||||
|   //(* abc9_required=-46 *) // Negative required times not currently supported |  | ||||||
|   input D, |   input D, | ||||||
|   (* invertible_pin = "IS_PRE_INVERTED" *) |   (* invertible_pin = "IS_PRE_INVERTED" *) | ||||||
|   (* abc9_required=764 *) |  | ||||||
|   input PRE |   input PRE | ||||||
| ); | ); | ||||||
|   parameter [0:0] INIT = 1'b1; |   parameter [0:0] INIT = 1'b1; | ||||||
|  | @ -674,25 +711,42 @@ module FDPE ( | ||||||
|     2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; |     2'b01: always @(posedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; | ||||||
|     2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; |     2'b10: always @(negedge C, posedge PRE) if ( PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; | ||||||
|     2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; |     2'b11: always @(negedge C, negedge PRE) if (!PRE) Q <= 1'b1; else if (CE) Q <= D ^ IS_D_INVERTED; | ||||||
|   endcase endgenerate |   endcase | ||||||
|  |   if (!IS_C_INVERTED) | ||||||
|  |     specify | ||||||
|  |       if (CE) (posedge C => (Q : D)) = 303; | ||||||
|  |       //if (CE) $setup(D  , posedge C, -46); // Negative times not currently supported | ||||||
|  |       $setup(CE , posedge C, 109); | ||||||
|  |       $setup(PRE, posedge C, 764); | ||||||
|  |     endspecify | ||||||
|  |   else | ||||||
|  |     specify | ||||||
|  |         if (CE) (negedge C => (Q : D)) = 303; | ||||||
|  |         //if (CE) $setup(D  , negedge C, -46); // Negative times not currently supported | ||||||
|  |         $setup(CE , negedge C, 109); | ||||||
|  |         $setup(PRE, negedge C, 764); | ||||||
|  |     endspecify | ||||||
|  |   endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| (* abc9_flop, lib_whitebox *) | (* abc9_flop, lib_whitebox *) | ||||||
| module FDPE_1 ( | module FDPE_1 ( | ||||||
|   (* abc9_arrival=303 *) |  | ||||||
|   output reg Q, |   output reg Q, | ||||||
|   (* clkbuf_sink *) |   (* clkbuf_sink *) | ||||||
|   input C, |   input C, | ||||||
|   (* abc9_required=109 *) |  | ||||||
|   input CE, |   input CE, | ||||||
|   //(* abc9_required=-46 *) // Negative required times not currently supported |  | ||||||
|   input D, |   input D, | ||||||
|   (* abc9_required=764 *) |  | ||||||
|   input PRE |   input PRE | ||||||
| ); | ); | ||||||
|   parameter [0:0] INIT = 1'b1; |   parameter [0:0] INIT = 1'b1; | ||||||
|   initial Q <= INIT; |   initial Q <= INIT; | ||||||
|   always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; |   always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D; | ||||||
|  |   specify | ||||||
|  |     if (CE) (negedge C => (Q : D)) = 303; | ||||||
|  |     //if (CE) $setup(D  , negedge C, -46); // Negative times not currently supported | ||||||
|  |     $setup(CE , negedge C, 109); | ||||||
|  |     $setup(PRE, negedge C, 764); | ||||||
|  |   endspecify | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDCPE ( | module FDCPE ( | ||||||
|  | @ -1303,33 +1357,13 @@ module RAM16X1D_1 ( | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAM32X1D ( | module RAM32X1D ( | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981 |  | ||||||
|   (* abc9_arrival=1153 *) |  | ||||||
|   output DPO, SPO, |   output DPO, SPO, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986 |  | ||||||
|   (* abc9_required=453 *) |  | ||||||
|   input  D, |   input  D, | ||||||
|   (* clkbuf_sink *) |   (* clkbuf_sink *) | ||||||
|   (* invertible_pin = "IS_WCLK_INVERTED" *) |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|   input  WCLK, |   input  WCLK, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 |  | ||||||
|   (* abc9_required=654 *) |  | ||||||
|   input  WE, |   input  WE, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800 |   input  A0, A1, A2, A3, A4, | ||||||
|   (* abc9_required=245 *) |  | ||||||
|   input  A0, |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/clBLM_R.sdf#L798 |  | ||||||
|   (* abc9_required=208 *) |  | ||||||
|   input  A1, |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796 |  | ||||||
|   (* abc9_required=147 *) |  | ||||||
|   input  A2, |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794 |  | ||||||
|   (* abc9_required=68 *) |  | ||||||
|   input  A3, |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792 |  | ||||||
|   (* abc9_required=66 *) |  | ||||||
|   input  A4, |  | ||||||
|   input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 |   input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 | ||||||
| ); | ); | ||||||
|   parameter INIT = 32'h0; |   parameter INIT = 32'h0; | ||||||
|  | @ -1341,35 +1375,61 @@ module RAM32X1D ( | ||||||
|   assign DPO = mem[dpra]; |   assign DPO = mem[dpra]; | ||||||
|   wire clk = WCLK ^ IS_WCLK_INVERTED; |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|   always @(posedge clk) if (WE) mem[a] <= D; |   always @(posedge clk) if (WE) mem[a] <= D; | ||||||
|  |   generate | ||||||
|  |     if (!IS_WCLK_INVERTED) | ||||||
|  |       specify | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981 | ||||||
|  |         if (WE) (posedge WCLK => (SPO : D)) = 1153; | ||||||
|  |         if (WE) (posedge WCLK => (DPO : D)) = 1153; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986 | ||||||
|  |         $setup(D , posedge WCLK, 453); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 | ||||||
|  |         $setup(WE, posedge WCLK, 654); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800 | ||||||
|  |         $setup(A0, posedge WCLK, 245); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L798 | ||||||
|  |         $setup(A1, posedge WCLK, 208); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796 | ||||||
|  |         $setup(A2, posedge WCLK, 147); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794 | ||||||
|  |         $setup(A3, posedge WCLK, 68); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792 | ||||||
|  |         $setup(A4, posedge WCLK, 66); | ||||||
|  |       endspecify | ||||||
|  |     else | ||||||
|  |       specify | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981 | ||||||
|  |         if (WE) (negedge WCLK => (SPO : D)) = 1153; | ||||||
|  |         if (WE) (negedge WCLK => (DPO : D)) = 1153; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986 | ||||||
|  |         $setup(D , negedge WCLK, 453); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 | ||||||
|  |         $setup(WE, negedge WCLK, 654); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800 | ||||||
|  |         $setup(A0, negedge WCLK, 245); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L798 | ||||||
|  |         $setup(A1, negedge WCLK, 208); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796 | ||||||
|  |         $setup(A2, negedge WCLK, 147); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794 | ||||||
|  |         $setup(A3, negedge WCLK, 68); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792 | ||||||
|  |         $setup(A4, negedge WCLK, 66); | ||||||
|  |       endspecify | ||||||
|  |   endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAM32X1D_1 ( | module RAM32X1D_1 ( | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981 |  | ||||||
|   (* abc9_arrival=1153 *) |  | ||||||
|   output DPO, SPO, |   output DPO, SPO, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986 |  | ||||||
|   (* abc9_required=453 *) |  | ||||||
|   input  D, |   input  D, | ||||||
|   (* clkbuf_sink *) |   (* clkbuf_sink *) | ||||||
|   (* invertible_pin = "IS_WCLK_INVERTED" *) |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|   input  WCLK, |   input  WCLK, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 |  | ||||||
|   (* abc9_required=654 *) |  | ||||||
|   input  WE, |   input  WE, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800 |  | ||||||
|   (* abc9_required=245 *) |  | ||||||
|   input  A0, |   input  A0, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/clBLM_R.sdf#L798 |  | ||||||
|   (* abc9_required=208 *) |  | ||||||
|   input  A1, |   input  A1, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796 |  | ||||||
|   (* abc9_required=147 *) |  | ||||||
|   input  A2, |   input  A2, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794 |  | ||||||
|   (* abc9_required=68 *) |  | ||||||
|   input  A3, |   input  A3, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792 |  | ||||||
|   (* abc9_required=66 *) |  | ||||||
|   input  A4, |   input  A4, | ||||||
|   input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 |   input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4 | ||||||
| ); | ); | ||||||
|  | @ -1382,39 +1442,35 @@ module RAM32X1D_1 ( | ||||||
|   assign DPO = mem[dpra]; |   assign DPO = mem[dpra]; | ||||||
|   wire clk = WCLK ^ IS_WCLK_INVERTED; |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|   always @(negedge clk) if (WE) mem[a] <= D; |   always @(negedge clk) if (WE) mem[a] <= D; | ||||||
|  |   specify | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981 | ||||||
|  |     if (WE) (negedge WCLK => (SPO : D)) = 1153; | ||||||
|  |     if (WE) (negedge WCLK => (DPO : D)) = 1153; | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986 | ||||||
|  |     $setup(D , negedge WCLK, 453); | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 | ||||||
|  |     $setup(WE, negedge WCLK, 654); | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L800 | ||||||
|  |     $setup(A0, negedge WCLK, 245); | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L798 | ||||||
|  |     $setup(A1, negedge WCLK, 208); | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L796 | ||||||
|  |     $setup(A2, negedge WCLK, 147); | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L794 | ||||||
|  |     $setup(A3, negedge WCLK, 68); | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792 | ||||||
|  |     $setup(A4, negedge WCLK, 66); | ||||||
|  |   endspecify | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAM64X1D ( | module RAM64X1D ( | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981 |  | ||||||
|   (* abc9_arrival=1153 *) |  | ||||||
|   output DPO, SPO, |   output DPO, SPO, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986 |  | ||||||
|   (* abc9_required=453 *) |  | ||||||
|   input  D, |   input  D, | ||||||
|   (* clkbuf_sink *) |   (* clkbuf_sink *) | ||||||
|   (* invertible_pin = "IS_WCLK_INVERTED" *) |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|   input  WCLK, |   input  WCLK, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 |  | ||||||
|   (* abc9_required=654 *) |  | ||||||
|   input  WE, |   input  WE, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828 |   input  A0, A1, A2, A3, A4, A5, | ||||||
|   (* abc9_required=362 *) |  | ||||||
|   input  A0, |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826 |  | ||||||
|   (* abc9_required=245 *) |  | ||||||
|   input  A1, |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824 |  | ||||||
|   (* abc9_required=208 *) |  | ||||||
|   input  A2, |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822 |  | ||||||
|   (* abc9_required=147 *) |  | ||||||
|   input  A3, |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820 |  | ||||||
|   (* abc9_required=68 *) |  | ||||||
|   input  A4, |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818 |  | ||||||
|   (* abc9_required=66 *) |  | ||||||
|   input  A5, |  | ||||||
|   input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 |   input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 | ||||||
| ); | ); | ||||||
|   parameter INIT = 64'h0; |   parameter INIT = 64'h0; | ||||||
|  | @ -1426,39 +1482,62 @@ module RAM64X1D ( | ||||||
|   assign DPO = mem[dpra]; |   assign DPO = mem[dpra]; | ||||||
|   wire clk = WCLK ^ IS_WCLK_INVERTED; |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|   always @(posedge clk) if (WE) mem[a] <= D; |   always @(posedge clk) if (WE) mem[a] <= D; | ||||||
|  |   generate | ||||||
|  |     if (!IS_WCLK_INVERTED) | ||||||
|  |       specify | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981 | ||||||
|  |         if (WE) (posedge WCLK => (SPO : D)) = 1153; | ||||||
|  |         if (WE) (posedge WCLK => (DPO : D)) = 1153; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986 | ||||||
|  |         $setup(D , posedge WCLK, 453); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 | ||||||
|  |         $setup(WE, posedge WCLK, 654); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828 | ||||||
|  |         $setup(A0, posedge WCLK, 362); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826 | ||||||
|  |         $setup(A1, posedge WCLK, 245); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824 | ||||||
|  |         $setup(A2, posedge WCLK, 208); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822 | ||||||
|  |         $setup(A3, posedge WCLK, 147); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820 | ||||||
|  |         $setup(A4, posedge WCLK, 68); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818 | ||||||
|  |         $setup(A5, posedge WCLK, 66); | ||||||
|  |       endspecify | ||||||
|  |     else | ||||||
|  |       specify | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981 | ||||||
|  |         if (WE) (negedge WCLK => (SPO : D)) = 1153; | ||||||
|  |         if (WE) (negedge WCLK => (DPO : D)) = 1153; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986 | ||||||
|  |         $setup(D , negedge WCLK, 453); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 | ||||||
|  |         $setup(WE, negedge WCLK, 654); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828 | ||||||
|  |         $setup(A0, negedge WCLK, 362); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826 | ||||||
|  |         $setup(A1, negedge WCLK, 245); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824 | ||||||
|  |         $setup(A2, negedge WCLK, 208); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822 | ||||||
|  |         $setup(A3, negedge WCLK, 147); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820 | ||||||
|  |         $setup(A4, negedge WCLK, 68); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818 | ||||||
|  |         $setup(A5, negedge WCLK, 66); | ||||||
|  |       endspecify | ||||||
|  |   endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAM64X1D_1 ( | module RAM64X1D_1 ( | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981 |  | ||||||
|   (* abc9_arrival=1153 *) |  | ||||||
|   output DPO, SPO, |   output DPO, SPO, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986 |  | ||||||
|   (* abc9_required=453 *) |  | ||||||
|   input  D, |   input  D, | ||||||
|   (* clkbuf_sink *) |   (* clkbuf_sink *) | ||||||
|   (* invertible_pin = "IS_WCLK_INVERTED" *) |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|   input  WCLK, |   input  WCLK, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 |  | ||||||
|   (* abc9_required=654 *) |  | ||||||
|   input  WE, |   input  WE, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828 |   input  A0, A1, A2, A3, A4, A5, | ||||||
|   (* abc9_required=362 *) |  | ||||||
|   input  A0, |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826 |  | ||||||
|   (* abc9_required=245 *) |  | ||||||
|   input  A1, |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824 |  | ||||||
|   (* abc9_required=208 *) |  | ||||||
|   input  A2, |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822 |  | ||||||
|   (* abc9_required=147 *) |  | ||||||
|   input  A3, |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820 |  | ||||||
|   (* abc9_required=68 *) |  | ||||||
|   input  A4, |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818 |  | ||||||
|   (* abc9_required=66 *) |  | ||||||
|   input  A5, |  | ||||||
|   input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 |   input  DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5 | ||||||
| ); | ); | ||||||
|   parameter INIT = 64'h0; |   parameter INIT = 64'h0; | ||||||
|  | @ -1470,21 +1549,35 @@ module RAM64X1D_1 ( | ||||||
|   assign DPO = mem[dpra]; |   assign DPO = mem[dpra]; | ||||||
|   wire clk = WCLK ^ IS_WCLK_INVERTED; |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|   always @(negedge clk) if (WE) mem[a] <= D; |   always @(negedge clk) if (WE) mem[a] <= D; | ||||||
|  |   specify | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981 | ||||||
|  |     if (WE) (negedge WCLK => (SPO : D)) = 1153; | ||||||
|  |     if (WE) (negedge WCLK => (DPO : D)) = 1153; | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986 | ||||||
|  |     $setup(D , negedge WCLK, 453); | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 | ||||||
|  |     $setup(WE, negedge WCLK, 654); | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L828 | ||||||
|  |     $setup(A0, negedge WCLK, 362); | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L826 | ||||||
|  |     $setup(A1, negedge WCLK, 245); | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L824 | ||||||
|  |     $setup(A2, negedge WCLK, 208); | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L822 | ||||||
|  |     $setup(A3, negedge WCLK, 147); | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L820 | ||||||
|  |     $setup(A4, negedge WCLK, 68); | ||||||
|  |     // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818 | ||||||
|  |     $setup(A5, negedge WCLK, 66); | ||||||
|  |   endspecify | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAM128X1D ( | module RAM128X1D ( | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981 |  | ||||||
|   //   plus 208ps to cross MUXF7 |  | ||||||
|   (* abc9_arrival=1359 *) |  | ||||||
|   output       DPO, SPO, |   output       DPO, SPO, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986 |  | ||||||
|   (* abc9_required=453 *) |  | ||||||
|   input        D, |   input        D, | ||||||
|   (* clkbuf_sink *) |   (* clkbuf_sink *) | ||||||
|   (* invertible_pin = "IS_WCLK_INVERTED" *) |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|   input        WCLK, |   input        WCLK, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 |  | ||||||
|   (* abc9_required=654 *) |  | ||||||
|   input        WE, |   input        WE, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-830 |   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-830 | ||||||
|   (* abc9_required="616 362 245 208 147 68 66" *) |   (* abc9_required="616 362 245 208 147 68 66" *) | ||||||
|  | @ -1498,6 +1591,46 @@ module RAM128X1D ( | ||||||
|   assign DPO = mem[DPRA]; |   assign DPO = mem[DPRA]; | ||||||
|   wire clk = WCLK ^ IS_WCLK_INVERTED; |   wire clk = WCLK ^ IS_WCLK_INVERTED; | ||||||
|   always @(posedge clk) if (WE) mem[A] <= D; |   always @(posedge clk) if (WE) mem[A] <= D; | ||||||
|  |   generate | ||||||
|  |     if (!IS_WCLK_INVERTED) | ||||||
|  |       specify | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981 | ||||||
|  |         //   plus 208ps to cross MUXF7 | ||||||
|  |         if (WE) (posedge WCLK => (SPO : D)) = 1359; | ||||||
|  |         if (WE) (posedge WCLK => (DPO : D)) = 1359; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986 | ||||||
|  |         $setup(D , posedge WCLK, 453); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 | ||||||
|  |         $setup(WE, posedge WCLK, 654); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-830 | ||||||
|  |         $setup(A[0], posedge WCLK, 616); | ||||||
|  |         $setup(A[1], posedge WCLK, 362); | ||||||
|  |         $setup(A[2], posedge WCLK, 245); | ||||||
|  |         $setup(A[3], posedge WCLK, 208); | ||||||
|  |         $setup(A[4], posedge WCLK, 147); | ||||||
|  |         $setup(A[5], posedge WCLK, 68); | ||||||
|  |         $setup(A[6], posedge WCLK, 66); | ||||||
|  |       endspecify | ||||||
|  |     else | ||||||
|  |       specify | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L981 | ||||||
|  |         //   plus 208ps to cross MUXF7 | ||||||
|  |         if (WE) (negedge WCLK => (SPO : D)) = 1359; | ||||||
|  |         if (WE) (negedge WCLK => (DPO : D)) = 1359; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986 | ||||||
|  |         $setup(D , negedge WCLK, 453); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 | ||||||
|  |         $setup(WE, negedge WCLK, 654); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-830 | ||||||
|  |         $setup(A[0], negedge WCLK, 616); | ||||||
|  |         $setup(A[1], negedge WCLK, 362); | ||||||
|  |         $setup(A[2], negedge WCLK, 245); | ||||||
|  |         $setup(A[3], negedge WCLK, 208); | ||||||
|  |         $setup(A[4], negedge WCLK, 147); | ||||||
|  |         $setup(A[5], negedge WCLK, 68); | ||||||
|  |         $setup(A[6], negedge WCLK, 66); | ||||||
|  |       endspecify | ||||||
|  |   endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAM256X1D ( | module RAM256X1D ( | ||||||
|  | @ -1521,43 +1654,19 @@ endmodule | ||||||
| // Multi port. | // Multi port. | ||||||
| 
 | 
 | ||||||
| module RAM32M ( | module RAM32M ( | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889 |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L857 |  | ||||||
|   (* abc9_arrival="1153 1188" *) |  | ||||||
|   output [1:0] DOA, |   output [1:0] DOA, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L925 |  | ||||||
|   (* abc9_arrival="1161 1187" *) |  | ||||||
|   output [1:0] DOB, |   output [1:0] DOB, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025 |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L993 |  | ||||||
|   (* abc9_arrival="1158 1180" *) |  | ||||||
|   output [1:0] DOC, |   output [1:0] DOC, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093 |  | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1061 |  | ||||||
|   (* abc9_arrival="1163 1190" *) |  | ||||||
|   output [1:0] DOD, |   output [1:0] DOD, | ||||||
|   input  [4:0] ADDRA, ADDRB, ADDRC, |   input  [4:0] ADDRA, ADDRB, ADDRC, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L792-L802 |  | ||||||
|   (* abc9_required="245 208 147 68 66" *) |  | ||||||
|   input  [4:0] ADDRD, |   input  [4:0] ADDRD, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988 |  | ||||||
|   (* abc9_required="453 384" *) |  | ||||||
|   input  [1:0] DIA, |   input  [1:0] DIA, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056 |  | ||||||
|   (* abc9_required="461 354" *) |  | ||||||
|   input  [1:0] DIB, |   input  [1:0] DIB, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124 |  | ||||||
|   (* abc9_required="457 375" *) |  | ||||||
|   input  [1:0] DIC, |   input  [1:0] DIC, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192 |  | ||||||
|   (* abc9_required="310 334" *) |  | ||||||
|   input  [1:0] DID, |   input  [1:0] DID, | ||||||
|   (* clkbuf_sink *) |   (* clkbuf_sink *) | ||||||
|   (* invertible_pin = "IS_WCLK_INVERTED" *) |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|   input        WCLK, |   input        WCLK, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 |  | ||||||
|   (* abc9_required=654 *) |  | ||||||
|   input        WE |   input        WE | ||||||
| ); | ); | ||||||
|   parameter [63:0] INIT_A = 64'h0000000000000000; |   parameter [63:0] INIT_A = 64'h0000000000000000; | ||||||
|  | @ -1581,6 +1690,87 @@ module RAM32M ( | ||||||
|       mem_c[2*ADDRD+:2] <= DIC; |       mem_c[2*ADDRD+:2] <= DIC; | ||||||
|       mem_d[2*ADDRD+:2] <= DID; |       mem_d[2*ADDRD+:2] <= DID; | ||||||
|     end |     end | ||||||
|  |   generate | ||||||
|  |     if (!IS_WCLK_INVERTED) | ||||||
|  |       specify | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889 | ||||||
|  |         if (WE) (posedge WCLK => (DOA[0] : DIA[0])) = 1153; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L857 | ||||||
|  |         if (WE) (posedge WCLK => (DOA[1] : DIA[1])) = 1188; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||||
|  |         if (WE) (posedge WCLK => (DOB[0] : DIB[0])) = 1161; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L925 | ||||||
|  |         if (WE) (posedge WCLK => (DOB[1] : DIB[1])) = 1187; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L993 | ||||||
|  |         if (WE) (posedge WCLK => (DOC[0] : DIC[0])) = 1158; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025 | ||||||
|  |         if (WE) (posedge WCLK => (DOC[1] : DIC[1])) = 1180; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093 | ||||||
|  |         if (WE) (posedge WCLK => (DOD[0] : DID[0])) = 1163; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1061 | ||||||
|  |         if (WE) (posedge WCLK => (DOD[1] : DID[1])) = 1190; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986 | ||||||
|  |         $setup(ADDRD[0], posedge WCLK, 245); | ||||||
|  |         $setup(ADDRD[1], posedge WCLK, 208); | ||||||
|  |         $setup(ADDRD[2], posedge WCLK, 147); | ||||||
|  |         $setup(ADDRD[3], posedge WCLK, 68); | ||||||
|  |         $setup(ADDRD[4], posedge WCLK, 66); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988 | ||||||
|  |         $setup(DIA[0], posedge WCLK, 453); | ||||||
|  |         $setup(DIA[1], posedge WCLK, 384); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056 | ||||||
|  |         $setup(DIB[0], posedge WCLK, 461); | ||||||
|  |         $setup(DIB[1], posedge WCLK, 354); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124 | ||||||
|  |         $setup(DIC[0], posedge WCLK, 457); | ||||||
|  |         $setup(DIC[1], posedge WCLK, 375); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192 | ||||||
|  |         $setup(DID[0], posedge WCLK, 310); | ||||||
|  |         $setup(DID[1], posedge WCLK, 334); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 | ||||||
|  |         $setup(WE, posedge WCLK, 654); | ||||||
|  |       endspecify | ||||||
|  |     else | ||||||
|  |       specify | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889 | ||||||
|  |         if (WE) (negedge WCLK => (DOA[0] : DIA[0])) = 1153; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L857 | ||||||
|  |         if (WE) (negedge WCLK => (DOA[1] : DIA[1])) = 1188; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||||
|  |         if (WE) (negedge WCLK => (DOB[0] : DIB[0])) = 1161; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L925 | ||||||
|  |         if (WE) (negedge WCLK => (DOB[1] : DIB[1])) = 1187; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L993 | ||||||
|  |         if (WE) (negedge WCLK => (DOC[0] : DIC[0])) = 1158; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025 | ||||||
|  |         if (WE) (negedge WCLK => (DOC[1] : DIC[1])) = 1180; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093 | ||||||
|  |         if (WE) (negedge WCLK => (DOD[0] : DID[0])) = 1163; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1061 | ||||||
|  |         if (WE) (negedge WCLK => (DOD[1] : DID[1])) = 1190; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986 | ||||||
|  |         $setup(ADDRD[0], negedge WCLK, 245); | ||||||
|  |         $setup(ADDRD[1], negedge WCLK, 208); | ||||||
|  |         $setup(ADDRD[2], negedge WCLK, 147); | ||||||
|  |         $setup(ADDRD[3], negedge WCLK, 68); | ||||||
|  |         $setup(ADDRD[4], negedge WCLK, 66); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988 | ||||||
|  |         $setup(DIA[0], negedge WCLK, 453); | ||||||
|  |         $setup(DIA[1], negedge WCLK, 384); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056 | ||||||
|  |         $setup(DIB[0], negedge WCLK, 461); | ||||||
|  |         $setup(DIB[1], negedge WCLK, 354); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124 | ||||||
|  |         $setup(DIC[0], negedge WCLK, 457); | ||||||
|  |         $setup(DIC[1], negedge WCLK, 375); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192 | ||||||
|  |         $setup(DID[0], negedge WCLK, 310); | ||||||
|  |         $setup(DID[1], negedge WCLK, 334); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 | ||||||
|  |         $setup(WE, posedge WCLK, 654); | ||||||
|  |       endspecify | ||||||
|  |   endgenerate | ||||||
|  | 
 | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAM32M16 ( | module RAM32M16 ( | ||||||
|  | @ -1653,39 +1843,19 @@ module RAM32M16 ( | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAM64M ( | module RAM64M ( | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889 |  | ||||||
|   (* abc9_arrival=1153 *) |  | ||||||
|   output       DOA, |   output       DOA, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 |  | ||||||
|   (* abc9_arrival=1161 *) |  | ||||||
|   output       DOB, |   output       DOB, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025 |  | ||||||
|   (* abc9_arrival=1158 *) |  | ||||||
|   output       DOC, |   output       DOC, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093 |  | ||||||
|   (* abc9_arrival=1163 *) |  | ||||||
|   output       DOD, |   output       DOD, | ||||||
|   input  [5:0] ADDRA, ADDRB, ADDRC, |   input  [5:0] ADDRA, ADDRB, ADDRC, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-L830 |  | ||||||
|   (* abc9_required="362 245 208 147 68 66" *) |  | ||||||
|   input  [5:0] ADDRD, |   input  [5:0] ADDRD, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988 |  | ||||||
|   (* abc9_required=384 *) |  | ||||||
|   input        DIA, |   input        DIA, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056 |  | ||||||
|   (* abc9_required=354 *) |  | ||||||
|   input        DIB, |   input        DIB, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124 |  | ||||||
|   (* abc9_required=375 *) |  | ||||||
|   input        DIC, |   input        DIC, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192 |  | ||||||
|   (* abc9_required=310 *) |  | ||||||
|   input        DID, |   input        DID, | ||||||
|   (* clkbuf_sink *) |   (* clkbuf_sink *) | ||||||
|   (* invertible_pin = "IS_WCLK_INVERTED" *) |   (* invertible_pin = "IS_WCLK_INVERTED" *) | ||||||
|   input        WCLK, |   input        WCLK, | ||||||
|   // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 |  | ||||||
|   (* abc9_required=654 *) |  | ||||||
|   input        WE |   input        WE | ||||||
| ); | ); | ||||||
|   parameter [63:0] INIT_A = 64'h0000000000000000; |   parameter [63:0] INIT_A = 64'h0000000000000000; | ||||||
|  | @ -1709,6 +1879,64 @@ module RAM64M ( | ||||||
|       mem_c[ADDRD] <= DIC; |       mem_c[ADDRD] <= DIC; | ||||||
|       mem_d[ADDRD] <= DID; |       mem_d[ADDRD] <= DID; | ||||||
|     end |     end | ||||||
|  |   generate | ||||||
|  |     if (!IS_WCLK_INVERTED) | ||||||
|  |       specify | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889 | ||||||
|  |         if (WE) (posedge WCLK => (DOA : DIA)) = 1153; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||||
|  |         if (WE) (posedge WCLK => (DOB : DIB)) = 1161; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025 | ||||||
|  |         if (WE) (posedge WCLK => (DOC : DIC)) = 1158; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093 | ||||||
|  |         if (WE) (posedge WCLK => (DOD : DID)) = 1163; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-L830 | ||||||
|  |         $setup(ADDRD[0], posedge WCLK, 362); | ||||||
|  |         $setup(ADDRD[1], posedge WCLK, 245); | ||||||
|  |         $setup(ADDRD[2], posedge WCLK, 208); | ||||||
|  |         $setup(ADDRD[3], posedge WCLK, 147); | ||||||
|  |         $setup(ADDRD[4], posedge WCLK, 68); | ||||||
|  |         $setup(ADDRD[5], posedge WCLK, 66); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988 | ||||||
|  |         $setup(DIA, posedge WCLK, 384); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056 | ||||||
|  |         $setup(DIB, posedge WCLK, 354); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124 | ||||||
|  |         $setup(DIC, posedge WCLK, 375); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192 | ||||||
|  |         $setup(DID, posedge WCLK, 310); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 | ||||||
|  |         $setup(WE, posedge WCLK, 654); | ||||||
|  |       endspecify | ||||||
|  |     else | ||||||
|  |       specify | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L889 | ||||||
|  |         if (WE) (negedge WCLK => (DOA : DIA)) = 1153; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957 | ||||||
|  |         if (WE) (negedge WCLK => (DOB : DIB)) = 1161; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1025 | ||||||
|  |         if (WE) (negedge WCLK => (DOC : DIC)) = 1158; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L1093 | ||||||
|  |         if (WE) (negedge WCLK => (DOD : DID)) = 1163; | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L818-L830 | ||||||
|  |         $setup(ADDRD[0], negedge WCLK, 362); | ||||||
|  |         $setup(ADDRD[1], negedge WCLK, 245); | ||||||
|  |         $setup(ADDRD[2], negedge WCLK, 208); | ||||||
|  |         $setup(ADDRD[3], negedge WCLK, 147); | ||||||
|  |         $setup(ADDRD[4], negedge WCLK, 68); | ||||||
|  |         $setup(ADDRD[5], negedge WCLK, 66); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L986-L988 | ||||||
|  |         $setup(DIA, negedge WCLK, 384); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1054-L1056 | ||||||
|  |         $setup(DIB, negedge WCLK, 354); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1122-L1124 | ||||||
|  |         $setup(DIC, negedge WCLK, 375); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L1190-L1192 | ||||||
|  |         $setup(DID, negedge WCLK, 310); | ||||||
|  |         // Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/31f51ac5ec7448dd6f79a8267f147123e4413c21/artix7/timings/CLBLM_R.sdf#L834 | ||||||
|  |         $setup(WE, negedge WCLK, 654); | ||||||
|  |       endspecify | ||||||
|  |   endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAM64M8 ( | module RAM64M8 ( | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue