Merge pull request #3099 from YosysHQ/claire/readargs

Use "read" command to parse HDL files from Yosys command-line
This commit is contained in:
Claire Xen 2021-12-10 11:23:53 +01:00 committed by GitHub
commit ce82afe44f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 52 additions and 41 deletions

View File

@ -118,7 +118,7 @@ int main(int argc, char **argv)
if (argc == 2) if (argc == 2)
{ {
// Run the first argument as a script file // Run the first argument as a script file
run_frontend(argv[1], "script", 0, 0, 0); run_frontend(argv[1], "script");
} }
} }
@ -202,12 +202,13 @@ int main(int argc, char **argv)
std::string output_filename = ""; std::string output_filename = "";
std::string scriptfile = ""; std::string scriptfile = "";
std::string depsfile = ""; std::string depsfile = "";
std::string topmodule = "";
bool scriptfile_tcl = false; bool scriptfile_tcl = false;
bool got_output_filename = false;
bool print_banner = true; bool print_banner = true;
bool print_stats = true; bool print_stats = true;
bool call_abort = false; bool call_abort = false;
bool timing_details = false; bool timing_details = false;
bool run_shell = true;
bool mode_v = false; bool mode_v = false;
bool mode_q = false; bool mode_q = false;
@ -288,6 +289,9 @@ int main(int argc, char **argv)
printf(" -A\n"); printf(" -A\n");
printf(" will call abort() at the end of the script. for debugging\n"); printf(" will call abort() at the end of the script. for debugging\n");
printf("\n"); printf("\n");
printf(" -r <module_name>\n");
printf(" elaborate command line arguments using the specified top module\n");
printf("\n");
printf(" -D <macro>[=<value>]\n"); printf(" -D <macro>[=<value>]\n");
printf(" set the specified Verilog define (via \"read -define\")\n"); printf(" set the specified Verilog define (via \"read -define\")\n");
printf("\n"); printf("\n");
@ -342,7 +346,7 @@ int main(int argc, char **argv)
} }
int opt; int opt;
while ((opt = getopt(argc, argv, "MXAQTVSgm:f:Hh:b:o:p:l:L:qv:tds:c:W:w:e:D:P:E:x:")) != -1) while ((opt = getopt(argc, argv, "MXAQTVSgm:f:Hh:b:o:p:l:L:qv:tds:c:W:w:e:r:D:P:E:x:")) != -1)
{ {
switch (opt) switch (opt)
{ {
@ -384,13 +388,15 @@ int main(int argc, char **argv)
break; break;
case 'b': case 'b':
backend_command = optarg; backend_command = optarg;
run_shell = false;
break; break;
case 'p': case 'p':
passes_commands.push_back(optarg); passes_commands.push_back(optarg);
run_shell = false;
break; break;
case 'o': case 'o':
output_filename = optarg; output_filename = optarg;
got_output_filename = true; run_shell = false;
break; break;
case 'l': case 'l':
case 'L': case 'L':
@ -422,10 +428,12 @@ int main(int argc, char **argv)
case 's': case 's':
scriptfile = optarg; scriptfile = optarg;
scriptfile_tcl = false; scriptfile_tcl = false;
run_shell = false;
break; break;
case 'c': case 'c':
scriptfile = optarg; scriptfile = optarg;
scriptfile_tcl = true; scriptfile_tcl = true;
run_shell = false;
break; break;
case 'W': case 'W':
log_warn_regexes.push_back(YS_REGEX_COMPILE(optarg)); log_warn_regexes.push_back(YS_REGEX_COMPILE(optarg));
@ -436,6 +444,9 @@ int main(int argc, char **argv)
case 'e': case 'e':
log_werror_regexes.push_back(YS_REGEX_COMPILE(optarg)); log_werror_regexes.push_back(YS_REGEX_COMPILE(optarg));
break; break;
case 'r':
topmodule = optarg;
break;
case 'D': case 'D':
vlog_defines.push_back(optarg); vlog_defines.push_back(optarg);
break; break;
@ -506,12 +517,6 @@ int main(int argc, char **argv)
for (auto &fn : plugin_filenames) for (auto &fn : plugin_filenames)
load_plugin(fn, {}); load_plugin(fn, {});
if (optind == argc && passes_commands.size() == 0 && scriptfile.empty()) {
if (!got_output_filename)
backend_command = "";
shell(yosys_design);
}
if (!vlog_defines.empty()) { if (!vlog_defines.empty()) {
std::string vdef_cmd = "read -define"; std::string vdef_cmd = "read -define";
for (auto vdef : vlog_defines) for (auto vdef : vlog_defines)
@ -520,7 +525,11 @@ int main(int argc, char **argv)
} }
while (optind < argc) while (optind < argc)
run_frontend(argv[optind++], frontend_command, output_filename == "-" ? &backend_command : NULL); if (run_frontend(argv[optind++], frontend_command))
run_shell = false;
if (!topmodule.empty())
run_pass("hierarchy -top " + topmodule);
if (!scriptfile.empty()) { if (!scriptfile.empty()) {
if (scriptfile_tcl) { if (scriptfile_tcl) {
@ -531,13 +540,15 @@ int main(int argc, char **argv)
log_error("Can't exectue TCL script: this version of yosys is not built with TCL support enabled.\n"); log_error("Can't exectue TCL script: this version of yosys is not built with TCL support enabled.\n");
#endif #endif
} else } else
run_frontend(scriptfile, "script", output_filename == "-" ? &backend_command : NULL); run_frontend(scriptfile, "script");
} }
for (auto it = passes_commands.begin(); it != passes_commands.end(); it++) for (auto it = passes_commands.begin(); it != passes_commands.end(); it++)
run_pass(*it); run_pass(*it);
if (!backend_command.empty()) if (run_shell)
shell(yosys_design);
else
run_backend(output_filename, backend_command); run_backend(output_filename, backend_command);
yosys_design->check(); yosys_design->check();

View File

@ -956,7 +956,7 @@ static void handle_label(std::string &command, bool &from_to_active, const std::
} }
} }
void run_frontend(std::string filename, std::string command, std::string *backend_command, std::string *from_to_label, RTLIL::Design *design) bool run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *from_to_label)
{ {
if (design == nullptr) if (design == nullptr)
design = yosys_design; design = yosys_design;
@ -966,11 +966,11 @@ void run_frontend(std::string filename, std::string command, std::string *backen
if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".gz") == 0) if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".gz") == 0)
filename_trim.erase(filename_trim.size()-3); filename_trim.erase(filename_trim.size()-3);
if (filename_trim.size() > 2 && filename_trim.compare(filename_trim.size()-2, std::string::npos, ".v") == 0) if (filename_trim.size() > 2 && filename_trim.compare(filename_trim.size()-2, std::string::npos, ".v") == 0)
command = "verilog"; command = " -vlog2k";
else if (filename_trim.size() > 2 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".sv") == 0) else if (filename_trim.size() > 2 && filename_trim.compare(filename_trim.size()-3, std::string::npos, ".sv") == 0)
command = "verilog -sv"; command = " -sv";
else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".vhd") == 0) else if (filename_trim.size() > 3 && filename_trim.compare(filename_trim.size()-4, std::string::npos, ".vhd") == 0)
command = "vhdl"; command = " -vhdl";
else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-5, std::string::npos, ".blif") == 0) else if (filename_trim.size() > 4 && filename_trim.compare(filename_trim.size()-5, std::string::npos, ".blif") == 0)
command = "blif"; command = "blif";
else if (filename_trim.size() > 5 && filename_trim.compare(filename_trim.size()-6, std::string::npos, ".eblif") == 0) else if (filename_trim.size() > 5 && filename_trim.compare(filename_trim.size()-6, std::string::npos, ".eblif") == 0)
@ -1056,10 +1056,12 @@ void run_frontend(std::string filename, std::string command, std::string *backen
if (filename != "-") if (filename != "-")
fclose(f); fclose(f);
if (backend_command != NULL && *backend_command == "auto") return true;
*backend_command = ""; }
return; if (command == "tcl") {
Pass::call(design, vector<string>({command, filename}));
return true;
} }
if (filename == "-") { if (filename == "-") {
@ -1068,16 +1070,15 @@ void run_frontend(std::string filename, std::string command, std::string *backen
log("\n-- Parsing `%s' using frontend `%s' --\n", filename.c_str(), command.c_str()); log("\n-- Parsing `%s' using frontend `%s' --\n", filename.c_str(), command.c_str());
} }
if (command == "tcl") if (command[0] == ' ') {
Pass::call(design, vector<string>({command, filename})); auto argv = split_tokens("read" + command);
else argv.push_back(filename);
Pass::call(design, argv);
} else
Frontend::frontend_call(design, NULL, filename, command); Frontend::frontend_call(design, NULL, filename, command);
design->check();
}
void run_frontend(std::string filename, std::string command, RTLIL::Design *design) design->check();
{ return false;
run_frontend(filename, command, nullptr, nullptr, design);
} }
void run_pass(std::string command, RTLIL::Design *design) void run_pass(std::string command, RTLIL::Design *design)
@ -1391,7 +1392,7 @@ struct ScriptCmdPass : public Pass {
else if (args.size() == 2) else if (args.size() == 2)
run_frontend(args[1], "script", design); run_frontend(args[1], "script", design);
else if (args.size() == 3) else if (args.size() == 3)
run_frontend(args[1], "script", NULL, &args[2], design); run_frontend(args[1], "script", design, &args[2]);
else else
extra_args(args, 2, design, false); extra_args(args, 2, design, false);
} }

View File

@ -347,8 +347,7 @@ std::vector<std::string> glob_filename(const std::string &filename_pattern);
void rewrite_filename(std::string &filename); void rewrite_filename(std::string &filename);
void run_pass(std::string command, RTLIL::Design *design = nullptr); void run_pass(std::string command, RTLIL::Design *design = nullptr);
void run_frontend(std::string filename, std::string command, std::string *backend_command, std::string *from_to_label = nullptr, RTLIL::Design *design = nullptr); bool run_frontend(std::string filename, std::string command, RTLIL::Design *design = nullptr, std::string *from_to_label = nullptr);
void run_frontend(std::string filename, std::string command, RTLIL::Design *design = nullptr);
void run_backend(std::string filename, std::string command, RTLIL::Design *design = nullptr); void run_backend(std::string filename, std::string command, RTLIL::Design *design = nullptr);
void shell(RTLIL::Design *design); void shell(RTLIL::Design *design);

View File

@ -1,5 +1,5 @@
! ../../../yosys -qp "synth_xilinx" ../common/tribuf.v ../../../yosys -f verilog -qp "synth_xilinx" ../common/tribuf.v
../../../yosys -qp "synth_xilinx -iopad; \ ../../../yosys -f verilog -qp "synth_xilinx -iopad; \
select -assert-count 2 t:IBUF; \ select -assert-count 2 t:IBUF; \
select -assert-count 1 t:INV; \ select -assert-count 1 t:INV; \
select -assert-count 1 t:OBUFT" ../common/tribuf.v select -assert-count 1 t:OBUFT" ../common/tribuf.v

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
set -e set -e
../../yosys -qq -p "proc; opt; memory -nomap -bram temp/brams_${2}.txt; opt -fast -full" \ ../../yosys -qq -f verilog -p "proc; opt; memory -nomap -bram temp/brams_${2}.txt; opt -fast -full" \
-l temp/synth_${1}_${2}.log -o temp/synth_${1}_${2}.v temp/brams_${1}.v -l temp/synth_${1}_${2}.log -o temp/synth_${1}_${2}.v temp/brams_${1}.v
iverilog -Dvcd_file=\"temp/tb_${1}_${2}.vcd\" -DSIMLIB_MEMDELAY=1 -o temp/tb_${1}_${2}.tb temp/brams_${1}_tb.v \ iverilog -Dvcd_file=\"temp/tb_${1}_${2}.vcd\" -DSIMLIB_MEMDELAY=1 -o temp/tb_${1}_${2}.tb temp/brams_${1}_tb.v \
temp/brams_${1}_ref.v temp/synth_${1}_${2}.v temp/brams_${2}.v ../../techlibs/common/simlib.v temp/brams_${1}_ref.v temp/synth_${1}_${2}.v temp/brams_${2}.v ../../techlibs/common/simlib.v

View File

@ -18,7 +18,7 @@ ${MAKE:-make} -f ../tools/autotest.mk SEED="$seed" EXTRA_FLAGS="$abcopt" *.v
for f in `egrep -l 'expect-(wr-ports|rd-ports|rd-clk)' *.v`; do for f in `egrep -l 'expect-(wr-ports|rd-ports|rd-clk)' *.v`; do
echo -n "Testing expectations for $f .." echo -n "Testing expectations for $f .."
../../yosys -qp "proc; opt; memory -nomap;; dump -outfile ${f%.v}.dmp t:\$mem_v2" $f ../../yosys -f verilog -qp "proc; opt; memory -nomap;; dump -outfile ${f%.v}.dmp t:\$mem_v2" $f
if grep -q expect-wr-ports $f; then if grep -q expect-wr-ports $f; then
grep -q "parameter \\\\WR_PORTS $(gawk '/expect-wr-ports/ { print $3; }' $f)\$" ${f%.v}.dmp || grep -q "parameter \\\\WR_PORTS $(gawk '/expect-wr-ports/ { print $3; }' $f)\$" ${f%.v}.dmp ||
{ echo " ERROR: Unexpected number of write ports."; false; } { echo " ERROR: Unexpected number of write ports."; false; }

View File

@ -2,7 +2,7 @@
set -e set -e
../../yosys -b 'verilog -noattr' -o mem_simple_4x1_synth.v -p 'proc; opt; memory -nomap; techmap -map mem_simple_4x1_map.v;; techmap; opt; abc;; stat' mem_simple_4x1_uut.v ../../yosys -b 'verilog -noattr' -o mem_simple_4x1_synth.v -p 'read_verilog mem_simple_4x1_uut.v; proc; opt; memory -nomap; techmap -map mem_simple_4x1_map.v;; techmap; opt; abc;; stat'
iverilog -o mem_simple_4x1_gold_tb mem_simple_4x1_tb.v mem_simple_4x1_uut.v iverilog -o mem_simple_4x1_gold_tb mem_simple_4x1_tb.v mem_simple_4x1_uut.v
iverilog -o mem_simple_4x1_gate_tb mem_simple_4x1_tb.v mem_simple_4x1_synth.v mem_simple_4x1_cells.v iverilog -o mem_simple_4x1_gate_tb mem_simple_4x1_tb.v mem_simple_4x1_synth.v mem_simple_4x1_cells.v

View File

@ -1,3 +1,3 @@
set -e set -e
../../yosys -p 'hierarchy -top top; techmap -map recursive_map.v -max_iter 1; select -assert-count 2 t:sub; select -assert-count 2 t:bar' recursive.v ../../yosys -p 'read_verilog recursive.v; hierarchy -top top; techmap -map recursive_map.v -max_iter 1; select -assert-count 2 t:sub; select -assert-count 2 t:bar'

View File

@ -1,9 +1,9 @@
#!/bin/bash #!/bin/bash
set -ex set -ex
../../yosys -q -o async_syn.v -p 'synth; rename uut syn' async.v ../../yosys -q -o async_syn.v -r uut -p 'synth; rename uut syn' async.v
../../yosys -q -o async_prp.v -p 'prep; rename uut prp' async.v ../../yosys -q -o async_prp.v -r uut -p 'prep; rename uut prp' async.v
../../yosys -q -o async_a2s.v -p 'prep; async2sync; rename uut a2s' async.v ../../yosys -q -o async_a2s.v -r uut -p 'prep; async2sync; rename uut a2s' async.v
../../yosys -q -o async_ffl.v -p 'prep; clk2fflogic; rename uut ffl' async.v ../../yosys -q -o async_ffl.v -r uut -p 'prep; clk2fflogic; rename uut ffl' async.v
iverilog -o async_sim -DTESTBENCH async.v async_???.v iverilog -o async_sim -DTESTBENCH async.v async_???.v
vvp -N async_sim > async.out vvp -N async_sim > async.out
tail async.out tail async.out