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: |       env: | ||||||
|         - MATRIX_EVAL="CONFIG=clang && CC=clang-5.0 && CXX=clang++-5.0" |         - MATRIX_EVAL="CONFIG=clang && CC=clang-5.0 && CXX=clang++-5.0" | ||||||
| 
 | 
 | ||||||
|     # Latest clang on Mac OS X | #   # Latest clang on Mac OS X | ||||||
|     - os: osx | #   - os: osx | ||||||
|       osx_image: xcode9.4 | #     osx_image: xcode9.4 | ||||||
|       env: | #     env: | ||||||
|         - MATRIX_EVAL="CONFIG=clang && CC=clang && CXX=clang++" | #       - MATRIX_EVAL="CONFIG=clang && CC=clang && CXX=clang++" | ||||||
| 
 | 
 | ||||||
| before_install: | before_install: | ||||||
|   - ./.travis/setup.sh |   - ./.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). | 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: | 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 | Setup | ||||||
| ====== | ====== | ||||||
|  | @ -296,6 +309,9 @@ Verilog Attributes and non-standard features | ||||||
|   passes to identify input and output ports of cells. The Verilog backend |   passes to identify input and output ports of cells. The Verilog backend | ||||||
|   also does not output blackbox modules on default. |   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 | - 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 |   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. |   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 port_rename = false; | ||||||
| 		bool attr_properties = false; | 		bool attr_properties = false; | ||||||
| 		std::map<RTLIL::IdString, std::map<RTLIL::IdString, int>> lib_cell_ports; | 		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); | 		CellTypes ct(design); | ||||||
| 		EdifNames edif_names; | 		EdifNames edif_names; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -15,6 +15,7 @@ new_project \ | ||||||
| import_files -hdl_source {netlist.vm} | import_files -hdl_source {netlist.vm} | ||||||
| import_files -sdc {example.sdc} | import_files -sdc {example.sdc} | ||||||
| import_files -io_pdc {example.pdc} | import_files -io_pdc {example.pdc} | ||||||
|  | build_design_hierarchy | ||||||
| set_option -synth 0 | set_option -synth 0 | ||||||
| 
 | 
 | ||||||
| organize_tool_files -tool PLACEROUTE \ | organize_tool_files -tool PLACEROUTE \ | ||||||
|  | @ -32,22 +33,25 @@ configure_tool -name PLACEROUTE \ | ||||||
|     -params EFFORT_LEVEL:false \ |     -params EFFORT_LEVEL:false \ | ||||||
|     -params REPAIR_MIN_DELAY:false |     -params REPAIR_MIN_DELAY:false | ||||||
| 
 | 
 | ||||||
|  | puts "" | ||||||
| puts "**> COMPILE" | puts "**> COMPILE" | ||||||
| run_tool -name {COMPILE} | run_tool -name {COMPILE} | ||||||
| puts "<** COMPILE" | puts "<** COMPILE" | ||||||
| 
 | 
 | ||||||
|  | puts "" | ||||||
| puts "**> PLACEROUTE" | puts "**> PLACEROUTE" | ||||||
| run_tool -name {PLACEROUTE} | run_tool -name {PLACEROUTE} | ||||||
| puts "<** PLACEROUTE" | puts "<** PLACEROUTE" | ||||||
| 
 | 
 | ||||||
|  | puts "" | ||||||
| puts "**> VERIFYTIMING" | puts "**> VERIFYTIMING" | ||||||
| run_tool -name {VERIFYTIMING} | run_tool -name {VERIFYTIMING} | ||||||
| puts "<** VERIFYTIMING" | puts "<** VERIFYTIMING" | ||||||
| 
 | 
 | ||||||
| save_project | puts "" | ||||||
| 
 | puts "**> BITSTREAM" | ||||||
| # puts "**> export_bitstream" | export_bitstream_file -trusted_facility_file 1 -trusted_facility_file_components {FABRIC} | ||||||
| # export_bitstream_file -trusted_facility_file 1 -trusted_facility_file_components {FABRIC} | puts "<** BITSTREAM" | ||||||
| # puts "<** export_bitstream" |  | ||||||
| 
 | 
 | ||||||
|  | puts "" | ||||||
| exit 0 | exit 0 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,6 @@ | ||||||
| #!/bin/bash | #!/bin/bash | ||||||
| set -ex | set -ex | ||||||
| yosys -p 'synth_sf2 -top example -edif netlist.edn -vlog netlist.vm' example.v | 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_SET_ASYNC = 0x00000800, | ||||||
| 			MEM2REG_FL_EQ2       = 0x00001000, | 			MEM2REG_FL_EQ2       = 0x00001000, | ||||||
| 			MEM2REG_FL_CMPLX_LHS = 0x00002000, | 			MEM2REG_FL_CMPLX_LHS = 0x00002000, | ||||||
|  | 			MEM2REG_FL_CONST_LHS = 0x00004000, | ||||||
|  | 			MEM2REG_FL_VAR_LHS   = 0x00008000, | ||||||
| 
 | 
 | ||||||
| 			/* proc flags */ | 			/* proc flags */ | ||||||
| 			MEM2REG_FL_EQ1       = 0x01000000, | 			MEM2REG_FL_EQ1       = 0x01000000, | ||||||
|  | @ -237,6 +239,7 @@ namespace AST | ||||||
| 		bool has_const_only_constructs(bool &recommend_const_eval); | 		bool has_const_only_constructs(bool &recommend_const_eval); | ||||||
| 		void replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall); | 		void replace_variables(std::map<std::string, varinfo_t> &variables, AstNode *fcall); | ||||||
| 		AstNode *eval_const_function(AstNode *fcall); | 		AstNode *eval_const_function(AstNode *fcall); | ||||||
|  | 		bool is_simple_const_expr(); | ||||||
| 
 | 
 | ||||||
| 		// create a human-readable text representation of the AST (for debugging)
 | 		// create a human-readable text representation of the AST (for debugging)
 | ||||||
| 		void dumpAst(FILE *f, std::string indent) const; | 		void dumpAst(FILE *f, std::string indent) const; | ||||||
|  |  | ||||||
|  | @ -544,7 +544,11 @@ struct AST_INTERNAL::ProcessGenerator | ||||||
| 			break; | 			break; | ||||||
| 
 | 
 | ||||||
| 		case AST_WIRE: | 		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; | 			break; | ||||||
| 
 | 
 | ||||||
| 		case AST_PARAMETER: | 		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) | 				if (memflags & AstNode::MEM2REG_FL_CMPLX_LHS) | ||||||
| 					goto verbose_activate; | 					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));
 | 				// log("Note: Not replacing memory %s with list of registers (flags=0x%08lx).\n", mem->str.c_str(), long(memflags));
 | ||||||
| 				continue; | 				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++) { | 		for (size_t i = 0; i < children.size(); i++) { | ||||||
| 			AstNode *node = children[i]; | 			AstNode *node = children[i]; | ||||||
| 			if (node->type == AST_WIRE) { | 			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) { | 				if (this_wire_scope.count(node->str) > 0) { | ||||||
| 					AstNode *first_node = this_wire_scope[node->str]; | 					AstNode *first_node = this_wire_scope[node->str]; | ||||||
| 					if (first_node->is_input && node->is_reg) | 					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 (current_scope.count(str) == 0) { | ||||||
| 			if (flag_autowire) { | 			if (flag_autowire || str == "\\$global_clock") { | ||||||
| 				AstNode *auto_wire = new AstNode(AST_AUTOWIRE); | 				AstNode *auto_wire = new AstNode(AST_AUTOWIRE); | ||||||
| 				auto_wire->str = str; | 				auto_wire->str = str; | ||||||
| 				current_ast_mod->children.push_back(auto_wire); | 				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); | 				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; | 				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; | 				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
 | 			// remember where this is
 | ||||||
| 			if (flags & MEM2REG_FL_INIT) { | 			if (flags & MEM2REG_FL_INIT) { | ||||||
| 				if (!(mem2reg_candidates[mem] & AstNode::MEM2REG_FL_SET_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) | 	if (type == AST_FUNCTION || type == AST_TASK) | ||||||
| 		return false; | 		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 (type == AST_ASSIGN && block == NULL && children[0]->mem2reg_check(mem2reg_set)) | ||||||
| 	{ | 	{ | ||||||
| 		if (async_block == NULL) { | 		if (async_block == NULL) { | ||||||
|  | @ -3277,6 +3332,16 @@ bool AstNode::has_const_only_constructs(bool &recommend_const_eval) | ||||||
| 	return false; | 	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()
 | // helper function for AstNode::eval_const_function()
 | ||||||
| void AstNode::replace_variables(std::map<std::string, AstNode::varinfo_t> &variables, AstNode *fcall) | 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) | 			if (m == nullptr) | ||||||
| 				continue; | 				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); | 				IdString new_m_name = m->derive(design, cell->parameters, true); | ||||||
| 				if (new_m_name.empty()) | 				if (new_m_name.empty()) | ||||||
| 					continue; | 					continue; | ||||||
|  |  | ||||||
|  | @ -5,4 +5,4 @@ EXTRA_OBJS += passes/pmgen/ice40_dsp_pm.h | ||||||
| .SECONDARY: 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 | 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] | pmgfile = sys.argv[1] | ||||||
| assert pmgfile.endswith(".pmg") | assert pmgfile.endswith(".pmg") | ||||||
| prefix = pmgfile[0:-4] | prefix = pmgfile[0:-4] | ||||||
| pmname = prefix.split('/')[-1] | prefix = prefix.split('/')[-1] | ||||||
|  | outfile = sys.argv[2] | ||||||
| 
 | 
 | ||||||
| state_types = dict() | state_types = dict() | ||||||
| udata_types = dict() | udata_types = dict() | ||||||
|  | @ -179,7 +180,7 @@ with open(pmgfile, "r") as f: | ||||||
| 
 | 
 | ||||||
|             blocks.append(block) |             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("// Generated by pmgen.py from {}.pgm".format(prefix), file=f) | ||||||
|     print("", 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("YOSYS_NAMESPACE_BEGIN", file=f) | ||||||
|     print("", 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("  Module *module;", file=f) | ||||||
|     print("  SigMap sigmap;", 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) |     print("", file=f) | ||||||
| 
 | 
 | ||||||
|     for index in range(len(blocks)): |     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("", 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) |     print("      module(module), sigmap(module) {", file=f) | ||||||
|     for s, t in sorted(udata_types.items()): |     for s, t in sorted(udata_types.items()): | ||||||
|         if t.endswith("*"): |         if t.endswith("*"): | ||||||
|  | @ -321,7 +322,7 @@ with open("%s_pm.h" % prefix, "w") as f: | ||||||
|     print("  }", file=f) |     print("  }", file=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("    for (auto cell : autoremove_cells)", file=f) | ||||||
|     print("      module->remove(cell);", file=f) |     print("      module->remove(cell);", file=f) | ||||||
|     print("  }", 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("", 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("    run([&](){on_accept_f(*this);});", file=f) | ||||||
|     print("  }", file=f) |     print("  }", 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 muxlsr = (LSRMUX == "INV") ? ~LSR : LSR; | ||||||
| 	wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK; | 	wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK; | ||||||
|  | 	wire srval; | ||||||
| 	generate | 	generate | ||||||
| 		if (LSRMODE == "PRLD") | 		if (LSRMODE == "PRLD") | ||||||
| 			wire srval = M; | 			assign srval = M; | ||||||
| 		else | 		else | ||||||
| 			localparam srval = (REGSET == "SET") ? 1'b1 : 1'b0; | 			assign srval = (REGSET == "SET") ? 1'b1 : 1'b0; | ||||||
| 	endgenerate | 	endgenerate | ||||||
| 
 | 
 | ||||||
| 	initial Q = srval; | 	initial Q = srval; | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue