/*-------------------------------------------------------------------------
 * (function: make_not_gate)
 * 	Just make a not gate
 *-----------------------------------------------------------------------*/
nnode_t *make_not_gate(nnode_t *node, short mark)
{
	nnode_t *logic_node;	

	logic_node = allocate_nnode();
	logic_node->traverse_visited = mark;
	logic_node->type = LOGICAL_NOT;
	logic_node->name = node_name(logic_node, node->name);
	logic_node->related_ast_node = node->related_ast_node;

	allocate_more_input_pins(logic_node, 1);
	allocate_more_output_pins(logic_node, 1);

	return logic_node;

}
/*-------------------------------------------------------------------------
 * (function: make_mult_block)
 * 	Just make a multiplier hard block
 *-----------------------------------------------------------------------*/
nnode_t *make_mult_block(nnode_t *node, short mark)
{
	nnode_t *logic_node;	

	logic_node = allocate_nnode();
	logic_node->traverse_visited = mark;
	logic_node->type = MULTIPLY;
	logic_node->name = node_name(logic_node, node->name);
	logic_node->related_ast_node = node->related_ast_node;
	logic_node->input_port_sizes = node->input_port_sizes;
	logic_node->num_input_port_sizes = node->num_input_port_sizes;
	logic_node->output_port_sizes = node->output_port_sizes;
	logic_node->num_output_port_sizes = node->num_output_port_sizes;

	allocate_more_input_pins(logic_node, node->num_input_pins);
	allocate_more_output_pins(logic_node, node->num_output_pins);

	return logic_node;
}
/*---------------------------------------------------------------------------------------------
 * (function: make_2port_logic_gates)
 * 	Make a 2 port gate with variable sizes.  The first port will be input_pins index 0..width_port1.
 *-------------------------------------------------------------------------------------------*/
nnode_t *make_2port_gate(operation_list type, int width_port1, int width_port2, int width_output, nnode_t *node, short mark)
{
	nnode_t *logic_node = allocate_nnode();
	logic_node->traverse_visited = mark;
	logic_node->type = type;
	logic_node->name = node_name(logic_node, node->name);
	logic_node->related_ast_node = node->related_ast_node;

	/* add the input ports as needed */
	allocate_more_input_pins(logic_node, width_port1);
	add_input_port_information(logic_node, width_port1);
	allocate_more_input_pins(logic_node, width_port2);
	add_input_port_information(logic_node, width_port2);
	/* add output */
	allocate_more_output_pins(logic_node, width_output);
	add_output_port_information(logic_node, width_output);

	return logic_node;
}
/*---------------------------------------------------------------------------------------------
 * (function: make_nport_logic_gates)
 * 	Make a n port gate with variable sizes.  The first port will be input_pins index 0..width_port1.
 *-------------------------------------------------------------------------------------------*/
nnode_t *make_nport_gate(operation_list type, int port_sizes, int width, int width_output, nnode_t *node, short mark)
{
    int i;
	nnode_t *logic_node = allocate_nnode();
	logic_node->traverse_visited = mark;
	logic_node->type = type;
	logic_node->name = node_name(logic_node, node->name);
	logic_node->related_ast_node = node->related_ast_node;

	/* add the input ports as needed */
    for(i = 0; i < port_sizes; i++) {
    	allocate_more_input_pins(logic_node, width);
	    add_input_port_information(logic_node, width);
    }
	//allocate_more_input_pins(logic_node, width_port2);
	//add_input_port_information(logic_node, width_port2);
	/* add output */
	allocate_more_output_pins(logic_node, width_output);
	add_output_port_information(logic_node, width_output);

	return logic_node;
}
Exemple #5
0
/*-------------------------------------------------------------------------
 * (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;
}