static int make_cmd(int argc, char **argv) { set_work_lib(); static struct option long_options[] = { { "deps-only", no_argument, 0, 'd' }, { "native", no_argument, 0, 'n' }, { "posix", no_argument, 0, 'p' }, { 0, 0, 0, 0 } }; int c, index = 0; const char *spec = ""; optind = 1; while ((c = getopt_long(argc, argv, spec, long_options, &index)) != -1) { switch (c) { case 0: // Set a flag break; case '?': // getopt_long already printed an error message exit(EXIT_FAILURE); case 'd': opt_set_int("make-deps-only", 1); break; case 'n': opt_set_int("native", 1); break; case 'p': opt_set_int("make-posix", 1); break; default: abort(); } } const int count = argc - optind; tree_t *targets = xmalloc(count * sizeof(tree_t)); lib_t work = lib_work(); for (int i = optind; i < argc; i++) { ident_t name = to_unit_name(argv[i]); ident_t elab = ident_prefix(name, ident_new("elab"), '.'); if ((targets[i - optind] = lib_get(work, elab)) == NULL) { if ((targets[i - optind] = lib_get(work, name)) == NULL) fatal("cannot find unit %s in library %s", istr(name), istr(lib_name(work))); } } make(targets, count, stdout); return EXIT_SUCCESS; }
static int dump_cmd(int argc, char **argv) { set_work_lib(); static struct option long_options[] = { {"elab", no_argument, 0, 'e'}, {"body", no_argument, 0, 'b'}, {"nets", no_argument, 0, 'n'}, {0, 0, 0, 0} }; bool add_elab = false, add_body = false, nets = false; int c, index = 0; const char *spec = "eb"; optind = 1; while ((c = getopt_long(argc, argv, spec, long_options, &index)) != -1) { switch (c) { case 0: // Set a flag break; case '?': // getopt_long already printed an error message exit(EXIT_FAILURE); case 'e': add_elab = true; break; case 'b': add_body = true; break; case 'n': add_elab = true; nets = true; break; default: abort(); } } if (optind == argc) fatal("missing unit name"); for (int i = optind; i < argc; i++) { ident_t name = to_unit_name(argv[i]); if (add_elab) name = ident_prefix(name, ident_new("elab"), '.'); else if (add_body) name = ident_prefix(name, ident_new("body"), '-'); tree_t top = lib_get(lib_work(), name); if (top == NULL) fatal("%s not analysed", istr(name)); (nets ? dump_nets : dump)(top); } return EXIT_SUCCESS; }
static int codegen(int argc, char **argv) { set_work_lib(); static struct option long_options[] = { {0, 0, 0, 0} }; int c, index = 0; const char *spec = ""; optind = 1; while ((c = getopt_long(argc, argv, spec, long_options, &index)) != -1) { switch (c) { case 0: // Set a flag break; case '?': // getopt_long already printed an error message exit(EXIT_FAILURE); default: abort(); } } if (optind == argc) fatal("missing top-level unit name"); ident_t unit_i = to_unit_name(argv[optind]); tree_t pack = lib_get(lib_work(), unit_i); if (pack == NULL) fatal("cannot find unit %s in library %s", istr(unit_i), istr(lib_name(lib_work()))); if (tree_kind(pack) != T_PACKAGE) fatal("this command can only be used with packages"); if (pack_needs_cgen(pack)) link_package(pack); ident_t body_i = ident_prefix(unit_i, ident_new("body"), '-'); tree_t body = lib_get(lib_work(), body_i); if (body != NULL) link_package(body); return EXIT_SUCCESS; }
static int analyse(int argc, char **argv) { set_work_lib(); static struct option long_options[] = { { "bootstrap", no_argument, 0, 'b' }, { "dump-llvm", no_argument, 0, 'd' }, { "prefer-explicit", no_argument, 0, 'p' }, { 0, 0, 0, 0 } }; int c, index = 0; const char *spec = ""; optind = 1; while ((c = getopt_long(argc, argv, spec, long_options, &index)) != -1) { switch (c) { case 0: // Set a flag break; case '?': // getopt_long already printed an error message exit(EXIT_FAILURE); case 'b': opt_set_int("bootstrap", 1); break; case 'd': opt_set_int("dump-llvm", 1); break; case 'p': opt_set_int("prefer-explicit", 1); break; default: abort(); } } size_t unit_list_sz = 32; tree_t *units LOCAL = xmalloc(sizeof(tree_t) * unit_list_sz); int n_units = 0; for (int i = optind; i < argc; i++) { input_from_file(argv[i]); tree_t unit; while ((unit = parse()) && sem_check(unit)) ARRAY_APPEND(units, unit, n_units, unit_list_sz); } for (int i = 0; i < n_units; i++) { simplify(units[i]); bounds_check(units[i]); } if (parse_errors() + sem_errors() + bounds_errors() > 0) return EXIT_FAILURE; for (int i = 0; i < n_units; i++) { tree_kind_t kind = tree_kind(units[i]); const bool need_cgen = (kind == T_PACK_BODY) || ((kind == T_PACKAGE) && pack_needs_cgen(units[i])); if (need_cgen) opt(units[i]); else units[i] = NULL; } lib_save(lib_work()); for (int i = 0; i < n_units; i++) { if (units[i] != NULL) cgen(units[i]); } return EXIT_SUCCESS; }
static int run(int argc, char **argv) { set_work_lib(); static struct option long_options[] = { { "trace", no_argument, 0, 't' }, { "batch", no_argument, 0, 'b' }, { "command", no_argument, 0, 'c' }, { "stop-time", required_argument, 0, 's' }, { "stats", no_argument, 0, 'S' }, { "wave", optional_argument, 0, 'w' }, { "stop-delta", required_argument, 0, 'd' }, { "format", required_argument, 0, 'f' }, { "include", required_argument, 0, 'i' }, { "exclude", required_argument, 0, 'e' }, { 0, 0, 0, 0 } }; enum { BATCH, COMMAND } mode = BATCH; enum { LXT, FST, VCD} wave_fmt = FST; uint64_t stop_time = UINT64_MAX; const char *wave_fname = NULL; int c, index = 0; const char *spec = "bcw::"; optind = 1; while ((c = getopt_long(argc, argv, spec, long_options, &index)) != -1) { switch (c) { case 0: // Set a flag break; case '?': // getopt_long already printed an error message exit(EXIT_FAILURE); case 't': opt_set_int("rt_trace_en", 1); break; case 'b': mode = BATCH; break; case 'c': mode = COMMAND; break; case 's': stop_time = parse_time(optarg); break; case 'f': if (strcmp(optarg, "vcd") == 0) wave_fmt = VCD; else if (strcmp(optarg, "fst") == 0) wave_fmt = FST; else if (strcmp(optarg, "lxt") == 0) wave_fmt = LXT; else fatal("invalid waveform format: %s", optarg); break; case 'S': opt_set_int("rt-stats", 1); break; case 'w': if (optarg == NULL) wave_fname = ""; else wave_fname = optarg; break; case 'd': opt_set_int("stop-delta", parse_int(optarg)); break; case 'i': wave_include_glob(optarg); break; case 'e': wave_exclude_glob(optarg); break; default: abort(); } } if (optind == argc) fatal("missing top-level unit name"); ident_t top = to_unit_name(argv[optind]); ident_t ename = ident_prefix(top, ident_new("elab"), '.'); tree_rd_ctx_t ctx; tree_t e = lib_get_ctx(lib_work(), ename, &ctx); if (e == NULL) fatal("%s not elaborated", istr(top)); else if (tree_kind(e) != T_ELAB) fatal("%s not suitable top level", istr(top)); if (wave_fname != NULL) { const char *name_map[] = { "LXT", "FST", "VCD" }; const char *ext_map[] = { "lxt", "fst", "vcd" }; char *tmp = NULL; if (*wave_fname == '\0') { tmp = xasprintf("%s.%s", argv[optind], ext_map[wave_fmt]); wave_fname = tmp; notef("writing %s waveform data to %s", name_map[wave_fmt], tmp); } wave_include_file(argv[optind]); switch (wave_fmt) { case LXT: lxt_init(wave_fname, e); break; case VCD: vcd_init(wave_fname, e); break; case FST: fst_init(wave_fname, e); break; } if (tmp != NULL) free(tmp); } if (mode == BATCH) rt_batch_exec(e, stop_time, ctx); else { bool master = slave_fork(); if (master) shell_run(e, ctx); else rt_slave_exec(e, ctx); } tree_read_end(ctx); return EXIT_SUCCESS; }
static int elaborate(int argc, char **argv) { set_work_lib(); static struct option long_options[] = { {"disable-opt", no_argument, 0, 'o'}, {"dump-llvm", no_argument, 0, 'd'}, {"native", no_argument, 0, 'n'}, {"cover", no_argument, 0, 'c'}, {0, 0, 0, 0} }; int c, index = 0; const char *spec = ""; optind = 1; while ((c = getopt_long(argc, argv, spec, long_options, &index)) != -1) { switch (c) { case 'o': opt_set_int("optimise", 0); break; case 'd': opt_set_int("dump-llvm", 1); break; case 'n': opt_set_int("native", 1); break; case 'c': opt_set_int("cover", 1); break; case 0: // Set a flag break; case '?': // getopt_long already printed an error message exit(EXIT_FAILURE); default: abort(); } } if (optind == argc) fatal("missing top-level unit name"); ident_t unit_i = to_unit_name(argv[optind]); tree_t unit = lib_get(lib_work(), unit_i); if (unit == NULL) fatal("cannot find unit %s in library %s", istr(unit_i), istr(lib_name(lib_work()))); tree_t e = elab(unit); if (e == NULL) return EXIT_FAILURE; opt(e); group_nets(e); // Save the library now so the code generator can attach temporary // meta data to trees lib_save(lib_work()); cgen(e); link_bc(e); return EXIT_SUCCESS; }
static int analyse(int argc, char **argv) { set_work_lib(); static struct option long_options[] = { { "bootstrap", no_argument, 0, 'b' }, { "dump-llvm", no_argument, 0, 'd' }, { "dump-vcode", optional_argument, 0, 'v' }, { "prefer-explicit", no_argument, 0, 'p' }, // DEPRECATED { "relax", required_argument, 0, 'r' }, { 0, 0, 0, 0 } }; int c, index = 0; const char *spec = ""; optind = 1; while ((c = getopt_long(argc, argv, spec, long_options, &index)) != -1) { switch (c) { case 0: // Set a flag break; case '?': fatal("unrecognised analyse option %s", argv[optind - 1]); case 'b': opt_set_int("bootstrap", 1); break; case 'd': opt_set_int("dump-llvm", 1); break; case 'v': opt_set_str("dump-vcode", optarg ?: ""); break; case 'p': warnf("the --prefer-explict option is deprecated: use " "--relax=prefer-explict instead"); opt_set_int("relax", RELAX_PREFER_EXPLICT); break; case 'r': opt_set_int("relax", parse_relax(optarg)); break; default: abort(); } } size_t unit_list_sz = 32; tree_t *units LOCAL = xmalloc(sizeof(tree_t) * unit_list_sz); int n_units = 0; for (int i = optind; i < argc; i++) { input_from_file(argv[i]); tree_t unit; while ((unit = parse()) && sem_check(unit)) ARRAY_APPEND(units, unit, n_units, unit_list_sz); } for (int i = 0; i < n_units; i++) { simplify(units[i]); bounds_check(units[i]); } if (parse_errors() + sem_errors() + bounds_errors() > 0) return EXIT_FAILURE; for (int i = 0; i < n_units; i++) { tree_kind_t kind = tree_kind(units[i]); const bool need_cgen = (kind == T_PACK_BODY) || ((kind == T_PACKAGE) && pack_needs_cgen(units[i])); if (need_cgen) opt(units[i]); else units[i] = NULL; } lib_save(lib_work()); for (int i = 0; i < n_units; i++) { if (units[i] != NULL) { lower_unit(units[i]); cgen(units[i]); } } return EXIT_SUCCESS; }
static int elaborate(int argc, char **argv) { set_work_lib(); static struct option long_options[] = { { "disable-opt", no_argument, 0, 'o' }, { "dump-llvm", no_argument, 0, 'd' }, { "dump-vcode", optional_argument, 0, 'V' }, { "native", no_argument, 0, 'n' }, { "cover", no_argument, 0, 'c' }, { "verbose", no_argument, 0, 'v' }, { 0, 0, 0, 0 } }; bool verbose = false; int c, index = 0; const char *spec = "v"; optind = 1; while ((c = getopt_long(argc, argv, spec, long_options, &index)) != -1) { switch (c) { case 'o': opt_set_int("optimise", 0); break; case 'd': opt_set_int("dump-llvm", 1); break; case 'V': opt_set_str("dump-vcode", optarg ?: ""); break; case 'n': opt_set_int("native", 1); break; case 'c': opt_set_int("cover", 1); break; case 'v': verbose = true; break; case 0: // Set a flag break; case '?': fatal("unrecognised elaborate option %s", argv[optind - 1]); default: abort(); } } if (optind == argc) fatal("missing top-level unit name"); elab_verbose(verbose, "initialising"); ident_t unit_i = to_unit_name(argv[optind]); tree_t unit = lib_get(lib_work(), unit_i); if (unit == NULL) fatal("cannot find unit %s in library %s", istr(unit_i), istr(lib_name(lib_work()))); elab_verbose(verbose, "loading top-level unit"); tree_t e = elab(unit); if (e == NULL) return EXIT_FAILURE; elab_verbose(verbose, "elaborating design"); opt(e); elab_verbose(verbose, "optimising design"); group_nets(e); elab_verbose(verbose, "grouping nets"); // Save the library now so the code generator can attach temporary // meta data to trees lib_save(lib_work()); elab_verbose(verbose, "saving library"); lower_unit(e); elab_verbose(verbose, "generating intermediate code"); cgen(e); elab_verbose(verbose, "generating LLVM"); link_bc(e); elab_verbose(verbose, "linking"); return EXIT_SUCCESS; }