示例#1
0
/*---------------------------------------------------------------------------------------------
 * (function: instantiate_logical_logic )
 *-------------------------------------------------------------------------------------------*/
void instantiate_logical_logic(nnode_t *node, operation_list op, short mark, netlist_t *netlist)
{
	int i;
	int port_B_offset;
	int width_a;
	int width_b;
	nnode_t *new_logic_cell;
	nnode_t *reduction1;
	nnode_t *reduction2;

	oassert(node->num_input_pins > 0);
	oassert(node->num_input_port_sizes == 2);
	oassert(node->num_output_pins == 1);
	/* setup the calculations for padding and indexing */
	width_a = node->input_port_sizes[0];
	width_b = node->input_port_sizes[1];
	port_B_offset = width_a;

	/* instantiate the cells */
	new_logic_cell = make_1port_logic_gate(op, 2, node, mark);
	reduction1 = make_1port_logic_gate(BITWISE_OR, width_a, node, mark);
	reduction2 = make_1port_logic_gate(BITWISE_OR, width_b, node, mark);

	/* connect inputs.  In the case that a signal is smaller than the other then zero pad */
	for(i = 0; i < width_a; i++)
	{
		/* Joining the inputs to the input 1 of that gate */
		if (i < width_a)
		{
			remap_pin_to_new_node(node->input_pins[i], reduction1, i);
		}
		else
		{
			/* ELSE - the B input does not exist, so this answer goes right through */
			add_a_input_pin_to_node_spot_idx(reduction1, get_a_zero_pin(netlist), i);
		}
	}
	for(i = 0; i < width_b; i++)
	{
		/* Joining the inputs to the input 1 of that gate */
		if (i < width_b)
		{
			remap_pin_to_new_node(node->input_pins[i+port_B_offset], reduction2, i);
		}
		else
		{
			/* ELSE - the B input does not exist, so this answer goes right through */
			add_a_input_pin_to_node_spot_idx(reduction2, get_a_zero_pin(netlist), i);
		}
	}

	connect_nodes(reduction1, 0, new_logic_cell, 0);
	connect_nodes(reduction2, 0, new_logic_cell, 1);

	instantiate_bitwise_reduction(reduction1, BITWISE_OR, mark, netlist);
	instantiate_bitwise_reduction(reduction2, BITWISE_OR, mark, netlist);

	remap_pin_to_new_node(node->output_pins[0], new_logic_cell, 0);
}
示例#2
0
/*-------------------------------------------------------------------------
 * (function: split_multiplier_a)
 *
 * This function works to split the "a" input of a multiplier into 
 *  several smaller multipliers to better "fit" with the available 
 *  resources in a targeted FPGA architecture.
 *
 * This function is at the lowest level since it simply receives
 *  a multiplier and is told how to split it. The end result is:
 *
 *  a1a0 * b => a0 * b + a1 * b => c
 *  
 * Note that for the addition we need to perform sign extension,
 * but this should not be a problem since the sign extension is always
 * extending NOT contracting.
 *
 *-----------------------------------------------------------------------*/
void split_multiplier_a(nnode_t *node, int a0, int a1, int b)
{
	nnode_t *a0b, *a1b, *addsmall;
	int i;

	/* Check for a legitimate split */
	oassert(node->input_port_sizes[0] == (a0 + a1));
	oassert(node->input_port_sizes[1] == b);
	
	/* New node for a0b multiply */
	a0b = allocate_nnode();
	a0b->name = (char *)malloc(strlen(node->name) + 3);
	strcpy(a0b->name, node->name);
	strcat(a0b->name, "-0");
	init_split_multiplier(node, a0b, 0, a0, 0, b);
	mult_list = insert_in_vptr_list(mult_list, a0b);

	/* New node for a1b multiply */
	a1b = allocate_nnode();
	a1b->name = (char *)malloc(strlen(node->name) + 3);
	strcpy(a1b->name, node->name);
	strcat(a1b->name, "-1");
	init_split_multiplier(node, a1b, a0, a1, 0, b);
	mult_list = insert_in_vptr_list(mult_list, a1b);

	/* New node for the add */
	addsmall = allocate_nnode();
	addsmall->name = (char *)malloc(strlen(node->name) + 6);
	strcpy(addsmall->name, node->name);
	strcat(addsmall->name, "-add0");
	init_cascade_adder(addsmall, a1b, a1 + b);
	
	/* Connect pins for addsmall */
	for (i = a0; i < a0b->output_port_sizes[0]; i++)
		connect_nodes(a0b, i, addsmall, i-a0);
	for (i = a0b->output_port_sizes[0] - a0; i < a1+b; i++) /* Sign extend */
		connect_nodes(a0b, a0b->output_port_sizes[0]-1, addsmall, i);
	for (i = b+a1; i < (2 * (a1 + b)); i++)
		connect_nodes(a1b, i-(b+a1), addsmall, i);

	/* Move original output pins for multiply to new outputs */
	for (i = 0; i < a0; i++)
		remap_pin_to_new_node(node->output_pins[i], a0b, i);

	for (i = a0; i < node->num_output_pins; i++)
		remap_pin_to_new_node(node->output_pins[i], addsmall, i-a0);

	/* Probably more to do here in freeing the old node! */
	free(node->name);
	free(node->input_port_sizes);
	free(node->output_port_sizes);

	/* Free arrays NOT the pins since relocated! */
	free(node->input_pins); 
	free(node->output_pins); 
	free(node);
	return;
}
示例#3
0
/*-------------------------------------------------------------------------
 * (function: split_multiplier_b)
 *
 * This function works to split the "b" input of a multiplier into 
 *  several smaller multipliers to better "fit" with the available 
 *  resources in a targeted FPGA architecture.
 *
 * This function is at the lowest level since it simply receives
 *  a multiplier and is told how to split it. The end result is:
 *
 *  a * b1b0 => a * b1 + a * b0 => c
 *  
 * Note that for the addition we need to perform sign extension,
 * but this should not be a problem since the sign extension is always
 * extending NOT contracting.
 *
 *-----------------------------------------------------------------------*/
void split_multiplier_b(nnode_t *node, int a, int b1, int b0)
{
	nnode_t *ab0, *ab1, *addsmall;
	int i;

	/* Check for a legitimate split */
	oassert(node->input_port_sizes[0] == a);
	oassert(node->input_port_sizes[1] == (b0 + b1));
	
	/* New node for ab0 multiply */
	ab0 = allocate_nnode();
	ab0->name = (char *)malloc(strlen(node->name) + 3);
	strcpy(ab0->name, node->name);
	strcat(ab0->name, "-0");
	init_split_multiplier(node, ab0, 0, a, 0, b0);
	mult_list = insert_in_vptr_list(mult_list, ab0);

	/* New node for ab1 multiply */
	ab1 = allocate_nnode();
	ab1->name = (char *)malloc(strlen(node->name) + 3);
	strcpy(ab1->name, node->name);
	strcat(ab1->name, "-1");
	init_split_multiplier(node, ab1, 0, a, b0, b1);
	mult_list = insert_in_vptr_list(mult_list, ab1);

	/* New node for the add */
	addsmall = allocate_nnode();
	addsmall->name = (char *)malloc(strlen(node->name) + 6);
	strcpy(addsmall->name, node->name);
	strcat(addsmall->name, "-add0");
	init_cascade_adder(addsmall, ab1, a + b1);
	
	/* Connect pins for addsmall */
	for (i = b0; i < ab0->output_port_sizes[0]; i++)
		connect_nodes(ab0, i, addsmall, i-b0);
	for (i = ab0->output_port_sizes[0] - b0; i < a+b1; i++) /* Sign extend */
		connect_nodes(ab0, ab0->output_port_sizes[0]-1, addsmall, i);
	for (i = b1+a; i < (2 * (a + b1)); i++)
		connect_nodes(ab1, i-(b1+a), addsmall, i);

	/* Move original output pins for multiply to new outputs */
	for (i = 0; i < b0; i++)
		remap_pin_to_new_node(node->output_pins[i], ab0, i);

	for (i = b0; i < node->num_output_pins; i++)
		remap_pin_to_new_node(node->output_pins[i], addsmall, i-b0);

	/* Probably more to do here in freeing the old node! */
	free(node->name);
	free(node->input_port_sizes);
	free(node->output_port_sizes);

	/* Free arrays NOT the pins since relocated! */
	free(node->input_pins); 
	free(node->output_pins); 
	free(node);
	return;
}
void iterate_node_2(node_t *node)
{
	int action;

	action = get_action_2(node);

	switch (action) {
		case 0:
			node->link_0->value = node->value;
		case 1:
			connect_nodes(node, node->link_0, node->link_1);
			/*  swap_nodes(node->link_0, node->link_1);  */
			swap_nodes(node, node->link_1);
			break;

		case 2:
			node->link_1->value = node->value;
		case 3:
			connect_nodes(node, node->link_1, node->link_0);
			/*  swap_nodes(node->link_1, node->link_0);  */
			swap_nodes(node, node->link_0);
			break;

		case 4:
			node->link_0->value = inverted_value(node);
			break;
		case 5:
			node->link_0->value = inverted_value(node);
			swap_nodes(node, node->link_1);
			break;

		case 6:
			node->link_1->value = inverted_value(node);
			break;
		case 7:
			node->link_1->value = inverted_value(node);
			swap_nodes(node, node->link_0);
			break;
	}
	/*
	  node->value = 0;
	  node->value = 1;
	  invert_value(node);
	  connect_nodes(node, node->link_0, node->link_1);
	  swap_values(node, node->link_0);
	  swap_values(node, node->link_1);
	  node->link_0->value = node->value;
	  node->link_0->value = 0;
	  node->link_0->value = 1;
	  node->link_0->value = inverted_value(node);
	  node->link_1->value = node->value;
	  node->link_1->value = 0;
	  node->link_1->value = 1;
	  node->link_1->value = inverted_value(node);
	  swap_nodes(node, node->link_0);
	  swap_nodes(node, node->link_1);
	*/
}
示例#5
0
/* /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// */
static int connect_node(Main *bmain, bNodeTree *ntree, bNode *node_fr, bNode *node_to, bNodeSocket *sock_to)
{
    bNodeSocket *sock_fr = node_fr->outputs.first;
    if (sock_fr && sock_to) {
        if(!connect_nodes(bmain, ntree, node_fr, sock_fr, node_to, sock_to))
            return 0;
    }
    return 1;
} /* connect_node() */
示例#6
0
int main( int argc, char* argv[])
{
  int number, minc, maxc, i;
  int connectivity;
  std::vector< std::set<int> > nodes;

  if ( argc != 4 ) {
    std::cout << "Usage :" << std::endl;
    std::cout << "\t" << argv[0] << " <number_of_nodes> <min_connectivity> <max_connectivity>" << std::endl;
    return 1;
  }
  
  number = atoi(argv[1]);
  minc   = atoi(argv[2]);
  maxc   = atoi(argv[3]);

  if ( number <= 0 || minc <= 0 || maxc <= 0 ) {
    std::cout << "Usage :" << std::endl;
    std::cout << "\t" << argv[0] << " <number_of_nodes> <min_connectivity> <max_connectivity>" << std::endl;
    return 1;
  }

  srand(time(0));
  
  nodes.reserve(number);

  std::vector<int> network;

  for ( i=0; i<number; i++ ) {
    nodes.push_back(std::set<int>());
    network.push_back(i);
  }



  for ( i=0; i<number; i++ ) {
    std::vector<int> t = network;

    connectivity = minc + rand()%(maxc-minc+1);

    while (nodes[i].size() < connectivity ) {
      int n;
      
      if ( t.size() == 0 ) {
        std::cout << "- Error! Current topology cannot be completed." << std::endl;
        return 0;
      }

      n = rand()%t.size();
      connect_nodes(i, t[n], nodes, maxc);
      t.erase(t.begin()+n);
    }
  }

  return 0;
}
示例#7
0
 void store_returns_in_temporary_vars_rec( Node* current, Node* graph_exit )
 {
     if( !current->is_visited( ) )
     {
         current->set_visited( true );
         
         if( current->is_graph_node( ) )
         {
             store_returns_in_temporary_vars_rec( current->get_graph_entry_node( ), graph_exit );
         }
         else if( current->is_return_node( ) )
         {
             Nodecl::ReturnStatement ret_stmt = current->get_statements( )[0].as<Nodecl::ReturnStatement>( );
             Nodecl::NodeclBase ret_value = ret_stmt.get_value( );
             if( !ret_value.is_null( ) )
             {
                 Type ret_value_type = ret_value.get_type( );
                 
                 // Build a symbol to store the temporary value
                 scope_entry_t* temp_sc_entry = ( scope_entry_t* ) xcalloc( 1, sizeof( scope_entry_t ) );
                 temp_sc_entry->symbol_name = "__tmp_return_val__";
                 temp_sc_entry->kind = SK_VARIABLE;
                 temp_sc_entry->type_information = ret_value_type.get_internal_type( );
                 temp_sc_entry->decl_context = ret_value.retrieve_context( ).get_decl_context( );
                 Nodecl::Symbol temp_sym = Nodecl::Symbol::make( Symbol( temp_sc_entry ), ret_stmt.get_locus( ) );
                 
                 // Build the statement that stores the return value in the temporary symbol 
                 Nodecl::Assignment tmp_stmt = Nodecl::Assignment::make( temp_sym, ret_value, ret_value_type, 
                                                                         ret_stmt.get_locus( ) );
                 
                 // Modify the 'current' node with the new information
                 current->set_type( NORMAL );
                 current->set_statements( ObjectList<Nodecl::NodeclBase>( 1, tmp_stmt ) );
             }
             else
             {   // We have to delete this node and connect its parent with the graph exit node
                 ObjectList<Node*> parents = current->get_parents( );
                 ObjectList<Edge_type> entry_types = current->get_entry_edge_types( );
                 ObjectList<std::string> entry_labels = current->get_entry_edge_labels( );
                 delete_node( current );
                 connect_nodes( parents, graph_exit, entry_types, entry_labels );
             }
         }
         
         ObjectList<Node*> children = current->get_children( );
         for( ObjectList<Node*>::iterator it = children.begin( ); it != children.end( ); ++it )
             store_returns_in_temporary_vars_rec( *it, graph_exit );
     }
 }
示例#8
0
/*---------------------------------------------------------------------------------------------
 * (function: instantiate_GE )
 *	Defines the HW needed for greter than equal with EQ, GT, AND and OR gates to create
 *	the appropriate logic function.
 *-------------------------------------------------------------------------------------------*/
void instantiate_GE(nnode_t *node, short type, short mark, netlist_t *netlist)
{
	int width_a;
	int width_b;
	int width_max;
	int i;
	int port_B_offset;
	int port_A_offset;
	nnode_t *equal;
	nnode_t *compare;
	nnode_t *logical_or_final_gate;

	oassert(node->num_output_pins == 1);
	oassert(node->num_input_pins > 0);
	oassert(node->num_input_port_sizes == 2);
	oassert(node->input_port_sizes[0] == node->input_port_sizes[1]);
	width_a = node->input_port_sizes[0];
	width_b = node->input_port_sizes[1];
	oassert(width_a == width_b);
	width_max = width_a > width_b ? width_a : width_b;

	port_A_offset = 0;
	port_B_offset = width_a;

	/* build an xnor bitwise XNOR */
	equal = make_2port_gate(LOGICAL_EQUAL, width_a, width_b, 1, node, mark);

	if (type == GTE) compare = make_2port_gate(GT, width_a, width_b, 1, node, mark);
	else             compare = make_2port_gate(LT, width_a, width_b, 1, node, mark);

	logical_or_final_gate = make_1port_logic_gate(LOGICAL_OR, 2, node, mark);

	/* connect inputs.  In the case that a signal is smaller than the other then zero pad */
	for(i = 0; i < width_max; i++)
	{
		/* Joining the inputs to the input 1 of that gate */
		if (i < width_a)
		{
			/* IF - this current input will also have a corresponding b_port input then join it to the gate */
			remap_pin_to_new_node(node->input_pins[i+port_A_offset], equal, i+port_A_offset);
			add_a_input_pin_to_node_spot_idx(compare, copy_input_npin(equal->input_pins[i+port_A_offset]), i+port_A_offset);
		}
		else
		{
			/* ELSE - the B input does not exist, so this answer goes right through */
			add_a_input_pin_to_node_spot_idx(equal, get_a_zero_pin(netlist), i+port_A_offset);
			add_a_input_pin_to_node_spot_idx(compare, get_a_zero_pin(netlist), i+port_A_offset);
		}

		if (i < width_b)
		{
			/* IF - this current input will also have a corresponding a_port input then join it to the gate */
			/* Joining the inputs to the input 2 of that gate */
			remap_pin_to_new_node(node->input_pins[i+port_B_offset], equal, i+port_B_offset);
			add_a_input_pin_to_node_spot_idx(compare, copy_input_npin(equal->input_pins[i+port_B_offset]), i+port_B_offset);
		}
		else
		{
			/* ELSE - the A input does not exist, so this answer goes right through */
			add_a_input_pin_to_node_spot_idx(equal, get_a_zero_pin(netlist), i+port_B_offset);
			add_a_input_pin_to_node_spot_idx(compare, get_a_zero_pin(netlist), i+port_B_offset);
		}
	}
	connect_nodes(equal, 0, logical_or_final_gate, 0);
	connect_nodes(compare, 0, logical_or_final_gate, 1);

	/* join that gate to the output */
	remap_pin_to_new_node(node->output_pins[0], logical_or_final_gate, 0);
	oassert(logical_or_final_gate->num_output_pins == 1);

	/* make the two intermediate gates */
	instantiate_EQUAL(equal, LOGICAL_EQUAL, mark, netlist);

	if (type == GTE) instantiate_GT(compare, GT, mark, netlist);
	else             instantiate_GT(compare, LT, mark, netlist);
}
示例#9
0
/*-------------------------------------------------------------------------
 * (function: split_multiplier)
 *
 * This function works to split a multiplier into several smaller
 *  multipliers to better "fit" with the available resources in a
 *  targeted FPGA architecture.
 *
 * This function is at the lowest level since it simply receives
 *  a multiplier and is told how to split it. The end result is:
 *
 *  a1a0 * b1b0 => a0 * b0 + a0 * b1 + a1 * b0 + a1 * b1 => c1c0 => c
 *  
 * If we "balance" the additions, we can actually remove one of the
 * addition operations since we know that a0 * b0 and a1 * b1 will
 * not overlap in bits. This allows us to skip the addition between
 * these two terms and simply concat the results together. Giving us
 * the resulting logic:
 *
 * ((a1 * b1) . (a0 * b0)) + ((a0 * b1) + (a1 * b0)) ==> Result
 *
 * Note that for some of the additions we need to perform sign extensions,
 * but this should not be a problem since the sign extension is always
 * extending NOT contracting.
 *
 *-----------------------------------------------------------------------*/
void split_multiplier(nnode_t *node, int a0, int b0, int a1, int b1)
{
	nnode_t *a0b0, *a0b1, *a1b0, *a1b1, *addsmall, *addbig;
	int i, size;

	/* Check for a legitimate split */
	oassert(node->input_port_sizes[0] == (a0 + a1));
	oassert(node->input_port_sizes[1] == (b0 + b1));
	
	/* New node for small multiply */
	a0b0 = allocate_nnode();
	a0b0->name = (char *)malloc(strlen(node->name) + 3);
	strcpy(a0b0->name, node->name);
	strcat(a0b0->name, "-0");
	init_split_multiplier(node, a0b0, 0, a0, 0, b0);
	mult_list = insert_in_vptr_list(mult_list, a0b0);

	/* New node for big multiply */
	a1b1 = allocate_nnode();
	a1b1->name = (char *)malloc(strlen(node->name) + 3);
	strcpy(a1b1->name, node->name);
	strcat(a1b1->name, "-3");
	init_split_multiplier(node, a1b1, a0, a1, b0, b1);
	mult_list = insert_in_vptr_list(mult_list, a1b1);

	/* New node for 2nd multiply */
	a0b1 = allocate_nnode();
	a0b1->name = (char *)malloc(strlen(node->name) + 3);
	strcpy(a0b1->name, node->name);
	strcat(a0b1->name, "-1");
	init_split_multiplier(node, a0b1, 0, a0, b0, b1);
	mult_list = insert_in_vptr_list(mult_list, a0b1);

	/* New node for 3rd multiply */
	a1b0 = allocate_nnode();
	a1b0->name = (char *)malloc(strlen(node->name) + 3);
	strcpy(a1b0->name, node->name);
	strcat(a1b0->name, "-2");
	init_split_multiplier(node, a1b0, a0, a1, 0, b0);
	mult_list = insert_in_vptr_list(mult_list, a1b0);

	/* New node for the initial add */
	addsmall = allocate_nnode();
	addsmall->name = (char *)malloc(strlen(node->name) + 6);
	strcpy(addsmall->name, node->name);
	strcat(addsmall->name, "-add0");
	init_cascade_adder(addsmall, a1b0, a0b1->output_port_sizes[0]);
	
	/* New node for the BIG add */
	addbig = allocate_nnode();
	addbig->name = (char *)malloc(strlen(node->name) + 6);
	strcpy(addbig->name, node->name);
	strcat(addbig->name, "-add1");
	init_cascade_adder(addbig, addsmall,
		a0b0->output_port_sizes[0] + a1b1->output_port_sizes[0]);
	
	/* Insert temporary pins for addsmall */
	for (i = 0; i < a0b1->output_port_sizes[0]; i++)
		connect_nodes(a0b1, i, addsmall, i);
	for (i = 0; i < a1b0->output_port_sizes[0]; i++)
		connect_nodes(a1b0, i, addsmall, i+a0b1->output_port_sizes[0]);

	/* Insert temporary pins for addbig */
	size = addsmall->output_port_sizes[0];
	for (i = 0; i < size; i++)
		connect_nodes(addsmall, i, addbig, i);
	for (i = 0; i < a1b1->output_port_sizes[0]; i++)
		connect_nodes(a1b1, i, addbig, i + size);
	size = size + a1b1->output_port_sizes[0];
	for (i = 0; i < a0b0->output_port_sizes[0]; i++)
		connect_nodes(a0b0, i, addbig, i + size);

	/* Move original output pins for multiply to addbig */
	for (i = 0; i < addbig->num_output_pins; i++)
		remap_pin_to_new_node(node->output_pins[i], addbig, i);

	/* Probably more to do here in freeing the old node! */
	free(node->name);
	free(node->input_port_sizes);
	free(node->output_port_sizes);

	/* Free arrays NOT the pins since relocated! */
	free(node->input_pins); 
	free(node->output_pins); 
	free(node);

	return;
}
示例#10
0
int main(int argc, char **argv)
{
  int node_num;
  int grid_size = 10000;
  int degree_one = 0;
  int placement = 0;
  int expansion = 0;
  int seed = 0;
  int ch;
  int print_version = 0;
  float frac = 0.0;
 
  node_type *node;

  my_stderr = stderr;

  /**************************************/
  /* getopt the command line arguments */
  /**************************************/

  if (argc == 1)
  {
    usage();
    exit(-1);
  }

  while ((ch = getopt(argc, argv, "d:f:p:n:s:Vvh")) != -1)
  {
    switch (ch)
    {
      case 'd':
        frac = atof(optarg);
        break;
      case 'f':
        my_stderr = fopen(optarg, "w");
        if (!my_stderr)
        {
          fprintf(stderr, "unable to open \"%s\" to output debugging info!\n", optarg);
          exit(-1);
        }
        break;
      case 'p':
        grid_size = atoi(optarg);
        break;
      case 'n':
        node_num = atoi(optarg);
        break;
      case 's':
        seed = atoi(optarg) % 64;
        break;
      case 'V':
      case 'v':
        print_version = 1;
        break;
      case 'h':
      default:
        usage();
	exit(-1);
    }
  }
    
  if ( print_version )
  {
    printf("Inet %s\n", VERSION);
    exit(0);
  }
 
  //if ( node_num < 3037 )
  if ( node_num < 10 )
  {
    //fprintf(stderr, "Error! the number of nodes must be no less than 3037!\n");
    fprintf(stderr, "Error! the number of nodes must be no less than 10!\n");
    exit(-1);
  }

  /****************************************************/
  /* the default is computed by a linear relationship */
  /****************************************************/
  degree_one = (int)((float)node_num * frac);
    fprintf(stderr, "1 degree_one : %d\n", degree_one);
  if (degree_one == 0)
    degree_one = DEGREE_1_SLOPE * node_num + DEGREE_1_INTERCEPT;
 
    fprintf(stderr, "2 degree_one : %d\n", degree_one);
  /*******************************************/
  /* initializes the random number generator */
  /*******************************************/
  random_reset();  
  

  /*******************/
  /* allocate memory */
  /*******************/
  node = (node_type *)malloc(sizeof(node_type) * node_num);
  if (!node)
  {
    fprintf(stderr, "no enough memory for node array (%d bytes needed)!\n", sizeof(node_type) * node_num);
    exit(-1);
  }

  /*****************************/
  /* go ahead, make a topology */
  /*****************************/
  generate_degrees(node, node_num, degree_one, seed);
  place_nodes(node, node_num, grid_size, placement, seed);
  connect_nodes(node, node_num, seed);

  generate_output(node, node_num);

  if (my_stderr != stderr)
  {
    fclose(my_stderr);
  }
}
示例#11
0
/*---------------------------------------------------------------------------------------------
 * (function: instantiate_EQUAL )
 *	Builds the hardware for an equal comparison by building EQ for parallel lines and then
 *	taking them all through an AND tree.
 *-------------------------------------------------------------------------------------------*/
void instantiate_EQUAL(nnode_t *node, short type, short mark, netlist_t *netlist)
{
	int width_a;
	int width_b;
	int width_max;
	int i;
	int port_B_offset;
	nnode_t *compare;
	nnode_t *combine;

	oassert(node->num_output_pins == 1);
	oassert(node->num_input_pins > 0);
	oassert(node->num_input_port_sizes == 2);
	width_a = node->input_port_sizes[0];
	width_b = node->input_port_sizes[1];
	width_max = width_a > width_b ? width_a : width_b;
	port_B_offset = width_a;

	/* build an xnor bitwise XNOR */
	if (type == LOGICAL_EQUAL)
	{
		compare = make_2port_gate(LOGICAL_XNOR, width_a, width_b, width_max, node, mark);
		combine = make_1port_logic_gate(LOGICAL_AND, width_max, node, mark);
	}
	else
	{
		compare = make_2port_gate(LOGICAL_XOR, width_a, width_b, width_max, node, mark);
		combine = make_1port_logic_gate(LOGICAL_OR, width_max, node, mark);
	}
	/* build an and bitwise AND */


	/* connect inputs.  In the case that a signal is smaller than the other then zero pad */
	for(i = 0; i < width_max; i++)
	{
		/* Joining the inputs to the input 1 of that gate */
		if (i < width_a)
		{
			if (i < width_b)
			{
				/* IF - this current input will also have a corresponding b_port input then join it to the gate */
				remap_pin_to_new_node(node->input_pins[i], compare, i);
			}
			else
			{
				/* ELSE - the B input does not exist, so this answer goes right through */
				add_a_input_pin_to_node_spot_idx(compare, get_a_zero_pin(netlist), i);
			}
		}

		if (i < width_b)
		{
			if (i < width_a)
			{
				/* IF - this current input will also have a corresponding a_port input then join it to the gate */
				/* Joining the inputs to the input 2 of that gate */
				remap_pin_to_new_node(node->input_pins[i+port_B_offset], compare, i+port_B_offset);
			}
			else
			{
				/* ELSE - the A input does not exist, so this answer goes right through */
				add_a_input_pin_to_node_spot_idx(compare, get_a_zero_pin(netlist), i+port_B_offset);
			}
		}

		/* hook it up to the logcial AND */
		connect_nodes(compare, i, combine, i);
	}

	/* join that gate to the output */
	remap_pin_to_new_node(node->output_pins[0], combine, 0);

	if (type == LOGICAL_EQUAL)
		instantiate_bitwise_logic(compare, BITWISE_XNOR, mark, netlist);
	else
		instantiate_bitwise_logic(compare, BITWISE_XOR, mark, netlist);
	/* Don't need to instantiate a Logic and gate since it is a function itself */

	oassert(combine->num_output_pins == 1);
}
示例#12
0
static int
flow_node_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct flow_static_type *type;
    struct flow_static_data *fsd;
    const struct sol_flow_static_node_spec *spec;
    char *node_storage_it;
    int r, i;

    type = (struct flow_static_type *)node->type;
    fsd = data;

    fsd->nodes = calloc(type->node_count, sizeof(struct sol_flow_node *));
    fsd->node_storage = calloc(1, type->node_storage_size);
    if (!fsd->nodes || !fsd->node_storage) {
        r = -ENOMEM;
        goto error_alloc;
    }

    /* Assure flow_send_idle()'s timeout is the first registered, so
     * that timeouts coming from nodes' init/open functions and that
     * may produce packets will always have them delivered */
    r = flow_delay_send(node, fsd);
    SOL_INT_CHECK(r, < 0, r);

    sol_list_init(&fsd->delayed_packets);

    /* Set all pointers before calling nodes methods */
    node_storage_it = fsd->node_storage;
    for (spec = type->node_specs, i = 0; spec->type != NULL; spec++, i++) {
        struct sol_flow_node *child_node = (struct sol_flow_node *)node_storage_it;

        fsd->nodes[i] = child_node;
        child_node->parent_data = INT_TO_PTR(i);
        node_storage_it += calc_node_size(spec);
    }

    for (spec = type->node_specs, i = 0; spec->type != NULL; spec++, i++) {
        struct sol_flow_node *child_node = fsd->nodes[i];
        struct sol_flow_node_options *child_opts;

        child_opts = sol_flow_node_get_options(spec->type, spec->opts);
        if (!child_opts) {
            SOL_WRN("failed to get options for node #%u, type=%p: %s",
                (unsigned)(spec - type->node_specs), spec->type,
                sol_util_strerrora(errno));
        }

        if (type->child_opts_set)
            type->child_opts_set(i, options, child_opts);
        r = sol_flow_node_init(child_node, node, spec->name, spec->type,
            child_opts);
        sol_flow_node_free_options(spec->type, child_opts);
        if (r < 0) {
            SOL_WRN("failed to init node #%u, type=%p, opts=%p: %s",
                (unsigned)(spec - type->node_specs), spec->type, spec->opts,
                sol_util_strerrora(-r));
            goto error_nodes;
        }
    }

    r = connect_nodes(type, fsd);
    if (r < 0)
        goto error_conns;

    return 0;

error_conns:
error_nodes:
    /* Skip the failed index, since it doesn't need fini. */
    for (i--; i >= 0; i--)
        sol_flow_node_fini(fsd->nodes[i]);

error_alloc:
    free(fsd->node_storage);
    free(fsd->nodes);

    return r;
}
示例#13
0
/*-------------------------------------------------------------------------
 * (function: split_dp_memory_depth)
 *
 * This function works to split the depth of a dual port memory into 
 *   several smaller memories.
 *------------------------------------------------------------------------
 */
void 
split_dp_memory_depth(nnode_t *node)
{
	int addr1_port = -1;
	int addr2_port = -1;
	int we1_port = -1;
	int we2_port = -1;
	int logical_size;
	int i, j;
	int idx;
	int addr1_pin_idx = 0;
	int we1_pin_idx = 0;
	int addr2_pin_idx = 0;
	int we2_pin_idx = 0;
	nnode_t *new_mem_node;
	nnode_t *and1_node, *not1_node, *ff1_node, *mux1_node;
	nnode_t *and2_node, *not2_node, *ff2_node, *mux2_node;
	npin_t *addr1_pin = NULL;
	npin_t *addr2_pin = NULL;
	npin_t *we1_pin = NULL;
	npin_t *we2_pin = NULL;
	npin_t *twe_pin, *taddr_pin;
	npin_t *clk_pin = NULL;
	npin_t *tdout_pin;

	oassert(node->type == MEMORY);

	/* Find which ports are the addr1 and addr2 ports */
	idx = 0;
	for (i = 0; i < node->num_input_port_sizes; i++)
	{
		if (strcmp("addr1", node->input_pins[idx]->mapping) == 0)
		{
			addr1_port = i;
			addr1_pin_idx = idx;
			addr1_pin = node->input_pins[idx];
		}
		else if (strcmp("addr2", node->input_pins[idx]->mapping) == 0)
		{
			addr2_port = i;
			addr2_pin_idx = idx;
			addr2_pin = node->input_pins[idx];
		}
		else if (strcmp("we1", node->input_pins[idx]->mapping) == 0)
		{
			we1_port = i;
			we1_pin = node->input_pins[idx];
			we1_pin_idx = idx;
		}
		else if (strcmp("we2", node->input_pins[idx]->mapping) == 0)
		{
			we2_port = i;
			we2_pin = node->input_pins[idx];
			we2_pin_idx = idx;
		}
		else if (strcmp("clk", node->input_pins[idx]->mapping) == 0)
		{
			clk_pin = node->input_pins[idx];
		}
		idx += node->input_port_sizes[i];
	}

	if (addr1_port == -1)
	{
		error_message(1, 0, -1, "No \"addr1\" port on dual port RAM");
	}

	
	/* Jason Luu HACK: Logical memory depth determination messed up, forced to use this method */
	for(i = 0; i < node->input_port_sizes[addr1_port]; i++)
	{
		if(strcmp(node->input_pins[addr1_pin_idx + i]->name, "top^ZERO_PAD_ZERO") == 0)
			break;
	}
	logical_size = i;
 	
	/* Check that the memory needs to be split */
	if (logical_size <= split_size) {
		dp_memory_list = insert_in_vptr_list(dp_memory_list, node);
		return;
	} 

	/* Let's remove the address1 line from the memory */
	for (i = addr1_pin_idx; i < node->num_input_pins - 1; i++)
	{
		node->input_pins[i] = node->input_pins[i+1];
		node->input_pins[i]->pin_node_idx--;
	}
	node->input_port_sizes[addr1_port]--;
	node->input_pins = realloc(node->input_pins, sizeof(npin_t *) * --node->num_input_pins);
	if ((we1_port != -1) && (we1_pin_idx >= addr1_pin_idx))
		we1_pin_idx--;
	if ((we2_port != -1) && (we2_pin_idx >= addr1_pin_idx))
		we2_pin_idx--;
	if ((addr2_port != -1) && (addr2_pin_idx >= addr1_pin_idx))
		addr2_pin_idx--;

	/* Let's remove the address2 line from the memory */
	if (addr2_port != -1)
	{
		for (i = addr2_pin_idx; i < node->num_input_pins - 1; i++)
		{
			node->input_pins[i] = node->input_pins[i+1];
			node->input_pins[i]->pin_node_idx--;
		}
		node->input_port_sizes[addr2_port]--;
		node->input_pins = realloc(node->input_pins, sizeof(npin_t *) * --node->num_input_pins);
		if ((we1_port != -1) && (we1_pin_idx >= addr2_pin_idx))
			we1_pin_idx--;
		if ((we2_port != -1) && (we2_pin_idx >= addr2_pin_idx))
			we2_pin_idx--;
		if (addr1_pin_idx >= addr2_pin_idx)
			addr1_pin_idx--;
	}

	/* Create the new memory node */
	new_mem_node = allocate_nnode();

	// Append the new name with an __H
	new_mem_node->name = append_string(node->name, "__H");

	{	// Append the old name with an __S
		char *new_name = append_string(node->name, "__S");
		free(node->name);
		node->name = new_name;
	}

	/* Copy properties from the original memory node */
	new_mem_node->type = node->type;
	new_mem_node->related_ast_node = node->related_ast_node;
	new_mem_node->traverse_visited = node->traverse_visited;

	// Copy over the port sizes for the new memory
	for (j = 0; j < node->num_output_port_sizes; j++)
		add_output_port_information(new_mem_node, node->output_port_sizes[j]);
	for (j = 0; j < node->num_input_port_sizes; j++)
		add_input_port_information (new_mem_node, node->input_port_sizes[j]);

	// allocate space for pins.
	allocate_more_node_output_pins (new_mem_node, node->num_output_pins);
	allocate_more_node_input_pins  (new_mem_node, node->num_input_pins);

	// Copy over the pins for the new memory
	for (j = 0; j < node->num_input_pins; j++)
		add_a_input_pin_to_node_spot_idx(new_mem_node, copy_input_npin(node->input_pins[j]), j);

	if (we1_pin != NULL)
	{
		and1_node = make_2port_gate(LOGICAL_AND, 1, 1, 1, node, node->traverse_visited);
		twe_pin = copy_input_npin(we1_pin);
		add_a_input_pin_to_node_spot_idx(and1_node, twe_pin, 1);
		taddr_pin = copy_input_npin(addr1_pin);
		add_a_input_pin_to_node_spot_idx(and1_node, taddr_pin, 0);
		connect_nodes(and1_node, 0, node, we1_pin_idx);
		node->input_pins[we1_pin_idx]->mapping = we1_pin->mapping;
	}

	if (we2_pin != NULL)
	{
		and2_node = make_2port_gate(LOGICAL_AND, 1, 1, 1, node, node->traverse_visited);
		twe_pin = copy_input_npin(we2_pin);
		add_a_input_pin_to_node_spot_idx(and2_node, twe_pin, 1);
		taddr_pin = copy_input_npin(addr2_pin);
		add_a_input_pin_to_node_spot_idx(and2_node, taddr_pin, 0);
		connect_nodes(and2_node, 0, node, we2_pin_idx);
		node->input_pins[we2_pin_idx]->mapping = we2_pin->mapping;
	}

	if (we1_pin != NULL)
	{
		taddr_pin = copy_input_npin(addr1_pin);
		not1_node = make_not_gate_with_input(taddr_pin, new_mem_node, new_mem_node->traverse_visited);
		and1_node = make_2port_gate(LOGICAL_AND, 1, 1, 1, new_mem_node, new_mem_node->traverse_visited);
		connect_nodes(not1_node, 0, and1_node, 0);
		add_a_input_pin_to_node_spot_idx(and1_node, we1_pin, 1);
		connect_nodes(and1_node, 0, new_mem_node, we1_pin_idx);
		new_mem_node->input_pins[we1_pin_idx]->mapping = we1_pin->mapping;
	}

	if (we2_pin != NULL)
	{
		taddr_pin = copy_input_npin(addr2_pin);
		not2_node = make_not_gate_with_input(taddr_pin, new_mem_node, new_mem_node->traverse_visited);
		and2_node = make_2port_gate(LOGICAL_AND, 1, 1, 1, new_mem_node, new_mem_node->traverse_visited);
		connect_nodes(not2_node, 0, and2_node, 0);
		add_a_input_pin_to_node_spot_idx(and2_node, we2_pin, 1);
		connect_nodes(and2_node, 0, new_mem_node, we2_pin_idx);
		new_mem_node->input_pins[we2_pin_idx]->mapping = we2_pin->mapping;
	}

	if (node->num_output_pins > 0) /* There is an "out1" output */
	{
		ff1_node = make_2port_gate(FF_NODE, 1, 1, 1, node, node->traverse_visited);
		add_a_input_pin_to_node_spot_idx(ff1_node, addr1_pin, 0);
		add_a_input_pin_to_node_spot_idx(ff1_node, copy_input_npin(clk_pin), 1);

		/* Copy over the output pins for the new memory */
		for (j = 0; j < node->output_port_sizes[0]; j++)
		{
			mux1_node = make_2port_gate(MUX_2, 2, 2, 1, node, node->traverse_visited);
			connect_nodes(ff1_node, 0, mux1_node, 0);
			not1_node = make_not_gate(node, node->traverse_visited);
			connect_nodes(ff1_node, 0, not1_node, 0);
			connect_nodes(not1_node, 0, mux1_node, 1);
			tdout_pin = node->output_pins[j];
			remap_pin_to_new_node(tdout_pin, mux1_node, 0);
			connect_nodes(node, j, mux1_node, 2);
			node->output_pins[j]->mapping = tdout_pin->mapping;
			connect_nodes(new_mem_node, j, mux1_node, 3);
			new_mem_node->output_pins[j]->mapping = tdout_pin->mapping;
			tdout_pin->mapping = NULL;

			mux1_node->output_pins[0]->name = mux1_node->name;
		}
	}

	if (node->num_output_pins > node->output_port_sizes[0]) /* There is an "out2" output */
	{
		ff2_node = make_2port_gate(FF_NODE, 1, 1, 1, node, node->traverse_visited);
		add_a_input_pin_to_node_spot_idx(ff2_node, addr2_pin, 0);
		add_a_input_pin_to_node_spot_idx(ff2_node, copy_input_npin(clk_pin), 1);

		/* Copy over the output pins for the new memory */
		for (j = 0; j < node->output_port_sizes[0]; j++)
		{
			mux2_node = make_2port_gate(MUX_2, 2, 2, 1, node, node->traverse_visited);
			connect_nodes(ff2_node, 0, mux2_node, 0);
			not2_node = make_not_gate(node, node->traverse_visited);

			connect_nodes(ff2_node, 0, not2_node, 0);
			connect_nodes(not2_node, 0, mux2_node, 1);

			tdout_pin = node->output_pins[node->output_port_sizes[0] + j];
			remap_pin_to_new_node(tdout_pin, mux2_node, 0);

			connect_nodes(node, node->output_port_sizes[0] + j, mux2_node, 2);
			node->output_pins[node->output_port_sizes[0] + j]->mapping = tdout_pin->mapping;
			connect_nodes(new_mem_node, node->output_port_sizes[0] + j, mux2_node, 3);
			new_mem_node->output_pins[node->output_port_sizes[0] + j]->mapping = tdout_pin->mapping;
			tdout_pin->mapping = NULL;

			mux2_node->output_pins[0]->name = mux2_node->name;
		}
	}

	/* must recurse on new memory if it's too small */
	if (logical_size <= split_size) {
		dp_memory_list = insert_in_vptr_list(dp_memory_list, new_mem_node);
		dp_memory_list = insert_in_vptr_list(dp_memory_list, node);
	} else {
		split_dp_memory_depth(node);
		split_dp_memory_depth(new_mem_node);
	}

	return;
}
示例#14
0
/*-------------------------------------------------------------------------
 * (function: split_sp_memory_depth)
 *
 * This function works to split the depth of a single port memory into 
 *   several smaller memories.
 *------------------------------------------------------------------------
 */
void
split_sp_memory_depth(nnode_t *node)
{
	int data_port = -1;
	int clk_port  = -1;
	int addr_port = -1;
	int we_port = -1;
	int logical_size;
	int i, j;
	int idx;
	int addr_pin_idx = 0;
	int we_pin_idx = 0;
	nnode_t *new_mem_node;
	nnode_t *and_node, *not_node,  *mux_node, *ff_node;
	npin_t *addr_pin = NULL;
	npin_t *we_pin = NULL;
	npin_t *clk_pin = NULL;
	npin_t *tdout_pin;


	oassert(node->type == MEMORY);


	// Find which port is the addr port
	idx = 0;
	for (i = 0; i < node->num_input_port_sizes; i++)
	{
		//printf("%s\n", node->input_pins[idx]->mapping);
		if (strcmp("addr", node->input_pins[idx]->mapping) == 0)
		{
			addr_port = i;
			addr_pin_idx = idx;
			addr_pin = node->input_pins[idx];
		}
		else if (strcmp("data", node->input_pins[idx]->mapping) == 0)
		{
			data_port = i;
		}
		else if (strcmp("we", node->input_pins[idx]->mapping) == 0)
		{
			we_port = i;
			we_pin = node->input_pins[idx];
			we_pin_idx = idx;
		}
		else if (strcmp("clk", node->input_pins[idx]->mapping) == 0)
		{
			clk_port = i;
			clk_pin = node->input_pins[idx];
		}
		idx += node->input_port_sizes[i];
	}
	if (data_port == -1)
	{
		error_message(1, 0, -1, "No \"data\" port on single port RAM");
	}
	if (addr_port == -1)
	{
		error_message(1, 0, -1, "No \"addr\" port on single port RAM");
	}
	if (we_port == -1)
	{
		error_message(1, 0, -1, "No \"we\" port on single port RAM");
	}
	if (clk_port == -1)
	{
		error_message(1, 0, -1, "No \"clk\" port on single port RAM");
	}
	
	// Check that the memory needs to be split
	// Jason Luu HACK: Logical memory depth determination messed up, forced to use this method
	for(i = 0; i < node->input_port_sizes[addr_port]; i++)
	{
		if(strcmp(node->input_pins[addr_pin_idx + i]->name, "top^ZERO_PAD_ZERO") == 0)
			break;
	}
	logical_size = i;
	if (split_size <= 0)
	{
		printf("Unsupported feature! Split size must be a positive number\n");
		exit(1);
	}
	if ((split_size > 0) && (logical_size <= split_size)) {
		sp_memory_list = insert_in_vptr_list(sp_memory_list, node);
		return;
	}

	// Let's remove the address line from the memory
	for (i = addr_pin_idx; i < node->num_input_pins - 1; i++)
	{
		node->input_pins[i] = node->input_pins[i+1];
		node->input_pins[i]->pin_node_idx--;
	}
	node->input_port_sizes[addr_port]--;
	node->input_pins = realloc(node->input_pins, sizeof(npin_t *) * --node->num_input_pins);

	if (we_pin_idx >= addr_pin_idx)
		we_pin_idx--;

	// Create the new memory node
	new_mem_node = allocate_nnode();
	// Append the new name with an __H
	new_mem_node->name = append_string(node->name, "__H");

	{	// Append the old name with an __S
		char *new_name = append_string(node->name, "__S");
		free(node->name);
		node->name = new_name;
	}

	// Copy properties from the original memory node
	new_mem_node->type = node->type;
	new_mem_node->related_ast_node = node->related_ast_node;
	new_mem_node->traverse_visited = node->traverse_visited;

	add_output_port_information(new_mem_node, node->num_output_pins);
	allocate_more_node_output_pins (new_mem_node, node->num_output_pins);

	for (j = 0; j < node->num_input_port_sizes; j++)
		add_input_port_information(new_mem_node, node->input_port_sizes[j]);

	// Copy over the input pins for the new memory, excluding we
	allocate_more_node_input_pins (new_mem_node, node->num_input_pins);
	for (j = 0; j < node->num_input_pins; j++)
	{
		if (j != we_pin_idx)
			add_a_input_pin_to_node_spot_idx(new_mem_node, copy_input_npin(node->input_pins[j]), j);
	}

	and_node = make_2port_gate(LOGICAL_AND, 1, 1, 1, node, node->traverse_visited);
	add_a_input_pin_to_node_spot_idx(and_node, we_pin, 1);
	add_a_input_pin_to_node_spot_idx(and_node, addr_pin, 0);
	connect_nodes(and_node, 0, node, we_pin_idx);
	node->input_pins[we_pin_idx]->mapping = we_pin->mapping;

	not_node = make_not_gate_with_input(copy_input_npin(addr_pin), new_mem_node, new_mem_node->traverse_visited);
	and_node = make_2port_gate(LOGICAL_AND, 1, 1, 1, new_mem_node, new_mem_node->traverse_visited);
	connect_nodes(not_node, 0, and_node, 0);
	add_a_input_pin_to_node_spot_idx(and_node, copy_input_npin(we_pin), 1);
	connect_nodes(and_node, 0, new_mem_node, we_pin_idx);
	new_mem_node->input_pins[we_pin_idx]->mapping = we_pin->mapping;

	ff_node = make_2port_gate(FF_NODE, 1, 1, 1, node, node->traverse_visited);
	add_a_input_pin_to_node_spot_idx(ff_node, copy_input_npin(addr_pin), 0);
	add_a_input_pin_to_node_spot_idx(ff_node, copy_input_npin(clk_pin), 1);

	// Copy over the output pins for the new memory
	for (j = 0; j < node->num_output_pins; j++)
	{
		mux_node = make_2port_gate(MUX_2, 2, 2, 1, node, node->traverse_visited);
		connect_nodes(ff_node, 0, mux_node, 0);

		not_node = make_not_gate(node, node->traverse_visited);
		connect_nodes(ff_node, 0, not_node, 0);
		connect_nodes(not_node, 0, mux_node, 1);

		tdout_pin = node->output_pins[j];
		remap_pin_to_new_node(tdout_pin, mux_node, 0);

		connect_nodes(node, j, mux_node, 2);
		node->output_pins[j]->mapping = tdout_pin->mapping;

		connect_nodes(new_mem_node, j, mux_node, 3);
		new_mem_node->output_pins[j]->mapping = tdout_pin->mapping;

		tdout_pin->mapping = NULL;

		mux_node->output_pins[0]->name = mux_node->name;
	}

	// must recurse on new memory if it's too small
	if (logical_size <= split_size) {
		sp_memory_list = insert_in_vptr_list(sp_memory_list, new_mem_node);
		sp_memory_list = insert_in_vptr_list(sp_memory_list, node);
	} else {
		split_sp_memory_depth(node);
		split_sp_memory_depth(new_mem_node);
	}

	return;
}
示例#15
0
/*--------------------------------------------------------------------------
 * (function: instantiate_add_w_carry )
 * 	This is for soft addition in output formats that don't handle 
 *	multi-output logic functions (BLIF).  We use one function for the 
 *	add, and one for the carry.
 *------------------------------------------------------------------------*/
void instantiate_add_w_carry(nnode_t *node, short mark, netlist_t *netlist)
{
	int width;
	int width_a;
	int width_b;
	int i;
	nnode_t **new_add_cells;
	nnode_t **new_carry_cells;

	oassert(node->num_input_pins > 0);
	oassert(node->num_input_port_sizes == 2);
	width = node->output_port_sizes[0];
	width_a = node->input_port_sizes[0];
	width_b = node->input_port_sizes[1];

	new_add_cells  = (nnode_t**)malloc(sizeof(nnode_t*)*width);
	new_carry_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width);

	/* create the adder units and the zero unit */
	for (i = 0; i < width; i++)
	{
		new_add_cells[i] = make_3port_gate(ADDER_FUNC, 1, 1, 1, 1, node, mark);
		// The last carry cell will be connected to an output pin, if one is available
		new_carry_cells[i] = make_3port_gate(CARRY_FUNC, 1, 1, 1, 1, node, mark);

	}

    	/* ground first carry in */
	add_a_input_pin_to_node_spot_idx(new_add_cells[0], get_a_zero_pin(netlist), 0);
	if (i > 1)
	{
		add_a_input_pin_to_node_spot_idx(new_carry_cells[0], get_a_zero_pin(netlist), 0);
	}

	/* connect inputs */
	for(i = 0; i < width; i++)
	{
		//printf("%s\n", node->input_pins[i]->name);

		if (i < width_a)
		{
			/* join the A port up to adder */
			remap_pin_to_new_node(node->input_pins[i], new_add_cells[i], 1);
			if (i < width - 1)
				add_a_input_pin_to_node_spot_idx(new_carry_cells[i], copy_input_npin(new_add_cells[i]->input_pins[1]), 1);
		}
		else 
		{
			add_a_input_pin_to_node_spot_idx(new_add_cells[i], get_a_zero_pin(netlist), 1);
			if (i < width - 1)
				add_a_input_pin_to_node_spot_idx(new_carry_cells[i], get_a_zero_pin(netlist), 1);
		}

		if (i < width_b)
		{
			/* join the B port up to adder */
			remap_pin_to_new_node(node->input_pins[i+width_a], new_add_cells[i], 2);
			if (i < width - 1)
				add_a_input_pin_to_node_spot_idx(new_carry_cells[i], copy_input_npin(new_add_cells[i]->input_pins[2]), 2);
		}
		else
		{
			add_a_input_pin_to_node_spot_idx(new_add_cells[i], get_a_zero_pin(netlist), 2);
			if (i < width - 1)
				add_a_input_pin_to_node_spot_idx(new_carry_cells[i], get_a_zero_pin(netlist), 2);
		}

		/* join that gate to the output */
		remap_pin_to_new_node(node->output_pins[i], new_add_cells[i], 0);
	}
	
	/* connect carry outs with carry ins */
	for(i = 1; i < width; i++)
	{
		connect_nodes(new_carry_cells[i-1], 0, new_add_cells[i], 0);
		if (i < width - 1)
			connect_nodes(new_carry_cells[i-1], 0, new_carry_cells[i], 0);
	}

	free(new_add_cells);
	free(new_carry_cells);
}
示例#16
0
/*---------------------------------------------------------------------------------------------
 * (function:  instantiate_unary_sub )
 *	Does 2's complement which is the equivalent of a unary subtraction as a HW implementation.	
 *-------------------------------------------------------------------------------------------*/
void instantiate_unary_sub(nnode_t *node, short mark, netlist_t *netlist)
{
	int width;
	int i;
	nnode_t **new_add_cells;
	nnode_t **new_carry_cells;
	nnode_t **new_not_cells;

	oassert(node->num_input_pins > 0);
	oassert(node->num_input_port_sizes == 1);
	width = node->output_port_sizes[0];

	new_add_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width);
	new_carry_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width);
	new_not_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width);

	/* create the adder units and the zero unit */
	for (i = 0; i < width; i++)
	{
		new_add_cells[i] = make_3port_gate(ADDER_FUNC, 1, 1, 1, 1, node, mark);
		new_not_cells[i] = make_not_gate(node, mark);
		if (i < width - 1)
		{
			new_carry_cells[i] = make_3port_gate(CARRY_FUNC, 1, 1, 1, 1, node, mark);
		}
	}

    	/* ground first carry in .  Note the one constant is inputted to start 2's complement */
	add_a_input_pin_to_node_spot_idx(new_add_cells[0], get_a_one_pin(netlist), 0);
	if (i > 1)
	{
		add_a_input_pin_to_node_spot_idx(new_carry_cells[0], get_a_one_pin(netlist), 0);
	}

	/* connect inputs */
	for(i = 0; i < width; i++)
	{
		/* join the A port up to adder */
		remap_pin_to_new_node(node->input_pins[i], new_not_cells[i], 0);
		connect_nodes(new_not_cells[i], 0, new_add_cells[i], 1);
		if (i < width - 1)
			connect_nodes(new_not_cells[i], 0, new_carry_cells[i], 1);

		add_a_input_pin_to_node_spot_idx(new_add_cells[i], get_a_zero_pin(netlist), 2);
		if (i < width - 1)
			add_a_input_pin_to_node_spot_idx(new_carry_cells[i], get_a_zero_pin(netlist), 2);

		/* join that gate to the output */
		remap_pin_to_new_node(node->output_pins[i], new_add_cells[i], 0);
	}
	
	/* connect carry outs with carry ins */
	for(i = 1; i < width; i++)
	{
		connect_nodes(new_carry_cells[i-1], 0, new_add_cells[i], 0);
		if (i < width - 1)
			connect_nodes(new_carry_cells[i-1], 0, new_carry_cells[i], 0);
	}

	free(new_add_cells);
	free(new_carry_cells);
}
void iterate_node_3(node_t *node)
{
	int action;

	action = get_action_3(node);

	switch (action) {
		case 0:
			node->link_1->value = node->value;
		case 9:
			connect_nodes(node, node->link_0, node->link_1);
			swap_nodes(node, node->link_2);
			break;
		case 1:
			node->link_2->value = node->value;
		case 10:
			connect_nodes(node, node->link_1, node->link_2);
			swap_nodes(node, node->link_0);
			break;
		case 2:
			node->link_0->value = node->value;
		case 11:
			connect_nodes(node, node->link_2, node->link_0);
			swap_nodes(node, node->link_1);
			break;

		case 3:
			disconnect_nodes(node, node->link_0);
		case 12:
			swap_nodes(node, node->link_0);
			break;
		case 4:
			disconnect_nodes(node, node->link_1);
		case 13:
			swap_nodes(node, node->link_1);
			break;
		case 5:
			disconnect_nodes(node, node->link_2);
		case 14:
			swap_nodes(node, node->link_2);
			break;

		case 6:
		case 15:
			swap_values(node, node->link_0);
			break;
		case 7:
			swap_values(node, node->link_1);
			break;
		case 8:
			swap_values(node, node->link_2);
			break;
	}
	/*
	  node->value = 0;
	  node->value = 1;
	  invert_value(node);
	  disconnect_nodes(node, node->link_0);
	  disconnect_nodes(node, node->link_1);
	  disconnect_nodes(node, node->link_2);
	  connect_nodes(node, node->link_0, node->link_1);
	  connect_nodes(node, node->link_1, node->link_2);
	  connect_nodes(node, node->link_2, node->link_0);
	  swap_values(node, node->link_0);
	  swap_values(node, node->link_1);
	  swap_values(node, node->link_2);
	  node->link_0->value = node->value;
	  node->link_0->value = 0;
	  node->link_0->value = 1;
	  node->link_0->value = inverted_value(node);
	  node->link_1->value = node->value;
	  node->link_1->value = 0;
	  node->link_1->value = 1;
	  node->link_1->value = inverted_value(node);
	  node->link_2->value = node->value;
	  node->link_2->value = 0;
	  node->link_2->value = 1;
	  node->link_2->value = inverted_value(node);
	  swap_nodes(node, node->link_0);
	  swap_nodes(node, node->link_1);
	  swap_nodes(node, node->link_2);
	*/
}
示例#18
0
/*---------------------------------------------------------------------------------------------
 * (function: instantiate_GT )
 *	Defines the HW needed for greter than equal with EQ, GT, AND and OR gates to create
 *	the appropriate logic function.
 *-------------------------------------------------------------------------------------------*/
void instantiate_GT(nnode_t *node, short type, short mark, netlist_t *netlist)
{
	int width_a;
	int width_b;
	int width_max;
	int i;
	int port_A_offset;
	int port_B_offset;
	int port_A_index;
	int port_B_index;
	int index = 0;
	nnode_t *xor_gate;
	nnode_t *logical_or_gate;
	nnode_t **or_cells;
	nnode_t **gt_cells;

	oassert(node->num_output_pins == 1);
	oassert(node->num_input_pins > 0);
	oassert(node->num_input_port_sizes == 2);
	oassert(node->input_port_sizes[0] == node->input_port_sizes[1]);
	width_a = node->input_port_sizes[0];
	width_b = node->input_port_sizes[1];
	width_max = width_a > width_b ? width_a : width_b;

	/* swaps ports A and B */
	if (type == GT)
	{
		port_A_offset = 0;
		port_B_offset = width_a;
		port_A_index = 0;
		port_B_index = width_a-1;
	}
	else if (type == LT)
	{
		port_A_offset = width_b;
		port_B_offset = 0;
		port_A_index = width_b-1;
		port_B_index = 0;
	}
	else
	{
		port_A_offset = 0;
		port_B_offset = 0;
		port_A_index = 0;
		port_B_index = 0;
		error_message(NETLIST_ERROR, node->related_ast_node->line_number, node->related_ast_node->file_number, "Invalid node type in instantiate_GT\n");
	}

	/* xor gate identifies if any bits don't match */
	xor_gate = make_2port_gate(LOGICAL_XOR, width_a-1, width_b-1, width_max-1, node, mark);
	/* collects all the GT signals and determines if gt */
	logical_or_gate = make_1port_logic_gate(LOGICAL_OR, width_max, node, mark);
	/* collects a chain if any 1 happens than the GT cells output 0 */
	or_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width_max-1);
	/* each cell checks if A > B and sends out a 1 if history has no 1s (3rd input) */
	gt_cells = (nnode_t**)malloc(sizeof(nnode_t*)*width_max);

	for (i = 0; i < width_max; i++)
	{
		gt_cells[i] = make_3port_gate(GT, 1, 1, 1, 1, node, mark);
		if (i < width_max-1)
		{
			or_cells[i] = make_2port_gate(LOGICAL_OR, 1, 1, 1, node, mark);
		}
	}

	/* connect inputs.  In the case that a signal is smaller than the other then zero pad */
	for(i = 0; i < width_max; i++)
	{
		/* Joining the inputs to the input 1 of that gate */
		if (i < width_a)
		{
			/* IF - this current input will also have a corresponding b_port input then join it to the gate */
			remap_pin_to_new_node(node->input_pins[i+port_A_offset], gt_cells[i], 0);
			if (i > 0)
				add_a_input_pin_to_node_spot_idx(xor_gate, copy_input_npin(gt_cells[i]->input_pins[0]), index+port_A_index);
		}
		else
		{
			/* ELSE - the B input does not exist, so this answer goes right through */
			add_a_input_pin_to_node_spot_idx(gt_cells[i], get_a_zero_pin(netlist), 0);
			if (i > 0)
				add_a_input_pin_to_node_spot_idx(xor_gate, get_a_zero_pin(netlist), index+port_A_index);
		}

		if (i < width_b)
		{
			/* IF - this current input will also have a corresponding a_port input then join it to the gate */
			/* Joining the inputs to the input 2 of that gate */
			remap_pin_to_new_node(node->input_pins[i+port_B_offset], gt_cells[i], 1);
			if (i > 0)
				add_a_input_pin_to_node_spot_idx(xor_gate, copy_input_npin(gt_cells[i]->input_pins[1]), index+port_B_index);
		}
		else
		{
			/* ELSE - the A input does not exist, so this answer goes right through */
			add_a_input_pin_to_node_spot_idx(gt_cells[i], get_a_zero_pin(netlist), 1);
			if (i > 0)
				add_a_input_pin_to_node_spot_idx(xor_gate, get_a_zero_pin(netlist), index+port_B_index);
		}

		if (i < width_max-1)
		{
			/* number of OR gates */
			if (i < width_max-2)
			{
				/* connect the msb or to the next lower bit */
				connect_nodes(or_cells[i+1], 0, or_cells[i], 1);
			}
			else
			{
				/* deal with the first greater than test which autom gets a zero */
				add_a_input_pin_to_node_spot_idx(or_cells[i], get_a_zero_pin(netlist), 1);
			}

			/* get all the equals with the or gates */
			connect_nodes(xor_gate, i, or_cells[i], 0);
			connect_nodes(or_cells[i], 0, gt_cells[i], 2);
			
		}
		else
		{
			/* deal with the first greater than test which autom gets a zero */
			add_a_input_pin_to_node_spot_idx(gt_cells[i], get_a_zero_pin(netlist), 2);
		}

		/* hook it up to the logcial AND */
		connect_nodes(gt_cells[i], 0, logical_or_gate, i);

		if (i > 0)
		{
			index++;
		}
	}

	/* join that gate to the output */
	remap_pin_to_new_node(node->output_pins[0], logical_or_gate, 0);
	oassert(logical_or_gate->num_output_pins == 1);

	instantiate_bitwise_logic(xor_gate, BITWISE_XOR, mark, netlist);
}
示例#19
0
/*---------------------------------------------------------------------------
 * (function: instantiate_simple_soft_multiplier )
 * Sample 4x4 multiplier to help understand logic.
 *
 * 					a3 	a2	a1	a0 
 *					b3 	b2 	b1 	b0
 *					---------------------------
 *					c03	c02	c01	c00
 *			+	c13	c12	c11	c10
 *			-----------------------------------	
 *			r14	r13	r12	r11	r10
 *		+	c23	c22	c21	c20
 *		-----------------------------------
 *		r24	r23	r22	r21	r20
 *	+	c33	c32	c31	c30
 *	------------------------------------
 *	o7	o6	o5	o4	o3	o2	o1	o0
 *
 *	In the first case will be c01
 *-------------------------------------------------------------------------*/
void instantiate_simple_soft_multiplier(nnode_t *node, short mark, netlist_t *netlist)
{
	int width_a;
	int width_b;
	int width;
	int multiplier_width;
	int multiplicand_width;
	nnode_t **adders_for_partial_products;
	nnode_t ***partial_products;
	int multiplicand_offset_index;
	int multiplier_offset_index;
	int current_index;
	int i, j;

	/* need for an carry-ripple-adder for each of the bits of port B. */
	/* good question of which is better to put on the bottom of multiplier.  Larger means more smaller adds, or small is 
	 * less large adds */
	oassert(node->num_output_pins > 0);
	oassert(node->num_input_pins > 0);
	oassert(node->num_input_port_sizes == 2);
	oassert(node->num_output_port_sizes == 1);
	width_a = node->input_port_sizes[0];
	width_b = node->input_port_sizes[1];
	width = node->output_port_sizes[0];
	multiplicand_width = width_b;
	multiplier_width = width_a;
	/* offset is related to which multport is chosen as the multiplicand */
	multiplicand_offset_index = width_a;
	multiplier_offset_index = 0;

	adders_for_partial_products = (nnode_t**)malloc(sizeof(nnode_t*)*multiplicand_width-1);

	/* need to generate partial products for each bit in width B. */
	partial_products = (nnode_t***)malloc(sizeof(nnode_t**)*multiplicand_width);

	/* generate the AND partial products */
	for (i = 0; i < multiplicand_width; i++)
	{
		/* create the memory for each AND gate needed for the levels of partial products */
		partial_products[i] = (nnode_t**)malloc(sizeof(nnode_t*)*multiplier_width);
		
		if (i < multiplicand_width - 1)
		{
			adders_for_partial_products[i] = make_2port_gate(ADD, multiplier_width+1, multiplier_width+1, multiplier_width+1, node, mark);
		}

		for (j = 0; j < multiplier_width; j++)
		{
			/* create each one of the partial products */
			partial_products[i][j] = make_1port_logic_gate(LOGICAL_AND, 2, node, mark);
		}
	}

	/* generate the coneections to the AND gates */
	for (i = 0; i < multiplicand_width; i++)
	{
		for (j = 0; j < multiplier_width; j++)
		{
			/* hookup the input of B to each AND gate */
			if (j == 0)
			{
				/* IF - this is the first time we are mapping multiplicand port then can remap */ 
				remap_pin_to_new_node(node->input_pins[i+multiplicand_offset_index], partial_products[i][j], 0);
			}
			else
			{
				/* ELSE - this needs to be a new ouput of the multiplicand port */
				add_input_pin_to_node(partial_products[i][j], copy_input_npin(partial_products[i][0]->input_pins[0]), 0);
			}

			/* hookup the input of the multiplier to each AND gate */
			if (i == 0)
			{
				/* IF - this is the first time we are mapping multiplier port then can remap */ 
				remap_pin_to_new_node(node->input_pins[j+multiplier_offset_index], partial_products[i][j], 1);
			}
			else
			{
				/* ELSE - this needs to be a new ouput of the multiplier port */
				add_input_pin_to_node(partial_products[i][j], copy_input_npin(partial_products[0][j]->input_pins[1]), 1);
			}
		}
	}

	/* hookup each of the adders */
	for (i = 0; i < multiplicand_width-1; i++) // -1 since the first stage is a combo of partial products while all others are part of tree
	{
		for (j = 0; j < multiplier_width+1; j++) // +1 since adders are one greater than multwidth to pass carry
		{
			/* join to port 1 of the add one of the partial products.  */
			if (i == 0)
			{
				/* IF - this is the first addition row, then adding two sets of partial products and first set is from the c0* */
				if (j < multiplier_width-1)
				{
					/* IF - we just take an element of the first list c[0][j+1]. */
					connect_nodes(partial_products[i][j+1], 0, adders_for_partial_products[i], j);
				}
				else
				{
					/* ELSE - this is the last input to the first adder, then we pass in 0 since no carry yet */
					add_input_pin_to_node(adders_for_partial_products[i], get_zero_pin(netlist), j);
				}
			}
			else if (j < multiplier_width)
			{
				/* ELSE - this is the standard situation when we need to hookup this adder with a previous adder, r[i-1][j+1] */
				connect_nodes(adders_for_partial_products[i-1], j+1, adders_for_partial_products[i], j);
			}
			else
			{
				add_input_pin_to_node(adders_for_partial_products[i], get_zero_pin(netlist), j);
			}
			
			if (j < multiplier_width)
			{
				/* IF - this is not most significant bit then just add current partial product */
				connect_nodes(partial_products[i+1][j], 0, adders_for_partial_products[i], j+multiplier_width+1);
			}
			else
			{
				add_input_pin_to_node(adders_for_partial_products[i], get_zero_pin(netlist), j+multiplier_width+1);
			}
		}
	}

	current_index = 0;
	/* hookup the outputs */
	for (i = 0; i < width; i++)
	{
		if (multiplicand_width == 1)
		{
			// this is undealt with
			error_message(1,-1,-1,"Cannot create soft multiplier with multiplicand width of 1.\n");
		}
		else if (i == 0)
		{
			/* IF - this is the LSbit, then we use a pass through from the partial product */
			remap_pin_to_new_node(node->output_pins[i], partial_products[0][0], 0);
		}
		else if (i < multiplicand_width - 1)
		{
			/* ELSE IF - these are the middle values that come from the LSbit of partial adders */
			remap_pin_to_new_node(node->output_pins[i], adders_for_partial_products[i-1], 0);
		}
		else 
		{
			/* ELSE - the final outputs are straight from the outputs of the last adder */
			remap_pin_to_new_node(node->output_pins[i], adders_for_partial_products[multiplicand_width-2], current_index);
			current_index++;
		}
	}

	/* soft map the adders if they need to be mapped */
	for (i = 0; i < multiplicand_width - 1; i++)
	{
		instantiate_add_w_carry(adders_for_partial_products[i], mark, netlist);
	}

	/* Cleanup everything */
	if (adders_for_partial_products != NULL)
	{
		free(adders_for_partial_products);
	}
	/* generate the AND partial products */
	for (i = 0; i < multiplicand_width; i++)
	{
		/* create the memory for each AND gate needed for the levels of partial products */
		if (partial_products[i] != NULL)
		{
			free(partial_products[i]);
		}
	}
	if (partial_products != NULL)
	{
		free(partial_products);
	}
}