blob: 952e9b7e0eba784ae7f6902bc66a53babc66e894 [file] [log] [blame]
/* Jason Luu
June 26, 2013
Carry chain arch generator. Creates arch files of fracturable 6-LUTs with varying parameters. Each fracturable 6-LUT can operate as one 6-LUT or two 5 LUTs with shared inputs.
The number of pins in dual 5-LUT mode is labelled FI where an FI = 5 means all 5 pins of the dual 5-LUTs are shared and an FI = 10 means no pins are shared.
Each 5-LUT can operate in arithmetic mode which consists of a one-bit full adder that is fed by two 4-lUTs with all 4 inputs shared. The adder cout pin drives the cin pin of the adjacent adder directly below.
FI varies from 5 to 10 and inputs to CLB (I) varies from 50 to 100
To run, enter: ./gen_c_chain_arch_sweep
*/
#include <stdio.h>
#include <assert.h>
static void print_header(FILE *fpout);
static void print_clb(FILE *fpout, int FI, int clbI);
static void print_footer(FILE *fpout);
int main(void) {
FILE *fpout;
char fname[100]; /* Architecture file name */
/* Create architectures sweeping through all FI from 5 to 10 and CLB inputs 50, 60, 70, 80, 90, 100 */
for(int i_FI = 5; i_FI <= 10; i_FI++) {
for(int i_clbI = 50; i_clbI <= 100; i_clbI += 10) {
/* Open arch file for writing */
sprintf(fname, "chain_FI%d_I%d.xml", i_FI, i_clbI);
fpout = fopen(fname, "w");
/* Populate arch file */
print_header(fpout);
print_clb(fpout, i_FI, i_clbI);
print_footer(fpout);
/* Close arch file */
fclose(fpout);
}
}
return 0;
}
static void print_header(FILE *fpout) {
fprintf(fpout, "<!-- \n");
fprintf(fpout, " Flagship Heterogeneous Architecture with Carry Chains for VTR 7.0.\n");
fprintf(fpout, "\n");
fprintf(fpout, " - 40 nm technology\n");
fprintf(fpout, " - General purpose logic block: \n");
fprintf(fpout, " K = 6, N = 10, fracturable 6 LUTs (can operate as one 6-LUT or two 5-LUTs with all 5 inputs shared) \n");
fprintf(fpout, " with optionally registered outputs\n");
fprintf(fpout, " Each 5-LUT has an arithemtic mode that converts it to a single-bit adder with both inputs driven by 4-LUTs (both 4-LUTs share all 4 inputs)\n");
fprintf(fpout, " Carry chain links to vertically adjacent logic blocks\n");
fprintf(fpout, " - Memory size 32 Kbits, memory aspect ratios vary from a data width of 1 to data width of 64. \n");
fprintf(fpout, " Height = 6, found on every (8n+2)th column\n");
fprintf(fpout, " - Multiplier modes: one 36x36, two 18x18, each 18x18 can also operate as two 9x9. \n");
fprintf(fpout, " Height = 4, found on every (8n+6)th column\n");
fprintf(fpout, " - Routing architecture: L = 4, fc_in = 0.15, Fc_out = 0.1\n");
fprintf(fpout, "\n");
fprintf(fpout, " Details on Modelling:\n");
fprintf(fpout, "\n");
fprintf(fpout, " The electrical design of the architecture described here is NOT from an \n");
fprintf(fpout, " optimized, SPICED architecture. Instead, we attempt to create a reasonable \n");
fprintf(fpout, " architecture file by using an existing commercial FPGA to approximate the area, \n");
fprintf(fpout, " delay, and power of the underlying components. This is combined with a reasonable 40 nm \n");
fprintf(fpout, " model of wiring and circuit design for low-level routing components, where available.\n");
fprintf(fpout, " The resulting architecture has delays that roughly match a commercial 40 nm FPGA, but also \n");
fprintf(fpout, " has wiring electrical parameters that allow the wire lengths and switch patterns to be \n");
fprintf(fpout, " modified and you will still get reasonable delay results for the new architecture.\n");
fprintf(fpout, " The following describes, in detail, how we obtained the various electrical values for this \n");
fprintf(fpout, " architecture.\n");
fprintf(fpout, "\n");
fprintf(fpout, " Rmin for nmos and pmos, routing buffer sizes, and I/O pad delays are from the ifar \n");
fprintf(fpout, " architecture created by Ian Kuon: K06 N10 45nm fc 0.15 area-delay optimized architecture. \n");
fprintf(fpout, " (n10k06l04.fc15.area1delay1.cmos45nm.bptm.cmos45nm.xml) \n");
fprintf(fpout, " This routing architecture was optimized for 45 nm, and we have scaled it linearly to 40 nm to \n");
fprintf(fpout, " match the overall target (a 40 nm FPGA).\n");
fprintf(fpout, "\n");
fprintf(fpout, " We obtain delay numbers by measuring delays of routing, soft logic blocks, \n");
fprintf(fpout, " memories, and multipliers from test circuits on a Stratix IV GX device \n");
fprintf(fpout, " (EP4SGX230DF29C2X, i.e. fastest speed grade). For routing, we took the average delay of H4 and V4 \n");
fprintf(fpout, " wires. Rmetal and Cmetal values for the routing wires were obtained from work done by Charles \n");
fprintf(fpout, " Chiasson. We use a 96 nm half-pitch (corresponding to mid-level metal stack 40 nm routing) and \n");
fprintf(fpout, " take the R and C data from the ITRS roadmap. \n");
fprintf(fpout, "\n");
fprintf(fpout, " For the general purpose logic block, we assume that the area and delays of the Stratix IV \n");
fprintf(fpout, " crossbar is close enough to the crossbar modelled here. We use 33 inputs and 20 feedback lines in \n");
fprintf(fpout, " the cluster and a full crossbar, leading to 53:1 multiplexers in front of each BLE input.\n");
fprintf(fpout, " Stratix IV uses 52 inputs and 20 feedback lines, but only a half-populated crossbar, leading to \n");
fprintf(fpout, " 36:1 multiplexers. We require 60 such multiplexers, while Stratix IV requires 88 for its more\n");
fprintf(fpout, " complex fracturable BLEs + the extra control signals. We justify this rough approximation as follows: \n");
fprintf(fpout, " The Stratix IV crossbar has more inputs (72 vs. 53) and \n");
fprintf(fpout, " outputs (88 vs. 60) than our full crossbar which should increase its area and delay, but the \n");
fprintf(fpout, " Stratix IV crossbar is also 50%% sparse (each mux is 36:1 instead of 53:1) which should reduce its \n");
fprintf(fpout, " area and delay. The total number of crossbar switch points is very similar between the two \n");
fprintf(fpout, " architectures (3160 for SIV and 3180 for the academic architecture below), so we can use the area \n");
fprintf(fpout, " & delay of the Stratix IV crossbar as a good approximation of our crossbar.\n");
fprintf(fpout, "\n");
fprintf(fpout, " For LUTs, we include LUT \n");
fprintf(fpout, " delays measured from Stratix IV which is dependant on the input used (ie. some \n");
fprintf(fpout, " LUT inputs are faster than others). The CAD tools at the time of VTR 7 does \n");
fprintf(fpout, " not consider differences in LUT input delays.\n");
fprintf(fpout, "\n");
fprintf(fpout, " Adder delays obtained as approximate values from a Stratix IV EP4SE230F29C3 device. \n");
fprintf(fpout, " Delay obtained by compiling a 256 bit adder (registered inputs and outputs, \n");
fprintf(fpout, " all pins except clock virtual) then measuring the delays in chip-planner, \n");
fprintf(fpout, " sumout delay = 0.271ns to 0.348 ns, intra-block carry delay = 0.011 ns, \n");
fprintf(fpout, " inter-block carry delay = 0.327 ns. Given this data, I will approximate \n");
fprintf(fpout, " sumout 0.3 ns, intra-block carry-delay = 0.01 ns, and \n");
fprintf(fpout, " inter-block carry-delay = 0.16 ns (since Altera inter-block carry delay has \n");
fprintf(fpout, " overhead that we don't have, I'll approximate the delay of a simpler chain at \n");
fprintf(fpout, " one half what they have. This is very rough, anything from 0.01ns to 0.327ns \n");
fprintf(fpout, " can be justified).\n");
fprintf(fpout, "\n");
fprintf(fpout, " Logic block area numbers obtained by scaling overall tile area of a 65nm \n");
fprintf(fpout, " Stratix III device, (as given in Wong, Betz and Rose, FPGA 2011) to 40 nm, then subtracting out \n");
fprintf(fpout, " routing area at a channel width of 300. We use a channel width of 300 because it can route \n");
fprintf(fpout, " all the VTR 6.0 benchmark circuits with an approximately 20%% safety margin, and is also close to the\n");
fprintf(fpout, " total channel width of Stratix IV. Hence this channel width is close to the commercial practice of\n");
fprintf(fpout, " choosing a width that provides high routability. The architecture can be routed at different channel\n");
fprintf(fpout, " widths, but we estimate the tile size and hence the physical length of routing wires assuming\n");
fprintf(fpout, " a channel width of 300.\n");
fprintf(fpout, "\n");
fprintf(fpout, " Sanity checks employed:\n");
fprintf(fpout, " 1. We confirmed the routing buffer delay is ~1/3rd of total routing delay at L = 4. This matches \n");
fprintf(fpout, " common electrical design.\n");
fprintf(fpout, "\n");
fprintf(fpout, " Authors: Jason Luu, Jeff Goeders, Vaughn Betz\n");
fprintf(fpout, "-->\n");
fprintf(fpout, " \n");
fprintf(fpout, " \n");
fprintf(fpout, " <architecture>\n");
fprintf(fpout, " \n");
fprintf(fpout, " <!-- \n");
fprintf(fpout, " ODIN II specific config begins \n");
fprintf(fpout, " Describes the types of user-specified netlist blocks (in blif, this corresponds to \n");
fprintf(fpout, " \".model [type_of_block]\") that this architecture supports.\n");
fprintf(fpout, "\n");
fprintf(fpout, " Note: Basic LUTs, I/Os, and flip-flops are not included here as there are \n");
fprintf(fpout, " already special structures in blif (.names, .input, .output, and .latch) \n");
fprintf(fpout, " that describe them.\n");
fprintf(fpout, " -->\n");
fprintf(fpout, " <models>\n");
fprintf(fpout, " <model name=\"multiply\">\n");
fprintf(fpout, " <input_ports>\n");
fprintf(fpout, " <port name=\"a\"/>\n");
fprintf(fpout, " <port name=\"b\"/>\n");
fprintf(fpout, " </input_ports>\n");
fprintf(fpout, " <output_ports>\n");
fprintf(fpout, " <port name=\"out\"/>\n");
fprintf(fpout, " </output_ports>\n");
fprintf(fpout, " </model>\n");
fprintf(fpout, " \n");
fprintf(fpout, " <model name=\"single_port_ram\">\n");
fprintf(fpout, " <input_ports>\n");
fprintf(fpout, " <port name=\"we\"/> <!-- control -->\n");
fprintf(fpout, " <port name=\"addr\"/> <!-- address lines -->\n");
fprintf(fpout, " <port name=\"data\"/> <!-- data lines can be broken down into smaller bit widths minimum size 1 -->\n");
fprintf(fpout, " <port name=\"clk\" is_clock=\"1\"/> <!-- memories are often clocked -->\n");
fprintf(fpout, " </input_ports>\n");
fprintf(fpout, " <output_ports>\n");
fprintf(fpout, " <port name=\"out\"/> <!-- output can be broken down into smaller bit widths minimum size 1 -->\n");
fprintf(fpout, " </output_ports>\n");
fprintf(fpout, " </model>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <model name=\"dual_port_ram\">\n");
fprintf(fpout, " <input_ports>\n");
fprintf(fpout, " <port name=\"we1\"/> <!-- write enable -->\n");
fprintf(fpout, " <port name=\"we2\"/> <!-- write enable -->\n");
fprintf(fpout, " <port name=\"addr1\"/> <!-- address lines -->\n");
fprintf(fpout, " <port name=\"addr2\"/> <!-- address lines -->\n");
fprintf(fpout, " <port name=\"data1\"/> <!-- data lines can be broken down into smaller bit widths minimum size 1 -->\n");
fprintf(fpout, " <port name=\"data2\"/> <!-- data lines can be broken down into smaller bit widths minimum size 1 -->\n");
fprintf(fpout, " <port name=\"clk\" is_clock=\"1\"/> <!-- memories are often clocked -->\n");
fprintf(fpout, " </input_ports>\n");
fprintf(fpout, " <output_ports>\n");
fprintf(fpout, " <port name=\"out1\"/> <!-- output can be broken down into smaller bit widths minimum size 1 -->\n");
fprintf(fpout, " <port name=\"out2\"/> <!-- output can be broken down into smaller bit widths minimum size 1 -->\n");
fprintf(fpout, " </output_ports>\n");
fprintf(fpout, " </model>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <model name=\"adder\">\n");
fprintf(fpout, " <input_ports>\n");
fprintf(fpout, " <port name=\"a\"/>\n");
fprintf(fpout, " <port name=\"b\"/>\n");
fprintf(fpout, " <port name=\"cin\"/>\n");
fprintf(fpout, " </input_ports>\n");
fprintf(fpout, " <output_ports>\n");
fprintf(fpout, " <port name=\"cout\"/>\n");
fprintf(fpout, " <port name=\"sumout\"/>\n");
fprintf(fpout, " </output_ports>\n");
fprintf(fpout, " </model>\n");
fprintf(fpout, "\n");
fprintf(fpout, " </models>\n");
fprintf(fpout, " <!-- ODIN II specific config ends -->\n");
fprintf(fpout, " \n");
fprintf(fpout, " <!-- Physical descriptions begin -->\n");
fprintf(fpout, " <layout auto=\"1.0\"/>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <device>\n");
fprintf(fpout, " <!-- VB & JL: Using Ian Kuon's transistor sizing and drive strength data for routing, at 40 nm. Ian used BPTM \n");
fprintf(fpout, " models. We are modifying the delay values however, to include metal C and R, which allows more architecture\n");
fprintf(fpout, " experimentation. We are also modifying the relative resistance of PMOS to be 1.8x that of NMOS\n");
fprintf(fpout, " (vs. Ian's 3x) as 1.8x lines up with Jeff G's data from a 45 nm process (and is more typical of \n");
fprintf(fpout, " 45 nm in general). I'm upping the Rmin_nmos from Ian's just over 6k to nearly 9k, and dropping \n");
fprintf(fpout, " RminW_pmos from 18k to 16k to hit this 1.8x ratio, while keeping the delays of buffers approximately\n");
fprintf(fpout, " lined up with Stratix IV. \n");
fprintf(fpout, " We are using Jeff G.'s capacitance data for 45 nm (in tech/ptm_45nm).\n");
fprintf(fpout, " Jeff's tables list C in for transistors with widths in multiples of the minimum feature size (45 nm).\n");
fprintf(fpout, " The minimum contactable transistor is 2.5 * 45 nm, so I need to multiply drive strength sizes in this file\n");
fprintf(fpout, " by 2.5x when looking up in Jeff's tables.\n");
fprintf(fpout, " The delay values are lined up with Stratix IV, which has an architecture similar to this\n");
fprintf(fpout, " proposed FPGA, and which is also 40 nm \n");
fprintf(fpout, " C_ipin_cblock: input capacitance of a track buffer, which VPR assumes is a single-stage\n");
fprintf(fpout, " 4x minimum drive strength buffer. -->\n");
fprintf(fpout, " \n");
fprintf(fpout, " <sizing R_minW_nmos=\"8926\" R_minW_pmos=\"16067\" ipin_mux_trans_size=\"1.222260\"/>\n");
fprintf(fpout, " <timing C_ipin_cblock=\"1.47e-15\" T_ipin_cblock=\"7.247000e-11\"/>\n");
fprintf(fpout, " <!-- Total Stratix IV tile area is about 8100 um^2, minimum width transistor area is 60 L^2 yields a tile area of 84375 MWTAs,\n");
fprintf(fpout, " Routing at W=300 is 30481 MWTAs, leaving us with a total of 53000 MWTAs for logic block area \n");
fprintf(fpout, " This means that only 37%% of our area is in the general routing, and 63%% is inside the logic\n");
fprintf(fpout, " block. Note that the crossbar / local interconnect is considered part of the logic block\n");
fprintf(fpout, " area in this analysis. That is a lower proportion of of routing area than most academics\n");
fprintf(fpout, " assume, but note that the total routing area really includes the crossbar, which would push\n");
fprintf(fpout, " routing area up significantly, we estimate into the ~70%% range.\n");
fprintf(fpout, " -->\n");
fprintf(fpout, " <area grid_logic_tile_area=\"53894\"/>\n");
fprintf(fpout, " <chan_width_distr>\n");
fprintf(fpout, " <io width=\"1.000000\"/>\n");
fprintf(fpout, " <x distr=\"uniform\" peak=\"1.000000\"/>\n");
fprintf(fpout, " <y distr=\"uniform\" peak=\"1.000000\"/>\n");
fprintf(fpout, " </chan_width_distr>\n");
fprintf(fpout, " <switch_block type=\"wilton\" fs=\"3\"/>\n");
fprintf(fpout, " </device>\n");
fprintf(fpout, " <switchlist>\n");
fprintf(fpout, " <!-- VB: the mux_trans_size and buf_size data below is in minimum width transistor *areas*, assuming the purple\n");
fprintf(fpout, " book area formula. This means the mux transistors are about 5x minimum drive strength.\n");
fprintf(fpout, " We assume the first stage of the buffer is 3x min drive strength to be reasonable given the large \n");
fprintf(fpout, " mux transistors, and this gives a reasonable stage ratio of a bit over 5x to the second stage. We assume\n");
fprintf(fpout, " the n and p transistors in the first stage are equal-sized to lower the buffer trip point, since it's fed\n");
fprintf(fpout, " by a pass transistor mux. We can then reverse engineer the buffer second stage to hit the specified \n");
fprintf(fpout, " buf_size (really buffer area) - 16.2x minimum drive nmos and 1.8*16.2 = 29.2x minimum drive.\n");
fprintf(fpout, " I then took the data from Jeff G.'s PTM modeling of 45 nm to get the Cin (gate of first stage) and Cout \n");
fprintf(fpout, " (diff of second stage) listed below. Jeff's models are in tech/ptm_45nm, and are in min feature multiples.\n");
fprintf(fpout, " The minimum contactable transistor is 2.5 * 45 nm, so I need to multiply the drive strength sizes above by \n");
fprintf(fpout, " 2.5x when looking up in Jeff's tables.\n");
fprintf(fpout, " Finally, we choose a switch delay (58 ps) that leads to length 4 wires having a delay equal to that of SIV of 126 ps.\n");
fprintf(fpout, " This also leads to the switch being 46%% of the total wire delay, which is reasonable. -->\n");
fprintf(fpout, " <switch type=\"mux\" name=\"0\" R=\"551\" Cin=\".77e-15\" Cout=\"4e-15\" Tdel=\"58e-12\" mux_trans_size=\"2.630740\" buf_size=\"27.645901\"/>\n");
fprintf(fpout, " </switchlist>\n");
fprintf(fpout, " <segmentlist>\n");
fprintf(fpout, " <!--- VB & JL: using ITRS metal stack data, 96 nm half pitch wires, which are intermediate metal width/space. \n");
fprintf(fpout, " With the 96 nm half pitch, such wires would take 60 um of height, vs. a 90 nm high (approximated as square) Stratix IV tile so this seems\n");
fprintf(fpout, " reasonable. Using a tile length of 90 nm, corresponding to the length of a Stratix IV tile if it were square. -->\n");
fprintf(fpout, " <segment freq=\"1.000000\" length=\"4\" type=\"unidir\" Rmetal=\"101\" Cmetal=\"22.5e-15\">\n");
fprintf(fpout, " <mux name=\"0\"/>\n");
fprintf(fpout, " <sb type=\"pattern\">1 1 1 1 1</sb>\n");
fprintf(fpout, " <cb type=\"pattern\">1 1 1 1</cb>\n");
fprintf(fpout, " </segment>\n");
fprintf(fpout, " </segmentlist>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <directlist>\n");
fprintf(fpout, " <direct name=\"adder_carry\" from_pin=\"clb.cout\" to_pin=\"clb.cin\" x_offset=\"0\" y_offset=\"-1\" z_offset=\"0\"/>\n");
fprintf(fpout, " </directlist>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <complexblocklist>\n");
fprintf(fpout, " \n");
fprintf(fpout, " <!-- Define I/O pads begin -->\n");
fprintf(fpout, " <!-- Capacity is a unique property of I/Os, it is the maximum number of I/Os that can be placed at the same (X,Y) location on the FPGA -->\n");
fprintf(fpout, " <pb_type name=\"io\" capacity=\"8\">\n");
fprintf(fpout, " <input name=\"outpad\" num_pins=\"1\"/>\n");
fprintf(fpout, " <output name=\"inpad\" num_pins=\"1\"/>\n");
fprintf(fpout, " <clock name=\"clock\" num_pins=\"1\"/>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <!-- IOs can operate as either inputs or outputs.\n");
fprintf(fpout, " Delays below come from Ian Kuon. They are small, so they should be interpreted as\n");
fprintf(fpout, " the delays to and from registers in the I/O (and generally I/Os are registered \n");
fprintf(fpout, " today and that is when you timing analyze them.\n");
fprintf(fpout, " -->\n");
fprintf(fpout, " <mode name=\"inpad\">\n");
fprintf(fpout, " <pb_type name=\"inpad\" blif_model=\".input\" num_pb=\"1\">\n");
fprintf(fpout, " <output name=\"inpad\" num_pins=\"1\"/>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"inpad\" input=\"inpad.inpad\" output=\"io.inpad\">\n");
fprintf(fpout, " <delay_constant max=\"4.243e-11\" in_port=\"inpad.inpad\" out_port=\"io.inpad\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " \n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, " <mode name=\"outpad\">\n");
fprintf(fpout, " <pb_type name=\"outpad\" blif_model=\".output\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"outpad\" num_pins=\"1\"/>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"outpad\" input=\"io.outpad\" output=\"outpad.outpad\">\n");
fprintf(fpout, " <delay_constant max=\"1.394e-11\" in_port=\"io.outpad\" out_port=\"outpad.outpad\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <!-- Every input pin is driven by 15%% of the tracks in a channel, every output pin is driven by 10%% of the tracks in a channel -->\n");
fprintf(fpout, " <fc in_type=\"frac\" in_val=\"0.15\" out_type=\"frac\" out_val=\"0.10\"/>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <!-- IOs go on the periphery of the FPGA, for consistency, \n");
fprintf(fpout, " make it physically equivalent on all sides so that only one definition of I/Os is needed.\n");
fprintf(fpout, " If I do not make a physically equivalent definition, then I need to define 4 different I/Os, one for each side of the FPGA\n");
fprintf(fpout, " -->\n");
fprintf(fpout, " <pinlocations pattern=\"custom\">\n");
fprintf(fpout, " <loc side=\"left\">io.outpad io.inpad io.clock</loc>\n");
fprintf(fpout, " <loc side=\"top\">io.outpad io.inpad io.clock</loc>\n");
fprintf(fpout, " <loc side=\"right\">io.outpad io.inpad io.clock</loc>\n");
fprintf(fpout, " <loc side=\"bottom\">io.outpad io.inpad io.clock</loc>\n");
fprintf(fpout, " </pinlocations>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <!-- Place I/Os on the sides of the FPGA -->\n");
fprintf(fpout, " <gridlocations>\n");
fprintf(fpout, " <loc type=\"perimeter\" priority=\"10\"/>\n");
fprintf(fpout, " </gridlocations>\n");
fprintf(fpout, " <power method=\"ignore\"/>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <!-- Define I/O pads ends -->\n");
fprintf(fpout, "\n");
}
static void print_clb(FILE *fpout, int FI, int clbI) {
assert(FI >= 5 && FI <= 10);
fprintf(fpout, " <!-- Define general purpose logic block (CLB) begin -->\n");
fprintf(fpout, " <pb_type name=\"clb\">\n");
fprintf(fpout, " <input name=\"I\" num_pins=\"%d\" equivalent=\"true\"/>\n", clbI);
fprintf(fpout, " <input name=\"cin\" num_pins=\"1\"/>\n");
fprintf(fpout, " <output name=\"O\" num_pins=\"20\" equivalent=\"false\"/>\n");
fprintf(fpout, " <output name=\"cout\" num_pins=\"1\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\"/>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <!-- Describe basic logic element with ifar delay numbers -->\n");
fprintf(fpout, " <pb_type name=\"fle\" num_pb=\"10\">\n");
if(FI == 5) {
fprintf(fpout, " <input name=\"in\" num_pins=\"6\"/>\n");
} else {
fprintf(fpout, " <input name=\"in\" num_pins=\"%d\"/>\n", FI);
}
fprintf(fpout, " <input name=\"cin\" num_pins=\"1\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"2\"/>\n");
fprintf(fpout, " <output name=\"cout\" num_pins=\"1\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\"/>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <mode name=\"n2_lut5\">\n");
fprintf(fpout, " <pb_type name=\"lut5inter\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"in\" num_pins=\"%d\"/>\n", FI);
fprintf(fpout, " <input name=\"cin\" num_pins=\"1\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"2\"/>\n");
fprintf(fpout, " <output name=\"cout\" num_pins=\"1\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\"/>\n");
fprintf(fpout, " <pb_type name=\"ble5\" num_pb=\"2\">\n");
fprintf(fpout, " <input name=\"in\" num_pins=\"5\"/>\n");
fprintf(fpout, " <input name=\"cin\" num_pins=\"1\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"1\"/>\n");
fprintf(fpout, " <output name=\"cout\" num_pins=\"1\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\"/> \n");
fprintf(fpout, " <mode name=\"blut5\">\n");
fprintf(fpout, " <pb_type name=\"flut5\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"in\" num_pins=\"5\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"1\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\"/> \n");
fprintf(fpout, " <!-- Regular LUT mode -->\n");
fprintf(fpout, " <pb_type name=\"lut5\" blif_model=\".names\" num_pb=\"1\" class=\"lut\">\n");
fprintf(fpout, " <input name=\"in\" num_pins=\"5\" port_class=\"lut_in\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"1\" port_class=\"lut_out\"/>\n");
fprintf(fpout, " <!-- LUT timing using delay matrix -->\n");
fprintf(fpout, " <!-- These are the physical delay inputs on a Stratix IV LUT but because VPR cannot do LUT rebalancing,\n");
fprintf(fpout, " we instead take the average of these numbers to get more stable results\n");
fprintf(fpout, " 82e-12\n");
fprintf(fpout, " 173e-12\n");
fprintf(fpout, " 261e-12\n");
fprintf(fpout, " 263e-12\n");
fprintf(fpout, " 398e-12\n");
fprintf(fpout, " -->\n");
fprintf(fpout, " <delay_matrix type=\"max\" in_port=\"lut5.in\" out_port=\"lut5.out\">\n");
fprintf(fpout, " 235e-12\n");
fprintf(fpout, " 235e-12\n");
fprintf(fpout, " 235e-12\n");
fprintf(fpout, " 235e-12\n");
fprintf(fpout, " 235e-12\n");
fprintf(fpout, " </delay_matrix>\n");
fprintf(fpout, " </pb_type> \n");
fprintf(fpout, " \n");
fprintf(fpout, " <pb_type name=\"ff\" blif_model=\".latch\" num_pb=\"1\" class=\"flipflop\">\n");
fprintf(fpout, " <input name=\"D\" num_pins=\"1\" port_class=\"D\"/>\n");
fprintf(fpout, " <output name=\"Q\" num_pins=\"1\" port_class=\"Q\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"66e-12\" port=\"ff.D\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"124e-12\" port=\"ff.Q\" clock=\"clk\"/>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"direct1\" input=\"flut5.in\" output=\"lut5.in\"/>\n");
fprintf(fpout, " <direct name=\"direct2\" input=\"lut5.out\" output=\"ff.D\">\n");
fprintf(fpout, " <pack_pattern name=\"ble5\" in_port=\"lut5.out\" out_port=\"ff.D\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"direct3\" input=\"flut5.clk\" output=\"ff.clk\"/> \n");
fprintf(fpout, " <mux name=\"mux1\" input=\"ff.Q lut5.out\" output=\"flut5.out\">\n");
fprintf(fpout, " <delay_constant max=\"25e-12\" in_port=\"lut5.out\" out_port=\"flut5.out\" />\n");
fprintf(fpout, " <delay_constant max=\"45e-12\" in_port=\"ff.Q\" out_port=\"flut5.out\" />\n");
fprintf(fpout, " </mux>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"direct1\" input=\"ble5.in\" output=\"flut5.in\"/>\n");
fprintf(fpout, " <direct name=\"direct2\" input=\"ble5.clk\" output=\"flut5.clk\"/>\n");
fprintf(fpout, " <direct name=\"direct3\" input=\"flut5.out\" output=\"ble5.out\"/> \n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, " <mode name=\"arithmetic\">\n");
fprintf(fpout, " <pb_type name=\"arithmetic\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"in\" num_pins=\"4\"/>\n");
fprintf(fpout, " <input name=\"cin\" num_pins=\"1\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"1\"/>\n");
fprintf(fpout, " <output name=\"cout\" num_pins=\"1\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\"/> \n");
fprintf(fpout, " <!-- Special dual-LUT mode that drives adder only -->\n");
fprintf(fpout, " <pb_type name=\"lut4\" blif_model=\".names\" num_pb=\"2\" class=\"lut\">\n");
fprintf(fpout, " <input name=\"in\" num_pins=\"4\" port_class=\"lut_in\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"1\" port_class=\"lut_out\"/>\n");
fprintf(fpout, " <!-- LUT timing using delay matrix -->\n");
fprintf(fpout, " <!-- These are the physical delay inputs on a Stratix IV LUT but because VPR cannot do LUT rebalancing,\n");
fprintf(fpout, " we instead take the average of these numbers to get more stable results\n");
fprintf(fpout, " 82e-12\n");
fprintf(fpout, " 173e-12\n");
fprintf(fpout, " 261e-12\n");
fprintf(fpout, " 263e-12\n");
fprintf(fpout, " -->\n");
fprintf(fpout, " <delay_matrix type=\"max\" in_port=\"lut4.in\" out_port=\"lut4.out\">\n");
fprintf(fpout, " 195e-12\n");
fprintf(fpout, " 195e-12\n");
fprintf(fpout, " 195e-12\n");
fprintf(fpout, " 195e-12\n");
fprintf(fpout, " </delay_matrix>\n");
fprintf(fpout, " </pb_type> \n");
fprintf(fpout, " <pb_type name=\"adder\" blif_model=\".subckt adder\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"a\" num_pins=\"1\"/>\n");
fprintf(fpout, " <input name=\"b\" num_pins=\"1\"/>\n");
fprintf(fpout, " <input name=\"cin\" num_pins=\"1\"/> \n");
fprintf(fpout, " <output name=\"cout\" num_pins=\"1\"/>\n");
fprintf(fpout, " <output name=\"sumout\" num_pins=\"1\"/>\n");
fprintf(fpout, " <delay_constant max=\"0.3e-9\" in_port=\"adder.a\" out_port=\"adder.sumout\"/>\n");
fprintf(fpout, " <delay_constant max=\"0.3e-9\" in_port=\"adder.b\" out_port=\"adder.sumout\"/>\n");
fprintf(fpout, " <delay_constant max=\"0.3e-9\" in_port=\"adder.cin\" out_port=\"adder.sumout\"/>\n");
fprintf(fpout, " <delay_constant max=\"0.3e-9\" in_port=\"adder.a\" out_port=\"adder.cout\"/>\n");
fprintf(fpout, " <delay_constant max=\"0.3e-9\" in_port=\"adder.b\" out_port=\"adder.cout\"/>\n");
fprintf(fpout, " <delay_constant max=\"0.01e-9\" in_port=\"adder.cin\" out_port=\"adder.cout\"/>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <pb_type name=\"ff\" blif_model=\".latch\" num_pb=\"1\" class=\"flipflop\">\n");
fprintf(fpout, " <input name=\"D\" num_pins=\"1\" port_class=\"D\"/>\n");
fprintf(fpout, " <output name=\"Q\" num_pins=\"1\" port_class=\"Q\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"66e-12\" port=\"ff.D\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"124e-12\" port=\"ff.Q\" clock=\"clk\"/>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"clock\" input=\"arithmetic.clk\" output=\"ff.clk\"/>\n");
fprintf(fpout, " <direct name=\"lut_in1\" input=\"arithmetic.in[3:0]\" output=\"lut4[0:0].in[3:0]\"/>\n");
fprintf(fpout, " <direct name=\"lut_in2\" input=\"arithmetic.in[3:0]\" output=\"lut4[1:1].in[3:0]\"/>\n");
fprintf(fpout, " <direct name=\"lut_to_add1\" input=\"lut4[0:0].out\" output=\"adder.a\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"lut_to_add2\" input=\"lut4[1:1].out\" output=\"adder.b\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"add_to_ff\" input=\"adder.sumout\" output=\"ff.D\">\n");
fprintf(fpout, " <pack_pattern name=\"chain\" in_port=\"adder.sumout\" out_port=\"ff.D\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"carry_in\" input=\"arithmetic.cin\" output=\"adder.cin\">\n");
fprintf(fpout, " <pack_pattern name=\"chain\" in_port=\"arithmetic.cin\" out_port=\"adder.cin\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"carry_out\" input=\"adder.cout\" output=\"arithmetic.cout\">\n");
fprintf(fpout, " <pack_pattern name=\"chain\" in_port=\"adder.cout\" out_port=\"arithmetic.cout\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <mux name=\"sumout\" input=\"ff.Q adder.sumout\" output=\"arithmetic.out\">\n");
fprintf(fpout, " <delay_constant max=\"25e-12\" in_port=\"adder.sumout\" out_port=\"arithmetic.out\" />\n");
fprintf(fpout, " <delay_constant max=\"45e-12\" in_port=\"ff.Q\" out_port=\"arithmetic.out\" />\n");
fprintf(fpout, " </mux>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"direct1\" input=\"ble5.in[3:0]\" output=\"arithmetic.in\"/>\n");
fprintf(fpout, " <direct name=\"carry_in\" input=\"ble5.cin\" output=\"arithmetic.cin\">\n");
fprintf(fpout, " <pack_pattern name=\"chain\" in_port=\"ble5.cin\" out_port=\"arithmetic.cin\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"carry_out\" input=\"arithmetic.cout\" output=\"ble5.cout\">\n");
fprintf(fpout, " <pack_pattern name=\"chain\" in_port=\"arithmetic.cout\" out_port=\"ble5.cout\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"direct2\" input=\"ble5.clk\" output=\"arithmetic.clk\"/>\n");
fprintf(fpout, " <direct name=\"direct3\" input=\"arithmetic.out\" output=\"ble5.out\"/> \n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"direct1\" input=\"lut5inter.in[4:0]\" output=\"ble5[0:0].in\"/>\n");
fprintf(fpout, " <direct name=\"direct2\" input=\"lut5inter.in[%d:%d]\" output=\"ble5[1:1].in\"/>\n", FI - 1, FI - 5);
fprintf(fpout, " <direct name=\"direct3\" input=\"ble5[1:0].out\" output=\"lut5inter.out\"/> \n");
fprintf(fpout, " <direct name=\"carry_in\" input=\"lut5inter.cin\" output=\"ble5[0:0].cin\">\n");
fprintf(fpout, " <pack_pattern name=\"chain\" in_port=\"lut5inter.cin\" out_port=\"ble5[0:0].cin\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"carry_out\" input=\"ble5[1:1].cout\" output=\"lut5inter.cout\">\n");
fprintf(fpout, " <pack_pattern name=\"chain\" in_port=\"ble5[1:1].cout\" out_port=\"lut5inter.cout\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"carry_link\" input=\"ble5[0:0].cout\" output=\"ble5[1:1].cin\">\n");
fprintf(fpout, " <pack_pattern name=\"chain\" in_port=\"ble5[0:0].cout\" out_port=\"ble5[1:1].cout\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <complete name=\"complete1\" input=\"lut5inter.clk\" output=\"ble5[1:0].clk\"/> \n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"direct1\" input=\"fle.in[%d:0]\" output=\"lut5inter.in\"/>\n", FI - 1);
fprintf(fpout, " <direct name=\"direct2\" input=\"lut5inter.out\" output=\"fle.out\"/>\n");
fprintf(fpout, " <direct name=\"direct3\" input=\"fle.clk\" output=\"lut5inter.clk\"/>\n");
fprintf(fpout, " <direct name=\"carry_in\" input=\"fle.cin\" output=\"lut5inter.cin\">\n");
fprintf(fpout, " <pack_pattern name=\"chain\" in_port=\"fle.cin\" out_port=\"lut5inter.cin\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"carry_out\" input=\"lut5inter.cout\" output=\"fle.cout\">\n");
fprintf(fpout, " <pack_pattern name=\"chain\" in_port=\"lut5inter.cout\" out_port=\"fle.cout\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode> <!-- n2_lut5 -->\n");
fprintf(fpout, " <mode name=\"n1_lut6\">\n");
fprintf(fpout, " <pb_type name=\"ble6\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"in\" num_pins=\"6\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"1\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\"/> \n");
fprintf(fpout, " <pb_type name=\"lut6\" blif_model=\".names\" num_pb=\"1\" class=\"lut\">\n");
fprintf(fpout, " <input name=\"in\" num_pins=\"6\" port_class=\"lut_in\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"1\" port_class=\"lut_out\"/>\n");
fprintf(fpout, " <!-- LUT timing using delay matrix -->\n");
fprintf(fpout, " <!-- These are the physical delay inputs on a Stratix IV LUT but because VPR cannot do LUT rebalancing,\n");
fprintf(fpout, " we instead take the average of these numbers to get more stable results\n");
fprintf(fpout, " 82e-12\n");
fprintf(fpout, " 173e-12\n");
fprintf(fpout, " 261e-12\n");
fprintf(fpout, " 263e-12\n");
fprintf(fpout, " 398e-12\n");
fprintf(fpout, " 397e-12\n");
fprintf(fpout, " -->\n");
fprintf(fpout, " <delay_matrix type=\"max\" in_port=\"lut6.in\" out_port=\"lut6.out\">\n");
fprintf(fpout, " 261e-12\n");
fprintf(fpout, " 261e-12\n");
fprintf(fpout, " 261e-12\n");
fprintf(fpout, " 261e-12\n");
fprintf(fpout, " 261e-12\n");
fprintf(fpout, " 261e-12\n");
fprintf(fpout, " </delay_matrix>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <pb_type name=\"ff\" blif_model=\".latch\" num_pb=\"1\" class=\"flipflop\">\n");
fprintf(fpout, " <input name=\"D\" num_pins=\"1\" port_class=\"D\"/>\n");
fprintf(fpout, " <output name=\"Q\" num_pins=\"1\" port_class=\"Q\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"66e-12\" port=\"ff.D\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"124e-12\" port=\"ff.Q\" clock=\"clk\"/>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"direct1\" input=\"ble6.in\" output=\"lut6[0:0].in\"/>\n");
fprintf(fpout, " <direct name=\"direct2\" input=\"lut6.out\" output=\"ff.D\">\n");
fprintf(fpout, " <pack_pattern name=\"ble6\" in_port=\"lut6.out\" out_port=\"ff.D\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"direct3\" input=\"ble6.clk\" output=\"ff.clk\"/> \n");
fprintf(fpout, " <mux name=\"mux1\" input=\"ff.Q lut6.out\" output=\"ble6.out\">\n");
fprintf(fpout, " <delay_constant max=\"25e-12\" in_port=\"lut6.out\" out_port=\"ble6.out\" />\n");
fprintf(fpout, " <delay_constant max=\"45e-12\" in_port=\"ff.Q\" out_port=\"ble6.out\" />\n");
fprintf(fpout, " </mux>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"direct1\" input=\"fle.in[5:0]\" output=\"ble6.in\"/>\n");
fprintf(fpout, " <direct name=\"direct2\" input=\"ble6.out\" output=\"fle.out[0:0]\"/>\n");
fprintf(fpout, " <direct name=\"direct3\" input=\"fle.clk\" output=\"ble6.clk\"/>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode> <!-- n1_lut6 -->\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <!-- We use a full crossbar to get logical equivalence at inputs of CLB \n");
fprintf(fpout, " The delays below come from Stratix IV. the delay through a connection block\n");
fprintf(fpout, " input mux + the crossbar in Stratix IV is 167 ps. We already have a 72 ps \n");
fprintf(fpout, " delay on the connection block input mux (modeled by Ian Kuon), so the remaining\n");
fprintf(fpout, " delay within the crossbar is 95 ps. \n");
fprintf(fpout, " The delays of cluster feedbacks in Stratix IV is 100 ps, when driven by a LUT.\n");
fprintf(fpout, " Since all our outputs LUT outputs go to a BLE output, and have a delay of \n");
fprintf(fpout, " 25 ps to do so, we subtract 25 ps from the 100 ps delay of a feedback\n");
fprintf(fpout, " to get the part that should be marked on the crossbar. -->\n");
fprintf(fpout, " <complete name=\"crossbar\" input=\"clb.I fle[9:0].out\" output=\"fle[9:0].in\">\n");
fprintf(fpout, " <delay_constant max=\"95e-12\" in_port=\"clb.I\" out_port=\"fle[9:0].in\" />\n");
fprintf(fpout, " <delay_constant max=\"75e-12\" in_port=\"fle[9:0].out\" out_port=\"fle[9:0].in\" />\n");
fprintf(fpout, " </complete>\n");
fprintf(fpout, " <complete name=\"clks\" input=\"clb.clk\" output=\"fle[9:0].clk\">\n");
fprintf(fpout, " </complete>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <!-- This way of specifying direct connection to clb outputs is important because this architecture uses automatic spreading of opins. \n");
fprintf(fpout, " By grouping to output pins in this fashion, if a logic block is completely filled by 6-LUTs, \n");
fprintf(fpout, " then the outputs those 6-LUTs take get evenly distributed across all four sides of the CLB instead of clumped on two sides (which is what happens with a more\n");
fprintf(fpout, " naive specification).\n");
fprintf(fpout, " -->\n");
fprintf(fpout, " <direct name=\"clbouts1\" input=\"fle[9:0].out[0:0]\" output=\"clb.O[9:0]\"/>\n");
fprintf(fpout, " <direct name=\"clbouts2\" input=\"fle[9:0].out[1:1]\" output=\"clb.O[19:10]\"/>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <!-- Carry chain links -->\n");
fprintf(fpout, " <direct name=\"carry_in\" input=\"clb.cin\" output=\"fle[0:0].cin\">\n");
fprintf(fpout, " <!-- Put all inter-block carry chain delay on this one edge -->\n");
fprintf(fpout, " <delay_constant max=\"0.16e-9\" in_port=\"clb.cin\" out_port=\"fle[0:0].cin\"/>\n");
fprintf(fpout, " <pack_pattern name=\"chain\" in_port=\"clb.cin\" out_port=\"fle[0:0].cin\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"carry_out\" input=\"fle[9:9].cout\" output=\"clb.cout\">\n");
fprintf(fpout, " <pack_pattern name=\"chain\" in_port=\"fle[9:9].cout\" out_port=\"clb.cout\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"carry_link\" input=\"fle[8:0].cout\" output=\"fle[9:1].cin\">\n");
fprintf(fpout, " <pack_pattern name=\"chain\" in_port=\"fle[8:0].cout\" out_port=\"fle[9:1].cin\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <fc in_type=\"frac\" in_val=\"0.15\" out_type=\"frac\" out_val=\"0.10\">\n");
fprintf(fpout, " <pin name=\"cin\" fc_type=\"frac\" fc_val=\"0\"/>\n");
fprintf(fpout, " <pin name=\"cout\" fc_type=\"frac\" fc_val=\"0\"/>\n");
fprintf(fpout, " </fc>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <pinlocations pattern=\"spread\"/>\n");
fprintf(fpout, " <gridlocations>\n");
fprintf(fpout, " <loc type=\"fill\" priority=\"1\"/>\n");
fprintf(fpout, " </gridlocations>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <!-- Define general purpose logic block (CLB) ends -->\n");
fprintf(fpout, "\n");
}
static void print_footer(FILE *fpout) {
fprintf(fpout, " <!-- Define fracturable multiplier begin -->\n");
fprintf(fpout, " <!-- This multiplier can operate as a 36x36 multiplier that can fracture to two 18x18 multipliers each of which can further fracture to two 9x9 multipliers \n");
fprintf(fpout, " For delay modelling, the 36x36 DSP multiplier in Stratix IV has a delay of 1.523 ns + 1.93 ns\n");
fprintf(fpout, " = 3.45 ns. The 18x18 mode doesn't need to sum four 18x18 multipliers, so it is a bit\n");
fprintf(fpout, " faster: 1.523 ns for the multiplier, and 1.09 ns for the multiplier output block.\n");
fprintf(fpout, " For the input and output interconnect delays, unlike Stratix IV, we don't\n");
fprintf(fpout, " have any routing/logic flexibility (crossbars) at the inputs. There is some output muxing\n");
fprintf(fpout, " in Stratix IV and this architecture to select which multiplier outputs should go out (e.g.\n");
fprintf(fpout, " 9x9 outputs, 18x18 or 36x36) so those are very close between the two architectures. \n");
fprintf(fpout, " We take the conservative (slightly pessimistic)\n");
fprintf(fpout, " approach modelling the input as the same as the Stratix IV input delay and the output delay the same as the Stratix IV DSP out delay.\n");
fprintf(fpout, " -->\n");
fprintf(fpout, " <pb_type name=\"mult_36\" height=\"4\">\n");
fprintf(fpout, " <input name=\"a\" num_pins=\"36\"/>\n");
fprintf(fpout, " <input name=\"b\" num_pins=\"36\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"72\"/>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <mode name=\"two_divisible_mult_18x18\">\n");
fprintf(fpout, " <pb_type name=\"divisible_mult_18x18\" num_pb=\"2\">\n");
fprintf(fpout, " <input name=\"a\" num_pins=\"18\"/>\n");
fprintf(fpout, " <input name=\"b\" num_pins=\"18\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"36\"/>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <!-- Model 9x9 delay and 18x18 delay as the same. 9x9 could be faster, but in Stratix IV\n");
fprintf(fpout, " isn't, presumably because the multiplier layout is really optimized for 18x18.\n");
fprintf(fpout, " -->\n");
fprintf(fpout, " <mode name=\"two_mult_9x9\">\n");
fprintf(fpout, " <pb_type name=\"mult_9x9_slice\" num_pb=\"2\">\n");
fprintf(fpout, " <input name=\"A_cfg\" num_pins=\"9\"/>\n");
fprintf(fpout, " <input name=\"B_cfg\" num_pins=\"9\"/>\n");
fprintf(fpout, " <output name=\"OUT_cfg\" num_pins=\"18\"/>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <pb_type name=\"mult_9x9\" blif_model=\".subckt multiply\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"a\" num_pins=\"9\"/>\n");
fprintf(fpout, " <input name=\"b\" num_pins=\"9\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"18\"/>\n");
fprintf(fpout, " <delay_constant max=\"1.523e-9\" in_port=\"mult_9x9.a\" out_port=\"mult_9x9.out\"/>\n");
fprintf(fpout, " <delay_constant max=\"1.523e-9\" in_port=\"mult_9x9.b\" out_port=\"mult_9x9.out\"/>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"a2a\" input=\"mult_9x9_slice.A_cfg\" output=\"mult_9x9.a\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"b2b\" input=\"mult_9x9_slice.B_cfg\" output=\"mult_9x9.b\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"out2out\" input=\"mult_9x9.out\" output=\"mult_9x9_slice.OUT_cfg\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"A_cfg\" energy_per_toggle=\"1.45e-12\"/>\n");
fprintf(fpout, " <port name=\"B_cfg\" energy_per_toggle=\"1.45e-12\"/>\n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"a2a\" input=\"divisible_mult_18x18.a\" output=\"mult_9x9_slice[1:0].A_cfg\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"b2b\" input=\"divisible_mult_18x18.b\" output=\"mult_9x9_slice[1:0].B_cfg\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"out2out\" input=\"mult_9x9_slice[1:0].OUT_cfg\" output=\"divisible_mult_18x18.out\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, "\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <mode name=\"mult_18x18\">\n");
fprintf(fpout, " <pb_type name=\"mult_18x18_slice\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"A_cfg\" num_pins=\"18\"/>\n");
fprintf(fpout, " <input name=\"B_cfg\" num_pins=\"18\"/>\n");
fprintf(fpout, " <output name=\"OUT_cfg\" num_pins=\"36\"/>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <pb_type name=\"mult_18x18\" blif_model=\".subckt multiply\" num_pb=\"1\" >\n");
fprintf(fpout, " <input name=\"a\" num_pins=\"18\"/>\n");
fprintf(fpout, " <input name=\"b\" num_pins=\"18\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"36\"/>\n");
fprintf(fpout, " <delay_constant max=\"1.523e-9\" in_port=\"mult_18x18.a\" out_port=\"mult_18x18.out\"/>\n");
fprintf(fpout, " <delay_constant max=\"1.523e-9\" in_port=\"mult_18x18.b\" out_port=\"mult_18x18.out\"/>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"a2a\" input=\"mult_18x18_slice.A_cfg\" output=\"mult_18x18.a\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"b2b\" input=\"mult_18x18_slice.B_cfg\" output=\"mult_18x18.b\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"out2out\" input=\"mult_18x18.out\" output=\"mult_18x18_slice.OUT_cfg\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"A_cfg\" energy_per_toggle=\"1.09e-12\"/>\n");
fprintf(fpout, " <port name=\"B_cfg\" energy_per_toggle=\"1.09e-12\"/>\n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/> \n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"a2a\" input=\"divisible_mult_18x18.a\" output=\"mult_18x18_slice.A_cfg\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"b2b\" input=\"divisible_mult_18x18.b\" output=\"mult_18x18_slice.B_cfg\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"out2out\" input=\"mult_18x18_slice.OUT_cfg\" output=\"divisible_mult_18x18.out\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <power method=\"sum-of-children\"/>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <!-- Stratix IV input delay of 207ps is conservative for this architecture because this architecture does not have an input crossbar in the multiplier. \n");
fprintf(fpout, " Subtract 72.5 ps delay, which is already in the connection block input mux, leading\n");
fprintf(fpout, " -->\n");
fprintf(fpout, " <direct name=\"a2a\" input=\"mult_36.a\" output=\"divisible_mult_18x18[1:0].a\">\n");
fprintf(fpout, " <delay_constant max=\"134e-12\" in_port=\"mult_36.a\" out_port=\"divisible_mult_18x18[1:0].a\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"b2b\" input=\"mult_36.b\" output=\"divisible_mult_18x18[1:0].b\">\n");
fprintf(fpout, " <delay_constant max=\"134e-12\" in_port=\"mult_36.b\" out_port=\"divisible_mult_18x18[1:0].b\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"out2out\" input=\"divisible_mult_18x18[1:0].out\" output=\"mult_36.out\">\n");
fprintf(fpout, " <delay_constant max=\"1.09e-9\" in_port=\"divisible_mult_18x18[1:0].out\" out_port=\"mult_36.out\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <mode name=\"mult_36x36\">\n");
fprintf(fpout, " <pb_type name=\"mult_36x36_slice\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"A_cfg\" num_pins=\"36\"/>\n");
fprintf(fpout, " <input name=\"B_cfg\" num_pins=\"36\"/>\n");
fprintf(fpout, " <output name=\"OUT_cfg\" num_pins=\"72\"/>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <pb_type name=\"mult_36x36\" blif_model=\".subckt multiply\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"a\" num_pins=\"36\"/>\n");
fprintf(fpout, " <input name=\"b\" num_pins=\"36\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"72\"/>\n");
fprintf(fpout, " <delay_constant max=\"1.523e-9\" in_port=\"mult_36x36.a\" out_port=\"mult_36x36.out\"/>\n");
fprintf(fpout, " <delay_constant max=\"1.523e-9\" in_port=\"mult_36x36.b\" out_port=\"mult_36x36.out\"/>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"a2a\" input=\"mult_36x36_slice.A_cfg\" output=\"mult_36x36.a\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"b2b\" input=\"mult_36x36_slice.B_cfg\" output=\"mult_36x36.b\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"out2out\" input=\"mult_36x36.out\" output=\"mult_36x36_slice.OUT_cfg\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"A_cfg\" energy_per_toggle=\"2.13e-12\"/>\n");
fprintf(fpout, " <port name=\"B_cfg\" energy_per_toggle=\"2.13e-12\"/>\n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <!-- Stratix IV input delay of 207ps is conservative for this architecture because this architecture does not have an input crossbar in the multiplier. \n");
fprintf(fpout, " Subtract 72.5 ps delay, which is already in the connection block input mux, leading\n");
fprintf(fpout, " to a 134 ps delay.\n");
fprintf(fpout, " -->\n");
fprintf(fpout, " <direct name=\"a2a\" input=\"mult_36.a\" output=\"mult_36x36_slice.A_cfg\">\n");
fprintf(fpout, " <delay_constant max=\"134e-12\" in_port=\"mult_36.a\" out_port=\"mult_36x36_slice.A_cfg\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"b2b\" input=\"mult_36.b\" output=\"mult_36x36_slice.B_cfg\">\n");
fprintf(fpout, " <delay_constant max=\"134e-12\" in_port=\"mult_36.b\" out_port=\"mult_36x36_slice.B_cfg\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"out2out\" input=\"mult_36x36_slice.OUT_cfg\" output=\"mult_36.out\">\n");
fprintf(fpout, " <delay_constant max=\"1.93e-9\" in_port=\"mult_36x36_slice.OUT_cfg\" out_port=\"mult_36.out\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, "\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <fc in_type=\"frac\" in_val=\"0.15\" out_type=\"frac\" out_val=\"0.10\"/>\n");
fprintf(fpout, " <pinlocations pattern=\"spread\"/>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <!-- Place this multiplier block every 8 columns from (and including) the sixth column -->\n");
fprintf(fpout, " <gridlocations>\n");
fprintf(fpout, " <loc type=\"col\" start=\"6\" repeat=\"8\" priority=\"2\"/>\n");
fprintf(fpout, " </gridlocations> \n");
fprintf(fpout, " <power method=\"sum-of-children\"/>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <!-- Define fracturable multiplier end -->\n");
fprintf(fpout, "\n");
fprintf(fpout, " <!-- Define fracturable memory begin -->\n");
fprintf(fpout, " <!-- 32 Kb Memory that can operate from 512x64 to 32Kx1 for single-port mode and 1024x32 to 32Kx1 for dual-port mode. \n");
fprintf(fpout, " Area and delay based off Stratix IV 9K and 144K memories (delay from linear interpolation, Tsu(483 ps, 636 ps) Tco(1084ps, 1969ps)). \n");
fprintf(fpout, " Input delay = 204ps (from Stratix IV LAB line) - 72ps (this architecture does not lump connection box delay in internal delay)\n");
fprintf(fpout, " Output delay = M4K buffer 50ps\n");
fprintf(fpout, " -->\n");
fprintf(fpout, " <pb_type name=\"memory\" height=\"6\">\n");
fprintf(fpout, " <input name=\"addr1\" num_pins=\"15\"/>\n");
fprintf(fpout, " <input name=\"addr2\" num_pins=\"15\"/>\n");
fprintf(fpout, " <input name=\"data\" num_pins=\"64\"/>\n");
fprintf(fpout, " <input name=\"we1\" num_pins=\"1\"/>\n");
fprintf(fpout, " <input name=\"we2\" num_pins=\"1\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"64\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\"/>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <!-- Specify single port mode first -->\n");
fprintf(fpout, " <mode name=\"mem_512x64_sp\">\n");
fprintf(fpout, " <pb_type name=\"mem_512x64_sp\" blif_model=\".subckt single_port_ram\" class=\"memory\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"addr\" num_pins=\"9\" port_class=\"address\"/>\n");
fprintf(fpout, " <input name=\"data\" num_pins=\"64\" port_class=\"data_in\"/>\n");
fprintf(fpout, " <input name=\"we\" num_pins=\"1\" port_class=\"write_en\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"64\" port_class=\"data_out\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_512x64_sp.addr\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_512x64_sp.data\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_512x64_sp.we\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_512x64_sp.out\" clock=\"clk\"/>\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"clk\" energy_per_toggle=\"9.0e-12\"/> \n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"address1\" input=\"memory.addr1[8:0]\" output=\"mem_512x64_sp.addr\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr1[8:0]\" out_port=\"mem_512x64_sp.addr\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data1\" input=\"memory.data[63:0]\" output=\"mem_512x64_sp.data\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[63:0]\" out_port=\"mem_512x64_sp.data\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_512x64_sp.we\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_512x64_sp.we\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout1\" input=\"mem_512x64_sp.out\" output=\"memory.out[63:0]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_512x64_sp.out\" out_port=\"memory.out[63:0]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"clk\" input=\"memory.clk\" output=\"mem_512x64_sp.clk\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <mode name=\"mem_1024x32_sp\">\n");
fprintf(fpout, " <pb_type name=\"mem_1024x32_sp\" blif_model=\".subckt single_port_ram\" class=\"memory\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"addr\" num_pins=\"10\" port_class=\"address\"/>\n");
fprintf(fpout, " <input name=\"data\" num_pins=\"32\" port_class=\"data_in\"/>\n");
fprintf(fpout, " <input name=\"we\" num_pins=\"1\" port_class=\"write_en\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"32\" port_class=\"data_out\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_1024x32_sp.addr\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_1024x32_sp.data\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_1024x32_sp.we\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_1024x32_sp.out\" clock=\"clk\"/>\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"clk\" energy_per_toggle=\"9.0e-12\"/> \n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"address1\" input=\"memory.addr1[9:0]\" output=\"mem_1024x32_sp.addr\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr1[9:0]\" out_port=\"mem_1024x32_sp.addr\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data1\" input=\"memory.data[31:0]\" output=\"mem_1024x32_sp.data\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[31:0]\" out_port=\"mem_1024x32_sp.data\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_1024x32_sp.we\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_1024x32_sp.we\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout1\" input=\"mem_1024x32_sp.out\" output=\"memory.out[31:0]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_1024x32_sp.out\" out_port=\"memory.out[31:0]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"clk\" input=\"memory.clk\" output=\"mem_1024x32_sp.clk\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <mode name=\"mem_2048x16_sp\">\n");
fprintf(fpout, " <pb_type name=\"mem_2048x16_sp\" blif_model=\".subckt single_port_ram\" class=\"memory\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"addr\" num_pins=\"11\" port_class=\"address\"/>\n");
fprintf(fpout, " <input name=\"data\" num_pins=\"16\" port_class=\"data_in\"/>\n");
fprintf(fpout, " <input name=\"we\" num_pins=\"1\" port_class=\"write_en\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"16\" port_class=\"data_out\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_2048x16_sp.addr\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_2048x16_sp.data\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_2048x16_sp.we\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_2048x16_sp.out\" clock=\"clk\"/>\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"clk\" energy_per_toggle=\"9.0e-12\"/> \n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"address1\" input=\"memory.addr1[10:0]\" output=\"mem_2048x16_sp.addr\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr1[10:0]\" out_port=\"mem_2048x16_sp.addr\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data1\" input=\"memory.data[15:0]\" output=\"mem_2048x16_sp.data\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[15:0]\" out_port=\"mem_2048x16_sp.data\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_2048x16_sp.we\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_2048x16_sp.we\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout1\" input=\"mem_2048x16_sp.out\" output=\"memory.out[15:0]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_2048x16_sp.out\" out_port=\"memory.out[15:0]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"clk\" input=\"memory.clk\" output=\"mem_2048x16_sp.clk\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <mode name=\"mem_4096x8_sp\">\n");
fprintf(fpout, " <pb_type name=\"mem_4096x8_sp\" blif_model=\".subckt single_port_ram\" class=\"memory\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"addr\" num_pins=\"12\" port_class=\"address\"/>\n");
fprintf(fpout, " <input name=\"data\" num_pins=\"8\" port_class=\"data_in\"/>\n");
fprintf(fpout, " <input name=\"we\" num_pins=\"1\" port_class=\"write_en\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"8\" port_class=\"data_out\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_4096x8_sp.addr\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_4096x8_sp.data\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_4096x8_sp.we\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_4096x8_sp.out\" clock=\"clk\"/>\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"clk\" energy_per_toggle=\"9.0e-12\"/> \n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"address1\" input=\"memory.addr1[11:0]\" output=\"mem_4096x8_sp.addr\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr1[11:0]\" out_port=\"mem_4096x8_sp.addr\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data1\" input=\"memory.data[7:0]\" output=\"mem_4096x8_sp.data\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[7:0]\" out_port=\"mem_4096x8_sp.data\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_4096x8_sp.we\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_4096x8_sp.we\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout1\" input=\"mem_4096x8_sp.out\" output=\"memory.out[7:0]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_4096x8_sp.out\" out_port=\"memory.out[7:0]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"clk\" input=\"memory.clk\" output=\"mem_4096x8_sp.clk\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <mode name=\"mem_8192x4_sp\">\n");
fprintf(fpout, " <pb_type name=\"mem_8192x4_sp\" blif_model=\".subckt single_port_ram\" class=\"memory\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"addr\" num_pins=\"13\" port_class=\"address\"/>\n");
fprintf(fpout, " <input name=\"data\" num_pins=\"4\" port_class=\"data_in\"/>\n");
fprintf(fpout, " <input name=\"we\" num_pins=\"1\" port_class=\"write_en\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"4\" port_class=\"data_out\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_8192x4_sp.addr\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_8192x4_sp.data\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_8192x4_sp.we\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_8192x4_sp.out\" clock=\"clk\"/>\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"clk\" energy_per_toggle=\"9.0e-12\"/> \n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"address1\" input=\"memory.addr1[12:0]\" output=\"mem_8192x4_sp.addr\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr1[12:0]\" out_port=\"mem_8192x4_sp.addr\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data1\" input=\"memory.data[3:0]\" output=\"mem_8192x4_sp.data\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[3:0]\" out_port=\"mem_8192x4_sp.data\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_8192x4_sp.we\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_8192x4_sp.we\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout1\" input=\"mem_8192x4_sp.out\" output=\"memory.out[3:0]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_8192x4_sp.out\" out_port=\"memory.out[3:0]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"clk\" input=\"memory.clk\" output=\"mem_8192x4_sp.clk\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <mode name=\"mem_16384x2_sp\">\n");
fprintf(fpout, " <pb_type name=\"mem_16384x2_sp\" blif_model=\".subckt single_port_ram\" class=\"memory\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"addr\" num_pins=\"14\" port_class=\"address\"/>\n");
fprintf(fpout, " <input name=\"data\" num_pins=\"2\" port_class=\"data_in\"/>\n");
fprintf(fpout, " <input name=\"we\" num_pins=\"1\" port_class=\"write_en\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"2\" port_class=\"data_out\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_16384x2_sp.addr\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_16384x2_sp.data\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_16384x2_sp.we\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_16384x2_sp.out\" clock=\"clk\"/>\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"clk\" energy_per_toggle=\"9.0e-12\"/> \n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"address1\" input=\"memory.addr1[13:0]\" output=\"mem_16384x2_sp.addr\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr1[13:0]\" out_port=\"mem_16384x2_sp.addr\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data1\" input=\"memory.data[1:0]\" output=\"mem_16384x2_sp.data\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[1:0]\" out_port=\"mem_16384x2_sp.data\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_16384x2_sp.we\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_16384x2_sp.we\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout1\" input=\"mem_16384x2_sp.out\" output=\"memory.out[1:0]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_16384x2_sp.out\" out_port=\"memory.out[1:0]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"clk\" input=\"memory.clk\" output=\"mem_16384x2_sp.clk\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode> \n");
fprintf(fpout, "\n");
fprintf(fpout, " <mode name=\"mem_32768x1_sp\">\n");
fprintf(fpout, " <pb_type name=\"mem_32768x1_sp\" blif_model=\".subckt single_port_ram\" class=\"memory\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"addr\" num_pins=\"15\" port_class=\"address\"/>\n");
fprintf(fpout, " <input name=\"data\" num_pins=\"1\" port_class=\"data_in\"/>\n");
fprintf(fpout, " <input name=\"we\" num_pins=\"1\" port_class=\"write_en\"/>\n");
fprintf(fpout, " <output name=\"out\" num_pins=\"1\" port_class=\"data_out\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_32768x1_sp.addr\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_32768x1_sp.data\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_32768x1_sp.we\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_32768x1_sp.out\" clock=\"clk\"/>\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"clk\" energy_per_toggle=\"9.0e-12\"/> \n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"address1\" input=\"memory.addr1[14:0]\" output=\"mem_32768x1_sp.addr\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr1[14:0]\" out_port=\"mem_32768x1_sp.addr\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data1\" input=\"memory.data[0:0]\" output=\"mem_32768x1_sp.data\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[0:0]\" out_port=\"mem_32768x1_sp.data\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_32768x1_sp.we\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_32768x1_sp.we\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout1\" input=\"mem_32768x1_sp.out\" output=\"memory.out[0:0]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_32768x1_sp.out\" out_port=\"memory.out[0:0]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"clk\" input=\"memory.clk\" output=\"mem_32768x1_sp.clk\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode> \n");
fprintf(fpout, "\n");
fprintf(fpout, " <!-- Specify true dual port mode next -->\n");
fprintf(fpout, " <mode name=\"mem_1024x32_dp\">\n");
fprintf(fpout, " <pb_type name=\"mem_1024x32_dp\" blif_model=\".subckt dual_port_ram\" class=\"memory\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"addr1\" num_pins=\"10\" port_class=\"address1\"/>\n");
fprintf(fpout, " <input name=\"addr2\" num_pins=\"10\" port_class=\"address2\"/>\n");
fprintf(fpout, " <input name=\"data1\" num_pins=\"32\" port_class=\"data_in1\"/>\n");
fprintf(fpout, " <input name=\"data2\" num_pins=\"32\" port_class=\"data_in2\"/>\n");
fprintf(fpout, " <input name=\"we1\" num_pins=\"1\" port_class=\"write_en1\"/>\n");
fprintf(fpout, " <input name=\"we2\" num_pins=\"1\" port_class=\"write_en2\"/>\n");
fprintf(fpout, " <output name=\"out1\" num_pins=\"32\" port_class=\"data_out1\"/>\n");
fprintf(fpout, " <output name=\"out2\" num_pins=\"32\" port_class=\"data_out2\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_1024x32_dp.addr1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_1024x32_dp.data1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_1024x32_dp.we1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_1024x32_dp.addr2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_1024x32_dp.data2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_1024x32_dp.we2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_1024x32_dp.out1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_1024x32_dp.out2\" clock=\"clk\"/>\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"clk\" energy_per_toggle=\"17.9e-12\"/> \n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"address1\" input=\"memory.addr1[9:0]\" output=\"mem_1024x32_dp.addr1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr1[9:0]\" out_port=\"mem_1024x32_dp.addr1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"address2\" input=\"memory.addr2[9:0]\" output=\"mem_1024x32_dp.addr2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr2[9:0]\" out_port=\"mem_1024x32_dp.addr2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data1\" input=\"memory.data[31:0]\" output=\"mem_1024x32_dp.data1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[31:0]\" out_port=\"mem_1024x32_dp.data1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data2\" input=\"memory.data[63:32]\" output=\"mem_1024x32_dp.data2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[63:32]\" out_port=\"mem_1024x32_dp.data2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_1024x32_dp.we1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_1024x32_dp.we1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen2\" input=\"memory.we2\" output=\"mem_1024x32_dp.we2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we2\" out_port=\"mem_1024x32_dp.we2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout1\" input=\"mem_1024x32_dp.out1\" output=\"memory.out[31:0]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_1024x32_dp.out1\" out_port=\"memory.out[31:0]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout2\" input=\"mem_1024x32_dp.out2\" output=\"memory.out[63:32]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_1024x32_dp.out2\" out_port=\"memory.out[63:32]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"clk\" input=\"memory.clk\" output=\"mem_1024x32_dp.clk\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <mode name=\"mem_2048x16_dp\">\n");
fprintf(fpout, " <pb_type name=\"mem_2048x16_dp\" blif_model=\".subckt dual_port_ram\" class=\"memory\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"addr1\" num_pins=\"11\" port_class=\"address1\"/>\n");
fprintf(fpout, " <input name=\"addr2\" num_pins=\"11\" port_class=\"address2\"/>\n");
fprintf(fpout, " <input name=\"data1\" num_pins=\"16\" port_class=\"data_in1\"/>\n");
fprintf(fpout, " <input name=\"data2\" num_pins=\"16\" port_class=\"data_in2\"/>\n");
fprintf(fpout, " <input name=\"we1\" num_pins=\"1\" port_class=\"write_en1\"/>\n");
fprintf(fpout, " <input name=\"we2\" num_pins=\"1\" port_class=\"write_en2\"/>\n");
fprintf(fpout, " <output name=\"out1\" num_pins=\"16\" port_class=\"data_out1\"/>\n");
fprintf(fpout, " <output name=\"out2\" num_pins=\"16\" port_class=\"data_out2\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_2048x16_dp.addr1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_2048x16_dp.data1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_2048x16_dp.we1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_2048x16_dp.addr2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_2048x16_dp.data2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_2048x16_dp.we2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_2048x16_dp.out1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_2048x16_dp.out2\" clock=\"clk\"/>\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"clk\" energy_per_toggle=\"17.9e-12\"/> \n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"address1\" input=\"memory.addr1[10:0]\" output=\"mem_2048x16_dp.addr1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr1[10:0]\" out_port=\"mem_2048x16_dp.addr1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"address2\" input=\"memory.addr2[10:0]\" output=\"mem_2048x16_dp.addr2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr2[10:0]\" out_port=\"mem_2048x16_dp.addr2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data1\" input=\"memory.data[15:0]\" output=\"mem_2048x16_dp.data1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[15:0]\" out_port=\"mem_2048x16_dp.data1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data2\" input=\"memory.data[31:16]\" output=\"mem_2048x16_dp.data2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[31:16]\" out_port=\"mem_2048x16_dp.data2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_2048x16_dp.we1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_2048x16_dp.we1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen2\" input=\"memory.we2\" output=\"mem_2048x16_dp.we2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we2\" out_port=\"mem_2048x16_dp.we2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout1\" input=\"mem_2048x16_dp.out1\" output=\"memory.out[15:0]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_2048x16_dp.out1\" out_port=\"memory.out[15:0]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout2\" input=\"mem_2048x16_dp.out2\" output=\"memory.out[31:16]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_2048x16_dp.out2\" out_port=\"memory.out[31:16]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"clk\" input=\"memory.clk\" output=\"mem_2048x16_dp.clk\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <mode name=\"mem_2048x8_dp\">\n");
fprintf(fpout, " <pb_type name=\"mem_2048x8_dp\" blif_model=\".subckt dual_port_ram\" class=\"memory\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"addr1\" num_pins=\"12\" port_class=\"address1\"/>\n");
fprintf(fpout, " <input name=\"addr2\" num_pins=\"12\" port_class=\"address2\"/>\n");
fprintf(fpout, " <input name=\"data1\" num_pins=\"8\" port_class=\"data_in1\"/>\n");
fprintf(fpout, " <input name=\"data2\" num_pins=\"8\" port_class=\"data_in2\"/>\n");
fprintf(fpout, " <input name=\"we1\" num_pins=\"1\" port_class=\"write_en1\"/>\n");
fprintf(fpout, " <input name=\"we2\" num_pins=\"1\" port_class=\"write_en2\"/>\n");
fprintf(fpout, " <output name=\"out1\" num_pins=\"8\" port_class=\"data_out1\"/>\n");
fprintf(fpout, " <output name=\"out2\" num_pins=\"8\" port_class=\"data_out2\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_2048x8_dp.addr1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_2048x8_dp.data1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_2048x8_dp.we1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_2048x8_dp.addr2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_2048x8_dp.data2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_2048x8_dp.we2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_2048x8_dp.out1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_2048x8_dp.out2\" clock=\"clk\"/>\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"clk\" energy_per_toggle=\"17.9e-12\"/> \n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"address1\" input=\"memory.addr1[11:0]\" output=\"mem_2048x8_dp.addr1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr1[11:0]\" out_port=\"mem_2048x8_dp.addr1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"address2\" input=\"memory.addr2[11:0]\" output=\"mem_2048x8_dp.addr2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr2[11:0]\" out_port=\"mem_2048x8_dp.addr2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data1\" input=\"memory.data[7:0]\" output=\"mem_2048x8_dp.data1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[7:0]\" out_port=\"mem_2048x8_dp.data1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data2\" input=\"memory.data[15:8]\" output=\"mem_2048x8_dp.data2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[15:8]\" out_port=\"mem_2048x8_dp.data2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_2048x8_dp.we1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_2048x8_dp.we1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen2\" input=\"memory.we2\" output=\"mem_2048x8_dp.we2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we2\" out_port=\"mem_2048x8_dp.we2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout1\" input=\"mem_2048x8_dp.out1\" output=\"memory.out[7:0]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_2048x8_dp.out1\" out_port=\"memory.out[7:0]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout2\" input=\"mem_2048x8_dp.out2\" output=\"memory.out[15:8]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_2048x8_dp.out2\" out_port=\"memory.out[15:8]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"clk\" input=\"memory.clk\" output=\"mem_2048x8_dp.clk\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, " <mode name=\"mem_8192x4_dp\">\n");
fprintf(fpout, " <pb_type name=\"mem_8192x4_dp\" blif_model=\".subckt dual_port_ram\" class=\"memory\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"addr1\" num_pins=\"13\" port_class=\"address1\"/>\n");
fprintf(fpout, " <input name=\"addr2\" num_pins=\"13\" port_class=\"address2\"/>\n");
fprintf(fpout, " <input name=\"data1\" num_pins=\"4\" port_class=\"data_in1\"/>\n");
fprintf(fpout, " <input name=\"data2\" num_pins=\"4\" port_class=\"data_in2\"/>\n");
fprintf(fpout, " <input name=\"we1\" num_pins=\"1\" port_class=\"write_en1\"/>\n");
fprintf(fpout, " <input name=\"we2\" num_pins=\"1\" port_class=\"write_en2\"/>\n");
fprintf(fpout, " <output name=\"out1\" num_pins=\"4\" port_class=\"data_out1\"/>\n");
fprintf(fpout, " <output name=\"out2\" num_pins=\"4\" port_class=\"data_out2\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_8192x4_dp.addr1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_8192x4_dp.data1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_8192x4_dp.we1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_8192x4_dp.addr2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_8192x4_dp.data2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_8192x4_dp.we2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_8192x4_dp.out1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_8192x4_dp.out2\" clock=\"clk\"/>\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"clk\" energy_per_toggle=\"17.9e-12\"/> \n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"address1\" input=\"memory.addr1[12:0]\" output=\"mem_8192x4_dp.addr1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr1[12:0]\" out_port=\"mem_8192x4_dp.addr1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"address2\" input=\"memory.addr2[12:0]\" output=\"mem_8192x4_dp.addr2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr2[12:0]\" out_port=\"mem_8192x4_dp.addr2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data1\" input=\"memory.data[3:0]\" output=\"mem_8192x4_dp.data1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[3:0]\" out_port=\"mem_8192x4_dp.data1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data2\" input=\"memory.data[7:4]\" output=\"mem_8192x4_dp.data2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[7:4]\" out_port=\"mem_8192x4_dp.data2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_8192x4_dp.we1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_8192x4_dp.we1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen2\" input=\"memory.we2\" output=\"mem_8192x4_dp.we2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we2\" out_port=\"mem_8192x4_dp.we2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout1\" input=\"mem_8192x4_dp.out1\" output=\"memory.out[3:0]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_8192x4_dp.out1\" out_port=\"memory.out[3:0]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout2\" input=\"mem_8192x4_dp.out2\" output=\"memory.out[7:4]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_8192x4_dp.out2\" out_port=\"memory.out[7:4]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"clk\" input=\"memory.clk\" output=\"mem_8192x4_dp.clk\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, " <mode name=\"mem_16384x2_dp\">\n");
fprintf(fpout, " <pb_type name=\"mem_16384x2_dp\" blif_model=\".subckt dual_port_ram\" class=\"memory\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"addr1\" num_pins=\"14\" port_class=\"address1\"/>\n");
fprintf(fpout, " <input name=\"addr2\" num_pins=\"14\" port_class=\"address2\"/>\n");
fprintf(fpout, " <input name=\"data1\" num_pins=\"2\" port_class=\"data_in1\"/>\n");
fprintf(fpout, " <input name=\"data2\" num_pins=\"2\" port_class=\"data_in2\"/>\n");
fprintf(fpout, " <input name=\"we1\" num_pins=\"1\" port_class=\"write_en1\"/>\n");
fprintf(fpout, " <input name=\"we2\" num_pins=\"1\" port_class=\"write_en2\"/>\n");
fprintf(fpout, " <output name=\"out1\" num_pins=\"2\" port_class=\"data_out1\"/>\n");
fprintf(fpout, " <output name=\"out2\" num_pins=\"2\" port_class=\"data_out2\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_16384x2_dp.addr1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_16384x2_dp.data1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_16384x2_dp.we1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_16384x2_dp.addr2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_16384x2_dp.data2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_16384x2_dp.we2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_16384x2_dp.out1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_16384x2_dp.out2\" clock=\"clk\"/>\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"clk\" energy_per_toggle=\"17.9e-12\"/> \n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"address1\" input=\"memory.addr1[13:0]\" output=\"mem_16384x2_dp.addr1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr1[13:0]\" out_port=\"mem_16384x2_dp.addr1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"address2\" input=\"memory.addr2[13:0]\" output=\"mem_16384x2_dp.addr2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr2[13:0]\" out_port=\"mem_16384x2_dp.addr2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data1\" input=\"memory.data[1:0]\" output=\"mem_16384x2_dp.data1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[1:0]\" out_port=\"mem_16384x2_dp.data1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data2\" input=\"memory.data[3:2]\" output=\"mem_16384x2_dp.data2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[3:2]\" out_port=\"mem_16384x2_dp.data2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_16384x2_dp.we1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_16384x2_dp.we1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen2\" input=\"memory.we2\" output=\"mem_16384x2_dp.we2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we2\" out_port=\"mem_16384x2_dp.we2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout1\" input=\"mem_16384x2_dp.out1\" output=\"memory.out[1:0]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_16384x2_dp.out1\" out_port=\"memory.out[1:0]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout2\" input=\"mem_16384x2_dp.out2\" output=\"memory.out[3:2]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_16384x2_dp.out2\" out_port=\"memory.out[3:2]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"clk\" input=\"memory.clk\" output=\"mem_16384x2_dp.clk\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <mode name=\"mem_32768x1_dp\">\n");
fprintf(fpout, " <pb_type name=\"mem_32768x1_dp\" blif_model=\".subckt dual_port_ram\" class=\"memory\" num_pb=\"1\">\n");
fprintf(fpout, " <input name=\"addr1\" num_pins=\"15\" port_class=\"address1\"/>\n");
fprintf(fpout, " <input name=\"addr2\" num_pins=\"15\" port_class=\"address2\"/>\n");
fprintf(fpout, " <input name=\"data1\" num_pins=\"1\" port_class=\"data_in1\"/>\n");
fprintf(fpout, " <input name=\"data2\" num_pins=\"1\" port_class=\"data_in2\"/>\n");
fprintf(fpout, " <input name=\"we1\" num_pins=\"1\" port_class=\"write_en1\"/>\n");
fprintf(fpout, " <input name=\"we2\" num_pins=\"1\" port_class=\"write_en2\"/>\n");
fprintf(fpout, " <output name=\"out1\" num_pins=\"1\" port_class=\"data_out1\"/>\n");
fprintf(fpout, " <output name=\"out2\" num_pins=\"1\" port_class=\"data_out2\"/>\n");
fprintf(fpout, " <clock name=\"clk\" num_pins=\"1\" port_class=\"clock\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_32768x1_dp.addr1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_32768x1_dp.data1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_32768x1_dp.we1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_32768x1_dp.addr2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_32768x1_dp.data2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_setup value=\"509e-12\" port=\"mem_32768x1_dp.we2\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_32768x1_dp.out1\" clock=\"clk\"/>\n");
fprintf(fpout, " <T_clock_to_Q max=\"1.234e-9\" port=\"mem_32768x1_dp.out2\" clock=\"clk\"/>\n");
fprintf(fpout, " <power method=\"pin-toggle\">\n");
fprintf(fpout, " <port name=\"clk\" energy_per_toggle=\"17.9e-12\"/> \n");
fprintf(fpout, " <static_power power_per_instance=\"0.0\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <interconnect>\n");
fprintf(fpout, " <direct name=\"address1\" input=\"memory.addr1[14:0]\" output=\"mem_32768x1_dp.addr1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr1[14:0]\" out_port=\"mem_32768x1_dp.addr1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"address2\" input=\"memory.addr2[14:0]\" output=\"mem_32768x1_dp.addr2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.addr2[14:0]\" out_port=\"mem_32768x1_dp.addr2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data1\" input=\"memory.data[0:0]\" output=\"mem_32768x1_dp.data1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[0:0]\" out_port=\"mem_32768x1_dp.data1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"data2\" input=\"memory.data[1:1]\" output=\"mem_32768x1_dp.data2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.data[1:1]\" out_port=\"mem_32768x1_dp.data2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen1\" input=\"memory.we1\" output=\"mem_32768x1_dp.we1\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we1\" out_port=\"mem_32768x1_dp.we1\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"writeen2\" input=\"memory.we2\" output=\"mem_32768x1_dp.we2\">\n");
fprintf(fpout, " <delay_constant max=\"132e-12\" in_port=\"memory.we2\" out_port=\"mem_32768x1_dp.we2\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout1\" input=\"mem_32768x1_dp.out1\" output=\"memory.out[0:0]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_32768x1_dp.out1\" out_port=\"memory.out[0:0]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"dataout2\" input=\"mem_32768x1_dp.out2\" output=\"memory.out[1:1]\">\n");
fprintf(fpout, " <delay_constant max=\"40e-12\" in_port=\"mem_32768x1_dp.out2\" out_port=\"memory.out[1:1]\"/>\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " <direct name=\"clk\" input=\"memory.clk\" output=\"mem_32768x1_dp.clk\">\n");
fprintf(fpout, " </direct>\n");
fprintf(fpout, " </interconnect>\n");
fprintf(fpout, " </mode>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <!-- Every input pin is driven by 15%% of the tracks in a channel, every output pin is driven by 10%% of the tracks in a channel -->\n");
fprintf(fpout, " <fc in_type=\"frac\" in_val=\"0.15\" out_type=\"frac\" out_val=\"0.10\"/>\n");
fprintf(fpout, " <pinlocations pattern=\"spread\"/>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <!-- Place this memory block every 8 columns from (and including) the second column -->\n");
fprintf(fpout, " <gridlocations>\n");
fprintf(fpout, " <loc type=\"col\" start=\"2\" repeat=\"8\" priority=\"2\"/>\n");
fprintf(fpout, " </gridlocations>\n");
fprintf(fpout, "\n");
fprintf(fpout, " <power method=\"sum-of-children\"/>\n");
fprintf(fpout, " </pb_type>\n");
fprintf(fpout, " <!-- Define fracturable memory end -->\n");
fprintf(fpout, "\n");
fprintf(fpout, " </complexblocklist>\n");
fprintf(fpout, " <power>\n");
fprintf(fpout, " <local_interconnect C_wire=\"2.5e-10\"/>\n");
fprintf(fpout, " </power>\n");
fprintf(fpout, " <clocks>\n");
fprintf(fpout, " <clock buffer_size=\"auto\" C_wire=\"2.5e-10\"/>\n");
fprintf(fpout, " </clocks>\n");
fprintf(fpout, "</architecture>\n");
}