mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into eddie/xilinx_srl
This commit is contained in:
		
						commit
						ba5d81c7f1
					
				
					 27 changed files with 1429 additions and 338 deletions
				
			
		|  | @ -26,6 +26,11 @@ Yosys 0.9 .. Yosys 0.9-dev | ||||||
|     - Added automatic gzip compression (based on filename extension) for backends |     - Added automatic gzip compression (based on filename extension) for backends | ||||||
|     - Improve attribute and parameter encoding in JSON to avoid ambiguities between |     - Improve attribute and parameter encoding in JSON to avoid ambiguities between | ||||||
|       bit vectors and strings containing [01xz]* |       bit vectors and strings containing [01xz]* | ||||||
|  |     - Added "clkbufmap" pass | ||||||
|  |     - Added "synth_xilinx -family xc6s" for Spartan 6 support (experimental) | ||||||
|  |     - Added "synth_xilinx -ise" (experimental) | ||||||
|  |     - Added "synth_xilinx -iopad" | ||||||
|  |     - "synth_xilinx" now automatically inserts clock buffers (add -noclkbuf to disable) | ||||||
|     - Improvements in pmgen: subpattern and recursive matches |     - Improvements in pmgen: subpattern and recursive matches | ||||||
|     - Added "opt_share" pass, run as part of "opt -full" |     - Added "opt_share" pass, run as part of "opt -full" | ||||||
|     - Added "ice40_wrapcarry" to encapsulate SB_LUT+SB_CARRY pairs for techmapping |     - Added "ice40_wrapcarry" to encapsulate SB_LUT+SB_CARRY pairs for techmapping | ||||||
|  |  | ||||||
|  | @ -390,6 +390,7 @@ Finally run all tests with "make config-{clang,gcc,gcc-4.8}": | ||||||
| Release: | Release: | ||||||
| 
 | 
 | ||||||
| 	- set YOSYS_VER to x.y.z in Makefile | 	- set YOSYS_VER to x.y.z in Makefile | ||||||
|  | 	- remove "bumpversion" target from Makefile | ||||||
| 	- update version string in CHANGELOG | 	- update version string in CHANGELOG | ||||||
| 	git commit -am "Yosys x.y.z" | 	git commit -am "Yosys x.y.z" | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										3
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								Makefile
									
										
									
									
									
								
							|  | @ -119,6 +119,9 @@ YOSYS_VER := 0.9+1 | ||||||
| GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) | GIT_REV := $(shell cd $(YOSYS_SRC) && git rev-parse --short HEAD 2> /dev/null || echo UNKNOWN) | ||||||
| OBJS = kernel/version_$(GIT_REV).o | OBJS = kernel/version_$(GIT_REV).o | ||||||
| 
 | 
 | ||||||
|  | bumpversion: | ||||||
|  | 	sed -i "/^YOSYS_VER := / s/+[0-9][0-9]*$$/+`git log --oneline 8a4c6e6.. | wc -l`/;" Makefile | ||||||
|  | 
 | ||||||
| # set 'ABCREV = default' to use abc/ as it is
 | # set 'ABCREV = default' to use abc/ as it is
 | ||||||
| #
 | #
 | ||||||
| # Note: If you do ABC development, make sure that 'abc' in this directory
 | # Note: If you do ABC development, make sure that 'abc' in this directory
 | ||||||
|  |  | ||||||
							
								
								
									
										15
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								README.md
									
										
									
									
									
								
							|  | @ -332,6 +332,21 @@ Verilog Attributes and non-standard features | ||||||
|   that represent module parameters or localparams (when the HDL front-end |   that represent module parameters or localparams (when the HDL front-end | ||||||
|   is run in -pwires mode). |   is run in -pwires mode). | ||||||
| 
 | 
 | ||||||
|  | - The ``clkbuf_driver`` attribute can be set on an output port of a blackbox | ||||||
|  |   module to mark it as a clock buffer output, and thus prevent ``clkbufmap`` | ||||||
|  |   from inserting another clock buffer on a net driven by such output. | ||||||
|  | 
 | ||||||
|  | - The ``clkbuf_sink`` attribute can be set on an input port of a module to | ||||||
|  |   request clock buffer insertion by the ``clkbufmap`` pass. | ||||||
|  | 
 | ||||||
|  | - The ``clkbuf_inhibit`` is the default attribute to set on a wire to prevent | ||||||
|  |   automatic clock buffer insertion by ``clkbufmap``. This behaviour can be | ||||||
|  |   overridden by providing a custom selection to ``clkbufmap``. | ||||||
|  | 
 | ||||||
|  | - The ``iopad_external_pin`` attribute on a blackbox module's port marks | ||||||
|  |   it as the external-facing pin of an I/O pad, and prevents ``iopadmap`` | ||||||
|  |   from inserting another pad cell on it. | ||||||
|  | 
 | ||||||
