/*--------------------------------------------------------------------------------------------- * (function: make_output_pins_for_existing_node) * Looks at a node and extracts the output pins into a signal list so they can be accessed * in this form *-------------------------------------------------------------------------------------------*/ signal_list_t *make_output_pins_for_existing_node(nnode_t* node, int width) { signal_list_t *return_list = init_signal_list(); int i; oassert(node->num_output_pins == width); for (i = 0; i < width; i++) { npin_t *new_pin1; npin_t *new_pin2; nnet_t *new_net; new_pin1 = allocate_npin(); new_pin2 = allocate_npin(); new_net = allocate_nnet(); new_net->name = node->name; /* hook the output pin into the node */ add_output_pin_to_node(node, new_pin1, i); /* hook up new pin 1 into the new net */ add_driver_pin_to_net(new_net, new_pin1); /* hook up the new pin 2 to this new net */ add_fanout_pin_to_net(new_net, new_pin2); /* add the new_pin2 to the list of pins */ add_pin_to_signal_list(return_list, new_pin2); } return return_list; }
/*------------------------------------------------------------------------ * (function: connect_nodes) * Connect one output node to the inputs of the input node *----------------------------------------------------------------------*/ void connect_nodes(nnode_t *out_node, int out_idx, nnode_t *in_node, int in_idx) { npin_t *new_in_pin; oassert(out_node->num_output_pins > out_idx); oassert(in_node->num_input_pins > in_idx); new_in_pin = allocate_npin(); /* create the pin that hooks up to the input */ add_input_pin_to_node(in_node, new_in_pin, in_idx); if (out_node->output_pins[out_idx] == NULL) { /* IF - this node has no output net or pin */ npin_t *new_out_pin; nnet_t *new_net; new_net = allocate_nnet(); new_out_pin = allocate_npin(); /* create the pin that hooks up to the input */ add_output_pin_to_node(out_node, new_out_pin, out_idx); /* hook up in pin out of the new net */ add_fanout_pin_to_net(new_net, new_in_pin); /* hook up the new pin 2 to this new net */ add_driver_pin_to_net(new_net, new_out_pin); } else { /* ELSE - there is a net so we just add a fanout */ /* hook up in pin out of the new net */ add_fanout_pin_to_net(out_node->output_pins[out_idx]->net, new_in_pin); } }
/*--------------------------------------------------------------------------------------------- * (function: get_a_one_pin) * this allows us to attach to the constant netlist driving one *-------------------------------------------------------------------------------------------*/ npin_t *get_one_pin(netlist_t *netlist) { npin_t *one_fanout_pin = allocate_npin(); one_fanout_pin->name = strdup(one_string); add_fanout_pin_to_net(netlist->one_net, one_fanout_pin); return one_fanout_pin; }
/*----------------------------------------------------------------------- * (function: get_a_zero_pin) * this allows us to attach to the constant netlist driving zero *---------------------------------------------------------------------*/ npin_t *get_zero_pin(netlist_t *netlist) { npin_t *zero_fanout_pin = allocate_npin(); zero_fanout_pin->name = strdup(zero_string); add_fanout_pin_to_net(netlist->zero_net, zero_fanout_pin); return zero_fanout_pin; }
/*----------------------------------------------------------------------- * (function: get_a_pad_pin) * this allows us to attach to the constant netlist driving hb_pad *---------------------------------------------------------------------*/ npin_t *get_pad_pin(netlist_t *netlist) { npin_t *pad_fanout_pin = allocate_npin(); pad_fanout_pin->name = strdup(pad_string); add_fanout_pin_to_net(netlist->pad_net, pad_fanout_pin); return pad_fanout_pin; }
/* * Pads the given output port to the width specified in the given model. */ void pad_memory_output_port(nnode_t *node, netlist_t *netlist, t_model *model, char *port_name) { int port_number = get_output_port_index_from_mapping(node, port_name); int port_index = get_output_pin_index_from_mapping (node, port_name); int port_size = node->output_port_sizes[port_number]; t_model_ports *ports = get_model_port(model->outputs, port_name); int target_size = ports->size; int diff = target_size - port_size; if (diff > 0) { allocate_more_node_output_pins(node, diff); // Shift other pins to the right, if any. int i; for (i = node->num_output_pins - 1; i >= port_index + target_size; i--) move_a_output_pin(node, i - diff, i); for (i = port_index + port_size; i < port_index + target_size; i++) { // Add new pins to the higher order spots. npin_t *new_pin = allocate_npin(); new_pin->mapping = strdup(port_name); add_a_output_pin_to_node_spot_idx(node, new_pin, i); } node->output_port_sizes[port_number] = target_size; } }
/*------------------------------------------------------------------------- * (function: copy_output_npin) * Copies an output pin *-----------------------------------------------------------------------*/ npin_t* copy_output_npin(npin_t* copy_pin) { npin_t *new_pin = allocate_npin(); oassert(copy_pin->type == OUTPUT); new_pin->name = copy_pin->name; new_pin->type = copy_pin->type; new_pin->net = copy_pin->net; new_pin->mapping = copy_pin->mapping; new_pin->is_default = copy_pin->is_default; return new_pin; }
/*------------------------------------------------------------------------- * (function: copy_input_npin) * Copies an input pin and potentially adds to the net *-----------------------------------------------------------------------*/ npin_t* copy_input_npin(npin_t* copy_pin) { npin_t *new_pin = allocate_npin(); oassert(copy_pin->type == INPUT); new_pin->name = copy_pin->name?strdup(copy_pin->name):0; new_pin->type = copy_pin->type; new_pin->mapping = copy_pin->mapping?strdup(copy_pin->mapping):0; new_pin->is_default = copy_pin->is_default; if (copy_pin->net != NULL) { add_fanout_pin_to_net(copy_pin->net, new_pin); } return new_pin; }
/*------------------------------------------------------------------------- * (function: pad_multiplier) * * Fill out a multiplier to a fixed size. Size is retrieved from global * hard_multipliers data. * * NOTE: The inputs are extended based on multiplier padding setting. *-----------------------------------------------------------------------*/ void pad_multiplier(nnode_t *node, netlist_t *netlist) { int diffa, diffb, diffout, i; int sizea, sizeb, sizeout; int ina, inb; int testa, testb; static int pad_pin_number = 0; oassert(node->type == MULTIPLY); oassert(hard_multipliers != NULL); sizea = node->input_port_sizes[0]; sizeb = node->input_port_sizes[1]; sizeout = node->output_port_sizes[0]; record_mult_distribution(node); /* Calculate the BEST fit hard multiplier to use */ ina = hard_multipliers->inputs->size; inb = hard_multipliers->inputs->next->size; if (ina < inb) { ina = hard_multipliers->inputs->next->size; inb = hard_multipliers->inputs->size; } diffa = ina - sizea; diffb = inb - sizeb; diffout = hard_multipliers->outputs->size - sizeout; if (configuration.split_hard_multiplier == 1) { struct s_linked_vptr *plist = hard_multipliers->pb_types; while ((diffa + diffb) && plist) { t_pb_type *physical = (t_pb_type *)(plist->data_vptr); plist = plist->next; testa = physical->ports[0].num_pins; testb = physical->ports[1].num_pins; if ((testa >= sizea) && (testb >= sizeb) && ((testa - sizea + testb - sizeb) < (diffa + diffb))) { diffa = testa - sizea; diffb = testb - sizeb; diffout = physical->ports[2].num_pins - sizeout; } } } /* Expand the inputs */ if ((diffa != 0) || (diffb != 0)) { allocate_more_input_pins(node, diffa + diffb); /* Shift pins for expansion of first input pins */ if (diffa != 0) { for (i = 1; i <= sizeb; i++) { move_input_pin(node, sizea + sizeb - i, node->num_input_pins - diffb - i); } /* Connect unused first input pins to zero/pad pin */ for (i = 0; i < diffa; i++) { if (configuration.mult_padding == 0) add_input_pin_to_node(node, get_zero_pin(netlist), i + sizea); else add_input_pin_to_node(node, get_pad_pin(netlist), i + sizea); } node->input_port_sizes[0] = sizea + diffa; } if (diffb != 0) { /* Connect unused second input pins to zero/pad pin */ for (i = 1; i <= diffb; i++) { if (configuration.mult_padding == 0) add_input_pin_to_node(node, get_zero_pin(netlist), node->num_input_pins - i); else add_input_pin_to_node(node, get_pad_pin(netlist), node->num_input_pins - i); } node->input_port_sizes[1] = sizeb + diffb; } } /* Expand the outputs */ if (diffout != 0) { allocate_more_output_pins(node, diffout); for (i = 0; i < diffout; i++) { // Add new pins to the higher order spots. npin_t *new_pin = allocate_npin(); // Pad outputs with a unique and descriptive name to avoid collisions. new_pin->name = append_string("", "unconnected_multiplier_output~%d", pad_pin_number++); add_output_pin_to_node(node, new_pin, i + sizeout); } node->output_port_sizes[0] = sizeout + diffout; } return; }