OpenFPGA/vpr7_x2p/vpr/SRC/mrfpga/mrfpga_api.c

143 lines
5.8 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
/* libarchfpga data structures*/
#include "util.h"
#include "physical_types.h"
/* END */
/* VPR data structures*/
#include "vpr_types.h"
#include "globals.h"
#include "rr_graph.h"
#include "vpr_utils.h"
/* END */
/* mrFPGA: Xifan TANG*/
#include "mrfpga_globals.h"
#include "mrfpga_util.h"
#include "buffer_insertion.h"
#include "cal_capacitance.h"
#include "mrfpga_api.h"
/***** Subroutines *****/
/* Copy the contents in arch_mrfpga to globals*/
void sync_arch_mrfpga_globals(t_arch_mrfpga arch_mrfpga) {
/* Booleans */
is_isolation = arch_mrfpga.is_isolation;
is_stack = arch_mrfpga.is_stack;
is_junction = arch_mrfpga.is_junction;
is_wire_buffer = arch_mrfpga.is_wire_buffer;
is_mrFPGA = arch_mrfpga.is_mrFPGA;
/* Copy some struct*/
wire_buffer_inf = arch_mrfpga.wire_buffer_inf;
memristor_inf = arch_mrfpga.memristor_inf;
max_pins_per_side = arch_mrfpga.max_pins_per_side;
main_best_buffer_list = arch_mrfpga.main_best_buffer_list;
num_normal_switch = arch_mrfpga.num_normal_switch;
start_seg_switch = arch_mrfpga.start_seg_switch;
/* SRAM and Pass Transistor Usage*/
is_show_sram = arch_mrfpga.is_show_sram;
is_show_pass_trans = arch_mrfpga.is_show_pass_trans;
Rseg_global = arch_mrfpga.Rseg_global;
Cseg_global = arch_mrfpga.Cseg_global;
return;
}
/* Get the switch type for mrFPGA: Xifan TANG
* This function is called rr_graph2.c but I move it here
* so that it is easy to see mrFPGA modifications
*/
void get_mrfpga_switch_type(boolean is_from_sbox,
boolean is_to_sbox,
short from_node_switch,
short to_node_switch,
short switch_types[2]) {
/* This routine looks at whether the from_node and to_node want a switch, *
* and what type of switch is used to connect *to* each type of node *
* (from_node_switch and to_node_switch). It decides what type of switch, *
* if any, should be used to go from from_node to to_node. If no switch *
* should be inserted (i.e. no connection), it returns OPEN. Its returned *
* values are in the switch_types array. It needs to return an array *
* because one topology (a buffer in the forward direction and a pass *
* transistor in the backward direction) results in *two* switches. */
/* modified by bjxiao to make the pass transistors accepted */
/* the original version has bugs */
/* this version is copied from VPR4.3 */
switch_types[0] = OPEN; /* No switch */
switch_types[1] = OPEN;
if (!is_from_sbox && !is_to_sbox) { /* No connection wanted in either dir */
switch_types[0] = OPEN;
}
else if (is_from_sbox && !is_to_sbox) { /* Only forward connection wanted */
switch_types[0] = to_node_switch; /* Type of switch to go *to* to_node */
}
else if (!is_from_sbox && is_to_sbox) {
/* Only backward connection desired. We're deciding whether or not to put *
* in the forward connection. Put it in if the backward connection uses *
* a bidirectional (pass transistor) switch. Remember that the backward *
* connection uses a from_node_switch type of switch. */
if ( switch_inf[from_node_switch].buffered == FALSE) {
switch_types[0] = from_node_switch;
}
} else {
/* Both a forward and a backward connection desired. If the switch types *
* desired for the two connection are different, we have to reconcile them. */
if (from_node_switch == to_node_switch) {
switch_types[0] = to_node_switch;
} else { /* Different switch types. Reconcile. */
if (switch_inf[to_node_switch].buffered) {
switch_types[0] = to_node_switch;
if ( switch_inf[from_node_switch].buffered == FALSE) {
/* Buffer in forward direction, pass transistor in backward. Put *
* in *two* edges. */
switch_types[1] = from_node_switch;
}
} else { /* Forward connection is a pass transistor. */
if (switch_inf[from_node_switch].buffered) {
switch_types[0] = to_node_switch;
} else {
/* Both forward and backward connections use pass transistors. *
* use whichever one is larger, since you'll only physically *
* build one switch. */
if (switch_inf[to_node_switch].R <
switch_inf[from_node_switch].R) {
switch_types[0] = to_node_switch;
} else if (switch_inf[from_node_switch].R <
switch_inf[to_node_switch].R) {
switch_types[0] = from_node_switch;
} else {
/* Two pass transistors have the same R, but are have different *
* switch indices. Use the one with lower index (arbitrarily), *
* to ensure both switches are of the same type (since you can *
* only physically build one). I'm being pretty dogmatic here. */
if (to_node_switch < from_node_switch) {
switch_types[0] = to_node_switch;
} else {
switch_types[0] = from_node_switch;
}
}
}
}
} /* End switch types are different */
} /* End both forward and backward connection desired. */
/* end */
}