| - In addition to the ``(* ... *)`` attribute syntax, Yosys supports | - In addition to the ``(* ... *)`` attribute syntax, Yosys supports | ||||||
|   the non-standard ``{* ... *}`` attribute syntax to set default attributes |   the non-standard ``{* ... *}`` attribute syntax to set default attributes | ||||||
|   for everything that comes after the ``{* ... *}`` statement. (Reset |   for everything that comes after the ``{* ... *}`` statement. (Reset | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| read_verilog example.v | read_verilog example.v | ||||||
| synth_xilinx -top example -family xc6s | synth_xilinx -top example -family xc6s -ise | ||||||
| iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I |  | ||||||
| write_edif -pvector bra example.edif | write_edif -pvector bra example.edif | ||||||
|  |  | ||||||
|  | @ -268,7 +268,7 @@ struct SatHelper | ||||||
| 				RTLIL::SigSpec removed_bits; | 				RTLIL::SigSpec removed_bits; | ||||||
| 				for (int i = 0; i < lhs.size(); i++) { | 				for (int i = 0; i < lhs.size(); i++) { | ||||||
| 					RTLIL::SigSpec bit = lhs.extract(i, 1); | 					RTLIL::SigSpec bit = lhs.extract(i, 1); | ||||||
| 					if (!satgen.initial_state.check_all(bit)) { | 					if (rhs[i] == State::Sx || !satgen.initial_state.check_all(bit)) { | ||||||
| 						removed_bits.append(bit); | 						removed_bits.append(bit); | ||||||
| 						lhs.remove(i, 1); | 						lhs.remove(i, 1); | ||||||
| 						rhs.remove(i, 1); | 						rhs.remove(i, 1); | ||||||
|  |  | ||||||
|  | @ -16,6 +16,7 @@ endif | ||||||
| 
 | 
 | ||||||
| ifneq ($(SMALL),1) | ifneq ($(SMALL),1) | ||||||
| OBJS += passes/techmap/iopadmap.o | OBJS += passes/techmap/iopadmap.o | ||||||
|  | OBJS += passes/techmap/clkbufmap.o | ||||||
| OBJS += passes/techmap/hilomap.o | OBJS += passes/techmap/hilomap.o | ||||||
| OBJS += passes/techmap/extract.o | OBJS += passes/techmap/extract.o | ||||||
| OBJS += passes/techmap/extract_fa.o | OBJS += passes/techmap/extract_fa.o | ||||||
|  |  | ||||||
|  | @ -143,6 +143,82 @@ void attrmap_apply(string objname, vector<std::unique_ptr<AttrmapAction>> &actio | ||||||
| 	attributes.swap(new_attributes); | 	attributes.swap(new_attributes); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void log_attrmap_paramap_options() | ||||||
|  | { | ||||||
|  | 	log("    -tocase <name>\n"); | ||||||
|  | 	log("        Match attribute names case-insensitively and set it to the specified\n"); | ||||||
|  | 	log("        name.\n"); | ||||||
|  | 	log("\n"); | ||||||
|  | 	log("    -rename <old_name> <new_name>\n"); | ||||||
|  | 	log("        Rename attributes as specified\n"); | ||||||
|  | 	log("\n"); | ||||||
|  | 	log("    -map <old_name>=<old_value> <new_name>=<new_value>\n"); | ||||||
|  | 	log("        Map key/value pairs as indicated.\n"); | ||||||
|  | 	log("\n"); | ||||||
|  | 	log("    -imap <old_name>=<old_value> <new_name>=<new_value>\n"); | ||||||
|  | 	log("        Like -map, but use case-insensitive match for <old_value> when\n"); | ||||||
|  | 	log("        it is a string value.\n"); | ||||||
|  | 	log("\n"); | ||||||
|  | 	log("    -remove <name>=<value>\n"); | ||||||
|  | 	log("        Remove attributes matching this pattern.\n"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool parse_attrmap_paramap_options(size_t &argidx, std::vector<std::string> &args, vector<std::unique_ptr<AttrmapAction>> &actions) | ||||||
|  | { | ||||||
|  | 	std::string arg = args[argidx]; | ||||||
|  | 	if (arg == "-tocase" && argidx+1 < args.size()) { | ||||||
|  | 		auto action = new AttrmapTocase; | ||||||
|  | 		action->name = args[++argidx]; | ||||||
|  | 		actions.push_back(std::unique_ptr<AttrmapAction>(action)); | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 	if (arg == "-rename" && argidx+2 < args.size()) { | ||||||
|  | 		auto action = new AttrmapRename; | ||||||
|  | 		action->old_name = args[++argidx]; | ||||||
|  | 		action->new_name = args[++argidx]; | ||||||
|  | 		actions.push_back(std::unique_ptr<AttrmapAction>(action)); | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 	if ((arg == "-map" || arg == "-imap") && argidx+2 < args.size()) { | ||||||
|  | 		string arg1 = args[++argidx]; | ||||||
|  | 		string arg2 = args[++argidx]; | ||||||
|  | 		string val1, val2; | ||||||
|  | 		size_t p = arg1.find("="); | ||||||
|  | 		if (p != string::npos) { | ||||||
|  | 			val1 = arg1.substr(p+1); | ||||||
|  | 			arg1 = arg1.substr(0, p); | ||||||
|  | 		} | ||||||
|  | 		p = arg2.find("="); | ||||||
|  | 		if (p != string::npos) { | ||||||
|  | 			val2 = arg2.substr(p+1); | ||||||
|  | 			arg2 = arg2.substr(0, p); | ||||||
|  | 		} | ||||||
|  | 		auto action = new AttrmapMap; | ||||||
|  | 		action->imap = (arg == "-map"); | ||||||
|  | 		action->old_name = arg1; | ||||||
|  | 		action->new_name = arg2; | ||||||
|  | 		action->old_value = val1; | ||||||
|  | 		action->new_value = val2; | ||||||
|  | 		actions.push_back(std::unique_ptr<AttrmapAction>(action)); | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 	if (arg == "-remove" && argidx+1 < args.size()) { | ||||||
|  | 		string arg1 = args[++argidx], val1; | ||||||
|  | 		size_t p = arg1.find("="); | ||||||
|  | 		if (p != string::npos) { | ||||||
|  | 			val1 = arg1.substr(p+1); | ||||||
|  | 			arg1 = arg1.substr(0, p); | ||||||
|  | 		} | ||||||
|  | 		auto action = new AttrmapRemove; | ||||||
|  | 		action->name = arg1; | ||||||
|  | 		action->has_value = (p != string::npos); | ||||||
|  | 		action->value = val1; | ||||||
|  | 		actions.push_back(std::unique_ptr<AttrmapAction>(action)); | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 	return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| struct AttrmapPass : public Pass { | struct AttrmapPass : public Pass { | ||||||
| 	AttrmapPass() : Pass("attrmap", "renaming attributes") { } | 	AttrmapPass() : Pass("attrmap", "renaming attributes") { } | ||||||
| 	void help() YS_OVERRIDE | 	void help() YS_OVERRIDE | ||||||
|  | @ -151,25 +227,10 @@ struct AttrmapPass : public Pass { | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    attrmap [options] [selection]\n"); | 		log("    attrmap [options] [selection]\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("This command renames attributes and/or mapps key/value pairs to\n"); | 		log("This command renames attributes and/or maps key/value pairs to\n"); | ||||||
| 		log("other key/value pairs.\n"); | 		log("other key/value pairs.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    -tocase <name>\n"); | 		log_attrmap_paramap_options(); | ||||||
| 		log("        Match attribute names case-insensitively and set it to the specified\n"); |  | ||||||
| 		log("        name.\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 		log("    -rename <old_name> <new_name>\n"); |  | ||||||
| 		log("        Rename attributes as specified\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 		log("    -map <old_name>=<old_value> <new_name>=<new_value>\n"); |  | ||||||
| 		log("        Map key/value pairs as indicated.\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 		log("    -imap <old_name>=<old_value> <new_name>=<new_value>\n"); |  | ||||||
| 		log("        Like -map, but use case-insensitive match for <old_value> when\n"); |  | ||||||
| 		log("        it is a string value.\n"); |  | ||||||
| 		log("\n"); |  | ||||||
| 		log("    -remove <name>=<value>\n"); |  | ||||||
| 		log("        Remove attributes matching this pattern.\n"); |  | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    -modattr\n"); | 		log("    -modattr\n"); | ||||||
| 		log("        Operate on module attributes instead of attributes on wires and cells.\n"); | 		log("        Operate on module attributes instead of attributes on wires and cells.\n"); | ||||||
|  | @ -190,58 +251,9 @@ struct AttrmapPass : public Pass { | ||||||
| 		size_t argidx; | 		size_t argidx; | ||||||
| 		for (argidx = 1; argidx < args.size(); argidx++) | 		for (argidx = 1; argidx < args.size(); argidx++) | ||||||
| 		{ | 		{ | ||||||
| 			std::string arg = args[argidx]; | 			if (parse_attrmap_paramap_options(argidx, args, actions)) | ||||||
| 			if (arg == "-tocase" && argidx+1 < args.size()) { |  | ||||||
| 				auto action = new AttrmapTocase; |  | ||||||
| 				action->name = args[++argidx]; |  | ||||||
| 				actions.push_back(std::unique_ptr<AttrmapAction>(action)); |  | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			if (args[argidx] == "-modattr") { | ||||||
| 			if (arg == "-rename" && argidx+2 < args.size()) { |  | ||||||
| 				auto action = new AttrmapRename; |  | ||||||
| 				action->old_name = args[++argidx]; |  | ||||||
| 				action->new_name = args[++argidx]; |  | ||||||
| 				actions.push_back(std::unique_ptr<AttrmapAction>(action)); |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			if ((arg == "-map" || arg == "-imap") && argidx+2 < args.size()) { |  | ||||||
| 				string arg1 = args[++argidx]; |  | ||||||
| 				string arg2 = args[++argidx]; |  | ||||||
| 				string val1, val2; |  | ||||||
| 				size_t p = arg1.find("="); |  | ||||||
| 				if (p != string::npos) { |  | ||||||
| 					val1 = arg1.substr(p+1); |  | ||||||
| 					arg1 = arg1.substr(0, p); |  | ||||||
| 				} |  | ||||||
| 				p = arg2.find("="); |  | ||||||
| 				if (p != string::npos) { |  | ||||||
| 					val2 = arg2.substr(p+1); |  | ||||||
| 					arg2 = arg2.substr(0, p); |  | ||||||
| 				} |  | ||||||
| 				auto action = new AttrmapMap; |  | ||||||
| 				action->imap = (arg == "-map"); |  | ||||||
| 				action->old_name = arg1; |  | ||||||
| 				action->new_name = arg2; |  | ||||||
| 				action->old_value = val1; |  | ||||||
| 				action->new_value = val2; |  | ||||||
| 				actions.push_back(std::unique_ptr<AttrmapAction>(action)); |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			if (arg == "-remove" && argidx+1 < args.size()) { |  | ||||||
| 				string arg1 = args[++argidx], val1; |  | ||||||
| 				size_t p = arg1.find("="); |  | ||||||
| 				if (p != string::npos) { |  | ||||||
| 					val1 = arg1.substr(p+1); |  | ||||||
| 					arg1 = arg1.substr(0, p); |  | ||||||
| 				} |  | ||||||
| 				auto action = new AttrmapRemove; |  | ||||||
| 				action->name = arg1; |  | ||||||
| 				action->has_value = (p != string::npos); |  | ||||||
| 				action->value = val1; |  | ||||||
| 				actions.push_back(std::unique_ptr<AttrmapAction>(action)); |  | ||||||
| 				continue; |  | ||||||
| 			} |  | ||||||
| 			if (arg == "-modattr") { |  | ||||||
| 				modattr_mode = true; | 				modattr_mode = true; | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | @ -287,4 +299,43 @@ struct AttrmapPass : public Pass { | ||||||
| 	} | 	} | ||||||
| } AttrmapPass; | } AttrmapPass; | ||||||
| 
 | 
 | ||||||
|  | struct ParamapPass : public Pass { | ||||||
|  | 	ParamapPass() : Pass("paramap", "renaming cell parameters") { } | ||||||
|  | 	void help() YS_OVERRIDE | ||||||
|  | 	{ | ||||||
|  | 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("    paramap [options] [selection]\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("This command renames cell parameters and/or maps key/value pairs to\n"); | ||||||
|  | 		log("other key/value pairs.\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log_attrmap_paramap_options(); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("For example, mapping Diamond-style ECP5 \"init\" attributes to Yosys-style:\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("    paramap -tocase INIT t:LUT4\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 	} | ||||||
|  | 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | ||||||
|  | 	{ | ||||||
|  | 		log_header(design, "Executing PARAMAP pass (move or copy cell parameters).\n"); | ||||||
|  | 
 | ||||||
|  | 		vector<std::unique_ptr<AttrmapAction>> actions; | ||||||
|  | 
 | ||||||
|  | 		size_t argidx; | ||||||
|  | 		for (argidx = 1; argidx < args.size(); argidx++) | ||||||
|  | 		{ | ||||||
|  | 			if (parse_attrmap_paramap_options(argidx, args, actions)) | ||||||
|  | 				continue; | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		extra_args(args, argidx, design); | ||||||
|  | 
 | ||||||
|  | 		for (auto module : design->selected_modules()) | ||||||
|  | 		for (auto cell : module->selected_cells()) | ||||||
|  | 			attrmap_apply(stringf("%s.%s", log_id(module), log_id(cell)), actions, cell->parameters); | ||||||
|  | 	} | ||||||
|  | } ParamapPass; | ||||||
|  | 
 | ||||||
| PRIVATE_NAMESPACE_END | PRIVATE_NAMESPACE_END | ||||||
|  |  | ||||||
							
								
								
									
										298
									
								
								passes/techmap/clkbufmap.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										298
									
								
								passes/techmap/clkbufmap.cc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,298 @@ | ||||||
|  | /*
 | ||||||
|  |  *  yosys -- Yosys Open SYnthesis Suite | ||||||
|  |  * | ||||||
|  |  *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at> | ||||||
|  |  *  Copyright (C) 2019  Marcin Kościelnicki <mwk@0x04.net> | ||||||
|  |  * | ||||||
|  |  *  Permission to use, copy, modify, and/or distribute this software for any | ||||||
|  |  *  purpose with or without fee is hereby granted, provided that the above | ||||||
|  |  *  copyright notice and this permission notice appear in all copies. | ||||||
|  |  * | ||||||
|  |  *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||||
|  |  *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||||
|  |  *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||||
|  |  *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||||
|  |  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||||
|  |  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||||||
|  |  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "kernel/yosys.h" | ||||||
|  | #include "kernel/sigtools.h" | ||||||
|  | 
 | ||||||
|  | USING_YOSYS_NAMESPACE | ||||||
|  | PRIVATE_NAMESPACE_BEGIN | ||||||
|  | 
 | ||||||
|  | void split_portname_pair(std::string &port1, std::string &port2) | ||||||
|  | { | ||||||
|  | 	size_t pos = port1.find_first_of(':'); | ||||||
|  | 	if (pos != std::string::npos) { | ||||||
|  | 		port2 = port1.substr(pos+1); | ||||||
|  | 		port1 = port1.substr(0, pos); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | struct ClkbufmapPass : public Pass { | ||||||
|  | 	ClkbufmapPass() : Pass("clkbufmap", "insert global buffers on clock networks") { } | ||||||
|  | 	void help() YS_OVERRIDE | ||||||
|  | 	{ | ||||||
|  | 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("    clkbufmap [options] [selection]\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("Inserts global buffers between nets connected to clock inputs and their drivers.\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("In the absence of any selection, all wires without the 'clkbuf_inhibit'\n"); | ||||||
|  | 		log("attribute will be considered for global buffer insertion.\n"); | ||||||
|  | 		log("Alternatively, to consider all wires without the 'buffer_type' attribute set to\n"); | ||||||
|  | 		log("'none' or 'bufr' one would specify:\n"); | ||||||
|  | 		log("  'w:* a:buffer_type=none a:buffer_type=bufr %%u %%d'\n"); | ||||||
|  | 		log("as the selection.\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("    -buf <celltype> <portname_out>:<portname_in>\n"); | ||||||
|  | 		log("        Specifies the cell type to use for the global buffers\n"); | ||||||
|  | 		log("        and its port names.  The first port will be connected to\n"); | ||||||
|  | 		log("        the clock network sinks, and the second will be connected\n"); | ||||||
|  | 		log("        to the actual clock source.  This option is required.\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("    -inpad <celltype> <portname_out>:<portname_in>\n"); | ||||||
|  | 		log("        If specified, a PAD cell of the given type is inserted on\n"); | ||||||
|  | 		log("        clock nets that are also top module's inputs (in addition\n"); | ||||||
|  | 		log("        to the global buffer).\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void module_queue(Design *design, Module *module, std::vector<Module *> &modules_sorted, pool<Module *> &modules_processed) { | ||||||
|  | 		if (modules_processed.count(module)) | ||||||
|  | 			return; | ||||||
|  | 		for (auto cell : module->cells()) { | ||||||
|  | 			Module *submodule = design->module(cell->type); | ||||||
|  | 			if (!submodule) | ||||||
|  | 				continue; | ||||||
|  | 			module_queue(design, submodule, modules_sorted, modules_processed); | ||||||
|  | 		} | ||||||
|  | 		modules_sorted.push_back(module); | ||||||
|  | 		modules_processed.insert(module); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | ||||||
|  | 	{ | ||||||
|  | 		log_header(design, "Executing CLKBUFMAP pass (inserting global clock buffers).\n"); | ||||||
|  | 
 | ||||||
|  | 		std::string buf_celltype, buf_portname, buf_portname2; | ||||||
|  | 		std::string inpad_celltype, inpad_portname, inpad_portname2; | ||||||
|  | 
 | ||||||
|  | 		size_t argidx; | ||||||
|  | 		for (argidx = 1; argidx < args.size(); argidx++) | ||||||
|  | 		{ | ||||||
|  | 			std::string arg = args[argidx]; | ||||||
|  | 			if (arg == "-buf" && argidx+2 < args.size()) { | ||||||
|  | 				buf_celltype = args[++argidx]; | ||||||
|  | 				buf_portname = args[++argidx]; | ||||||
|  | 				split_portname_pair(buf_portname, buf_portname2); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			if (arg == "-inpad" && argidx+2 < args.size()) { | ||||||
|  | 				inpad_celltype = args[++argidx]; | ||||||
|  | 				inpad_portname = args[++argidx]; | ||||||
|  | 				split_portname_pair(inpad_portname, inpad_portname2); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		bool select = false; | ||||||
|  | 		if (argidx < args.size()) { | ||||||
|  | 			if (args[argidx].compare(0, 1, "-") != 0) | ||||||
|  | 				select = true; | ||||||
|  | 			extra_args(args, argidx, design); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (buf_celltype.empty()) | ||||||
|  | 			log_error("The -buf option is required.\n"); | ||||||
|  | 
 | ||||||
|  | 		// Cell type, port name, bit index.
 | ||||||
|  | 		pool<pair<IdString, pair<IdString, int>>> sink_ports; | ||||||
|  | 		pool<pair<IdString, pair<IdString, int>>> buf_ports; | ||||||
|  | 
 | ||||||
|  | 		// Process submodules before module using them.
 | ||||||
|  | 		std::vector<Module *> modules_sorted; | ||||||
|  | 		pool<Module *> modules_processed; | ||||||
|  | 		for (auto module : design->selected_modules()) | ||||||
|  | 			module_queue(design, module, modules_sorted, modules_processed); | ||||||
|  | 
 | ||||||
|  | 		for (auto module : modules_sorted) | ||||||
|  | 		{ | ||||||
|  | 			if (module->get_blackbox_attribute()) { | ||||||
|  | 				for (auto port : module->ports) { | ||||||
|  | 					auto wire = module->wire(port); | ||||||
|  | 					if (wire->get_bool_attribute("\\clkbuf_driver")) | ||||||
|  | 						for (int i = 0; i < GetSize(wire); i++) | ||||||
|  | 							buf_ports.insert(make_pair(module->name, make_pair(wire->name, i))); | ||||||
|  | 					if (wire->get_bool_attribute("\\clkbuf_sink")) | ||||||
|  | 						for (int i = 0; i < GetSize(wire); i++) | ||||||
|  | 							sink_ports.insert(make_pair(module->name, make_pair(wire->name, i))); | ||||||
|  | 				} | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			pool<SigBit> sink_wire_bits; | ||||||
|  | 			pool<SigBit> buf_wire_bits; | ||||||
|  | 			pool<SigBit> driven_wire_bits; | ||||||
|  | 			SigMap sigmap(module); | ||||||
|  | 			// bit -> (buffer, buffer's input)
 | ||||||
|  | 			dict<SigBit, pair<Cell *, Wire *>> buffered_bits; | ||||||
|  | 
 | ||||||
|  | 			// First, collect nets that could use a clock buffer.
 | ||||||
|  | 			for (auto cell : module->cells()) | ||||||
|  | 			for (auto port : cell->connections()) | ||||||
|  | 			for (int i = 0; i < port.second.size(); i++) | ||||||
|  | 				if (sink_ports.count(make_pair(cell->type, make_pair(port.first, i)))) | ||||||
|  | 					sink_wire_bits.insert(sigmap(port.second[i])); | ||||||
|  | 
 | ||||||
|  | 			// Second, collect ones that already have a clock buffer.
 | ||||||
|  | 			for (auto cell : module->cells()) | ||||||
|  | 			for (auto port : cell->connections()) | ||||||
|  | 			for (int i = 0; i < port.second.size(); i++) | ||||||
|  | 				if (buf_ports.count(make_pair(cell->type, make_pair(port.first, i)))) | ||||||
|  | 					buf_wire_bits.insert(sigmap(port.second[i])); | ||||||
|  | 
 | ||||||
|  | 			// Collect all driven bits.
 | ||||||
|  | 			for (auto cell : module->cells()) | ||||||
|  | 			for (auto port : cell->connections()) | ||||||
|  | 				if (cell->output(port.first)) | ||||||
|  | 					for (int i = 0; i < port.second.size(); i++) | ||||||
|  | 						driven_wire_bits.insert(port.second[i]); | ||||||
|  | 
 | ||||||
|  | 			// Insert buffers.
 | ||||||
|  | 			std::vector<pair<Wire *, Wire *>> input_queue; | ||||||
|  | 			// Copy current wire list, as we will be adding new ones during iteration.
 | ||||||
|  | 			std::vector<Wire *> wires(module->wires()); | ||||||
|  | 			for (auto wire : wires) | ||||||
|  | 			{ | ||||||
|  | 				// Should not happen.
 | ||||||
|  | 				if (wire->port_input && wire->port_output) | ||||||
|  | 					continue; | ||||||
|  | 				bool process_wire = module->selected(wire); | ||||||
|  | 				if (!select && wire->get_bool_attribute("\\clkbuf_inhibit")) | ||||||
|  | 					process_wire = false; | ||||||
|  | 				if (!process_wire) { | ||||||
|  | 					// This wire is supposed to be bypassed, so make sure we don't buffer it in
 | ||||||
|  | 					// some buffer higher up in the hierarchy.
 | ||||||
|  | 					if (wire->port_output) | ||||||
|  | 						for (int i = 0; i < GetSize(wire); i++) | ||||||
|  | 							buf_ports.insert(make_pair(module->name, make_pair(wire->name, i))); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				pool<int> input_bits; | ||||||
|  | 
 | ||||||
|  | 				for (int i = 0; i < GetSize(wire); i++) | ||||||
|  | 				{ | ||||||
|  | 					SigBit wire_bit(wire, i); | ||||||
|  | 					SigBit mapped_wire_bit = sigmap(wire_bit); | ||||||
|  | 					if (buf_wire_bits.count(mapped_wire_bit)) { | ||||||
|  | 						// Already buffered downstream.  If this is an output, mark it.
 | ||||||
|  | 						if (wire->port_output) | ||||||
|  | 							buf_ports.insert(make_pair(module->name, make_pair(wire->name, i))); | ||||||
|  | 					} else if (!sink_wire_bits.count(mapped_wire_bit)) { | ||||||
|  | 						// Nothing to do.
 | ||||||
|  | 					} else if (driven_wire_bits.count(wire_bit) || (wire->port_input && module->get_bool_attribute("\\top"))) { | ||||||
|  | 						// Clock network not yet buffered, driven by one of
 | ||||||
|  | 						// our cells or a top-level input -- buffer it.
 | ||||||
|  | 
 | ||||||
|  | 						log("Inserting %s on %s.%s[%d].\n", buf_celltype.c_str(), log_id(module), log_id(wire), i); | ||||||
|  | 						RTLIL::Cell *cell = module->addCell(NEW_ID, RTLIL::escape_id(buf_celltype)); | ||||||
|  | 						Wire *iwire = module->addWire(NEW_ID); | ||||||
|  | 						cell->setPort(RTLIL::escape_id(buf_portname), mapped_wire_bit); | ||||||
|  | 						cell->setPort(RTLIL::escape_id(buf_portname2), iwire); | ||||||
|  | 						if (wire->port_input && !inpad_celltype.empty() && module->get_bool_attribute("\\top")) { | ||||||
|  | 							log("Inserting %s on %s.%s[%d].\n", inpad_celltype.c_str(), log_id(module), log_id(wire), i); | ||||||
|  | 							RTLIL::Cell *cell2 = module->addCell(NEW_ID, RTLIL::escape_id(inpad_celltype)); | ||||||
|  | 							cell2->setPort(RTLIL::escape_id(inpad_portname), iwire); | ||||||
|  | 							iwire = module->addWire(NEW_ID); | ||||||
|  | 							cell2->setPort(RTLIL::escape_id(inpad_portname2), iwire); | ||||||
|  | 						} | ||||||
|  | 						buffered_bits[mapped_wire_bit] = make_pair(cell, iwire); | ||||||
|  | 
 | ||||||
|  | 						if (wire->port_input) { | ||||||
|  | 							input_bits.insert(i); | ||||||
|  | 						} | ||||||
|  | 					} else if (wire->port_input) { | ||||||
|  | 						// A clock input in a submodule -- mark it, let higher level
 | ||||||
|  | 						// worry about it.
 | ||||||
|  | 						if (wire->port_input) | ||||||
|  | 							sink_ports.insert(make_pair(module->name, make_pair(wire->name, i))); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 				if (!input_bits.empty()) { | ||||||
|  | 					// This is an input port and some buffers were inserted -- we need
 | ||||||
|  | 					// to create a new input wire and transfer attributes.
 | ||||||
|  | 					Wire *new_wire = module->addWire(NEW_ID, wire); | ||||||
|  | 
 | ||||||
|  | 					for (int i = 0; i < wire->width; i++) { | ||||||
|  | 						SigBit wire_bit(wire, i); | ||||||
|  | 						SigBit mapped_wire_bit = sigmap(wire_bit); | ||||||
|  | 						auto it = buffered_bits.find(mapped_wire_bit); | ||||||
|  | 						if (it != buffered_bits.end()) { | ||||||
|  | 
 | ||||||
|  | 							module->connect(it->second.second, SigSpec(new_wire, i)); | ||||||
|  | 						} else { | ||||||
|  | 							module->connect(SigSpec(wire, i), SigSpec(new_wire, i)); | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 					input_queue.push_back(make_pair(wire, new_wire)); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// Mark any newly-buffered output ports as such.
 | ||||||
|  | 			for (auto wire : module->selected_wires()) { | ||||||
|  | 				if (wire->port_input || !wire->port_output) | ||||||
|  | 					continue; | ||||||
|  | 				for (int i = 0; i < GetSize(wire); i++) | ||||||
|  | 				{ | ||||||
|  | 					SigBit wire_bit(wire, i); | ||||||
|  | 					SigBit mapped_wire_bit = sigmap(wire_bit); | ||||||
|  | 					if (buffered_bits.count(mapped_wire_bit)) | ||||||
|  | 						buf_ports.insert(make_pair(module->name, make_pair(wire->name, i))); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// Reconnect the drivers to buffer inputs.
 | ||||||
|  | 			for (auto cell : module->cells()) | ||||||
|  | 			for (auto port : cell->connections()) { | ||||||
|  | 				if (!cell->output(port.first)) | ||||||
|  | 					continue; | ||||||
|  | 				SigSpec sig = port.second; | ||||||
|  | 				bool newsig = false; | ||||||
|  | 				for (auto &bit : sig) { | ||||||
|  | 					const auto it = buffered_bits.find(sigmap(bit)); | ||||||
|  | 					if (it == buffered_bits.end()) | ||||||
|  | 						continue; | ||||||
|  | 					// Avoid substituting buffer's own output pin.
 | ||||||
|  | 					if (cell == it->second.first) | ||||||
|  | 						continue; | ||||||
|  | 					bit = it->second.second; | ||||||
|  | 					newsig = true; | ||||||
|  | 				} | ||||||
|  | 				if (newsig) | ||||||
|  | 					cell->setPort(port.first, sig); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// This has to be done last, to avoid upsetting sigmap before the port reconnections.
 | ||||||
|  | 			for (auto &it : input_queue) { | ||||||
|  | 				Wire *wire = it.first; | ||||||
|  | 				Wire *new_wire = it.second; | ||||||
|  | 				module->swap_names(new_wire, wire); | ||||||
|  | 				wire->attributes.clear(); | ||||||
|  | 				wire->port_id = 0; | ||||||
|  | 				wire->port_input = false; | ||||||
|  | 				wire->port_output = false; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			module->fixup_ports(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } ClkbufmapPass; | ||||||
|  | 
 | ||||||
|  | PRIVATE_NAMESPACE_END | ||||||
|  | @ -64,6 +64,11 @@ struct IopadmapPass : public Pass { | ||||||
| 		log("        of the tristate driver and the 2nd portname is the internal output\n"); | 		log("        of the tristate driver and the 2nd portname is the internal output\n"); | ||||||
| 		log("        buffering the external signal.\n"); | 		log("        buffering the external signal.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | 		log("    -ignore <celltype> <portname>[:<portname>]*\n"); | ||||||
|  | 		log("        Skips mapping inputs/outputs that are already connected to given\n"); | ||||||
|  | 		log("        ports of the given cell.  Can be used multiple times.  This is in\n"); | ||||||
|  | 		log("        addition to the cells specified as mapping targets.\n"); | ||||||
|  | 		log("\n"); | ||||||
| 		log("    -widthparam <param_name>\n"); | 		log("    -widthparam <param_name>\n"); | ||||||
| 		log("        Use the specified parameter name to set the port width.\n"); | 		log("        Use the specified parameter name to set the port width.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | @ -88,6 +93,7 @@ struct IopadmapPass : public Pass { | ||||||
| 		std::string toutpad_celltype, toutpad_portname, toutpad_portname2, toutpad_portname3; | 		std::string toutpad_celltype, toutpad_portname, toutpad_portname2, toutpad_portname3; | ||||||
| 		std::string tinoutpad_celltype, tinoutpad_portname, tinoutpad_portname2, tinoutpad_portname3, tinoutpad_portname4; | 		std::string tinoutpad_celltype, tinoutpad_portname, tinoutpad_portname2, tinoutpad_portname3, tinoutpad_portname4; | ||||||
| 		std::string widthparam, nameparam; | 		std::string widthparam, nameparam; | ||||||
|  | 		pool<pair<IdString, IdString>> ignore; | ||||||
| 		bool flag_bits = false; | 		bool flag_bits = false; | ||||||
| 
 | 
 | ||||||
| 		size_t argidx; | 		size_t argidx; | ||||||
|  | @ -127,6 +133,18 @@ struct IopadmapPass : public Pass { | ||||||
| 				split_portname_pair(tinoutpad_portname3, tinoutpad_portname4); | 				split_portname_pair(tinoutpad_portname3, tinoutpad_portname4); | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | 			if (arg == "-ignore" && argidx+2 < args.size()) { | ||||||
|  | 				std::string ignore_celltype = args[++argidx]; | ||||||
|  | 				std::string ignore_portname = args[++argidx]; | ||||||
|  | 				std::string ignore_portname2; | ||||||
|  | 				while (!ignore_portname.empty()) { | ||||||
|  | 					split_portname_pair(ignore_portname, ignore_portname2); | ||||||
|  | 					ignore.insert(make_pair(RTLIL::escape_id(ignore_celltype), RTLIL::escape_id(ignore_portname))); | ||||||
|  | 
 | ||||||
|  | 					ignore_portname = ignore_portname2; | ||||||
|  | 				} | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
| 			if (arg == "-widthparam" && argidx+1 < args.size()) { | 			if (arg == "-widthparam" && argidx+1 < args.size()) { | ||||||
| 				widthparam = args[++argidx]; | 				widthparam = args[++argidx]; | ||||||
| 				continue; | 				continue; | ||||||
|  | @ -143,6 +161,23 @@ struct IopadmapPass : public Pass { | ||||||
| 		} | 		} | ||||||
| 		extra_args(args, argidx, design); | 		extra_args(args, argidx, design); | ||||||
| 
 | 
 | ||||||
|  | 		if (!inpad_portname2.empty()) | ||||||
|  | 			ignore.insert(make_pair(RTLIL::escape_id(inpad_celltype), RTLIL::escape_id(inpad_portname2))); | ||||||
|  | 		if (!outpad_portname2.empty()) | ||||||
|  | 			ignore.insert(make_pair(RTLIL::escape_id(outpad_celltype), RTLIL::escape_id(outpad_portname2))); | ||||||
|  | 		if (!inoutpad_portname2.empty()) | ||||||
|  | 			ignore.insert(make_pair(RTLIL::escape_id(inoutpad_celltype), RTLIL::escape_id(inoutpad_portname2))); | ||||||
|  | 		if (!toutpad_portname3.empty()) | ||||||
|  | 			ignore.insert(make_pair(RTLIL::escape_id(toutpad_celltype), RTLIL::escape_id(toutpad_portname3))); | ||||||
|  | 		if (!tinoutpad_portname4.empty()) | ||||||
|  | 			ignore.insert(make_pair(RTLIL::escape_id(tinoutpad_celltype), RTLIL::escape_id(tinoutpad_portname4))); | ||||||
|  | 
 | ||||||
|  | 		for (auto module : design->modules()) | ||||||
|  | 			if (module->get_blackbox_attribute()) | ||||||
|  | 				for (auto wire : module->wires()) | ||||||
|  | 					if (wire->get_bool_attribute("\\iopad_external_pin")) | ||||||
|  | 						ignore.insert(make_pair(module->name, wire->name)); | ||||||
|  | 
 | ||||||
| 		for (auto module : design->selected_modules()) | 		for (auto module : design->selected_modules()) | ||||||
| 		{ | 		{ | ||||||
| 			dict<IdString, pool<int>> skip_wires; | 			dict<IdString, pool<int>> skip_wires; | ||||||
|  | @ -150,28 +185,11 @@ struct IopadmapPass : public Pass { | ||||||
| 			SigMap sigmap(module); | 			SigMap sigmap(module); | ||||||
| 
 | 
 | ||||||
| 			for (auto cell : module->cells()) | 			for (auto cell : module->cells()) | ||||||
| 			{ | 			for (auto port : cell->connections()) | ||||||
| 				if (cell->type == RTLIL::escape_id(inpad_celltype) && cell->hasPort(RTLIL::escape_id(inpad_portname2))) | 				if (ignore.count(make_pair(cell->type, port.first))) | ||||||
| 					for (auto bit : sigmap(cell->getPort(RTLIL::escape_id(inpad_portname2)))) | 					for (auto bit : sigmap(port.second)) | ||||||
| 						skip_wire_bits.insert(bit); | 						skip_wire_bits.insert(bit); | ||||||
| 
 | 
 | ||||||
| 				if (cell->type == RTLIL::escape_id(outpad_celltype) && cell->hasPort(RTLIL::escape_id(outpad_portname2))) |  | ||||||
| 					for (auto bit : sigmap(cell->getPort(RTLIL::escape_id(outpad_portname2)))) |  | ||||||
| 						skip_wire_bits.insert(bit); |  | ||||||
| 
 |  | ||||||
| 				if (cell->type == RTLIL::escape_id(inoutpad_celltype) && cell->hasPort(RTLIL::escape_id(inoutpad_portname2))) |  | ||||||
| 					for (auto bit : sigmap(cell->getPort(RTLIL::escape_id(inoutpad_portname2)))) |  | ||||||
| 						skip_wire_bits.insert(bit); |  | ||||||
| 
 |  | ||||||
| 				if (cell->type == RTLIL::escape_id(toutpad_celltype) && cell->hasPort(RTLIL::escape_id(toutpad_portname3))) |  | ||||||
| 					for (auto bit : sigmap(cell->getPort(RTLIL::escape_id(toutpad_portname3)))) |  | ||||||
| 						skip_wire_bits.insert(bit); |  | ||||||
| 
 |  | ||||||
| 				if (cell->type == RTLIL::escape_id(tinoutpad_celltype) && cell->hasPort(RTLIL::escape_id(tinoutpad_portname4))) |  | ||||||
| 					for (auto bit : sigmap(cell->getPort(RTLIL::escape_id(tinoutpad_portname4)))) |  | ||||||
| 						skip_wire_bits.insert(bit); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty()) | 			if (!toutpad_celltype.empty() || !tinoutpad_celltype.empty()) | ||||||
| 			{ | 			{ | ||||||
| 				dict<SigBit, pair<IdString, pool<IdString>>> tbuf_bits; | 				dict<SigBit, pair<IdString, pool<IdString>>> tbuf_bits; | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| 
 | 
 | ||||||
| OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_ffinit.o | OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_ffinit.o \ | ||||||
|  |         techlibs/ecp5/ecp5_gsr.o | ||||||
| 
 | 
 | ||||||
| $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_map.v)) | $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_map.v)) | ||||||
| $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_sim.v)) | $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_sim.v)) | ||||||
|  |  | ||||||
|  | @ -33,7 +33,7 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); | ||||||
| 			.CLKBMUX(CLKBMUX), | 			.CLKBMUX(CLKBMUX), | ||||||
| 			.WRITEMODE_A(WRITEMODE_A), | 			.WRITEMODE_A(WRITEMODE_A), | ||||||
| 			.WRITEMODE_B("READBEFOREWRITE"), | 			.WRITEMODE_B("READBEFOREWRITE"), | ||||||
| 			.GSR("DISABLED") | 			.GSR("AUTO") | ||||||
| 		) _TECHMAP_REPLACE_ ( | 		) _TECHMAP_REPLACE_ ( | ||||||
| 			`include "bram_conn_1.vh" | 			`include "bram_conn_1.vh" | ||||||
| 			.CLKA(CLK2), .CLKB(CLK3), | 			.CLKA(CLK2), .CLKB(CLK3), | ||||||
|  | @ -50,7 +50,7 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); | ||||||
| 			.CLKBMUX(CLKBMUX), | 			.CLKBMUX(CLKBMUX), | ||||||
| 			.WRITEMODE_A(WRITEMODE_A), | 			.WRITEMODE_A(WRITEMODE_A), | ||||||
| 			.WRITEMODE_B("READBEFOREWRITE"), | 			.WRITEMODE_B("READBEFOREWRITE"), | ||||||
| 			.GSR("DISABLED") | 			.GSR("AUTO") | ||||||
| 		) _TECHMAP_REPLACE_ ( | 		) _TECHMAP_REPLACE_ ( | ||||||
| 			`include "bram_conn_2.vh" | 			`include "bram_conn_2.vh" | ||||||
| 			.CLKA(CLK2), .CLKB(CLK3), | 			.CLKA(CLK2), .CLKB(CLK3), | ||||||
|  | @ -67,7 +67,7 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); | ||||||
| 			.CLKBMUX(CLKBMUX), | 			.CLKBMUX(CLKBMUX), | ||||||
| 			.WRITEMODE_A(WRITEMODE_A), | 			.WRITEMODE_A(WRITEMODE_A), | ||||||
| 			.WRITEMODE_B("READBEFOREWRITE"), | 			.WRITEMODE_B("READBEFOREWRITE"), | ||||||
| 			.GSR("DISABLED") | 			.GSR("AUTO") | ||||||
| 		) _TECHMAP_REPLACE_ ( | 		) _TECHMAP_REPLACE_ ( | ||||||
| 			`include "bram_conn_4.vh" | 			`include "bram_conn_4.vh" | ||||||
| 			.CLKA(CLK2), .CLKB(CLK3), | 			.CLKA(CLK2), .CLKB(CLK3), | ||||||
|  | @ -84,7 +84,7 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); | ||||||
| 			.CLKBMUX(CLKBMUX), | 			.CLKBMUX(CLKBMUX), | ||||||
| 			.WRITEMODE_A(WRITEMODE_A), | 			.WRITEMODE_A(WRITEMODE_A), | ||||||
| 			.WRITEMODE_B("READBEFOREWRITE"), | 			.WRITEMODE_B("READBEFOREWRITE"), | ||||||
| 			.GSR("DISABLED") | 			.GSR("AUTO") | ||||||
| 		) _TECHMAP_REPLACE_ ( | 		) _TECHMAP_REPLACE_ ( | ||||||
| 			`include "bram_conn_9.vh" | 			`include "bram_conn_9.vh" | ||||||
| 			.CLKA(CLK2), .CLKB(CLK3), | 			.CLKA(CLK2), .CLKB(CLK3), | ||||||
|  | @ -101,7 +101,7 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); | ||||||
| 			.CLKBMUX(CLKBMUX), | 			.CLKBMUX(CLKBMUX), | ||||||
| 			.WRITEMODE_A(WRITEMODE_A), | 			.WRITEMODE_A(WRITEMODE_A), | ||||||
| 			.WRITEMODE_B("READBEFOREWRITE"), | 			.WRITEMODE_B("READBEFOREWRITE"), | ||||||
| 			.GSR("DISABLED") | 			.GSR("AUTO") | ||||||
| 		) _TECHMAP_REPLACE_ ( | 		) _TECHMAP_REPLACE_ ( | ||||||
| 			`include "bram_conn_18.vh" | 			`include "bram_conn_18.vh" | ||||||
| 			.CLKA(CLK2), .CLKB(CLK3), | 			.CLKA(CLK2), .CLKB(CLK3), | ||||||
|  |  | ||||||
|  | @ -664,3 +664,23 @@ module PCSCLKDIV ( | ||||||
| ); | ); | ||||||
| 	parameter GSR = "DISABLED"; | 	parameter GSR = "DISABLED"; | ||||||
| endmodule | endmodule | ||||||
|  | 
 | ||||||
|  | // Note: this module is not marked keep as we want it swept away in synth (sim use only) | ||||||
|  | (* blackbox *) | ||||||
|  | module PUR ( | ||||||
|  | 	input PUR | ||||||
|  | ); | ||||||
|  | 	parameter RST_PULSE = 1; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | (* blackbox, keep *) | ||||||
|  | module GSR ( | ||||||
|  | 	input GSR | ||||||
|  | ); | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | (* blackbox, keep *) | ||||||
|  | module SGSR ( | ||||||
|  | 	input GSR, CLK | ||||||
|  | ); | ||||||
|  | endmodule | ||||||
|  | @ -1,51 +1,51 @@ | ||||||
| module  \$_DFF_N_ (input D, C, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule | module  \$_DFF_N_ (input D, C, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$_DFF_P_ (input D, C, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule | module  \$_DFF_P_ (input D, C, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule | ||||||
| 
 | 
 | ||||||
| module  \$_DFFE_NN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule | module  \$_DFFE_NN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$_DFFE_PN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule | module  \$_DFFE_PN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule | ||||||
| 
 | 
 | ||||||
| module  \$_DFFE_NP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule | module  \$_DFFE_NP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$_DFFE_PP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule | module  \$_DFFE_PP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule | ||||||
| 
 | 
 | ||||||
| module  \$_DFF_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$_DFF_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$_DFF_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$_DFF_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$_DFF_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$_DFF_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$_DFF_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$_DFF_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| 
 | 
 | ||||||
| module  \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| 
 | 
 | ||||||
| module  \$__DFFS_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$__DFFS_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFS_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$__DFFS_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFS_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$__DFFS_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFS_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$__DFFS_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| 
 | 
 | ||||||
| module  \$__DFFS_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$__DFFS_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFS_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$__DFFS_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFS_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$__DFFS_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFS_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$__DFFS_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| 
 | 
 | ||||||
| module  \$__DFFE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$__DFFE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$__DFFE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$__DFFE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$__DFFE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| 
 | 
 | ||||||
| module  \$__DFFE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$__DFFE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$__DFFE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$__DFFE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$__DFFE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| 
 | 
 | ||||||
| module  \$__DFFSE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$__DFFSE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFSE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$__DFFSE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFSE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$__DFFSE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFSE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | module  \$__DFFSE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule | ||||||
| 
 | 
 | ||||||
| module  \$__DFFSE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$__DFFSE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFSE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$__DFFSE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| module  \$__DFFSE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | module  \$__DFFSE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE"))  _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule | ||||||
| 
 | 
 | ||||||
| // TODO: Diamond flip-flops | // TODO: Diamond flip-flops | ||||||
| // module FD1P3AX(); endmodule | // module FD1P3AX(); endmodule | ||||||
|  |  | ||||||
							
								
								
									
										135
									
								
								techlibs/ecp5/ecp5_gsr.cc
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								techlibs/ecp5/ecp5_gsr.cc
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,135 @@ | ||||||
|  | /*
 | ||||||
|  |  *  yosys -- Yosys Open SYnthesis Suite | ||||||
|  |  * | ||||||
|  |  *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at> | ||||||
|  |  *  Copyright (C) 2019  David Shah <david@symbioticeda.com> | ||||||
|  |  * | ||||||
|  |  *  Permission to use, copy, modify, and/or distribute this software for any | ||||||
|  |  *  purpose with or without fee is hereby granted, provided that the above | ||||||
|  |  *  copyright notice and this permission notice appear in all copies. | ||||||
|  |  * | ||||||
|  |  *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||||||
|  |  *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||||||
|  |  *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||||||
|  |  *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||||||
|  |  *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||||||
|  |  *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||||||
|  |  *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | #include "kernel/yosys.h" | ||||||
|  | #include "kernel/sigtools.h" | ||||||
|  | 
 | ||||||
|  | USING_YOSYS_NAMESPACE | ||||||
|  | PRIVATE_NAMESPACE_BEGIN | ||||||
|  | 
 | ||||||
|  | struct Ecp5GsrPass : public Pass { | ||||||
|  | 	Ecp5GsrPass() : Pass("ecp5_gsr", "ECP5: handle GSR") { } | ||||||
|  | 	void help() YS_OVERRIDE | ||||||
|  | 	{ | ||||||
|  | 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("    ecp5_gsr [options] [selection]\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("Trim active low async resets connected to GSR and resolve GSR parameter,\n"); | ||||||
|  | 		log("if a GSR or SGSR primitive is used in the design.\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("If any cell has the GSR parameter set to \"AUTO\", this will be resolved\n"); | ||||||
|  | 		log("to \"ENABLED\" if a GSR primitive is present and the (* nogsr *) attribute\n"); | ||||||
|  | 		log("is not set, otherwise it will be resolved to \"DISABLED\".\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 	} | ||||||
|  | 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | ||||||
|  | 	{ | ||||||
|  | 		log_header(design, "Executing ECP5_GSR pass (implement FF init values).\n"); | ||||||
|  | 
 | ||||||
|  | 		size_t argidx; | ||||||
|  | 		for (argidx = 1; argidx < args.size(); argidx++) | ||||||
|  | 		{ | ||||||
|  | 			// if (args[argidx] == "-singleton") {
 | ||||||
|  | 			// 	singleton_mode = true;
 | ||||||
|  | 			// 	continue;
 | ||||||
|  | 			// }
 | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		extra_args(args, argidx, design); | ||||||
|  | 
 | ||||||
|  | 		for (auto module : design->selected_modules()) | ||||||
|  | 		{ | ||||||
|  | 			log("Handling GSR in %s.\n", log_id(module)); | ||||||
|  | 
 | ||||||
|  | 			SigMap sigmap(module); | ||||||
|  | 
 | ||||||
|  | 			SigBit gsr; | ||||||
|  | 			bool found_gsr = false; | ||||||
|  | 
 | ||||||
|  | 			for (auto cell : module->selected_cells()) | ||||||
|  | 			{ | ||||||
|  | 				if (cell->type != ID(GSR) && cell->type != ID(SGSR)) | ||||||
|  | 					continue; | ||||||
|  | 				if (found_gsr) | ||||||
|  | 					log_error("Found more than one GSR or SGSR cell in module %s.\n", log_id(module)); | ||||||
|  | 				found_gsr = true; | ||||||
|  | 				SigSpec sig_gsr = cell->getPort(ID(GSR)); | ||||||
|  | 				if (GetSize(sig_gsr) < 1) | ||||||
|  | 					log_error("GSR cell %s has disconnected GSR input.\n", log_id(cell)); | ||||||
|  | 				gsr = sigmap(sig_gsr[0]); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			// Resolve GSR parameter
 | ||||||
|  | 
 | ||||||
|  | 			for (auto cell : module->selected_cells()) | ||||||
|  | 			{ | ||||||
|  | 				if (!cell->hasParam(ID(GSR)) || cell->getParam(ID(GSR)).decode_string() != "AUTO") | ||||||
|  | 					continue; | ||||||
|  | 				 | ||||||
|  | 				bool gsren = found_gsr; | ||||||
|  | 				if (cell->get_bool_attribute("\\nogsr")) | ||||||
|  | 					gsren = false; | ||||||
|  | 				cell->setParam(ID(GSR), gsren ? Const("ENABLED") : Const("DISABLED")); | ||||||
|  | 				 | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			if (!found_gsr) | ||||||
|  | 				continue; | ||||||
|  | 
 | ||||||
|  | 			// For finding active low FF inputs
 | ||||||
|  | 			pool<SigBit> inverted_gsr; | ||||||
|  | 
 | ||||||
|  | 			log_debug("GSR net in module %s is %s.\n", log_id(module), log_signal(gsr)); | ||||||
|  | 			for (auto cell : module->selected_cells()) | ||||||
|  | 			{ | ||||||
|  | 				if (cell->type != ID($_NOT_)) | ||||||
|  | 					continue; | ||||||
|  | 				SigSpec sig_a = cell->getPort(ID(A)), sig_y = cell->getPort(ID(Y)); | ||||||
|  | 				if (GetSize(sig_a) < 1 || GetSize(sig_y) < 1) | ||||||
|  | 					continue; | ||||||
|  | 				SigBit a = sigmap(sig_a[0]); | ||||||
|  | 				if (a == gsr) | ||||||
|  | 					inverted_gsr.insert(sigmap(sig_y[0])); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			for (auto cell : module->selected_cells()) | ||||||
|  | 			{ | ||||||
|  | 				if (cell->type != ID(TRELLIS_FF)) | ||||||
|  | 					continue; | ||||||
|  | 				if (!cell->hasParam(ID(GSR)) || cell->getParam(ID(GSR)).decode_string() != "ENABLED") | ||||||
|  | 					continue; | ||||||
|  | 				if (!cell->hasParam(ID(SRMODE)) || cell->getParam(ID(SRMODE)).decode_string() != "ASYNC") | ||||||
|  | 					continue; | ||||||
|  | 				SigSpec sig_lsr = cell->getPort(ID(LSR)); | ||||||
|  | 				if (GetSize(sig_lsr) < 1) | ||||||
|  | 					continue; | ||||||
|  | 				SigBit lsr = sigmap(sig_lsr[0]); | ||||||
|  | 				if (!inverted_gsr.count(lsr)) | ||||||
|  | 					continue; | ||||||
|  | 				cell->setParam(ID(SRMODE), Const("SYNC")); | ||||||
|  | 				cell->unsetPort(ID(LSR)); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } Ecp5GsrPass; | ||||||
|  | 
 | ||||||
|  | PRIVATE_NAMESPACE_END | ||||||
|  | @ -271,6 +271,8 @@ struct SynthEcp5Pass : public ScriptPass | ||||||
| 			run("opt_expr -undriven -mux_undef"); | 			run("opt_expr -undriven -mux_undef"); | ||||||
| 			run("simplemap"); | 			run("simplemap"); | ||||||
| 			run("ecp5_ffinit"); | 			run("ecp5_ffinit"); | ||||||
|  | 			run("ecp5_gsr"); | ||||||
|  | 			run("opt_clean"); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (check_label("map_luts")) | 		if (check_label("map_luts")) | ||||||
|  |  | ||||||
|  | @ -29,24 +29,35 @@ module GND(output G); | ||||||
|   assign G = 0; |   assign G = 0; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module IBUF(output O, input I); | module IBUF( | ||||||
|  |     output O, | ||||||
|  |     (* iopad_external_pin *) | ||||||
|  |     input I); | ||||||
|   parameter IOSTANDARD = "default"; |   parameter IOSTANDARD = "default"; | ||||||
|   parameter IBUF_LOW_PWR = 0; |   parameter IBUF_LOW_PWR = 0; | ||||||
|   assign O = I; |   assign O = I; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module OBUF(output O, input I); | module OBUF( | ||||||
|  |     (* iopad_external_pin *) | ||||||
|  |     output O, | ||||||
|  |     input I); | ||||||
|   parameter IOSTANDARD = "default"; |   parameter IOSTANDARD = "default"; | ||||||
|   parameter DRIVE = 12; |   parameter DRIVE = 12; | ||||||
|   parameter SLEW = "SLOW"; |   parameter SLEW = "SLOW"; | ||||||
|   assign O = I; |   assign O = I; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module BUFG(output O, input I); | module BUFG( | ||||||
|  |     (* clkbuf_driver *) | ||||||
|  |     output O, | ||||||
|  |     input I); | ||||||
|  | 
 | ||||||
|   assign O = I; |   assign O = I; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module BUFGCTRL( | module BUFGCTRL( | ||||||
|  |     (* clkbuf_driver *) | ||||||
|     output O, |     output O, | ||||||
|     input I0, input I1, |     input I0, input I1, | ||||||
|     input S0, input S1, |     input S0, input S1, | ||||||
|  | @ -72,7 +83,11 @@ assign O = S0_true ? I0_internal : (S1_true ? I1_internal : INIT_OUT); | ||||||
| 
 | 
 | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module BUFHCE(output O, input I, input CE); | module BUFHCE( | ||||||
|  |     (* clkbuf_driver *) | ||||||
|  |     output O, | ||||||
|  |     input I, | ||||||
|  |     input CE); | ||||||
| 
 | 
 | ||||||
| parameter [0:0] INIT_OUT = 1'b0; | parameter [0:0] INIT_OUT = 1'b0; | ||||||
| parameter CE_TYPE = "SYNC"; | parameter CE_TYPE = "SYNC"; | ||||||
|  | @ -221,7 +236,7 @@ endmodule | ||||||
| 
 | 
 | ||||||
| `endif | `endif | ||||||
| 
 | 
 | ||||||
| module FDRE (output reg Q, input C, CE, D, R); | module FDRE (output reg Q, (* clkbuf_sink *) input C, input CE, D, R); | ||||||
|   parameter [0:0] INIT = 1'b0; |   parameter [0:0] INIT = 1'b0; | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |   parameter [0:0] IS_C_INVERTED = 1'b0; | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |   parameter [0:0] IS_D_INVERTED = 1'b0; | ||||||
|  | @ -233,7 +248,7 @@ module FDRE (output reg Q, input C, CE, D, R); | ||||||
|   endcase endgenerate |   endcase endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDSE (output reg Q, input C, CE, D, S); | module FDSE (output reg Q, (* clkbuf_sink *) input C, input CE, D, S); | ||||||
|   parameter [0:0] INIT = 1'b1; |   parameter [0:0] INIT = 1'b1; | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |   parameter [0:0] IS_C_INVERTED = 1'b0; | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |   parameter [0:0] IS_D_INVERTED = 1'b0; | ||||||
|  | @ -245,7 +260,7 @@ module FDSE (output reg Q, input C, CE, D, S); | ||||||
|   endcase endgenerate |   endcase endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDCE (output reg Q, input C, CE, D, CLR); | module FDCE (output reg Q, (* clkbuf_sink *) input C, input CE, D, CLR); | ||||||
|   parameter [0:0] INIT = 1'b0; |   parameter [0:0] INIT = 1'b0; | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |   parameter [0:0] IS_C_INVERTED = 1'b0; | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |   parameter [0:0] IS_D_INVERTED = 1'b0; | ||||||
|  | @ -259,7 +274,7 @@ module FDCE (output reg Q, input C, CE, D, CLR); | ||||||
|   endcase endgenerate |   endcase endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDPE (output reg Q, input C, CE, D, PRE); | module FDPE (output reg Q, (* clkbuf_sink *) input C, input CE, D, PRE); | ||||||
|   parameter [0:0] INIT = 1'b1; |   parameter [0:0] INIT = 1'b1; | ||||||
|   parameter [0:0] IS_C_INVERTED = 1'b0; |   parameter [0:0] IS_C_INVERTED = 1'b0; | ||||||
|   parameter [0:0] IS_D_INVERTED = 1'b0; |   parameter [0:0] IS_D_INVERTED = 1'b0; | ||||||
|  | @ -273,25 +288,25 @@ module FDPE (output reg Q, input C, CE, D, PRE); | ||||||
|   endcase endgenerate |   endcase endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDRE_1 (output reg Q, input C, CE, D, R); | module FDRE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, 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; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDSE_1 (output reg Q, input C, CE, D, S); | module FDSE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, 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; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDCE_1 (output reg Q, input C, CE, D, CLR); | module FDCE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, CLR); | ||||||
|   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; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module FDPE_1 (output reg Q, input C, CE, D, PRE); | module FDPE_1 (output reg Q, (* clkbuf_sink *) input C, input CE, D, 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; | ||||||
|  | @ -302,6 +317,7 @@ module RAM32X1D ( | ||||||
|   output DPO, SPO, |   output DPO, SPO, | ||||||
|   (* abc_scc_break *) |   (* abc_scc_break *) | ||||||
|   input  D, |   input  D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|   input  WCLK, |   input  WCLK, | ||||||
|   (* abc_scc_break *) |   (* abc_scc_break *) | ||||||
|   input  WE, |   input  WE, | ||||||
|  | @ -324,6 +340,7 @@ module RAM64X1D ( | ||||||
|   output DPO, SPO, |   output DPO, SPO, | ||||||
|   (* abc_scc_break *) |   (* abc_scc_break *) | ||||||
|   input  D, |   input  D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|   input  WCLK, |   input  WCLK, | ||||||
|   (* abc_scc_break *) |   (* abc_scc_break *) | ||||||
|   input  WE, |   input  WE, | ||||||
|  | @ -346,6 +363,7 @@ module RAM128X1D ( | ||||||
|   output       DPO, SPO, |   output       DPO, SPO, | ||||||
|   (* abc_scc_break *) |   (* abc_scc_break *) | ||||||
|   input        D, |   input        D, | ||||||
|  |   (* clkbuf_sink *) | ||||||
|   input        WCLK, |   input        WCLK, | ||||||
|   (* abc_scc_break *) |   (* abc_scc_break *) | ||||||
|   input        WE, |   input        WE, | ||||||
|  | @ -362,7 +380,9 @@ endmodule | ||||||
| 
 | 
 | ||||||
| module SRL16E ( | module SRL16E ( | ||||||
|   output Q, |   output Q, | ||||||
|   input A0, A1, A2, A3, CE, CLK, D |   (* clkbuf_sink *) | ||||||
|  |   input CLK, | ||||||
|  |   input A0, A1, A2, A3, CE, D | ||||||
| ); | ); | ||||||
|   parameter [15:0] INIT = 16'h0000; |   parameter [15:0] INIT = 16'h0000; | ||||||
|   parameter [0:0] IS_CLK_INVERTED = 1'b0; |   parameter [0:0] IS_CLK_INVERTED = 1'b0; | ||||||
|  | @ -374,7 +394,27 @@ module SRL16E ( | ||||||
|       always @(negedge CLK) if (CE) r <= { r[14:0], D }; |       always @(negedge CLK) if (CE) r <= { r[14:0], D }; | ||||||
|     end |     end | ||||||
|     else |     else | ||||||
|         always @(posedge CLK) if (CE) r <= { r[14:0], D }; |       always @(posedge CLK) if (CE) r <= { r[14:0], D }; | ||||||
|  |   endgenerate | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module SRLC16E ( | ||||||
|  |   output Q, | ||||||
|  |   output Q15, | ||||||
|  |   input A0, A1, A2, A3, CE, CLK, D | ||||||
|  | ); | ||||||
|  |   parameter [15:0] INIT = 16'h0000; | ||||||
|  |   parameter [0:0] IS_CLK_INVERTED = 1'b0; | ||||||
|  | 
 | ||||||
|  |   reg [15:0] r = INIT; | ||||||
|  |   assign Q15 = r[15]; | ||||||
|  |   assign Q = r[{A3,A2,A1,A0}]; | ||||||
|  |   generate | ||||||
|  |     if (IS_CLK_INVERTED) begin | ||||||
|  |       always @(negedge CLK) if (CE) r <= { r[14:0], D }; | ||||||
|  |     end | ||||||
|  |     else | ||||||
|  |       always @(posedge CLK) if (CE) r <= { r[14:0], D }; | ||||||
|   endgenerate |   endgenerate | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
|  | @ -382,7 +422,9 @@ module SRLC32E ( | ||||||
|   output Q, |   output Q, | ||||||
|   output Q31, |   output Q31, | ||||||
|   input [4:0] A, |   input [4:0] A, | ||||||
|   input CE, CLK, D |   (* clkbuf_sink *) | ||||||
|  |   input CLK, | ||||||
|  |   input CE, D | ||||||
| ); | ); | ||||||
|   parameter [31:0] INIT = 32'h00000000; |   parameter [31:0] INIT = 32'h00000000; | ||||||
|   parameter [0:0] IS_CLK_INVERTED = 1'b0; |   parameter [0:0] IS_CLK_INVERTED = 1'b0; | ||||||
|  |  | ||||||
							
								
								
									
										257
									
								
								techlibs/xilinx/cells_xtra.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										257
									
								
								techlibs/xilinx/cells_xtra.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,257 @@ | ||||||
|  | #!/usr/bin/env python3 | ||||||
|  | 
 | ||||||
|  | from argparse import ArgumentParser | ||||||
|  | from io import StringIO | ||||||
|  | from enum import Enum, auto | ||||||
|  | import os.path | ||||||
|  | import sys | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Cell: | ||||||
|  |     def __init__(self, name, keep=False, port_attrs={}): | ||||||
|  |         self.name = name | ||||||
|  |         self.keep = keep | ||||||
|  |         self.port_attrs = port_attrs | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | CELLS = [ | ||||||
|  |     # Design elements types listed in Xilinx UG953 | ||||||
|  |     Cell('BSCANE2', keep=True), | ||||||
|  |     # Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}), | ||||||
|  |     Cell('BUFGCE', port_attrs={'O': ['clkbuf_driver']}), | ||||||
|  |     Cell('BUFGCE_1', port_attrs={'O': ['clkbuf_driver']}), | ||||||
|  |     #Cell('BUFGCTRL', port_attrs={'O': ['clkbuf_driver']}), | ||||||
|  |     Cell('BUFGMUX', port_attrs={'O': ['clkbuf_driver']}), | ||||||
|  |     Cell('BUFGMUX_1', port_attrs={'O': ['clkbuf_driver']}), | ||||||
|  |     Cell('BUFGMUX_CTRL', port_attrs={'O': ['clkbuf_driver']}), | ||||||
|  |     Cell('BUFH', port_attrs={'O': ['clkbuf_driver']}), | ||||||
|  |     #Cell('BUFHCE', port_attrs={'O': ['clkbuf_driver']}), | ||||||
|  |     Cell('BUFIO', port_attrs={'O': ['clkbuf_driver']}), | ||||||
|  |     Cell('BUFMR', port_attrs={'O': ['clkbuf_driver']}), | ||||||
|  |     Cell('BUFMRCE', port_attrs={'O': ['clkbuf_driver']}), | ||||||
|  |     Cell('BUFR', port_attrs={'O': ['clkbuf_driver']}), | ||||||
|  |     Cell('CAPTUREE2', keep=True), | ||||||
|  |     # Cell('CARRY4'), | ||||||
|  |     Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('DCIRESET', keep=True), | ||||||
|  |     Cell('DNA_PORT'), | ||||||
|  |     Cell('DSP48E1', port_attrs={'CLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('EFUSE_USR'), | ||||||
|  |     # Cell('FDCE'), | ||||||
|  |     # Cell('FDPE'), | ||||||
|  |     # Cell('FDRE'), | ||||||
|  |     # Cell('FDSE'), | ||||||
|  |     Cell('FIFO18E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('FIFO36E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('FRAME_ECCE2'), | ||||||
|  |     Cell('GTHE2_CHANNEL'), | ||||||
|  |     Cell('GTHE2_COMMON'), | ||||||
|  |     Cell('GTPE2_CHANNEL'), | ||||||
|  |     Cell('GTPE2_COMMON'), | ||||||
|  |     Cell('GTXE2_CHANNEL'), | ||||||
|  |     Cell('GTXE2_COMMON'), | ||||||
|  |     # Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}), | ||||||
|  |     Cell('IBUF_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin']}), | ||||||
|  |     Cell('IBUF_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin']}), | ||||||
|  |     Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}), | ||||||
|  |     Cell('IBUFDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}), | ||||||
|  |     Cell('IBUFDS_DIFF_OUT_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}), | ||||||
|  |     Cell('IBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}), | ||||||
|  |     Cell('IBUFDS_GTE2', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}), | ||||||
|  |     Cell('IBUFDS_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}), | ||||||
|  |     Cell('IBUFDS_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}), | ||||||
|  |     Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}), | ||||||
|  |     Cell('IBUFGDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}), | ||||||
|  |     Cell('IBUFGDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}), | ||||||
|  |     Cell('ICAPE2', keep=True), | ||||||
|  |     Cell('IDDR', port_attrs={'C': ['clkbuf_sink']}), | ||||||
|  |     Cell('IDDR_2CLK', port_attrs={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}), | ||||||
|  |     Cell('IDELAYCTRL', keep=True, port_attrs={'REFCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('IDELAYE2', port_attrs={'C': ['clkbuf_sink']}), | ||||||
|  |     Cell('IN_FIFO', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('IOBUF', port_attrs={'IO': ['iopad_external_pin']}), | ||||||
|  |     Cell('IOBUF_DCIEN', port_attrs={'IO': ['iopad_external_pin']}), | ||||||
|  |     Cell('IOBUF_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin']}), | ||||||
|  |     Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin']}), | ||||||
|  |     Cell('IOBUFDS_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}), | ||||||
|  |     Cell('IOBUFDS_DIFF_OUT', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}), | ||||||
|  |     Cell('IOBUFDS_DIFF_OUT_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}), | ||||||
|  |     Cell('IOBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}), | ||||||
|  |     Cell('ISERDESE2', port_attrs={ | ||||||
|  |         'CLK': ['clkbuf_sink'], | ||||||
|  |         'CLKB': ['clkbuf_sink'], | ||||||
|  |         'OCLK': ['clkbuf_sink'], | ||||||
|  |         'OCLKB': ['clkbuf_sink'], | ||||||
|  |         'CLKDIV': ['clkbuf_sink'], | ||||||
|  |         'CLKDIVP': ['clkbuf_sink'], | ||||||
|  |     }), | ||||||
|  |     Cell('KEEPER'), | ||||||
|  |     Cell('LDCE'), | ||||||
|  |     Cell('LDPE'), | ||||||
|  |     # Cell('LUT1'), | ||||||
|  |     # Cell('LUT2'), | ||||||
|  |     # Cell('LUT3'), | ||||||
|  |     # Cell('LUT4'), | ||||||
|  |     # Cell('LUT5'), | ||||||
|  |     # Cell('LUT6'), | ||||||
|  |     #Cell('LUT6_2'), | ||||||
|  |     Cell('MMCME2_ADV'), | ||||||
|  |     Cell('MMCME2_BASE'), | ||||||
|  |     # Cell('MUXF7'), | ||||||
|  |     # Cell('MUXF8'), | ||||||
|  |     # Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}), | ||||||
|  |     Cell('OBUFDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}), | ||||||
|  |     Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}), | ||||||
|  |     Cell('OBUFTDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}), | ||||||
|  |     Cell('ODDR', port_attrs={'C': ['clkbuf_sink']}), | ||||||
|  |     Cell('ODELAYE2', port_attrs={'C': ['clkbuf_sink']}), | ||||||
|  |     Cell('OSERDESE2', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}), | ||||||
|  |     Cell('OUT_FIFO', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('PHASER_IN'), | ||||||
|  |     Cell('PHASER_IN_PHY'), | ||||||
|  |     Cell('PHASER_OUT'), | ||||||
|  |     Cell('PHASER_OUT_PHY'), | ||||||
|  |     Cell('PHASER_REF'), | ||||||
|  |     Cell('PHY_CONTROL'), | ||||||
|  |     Cell('PLLE2_ADV'), | ||||||
|  |     Cell('PLLE2_BASE'), | ||||||
|  |     Cell('PS7', keep=True), | ||||||
|  |     Cell('PULLDOWN'), | ||||||
|  |     Cell('PULLUP'), | ||||||
|  |     #Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|  |     #Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|  |     #Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}), | ||||||
|  |     # Cell('RAMB18E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}), | ||||||
|  |     # Cell('RAMB36E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('ROM128X1'), | ||||||
|  |     Cell('ROM256X1'), | ||||||
|  |     Cell('ROM32X1'), | ||||||
|  |     Cell('ROM64X1'), | ||||||
|  |     #Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}), | ||||||
|  |     #Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}), | ||||||
|  |     Cell('STARTUPE2', keep=True), | ||||||
|  |     Cell('USR_ACCESSE2'), | ||||||
|  |     Cell('XADC'), | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | class State(Enum): | ||||||
|  |     OUTSIDE = auto() | ||||||
|  |     IN_MODULE = auto() | ||||||
|  |     IN_OTHER_MODULE = auto() | ||||||
|  |     IN_FUNCTION = auto() | ||||||
|  |     IN_TASK = auto() | ||||||
|  | 
 | ||||||
|  | def xtract_cell_decl(cell, dirs, outf): | ||||||
|  |     for dir in dirs: | ||||||
|  |         fname = os.path.join(dir, cell.name + '.v') | ||||||
|  |         try: | ||||||
|  |             with open(fname) as f: | ||||||
|  |                 state = State.OUTSIDE | ||||||
|  |                 found = False | ||||||
|  |                 # Probably the most horrible Verilog "parser" ever written. | ||||||
|  |                 for l in f: | ||||||
|  |                     l = l.partition('//')[0] | ||||||
|  |                     l = l.strip() | ||||||
|  |                     if l == 'module {}'.format(cell.name) or l.startswith('module {} '.format(cell.name)): | ||||||
|  |                         if found: | ||||||
|  |                             print('Multiple modules in {}.'.format(fname)) | ||||||
|  |                             sys.exit(1) | ||||||
|  |                         elif state != State.OUTSIDE: | ||||||
|  |                             print('Nested modules in {}.'.format(fname)) | ||||||
|  |                             sys.exit(1) | ||||||
|  |                         found = True | ||||||
|  |                         state = State.IN_MODULE | ||||||
|  |                         if cell.keep: | ||||||
|  |                             outf.write('(* keep *)\n') | ||||||
|  |                         outf.write('module {} (...);\n'.format(cell.name)) | ||||||
|  |                     elif l.startswith('module '): | ||||||
|  |                         if state != State.OUTSIDE: | ||||||
|  |                             print('Nested modules in {}.'.format(fname)) | ||||||
|  |                             sys.exit(1) | ||||||
|  |                         state = State.IN_OTHER_MODULE | ||||||
|  |                     elif l.startswith('task '): | ||||||
|  |                         if state == State.IN_MODULE: | ||||||
|  |                             state = State.IN_TASK | ||||||
|  |                     elif l.startswith('function '): | ||||||
|  |                         if state == State.IN_MODULE: | ||||||
|  |                             state = State.IN_FUNCTION | ||||||
|  |                     elif l == 'endtask': | ||||||
|  |                         if state == State.IN_TASK: | ||||||
|  |                             state = State.IN_MODULE | ||||||
|  |                     elif l == 'endfunction': | ||||||
|  |                         if state == State.IN_FUNCTION: | ||||||
|  |                             state = State.IN_MODULE | ||||||
|  |                     elif l == 'endmodule': | ||||||
|  |                         if state == State.IN_MODULE: | ||||||
|  |                             outf.write(l + '\n') | ||||||
|  |                             outf.write('\n') | ||||||
|  |                         elif state != State.IN_OTHER_MODULE: | ||||||
|  |                             print('endmodule in weird place in {}.'.format(cell.name, fname)) | ||||||
|  |                             sys.exit(1) | ||||||
|  |                         state = State.OUTSIDE | ||||||
|  |                     elif l.startswith(('input ', 'output ', 'inout ')) and state == State.IN_MODULE: | ||||||
|  |                         if l.endswith((';', ',')): | ||||||
|  |                             l = l[:-1] | ||||||
|  |                         if ';' in l: | ||||||
|  |                             print('Weird port line in {} [{}].'.format(fname, l)) | ||||||
|  |                             sys.exit(1) | ||||||
|  |                         kind, _, ports = l.partition(' ') | ||||||
|  |                         for port in ports.split(','): | ||||||
|  |                             port = port.strip() | ||||||
|  |                             for attr in cell.port_attrs.get(port, []): | ||||||
|  |                                 outf.write('    (* {} *)\n'.format(attr)) | ||||||
|  |                             outf.write('    {} {};\n'.format(kind, port)) | ||||||
|  |                     elif l.startswith('parameter ') and state == State.IN_MODULE: | ||||||
|  |                         if 'UNPLACED' in l: | ||||||
|  |                             continue | ||||||
|  |                         if l.endswith((';', ',')): | ||||||
|  |                             l = l[:-1] | ||||||
|  |                         while '  ' in l: | ||||||
|  |                             l = l.replace('  ', ' ') | ||||||
|  |                         if ';' in l: | ||||||
|  |                             print('Weird parameter line in {} [{}].'.format(fname, l)) | ||||||
|  |                             sys.exit(1) | ||||||
|  |                         outf.write('    {};\n'.format(l)) | ||||||
|  |                 if state != State.OUTSIDE: | ||||||
|  |                     print('endmodule not found in {}.'.format(fname)) | ||||||
|  |                     sys.exit(1) | ||||||
|  |                 if not found: | ||||||
|  |                     print('Cannot find module {} in {}.'.format(cell.name, fname)) | ||||||
|  |                     sys.exit(1) | ||||||
|  |             return | ||||||
|  |         except FileNotFoundError: | ||||||
|  |             continue | ||||||
|  |     print('Cannot find {}.'.format(cell.name)) | ||||||
|  |     sys.exit(1) | ||||||
|  | 
 | ||||||
|  | if __name__ == '__main__': | ||||||
|  |     parser = ArgumentParser(description='Extract Xilinx blackbox cell definitions from Vivado.') | ||||||
|  |     parser.add_argument('vivado_dir', nargs='?', default='/opt/Xilinx/Vivado/2018.1') | ||||||
|  |     args = parser.parse_args() | ||||||
|  | 
 | ||||||
|  |     dirs = [ | ||||||
|  |         os.path.join(args.vivado_dir, 'data/verilog/src/xeclib'), | ||||||
|  |         os.path.join(args.vivado_dir, 'data/verilog/src/retarget'), | ||||||
|  |     ] | ||||||
|  |     for dir in dirs: | ||||||
|  |         if not os.path.isdir(dir): | ||||||
|  |             print('{} is not a directory'.format(dir)) | ||||||
|  | 
 | ||||||
|  |     out = StringIO() | ||||||
|  |     for cell in CELLS: | ||||||
|  |         xtract_cell_decl(cell, dirs, out) | ||||||
|  | 
 | ||||||
|  |     with open('cells_xtra.v', 'w') as f: | ||||||
|  |         f.write('// Created by cells_xtra.py from Xilinx models\n') | ||||||
|  |         f.write('\n') | ||||||
|  |         f.write(out.getvalue()) | ||||||
|  | @ -1,147 +0,0 @@ | ||||||
| #!/bin/bash |  | ||||||
| 
 |  | ||||||
| set -e |  | ||||||
| libdir="/opt/Xilinx/Vivado/2018.1/data/verilog/src" |  | ||||||
| 
 |  | ||||||
| function xtract_cell_decl() |  | ||||||
| { |  | ||||||
| 	for dir in $libdir/xeclib $libdir/retarget; do |  | ||||||
| 		[ -f $dir/$1.v ] || continue |  | ||||||
| 		[ -z "$2" ] || echo $2 |  | ||||||
| 		egrep '^\s*((end)?module|parameter|input|inout|output|(end)?function|(end)?task)' $dir/$1.v | |  | ||||||
| 			sed -re '/UNPLACED/ d; /^\s*function/,/endfunction/ d; /^\s*task/,/endtask/ d; |  | ||||||
| 			         s,//.*,,; s/#?\(.*/(...);/; s/^(input|output|parameter)/ \1/; |  | ||||||
| 			         s/\s+$//; s/,$/;/; /input|output|parameter/ s/[^;]$/&;/; s/\s+/ /g; |  | ||||||
| 				 s/^ ((end)?module)/\1/; s/^ /    /; /module.*_bb/,/endmodule/ d;' |  | ||||||
| 		echo; return |  | ||||||
| 	done |  | ||||||
| 	echo "Can't find $1." |  | ||||||
| 	exit 1 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| { |  | ||||||
| 	echo "// Created by cells_xtra.sh from Xilinx models" |  | ||||||
| 	echo |  | ||||||
| 
 |  | ||||||
| 	# Design elements types listed in Xilinx UG953 |  | ||||||
| 	xtract_cell_decl BSCANE2 |  | ||||||
| 	# xtract_cell_decl BUFG |  | ||||||
| 	xtract_cell_decl BUFGCE |  | ||||||
| 	xtract_cell_decl BUFGCE_1 |  | ||||||
| 	#xtract_cell_decl BUFGCTRL |  | ||||||
| 	xtract_cell_decl BUFGMUX |  | ||||||
| 	xtract_cell_decl BUFGMUX_1 |  | ||||||
| 	xtract_cell_decl BUFGMUX_CTRL |  | ||||||
| 	xtract_cell_decl BUFH |  | ||||||
| 	#xtract_cell_decl BUFHCE |  | ||||||
| 	xtract_cell_decl BUFIO |  | ||||||
| 	xtract_cell_decl BUFMR |  | ||||||
| 	xtract_cell_decl BUFMRCE |  | ||||||
| 	xtract_cell_decl BUFR |  | ||||||
| 	xtract_cell_decl CAPTUREE2 "(* keep *)" |  | ||||||
| 	# xtract_cell_decl CARRY4 |  | ||||||
| 	xtract_cell_decl CFGLUT5 |  | ||||||
| 	xtract_cell_decl DCIRESET "(* keep *)" |  | ||||||
| 	xtract_cell_decl DNA_PORT |  | ||||||
| 	xtract_cell_decl DSP48E1 |  | ||||||
| 	xtract_cell_decl EFUSE_USR |  | ||||||
| 	# xtract_cell_decl FDCE |  | ||||||
| 	# xtract_cell_decl FDPE |  | ||||||
| 	# xtract_cell_decl FDRE |  | ||||||
| 	# xtract_cell_decl FDSE |  | ||||||
| 	xtract_cell_decl FIFO18E1 |  | ||||||
| 	xtract_cell_decl FIFO36E1 |  | ||||||
| 	xtract_cell_decl FRAME_ECCE2 |  | ||||||
| 	xtract_cell_decl GTHE2_CHANNEL |  | ||||||
| 	xtract_cell_decl GTHE2_COMMON |  | ||||||
| 	xtract_cell_decl GTPE2_CHANNEL |  | ||||||
| 	xtract_cell_decl GTPE2_COMMON |  | ||||||
| 	xtract_cell_decl GTXE2_CHANNEL |  | ||||||
| 	xtract_cell_decl GTXE2_COMMON |  | ||||||
| 	# xtract_cell_decl IBUF |  | ||||||
| 	xtract_cell_decl IBUF_IBUFDISABLE |  | ||||||
| 	xtract_cell_decl IBUF_INTERMDISABLE |  | ||||||
| 	xtract_cell_decl IBUFDS |  | ||||||
| 	xtract_cell_decl IBUFDS_DIFF_OUT |  | ||||||
| 	xtract_cell_decl IBUFDS_DIFF_OUT_IBUFDISABLE |  | ||||||
| 	xtract_cell_decl IBUFDS_DIFF_OUT_INTERMDISABLE |  | ||||||
| 	xtract_cell_decl IBUFDS_GTE2 |  | ||||||
| 	xtract_cell_decl IBUFDS_IBUFDISABLE |  | ||||||
| 	xtract_cell_decl IBUFDS_INTERMDISABLE |  | ||||||
| 	xtract_cell_decl ICAPE2 "(* keep *)" |  | ||||||
| 	xtract_cell_decl IDDR |  | ||||||
| 	xtract_cell_decl IDDR_2CLK |  | ||||||
| 	xtract_cell_decl IDELAYCTRL "(* keep *)" |  | ||||||
| 	xtract_cell_decl IDELAYE2 |  | ||||||
| 	xtract_cell_decl IN_FIFO |  | ||||||
| 	xtract_cell_decl IOBUF |  | ||||||
| 	xtract_cell_decl IOBUF_DCIEN |  | ||||||
| 	xtract_cell_decl IOBUF_INTERMDISABLE |  | ||||||
| 	xtract_cell_decl IOBUFDS |  | ||||||
| 	xtract_cell_decl IOBUFDS_DCIEN |  | ||||||
| 	xtract_cell_decl IOBUFDS_DIFF_OUT |  | ||||||
| 	xtract_cell_decl IOBUFDS_DIFF_OUT_DCIEN |  | ||||||
| 	xtract_cell_decl IOBUFDS_DIFF_OUT_INTERMDISABLE |  | ||||||
| 	xtract_cell_decl ISERDESE2 |  | ||||||
| 	xtract_cell_decl KEEPER |  | ||||||
| 	xtract_cell_decl LDCE |  | ||||||
| 	xtract_cell_decl LDPE |  | ||||||
| 	# xtract_cell_decl LUT1 |  | ||||||
| 	# xtract_cell_decl LUT2 |  | ||||||
| 	# xtract_cell_decl LUT3 |  | ||||||
| 	# xtract_cell_decl LUT4 |  | ||||||
| 	# xtract_cell_decl LUT5 |  | ||||||
| 	# xtract_cell_decl LUT6 |  | ||||||
| 	#xtract_cell_decl LUT6_2 |  | ||||||
| 	xtract_cell_decl MMCME2_ADV |  | ||||||
| 	xtract_cell_decl MMCME2_BASE |  | ||||||
| 	# xtract_cell_decl MUXF7 |  | ||||||
| 	# xtract_cell_decl MUXF8 |  | ||||||
| 	# xtract_cell_decl OBUF |  | ||||||
| 	xtract_cell_decl OBUFDS |  | ||||||
| 	xtract_cell_decl OBUFT |  | ||||||
| 	xtract_cell_decl OBUFTDS |  | ||||||
| 	xtract_cell_decl ODDR |  | ||||||
| 	xtract_cell_decl ODELAYE2 |  | ||||||
| 	xtract_cell_decl OSERDESE2 |  | ||||||
| 	xtract_cell_decl OUT_FIFO |  | ||||||
| 	xtract_cell_decl PHASER_IN |  | ||||||
| 	xtract_cell_decl PHASER_IN_PHY |  | ||||||
| 	xtract_cell_decl PHASER_OUT |  | ||||||
| 	xtract_cell_decl PHASER_OUT_PHY |  | ||||||
| 	xtract_cell_decl PHASER_REF |  | ||||||
| 	xtract_cell_decl PHY_CONTROL |  | ||||||
| 	xtract_cell_decl PLLE2_ADV |  | ||||||
| 	xtract_cell_decl PLLE2_BASE |  | ||||||
| 	xtract_cell_decl PS7 "(* keep *)" |  | ||||||
| 	xtract_cell_decl PULLDOWN |  | ||||||
| 	xtract_cell_decl PULLUP |  | ||||||
| 	#xtract_cell_decl RAM128X1D |  | ||||||
| 	xtract_cell_decl RAM128X1S |  | ||||||
| 	xtract_cell_decl RAM256X1S |  | ||||||
| 	xtract_cell_decl RAM32M |  | ||||||
| 	#xtract_cell_decl RAM32X1D |  | ||||||
| 	xtract_cell_decl RAM32X1S |  | ||||||
| 	xtract_cell_decl RAM32X1S_1 |  | ||||||
| 	xtract_cell_decl RAM32X2S |  | ||||||
| 	xtract_cell_decl RAM64M |  | ||||||
| 	#xtract_cell_decl RAM64X1D |  | ||||||
| 	xtract_cell_decl RAM64X1S |  | ||||||
| 	xtract_cell_decl RAM64X1S_1 |  | ||||||
| 	xtract_cell_decl RAM64X2S |  | ||||||
| 	# xtract_cell_decl RAMB18E1 |  | ||||||
| 	# xtract_cell_decl RAMB36E1 |  | ||||||
| 	xtract_cell_decl ROM128X1 |  | ||||||
| 	xtract_cell_decl ROM256X1 |  | ||||||
| 	xtract_cell_decl ROM32X1 |  | ||||||
| 	xtract_cell_decl ROM64X1 |  | ||||||
| 	#xtract_cell_decl SRL16E |  | ||||||
| 	#xtract_cell_decl SRLC32E |  | ||||||
| 	xtract_cell_decl STARTUPE2 "(* keep *)" |  | ||||||
| 	xtract_cell_decl USR_ACCESSE2 |  | ||||||
| 	xtract_cell_decl XADC |  | ||||||
| } > cells_xtra.new |  | ||||||
| 
 |  | ||||||
| mv cells_xtra.new cells_xtra.v |  | ||||||
| exit 0 |  | ||||||
| 
 |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| // Created by cells_xtra.sh from Xilinx models | // Created by cells_xtra.py from Xilinx models | ||||||
| 
 | 
 | ||||||
|  | (* keep *) | ||||||
| module BSCANE2 (...); | module BSCANE2 (...); | ||||||
|     parameter DISABLE_JTAG = "FALSE"; |     parameter DISABLE_JTAG = "FALSE"; | ||||||
|     parameter integer JTAG_CHAIN = 1; |     parameter integer JTAG_CHAIN = 1; | ||||||
|  | @ -20,29 +21,39 @@ module BUFGCE (...); | ||||||
|     parameter CE_TYPE = "SYNC"; |     parameter CE_TYPE = "SYNC"; | ||||||
|     parameter [0:0] IS_CE_INVERTED = 1'b0; |     parameter [0:0] IS_CE_INVERTED = 1'b0; | ||||||
|     parameter [0:0] IS_I_INVERTED = 1'b0; |     parameter [0:0] IS_I_INVERTED = 1'b0; | ||||||
|  |     (* clkbuf_driver *) | ||||||
|     output O; |     output O; | ||||||
|     input CE; |     input CE; | ||||||
|     input I; |     input I; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module BUFGCE_1 (...); | module BUFGCE_1 (...); | ||||||
|  |     (* clkbuf_driver *) | ||||||
|     output O; |     output O; | ||||||
|     input CE, I; |     input CE; | ||||||
|  |     input I; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module BUFGMUX (...); | module BUFGMUX (...); | ||||||
|     parameter CLK_SEL_TYPE = "SYNC"; |     parameter CLK_SEL_TYPE = "SYNC"; | ||||||
|  |     (* clkbuf_driver *) | ||||||
|     output O; |     output O; | ||||||
|     input I0, I1, S; |     input I0; | ||||||
|  |     input I1; | ||||||
|  |     input S; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module BUFGMUX_1 (...); | module BUFGMUX_1 (...); | ||||||
|     parameter CLK_SEL_TYPE = "SYNC"; |     parameter CLK_SEL_TYPE = "SYNC"; | ||||||
|  |     (* clkbuf_driver *) | ||||||
|     output O; |     output O; | ||||||
|     input I0, I1, S; |     input I0; | ||||||
|  |     input I1; | ||||||
|  |     input S; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module BUFGMUX_CTRL (...); | module BUFGMUX_CTRL (...); | ||||||
|  |     (* clkbuf_driver *) | ||||||
|     output O; |     output O; | ||||||
|     input I0; |     input I0; | ||||||
|     input I1; |     input I1; | ||||||
|  | @ -50,16 +61,19 @@ module BUFGMUX_CTRL (...); | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module BUFH (...); | module BUFH (...); | ||||||
|  |     (* clkbuf_driver *) | ||||||
|     output O; |     output O; | ||||||
|     input I; |     input I; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module BUFIO (...); | module BUFIO (...); | ||||||
|  |     (* clkbuf_driver *) | ||||||
|     output O; |     output O; | ||||||
|     input I; |     input I; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module BUFMR (...); | module BUFMR (...); | ||||||
|  |     (* clkbuf_driver *) | ||||||
|     output O; |     output O; | ||||||
|     input I; |     input I; | ||||||
| endmodule | endmodule | ||||||
|  | @ -68,12 +82,14 @@ module BUFMRCE (...); | ||||||
|     parameter CE_TYPE = "SYNC"; |     parameter CE_TYPE = "SYNC"; | ||||||
|     parameter integer INIT_OUT = 0; |     parameter integer INIT_OUT = 0; | ||||||
|     parameter [0:0] IS_CE_INVERTED = 1'b0; |     parameter [0:0] IS_CE_INVERTED = 1'b0; | ||||||
|  |     (* clkbuf_driver *) | ||||||
|     output O; |     output O; | ||||||
|     input CE; |     input CE; | ||||||
|     input I; |     input I; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module BUFR (...); | module BUFR (...); | ||||||
|  |     (* clkbuf_driver *) | ||||||
|     output O; |     output O; | ||||||
|     input CE; |     input CE; | ||||||
|     input CLR; |     input CLR; | ||||||
|  | @ -95,8 +111,15 @@ module CFGLUT5 (...); | ||||||
|     output CDO; |     output CDO; | ||||||
|     output O5; |     output O5; | ||||||
|     output O6; |     output O6; | ||||||
|     input I4, I3, I2, I1, I0; |     input I4; | ||||||
|     input CDI, CE, CLK; |     input I3; | ||||||
|  |     input I2; | ||||||
|  |     input I1; | ||||||
|  |     input I0; | ||||||
|  |     input CDI; | ||||||
|  |     input CE; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|  |     input CLK; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| (* keep *) | (* keep *) | ||||||
|  | @ -108,7 +131,10 @@ endmodule | ||||||
| module DNA_PORT (...); | module DNA_PORT (...); | ||||||
|     parameter [56:0] SIM_DNA_VALUE = 57'h0; |     parameter [56:0] SIM_DNA_VALUE = 57'h0; | ||||||
|     output DOUT; |     output DOUT; | ||||||
|     input CLK, DIN, READ, SHIFT; |     input CLK; | ||||||
|  |     input DIN; | ||||||
|  |     input READ; | ||||||
|  |     input SHIFT; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module DSP48E1 (...); | module DSP48E1 (...); | ||||||
|  | @ -175,6 +201,7 @@ module DSP48E1 (...); | ||||||
|     input CEINMODE; |     input CEINMODE; | ||||||
|     input CEM; |     input CEM; | ||||||
|     input CEP; |     input CEP; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input CLK; |     input CLK; | ||||||
|     input [24:0] D; |     input [24:0] D; | ||||||
|     input [4:0] INMODE; |     input [4:0] INMODE; | ||||||
|  | @ -227,11 +254,13 @@ module FIFO18E1 (...); | ||||||
|     output WRERR; |     output WRERR; | ||||||
|     input [31:0] DI; |     input [31:0] DI; | ||||||
|     input [3:0] DIP; |     input [3:0] DIP; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input RDCLK; |     input RDCLK; | ||||||
|     input RDEN; |     input RDEN; | ||||||
|     input REGCE; |     input REGCE; | ||||||
|     input RST; |     input RST; | ||||||
|     input RSTREG; |     input RSTREG; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input WRCLK; |     input WRCLK; | ||||||
|     input WREN; |     input WREN; | ||||||
| endmodule | endmodule | ||||||
|  | @ -272,11 +301,13 @@ module FIFO36E1 (...); | ||||||
|     input [7:0] DIP; |     input [7:0] DIP; | ||||||
|     input INJECTDBITERR; |     input INJECTDBITERR; | ||||||
|     input INJECTSBITERR; |     input INJECTSBITERR; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input RDCLK; |     input RDCLK; | ||||||
|     input RDEN; |     input RDEN; | ||||||
|     input REGCE; |     input REGCE; | ||||||
|     input RST; |     input RST; | ||||||
|     input RSTREG; |     input RSTREG; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input WRCLK; |     input WRCLK; | ||||||
|     input WREN; |     input WREN; | ||||||
| endmodule | endmodule | ||||||
|  | @ -1969,6 +2000,7 @@ module IBUF_IBUFDISABLE (...); | ||||||
|     parameter SIM_DEVICE = "7SERIES"; |     parameter SIM_DEVICE = "7SERIES"; | ||||||
|     parameter USE_IBUFDISABLE = "TRUE"; |     parameter USE_IBUFDISABLE = "TRUE"; | ||||||
|     output O; |     output O; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     input I; |     input I; | ||||||
|     input IBUFDISABLE; |     input IBUFDISABLE; | ||||||
| endmodule | endmodule | ||||||
|  | @ -1979,6 +2011,7 @@ module IBUF_INTERMDISABLE (...); | ||||||
|     parameter SIM_DEVICE = "7SERIES"; |     parameter SIM_DEVICE = "7SERIES"; | ||||||
|     parameter USE_IBUFDISABLE = "TRUE"; |     parameter USE_IBUFDISABLE = "TRUE"; | ||||||
|     output O; |     output O; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     input I; |     input I; | ||||||
|     input IBUFDISABLE; |     input IBUFDISABLE; | ||||||
|     input INTERMDISABLE; |     input INTERMDISABLE; | ||||||
|  | @ -1993,7 +2026,10 @@ module IBUFDS (...); | ||||||
|     parameter IFD_DELAY_VALUE = "AUTO"; |     parameter IFD_DELAY_VALUE = "AUTO"; | ||||||
|     parameter IOSTANDARD = "DEFAULT"; |     parameter IOSTANDARD = "DEFAULT"; | ||||||
|     output O; |     output O; | ||||||
|     input I, IB; |     (* iopad_external_pin *) | ||||||
|  |     input I; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|  |     input IB; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module IBUFDS_DIFF_OUT (...); | module IBUFDS_DIFF_OUT (...); | ||||||
|  | @ -2001,8 +2037,12 @@ module IBUFDS_DIFF_OUT (...); | ||||||
|     parameter DQS_BIAS = "FALSE"; |     parameter DQS_BIAS = "FALSE"; | ||||||
|     parameter IBUF_LOW_PWR = "TRUE"; |     parameter IBUF_LOW_PWR = "TRUE"; | ||||||
|     parameter IOSTANDARD = "DEFAULT"; |     parameter IOSTANDARD = "DEFAULT"; | ||||||
|     output O, OB; |     output O; | ||||||
|     input I, IB; |     output OB; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|  |     input I; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|  |     input IB; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module IBUFDS_DIFF_OUT_IBUFDISABLE (...); | module IBUFDS_DIFF_OUT_IBUFDISABLE (...); | ||||||
|  | @ -2014,7 +2054,9 @@ module IBUFDS_DIFF_OUT_IBUFDISABLE (...); | ||||||
|     parameter USE_IBUFDISABLE = "TRUE"; |     parameter USE_IBUFDISABLE = "TRUE"; | ||||||
|     output O; |     output O; | ||||||
|     output OB; |     output OB; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     input I; |     input I; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     input IB; |     input IB; | ||||||
|     input IBUFDISABLE; |     input IBUFDISABLE; | ||||||
| endmodule | endmodule | ||||||
|  | @ -2028,7 +2070,9 @@ module IBUFDS_DIFF_OUT_INTERMDISABLE (...); | ||||||
|     parameter USE_IBUFDISABLE = "TRUE"; |     parameter USE_IBUFDISABLE = "TRUE"; | ||||||
|     output O; |     output O; | ||||||
|     output OB; |     output OB; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     input I; |     input I; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     input IB; |     input IB; | ||||||
|     input IBUFDISABLE; |     input IBUFDISABLE; | ||||||
|     input INTERMDISABLE; |     input INTERMDISABLE; | ||||||
|  | @ -2041,7 +2085,9 @@ module IBUFDS_GTE2 (...); | ||||||
|     output O; |     output O; | ||||||
|     output ODIV2; |     output ODIV2; | ||||||
|     input CEB; |     input CEB; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     input I; |     input I; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     input IB; |     input IB; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
|  | @ -2053,7 +2099,9 @@ module IBUFDS_IBUFDISABLE (...); | ||||||
|     parameter SIM_DEVICE = "7SERIES"; |     parameter SIM_DEVICE = "7SERIES"; | ||||||
|     parameter USE_IBUFDISABLE = "TRUE"; |     parameter USE_IBUFDISABLE = "TRUE"; | ||||||
|     output O; |     output O; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     input I; |     input I; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     input IB; |     input IB; | ||||||
|     input IBUFDISABLE; |     input IBUFDISABLE; | ||||||
| endmodule | endmodule | ||||||
|  | @ -2066,12 +2114,50 @@ module IBUFDS_INTERMDISABLE (...); | ||||||
|     parameter SIM_DEVICE = "7SERIES"; |     parameter SIM_DEVICE = "7SERIES"; | ||||||
|     parameter USE_IBUFDISABLE = "TRUE"; |     parameter USE_IBUFDISABLE = "TRUE"; | ||||||
|     output O; |     output O; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     input I; |     input I; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     input IB; |     input IB; | ||||||
|     input IBUFDISABLE; |     input IBUFDISABLE; | ||||||
|     input INTERMDISABLE; |     input INTERMDISABLE; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
|  | module IBUFG (...); | ||||||
|  |     parameter CAPACITANCE = "DONT_CARE"; | ||||||
|  |     parameter IBUF_DELAY_VALUE = "0"; | ||||||
|  |     parameter IBUF_LOW_PWR = "TRUE"; | ||||||
|  |     parameter IOSTANDARD = "DEFAULT"; | ||||||
|  |     output O; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|  |     input I; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module IBUFGDS (...); | ||||||
|  |     parameter CAPACITANCE = "DONT_CARE"; | ||||||
|  |     parameter DIFF_TERM = "FALSE"; | ||||||
|  |     parameter IBUF_DELAY_VALUE = "0"; | ||||||
|  |     parameter IBUF_LOW_PWR = "TRUE"; | ||||||
|  |     parameter IOSTANDARD = "DEFAULT"; | ||||||
|  |     output O; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|  |     input I; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|  |     input IB; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module IBUFGDS_DIFF_OUT (...); | ||||||
|  |     parameter DIFF_TERM = "FALSE"; | ||||||
|  |     parameter DQS_BIAS = "FALSE"; | ||||||
|  |     parameter IBUF_LOW_PWR = "TRUE"; | ||||||
|  |     parameter IOSTANDARD = "DEFAULT"; | ||||||
|  |     output O; | ||||||
|  |     output OB; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|  |     input I; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|  |     input IB; | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
| (* keep *) | (* keep *) | ||||||
| module ICAPE2 (...); | module ICAPE2 (...); | ||||||
|     parameter [31:0] DEVICE_ID = 32'h04244093; |     parameter [31:0] DEVICE_ID = 32'h04244093; | ||||||
|  | @ -2095,6 +2181,7 @@ module IDDR (...); | ||||||
|     parameter XON = "TRUE"; |     parameter XON = "TRUE"; | ||||||
|     output Q1; |     output Q1; | ||||||
|     output Q2; |     output Q2; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input C; |     input C; | ||||||
|     input CE; |     input CE; | ||||||
|     input D; |     input D; | ||||||
|  | @ -2112,7 +2199,9 @@ module IDDR_2CLK (...); | ||||||
|     parameter SRTYPE = "SYNC"; |     parameter SRTYPE = "SYNC"; | ||||||
|     output Q1; |     output Q1; | ||||||
|     output Q2; |     output Q2; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input C; |     input C; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input CB; |     input CB; | ||||||
|     input CE; |     input CE; | ||||||
|     input D; |     input D; | ||||||
|  | @ -2124,6 +2213,7 @@ endmodule | ||||||
| module IDELAYCTRL (...); | module IDELAYCTRL (...); | ||||||
|     parameter SIM_DEVICE = "7SERIES"; |     parameter SIM_DEVICE = "7SERIES"; | ||||||
|     output RDY; |     output RDY; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input REFCLK; |     input REFCLK; | ||||||
|     input RST; |     input RST; | ||||||
| endmodule | endmodule | ||||||
|  | @ -2143,6 +2233,7 @@ module IDELAYE2 (...); | ||||||
|     parameter integer SIM_DELAY_D = 0; |     parameter integer SIM_DELAY_D = 0; | ||||||
|     output [4:0] CNTVALUEOUT; |     output [4:0] CNTVALUEOUT; | ||||||
|     output DATAOUT; |     output DATAOUT; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input C; |     input C; | ||||||
|     input CE; |     input CE; | ||||||
|     input CINVCTRL; |     input CINVCTRL; | ||||||
|  | @ -2174,9 +2265,11 @@ module IN_FIFO (...); | ||||||
|     output [7:0] Q7; |     output [7:0] Q7; | ||||||
|     output [7:0] Q8; |     output [7:0] Q8; | ||||||
|     output [7:0] Q9; |     output [7:0] Q9; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input RDCLK; |     input RDCLK; | ||||||
|     input RDEN; |     input RDEN; | ||||||
|     input RESET; |     input RESET; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input WRCLK; |     input WRCLK; | ||||||
|     input WREN; |     input WREN; | ||||||
|     input [3:0] D0; |     input [3:0] D0; | ||||||
|  | @ -2197,8 +2290,10 @@ module IOBUF (...); | ||||||
|     parameter IOSTANDARD = "DEFAULT"; |     parameter IOSTANDARD = "DEFAULT"; | ||||||
|     parameter SLEW = "SLOW"; |     parameter SLEW = "SLOW"; | ||||||
|     output O; |     output O; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     inout IO; |     inout IO; | ||||||
|     input I, T; |     input I; | ||||||
|  |     input T; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module IOBUF_DCIEN (...); | module IOBUF_DCIEN (...); | ||||||
|  | @ -2209,6 +2304,7 @@ module IOBUF_DCIEN (...); | ||||||
|     parameter SLEW = "SLOW"; |     parameter SLEW = "SLOW"; | ||||||
|     parameter USE_IBUFDISABLE = "TRUE"; |     parameter USE_IBUFDISABLE = "TRUE"; | ||||||
|     output O; |     output O; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     inout IO; |     inout IO; | ||||||
|     input DCITERMDISABLE; |     input DCITERMDISABLE; | ||||||
|     input I; |     input I; | ||||||
|  | @ -2224,6 +2320,7 @@ module IOBUF_INTERMDISABLE (...); | ||||||
|     parameter SLEW = "SLOW"; |     parameter SLEW = "SLOW"; | ||||||
|     parameter USE_IBUFDISABLE = "TRUE"; |     parameter USE_IBUFDISABLE = "TRUE"; | ||||||
|     output O; |     output O; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     inout IO; |     inout IO; | ||||||
|     input I; |     input I; | ||||||
|     input IBUFDISABLE; |     input IBUFDISABLE; | ||||||
|  | @ -2238,8 +2335,11 @@ module IOBUFDS (...); | ||||||
|     parameter IOSTANDARD = "DEFAULT"; |     parameter IOSTANDARD = "DEFAULT"; | ||||||
|     parameter SLEW = "SLOW"; |     parameter SLEW = "SLOW"; | ||||||
|     output O; |     output O; | ||||||
|     inout IO, IOB; |     (* iopad_external_pin *) | ||||||
|     input I, T; |     inout IO; | ||||||
|  |     inout IOB; | ||||||
|  |     input I; | ||||||
|  |     input T; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module IOBUFDS_DCIEN (...); | module IOBUFDS_DCIEN (...); | ||||||
|  | @ -2251,7 +2351,9 @@ module IOBUFDS_DCIEN (...); | ||||||
|     parameter SLEW = "SLOW"; |     parameter SLEW = "SLOW"; | ||||||
|     parameter USE_IBUFDISABLE = "TRUE"; |     parameter USE_IBUFDISABLE = "TRUE"; | ||||||
|     output O; |     output O; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     inout IO; |     inout IO; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     inout IOB; |     inout IOB; | ||||||
|     input DCITERMDISABLE; |     input DCITERMDISABLE; | ||||||
|     input I; |     input I; | ||||||
|  | @ -2266,7 +2368,9 @@ module IOBUFDS_DIFF_OUT (...); | ||||||
|     parameter IOSTANDARD = "DEFAULT"; |     parameter IOSTANDARD = "DEFAULT"; | ||||||
|     output O; |     output O; | ||||||
|     output OB; |     output OB; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     inout IO; |     inout IO; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     inout IOB; |     inout IOB; | ||||||
|     input I; |     input I; | ||||||
|     input TM; |     input TM; | ||||||
|  | @ -2282,7 +2386,9 @@ module IOBUFDS_DIFF_OUT_DCIEN (...); | ||||||
|     parameter USE_IBUFDISABLE = "TRUE"; |     parameter USE_IBUFDISABLE = "TRUE"; | ||||||
|     output O; |     output O; | ||||||
|     output OB; |     output OB; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     inout IO; |     inout IO; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     inout IOB; |     inout IOB; | ||||||
|     input DCITERMDISABLE; |     input DCITERMDISABLE; | ||||||
|     input I; |     input I; | ||||||
|  | @ -2300,7 +2406,9 @@ module IOBUFDS_DIFF_OUT_INTERMDISABLE (...); | ||||||
|     parameter USE_IBUFDISABLE = "TRUE"; |     parameter USE_IBUFDISABLE = "TRUE"; | ||||||
|     output O; |     output O; | ||||||
|     output OB; |     output OB; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     inout IO; |     inout IO; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     inout IOB; |     inout IOB; | ||||||
|     input I; |     input I; | ||||||
|     input IBUFDISABLE; |     input IBUFDISABLE; | ||||||
|  | @ -2348,15 +2456,21 @@ module ISERDESE2 (...); | ||||||
|     input BITSLIP; |     input BITSLIP; | ||||||
|     input CE1; |     input CE1; | ||||||
|     input CE2; |     input CE2; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input CLK; |     input CLK; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input CLKB; |     input CLKB; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input CLKDIV; |     input CLKDIV; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input CLKDIVP; |     input CLKDIVP; | ||||||
|     input D; |     input D; | ||||||
|     input DDLY; |     input DDLY; | ||||||
|     input DYNCLKDIVSEL; |     input DYNCLKDIVSEL; | ||||||
|     input DYNCLKSEL; |     input DYNCLKSEL; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input OCLK; |     input OCLK; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input OCLKB; |     input OCLKB; | ||||||
|     input OFB; |     input OFB; | ||||||
|     input RST; |     input RST; | ||||||
|  | @ -2375,7 +2489,10 @@ module LDCE (...); | ||||||
|     parameter MSGON = "TRUE"; |     parameter MSGON = "TRUE"; | ||||||
|     parameter XON = "TRUE"; |     parameter XON = "TRUE"; | ||||||
|     output Q; |     output Q; | ||||||
|     input CLR, D, G, GE; |     input CLR; | ||||||
|  |     input D; | ||||||
|  |     input G; | ||||||
|  |     input GE; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module LDPE (...); | module LDPE (...); | ||||||
|  | @ -2385,7 +2502,10 @@ module LDPE (...); | ||||||
|     parameter MSGON = "TRUE"; |     parameter MSGON = "TRUE"; | ||||||
|     parameter XON = "TRUE"; |     parameter XON = "TRUE"; | ||||||
|     output Q; |     output Q; | ||||||
|     input D, G, GE, PRE; |     input D; | ||||||
|  |     input G; | ||||||
|  |     input GE; | ||||||
|  |     input PRE; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module MMCME2_ADV (...); | module MMCME2_ADV (...); | ||||||
|  | @ -2533,7 +2653,10 @@ module OBUFDS (...); | ||||||
|     parameter CAPACITANCE = "DONT_CARE"; |     parameter CAPACITANCE = "DONT_CARE"; | ||||||
|     parameter IOSTANDARD = "DEFAULT"; |     parameter IOSTANDARD = "DEFAULT"; | ||||||
|     parameter SLEW = "SLOW"; |     parameter SLEW = "SLOW"; | ||||||
|     output O, OB; |     (* iopad_external_pin *) | ||||||
|  |     output O; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|  |     output OB; | ||||||
|     input I; |     input I; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
|  | @ -2542,20 +2665,27 @@ module OBUFT (...); | ||||||
|     parameter integer DRIVE = 12; |     parameter integer DRIVE = 12; | ||||||
|     parameter IOSTANDARD = "DEFAULT"; |     parameter IOSTANDARD = "DEFAULT"; | ||||||
|     parameter SLEW = "SLOW"; |     parameter SLEW = "SLOW"; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|     output O; |     output O; | ||||||
|     input I, T; |     input I; | ||||||
|  |     input T; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module OBUFTDS (...); | module OBUFTDS (...); | ||||||
|     parameter CAPACITANCE = "DONT_CARE"; |     parameter CAPACITANCE = "DONT_CARE"; | ||||||
|     parameter IOSTANDARD = "DEFAULT"; |     parameter IOSTANDARD = "DEFAULT"; | ||||||
|     parameter SLEW = "SLOW"; |     parameter SLEW = "SLOW"; | ||||||
|     output O, OB; |     (* iopad_external_pin *) | ||||||
|     input I, T; |     output O; | ||||||
|  |     (* iopad_external_pin *) | ||||||
|  |     output OB; | ||||||
|  |     input I; | ||||||
|  |     input T; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module ODDR (...); | module ODDR (...); | ||||||
|     output Q; |     output Q; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input C; |     input C; | ||||||
|     input CE; |     input CE; | ||||||
|     input D1; |     input D1; | ||||||
|  | @ -2586,6 +2716,7 @@ module ODELAYE2 (...); | ||||||
|     parameter integer SIM_DELAY_D = 0; |     parameter integer SIM_DELAY_D = 0; | ||||||
|     output [4:0] CNTVALUEOUT; |     output [4:0] CNTVALUEOUT; | ||||||
|     output DATAOUT; |     output DATAOUT; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input C; |     input C; | ||||||
|     input CE; |     input CE; | ||||||
|     input CINVCTRL; |     input CINVCTRL; | ||||||
|  | @ -2631,7 +2762,9 @@ module OSERDESE2 (...); | ||||||
|     output TBYTEOUT; |     output TBYTEOUT; | ||||||
|     output TFB; |     output TFB; | ||||||
|     output TQ; |     output TQ; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input CLK; |     input CLK; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input CLKDIV; |     input CLKDIV; | ||||||
|     input D1; |     input D1; | ||||||
|     input D2; |     input D2; | ||||||
|  | @ -2673,9 +2806,11 @@ module OUT_FIFO (...); | ||||||
|     output [3:0] Q9; |     output [3:0] Q9; | ||||||
|     output [7:0] Q5; |     output [7:0] Q5; | ||||||
|     output [7:0] Q6; |     output [7:0] Q6; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input RDCLK; |     input RDCLK; | ||||||
|     input RDEN; |     input RDEN; | ||||||
|     input RESET; |     input RESET; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input WRCLK; |     input WRCLK; | ||||||
|     input WREN; |     input WREN; | ||||||
|     input [7:0] D0; |     input [7:0] D0; | ||||||
|  | @ -3659,7 +3794,17 @@ module RAM128X1S (...); | ||||||
|     parameter [127:0] INIT = 128'h00000000000000000000000000000000; |     parameter [127:0] INIT = 128'h00000000000000000000000000000000; | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |     parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|     output O; |     output O; | ||||||
|     input A0, A1, A2, A3, A4, A5, A6, D, WCLK, WE; |     input A0; | ||||||
|  |     input A1; | ||||||
|  |     input A2; | ||||||
|  |     input A3; | ||||||
|  |     input A4; | ||||||
|  |     input A5; | ||||||
|  |     input A6; | ||||||
|  |     input D; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|  |     input WCLK; | ||||||
|  |     input WE; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAM256X1S (...); | module RAM256X1S (...); | ||||||
|  | @ -3668,6 +3813,7 @@ module RAM256X1S (...); | ||||||
|     output O; |     output O; | ||||||
|     input [7:0] A; |     input [7:0] A; | ||||||
|     input D; |     input D; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input WCLK; |     input WCLK; | ||||||
|     input WE; |     input WE; | ||||||
| endmodule | endmodule | ||||||
|  | @ -3690,6 +3836,7 @@ module RAM32M (...); | ||||||
|     input [1:0] DIB; |     input [1:0] DIB; | ||||||
|     input [1:0] DIC; |     input [1:0] DIC; | ||||||
|     input [1:0] DID; |     input [1:0] DID; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input WCLK; |     input WCLK; | ||||||
|     input WE; |     input WE; | ||||||
| endmodule | endmodule | ||||||
|  | @ -3698,22 +3845,48 @@ module RAM32X1S (...); | ||||||
|     parameter [31:0] INIT = 32'h00000000; |     parameter [31:0] INIT = 32'h00000000; | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |     parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|     output O; |     output O; | ||||||
|     input A0, A1, A2, A3, A4, D, WCLK, WE; |     input A0; | ||||||
|  |     input A1; | ||||||
|  |     input A2; | ||||||
|  |     input A3; | ||||||
|  |     input A4; | ||||||
|  |     input D; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|  |     input WCLK; | ||||||
|  |     input WE; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAM32X1S_1 (...); | module RAM32X1S_1 (...); | ||||||
|     parameter [31:0] INIT = 32'h00000000; |     parameter [31:0] INIT = 32'h00000000; | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |     parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|     output O; |     output O; | ||||||
|     input A0, A1, A2, A3, A4, D, WCLK, WE; |     input A0; | ||||||
|  |     input A1; | ||||||
|  |     input A2; | ||||||
|  |     input A3; | ||||||
|  |     input A4; | ||||||
|  |     input D; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|  |     input WCLK; | ||||||
|  |     input WE; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAM32X2S (...); | module RAM32X2S (...); | ||||||
|     parameter [31:0] INIT_00 = 32'h00000000; |     parameter [31:0] INIT_00 = 32'h00000000; | ||||||
|     parameter [31:0] INIT_01 = 32'h00000000; |     parameter [31:0] INIT_01 = 32'h00000000; | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |     parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|     output O0, O1; |     output O0; | ||||||
|     input A0, A1, A2, A3, A4, D0, D1, WCLK, WE; |     output O1; | ||||||
|  |     input A0; | ||||||
|  |     input A1; | ||||||
|  |     input A2; | ||||||
|  |     input A3; | ||||||
|  |     input A4; | ||||||
|  |     input D0; | ||||||
|  |     input D1; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|  |     input WCLK; | ||||||
|  |     input WE; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAM64M (...); | module RAM64M (...); | ||||||
|  | @ -3734,6 +3907,7 @@ module RAM64M (...); | ||||||
|     input DIB; |     input DIB; | ||||||
|     input DIC; |     input DIC; | ||||||
|     input DID; |     input DID; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|     input WCLK; |     input WCLK; | ||||||
|     input WE; |     input WE; | ||||||
| endmodule | endmodule | ||||||
|  | @ -3742,46 +3916,97 @@ module RAM64X1S (...); | ||||||
|     parameter [63:0] INIT = 64'h0000000000000000; |     parameter [63:0] INIT = 64'h0000000000000000; | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |     parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|     output O; |     output O; | ||||||
|     input A0, A1, A2, A3, A4, A5, D, WCLK, WE; |     input A0; | ||||||
|  |     input A1; | ||||||
|  |     input A2; | ||||||
|  |     input A3; | ||||||
|  |     input A4; | ||||||
|  |     input A5; | ||||||
|  |     input D; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|  |     input WCLK; | ||||||
|  |     input WE; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAM64X1S_1 (...); | module RAM64X1S_1 (...); | ||||||
|     parameter [63:0] INIT = 64'h0000000000000000; |     parameter [63:0] INIT = 64'h0000000000000000; | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |     parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|     output O; |     output O; | ||||||
|     input A0, A1, A2, A3, A4, A5, D, WCLK, WE; |     input A0; | ||||||
|  |     input A1; | ||||||
|  |     input A2; | ||||||
|  |     input A3; | ||||||
|  |     input A4; | ||||||
|  |     input A5; | ||||||
|  |     input D; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|  |     input WCLK; | ||||||
|  |     input WE; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAM64X2S (...); | module RAM64X2S (...); | ||||||
|     parameter [63:0] INIT_00 = 64'h0000000000000000; |     parameter [63:0] INIT_00 = 64'h0000000000000000; | ||||||
|     parameter [63:0] INIT_01 = 64'h0000000000000000; |     parameter [63:0] INIT_01 = 64'h0000000000000000; | ||||||
|     parameter [0:0] IS_WCLK_INVERTED = 1'b0; |     parameter [0:0] IS_WCLK_INVERTED = 1'b0; | ||||||
|     output O0, O1; |     output O0; | ||||||
|     input A0, A1, A2, A3, A4, A5, D0, D1, WCLK, WE; |     output O1; | ||||||
|  |     input A0; | ||||||
|  |     input A1; | ||||||
|  |     input A2; | ||||||
|  |     input A3; | ||||||
|  |     input A4; | ||||||
|  |     input A5; | ||||||
|  |     input D0; | ||||||
|  |     input D1; | ||||||
|  |     (* clkbuf_sink *) | ||||||
|  |     input WCLK; | ||||||
|  |     input WE; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module ROM128X1 (...); | module ROM128X1 (...); | ||||||
|     parameter [127:0] INIT = 128'h00000000000000000000000000000000; |     parameter [127:0] INIT = 128'h00000000000000000000000000000000; | ||||||
|     output O; |     output O; | ||||||
|     input A0, A1, A2, A3, A4, A5, A6; |     input A0; | ||||||
|  |     input A1; | ||||||
|  |     input A2; | ||||||
|  |     input A3; | ||||||
|  |     input A4; | ||||||
|  |     input A5; | ||||||
|  |     input A6; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module ROM256X1 (...); | module ROM256X1 (...); | ||||||
|     parameter [255:0] INIT = 256'h0000000000000000000000000000000000000000000000000000000000000000; |     parameter [255:0] INIT = 256'h0000000000000000000000000000000000000000000000000000000000000000; | ||||||
|     output O; |     output O; | ||||||
|     input A0, A1, A2, A3, A4, A5, A6, A7; |     input A0; | ||||||
|  |     input A1; | ||||||
|  |     input A2; | ||||||
|  |     input A3; | ||||||
|  |     input A4; | ||||||
|  |     input A5; | ||||||
|  |     input A6; | ||||||
|  |     input A7; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module ROM32X1 (...); | module ROM32X1 (...); | ||||||
|     parameter [31:0] INIT = 32'h00000000; |     parameter [31:0] INIT = 32'h00000000; | ||||||
|     output O; |     output O; | ||||||
|     input A0, A1, A2, A3, A4; |     input A0; | ||||||
|  |     input A1; | ||||||
|  |     input A2; | ||||||
|  |     input A3; | ||||||
|  |     input A4; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module ROM64X1 (...); | module ROM64X1 (...); | ||||||
|     parameter [63:0] INIT = 64'h0000000000000000; |     parameter [63:0] INIT = 64'h0000000000000000; | ||||||
|     output O; |     output O; | ||||||
|     input A0, A1, A2, A3, A4, A5; |     input A0; | ||||||
|  |     input A1; | ||||||
|  |     input A2; | ||||||
|  |     input A3; | ||||||
|  |     input A4; | ||||||
|  |     input A5; | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| (* keep *) | (* keep *) | ||||||
|  |  | ||||||
|  | @ -63,6 +63,9 @@ struct SynthXilinxPass : public ScriptPass | ||||||
| 		log("        generate an output netlist (and BLIF file) suitable for VPR\n"); | 		log("        generate an output netlist (and BLIF file) suitable for VPR\n"); | ||||||
| 		log("        (this feature is experimental and incomplete)\n"); | 		log("        (this feature is experimental and incomplete)\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | 		log("    -ise\n"); | ||||||
|  | 		log("        generate an output netlist suitable for ISE (enables -iopad)\n"); | ||||||
|  | 		log("\n"); | ||||||
| 		log("    -nobram\n"); | 		log("    -nobram\n"); | ||||||
| 		log("        do not use block RAM cells in output netlist\n"); | 		log("        do not use block RAM cells in output netlist\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | @ -78,6 +81,15 @@ struct SynthXilinxPass : public ScriptPass | ||||||
| 		log("    -nowidelut\n"); | 		log("    -nowidelut\n"); | ||||||
| 		log("        do not use MUXF[78] resources to implement LUTs larger than LUT6s\n"); | 		log("        do not use MUXF[78] resources to implement LUTs larger than LUT6s\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
|  | 		log("    -iopad\n"); | ||||||
|  | 		log("        enable I/O buffer insertion (selected automatically by -ise)\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("    -noiopad\n"); | ||||||
|  | 		log("        disable I/O buffer insertion (only useful with -ise)\n"); | ||||||
|  | 		log("\n"); | ||||||
|  | 		log("    -noclkbuf\n"); | ||||||
|  | 		log("        disable automatic clock buffer insertion\n"); | ||||||
|  | 		log("\n"); | ||||||
| 		log("    -widemux <int>\n"); | 		log("    -widemux <int>\n"); | ||||||
| 		log("        enable inference of hard multiplexer resources (MUXF[78]) for muxes at or\n"); | 		log("        enable inference of hard multiplexer resources (MUXF[78]) for muxes at or\n"); | ||||||
| 		log("        above this number of inputs (minimum value 2, recommended value >= 5).\n"); | 		log("        above this number of inputs (minimum value 2, recommended value >= 5).\n"); | ||||||
|  | @ -104,7 +116,7 @@ struct SynthXilinxPass : public ScriptPass | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	std::string top_opt, edif_file, blif_file, family; | 	std::string top_opt, edif_file, blif_file, family; | ||||||
| 	bool flatten, retime, vpr, nobram, nolutram, nosrl, nocarry, nowidelut, abc9; | 	bool flatten, retime, vpr, ise, iopad, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, abc9; | ||||||
| 	bool flatten_before_abc; | 	bool flatten_before_abc; | ||||||
| 	int widemux; | 	int widemux; | ||||||
| 
 | 
 | ||||||
|  | @ -117,6 +129,10 @@ struct SynthXilinxPass : public ScriptPass | ||||||
| 		flatten = false; | 		flatten = false; | ||||||
| 		retime = false; | 		retime = false; | ||||||
| 		vpr = false; | 		vpr = false; | ||||||
|  | 		ise = false; | ||||||
|  | 		iopad = false; | ||||||
|  | 		noiopad = false; | ||||||
|  | 		noclkbuf = false; | ||||||
| 		nocarry = false; | 		nocarry = false; | ||||||
| 		nobram = false; | 		nobram = false; | ||||||
| 		nolutram = false; | 		nolutram = false; | ||||||
|  | @ -184,6 +200,22 @@ struct SynthXilinxPass : public ScriptPass | ||||||
| 				vpr = true; | 				vpr = true; | ||||||
| 				continue; | 				continue; | ||||||
| 			} | 			} | ||||||
|  | 			if (args[argidx] == "-ise") { | ||||||
|  | 				ise = true; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			if (args[argidx] == "-iopad") { | ||||||
|  | 				iopad = true; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			if (args[argidx] == "-noiopad") { | ||||||
|  | 				noiopad = true; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			if (args[argidx] == "-noclkbuf") { | ||||||
|  | 				noclkbuf = true; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
| 			if (args[argidx] == "-nocarry") { | 			if (args[argidx] == "-nocarry") { | ||||||
| 				nocarry = true; | 				nocarry = true; | ||||||
| 				continue; | 				continue; | ||||||
|  | @ -430,6 +462,18 @@ struct SynthXilinxPass : public ScriptPass | ||||||
| 			run("clean"); | 			run("clean"); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | 		if (check_label("finalize")) { | ||||||
|  | 			bool do_iopad = iopad || (ise && !noiopad); | ||||||
|  | 			if (help_mode || !noclkbuf) { | ||||||
|  | 				if (help_mode || do_iopad) | ||||||
|  | 					run("clkbufmap -buf BUFG O:I -inpad IBUFG O:I", "(skip if '-noclkbuf', '-inpad' passed if '-iopad' or '-ise' and not '-noiopad')"); | ||||||
|  | 				else | ||||||
|  | 					run("clkbufmap -buf BUFG O:I"); | ||||||
|  | 			} | ||||||
|  | 			if (do_iopad) | ||||||
|  | 				run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I A:top", "(only if '-iopad' or '-ise' and not '-noiopad')"); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 		if (check_label("check")) { | 		if (check_label("check")) { | ||||||
| 			run("hierarchy -check"); | 			run("hierarchy -check"); | ||||||
| 			run("stat -tech xilinx"); | 			run("stat -tech xilinx"); | ||||||
|  |  | ||||||
|  | @ -1,5 +1,7 @@ | ||||||
| module RAMB8BWER ( | module RAMB8BWER ( | ||||||
|  | 	(* clkbuf_sink *) | ||||||
| 	input CLKAWRCLK, | 	input CLKAWRCLK, | ||||||
|  | 	(* clkbuf_sink *) | ||||||
| 	input CLKBRDCLK, | 	input CLKBRDCLK, | ||||||
| 	input ENAWREN, | 	input ENAWREN, | ||||||
| 	input ENBRDEN, | 	input ENBRDEN, | ||||||
|  | @ -87,7 +89,9 @@ module RAMB8BWER ( | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAMB16BWER ( | module RAMB16BWER ( | ||||||
|  | 	(* clkbuf_sink *) | ||||||
| 	input CLKA, | 	input CLKA, | ||||||
|  | 	(* clkbuf_sink *) | ||||||
| 	input CLKB, | 	input CLKB, | ||||||
| 	input ENA, | 	input ENA, | ||||||
| 	input ENB, | 	input ENB, | ||||||
|  |  | ||||||
|  | @ -1,5 +1,7 @@ | ||||||
| module RAMB18E1 ( | module RAMB18E1 ( | ||||||
|  | 	(* clkbuf_sink *) | ||||||
| 	input CLKARDCLK, | 	input CLKARDCLK, | ||||||
|  | 	(* clkbuf_sink *) | ||||||
| 	input CLKBWRCLK, | 	input CLKBWRCLK, | ||||||
| 	input ENARDEN, | 	input ENARDEN, | ||||||
| 	input ENBWREN, | 	input ENBWREN, | ||||||
|  | @ -123,7 +125,9 @@ module RAMB18E1 ( | ||||||
| endmodule | endmodule | ||||||
| 
 | 
 | ||||||
| module RAMB36E1 ( | module RAMB36E1 ( | ||||||
|  | 	(* clkbuf_sink *) | ||||||
| 	input CLKARDCLK, | 	input CLKARDCLK, | ||||||
|  | 	(* clkbuf_sink *) | ||||||
| 	input CLKBWRCLK, | 	input CLKBWRCLK, | ||||||
| 	input ENARDEN, | 	input ENARDEN, | ||||||
| 	input ENBWREN, | 	input ENBWREN, | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| module test(input clk, input [3:0] bar, output [3:0] foo); | module test(input clk, input [3:0] bar, output [3:0] foo, asdf); | ||||||
|   reg [3:0] foo = 0; |   reg [3:0] foo = 0; | ||||||
|   reg [3:0] last_bar = 0; |   reg [3:0] last_bar = 0; | ||||||
|  |   reg [3:0] asdf = 4'b1xxx; | ||||||
| 
 | 
 | ||||||
|   always @* |   always @* | ||||||
|     foo[1:0] <= bar[1:0]; |     foo[1:0] <= bar[1:0]; | ||||||
|  | @ -11,5 +12,10 @@ module test(input clk, input [3:0] bar, output [3:0] foo); | ||||||
|   always @(posedge clk) |   always @(posedge clk) | ||||||
|     last_bar <= bar; |     last_bar <= bar; | ||||||
| 
 | 
 | ||||||
|  |   always @(posedge clk) | ||||||
|  |     asdf[3] <= bar[3]; | ||||||
|  |   always @* | ||||||
|  |     asdf[2:0] = 3'b111; | ||||||
|  | 
 | ||||||
|   assert property (foo == {last_bar[3:2], bar[1:0]}); |   assert property (foo == {last_bar[3:2], bar[1:0]}); | ||||||
| endmodule | endmodule | ||||||
|  |  | ||||||
							
								
								
									
										1
									
								
								tests/techmap/.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								tests/techmap/.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -1 +1,2 @@ | ||||||
| *.log | *.log | ||||||
|  | /*.mk | ||||||
|  |  | ||||||
							
								
								
									
										96
									
								
								tests/techmap/clkbufmap.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								tests/techmap/clkbufmap.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,96 @@ | ||||||
|  | read_verilog <<EOT | ||||||
|  | module clkbuf (input i, (* clkbuf_driver *) output o); endmodule | ||||||
|  | module dff ((* clkbuf_sink *) input clk, input d, output q); endmodule | ||||||
|  | module dffe ((* clkbuf_sink *) input c, input d, e, output q); endmodule | ||||||
|  | module latch (input e, d, output q); endmodule | ||||||
|  | module clkgen (output o); endmodule | ||||||
|  | 
 | ||||||
|  | module top(input clk1, clk2, clk3, d, e, output [4:0] q); | ||||||
|  | wire clk4, clk5, clk6; | ||||||
|  | dff s0 (.clk(clk1), .d(d), .q(q[0])); | ||||||
|  | dffe s1 (.c(clk2), .d(d), .e(e), .q(q[1])); | ||||||
|  | latch s2 (.e(clk3), .d(d), .q(q[2])); | ||||||
|  | sub s3 (.sclk4(clk4), .sclk5(clk5), .sclk6(clk6), .sd(d), .sq(q[3])); | ||||||
|  | dff s4 (.clk(clk4), .d(d), .q(q[4])); | ||||||
|  | dff s5 (.clk(clk5), .d(d), .q(q[4])); | ||||||
|  | dff s6 (.clk(clk6), .d(d), .q(q[4])); | ||||||
|  | endmodule | ||||||
|  | 
 | ||||||
|  | module sub(output sclk4, output sclk5, output sclk6, input sd, output sq); | ||||||
|  | wire tmp; | ||||||
|  | clkgen s7(.o(sclk4)); | ||||||
|  | clkgen s8(.o(sclk5)); | ||||||
|  | clkgen s9(.o(tmp)); | ||||||
|  | clkbuf s10(.i(tmp), .o(sclk6)); | ||||||
|  | dff s11(.clk(sclk4), .d(sd), .q(sq)); | ||||||
|  | endmodule | ||||||
|  | EOT | ||||||
|  | 
 | ||||||
|  | hierarchy -auto-top | ||||||
|  | design -save ref | ||||||
|  | 
 | ||||||
|  | # ---------------------- | ||||||
|  | 
 | ||||||
|  | design -load ref | ||||||
|  | clkbufmap -buf clkbuf o:i | ||||||
|  | select -assert-count 3 top/t:clkbuf | ||||||
|  | select -assert-count 2 sub/t:clkbuf | ||||||
|  | select -set clk1 w:clk1 %a %co t:clkbuf %i          # Find 'clk1' fanouts that are 'clkbuf' | ||||||
|  | select -assert-count 1 @clk1                        # Check there is one such fanout | ||||||
|  | select -assert-count 1 @clk1 %x:+[o] %co c:s* %i    # Check that the 'o' of that clkbuf drives one fanout | ||||||
|  | select -assert-count 1 @clk1 %x:+[o] %co c:s0 %i    # And that one fanout is 's0' | ||||||
|  | select -set clk2 w:clk2 %a %co t:clkbuf %i | ||||||
|  | select -assert-count 1 @clk2 | ||||||
|  | select -assert-count 1 @clk2 %x:+[o] %co c:s* %i | ||||||
|  | select -assert-count 1 @clk2 %x:+[o] %co c:s1 %i | ||||||
|  | select -set clk5 w:clk5 %a %ci t:clkbuf %i | ||||||
|  | select -assert-count 1 @clk5 | ||||||
|  | select -assert-count 1 @clk5 %x:+[o] %co c:s5 %i | ||||||
|  | select -assert-count 1 @clk5 %x:+[i] %ci c:s3 %i | ||||||
|  | select -set sclk4 w:sclk4 %a %ci t:clkbuf %i | ||||||
|  | select -assert-count 1 @sclk4 | ||||||
|  | select -assert-count 1 @sclk4 %x:+[o] %co c:s11 %i | ||||||
|  | select -assert-count 1 @sclk4 %x:+[i] %ci c:s7 %i | ||||||
|  | 
 | ||||||
|  | # ---------------------- | ||||||
|  | 
 | ||||||
|  | design -load ref | ||||||
|  | setattr -set clkbuf_inhibit 0 w:clk1 | ||||||
|  | setattr -set clkbuf_inhibit 1 w:clk2 | ||||||
|  | clkbufmap -buf clkbuf o:i | ||||||
|  | select -assert-count 2 top/t:clkbuf | ||||||
|  | select -set clk1 w:clk1 %a %co t:clkbuf %i          # Find 'clk1' fanouts that are 'clkbuf' | ||||||
|  | select -assert-count 1 @clk1                        # Check there is one such fanout | ||||||
|  | select -assert-count 1 @clk1 %x:+[o] %co c:s* %i    # Check that the 'o' of that clkbuf drives one fanout | ||||||
|  | select -assert-count 1 @clk1 %x:+[o] %co c:s0 %i    # And that one fanout is 's0' | ||||||
|  | select -assert-count 0 w:clk2 %a %co t:clkbuf %i | ||||||
|  | 
 | ||||||
|  | # ---------------------- | ||||||
|  | 
 | ||||||
|  | design -load ref | ||||||
|  | setattr -set clkbuf_inhibit 1 w:clk1 | ||||||
|  | setattr -set buffer_type "bufg" w:clk2 | ||||||
|  | clkbufmap -buf clkbuf o:i w:* a:buffer_type=none a:buffer_type=bufr %u %d | ||||||
|  | select -assert-count 3 top/t:clkbuf | ||||||
|  | select -assert-count 2 sub/t:clkbuf | ||||||
|  | select -set clk1 w:clk1 %a %co t:clkbuf %i          # Find 'clk1' fanouts that are 'clkbuf' | ||||||
|  | select -assert-count 1 @clk1                        # Check there is one such fanout | ||||||
|  | select -assert-count 1 @clk1 %x:+[o] %co c:s* %i    # Check that the 'o' of that clkbuf drives one fanout | ||||||
|  | select -assert-count 1 @clk1 %x:+[o] %co c:s0 %i    # And that one fanout is 's0' | ||||||
|  | select -set clk2 w:clk2 %a %co t:clkbuf %i          # Find 'clk1' fanouts that are 'clkbuf' | ||||||
|  | select -assert-count 1 @clk2                        # Check there is one such fanout | ||||||
|  | select -assert-count 1 @clk2 %x:+[o] %co c:s* %i    # Check that the 'o' of that clkbuf drives one fanout | ||||||
|  | select -assert-count 1 @clk2 %x:+[o] %co c:s1 %i    # And that one fanout is 's0' | ||||||
|  | 
 | ||||||
|  | # ---------------------- | ||||||
|  | 
 | ||||||
|  | design -load ref | ||||||
|  | setattr -set buffer_type "none" w:clk1 | ||||||
|  | setattr -set buffer_type "bufr" w:clk2 | ||||||
|  | setattr -set buffer_type "bufr" w:sclk4 | ||||||
|  | setattr -set buffer_type "bufr" w:sclk5 | ||||||
|  | clkbufmap -buf clkbuf o:i w:* a:buffer_type=none a:buffer_type=bufr %u %d | ||||||
|  | select -assert-count 0 w:clk1 %a %co t:clkbuf %i | ||||||
|  | select -assert-count 0 w:clk2 %a %co t:clkbuf %i | ||||||
|  | select -assert-count 0 top/t:clkbuf | ||||||
|  | select -assert-count 1 sub/t:clkbuf | ||||||
|  | @ -1,10 +1,20 @@ | ||||||
| #!/bin/bash | #!/usr/bin/env bash | ||||||
| set -e | set -e | ||||||
| for x in *_runtest.sh; do | { | ||||||
| 	echo "Running $x.." | echo "all::" | ||||||
| 	if ! bash $x &> ${x%.sh}.log; then | for x in *.ys; do | ||||||
| 		tail ${x%.sh}.log | 	echo "all:: run-$x" | ||||||
| 		echo ERROR | 	echo "run-$x:" | ||||||
| 		exit 1 | 	echo "	@echo 'Running $x..'" | ||||||
|  | 	echo "	@../../yosys -ql ${x%.ys}.log $x" | ||||||
|  | done | ||||||
|  | for s in *.sh; do | ||||||
|  | 	if [ "$s" != "run-test.sh" ]; then | ||||||
|  | 		echo "all:: run-$s" | ||||||
|  | 		echo "run-$s:" | ||||||
|  | 		echo "	@echo 'Running $s..'" | ||||||
|  | 		echo "	@bash $s > ${s%.sh}.log 2>&1" | ||||||
| 	fi | 	fi | ||||||
| done | done | ||||||
|  | } > run-test.mk | ||||||
|  | exec ${MAKE:-make} -f run-test.mk | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue