/* * This is the main entry point that Icarus Verilog calls to generate * code for a pal. */ int target_design(ivl_design_t des) { unsigned idx; const char*part; ivl_scope_t root; /* Get the part type from the design, using the "part" key. Given the part type, try to open the pal description so that we can figure out the device. */ part = ivl_design_flag(des, "part"); if ((part == 0) || (*part == 0)) { fprintf(stderr, "error: part must be specified. Specify a\n"); fprintf(stderr, " : type with the -fpart=<type> option.\n"); return -1; } pal = pal_alloc(part); if (pal == 0) { fprintf(stderr, "error: %s is not a valid part type.\n", part); return -1; } assert(pal); pins = pal_pins(pal); assert(pins > 0); /* Allocate the pin array, ready to start assigning resources. */ bind_pin = calloc(pins, sizeof (struct pal_bind_s)); /* Connect all the macrocells that drive pins to the pin that they drive. This doesn't yet look at the design, but is initializing the bind_pin array with part information. */ for (idx = 0 ; idx < pal_sops(pal) ; idx += 1) { pal_sop_t sop = pal_sop(pal, idx); int spin = pal_sop_pin(sop); if (spin == 0) continue; assert(spin > 0); bind_pin[spin-1].sop = sop; } /* Get pin assignments from the user. This is the first and most constrained step. Everything else must work around the results of these bindings. */ root = ivl_design_root(des); get_pad_bindings(root, 0); if (pal_errors) { fprintf(stderr, "PAD assignment failed.\n"); pal_free(pal); return -1; } /* Run through the assigned output pins and absorb the output enables that are connected to them. */ absorb_pad_enables(); /* Scan all the registers, and assign them to macro-cells. */ root = ivl_design_root(des); fit_registers(root, 0); if (pal_errors) { fprintf(stderr, "Register fitting failed.\n"); pal_free(pal); return -1; } fit_logic(); if (pal_errors) { fprintf(stderr, "Logic fitting failed.\n"); pal_free(pal); return -1; } dump_final_design(stdout); emit_jedec(ivl_design_flag(des, "-o")); pal_free(pal); return 0; }
pal* pal_new_for_path(const char *path) { return pal_init_for_path(pal_alloc(), path); }