mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-11-04 13:29:12 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into xc7mux
This commit is contained in:
		
						commit
						5cd19b52da
					
				
					 23 changed files with 312 additions and 221 deletions
				
			
		
							
								
								
									
										8
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										8
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -294,7 +294,7 @@ endif
 | 
				
			||||||
PY_WRAPPER_FILE = kernel/python_wrappers
 | 
					PY_WRAPPER_FILE = kernel/python_wrappers
 | 
				
			||||||
OBJS += $(PY_WRAPPER_FILE).o
 | 
					OBJS += $(PY_WRAPPER_FILE).o
 | 
				
			||||||
PY_GEN_SCRIPT= py_wrap_generator
 | 
					PY_GEN_SCRIPT= py_wrap_generator
 | 
				
			||||||
PY_WRAP_INCLUDES := $(shell python$(PYTHON_VERSION) -c "import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).print_includes()")
 | 
					PY_WRAP_INCLUDES := $(shell python$(PYTHON_VERSION) -c "from misc import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).print_includes()")
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifeq ($(ENABLE_READLINE),1)
 | 
					ifeq ($(ENABLE_READLINE),1)
 | 
				
			||||||
| 
						 | 
					@ -550,9 +550,9 @@ libyosys.so: $(filter-out kernel/driver.o,$(OBJS))
 | 
				
			||||||
	$(Q) mkdir -p $(dir $@)
 | 
						$(Q) mkdir -p $(dir $@)
 | 
				
			||||||
	$(P) cat $< | grep -E -v "#[ ]*(include|error)" | $(LD) -x c++ -o $@ -E -P -
 | 
						$(P) cat $< | grep -E -v "#[ ]*(include|error)" | $(LD) -x c++ -o $@ -E -P -
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$(PY_WRAPPER_FILE).cc: $(PY_GEN_SCRIPT).py $(PY_WRAP_INCLUDES)
 | 
					$(PY_WRAPPER_FILE).cc: misc/$(PY_GEN_SCRIPT).py $(PY_WRAP_INCLUDES)
 | 
				
			||||||
	$(Q) mkdir -p $(dir $@)
 | 
						$(Q) mkdir -p $(dir $@)
 | 
				
			||||||
	$(P) python$(PYTHON_VERSION) -c "import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).gen_wrappers(\"$(PY_WRAPPER_FILE).cc\")"
 | 
						$(P) python$(PYTHON_VERSION) -c "from misc import $(PY_GEN_SCRIPT); $(PY_GEN_SCRIPT).gen_wrappers(\"$(PY_WRAPPER_FILE).cc\")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
%.o: %.cpp
 | 
					%.o: %.cpp
 | 
				
			||||||
	$(Q) mkdir -p $(dir $@)
 | 
						$(Q) mkdir -p $(dir $@)
 | 
				
			||||||
| 
						 | 
					@ -685,7 +685,7 @@ ifeq ($(ENABLE_LIBYOSYS),1)
 | 
				
			||||||
