/*--------------------------------------------------------------------------------------------- * (function: make_1port_logic_gate_with_inputs) * Make a gate with variable sized inputs, 1 output, and connect to the supplied inputs *-------------------------------------------------------------------------------------------*/ nnode_t *make_1port_logic_gate_with_inputs(operation_list type, int width, signal_list_t *pin_list, nnode_t *node, short mark) { nnode_t *logic_node; int i; logic_node = make_1port_gate(type, width, 1, node, mark); /* hookup all the pins */ for (i = 0; i < width; i++) { add_input_pin_to_node(logic_node, pin_list->pins[i], i); } return logic_node; }
/*--------------------------------------------------------------------------------------------- * (function: instantiate_shift_left_or_right ) * Creates the hardware for a shift left or right operation by a constant size. *-------------------------------------------------------------------------------------------*/ void instantiate_shift_left_or_right(nnode_t *node, short type, short mark, netlist_t *netlist) { /* these variables are used in an attempt so that I don't need if cases. Probably a bad idea, but fun */ int width; int i; int shift_size; nnode_t *buf_node; width = node->input_port_sizes[0]; if (node->related_ast_node->children[1]->type == NUMBERS) { /* record the size of the shift */ shift_size = node->related_ast_node->children[1]->types.number.value; } else { shift_size = 0; error_message(NETLIST_ERROR, node->related_ast_node->line_number, node->related_ast_node->file_number, "Odin only supports constant shifts at present\n"); } buf_node = make_1port_gate(BUF_NODE, width, width, node, mark); if (type == SL) { /* IF shift left */ /* connect inputs to outputs */ for(i = 0; i < width - shift_size; i++) { // connect higher output pin to lower input pin remap_pin_to_new_node(node->input_pins[i], buf_node, i+shift_size); } /* connect ZERO to outputs that don't have inputs connected */ for(i = 0; i < shift_size; i++) { // connect 0 to lower outputs add_a_input_pin_to_node_spot_idx(buf_node, get_a_zero_pin(netlist), i); } for(i = width-1; i >= width-shift_size; i--) { /* demap the node from the net */ int idx_2_buffer = node->input_pins[i]->pin_net_idx; node->input_pins[i]->net->fanout_pins[idx_2_buffer] = NULL; } } else { /* ELSE shift right */ /* connect inputs to outputs */ for(i = width - 1; i >= shift_size; i--) { // connect higher input pin to lower output pin remap_pin_to_new_node(node->input_pins[i], buf_node, i-shift_size); } /* connect ZERO to outputs that don't have inputs connected */ for(i = width - 1; i >= width - shift_size; i--) { // connect 0 to lower outputs add_a_input_pin_to_node_spot_idx(buf_node, get_a_zero_pin(netlist), i); } for(i = 0; i < shift_size; i++) { /* demap the node from the net */ int idx_2_buffer = node->input_pins[i]->pin_net_idx; node->input_pins[i]->net->fanout_pins[idx_2_buffer] = NULL; } } for(i = 0; i < width; i++) { remap_pin_to_new_node(node->output_pins[i], buf_node, i); } /* instantiate the buffer */ instantiate_buffer(buf_node, mark, netlist); }
/*--------------------------------------------------------------------------------------------- * (function: make_1port_logic_gate) * Make a gate with variable sized inputs and 1 output *-------------------------------------------------------------------------------------------*/ nnode_t *make_1port_logic_gate(operation_list type, int width, nnode_t *node, short mark) { nnode_t *logic_node = make_1port_gate(type, width, 1, node, mark); return logic_node; }