mirror of https://github.com/YosysHQ/yosys.git
Added support for macro arguments
This commit is contained in:
parent
09bd82db21
commit
921064c200
|
@ -76,8 +76,9 @@ static char next_char()
|
|||
return ch == '\r' ? next_char() : ch;
|
||||
}
|
||||
|
||||
static void skip_spaces()
|
||||
static std::string skip_spaces()
|
||||
{
|
||||
std::string spaces;
|
||||
while (1) {
|
||||
char ch = next_char();
|
||||
if (ch == 0)
|
||||
|
@ -86,7 +87,9 @@ static void skip_spaces()
|
|||
return_char(ch);
|
||||
break;
|
||||
}
|
||||
spaces += ch;
|
||||
}
|
||||
return spaces;
|
||||
}
|
||||
|
||||
static std::string next_token(bool pass_newline = false)
|
||||
|
@ -170,6 +173,7 @@ static std::string next_token(bool pass_newline = false)
|
|||
else
|
||||
{
|
||||
const char *ok = "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ$0123456789";
|
||||
if (ch == '`' || strchr(ok, ch) != NULL)
|
||||
while ((ch = next_char()) != 0) {
|
||||
if (strchr(ok, ch) == NULL) {
|
||||
return_char(ch);
|
||||
|
@ -289,12 +293,29 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m
|
|||
|
||||
if (tok == "`define") {
|
||||
std::string name, value;
|
||||
std::map<std::string, int> args;
|
||||
skip_spaces();
|
||||
name = next_token(true);
|
||||
skip_spaces();
|
||||
int newline_count = 0;
|
||||
int state = 0;
|
||||
while (!tok.empty()) {
|
||||
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") {
|
||||
return_char('\n');
|
||||
break;
|
||||
|
@ -309,8 +330,12 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m
|
|||
return_char(ch);
|
||||
}
|
||||
} else
|
||||
if (args.count(tok) > 0)
|
||||
value += stringf("`macro_%s_arg%d", name.c_str(), args.at(tok));
|
||||
else
|
||||
value += tok;
|
||||
}
|
||||
}
|
||||
while (newline_count-- > 0)
|
||||
return_char('\n');
|
||||
// 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) {
|
||||
// printf("expand: >>%s<< -> >>%s<<\n", tok.c_str(), defines_map[tok.substr(1)].c_str());
|
||||
insert_input(defines_map[tok.substr(1)]);
|
||||
std::string name = 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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…
Reference in New Issue