ifeq ($(ENABLE_PYOSYS),1)
 | 
					ifeq ($(ENABLE_PYOSYS),1)
 | 
				
			||||||
	$(INSTALL_SUDO) mkdir -p $(PYTHON_DESTDIR)/pyosys
 | 
						$(INSTALL_SUDO) mkdir -p $(PYTHON_DESTDIR)/pyosys
 | 
				
			||||||
	$(INSTALL_SUDO) cp libyosys.so $(PYTHON_DESTDIR)/pyosys
 | 
						$(INSTALL_SUDO) cp libyosys.so $(PYTHON_DESTDIR)/pyosys
 | 
				
			||||||
	$(INSTALL_SUDO) cp __init__.py $(PYTHON_DESTDIR)/pyosys
 | 
						$(INSTALL_SUDO) cp misc/__init__.py $(PYTHON_DESTDIR)/pyosys
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -163,31 +163,61 @@ struct FirrtlWorker
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	/* Memories defined within this module. */
 | 
						/* Memories defined within this module. */
 | 
				
			||||||
	 struct memory {
 | 
						struct memory {
 | 
				
			||||||
		 string name;					// memory name
 | 
							Cell *pCell;					// for error reporting
 | 
				
			||||||
		 int abits;						// number of address bits
 | 
							string name;					// memory name
 | 
				
			||||||
		 int size;						// size (in units) of the memory
 | 
							int abits;						// number of address bits
 | 
				
			||||||
		 int width;						// size (in bits) of each element
 | 
							int size;						// size (in units) of the memory
 | 
				
			||||||
		 int read_latency;
 | 
							int width;						// size (in bits) of each element
 | 
				
			||||||
		 int write_latency;
 | 
							int read_latency;
 | 
				
			||||||
		 vector<read_port> read_ports;
 | 
							int write_latency;
 | 
				
			||||||
		 vector<write_port> write_ports;
 | 
							vector<read_port> read_ports;
 | 
				
			||||||
		 std::string init_file;
 | 
							vector<write_port> write_ports;
 | 
				
			||||||
		 std::string init_file_srcFileSpec;
 | 
							std::string init_file;
 | 
				
			||||||
		 memory(string name, int abits, int size, int width) : name(name), abits(abits), size(size), width(width), read_latency(0), write_latency(1), init_file(""), init_file_srcFileSpec("") {}
 | 
							std::string init_file_srcFileSpec;
 | 
				
			||||||
		 memory() : read_latency(0), write_latency(1), init_file(""), init_file_srcFileSpec(""){}
 | 
							string srcLine;
 | 
				
			||||||
		 void add_memory_read_port(read_port &rp) {
 | 
							memory(Cell *pCell, string name, int abits, int size, int width) : pCell(pCell), name(name), abits(abits), size(size), width(width), read_latency(0), write_latency(1), init_file(""), init_file_srcFileSpec("") {
 | 
				
			||||||
			 read_ports.push_back(rp);
 | 
								// Provide defaults for abits or size if one (but not the other) is specified.
 | 
				
			||||||
		 }
 | 
								if (this->abits == 0 && this->size != 0) {
 | 
				
			||||||
		 void add_memory_write_port(write_port &wp) {
 | 
									this->abits = ceil_log2(this->size);
 | 
				
			||||||
			 write_ports.push_back(wp);
 | 
								} else if (this->abits != 0 && this->size == 0) {
 | 
				
			||||||
		 }
 | 
									this->size = 1 << this->abits;
 | 
				
			||||||
		 void add_memory_file(std::string init_file, std::string init_file_srcFileSpec) {
 | 
								}
 | 
				
			||||||
			 this->init_file = init_file;
 | 
								// Sanity-check this construction.
 | 
				
			||||||
			 this->init_file_srcFileSpec = init_file_srcFileSpec;
 | 
								if (this->name == "") {
 | 
				
			||||||
 | 
									log_error("Nameless memory%s\n", this->atLine());
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (this->abits == 0 && this->size == 0) {
 | 
				
			||||||
 | 
									log_error("Memory %s has zero address bits and size%s\n", this->name.c_str(), this->atLine());
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (this->width == 0) {
 | 
				
			||||||
 | 
									log_error("Memory %s has zero width%s\n", this->name.c_str(), this->atLine());
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		 }
 | 
							 }
 | 
				
			||||||
 | 
							// We need a default constructor for the dict insert.
 | 
				
			||||||
 | 
						   memory() : pCell(0), read_latency(0), write_latency(1), init_file(""), init_file_srcFileSpec(""){}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	 };
 | 
							const char *atLine() {
 | 
				
			||||||
 | 
								if (srcLine == "") {
 | 
				
			||||||
 | 
									if (pCell) {
 | 
				
			||||||
 | 
										auto p = pCell->attributes.find("\\src");
 | 
				
			||||||
 | 
										srcLine = " at " + p->second.decode_string();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return srcLine.c_str();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							void add_memory_read_port(read_port &rp) {
 | 
				
			||||||
 | 
								read_ports.push_back(rp);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							void add_memory_write_port(write_port &wp) {
 | 
				
			||||||
 | 
								write_ports.push_back(wp);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							void add_memory_file(std::string init_file, std::string init_file_srcFileSpec) {
 | 
				
			||||||
 | 
								this->init_file = init_file;
 | 
				
			||||||
 | 
								this->init_file_srcFileSpec = init_file_srcFileSpec;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
	dict<string, memory> memories;
 | 
						dict<string, memory> memories;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void register_memory(memory &m)
 | 
						void register_memory(memory &m)
 | 
				
			||||||
| 
						 | 
					@ -604,7 +634,7 @@ struct FirrtlWorker
 | 
				
			||||||
				int abits = cell->parameters.at("\\ABITS").as_int();
 | 
									int abits = cell->parameters.at("\\ABITS").as_int();
 | 
				
			||||||
				int width = cell->parameters.at("\\WIDTH").as_int();
 | 
									int width = cell->parameters.at("\\WIDTH").as_int();
 | 
				
			||||||
				int size = cell->parameters.at("\\SIZE").as_int();
 | 
									int size = cell->parameters.at("\\SIZE").as_int();
 | 
				
			||||||
				memory m(mem_id, abits, size, width);
 | 
									memory m(cell, mem_id, abits, size, width);
 | 
				
			||||||
				int rd_ports = cell->parameters.at("\\RD_PORTS").as_int();
 | 
									int rd_ports = cell->parameters.at("\\RD_PORTS").as_int();
 | 
				
			||||||
				int wr_ports = cell->parameters.at("\\WR_PORTS").as_int();
 | 
									int wr_ports = cell->parameters.at("\\WR_PORTS").as_int();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -681,6 +711,8 @@ struct FirrtlWorker
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				std::string cell_type = fid(cell->type);
 | 
									std::string cell_type = fid(cell->type);
 | 
				
			||||||
				std::string mem_id = make_id(cell->parameters["\\MEMID"].decode_string());
 | 
									std::string mem_id = make_id(cell->parameters["\\MEMID"].decode_string());
 | 
				
			||||||
 | 
									int abits = cell->parameters.at("\\ABITS").as_int();
 | 
				
			||||||
 | 
									int width = cell->parameters.at("\\WIDTH").as_int();
 | 
				
			||||||
				memory *mp = nullptr;
 | 
									memory *mp = nullptr;
 | 
				
			||||||
				if (cell->type == "$meminit" ) {
 | 
									if (cell->type == "$meminit" ) {
 | 
				
			||||||
					log_error("$meminit (%s.%s.%s) currently unsupported\n", log_id(module), log_id(cell), mem_id.c_str());
 | 
										log_error("$meminit (%s.%s.%s) currently unsupported\n", log_id(module), log_id(cell), mem_id.c_str());
 | 
				
			||||||
| 
						 | 
					@ -693,6 +725,11 @@ struct FirrtlWorker
 | 
				
			||||||
					Const clk_enable = cell->parameters.at("\\CLK_ENABLE");
 | 
										Const clk_enable = cell->parameters.at("\\CLK_ENABLE");
 | 
				
			||||||
					Const clk_polarity = cell->parameters.at("\\CLK_POLARITY");
 | 
										Const clk_polarity = cell->parameters.at("\\CLK_POLARITY");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										// Do we already have an entry for this memory?
 | 
				
			||||||
 | 
										if (memories.count(mem_id) == 0) {
 | 
				
			||||||
 | 
											memory m(cell, mem_id, abits, 0, width);
 | 
				
			||||||
 | 
											register_memory(m);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
					mp = &memories.at(mem_id);
 | 
										mp = &memories.at(mem_id);
 | 
				
			||||||
					int portNum = 0;
 | 
										int portNum = 0;
 | 
				
			||||||
					bool transparency = false;
 | 
										bool transparency = false;
 | 
				
			||||||
| 
						 | 
					@ -890,7 +927,7 @@ struct FirrtlWorker
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// If we have any memory definitions, output them.
 | 
							// If we have any memory definitions, output them.
 | 
				
			||||||
		for (auto kv : memories) {
 | 
							for (auto kv : memories) {
 | 
				
			||||||
			memory m = kv.second;
 | 
								memory &m = kv.second;
 | 
				
			||||||
			f << stringf("    mem %s:\n", m.name.c_str());
 | 
								f << stringf("    mem %s:\n", m.name.c_str());
 | 
				
			||||||
			f << stringf("      data-type => UInt<%d>\n", m.width);
 | 
								f << stringf("      data-type => UInt<%d>\n", m.width);
 | 
				
			||||||
			f << stringf("      depth => %d\n", m.size);
 | 
								f << stringf("      depth => %d\n", m.size);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1172,6 +1172,15 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
 | 
				
			||||||
			varbuf->children[0] = buf;
 | 
								varbuf->children[0] = buf;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
 | 
							if (type == AST_FOR) {
 | 
				
			||||||
 | 
								AstNode *buf = next_ast->clone();
 | 
				
			||||||
 | 
								delete buf->children[1];
 | 
				
			||||||
 | 
								buf->children[1] = varbuf->children[0]->clone();
 | 
				
			||||||
 | 
								current_block->children.insert(current_block->children.begin() + current_block_idx++, buf);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		current_scope[varbuf->str] = backup_scope_varbuf;
 | 
							current_scope[varbuf->str] = backup_scope_varbuf;
 | 
				
			||||||
		delete varbuf;
 | 
							delete varbuf;
 | 
				
			||||||
		delete_children();
 | 
							delete_children();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -242,8 +242,6 @@ struct VerilogFrontend : public Frontend {
 | 
				
			||||||
		nowb_mode = false;
 | 
							nowb_mode = false;
 | 
				
			||||||
		default_nettype_wire = true;
 | 
							default_nettype_wire = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		log_header(design, "Executing Verilog-2005 frontend.\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		args.insert(args.begin()+1, verilog_defaults.begin(), verilog_defaults.end());
 | 
							args.insert(args.begin()+1, verilog_defaults.begin(), verilog_defaults.end());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		size_t argidx;
 | 
							size_t argidx;
 | 
				
			||||||
| 
						 | 
					@ -415,6 +413,8 @@ struct VerilogFrontend : public Frontend {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		extra_args(f, filename, args, argidx);
 | 
							extra_args(f, filename, args, argidx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							log_header(design, "Executing Verilog-2005 frontend: %s\n", filename.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		log("Parsing %s%s input from `%s' to AST representation.\n",
 | 
							log("Parsing %s%s input from `%s' to AST representation.\n",
 | 
				
			||||||
				formal_mode ? "formal " : "", sv_mode ? "SystemVerilog" : "Verilog", filename.c_str());
 | 
									formal_mode ? "formal " : "", sv_mode ? "SystemVerilog" : "Verilog", filename.c_str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -529,13 +529,13 @@ int main(int argc, char **argv)
 | 
				
			||||||
			log_error("Can't open dependencies file for writing: %s\n", strerror(errno));
 | 
								log_error("Can't open dependencies file for writing: %s\n", strerror(errno));
 | 
				
			||||||
		bool first = true;
 | 
							bool first = true;
 | 
				
			||||||
		for (auto fn : yosys_output_files) {
 | 
							for (auto fn : yosys_output_files) {
 | 
				
			||||||
			fprintf(f, "%s%s", first ? "" : " ", fn.c_str());
 | 
								fprintf(f, "%s%s", first ? "" : " ", escape_filename_spaces(fn).c_str());
 | 
				
			||||||
			first = false;
 | 
								first = false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		fprintf(f, ":");
 | 
							fprintf(f, ":");
 | 
				
			||||||
		for (auto fn : yosys_input_files) {
 | 
							for (auto fn : yosys_input_files) {
 | 
				
			||||||
			if (yosys_output_files.count(fn) == 0)
 | 
								if (yosys_output_files.count(fn) == 0)
 | 
				
			||||||
				fprintf(f, " %s", fn.c_str());
 | 
									fprintf(f, " %s", escape_filename_spaces(fn).c_str());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		fprintf(f, "\n");
 | 
							fprintf(f, "\n");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3456,7 +3456,7 @@ bool RTLIL::SigSpec::operator ==(const RTLIL::SigSpec &other) const
 | 
				
			||||||
	pack();
 | 
						pack();
 | 
				
			||||||
	other.pack();
 | 
						other.pack();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (chunks_.size() != chunks_.size())
 | 
						if (chunks_.size() != other.chunks_.size())
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	updhash();
 | 
						updhash();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -482,6 +482,20 @@ void remove_directory(std::string dirname)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					std::string escape_filename_spaces(const std::string& filename)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						std::string out;
 | 
				
			||||||
 | 
						out.reserve(filename.size());
 | 
				
			||||||
 | 
						for (auto c : filename)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (c == ' ')
 | 
				
			||||||
 | 
								out += "\\ ";
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								out.push_back(c);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return out;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int GetSize(RTLIL::Wire *wire)
 | 
					int GetSize(RTLIL::Wire *wire)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return wire->width;
 | 
						return wire->width;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -257,6 +257,7 @@ std::string make_temp_dir(std::string template_str = "/tmp/yosys_XXXXXX");
 | 
				
			||||||
bool check_file_exists(std::string filename, bool is_exec = false);
 | 
					bool check_file_exists(std::string filename, bool is_exec = false);
 | 
				
			||||||
bool is_absolute_path(std::string filename);
 | 
					bool is_absolute_path(std::string filename);
 | 
				
			||||||
void remove_directory(std::string dirname);
 | 
					void remove_directory(std::string dirname);
 | 
				
			||||||
 | 
					std::string escape_filename_spaces(const std::string& filename);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
template<typename T> int GetSize(const T &obj) { return obj.size(); }
 | 
					template<typename T> int GetSize(const T &obj) { return obj.size(); }
 | 
				
			||||||
int GetSize(RTLIL::Wire *wire);
 | 
					int GetSize(RTLIL::Wire *wire);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -291,7 +291,7 @@ struct QwpWorker
 | 
				
			||||||
		// gaussian elimination
 | 
							// gaussian elimination
 | 
				
			||||||
		for (int i = 0; i < N; i++)
 | 
							for (int i = 0; i < N; i++)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (config.verbose && ((i+1) % (N/15)) == 0)
 | 
								if (config.verbose && N > 15 && ((i+1) % (N/15)) == 0)
 | 
				
			||||||
				log("> Solved %d%%: %d/%d\n", (100*(i+1))/N, i+1, N);
 | 
									log("> Solved %d%%: %d/%d\n", (100*(i+1))/N, i+1, N);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// find best row
 | 
								// find best row
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -281,13 +281,26 @@ void rmunused_module_signals(RTLIL::Module *module, bool purge_mode, bool verbos
 | 
				
			||||||
				maybe_del_wires.push_back(wire);
 | 
									maybe_del_wires.push_back(wire);
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				log_assert(GetSize(s1) == GetSize(s2));
 | 
									log_assert(GetSize(s1) == GetSize(s2));
 | 
				
			||||||
 | 
									Const initval;
 | 
				
			||||||
 | 
									if (wire->attributes.count("\\init"))
 | 
				
			||||||
 | 
										initval = wire->attributes.at("\\init");
 | 
				
			||||||
 | 
									if (GetSize(initval) != GetSize(wire))
 | 
				
			||||||
 | 
										initval.bits.resize(GetSize(wire), State::Sx);
 | 
				
			||||||
				RTLIL::SigSig new_conn;
 | 
									RTLIL::SigSig new_conn;
 | 
				
			||||||
				for (int i = 0; i < GetSize(s1); i++)
 | 
									for (int i = 0; i < GetSize(s1); i++)
 | 
				
			||||||
					if (s1[i] != s2[i]) {
 | 
										if (s1[i] != s2[i]) {
 | 
				
			||||||
 | 
											if (s2[i] == State::Sx && (initval[i] == State::S0 || initval[i] == State::S1)) {
 | 
				
			||||||
 | 
												s2[i] = initval[i];
 | 
				
			||||||
 | 
												initval[i] = State::Sx;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
						new_conn.first.append_bit(s1[i]);
 | 
											new_conn.first.append_bit(s1[i]);
 | 
				
			||||||
						new_conn.second.append_bit(s2[i]);
 | 
											new_conn.second.append_bit(s2[i]);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				if (new_conn.first.size() > 0) {
 | 
									if (new_conn.first.size() > 0) {
 | 
				
			||||||
 | 
										if (initval.is_fully_undef())
 | 
				
			||||||
 | 
											wire->attributes.erase("\\init");
 | 
				
			||||||
 | 
										else
 | 
				
			||||||
 | 
											wire->attributes.at("\\init") = initval;
 | 
				
			||||||
					used_signals.add(new_conn.first);
 | 
										used_signals.add(new_conn.first);
 | 
				
			||||||
					used_signals.add(new_conn.second);
 | 
										used_signals.add(new_conn.second);
 | 
				
			||||||
					module->connect(new_conn);
 | 
										module->connect(new_conn);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,6 +39,9 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module)
 | 
				
			||||||
	SigPool used_signals;
 | 
						SigPool used_signals;
 | 
				
			||||||
	SigPool all_signals;
 | 
						SigPool all_signals;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dict<SigBit, pair<Wire*, State>> initbits;
 | 
				
			||||||
 | 
						pool<Wire*> revisit_initwires;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (auto cell : module->cells())
 | 
						for (auto cell : module->cells())
 | 
				
			||||||
	for (auto &conn : cell->connections()) {
 | 
						for (auto &conn : cell->connections()) {
 | 
				
			||||||
		if (!ct.cell_known(cell->type) || ct.cell_output(cell->type, conn.first))
 | 
							if (!ct.cell_known(cell->type) || ct.cell_output(cell->type, conn.first))
 | 
				
			||||||
| 
						 | 
					@ -48,6 +51,14 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (auto wire : module->wires()) {
 | 
						for (auto wire : module->wires()) {
 | 
				
			||||||
 | 
							if (wire->attributes.count("\\init")) {
 | 
				
			||||||
 | 
								SigSpec sig = sigmap(wire);
 | 
				
			||||||
 | 
								Const initval = wire->attributes.at("\\init");
 | 
				
			||||||
 | 
								for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++) {
 | 
				
			||||||
 | 
									if (initval[i] == State::S0 || initval[i] == State::S1)
 | 
				
			||||||
 | 
										initbits[sig[i]] = make_pair(wire, initval[i]);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if (wire->port_input)
 | 
							if (wire->port_input)
 | 
				
			||||||
			driven_signals.add(sigmap(wire));
 | 
								driven_signals.add(sigmap(wire));
 | 
				
			||||||
		if (wire->port_output)
 | 
							if (wire->port_output)
 | 
				
			||||||
| 
						 | 
					@ -67,10 +78,38 @@ void replace_undriven(RTLIL::Design *design, RTLIL::Module *module)
 | 
				
			||||||
		if (sig.size() == 0)
 | 
							if (sig.size() == 0)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		log_debug("Setting undriven signal in %s to undef: %s\n", RTLIL::id2cstr(module->name), log_signal(c));
 | 
							Const val(RTLIL::State::Sx, GetSize(sig));
 | 
				
			||||||
		module->connect(RTLIL::SigSig(c, RTLIL::SigSpec(RTLIL::State::Sx, c.width)));
 | 
							for (int i = 0; i < GetSize(sig); i++) {
 | 
				
			||||||
 | 
								SigBit bit = sigmap(sig[i]);
 | 
				
			||||||
 | 
								auto cursor = initbits.find(bit);
 | 
				
			||||||
 | 
								if (cursor != initbits.end()) {
 | 
				
			||||||
 | 
									revisit_initwires.insert(cursor->second.first);
 | 
				
			||||||
 | 
									val[i] = cursor->second.second;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							log_debug("Setting undriven signal in %s to constant: %s = %s\n", RTLIL::id2cstr(module->name), log_signal(sig), log_signal(val));
 | 
				
			||||||
 | 
							module->connect(sig, val);
 | 
				
			||||||
		did_something = true;
 | 
							did_something = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!revisit_initwires.empty())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SigMap sm2(module);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (auto wire : revisit_initwires) {
 | 
				
			||||||
 | 
								SigSpec sig = sm2(wire);
 | 
				
			||||||
 | 
								Const initval = wire->attributes.at("\\init");
 | 
				
			||||||
 | 
								for (int i = 0; i < GetSize(initval) && i < GetSize(wire); i++) {
 | 
				
			||||||
 | 
									if (SigBit(initval[i]) == sig[i])
 | 
				
			||||||
 | 
										initval[i] = State::Sx;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (initval.is_fully_undef())
 | 
				
			||||||
 | 
									wire->attributes.erase("\\init");
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									wire->attributes["\\init"] = initval;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val)
 | 
					void replace_cell(SigMap &assign_map, RTLIL::Module *module, RTLIL::Cell *cell, std::string info, std::string out_port, RTLIL::SigSpec out_val)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -180,6 +180,8 @@ struct WreduceWorker
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			auto info = mi.query(sig_q[i]);
 | 
								auto info = mi.query(sig_q[i]);
 | 
				
			||||||
 | 
								if (info == nullptr)
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
			if (!info->is_output && GetSize(info->ports) == 1 && !keep_bits.count(mi.sigmap(sig_q[i]))) {
 | 
								if (!info->is_output && GetSize(info->ports) == 1 && !keep_bits.count(mi.sigmap(sig_q[i]))) {
 | 
				
			||||||
				remove_init_bits.insert(sig_q[i]);
 | 
									remove_init_bits.insert(sig_q[i]);
 | 
				
			||||||
				sig_d.remove(i);
 | 
									sig_d.remove(i);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1169,6 +1169,7 @@ struct SatPass : public Pass {
 | 
				
			||||||
			if (args[argidx] == "-tempinduct-def") {
 | 
								if (args[argidx] == "-tempinduct-def") {
 | 
				
			||||||
				tempinduct = true;
 | 
									tempinduct = true;
 | 
				
			||||||
				tempinduct_def = true;
 | 
									tempinduct_def = true;
 | 
				
			||||||
 | 
									enable_undef = true;
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (args[argidx] == "-tempinduct-baseonly") {
 | 
								if (args[argidx] == "-tempinduct-baseonly") {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -178,7 +178,17 @@ struct ShregmapTechXilinx7 : ShregmapTech
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Only map if $shiftx exclusively covers the shift register
 | 
							// Only map if $shiftx exclusively covers the shift register
 | 
				
			||||||
		if (shiftx->type == "$shiftx") {
 | 
							if (shiftx->type == "$shiftx") {
 | 
				
			||||||
			if (GetSize(taps) != shiftx->getParam("\\A_WIDTH").as_int())
 | 
								if (GetSize(taps) > shiftx->getParam("\\A_WIDTH").as_int())
 | 
				
			||||||
 | 
									return false;
 | 
				
			||||||
 | 
								// Due to padding the most significant bits of A may be 1'bx,
 | 
				
			||||||
 | 
								//   and if so, discount them
 | 
				
			||||||
 | 
								if (GetSize(taps) < shiftx->getParam("\\A_WIDTH").as_int()) {
 | 
				
			||||||
 | 
									const SigSpec A = shiftx->getPort("\\A");
 | 
				
			||||||
 | 
									const int A_width = shiftx->getParam("\\A_WIDTH").as_int();
 | 
				
			||||||
 | 
									for (int i = GetSize(taps); i < A_width; ++i)
 | 
				
			||||||
 | 
										if (A[i] != RTLIL::Sx) return false;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else if (GetSize(taps) != shiftx->getParam("\\A_WIDTH").as_int())
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else if (shiftx->type == "$mux") {
 | 
							else if (shiftx->type == "$mux") {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -253,7 +253,7 @@ struct SynthEcp5Pass : public ScriptPass
 | 
				
			||||||
			if (!nodffe)
 | 
								if (!nodffe)
 | 
				
			||||||
				run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*");
 | 
									run("dff2dffe -direct-match $_DFF_* -direct-match $__DFFS_*");
 | 
				
			||||||
			run("techmap -D NO_LUT -map +/ecp5/cells_map.v");
 | 
								run("techmap -D NO_LUT -map +/ecp5/cells_map.v");
 | 
				
			||||||
			run("opt_expr -mux_undef");
 | 
								run("opt_expr -undriven -mux_undef");
 | 
				
			||||||
			run("simplemap");
 | 
								run("simplemap");
 | 
				
			||||||
			run("ecp5_ffinit");
 | 
								run("ecp5_ffinit");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -245,11 +245,13 @@ struct SynthIce40Pass : public ScriptPass
 | 
				
			||||||
			run("proc");
 | 
								run("proc");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (flatten && check_label("flatten", "(unless -noflatten)"))
 | 
							if (check_label("flatten", "(unless -noflatten)"))
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			run("flatten");
 | 
								if (flatten) {
 | 
				
			||||||
			run("tribuf -logic");
 | 
									run("flatten");
 | 
				
			||||||
			run("deminout");
 | 
									run("tribuf -logic");
 | 
				
			||||||
 | 
									run("deminout");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_label("coarse"))
 | 
							if (check_label("coarse"))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,6 +17,14 @@
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Convert negative-polarity reset to positive-polarity
 | 
				
			||||||
 | 
					module  \$_DFF_NN0_ (input D, C, R, output Q); \$_DFF_NP0_  _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
 | 
				
			||||||
 | 
					module  \$_DFF_PN0_ (input D, C, R, output Q); \$_DFF_PP0_  _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module  \$_DFF_NN1_ (input D, C, R, output Q); \$_DFF_NP1   _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
 | 
				
			||||||
 | 
					module  \$_DFF_PN1_ (input D, C, R, output Q); \$_DFF_PP1   _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module \$__SHREG_ (input C, input D, input E, output Q);
 | 
					module \$__SHREG_ (input C, input D, input E, output Q);
 | 
				
			||||||
  parameter DEPTH = 0;
 | 
					  parameter DEPTH = 0;
 | 
				
			||||||
  parameter [DEPTH-1:0] INIT = 0;
 | 
					  parameter [DEPTH-1:0] INIT = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,26 +22,21 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
`ifndef _NO_FFS
 | 
					`ifndef _NO_FFS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
`ifndef _NO_POS_SR
 | 
					 | 
				
			||||||
module  \$_DFF_N_   (input D, C, output Q);    FDRE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); endmodule
 | 
					module  \$_DFF_N_   (input D, C, output Q);    FDRE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); endmodule
 | 
				
			||||||
module  \$_DFF_P_   (input D, C, output Q);    FDRE   #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); endmodule
 | 
					module  \$_DFF_P_   (input D, C, output Q);    FDRE   #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); endmodule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module  \$_DFFE_NP_ (input D, C, E, output Q); FDRE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E),    .R(1'b0)); endmodule
 | 
					module  \$_DFFE_NP_ (input D, C, E, output Q); FDRE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E),    .R(1'b0)); endmodule
 | 
				
			||||||
module  \$_DFFE_PP_ (input D, C, E, output Q); FDRE   #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E),    .R(1'b0)); endmodule
 | 
					module  \$_DFFE_PP_ (input D, C, E, output Q); FDRE   #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E),    .R(1'b0)); endmodule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module  \$_DFF_NN0_ (input D, C, R, output Q); FDCE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R)); endmodule
 | 
				
			||||||
module  \$_DFF_NP0_ (input D, C, R, output Q); FDCE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); endmodule
 | 
					module  \$_DFF_NP0_ (input D, C, R, output Q); FDCE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); endmodule
 | 
				
			||||||
 | 
					module  \$_DFF_PN0_ (input D, C, R, output Q); FDCE   #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R)); endmodule
 | 
				
			||||||
module  \$_DFF_PP0_ (input D, C, R, output Q); FDCE   #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); endmodule
 | 
					module  \$_DFF_PP0_ (input D, C, R, output Q); FDCE   #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); endmodule
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module  \$_DFF_NN1_ (input D, C, R, output Q); FDPE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R)); endmodule
 | 
				
			||||||
module  \$_DFF_NP1_ (input D, C, R, output Q); FDPE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); endmodule
 | 
					module  \$_DFF_NP1_ (input D, C, R, output Q); FDPE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); endmodule
 | 
				
			||||||
 | 
					module  \$_DFF_PN1_ (input D, C, R, output Q); FDPE   #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R)); endmodule
 | 
				
			||||||
module  \$_DFF_PP1_ (input D, C, R, output Q); FDPE   #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); endmodule
 | 
					module  \$_DFF_PP1_ (input D, C, R, output Q); FDPE   #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); endmodule
 | 
				
			||||||
`endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module  \$_DFF_NN0_ (input D, C, R, output Q); \$_DFF_NP0_         _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C),              .R(~R)); endmodule
 | 
					 | 
				
			||||||
module  \$_DFF_PN0_ (input D, C, R, output Q); \$_DFF_PP0_         _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C),              .R(~R)); endmodule
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
module  \$_DFF_NN1_ (input D, C, R, output Q); \$_DFF_NP1          _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C),              .R(~R)); endmodule
 | 
					 | 
				
			||||||
module  \$_DFF_PN1_ (input D, C, R, output Q); \$_DFF_PP1          _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C),              .R(~R)); endmodule
 | 
					 | 
				
			||||||
`endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
`endif
 | 
					`endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,18 +25,9 @@
 | 
				
			||||||
USING_YOSYS_NAMESPACE
 | 
					USING_YOSYS_NAMESPACE
 | 
				
			||||||
PRIVATE_NAMESPACE_BEGIN
 | 
					PRIVATE_NAMESPACE_BEGIN
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool check_label(bool &active, std::string run_from, std::string run_to, std::string label)
 | 
					struct SynthXilinxPass : public ScriptPass
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (label == run_from)
 | 
						SynthXilinxPass() : ScriptPass("synth_xilinx", "synthesis for Xilinx FPGAs") { }
 | 
				
			||||||
		active = true;
 | 
					 | 
				
			||||||
	if (label == run_to)
 | 
					 | 
				
			||||||
		active = false;
 | 
					 | 
				
			||||||
	return active;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct SynthXilinxPass : public Pass
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	SynthXilinxPass() : Pass("synth_xilinx", "synthesis for Xilinx FPGAs") { }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void help() YS_OVERRIDE
 | 
						void help() YS_OVERRIDE
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -94,81 +85,32 @@ struct SynthXilinxPass : public Pass
 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
		log("The following commands are executed by this synthesis command:\n");
 | 
							log("The following commands are executed by this synthesis command:\n");
 | 
				
			||||||
		log("\n");
 | 
							help_script();
 | 
				
			||||||
		log("    begin:\n");
 | 
					 | 
				
			||||||
		log("        read_verilog -lib +/xilinx/cells_sim.v\n");
 | 
					 | 
				
			||||||
		log("        read_verilog -lib +/xilinx/cells_xtra.v\n");
 | 
					 | 
				
			||||||
		log("        read_verilog -lib +/xilinx/brams_bb.v\n");
 | 
					 | 
				
			||||||
		log("        hierarchy -check -top <top>\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    flatten:     (only if -flatten)\n");
 | 
					 | 
				
			||||||
		log("        proc\n");
 | 
					 | 
				
			||||||
		log("        flatten\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    coarse:\n");
 | 
					 | 
				
			||||||
		log("        synth -run coarse\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    bram: (only executed when '-nobram' is not given)\n");
 | 
					 | 
				
			||||||
		log("        memory_bram -rules +/xilinx/brams.txt\n");
 | 
					 | 
				
			||||||
		log("        techmap -map +/xilinx/brams_map.v\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    dram: (only executed when '-nodram' is not given)\n");
 | 
					 | 
				
			||||||
		log("        memory_bram -rules +/xilinx/drams.txt\n");
 | 
					 | 
				
			||||||
		log("        techmap -map +/xilinx/drams_map.v\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    fine:\n");
 | 
					 | 
				
			||||||
		log("        opt -fast\n");
 | 
					 | 
				
			||||||
		log("        memory_map\n");
 | 
					 | 
				
			||||||
		log("        dffsr2dff\n");
 | 
					 | 
				
			||||||
		log("        dff2dffe\n");
 | 
					 | 
				
			||||||
		log("        techmap -map +/xilinx/arith_map.v (without '-nocarry' only)\n");
 | 
					 | 
				
			||||||
		log("        opt -fast\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    map_cells:\n");
 | 
					 | 
				
			||||||
		log("        pmux2shiftx (without '-nosrl' and '-nomux' only)\n");
 | 
					 | 
				
			||||||
		log("        simplemap t:$dff t:$dffe (without '-nosrl' only)\n");
 | 
					 | 
				
			||||||
		log("        opt_expr -mux_undef (without '-nosrl' only)\n");
 | 
					 | 
				
			||||||
		log("        shregmap -tech xilinx -minlen 3 (without '-nosrl' only)\n");
 | 
					 | 
				
			||||||
		log("        techmap -map +/xilinx/cells_map.v\n");
 | 
					 | 
				
			||||||
		log("        clean\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    map_luts:\n");
 | 
					 | 
				
			||||||
		log("        opt -full\n");
 | 
					 | 
				
			||||||
		log("        techmap -map +/techmap.v -D _NO_POS_SR -map +/xilinx/ff_map.v\n");
 | 
					 | 
				
			||||||
		log("        abc -luts 2:2,3,6:5,10,20 [-dff]\n");
 | 
					 | 
				
			||||||
		log("        clean\n");
 | 
					 | 
				
			||||||
		log("        shregmap -minlen 3 -init -params -enpol any_or_none (without '-nosrl' only)\n");
 | 
					 | 
				
			||||||
		log("        techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v\n");
 | 
					 | 
				
			||||||
		log("        dffinit -ff FDRE   Q INIT -ff FDCE   Q INIT -ff FDPE   Q INIT -ff FDSE   Q INIT \\\n");
 | 
					 | 
				
			||||||
		log("                -ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    check:\n");
 | 
					 | 
				
			||||||
		log("        hierarchy -check\n");
 | 
					 | 
				
			||||||
		log("        stat\n");
 | 
					 | 
				
			||||||
		log("        check -noinit\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    edif:     (only if -edif)\n");
 | 
					 | 
				
			||||||
		log("        write_edif <file-name>\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
					 | 
				
			||||||
		log("    blif:     (only if -blif)\n");
 | 
					 | 
				
			||||||
		log("        write_blif <file-name>\n");
 | 
					 | 
				
			||||||
		log("\n");
 | 
							log("\n");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string top_opt, edif_file, blif_file, abc;
 | 
				
			||||||
 | 
						bool flatten, retime, vpr, nocarry, nobram, nodram, nosrl, nomux;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void clear_flags() YS_OVERRIDE
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							top_opt = "-auto-top";
 | 
				
			||||||
 | 
							edif_file.clear();
 | 
				
			||||||
 | 
							blif_file.clear();
 | 
				
			||||||
 | 
							abc = "abc";
 | 
				
			||||||
 | 
							flatten = false;
 | 
				
			||||||
 | 
							retime = false;
 | 
				
			||||||
 | 
							vpr = false;
 | 
				
			||||||
 | 
							nobram = false;
 | 
				
			||||||
 | 
							nodram = false;
 | 
				
			||||||
 | 
							nosrl = false;
 | 
				
			||||||
 | 
							nomux = false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
 | 
						void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		std::string top_opt = "-auto-top";
 | 
					 | 
				
			||||||
		std::string edif_file;
 | 
					 | 
				
			||||||
		std::string blif_file;
 | 
					 | 
				
			||||||
		std::string run_from, run_to;
 | 
							std::string run_from, run_to;
 | 
				
			||||||
		std::string abc = "abc";
 | 
							clear_flags();
 | 
				
			||||||
		bool flatten = false;
 | 
					 | 
				
			||||||
		bool retime = false;
 | 
					 | 
				
			||||||
		bool vpr = false;
 | 
					 | 
				
			||||||
		bool nocarry = false;
 | 
					 | 
				
			||||||
		bool nobram = false;
 | 
					 | 
				
			||||||
		bool nodram = false;
 | 
					 | 
				
			||||||
		bool nosrl = false;
 | 
					 | 
				
			||||||
		bool nomux = false;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		size_t argidx;
 | 
							size_t argidx;
 | 
				
			||||||
		for (argidx = 1; argidx < args.size(); argidx++)
 | 
							for (argidx = 1; argidx < args.size(); argidx++)
 | 
				
			||||||
| 
						 | 
					@ -219,8 +161,8 @@ struct SynthXilinxPass : public Pass
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (args[argidx] == "-nosrl") {
 | 
								if (args[argidx] == "-nosrl") {
 | 
				
			||||||
				nosrl = true;
 | 
									nosrl = true;
 | 
				
			||||||
                continue;
 | 
									continue;
 | 
				
			||||||
            }
 | 
								}
 | 
				
			||||||
			if (args[argidx] == "-nomux") {
 | 
								if (args[argidx] == "-nomux") {
 | 
				
			||||||
				nomux = true;
 | 
									nomux = true;
 | 
				
			||||||
				continue;
 | 
									continue;
 | 
				
			||||||
| 
						 | 
					@ -236,135 +178,130 @@ struct SynthXilinxPass : public Pass
 | 
				
			||||||
		if (!design->full_selection())
 | 
							if (!design->full_selection())
 | 
				
			||||||
			log_cmd_error("This command only operates on fully selected designs!\n");
 | 
								log_cmd_error("This command only operates on fully selected designs!\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool active = run_from.empty();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		log_header(design, "Executing SYNTH_XILINX pass.\n");
 | 
							log_header(design, "Executing SYNTH_XILINX pass.\n");
 | 
				
			||||||
		log_push();
 | 
							log_push();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_label(active, run_from, run_to, "begin"))
 | 
							run_script(design, run_from, run_to);
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			if (vpr) {
 | 
					 | 
				
			||||||
				Pass::call(design, "read_verilog -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v");
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				Pass::call(design, "read_verilog -lib +/xilinx/cells_sim.v");
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			Pass::call(design, "read_verilog -lib +/xilinx/cells_xtra.v");
 | 
							log_pop();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!nobram) {
 | 
						void script() YS_OVERRIDE
 | 
				
			||||||
				Pass::call(design, "read_verilog -lib +/xilinx/brams_bb.v");
 | 
						{
 | 
				
			||||||
			}
 | 
							if (check_label("begin")) {
 | 
				
			||||||
 | 
								if (vpr)
 | 
				
			||||||
 | 
									run("read_verilog -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v");
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
									run("read_verilog -lib +/xilinx/cells_sim.v");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			Pass::call(design, stringf("hierarchy -check %s", top_opt.c_str()));
 | 
								run("read_verilog -lib +/xilinx/cells_xtra.v");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (!nobram || help_mode)
 | 
				
			||||||
 | 
									run("read_verilog -lib +/xilinx/brams_bb.v", "(skip if '-nobram')");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								run(stringf("hierarchy -check %s", top_opt.c_str()));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (flatten && check_label(active, run_from, run_to, "flatten"))
 | 
							if (check_label("flatten", "(with '-flatten' only)")) {
 | 
				
			||||||
		{
 | 
								if (flatten || help_mode) {
 | 
				
			||||||
			Pass::call(design, "proc");
 | 
									run("proc");
 | 
				
			||||||
			Pass::call(design, "flatten");
 | 
									run("flatten");
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (check_label(active, run_from, run_to, "coarse"))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Pass::call(design, "synth -run coarse");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (check_label(active, run_from, run_to, "bram"))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			if (!nobram) {
 | 
					 | 
				
			||||||
				Pass::call(design, "memory_bram -rules +/xilinx/brams.txt");
 | 
					 | 
				
			||||||
				Pass::call(design, "techmap -map +/xilinx/brams_map.v");
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_label(active, run_from, run_to, "dram"))
 | 
							if (check_label("coarse")) {
 | 
				
			||||||
		{
 | 
								run("synth -run coarse");
 | 
				
			||||||
			if (!nodram) {
 | 
							}
 | 
				
			||||||
				Pass::call(design, "memory_bram -rules +/xilinx/drams.txt");
 | 
					
 | 
				
			||||||
				Pass::call(design, "techmap -map +/xilinx/drams_map.v");
 | 
							if (check_label("bram", "(skip if '-nobram')")) {
 | 
				
			||||||
 | 
								if (!nobram || help_mode) {
 | 
				
			||||||
 | 
									run("memory_bram -rules +/xilinx/brams.txt");
 | 
				
			||||||
 | 
									run("techmap -map +/xilinx/brams_map.v");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_label(active, run_from, run_to, "fine"))
 | 
							if (check_label("dram", "(skip if '-nodram')")) {
 | 
				
			||||||
		{
 | 
								if (!nodram || help_mode) {
 | 
				
			||||||
			Pass::call(design, "opt -fast -full");
 | 
									run("memory_bram -rules +/xilinx/drams.txt");
 | 
				
			||||||
			Pass::call(design, "memory_map");
 | 
									run("techmap -map +/xilinx/drams_map.v");
 | 
				
			||||||
			Pass::call(design, "dffsr2dff");
 | 
					 | 
				
			||||||
			Pass::call(design, "dff2dffe");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (!nocarry) {
 | 
					 | 
				
			||||||
				if (vpr)
 | 
					 | 
				
			||||||
					Pass::call(design, "techmap -D _EXPLICIT_CARRY -map +/xilinx/arith_map.v");
 | 
					 | 
				
			||||||
				else
 | 
					 | 
				
			||||||
					Pass::call(design, "techmap -map +/xilinx/arith_map.v");
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (check_label("fine")) {
 | 
				
			||||||
			// shregmap -tech xilinx can cope with $shiftx and $mux
 | 
								// shregmap -tech xilinx can cope with $shiftx and $mux
 | 
				
			||||||
			//   cells for identifying variable-length shift registers,
 | 
								//   cells for identifying variable-length shift registers,
 | 
				
			||||||
			//   so attempt to convert $pmux-es to the former
 | 
								//   so attempt to convert $pmux-es to the former
 | 
				
			||||||
			// Also: wide multiplexer inference benefits from this too
 | 
								// Also: wide multiplexer inference benefits from this too
 | 
				
			||||||
			if (!nosrl || !nomux)
 | 
								if (!nosrl || !nomux)
 | 
				
			||||||
				Pass::call(design, "pmux2shiftx");
 | 
									run("pmux2shiftx", "(skip if '-nosrl' and '-nomux')");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			Pass::call(design, "opt -full");
 | 
								run("opt -fast -full");
 | 
				
			||||||
			Pass::call(design, "techmap");
 | 
								run("memory_map");
 | 
				
			||||||
			Pass::call(design, "opt -fast");
 | 
								run("dffsr2dff");
 | 
				
			||||||
 | 
								run("dff2dffe");
 | 
				
			||||||
 | 
								run("opt -full");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// shregmap with '-tech xilinx' infers variable length shift regs
 | 
								if (!vpr || help_mode)
 | 
				
			||||||
			if (!nosrl)
 | 
									run("techmap -map +/xilinx/arith_map.v");
 | 
				
			||||||
				Pass::call(design, "shregmap -tech xilinx -minlen 3");
 | 
								else
 | 
				
			||||||
 | 
									run("techmap -map +/xilinx/arith_map.v -D _EXPLICIT_CARRY");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!nomux)
 | 
								if (!nosrl || help_mode) {
 | 
				
			||||||
				Pass::call(design, "muxcover -mux8 -mux16");
 | 
									// shregmap operates on bit-level flops, not word-level,
 | 
				
			||||||
 | 
									//   so break those down here
 | 
				
			||||||
 | 
									run("simplemap t:$dff t:$dffe", "(skip if '-nosrl')");
 | 
				
			||||||
 | 
									// shregmap with '-tech xilinx' infers variable length shift regs
 | 
				
			||||||
 | 
									run("shregmap -tech xilinx -minlen 3", "(skip if '-nosrl')");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			Pass::call(design, "opt -fast");
 | 
								run("techmap");
 | 
				
			||||||
 | 
								run("opt -fast");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (!nomux || help_mode)
 | 
				
			||||||
 | 
									run("muxcover -mux8 -mux16");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_label(active, run_from, run_to, "map_cells"))
 | 
							if (check_label("map_cells")) {
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			std::string define;
 | 
								std::string define;
 | 
				
			||||||
			if (nomux)
 | 
								if (nomux)
 | 
				
			||||||
				define += " -D NO_MUXFN";
 | 
									define += " -D NO_MUXFN";
 | 
				
			||||||
			Pass::call(design, "techmap" + define + " -map +/xilinx/cells_map.v");
 | 
								run("techmap -map +/techmap.v -map +/xilinx/cells_map.v" + define);
 | 
				
			||||||
			Pass::call(design, "clean");
 | 
								run("clean");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_label(active, run_from, run_to, "map_luts"))
 | 
							if (check_label("map_luts")) {
 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			Pass::call(design, "techmap -map +/techmap.v -D _NO_POS_SR -map +/xilinx/ff_map.v");
 | 
					 | 
				
			||||||
			if (abc == "abc9")
 | 
								if (abc == "abc9")
 | 
				
			||||||
				Pass::call(design, abc + " -lut +/xilinx/abc.lut -box +/xilinx/abc.box" + string(retime ? " -dff" : ""));
 | 
									run(abc + " -lut +/xilinx/abc.lut -box +/xilinx/abc.box" + string(retime ? " -dff" : ""));
 | 
				
			||||||
 | 
								else if (help_mode)
 | 
				
			||||||
 | 
									run(abc + " -luts 2:2,3,6:5,10,20 [-dff]");
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				Pass::call(design, abc + " -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : ""));
 | 
									run(abc + " -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : ""));
 | 
				
			||||||
			Pass::call(design, "clean");
 | 
								run("clean");
 | 
				
			||||||
			// This shregmap call infers fixed length shift registers after abc
 | 
								// This shregmap call infers fixed length shift registers after abc
 | 
				
			||||||
			//   has performed any necessary retiming
 | 
								//   has performed any necessary retiming
 | 
				
			||||||
			if (!nosrl)
 | 
								if (!nosrl || help_mode)
 | 
				
			||||||
				Pass::call(design, "shregmap -minlen 3 -init -params -enpol any_or_none");
 | 
									run("shregmap -minlen 3 -init -params -enpol any_or_none", "(skip if '-nosrl')");
 | 
				
			||||||
			Pass::call(design, "techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v");
 | 
								run("techmap -map +/xilinx/lut_map.v -map +/xilinx/ff_map.v -map +/xilinx/cells_map.v");
 | 
				
			||||||
			Pass::call(design, "dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT "
 | 
								run("dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT "
 | 
				
			||||||
					"-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT");
 | 
										"-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT");
 | 
				
			||||||
 | 
								run("clean");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_label(active, run_from, run_to, "check"))
 | 
							if (check_label("check")) {
 | 
				
			||||||
		{
 | 
								run("hierarchy -check");
 | 
				
			||||||
			Pass::call(design, "hierarchy -check");
 | 
								run("stat");
 | 
				
			||||||
			Pass::call(design, "stat");
 | 
								run("check -noinit");
 | 
				
			||||||
			Pass::call(design, "check -noinit");
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (check_label(active, run_from, run_to, "edif"))
 | 
							if (check_label("edif")) {
 | 
				
			||||||
		{
 | 
								if (!edif_file.empty() || help_mode)
 | 
				
			||||||
			if (!edif_file.empty())
 | 
									run(stringf("write_edif -pvector bra %s", edif_file.c_str()));
 | 
				
			||||||
				Pass::call(design, stringf("write_edif -pvector bra %s", edif_file.c_str()));
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (check_label(active, run_from, run_to, "blif"))
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			if (!blif_file.empty())
 | 
					 | 
				
			||||||
				Pass::call(design, stringf("write_blif %s", edif_file.c_str()));
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		log_pop();
 | 
							if (check_label("blif")) {
 | 
				
			||||||
 | 
								if (!blif_file.empty() || help_mode)
 | 
				
			||||||
 | 
									run(stringf("write_blif %s", edif_file.c_str()));
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
} SynthXilinxPass;
 | 
					} SynthXilinxPass;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										22
									
								
								tests/memories/firrtl_938.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								tests/memories/firrtl_938.v
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,22 @@
 | 
				
			||||||
 | 
					module top
 | 
				
			||||||
 | 
					(
 | 
				
			||||||
 | 
						input [7:0] data_a,
 | 
				
			||||||
 | 
						input [6:1] addr_a,
 | 
				
			||||||
 | 
						input we_a, clk,
 | 
				
			||||||
 | 
						output reg [7:0] q_a
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
						// Declare the RAM variable
 | 
				
			||||||
 | 
						reg [7:0] ram[63:0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Port A
 | 
				
			||||||
 | 
						always @ (posedge clk)
 | 
				
			||||||
 | 
						begin
 | 
				
			||||||
 | 
							if (we_a)
 | 
				
			||||||
 | 
							begin
 | 
				
			||||||
 | 
								ram[addr_a] <= data_a;
 | 
				
			||||||
 | 
								q_a <= data_a;
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
								q_a <= ram[addr_a];
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					endmodule
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,7 @@ operators.v	$pow
 | 
				
			||||||
partsel.v	drops modules
 | 
					partsel.v	drops modules
 | 
				
			||||||
process.v	drops modules
 | 
					process.v	drops modules
 | 
				
			||||||
realexpr.v	drops modules
 | 
					realexpr.v	drops modules
 | 
				
			||||||
 | 
					retime.v	Initial value (11110101) for (retime_test.ff) not supported
 | 
				
			||||||
scopes.v	original verilog issues ( -x where x isn't declared signed)
 | 
					scopes.v	original verilog issues ( -x where x isn't declared signed)
 | 
				
			||||||
sincos.v	$adff
 | 
					sincos.v	$adff
 | 
				
			||||||
specify.v	no code (empty module generates error
 | 
					specify.v	no code (empty module generates error
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue