mirror of
				https://github.com/YosysHQ/yosys
				synced 2025-10-28 10:19:26 +00:00 
			
		
		
		
	Added support for macro arguments
This commit is contained in:
		
							parent
							
								
									09bd82db21
								
							
						
					
					
						commit
						921064c200
					
				
					 2 changed files with 84 additions and 23 deletions
				
			
		|  | @ -76,8 +76,9 @@ static char next_char() | ||||||
| 	return ch == '\r' ? next_char() : ch; | 	return ch == '\r' ? next_char() : ch; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void skip_spaces() | static std::string skip_spaces() | ||||||
| { | { | ||||||
|  | 	std::string spaces; | ||||||
| 	while (1) { | 	while (1) { | ||||||
| 		char ch = next_char(); | 		char ch = next_char(); | ||||||
| 		if (ch == 0) | 		if (ch == 0) | ||||||
|  | @ -86,7 +87,9 @@ static void skip_spaces() | ||||||
| 			return_char(ch); | 			return_char(ch); | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
|  | 		spaces += ch; | ||||||
| 	} | 	} | ||||||
|  | 	return spaces; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static std::string next_token(bool pass_newline = false) | static std::string next_token(bool pass_newline = false) | ||||||
|  | @ -170,6 +173,7 @@ static std::string next_token(bool pass_newline = false) | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| 		const char *ok = "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ$0123456789"; | 		const char *ok = "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ$0123456789"; | ||||||
|  | 		if (ch == '`' || strchr(ok, ch) != NULL) | ||||||
| 			while ((ch = next_char()) != 0) { | 			while ((ch = next_char()) != 0) { | ||||||
| 				if (strchr(ok, ch) == NULL) { | 				if (strchr(ok, ch) == NULL) { | ||||||
| 					return_char(ch); | 					return_char(ch); | ||||||
|  | @ -289,12 +293,29 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m | ||||||
| 
 | 
 | ||||||
| 		if (tok == "`define") { | 		if (tok == "`define") { | ||||||
| 			std::string name, value; | 			std::string name, value; | ||||||
|  | 			std::map<std::string, int> args; | ||||||
| 			skip_spaces(); | 			skip_spaces(); | ||||||
| 			name = next_token(true); | 			name = next_token(true); | ||||||
| 			skip_spaces(); | 			skip_spaces(); | ||||||
| 			int newline_count = 0; | 			int newline_count = 0; | ||||||
|  | 			int state = 0; | ||||||
| 			while (!tok.empty()) { | 			while (!tok.empty()) { | ||||||
| 				tok = next_token(); | 				tok = next_token(); | ||||||
|  | 				if (state == 0 && tok == "(") { | ||||||
|  | 					state = 1; | ||||||
|  | 					skip_spaces(); | ||||||
|  | 				} else | ||||||
|  | 				if (state == 1) { | ||||||
|  | 					if (tok == ")") | ||||||
|  | 						state = 2; | ||||||
|  | 					else if (tok != ",") { | ||||||
|  | 						int arg_idx = args.size()+1; | ||||||
|  | 						args[tok] = arg_idx; | ||||||
|  | 					} | ||||||
|  | 					skip_spaces(); | ||||||
|  | 				} else { | ||||||
|  | 					if (state != 2) | ||||||
|  | 						state = 3; | ||||||
| 					if (tok == "\n") { | 					if (tok == "\n") { | ||||||
| 						return_char('\n'); | 						return_char('\n'); | ||||||
| 						break; | 						break; | ||||||
|  | @ -309,8 +330,12 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m | ||||||
| 							return_char(ch); | 							return_char(ch); | ||||||
| 						} | 						} | ||||||
| 					} else | 					} else | ||||||
|  | 					if (args.count(tok) > 0) | ||||||
|  | 						value += stringf("`macro_%s_arg%d", name.c_str(), args.at(tok)); | ||||||
|  | 					else | ||||||
| 						value += tok; | 						value += tok; | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
| 			while (newline_count-- > 0) | 			while (newline_count-- > 0) | ||||||
| 				return_char('\n'); | 				return_char('\n'); | ||||||
| 			// printf("define: >>%s<< -> >>%s<<\n", name.c_str(), value.c_str());
 | 			// printf("define: >>%s<< -> >>%s<<\n", name.c_str(), value.c_str());
 | ||||||
|  | @ -338,8 +363,35 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (tok.size() > 1 && tok[0] == '`' && defines_map.count(tok.substr(1)) > 0) { | 		if (tok.size() > 1 && tok[0] == '`' && defines_map.count(tok.substr(1)) > 0) { | ||||||
| 			// printf("expand: >>%s<< -> >>%s<<\n", tok.c_str(), defines_map[tok.substr(1)].c_str());
 | 			std::string name = tok.substr(1); | ||||||
| 			insert_input(defines_map[tok.substr(1)]); | 			// printf("expand: >>%s<< -> >>%s<<\n", name.c_str(), defines_map[name].c_str());
 | ||||||
|  | 			std::string skipped_spaces = skip_spaces(); | ||||||
|  | 			tok = next_token(true); | ||||||
|  | 			if (tok == "(") { | ||||||
|  | 				int level = 1; | ||||||
|  | 				std::vector<std::string> args; | ||||||
|  | 				args.push_back(std::string()); | ||||||
|  | 				while (1) | ||||||
|  | 				{ | ||||||
|  | 					tok = next_token(true); | ||||||
|  | 					if (tok == ")" || tok == "}" || tok == "]") | ||||||
|  | 						level--; | ||||||
|  | 					if (level == 0) | ||||||
|  | 						break; | ||||||
|  | 					if (level == 1 && tok == ",") | ||||||
|  | 						args.push_back(std::string()); | ||||||
|  | 					else | ||||||
|  | 						args.back() += tok; | ||||||
|  | 					if (tok == "(" || tok == "{" || tok == "[") | ||||||
|  | 						level++; | ||||||
|  | 				} | ||||||
|  | 				for (size_t i = 0; i < args.size(); i++) | ||||||
|  | 					defines_map[stringf("macro_%s_arg%d", name.c_str(), i+1)] = args[i]; | ||||||
|  | 			} else { | ||||||
|  | 				insert_input(tok); | ||||||
|  | 				insert_input(skipped_spaces); | ||||||
|  | 			} | ||||||
|  | 			insert_input(defines_map[name]); | ||||||
| 			continue; | 			continue; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										9
									
								
								tests/simple/macros.v
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								tests/simple/macros.v
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,9 @@ | ||||||
|  | module test(a, y); | ||||||
|  | `define MSB_LSB_SEP : | ||||||
|  | `define get_msb(off, len) ((off)+(len)-1) | ||||||
|  | `define get_lsb(off, len) (off) | ||||||
|  | `define sel_bits(offset, len) `get_msb(offset, len) `MSB_LSB_SEP `get_lsb(offset, len) | ||||||
|  | input [31:0] a; | ||||||
|  | output [7:0] y; | ||||||
|  | assign y = a[`sel_bits(16, 8)]; | ||||||
|  | endmodule | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue