mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-06 22:23:23 +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,13 +173,14 @@ static std::string next_token(bool pass_newline = false)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char *ok = "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ$0123456789";
|
const char *ok = "abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ$0123456789";
|
||||||
while ((ch = next_char()) != 0) {
|
if (ch == '`' || strchr(ok, ch) != NULL)
|
||||||
if (strchr(ok, ch) == NULL) {
|
while ((ch = next_char()) != 0) {
|
||||||
return_char(ch);
|
if (strchr(ok, ch) == NULL) {
|
||||||
break;
|
return_char(ch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
token += ch;
|
||||||
}
|
}
|
||||||
token += ch;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return token;
|
return token;
|
||||||
|
@ -289,27 +293,48 @@ 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 (tok == "\n") {
|
if (state == 0 && tok == "(") {
|
||||||
return_char('\n');
|
state = 1;
|
||||||
break;
|
skip_spaces();
|
||||||
}
|
|
||||||
if (tok == "\\") {
|
|
||||||
char ch = next_char();
|
|
||||||
if (ch == '\n') {
|
|
||||||
value += " ";
|
|
||||||
newline_count++;
|
|
||||||
} else {
|
|
||||||
value += std::string("\\");
|
|
||||||
return_char(ch);
|
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
value += tok;
|
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;
|
||||||
|
}
|
||||||
|
if (tok == "\\") {
|
||||||
|
char ch = next_char();
|
||||||
|
if (ch == '\n') {
|
||||||
|
value += " ";
|
||||||
|
newline_count++;
|
||||||
|
} else {
|
||||||
|
value += std::string("\\");
|
||||||
|
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)
|
while (newline_count-- > 0)
|
||||||
return_char('\n');
|
return_char('\n');
|
||||||
|
@ -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