mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-31 03:32:29 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into xaig_dff
This commit is contained in:
		
						commit
						35fd9b0473
					
				
					 7 changed files with 87 additions and 11 deletions
				
			
		|  | @ -12,6 +12,7 @@ Yosys 0.9 .. Yosys 0.9-dev | ||||||
|     - Added "synth_xilinx -abc9" (experimental) |     - Added "synth_xilinx -abc9" (experimental) | ||||||
|     - Added "synth_ice40 -abc9" (experimental) |     - Added "synth_ice40 -abc9" (experimental) | ||||||
|     - Added "synth -abc9" (experimental) |     - Added "synth -abc9" (experimental) | ||||||
|  |     - Added "script -scriptwire | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| Yosys 0.8 .. Yosys 0.8-dev | Yosys 0.8 .. Yosys 0.8-dev | ||||||
|  |  | ||||||
|  | @ -193,6 +193,8 @@ YOSYS_NAMESPACE_END | ||||||
|     to fix parsing of cells otherwise. (the current cell parser forces a reduce very early to update some |     to fix parsing of cells otherwise. (the current cell parser forces a reduce very early to update some | ||||||
|     global state.. its a mess) */ |     global state.. its a mess) */ | ||||||
| [a-zA-Z_$][a-zA-Z0-9_$]*/[ \t\r\n]*:[ \t\r\n]*(assert|assume|cover|restrict)[^a-zA-Z0-9_$\.] { | [a-zA-Z_$][a-zA-Z0-9_$]*/[ \t\r\n]*:[ \t\r\n]*(assert|assume|cover|restrict)[^a-zA-Z0-9_$\.] { | ||||||
|  | 	if (!strcmp(yytext, "default")) | ||||||
|  | 		return TOK_DEFAULT; | ||||||
| 	frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); | 	frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); | ||||||
| 	return TOK_SVA_LABEL; | 	return TOK_SVA_LABEL; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1254,24 +1254,55 @@ struct HistoryPass : public Pass { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| struct ScriptCmdPass : public Pass { | struct ScriptCmdPass : public Pass { | ||||||
| 	ScriptCmdPass() : Pass("script", "execute commands from script file") { } | 	ScriptCmdPass() : Pass("script", "execute commands from file or wire") { } | ||||||
| 	void help() YS_OVERRIDE { | 	void help() YS_OVERRIDE { | ||||||
|  | 		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
 | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("    script <filename> [<from_label>:<to_label>]\n"); | 		log("    script <filename> [<from_label>:<to_label>]\n"); | ||||||
|  | 		log("    script -scriptwire [selection]\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("This command executes the yosys commands in the specified file.\n"); | 		log("This command executes the yosys commands in the specified file (default\n"); | ||||||
|  | 		log("behaviour), or commands embedded in the constant text value connected to the\n"); | ||||||
|  | 		log("selected wires.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("The 2nd argument can be used to only execute the section of the\n"); | 		log("In the default (file) case, the 2nd argument can be used to only execute the\n"); | ||||||
| 		log("file between the specified labels. An empty from label is synonymous\n"); | 		log("section of the file between the specified labels. An empty from label is\n"); | ||||||
| 		log("for the beginning of the file and an empty to label is synonymous\n"); | 		log("synonymous with the beginning of the file and an empty to label is synonymous\n"); | ||||||
| 		log("for the end of the file.\n"); | 		log("with the end of the file.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 		log("If only one label is specified (without ':') then only the block\n"); | 		log("If only one label is specified (without ':') then only the block\n"); | ||||||
| 		log("marked with that label (until the next label) is executed.\n"); | 		log("marked with that label (until the next label) is executed.\n"); | ||||||
| 		log("\n"); | 		log("\n"); | ||||||
| 	} | 	} | ||||||
| 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE { | 	void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE | ||||||
| 		if (args.size() < 2) | 	{ | ||||||
|  | 		bool scriptwire = false; | ||||||
|  | 
 | ||||||
|  | 		size_t argidx; | ||||||
|  | 		for (argidx = 1; argidx < args.size(); argidx++) { | ||||||
|  | 			if (args[argidx] == "-scriptwire") { | ||||||
|  | 				scriptwire = true; | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			break; | ||||||
|  | 		} | ||||||
|  | 		if (scriptwire) { | ||||||
|  | 			extra_args(args, argidx, design); | ||||||
|  | 
 | ||||||
|  | 			for (auto mod : design->selected_modules()) | ||||||
|  | 				for (auto &c : mod->connections()) { | ||||||
|  | 					if (!c.first.is_wire()) | ||||||
|  | 						continue; | ||||||
|  | 					auto w = c.first.as_wire(); | ||||||
|  | 					if (!mod->selected(w)) | ||||||
|  | 						continue; | ||||||
|  | 					if (!c.second.is_fully_const()) | ||||||
|  | 						log_error("RHS of selected wire %s.%s is not constant.\n", log_id(mod), log_id(w)); | ||||||
|  | 					auto v = c.second.as_const(); | ||||||
|  | 					Pass::call_on_module(design, mod, v.decode_string()); | ||||||
|  | 				} | ||||||
|  | 		} | ||||||
|  | 		else if (args.size() < 2) | ||||||
| 			log_cmd_error("Missing script file.\n"); | 			log_cmd_error("Missing script file.\n"); | ||||||
| 		else if (args.size() == 2) | 		else if (args.size() == 2) | ||||||
| 			run_frontend(args[1], "script", design); | 			run_frontend(args[1], "script", design); | ||||||
|  |  | ||||||
|  | @ -17,6 +17,7 @@ | ||||||
|  * |  * | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | #include <algorithm> | ||||||
| #include "kernel/yosys.h" | #include "kernel/yosys.h" | ||||||
| #include "kernel/sigtools.h" | #include "kernel/sigtools.h" | ||||||
| 
 | 
 | ||||||
|  | @ -183,12 +184,12 @@ struct MemoryDffWorker | ||||||
| 		if (mux_cells_a.count(sig_data) || mux_cells_b.count(sig_data)) | 		if (mux_cells_a.count(sig_data) || mux_cells_b.count(sig_data)) | ||||||
| 		{ | 		{ | ||||||
| 			RTLIL::SigSpec en; | 			RTLIL::SigSpec en; | ||||||
| 			RTLIL::SigSpec check_q; | 			std::vector<RTLIL::SigSpec> check_q; | ||||||
| 
 | 
 | ||||||
| 			do { | 			do { | ||||||
| 				bool enable_invert = mux_cells_a.count(sig_data) != 0; | 				bool enable_invert = mux_cells_a.count(sig_data) != 0; | ||||||
| 				Cell *mux = enable_invert ? mux_cells_a.at(sig_data) : mux_cells_b.at(sig_data); | 				Cell *mux = enable_invert ? mux_cells_a.at(sig_data) : mux_cells_b.at(sig_data); | ||||||
| 				check_q = sigmap(mux->getPort(enable_invert ? "\\B" : "\\A")); | 				check_q.push_back(sigmap(mux->getPort(enable_invert ? "\\B" : "\\A"))); | ||||||
| 				sig_data = sigmap(mux->getPort("\\Y")); | 				sig_data = sigmap(mux->getPort("\\Y")); | ||||||
| 				en.append(enable_invert ? module->LogicNot(NEW_ID, mux->getPort("\\S")) : mux->getPort("\\S")); | 				en.append(enable_invert ? module->LogicNot(NEW_ID, mux->getPort("\\S")) : mux->getPort("\\S")); | ||||||
| 			} while (mux_cells_a.count(sig_data) || mux_cells_b.count(sig_data)); | 			} while (mux_cells_a.count(sig_data) || mux_cells_b.count(sig_data)); | ||||||
|  | @ -197,7 +198,8 @@ struct MemoryDffWorker | ||||||
| 				if (sigbit_users_count[bit] > 1) | 				if (sigbit_users_count[bit] > 1) | ||||||
| 					goto skip_ff_after_read_merging; | 					goto skip_ff_after_read_merging; | ||||||
| 
 | 
 | ||||||
| 			if (find_sig_before_dff(sig_data, clk_data, clk_polarity, true) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx) && sig_data == check_q) | 			if (find_sig_before_dff(sig_data, clk_data, clk_polarity, true) && clk_data != RTLIL::SigSpec(RTLIL::State::Sx) && | ||||||
|  | 					std::all_of(check_q.begin(), check_q.end(), [&](const SigSpec &cq) {return cq == sig_data; })) | ||||||
| 			{ | 			{ | ||||||
| 				disconnect_dff(sig_data); | 				disconnect_dff(sig_data); | ||||||
| 				cell->setPort("\\CLK", clk_data); | 				cell->setPort("\\CLK", clk_data); | ||||||
|  |  | ||||||
							
								
								
									
										16
									
								
								tests/memories/read_two_mux.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								tests/memories/read_two_mux.v
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | ||||||
|  | // expect-wr-ports 1 | ||||||
|  | // expect-rd-ports 1 | ||||||
|  | // expect-no-rd-clk | ||||||
|  | 
 | ||||||
|  | module top(input clk, input we, re, reset, input [7:0] addr, wdata, output reg [7:0] rdata); | ||||||
|  | 
 | ||||||
|  | reg [7:0] bram[0:255]; | ||||||
|  | (* keep *) reg dummy; | ||||||
|  | 
 | ||||||
|  | always @(posedge clk) begin | ||||||
|  | 	rdata <= re ? (reset ? 8'b0 : bram[addr]) : rdata; | ||||||
|  | 	if (we) | ||||||
|  | 		bram[addr] <= wdata; | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | endmodule | ||||||
|  | @ -31,6 +31,10 @@ for f in `egrep -l 'expect-(wr-ports|rd-ports|rd-clk)' *.v`; do | ||||||
| 		grep -q "connect \\\\RD_CLK \\$(gawk '/expect-rd-clk/ { print $3; }' $f)\$" ${f%.v}.dmp || | 		grep -q "connect \\\\RD_CLK \\$(gawk '/expect-rd-clk/ { print $3; }' $f)\$" ${f%.v}.dmp || | ||||||
| 				{ echo " ERROR: Unexpected read clock."; false; } | 				{ echo " ERROR: Unexpected read clock."; false; } | ||||||
| 	fi | 	fi | ||||||
|  | 	if grep -q expect-no-rd-clk $f; then | ||||||
|  | 		grep -q "connect \\\\RD_CLK 1'x\$" ${f%.v}.dmp || | ||||||
|  | 				{ echo " ERROR: Expected no read clock."; false; } | ||||||
|  | 	fi | ||||||
| 	echo " ok." | 	echo " ok." | ||||||
| done | done | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										20
									
								
								tests/various/script.ys
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								tests/various/script.ys
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | ||||||
|  | read_verilog -formal <<EOT | ||||||
|  |     module top; | ||||||
|  |         foo bar(); | ||||||
|  |         foo asdf(); | ||||||
|  |         winnie the_pooh(); | ||||||
|  | 
 | ||||||
|  |         wire [1023:0] _RUNME0 = "select -assert-count 2 t:foo"; | ||||||
|  |         wire [1023:0] _RUNME1 = "select -assert-count 1 t:winnie"; | ||||||
|  |     endmodule | ||||||
|  | 
 | ||||||
|  |     module other; | ||||||
|  |         wire [1023:0] _DELETE = "cd; delete c:bar"; | ||||||
|  |     endmodule | ||||||
|  | EOT | ||||||
|  | 
 | ||||||
|  | script -scriptwire w:_RUNME* | ||||||
|  | 
 | ||||||
|  | select w:_DELETE | ||||||
|  | script -scriptwire | ||||||
|  | select -assert-count 1 t:foo | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue