mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-29 18:52:30 +00:00 
			
		
		
		
	Merge remote-tracking branch 'upstream/master'
This commit is contained in:
		
						commit
						6d2ea6fe55
					
				
					 12 changed files with 124 additions and 28 deletions
				
			
		
							
								
								
									
										10
									
								
								.travis.yml
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								.travis.yml
									
										
									
									
									
								
							|  | @ -132,11 +132,11 @@ matrix: | |||
|       env: | ||||
|         - MATRIX_EVAL="CONFIG=clang && CC=clang-5.0 && CXX=clang++-5.0" | ||||
| 
 | ||||
|     # Latest clang on Mac OS X | ||||
|     - os: osx | ||||
|       osx_image: xcode9.4 | ||||
|       env: | ||||
|         - MATRIX_EVAL="CONFIG=clang && CC=clang && CXX=clang++" | ||||
| #   # Latest clang on Mac OS X | ||||
| #   - os: osx | ||||
| #     osx_image: xcode9.4 | ||||
| #     env: | ||||
| #       - MATRIX_EVAL="CONFIG=clang && CC=clang && CXX=clang++" | ||||
| 
 | ||||
| before_install: | ||||
|   - ./.travis/setup.sh | ||||
|  |  | |||
							
								
								
									
										22
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								README.md
									
										
									
									
									
								
							|  | @ -34,11 +34,24 @@ compatible license that is similar in terms to the MIT license | |||
| or the 2-clause BSD license). | ||||
| 
 | ||||
| 
 | ||||
| Web Site | ||||
| ======== | ||||
| Web Site and Other Resources | ||||
| ============================ | ||||
| 
 | ||||
| More information and documentation can be found on the Yosys web site: | ||||
| http://www.clifford.at/yosys/ | ||||
| - http://www.clifford.at/yosys/ | ||||
| 
 | ||||
| The "Documentation" page on the web site contains links to more resources, | ||||
| including a manual that even describes some of the Yosys internals: | ||||
| - http://www.clifford.at/yosys/documentation.html | ||||
| 
 | ||||
| The file `CodingReadme` in this directory contains additional information | ||||
| for people interested in using the Yosys C++ APIs. | ||||
| 
 | ||||
| Users interested in formal verification might want to use the formal verification | ||||
| front-end for Yosys, SymbiYosys: | ||||
| - https://symbiyosys.readthedocs.io/en/latest/ | ||||
| - https://github.com/YosysHQ/SymbiYosys | ||||
| 
 | ||||
| 
 | ||||
| Setup | ||||
| ====== | ||||
|  | @ -296,6 +309,9 @@ Verilog Attributes and non-standard features | |||
|   passes to identify input and output ports of cells. The Verilog backend | ||||
|   also does not output blackbox modules on default. | ||||
| 
 | ||||
| - The ``dynports'' attribute is used by the Verilog front-end to mark modules | ||||
|   that have ports with a width that depends on a parameter. | ||||
| 
 | ||||
| - The ``keep`` attribute on cells and wires is used to mark objects that should | ||||
|   never be removed by the optimizer. This is used for example for cells that | ||||
|   have hidden connections that are not part of the netlist, such as IO pads. | ||||
|  |  | |||
|  | @ -130,7 +130,7 @@ struct EdifBackend : public Backend { | |||
| 		bool port_rename = false; | ||||
| 		bool attr_properties = false; | ||||
| 		std::map<RTLIL::IdString, std::map<RTLIL::IdString, int>> lib_cell_ports; | ||||
| 		bool nogndvcc = false, gndvccy = true; | ||||
| 		bool nogndvcc = false, gndvccy = false; | ||||
| 		CellTypes ct(design); | ||||
| 		EdifNames edif_names; | ||||
| 
 | ||||
|  |  | |||
|  | @ -15,6 +15,7 @@ new_project \ | |||
| import_files -hdl_source {netlist.vm} | ||||
| import_files -sdc {example.sdc} | ||||
| import_files -io_pdc {example.pdc} | ||||
| build_design_hierarchy | ||||
| set_option -synth 0 | ||||
| 
 | ||||
| organize_tool_files -tool PLACEROUTE \ | ||||
|  | @ -32,22 +33,25 @@ configure_tool -name PLACEROUTE \ | |||
|     -params EFFORT_LEVEL:false \ | ||||
|     -params REPAIR_MIN_DELAY:false | ||||
| 
 | ||||
| puts "" | ||||
| puts "**> COMPILE" | ||||
| run_tool -name {COMPILE} | ||||
| puts "<** COMPILE" | ||||
| 
 | ||||
| puts "" | ||||
| puts "**> PLACEROUTE" | ||||
| run_tool -name {PLACEROUTE} | ||||
| puts "<** PLACEROUTE" | ||||
| 
 | ||||
| puts "" | ||||
| puts "**> VERIFYTIMING" | ||||
| run_tool -name {VERIFYTIMING} | ||||
| puts "<** VERIFYTIMING" | ||||
| 
 | ||||
| save_project | ||||
| 
 | ||||
| # puts "**> export_bitstream" | ||||
| # export_bitstream_file -trusted_facility_file 1 -trusted_facility_file_components {FABRIC} | ||||
| # puts "<** export_bitstream" | ||||
| puts "" | ||||
| puts "**> BITSTREAM" | ||||
| export_bitstream_file -trusted_facility_file 1 -trusted_facility_file_components {FABRIC} | ||||
| puts "<** BITSTREAM" | ||||
| 
 | ||||
| puts "" | ||||
| exit 0 | ||||
|  |  | |||
|  | @ -1,4 +1,6 @@ | |||
| #!/bin/bash | ||||
| set -ex | ||||
| yosys -p 'synth_sf2 -top example -edif netlist.edn -vlog netlist.vm' example.v | ||||
| LM_LICENSE_FILE=1702@`hostname` /opt/microsemi/Libero_SoC_v11.9/Libero/bin/libero SCRIPT:libero.tcl | ||||
| export LM_LICENSE_FILE=${LM_LICENSE_FILE:-1702@localhost} | ||||
| /opt/microsemi/Libero_SoC_v12.0/Libero/bin/libero SCRIPT:libero.tcl | ||||
| cp proj/designer/example/export/example.stp . | ||||
|  |  | |||
|  | @ -214,6 +214,8 @@ namespace AST | |||
| 			MEM2REG_FL_SET_ASYNC = 0x00000800, | ||||
| 			MEM2REG_FL_EQ2       = 0x00001000, | ||||
| 			MEM2REG_FL_CMPLX_LHS = 0x00002000, | ||||
| 			MEM2REG_FL_CONST_LHS = 0x00004000, | ||||
| 			MEM2REG_FL_VAR_LHS   = 0x00008000, | ||||
| 
 | ||||
| 			/* proc flags */ | ||||
| 			MEM2REG_FL_EQ1       = 0x01000000, | ||||
|  | @ -237,6 +239,7 @@ namespace AST | |||
| 		bool has_const_only_constructs(bool &recommend_const_eval); | ||||
| 		void replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall); | ||||
| 		AstNode *eval_const_function(AstNode *fcall); | ||||
| 		bool is_simple_const_expr(); | ||||
| 
 | ||||
| 		// create a human-readable text representation of the AST (for debugging)
 | ||||
| 		void dumpAst(FILE *f, std::string indent) const; | ||||
|  |  | |||
|  | @ -544,7 +544,11 @@ struct AST_INTERNAL::ProcessGenerator | |||
| 			break; | ||||
| 
 | ||||
| 		case AST_WIRE: | ||||
| 			log_file_error(ast->filename, ast->linenum, "Found wire declaration in block without label!\n"); | ||||
| 			log_file_error(ast->filename, ast->linenum, "Found reg declaration in block without label!\n"); | ||||
| 			break; | ||||
| 
 | ||||
| 		case AST_ASSIGN: | ||||
| 			log_file_error(ast->filename, ast->linenum, "Found continous assignment in always/initial block!\n"); | ||||
| 			break; | ||||
| 
 | ||||
| 		case AST_PARAMETER: | ||||
|  |  | |||
|  | @ -113,6 +113,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 				if (memflags & AstNode::MEM2REG_FL_CMPLX_LHS) | ||||
| 					goto verbose_activate; | ||||
| 
 | ||||
| 				if ((memflags & AstNode::MEM2REG_FL_CONST_LHS) && !(memflags & AstNode::MEM2REG_FL_VAR_LHS)) | ||||
| 					goto verbose_activate; | ||||
| 
 | ||||
| 				// log("Note: Not replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
 | ||||
| 				continue; | ||||
| 
 | ||||
|  | @ -325,6 +328,15 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 		for (size_t i = 0; i < children.size(); i++) { | ||||
| 			AstNode *node = children[i]; | ||||
| 			if (node->type == AST_WIRE) { | ||||
| 				if (node->children.size() == 1 && node->children[0]->type == AST_RANGE) { | ||||
| 					for (auto c : node->children[0]->children) { | ||||
| 						if (!c->is_simple_const_expr()) { | ||||
| 							if (attributes.count("\\dynports")) | ||||
| 								delete attributes.at("\\dynports"); | ||||
| 							attributes["\\dynports"] = AstNode::mkconst_int(1, true); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 				if (this_wire_scope.count(node->str) > 0) { | ||||
| 					AstNode *first_node = this_wire_scope[node->str]; | ||||
| 					if (first_node->is_input && node->is_reg) | ||||
|  | @ -938,7 +950,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, | |||
| 			} | ||||
| 		} | ||||
| 		if (current_scope.count(str) == 0) { | ||||
| 			if (flag_autowire) { | ||||
| 			if (flag_autowire || str == "\\$global_clock") { | ||||
| 				AstNode *auto_wire = new AstNode(AST_AUTOWIRE); | ||||
| 				auto_wire->str = str; | ||||
| 				current_ast_mod->children.push_back(auto_wire); | ||||
|  | @ -2169,6 +2181,8 @@ skip_dynamic_range_lvalue_expansion:; | |||
| 				} | ||||
| 
 | ||||
| 				newNode = readmem(str == "\\$readmemh", node_filename->bitsAsConst().decode_string(), node_memory->id2ast, start_addr, finish_addr, unconditional_init); | ||||
| 				delete node_filename; | ||||
| 				delete node_memory; | ||||
| 				goto apply_newNode; | ||||
| 			} | ||||
| 
 | ||||
|  | @ -2936,6 +2950,14 @@ void AstNode::mem2reg_as_needed_pass1(dict<AstNode*, pool<std::string>> &mem2reg | |||
| 				proc_flags[mem] |= AstNode::MEM2REG_FL_EQ1; | ||||
| 			} | ||||
| 
 | ||||
| 			// remember if this is a constant index or not
 | ||||
| 			if (children[0]->children.size() && children[0]->children[0]->type == AST_RANGE && children[0]->children[0]->children.size()) { | ||||
| 				if (children[0]->children[0]->children[0]->type == AST_CONSTANT) | ||||
| 					mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_CONST_LHS; | ||||
| 				else | ||||
| 					mem2reg_candidates[mem] |= AstNode::MEM2REG_FL_VAR_LHS; | ||||
| 			} | ||||
| 
 | ||||
| 			// remember where this is
 | ||||
| 			if (flags & MEM2REG_FL_INIT) { | ||||
| 				if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_INIT)) | ||||
|  | @ -3048,6 +3070,39 @@ bool AstNode::mem2reg_as_needed_pass2(pool<AstNode*> &mem2reg_set, AstNode *mod, | |||
| 	if (type == AST_FUNCTION || type == AST_TASK) | ||||
| 		return false; | ||||
| 
 | ||||
| 	if (type == AST_MEMINIT && id2ast && mem2reg_set.count(id2ast)) | ||||
| 	{ | ||||
| 		log_assert(children[0]->type == AST_CONSTANT); | ||||
| 		log_assert(children[1]->type == AST_CONSTANT); | ||||
| 		log_assert(children[2]->type == AST_CONSTANT); | ||||
| 
 | ||||
| 		int cursor = children[0]->asInt(false); | ||||
| 		Const data = children[1]->bitsAsConst(); | ||||
| 		int length = children[2]->asInt(false); | ||||
| 
 | ||||
| 		if (length != 0) | ||||
| 		{ | ||||
| 			AstNode *block = new AstNode(AST_INITIAL, new AstNode(AST_BLOCK)); | ||||
| 			mod->children.push_back(block); | ||||
| 			block = block->children[0]; | ||||
| 
 | ||||
| 			int wordsz = GetSize(data) / length; | ||||
| 
 | ||||
| 			for (int i = 0; i < length; i++) { | ||||
| 				block->children.push_back(new AstNode(AST_ASSIGN_EQ, new AstNode(AST_IDENTIFIER, new AstNode(AST_RANGE, AstNode::mkconst_int(cursor+i, false))), mkconst_bits(data.extract(i*wordsz, wordsz).bits, false))); | ||||
| 				block->children.back()->children[0]->str = str; | ||||
| 				block->children.back()->children[0]->id2ast = id2ast; | ||||
| 				block->children.back()->children[0]->was_checked = true; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		AstNode *newNode = new AstNode(AST_NONE); | ||||
| 		newNode->cloneInto(this); | ||||
| 		delete newNode; | ||||
| 
 | ||||
| 		did_something = true; | ||||
| 	} | ||||
| 
 | ||||
| 	if (type == AST_ASSIGN && block == NULL && children[0]->mem2reg_check(mem2reg_set)) | ||||
| 	{ | ||||
| 		if (async_block == NULL) { | ||||
|  | @ -3277,6 +3332,16 @@ bool AstNode::has_const_only_constructs(bool &recommend_const_eval) | |||
| 	return false; | ||||
| } | ||||
| 
 | ||||
| bool AstNode::is_simple_const_expr() | ||||
| { | ||||
| 	if (type == AST_IDENTIFIER) | ||||
| 		return false; | ||||
| 	for (auto child : children) | ||||
| 		if (!child->is_simple_const_expr()) | ||||
| 			return false; | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| // helper function for AstNode::eval_const_function()
 | ||||
| void AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &variables, AstNode *fcall) | ||||
| { | ||||
|  |  | |||
|  | @ -910,7 +910,7 @@ struct HierarchyPass : public Pass { | |||
| 			if (m == nullptr) | ||||
| 				continue; | ||||
| 
 | ||||
| 			if (m->get_bool_attribute("\\blackbox") && !cell->parameters.empty()) { | ||||
| 			if (m->get_bool_attribute("\\blackbox") && !cell->parameters.empty() && m->get_bool_attribute("\\dynports")) { | ||||
| 				IdString new_m_name = m->derive(design, cell->parameters, true); | ||||
| 				if (new_m_name.empty()) | ||||
| 					continue; | ||||
|  |  | |||
|  | @ -5,4 +5,4 @@ EXTRA_OBJS += passes/pmgen/ice40_dsp_pm.h | |||
| .SECONDARY: passes/pmgen/ice40_dsp_pm.h | ||||
| 
 | ||||
| passes/pmgen/ice40_dsp_pm.h: passes/pmgen/pmgen.py passes/pmgen/ice40_dsp.pmg | ||||
| 	$(P) mkdir -p passes/pmgen && python3 $^ | ||||
| 	$(P) mkdir -p passes/pmgen && python3 $^ $@ | ||||
|  |  | |||
|  | @ -9,7 +9,8 @@ pp = pprint.PrettyPrinter(indent=4) | |||
| pmgfile = sys.argv[1] | ||||
| assert pmgfile.endswith(".pmg") | ||||
| prefix = pmgfile[0:-4] | ||||
| pmname = prefix.split('/')[-1] | ||||
| prefix = prefix.split('/')[-1] | ||||
| outfile = sys.argv[2] | ||||
| 
 | ||||
| state_types = dict() | ||||
| udata_types = dict() | ||||
|  | @ -179,7 +180,7 @@ with open(pmgfile, "r") as f: | |||
| 
 | ||||
|             blocks.append(block) | ||||
| 
 | ||||
| with open("%s_pm.h" % prefix, "w") as f: | ||||
| with open(outfile, "w") as f: | ||||
|     print("// Generated by pmgen.py from {}.pgm".format(prefix), file=f) | ||||
|     print("", file=f) | ||||
| 
 | ||||
|  | @ -190,10 +191,10 @@ with open("%s_pm.h" % prefix, "w") as f: | |||
|     print("YOSYS_NAMESPACE_BEGIN", file=f) | ||||
|     print("", file=f) | ||||
| 
 | ||||
|     print("struct {}_pm {{".format(pmname), file=f) | ||||
|     print("struct {}_pm {{".format(prefix), file=f) | ||||
|     print("  Module *module;", file=f) | ||||
|     print("  SigMap sigmap;", file=f) | ||||
|     print("  std::function<void()> on_accept;".format(pmname), file=f) | ||||
|     print("  std::function<void()> on_accept;".format(prefix), file=f) | ||||
|     print("", file=f) | ||||
| 
 | ||||
|     for index in range(len(blocks)): | ||||
|  | @ -291,7 +292,7 @@ with open("%s_pm.h" % prefix, "w") as f: | |||
|     print("  }", file=f) | ||||
|     print("", file=f) | ||||
| 
 | ||||
|     print("  {}_pm(Module *module, const vector<Cell*> &cells) :".format(pmname), file=f) | ||||
|     print("  {}_pm(Module *module, const vector<Cell*> &cells) :".format(prefix), file=f) | ||||
|     print("      module(module), sigmap(module) {", file=f) | ||||
|     for s, t in sorted(udata_types.items()): | ||||
|         if t.endswith("*"): | ||||
|  | @ -321,7 +322,7 @@ with open("%s_pm.h" % prefix, "w") as f: | |||
|     print("  }", file=f) | ||||
|     print("", file=f) | ||||
| 
 | ||||
|     print("  ~{}_pm() {{".format(pmname), file=f) | ||||
|     print("  ~{}_pm() {{".format(prefix), file=f) | ||||
|     print("    for (auto cell : autoremove_cells)", file=f) | ||||
|     print("      module->remove(cell);", file=f) | ||||
|     print("  }", file=f) | ||||
|  | @ -340,7 +341,7 @@ with open("%s_pm.h" % prefix, "w") as f: | |||
|     print("  }", file=f) | ||||
|     print("", file=f) | ||||
| 
 | ||||
|     print("  void run(std::function<void({}_pm&)> on_accept_f) {{".format(pmname), file=f) | ||||
|     print("  void run(std::function<void({}_pm&)> on_accept_f) {{".format(prefix), file=f) | ||||
|     print("    run([&](){on_accept_f(*this);});", file=f) | ||||
|     print("  }", file=f) | ||||
|     print("", file=f) | ||||
|  |  | |||
|  | @ -223,11 +223,12 @@ module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q); | |||
| 
 | ||||
| 	wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR; | ||||
| 	wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK; | ||||
| 	wire srval; | ||||
| 	generate | ||||
| 		if (LSRMODE == "PRLD") | ||||
| 			wire srval = M; | ||||
| 			assign srval = M; | ||||
| 		else | ||||
| 			localparam srval = (REGSET == "SET") ? 1'b1 : 1'b0; | ||||
| 			assign srval = (REGSET == "SET") ? 1'b1 : 1'b0; | ||||
| 	endgenerate | ||||
| 
 | ||||
| 	initial Q = srval; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue