/*------------------------------------------------------------------------- * (function: clean_memories) * * Clean up the memory by deleting the list structure of memories * during optimization. *-----------------------------------------------------------------------*/ void clean_memories() { while (sp_memory_list != NULL) sp_memory_list = delete_in_vptr_list(sp_memory_list); while (dp_memory_list != NULL) dp_memory_list = delete_in_vptr_list(dp_memory_list); }
/*------------------------------------------------------------------------- * (function: clean_multipliers) * * Clean up the memory by deleting the list structure of multipliers * during optimization *-----------------------------------------------------------------------*/ void clean_multipliers() { while (mult_list != NULL) mult_list = delete_in_vptr_list(mult_list); return; }
/*------------------------------------------------------------------------- * (function: iterate_multipliers) * * This function will iterate over all of the multiply operations that * exist in the netlist and perform a splitting so that they can * fit into a basic hard multiplier block that exists on the FPGA. * If the proper option is set, then it will be expanded as well * to just use a fixed size hard multiplier. *-----------------------------------------------------------------------*/ void iterate_multipliers(netlist_t *netlist) { int sizea, sizeb, swap; int mula, mulb; int a0, a1, b0, b1; nnode_t *node; /* Can only perform the optimisation if hard multipliers exist! */ if (hard_multipliers == NULL) return; sizea = hard_multipliers->inputs->size; sizeb = hard_multipliers->inputs->next->size; if (sizea < sizeb) { swap = sizea; sizea = sizeb; sizeb = swap; } while (mult_list != NULL) { node = (nnode_t *)mult_list->data_vptr; mult_list = delete_in_vptr_list(mult_list); oassert(node != NULL); if (node->type == HARD_IP) node->type = MULTIPLY; oassert(node->type == MULTIPLY); mula = node->input_port_sizes[0]; mulb = node->input_port_sizes[1]; if (mula < mulb) { swap = sizea; sizea = sizeb; sizeb = swap; } /* Do I need to split the multiplier on both inputs? */ if ((mula > sizea) && (mulb > sizeb)) { a0 = sizea; a1 = mula - sizea; b0 = sizeb; b1 = mulb - sizeb; split_multiplier(node, a0, b0, a1, b1); } else if (mula > sizea) /* split multiplier on a input? */ { a0 = sizea; a1 = mula - sizea; split_multiplier_a(node, a0, a1, mulb); } else if (mulb > sizeb) /* split multiplier on b input? */ { b1 = sizeb; b0 = mulb - sizeb; split_multiplier_b(node, mula, b0, b1); } else if ((sizea >= min_mult) && (sizeb >= min_mult)) { /* Check to ensure IF mult needs to be exact size */ if(configuration.fixed_hard_multiplier != 0) pad_multiplier(node, netlist); } } return; }
/*------------------------------------------------------------------------- * (function: iterate_memories) * * This function will iterate over all of the memory hard blocks that * exist in the netlist and perform a splitting so that they can * be easily packed into hard memory blocks on the FPGA. *-----------------------------------------------------------------------*/ void iterate_memories(netlist_t *netlist) { nnode_t *node; struct s_linked_vptr *temp; /* Split it up on depth */ if (configuration.split_memory_depth != 0) { /* Jason Luu: HACK detected: split_size should NOT come from configuration.split_memory_depth, it should come from the maximum model size for the port, IMPORTANT TODO!!!! */ split_size = configuration.split_memory_depth; temp = sp_memory_list; sp_memory_list = NULL; while (temp != NULL) { node = (nnode_t *)temp->data_vptr; oassert(node != NULL); oassert(node->type == MEMORY); temp = delete_in_vptr_list(temp); split_sp_memory_depth(node); } temp = dp_memory_list; dp_memory_list = NULL; while (temp != NULL) { node = (nnode_t *)temp->data_vptr; oassert(node != NULL); oassert(node->type == MEMORY); temp = delete_in_vptr_list(temp); split_dp_memory_depth(node); } } /* Split memory up on width */ if (configuration.split_memory_width) { temp = sp_memory_list; sp_memory_list = NULL; while (temp != NULL) { node = (nnode_t *)temp->data_vptr; oassert(node != NULL); oassert(node->type == MEMORY); temp = delete_in_vptr_list(temp); split_sp_memory_width(node); } temp = dp_memory_list; dp_memory_list = NULL; while (temp != NULL) { node = (nnode_t *)temp->data_vptr; oassert(node != NULL); oassert(node->type == MEMORY); temp = delete_in_vptr_list(temp); split_dp_memory_width(node); } } else { temp = sp_memory_list; sp_memory_list = NULL; while (temp != NULL) { node = (nnode_t *)temp->data_vptr; oassert(node != NULL); oassert(node->type == MEMORY); temp = delete_in_vptr_list(temp); split_sp_memory_to_arch_width(node); } temp = sp_memory_list; sp_memory_list = NULL; while (temp != NULL) { node = (nnode_t *)temp->data_vptr; oassert(node != NULL); oassert(node->type == MEMORY); temp = delete_in_vptr_list(temp); pad_sp_memory_width(node, netlist); } temp = dp_memory_list; dp_memory_list = NULL; while (temp != NULL) { node = (nnode_t *)temp->data_vptr; oassert(node != NULL); oassert(node->type == MEMORY); temp = delete_in_vptr_list(temp); split_dp_memory_to_arch_width(node); } temp = dp_memory_list; dp_memory_list = NULL; while (temp != NULL) { node = (nnode_t *)temp->data_vptr; oassert(node != NULL); oassert(node->type == MEMORY); temp = delete_in_vptr_list(temp); pad_dp_memory_width(node, netlist); } } return; }