upgrade Verilog SB generator using the RRSwitchBlock
This commit is contained in:
parent
ec70bcee99
commit
ea8c36ce6e
|
@ -38,6 +38,14 @@ include(FilesToDirs)
|
|||
# compiler flag configuration checks
|
||||
include(CheckCXXCompilerFlag)
|
||||
|
||||
#
|
||||
# We require c++14 support
|
||||
#
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF) #No compiler specific extensions
|
||||
|
||||
|
||||
# Set WARN FLAGS
|
||||
set(WARN_FLAGS "")
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ class Side {
|
|||
enum e_side get_rotate_counterclockwise() const;
|
||||
bool validate() const;
|
||||
size_t to_size_t() const;
|
||||
char* to_string() const;
|
||||
public: /* Mutators */
|
||||
void set_side(size_t side);
|
||||
void set_side(enum e_side side);
|
||||
|
|
|
@ -87,6 +87,22 @@ size_t Side::to_size_t() const {
|
|||
}
|
||||
}
|
||||
|
||||
/* Convert to char* */
|
||||
char* Side::to_string() const {
|
||||
switch (side_) {
|
||||
case TOP:
|
||||
return "top";
|
||||
case RIGHT:
|
||||
return "right";
|
||||
case BOTTOM:
|
||||
return "bottom";
|
||||
case LEFT:
|
||||
return "left";
|
||||
default:
|
||||
return "invalid_side";
|
||||
}
|
||||
}
|
||||
|
||||
/* Public Mutators */
|
||||
void Side::set_side(size_t side) {
|
||||
switch (side) {
|
||||
|
|
|
@ -21,6 +21,7 @@ DeviceCoordinator::DeviceCoordinator() {
|
|||
}
|
||||
|
||||
/* Public accessors */
|
||||
|
||||
size_t DeviceCoordinator::get_x() const {
|
||||
return x_;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef DEVICE_COORDINATOR_H
|
||||
#define DEVICE_COORDINATOR_H
|
||||
|
||||
#include "sides.h"
|
||||
|
||||
/* Coordinator System for FPGA Device
|
||||
* It is based on a 3-D (x,y,z) coordinator system
|
||||
* (x,y) is used for all the routing resources,
|
||||
|
@ -8,9 +10,6 @@
|
|||
*/
|
||||
class DeviceCoordinator {
|
||||
public: /* Contructors */
|
||||
/*
|
||||
DeviceCoordinator(DeviceCoordinator& coordinator);
|
||||
*/
|
||||
DeviceCoordinator(size_t x, size_t y);
|
||||
DeviceCoordinator();
|
||||
public: /* Accessors */
|
||||
|
|
|
@ -3129,7 +3129,7 @@ void spice_backannotate_vpr_post_route_info(t_det_routing_arch RoutingArch,
|
|||
/* Build Array for each Switch block and Connection block */
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Collecting detailed information for each Switch block...\n");
|
||||
alloc_and_build_switch_blocks_info(RoutingArch, num_rr_nodes, rr_node, rr_node_indices);
|
||||
device_rr_switch_block = build_device_rr_switch_blocks(RoutingArch, num_rr_nodes, rr_node, rr_node_indices);
|
||||
device_rr_switch_block = build_device_rr_switch_blocks(num_rr_nodes, rr_node, rr_node_indices);
|
||||
|
||||
vpr_printf(TIO_MESSAGE_INFO, "Collecting detailed information for each to Connection block...\n");
|
||||
alloc_and_build_connection_blocks_info(RoutingArch, num_rr_nodes, rr_node, rr_node_indices);
|
||||
|
|
|
@ -82,7 +82,6 @@ void print_device_rr_chan_stats(DeviceRRChan& device_rr_chan);
|
|||
|
||||
static
|
||||
RRSwitchBlock build_rr_switch_block(int sb_x, int sb_y,
|
||||
t_det_routing_arch RoutingArch,
|
||||
int LL_num_rr_nodes,
|
||||
t_rr_node* LL_rr_node,
|
||||
t_ivec*** LL_rr_node_indices);
|
||||
|
@ -846,7 +845,6 @@ DeviceRRChan build_device_rr_chan(int LL_num_rr_nodes, t_rr_node* LL_rr_node,
|
|||
*/
|
||||
static
|
||||
RRSwitchBlock build_rr_switch_block(int sb_x, int sb_y,
|
||||
t_det_routing_arch RoutingArch,
|
||||
int LL_num_rr_nodes,
|
||||
t_rr_node* LL_rr_node,
|
||||
t_ivec*** LL_rr_node_indices) {
|
||||
|
@ -857,6 +855,9 @@ RRSwitchBlock build_rr_switch_block(int sb_x, int sb_y,
|
|||
assert((!(0 > sb_x))&&(!(sb_x > (nx + 1))));
|
||||
assert((!(0 > sb_y))&&(!(sb_y > (ny + 1))));
|
||||
|
||||
/* Coordinator initialization */
|
||||
rr_switch_block.set_coordinator(size_t(sb_x), size_t(sb_y));
|
||||
|
||||
/* Basic information*/
|
||||
rr_switch_block.init_num_sides(4); /* Fixed number of sides */
|
||||
|
||||
|
@ -1000,7 +1001,7 @@ RRSwitchBlock build_rr_switch_block(int sb_x, int sb_y,
|
|||
/* Grid[x][y+1] BOTTOM side outputs pins */
|
||||
opin_grid_side[0] = BOTTOM;
|
||||
/* Grid[x][y] TOP side outputs pins */
|
||||
opin_grid_side[0] = TOP;
|
||||
opin_grid_side[1] = TOP;
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
|
@ -1056,8 +1057,7 @@ RRSwitchBlock build_rr_switch_block(int sb_x, int sb_y,
|
|||
* Each switch block in the FPGA fabric will be an instance of these modules.
|
||||
* We maintain a map from each instance to each module
|
||||
*/
|
||||
DeviceRRSwitchBlock build_device_rr_switch_blocks(t_det_routing_arch RoutingArch,
|
||||
int LL_num_rr_nodes,
|
||||
DeviceRRSwitchBlock build_device_rr_switch_blocks(int LL_num_rr_nodes,
|
||||
t_rr_node* LL_rr_node,
|
||||
t_ivec*** LL_rr_node_indices) {
|
||||
/* Create an object */
|
||||
|
@ -1070,7 +1070,7 @@ DeviceRRSwitchBlock build_device_rr_switch_blocks(t_det_routing_arch RoutingArch
|
|||
/* For each switch block, determine the size of array */
|
||||
for (int ix = 0; ix < (nx + 1); ++ix) {
|
||||
for (int iy = 0; iy < (ny + 1); ++iy) {
|
||||
RRSwitchBlock rr_switch_block = build_rr_switch_block(ix, iy, RoutingArch,
|
||||
RRSwitchBlock rr_switch_block = build_rr_switch_block(ix, iy,
|
||||
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices);
|
||||
DeviceCoordinator sb_coordinator(ix, iy);
|
||||
LL_device_rr_switch_block.add_rr_switch_block(sb_coordinator, rr_switch_block);
|
||||
|
|
|
@ -14,8 +14,7 @@ DeviceRRChan build_device_rr_chan(int LL_num_rr_nodes, t_rr_node* LL_rr_node,
|
|||
* Each switch block in the FPGA fabric will be an instance of these modules.
|
||||
* We maintain a map from each instance to each module
|
||||
*/
|
||||
DeviceRRSwitchBlock build_device_rr_switch_blocks(t_det_routing_arch RoutingArch,
|
||||
int LL_num_rr_nodes,
|
||||
DeviceRRSwitchBlock build_device_rr_switch_blocks(int LL_num_rr_nodes,
|
||||
t_rr_node* LL_rr_node,
|
||||
t_ivec*** LL_rr_node_indices);
|
||||
|
||||
|
|
|
@ -35,6 +35,11 @@ enum e_dir_err {
|
|||
E_DIR_EXIST
|
||||
};
|
||||
|
||||
|
||||
/***** Local Subroutines *****/
|
||||
static
|
||||
enum e_dir_err try_access_dir(char* dir_path);
|
||||
|
||||
/***** Subroutines *****/
|
||||
char* my_gettime() {
|
||||
time_t current_time;
|
||||
|
@ -98,6 +103,7 @@ void my_remove_file(char* file_path) {
|
|||
return;
|
||||
}
|
||||
|
||||
static
|
||||
enum e_dir_err try_access_dir(char* dir_path) {
|
||||
struct stat s;
|
||||
int err = stat(dir_path, &s);
|
||||
|
@ -141,6 +147,7 @@ int create_dir_path(char* dir_path) {
|
|||
dir_path);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"Create directory(%s)...Failed!\n",dir_path);
|
||||
exit(1);
|
||||
|
@ -651,13 +658,23 @@ char* fpga_spice_create_one_subckt_filename(char* file_name_prefix,
|
|||
int subckt_x, int subckt_y,
|
||||
char* file_name_postfix) {
|
||||
char* fname = NULL;
|
||||
|
||||
if ( -1 == subckt_y ) {
|
||||
fname = (char*) my_malloc(sizeof(char) * (strlen(file_name_prefix)
|
||||
+ strlen(my_itoa(subckt_x)) + 1
|
||||
+ strlen(file_name_postfix) + 1));
|
||||
|
||||
fname = (char*) my_malloc(sizeof(char) * (strlen(file_name_prefix)
|
||||
+ strlen(my_itoa(subckt_x)) + 1 + strlen(my_itoa(subckt_y))
|
||||
+ strlen(file_name_postfix) + 1));
|
||||
sprintf(fname, "%s%d_%s",
|
||||
file_name_prefix, subckt_x, file_name_postfix);
|
||||
|
||||
sprintf(fname, "%s%d_%d%s",
|
||||
file_name_prefix, subckt_x, subckt_y, file_name_postfix);
|
||||
} else {
|
||||
fname = (char*) my_malloc(sizeof(char) * (strlen(file_name_prefix)
|
||||
+ strlen(my_itoa(subckt_x)) + 1 + strlen(my_itoa(subckt_y))
|
||||
+ strlen(file_name_postfix) + 1));
|
||||
|
||||
sprintf(fname, "%s%d_%d%s",
|
||||
file_name_prefix, subckt_x, subckt_y, file_name_postfix);
|
||||
}
|
||||
|
||||
return fname;
|
||||
}
|
||||
|
@ -1226,7 +1243,6 @@ int get_rr_node_net_init_value(t_rr_node node) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int recommend_num_sim_clock_cycle(float sim_window_size) {
|
||||
float avg_density = 0.;
|
||||
float median_density = 0.;
|
||||
|
|
|
@ -71,6 +71,9 @@ char* format_spice_node_prefix(char* spice_node_prefix);
|
|||
|
||||
t_block* search_mapped_block(int x, int y, int z);
|
||||
|
||||
int* my_decimal2binary(int decimal,
|
||||
int* binary_len);
|
||||
|
||||
char** fpga_spice_strtok(char* str,
|
||||
char* delims,
|
||||
int* len);
|
||||
|
@ -128,7 +131,7 @@ float get_rr_node_net_probability(t_rr_node node);
|
|||
|
||||
int get_rr_node_net_init_value(t_rr_node node);
|
||||
|
||||
int recommend_num_sim_clock_cycle();
|
||||
int recommend_num_sim_clock_cycle(float sim_window_size);
|
||||
|
||||
void auto_select_num_sim_clock_cycle(t_spice* spice,
|
||||
float signal_density_weight);
|
||||
|
@ -406,4 +409,6 @@ void get_fpga_x2p_global_all_clock_ports(t_llist* head,
|
|||
int* num_clock_ports,
|
||||
t_spice_model_port*** clock_port);
|
||||
|
||||
int my_strlen_int(int input_int);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
|
||||
#include <util.h>
|
||||
|
||||
#include "quicksort.h"
|
||||
|
||||
void my_free(void* ptr);
|
||||
|
||||
/* Subroutines */
|
||||
|
|
|
@ -2,3 +2,10 @@
|
|||
/* QuickSort functions */
|
||||
void quicksort_float_index(int len, int* sort_index,
|
||||
float* sort_value);
|
||||
|
||||
void quicksort_float(int len,
|
||||
float* sort_value);
|
||||
|
||||
void do_quicksort_float_index(int len,
|
||||
int* sort_index,
|
||||
float* sort_value);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <cassert>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include "rr_blocks.h"
|
||||
|
@ -85,6 +86,7 @@ bool RRChan::is_mirror(RRChan& cand) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Mutators */
|
||||
/* modify type */
|
||||
void RRChan::set_type(t_rr_type type) {
|
||||
|
@ -306,17 +308,32 @@ bool DeviceRRChan::valid_module_id(t_rr_type chan_type, size_t module_id) const
|
|||
|
||||
/* Accessors */
|
||||
|
||||
/* get the x coordinator of this switch block */
|
||||
size_t RRSwitchBlock::get_x() const {
|
||||
return coordinator_.get_x();
|
||||
}
|
||||
|
||||
/* get the y coordinator of this switch block */
|
||||
size_t RRSwitchBlock::get_y() const {
|
||||
return coordinator_.get_y();
|
||||
}
|
||||
|
||||
/* Get the number of sides of this SB */
|
||||
DeviceCoordinator RRSwitchBlock::get_coordinator() const {
|
||||
return coordinator_;
|
||||
}
|
||||
|
||||
/* Get the number of sides of this SB */
|
||||
size_t RRSwitchBlock::get_num_sides() const {
|
||||
assert (validate_num_sides());
|
||||
return chan_rr_node_direction_.size();
|
||||
return chan_node_direction_.size();
|
||||
}
|
||||
|
||||
/* Get the number of routing tracks on a side */
|
||||
size_t RRSwitchBlock::get_chan_width(enum e_side side) const {
|
||||
Side side_manager(side);
|
||||
assert(side_manager.validate());
|
||||
return chan_rr_node_[side_manager.to_size_t()].size();
|
||||
return chan_node_[side_manager.to_size_t()].size();
|
||||
}
|
||||
|
||||
/* Get the direction of a rr_node at a given side and track_id */
|
||||
|
@ -330,7 +347,7 @@ enum PORTS RRSwitchBlock::get_chan_node_direction(enum e_side side, size_t track
|
|||
/* Ensure the track is valid in the context of this switch block at a specific side */
|
||||
assert( validate_track_id(side, track_id) );
|
||||
|
||||
return chan_rr_node_direction_[side_manager.to_size_t()][track_id];
|
||||
return chan_node_direction_[side_manager.to_size_t()][track_id];
|
||||
}
|
||||
|
||||
/* get a rr_node at a given side and track_id */
|
||||
|
@ -344,21 +361,61 @@ t_rr_node* RRSwitchBlock::get_chan_node(enum e_side side, size_t track_id) const
|
|||
/* Ensure the track is valid in the context of this switch block at a specific side */
|
||||
assert( validate_track_id(side, track_id) );
|
||||
|
||||
return chan_rr_node_[side_manager.to_size_t()][track_id];
|
||||
return chan_node_[side_manager.to_size_t()][track_id];
|
||||
}
|
||||
|
||||
/* Get the number of IPIN rr_nodes on a side */
|
||||
size_t RRSwitchBlock::get_num_ipin_rr_nodes(enum e_side side) const {
|
||||
size_t RRSwitchBlock::get_num_ipin_nodes(enum e_side side) const {
|
||||
Side side_manager(side);
|
||||
assert(side_manager.validate());
|
||||
return ipin_rr_node_[side_manager.to_size_t()].size();
|
||||
return ipin_node_[side_manager.to_size_t()].size();
|
||||
}
|
||||
|
||||
/* Get the number of OPIN rr_nodes on a side */
|
||||
size_t RRSwitchBlock::get_num_opin_rr_nodes(enum e_side side) const {
|
||||
size_t RRSwitchBlock::get_num_opin_nodes(enum e_side side) const {
|
||||
Side side_manager(side);
|
||||
assert(side_manager.validate());
|
||||
return opin_rr_node_[side_manager.to_size_t()].size();
|
||||
return opin_node_[side_manager.to_size_t()].size();
|
||||
}
|
||||
|
||||
/* get a opin_node at a given side and track_id */
|
||||
t_rr_node* RRSwitchBlock::get_opin_node(enum e_side side, size_t node_id) const {
|
||||
Side side_manager(side);
|
||||
assert(side_manager.validate());
|
||||
|
||||
/* Ensure the side is valid in the context of this switch block */
|
||||
assert( validate_side(side) );
|
||||
|
||||
/* Ensure the track is valid in the context of this switch block at a specific side */
|
||||
assert( validate_opin_node_id(side, node_id) );
|
||||
|
||||
return opin_node_[side_manager.to_size_t()][node_id];
|
||||
}
|
||||
|
||||
/* get the grid_side of a opin_node at a given side and track_id */
|
||||
enum e_side RRSwitchBlock::get_opin_node_grid_side(enum e_side side, size_t node_id) const {
|
||||
Side side_manager(side);
|
||||
assert(side_manager.validate());
|
||||
|
||||
/* Ensure the side is valid in the context of this switch block */
|
||||
assert( validate_side(side) );
|
||||
|
||||
/* Ensure the track is valid in the context of this switch block at a specific side */
|
||||
assert( validate_opin_node_id(side, node_id) );
|
||||
|
||||
return opin_node_grid_side_[side_manager.to_size_t()][node_id];
|
||||
}
|
||||
|
||||
/* get the grid side of a opin_rr_node */
|
||||
enum e_side RRSwitchBlock::get_opin_node_grid_side(t_rr_node* opin_node) const {
|
||||
enum e_side side;
|
||||
int index;
|
||||
|
||||
/* Find the side and index */
|
||||
get_node_side_and_index(opin_node, IN_PORT, &side, &index);
|
||||
assert(-1 != index);
|
||||
assert(validate_side(side));
|
||||
return get_opin_node_grid_side(side, index);
|
||||
}
|
||||
|
||||
/* Get the node index in the array, return -1 if not found */
|
||||
|
@ -377,25 +434,25 @@ int RRSwitchBlock::get_node_index(t_rr_node* node,
|
|||
case CHANX:
|
||||
case CHANY:
|
||||
for (size_t inode = 0; inode < get_chan_width(node_side); ++inode) {
|
||||
if ((node == chan_rr_node_[side_manager.to_size_t()][inode])
|
||||
if ((node == chan_node_[side_manager.to_size_t()][inode])
|
||||
/* Check if direction meets specification */
|
||||
&&(node_direction == chan_rr_node_direction_[side_manager.to_size_t()][inode])) {
|
||||
&&(node_direction == chan_node_direction_[side_manager.to_size_t()][inode])) {
|
||||
cnt++;
|
||||
ret = inode;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IPIN:
|
||||
for (size_t inode = 0; inode < get_num_ipin_rr_nodes(node_side); ++inode) {
|
||||
if (node == ipin_rr_node_[side_manager.to_size_t()][inode]) {
|
||||
for (size_t inode = 0; inode < get_num_ipin_nodes(node_side); ++inode) {
|
||||
if (node == ipin_node_[side_manager.to_size_t()][inode]) {
|
||||
cnt++;
|
||||
ret = inode;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case OPIN:
|
||||
for (size_t inode = 0; inode < get_num_opin_rr_nodes(node_side); ++inode) {
|
||||
if (node == opin_rr_node_[side_manager.to_size_t()][inode]) {
|
||||
for (size_t inode = 0; inode < get_num_opin_nodes(node_side); ++inode) {
|
||||
if (node == opin_node_[side_manager.to_size_t()][inode]) {
|
||||
cnt++;
|
||||
ret = inode;
|
||||
}
|
||||
|
@ -469,11 +526,29 @@ void RRSwitchBlock::get_node_side_and_index(t_rr_node* node,
|
|||
}
|
||||
|
||||
size_t RRSwitchBlock::get_num_reserved_conf_bits() const {
|
||||
return num_reserved_conf_bits_;
|
||||
assert (validate_num_reserved_conf_bits());
|
||||
return reserved_conf_bits_msb_ - reserved_conf_bits_lsb_ + 1;
|
||||
}
|
||||
|
||||
size_t RRSwitchBlock::get_reserved_conf_bits_lsb() const {
|
||||
return reserved_conf_bits_lsb_;
|
||||
}
|
||||
|
||||
size_t RRSwitchBlock::get_reserved_conf_bits_msb() const {
|
||||
return reserved_conf_bits_msb_;
|
||||
}
|
||||
|
||||
size_t RRSwitchBlock::get_num_conf_bits() const {
|
||||
return num_conf_bits_;
|
||||
assert (validate_num_conf_bits());
|
||||
return conf_bits_msb_ - conf_bits_lsb_ + 1;
|
||||
}
|
||||
|
||||
size_t RRSwitchBlock::get_conf_bits_lsb() const {
|
||||
return conf_bits_lsb_;
|
||||
}
|
||||
|
||||
size_t RRSwitchBlock::get_conf_bits_msb() const {
|
||||
return conf_bits_msb_;
|
||||
}
|
||||
|
||||
/* Check if the node imply a short connection inside the SB, which happens to long wires across a FPGA fabric */
|
||||
|
@ -493,8 +568,6 @@ bool RRSwitchBlock::is_node_imply_short_connection(t_rr_node* src_node) const {
|
|||
}
|
||||
|
||||
return false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* check if the candidate SB is a mirror of the current one */
|
||||
|
@ -547,7 +620,7 @@ bool RRSwitchBlock::is_mirror(RRSwitchBlock& cand) const {
|
|||
for (size_t side = 0; side < get_num_sides(); ++side) {
|
||||
Side side_manager(side);
|
||||
|
||||
if (get_num_ipin_rr_nodes(side_manager.get_side()) != cand.get_num_ipin_rr_nodes(side_manager.get_side())) {
|
||||
if (get_num_ipin_nodes(side_manager.get_side()) != cand.get_num_ipin_nodes(side_manager.get_side())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -561,64 +634,144 @@ bool RRSwitchBlock::is_mirror(RRSwitchBlock& cand) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
/* Public Accessors: Cooridinator conversion */
|
||||
DeviceCoordinator RRSwitchBlock::get_side_block_coordinator(enum e_side side) const {
|
||||
Side side_manager(side);
|
||||
assert(side_manager.validate());
|
||||
DeviceCoordinator ret(get_x(), get_y());
|
||||
|
||||
switch (side_manager.get_side()) {
|
||||
case TOP:
|
||||
/* (0 == side) */
|
||||
/* 1. Channel Y [x][y+1] inputs */
|
||||
ret.set_y(ret.get_y() + 1);
|
||||
break;
|
||||
case RIGHT:
|
||||
/* 1 == side */
|
||||
/* 2. Channel X [x+1][y] inputs */
|
||||
ret.set_x(ret.get_x() + 1);
|
||||
break;
|
||||
case BOTTOM:
|
||||
/* 2 == side */
|
||||
/* 3. Channel Y [x][y] inputs */
|
||||
break;
|
||||
case LEFT:
|
||||
/* 3 == side */
|
||||
/* 4. Channel X [x][y] inputs */
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(File: %s [LINE%d]) Invalid side!\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Public Accessors Verilog writer */
|
||||
char* RRSwitchBlock::gen_verilog_module_name() const {
|
||||
char* ret = NULL;
|
||||
std::string x_str = std::to_string(get_x());
|
||||
std::string y_str = std::to_string(get_y());
|
||||
|
||||
ret = (char*)my_malloc(2 + 1 + x_str.length()
|
||||
+ 2 + y_str.length()
|
||||
+ 1 + 1);
|
||||
|
||||
sprintf(ret, "sb_%lu__%lu_",
|
||||
get_x(), get_y());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* RRSwitchBlock::gen_verilog_instance_name() const {
|
||||
char* ret = NULL;
|
||||
std::string x_str = std::to_string(get_x());
|
||||
std::string y_str = std::to_string(get_y());
|
||||
|
||||
ret = (char*)my_malloc(2 + 1 + x_str.length()
|
||||
+ 2 + y_str.length()
|
||||
+ 4 + 1);
|
||||
|
||||
sprintf(ret, "sb_%lu__%lu__0_",
|
||||
get_x(), get_y());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/* Public mutators */
|
||||
/* Allocate the vectors with the given number of sides */
|
||||
void RRSwitchBlock::init_num_sides(size_t num_sides) {
|
||||
/* Initialize the vectors */
|
||||
chan_rr_node_direction_.resize(num_sides);
|
||||
chan_rr_node_.resize(num_sides);
|
||||
ipin_rr_node_.resize(num_sides);
|
||||
ipin_rr_node_grid_side_.resize(num_sides);
|
||||
opin_rr_node_.resize(num_sides);
|
||||
opin_rr_node_grid_side_.resize(num_sides);
|
||||
|
||||
/* Set the coordinator (x,y) for the switch block */
|
||||
void RRSwitchBlock::set_coordinator(size_t x, size_t y) {
|
||||
coordinator_.set(x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add a node to the chan_rr_node_ list and also assign its direction in chan_rr_node_direction_ */
|
||||
/* Allocate the vectors with the given number of sides */
|
||||
void RRSwitchBlock::init_num_sides(size_t num_sides) {
|
||||
/* Initialize the vectors */
|
||||
chan_node_direction_.resize(num_sides);
|
||||
chan_node_.resize(num_sides);
|
||||
ipin_node_.resize(num_sides);
|
||||
ipin_node_grid_side_.resize(num_sides);
|
||||
opin_node_.resize(num_sides);
|
||||
opin_node_grid_side_.resize(num_sides);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add a node to the chan_node_ list and also assign its direction in chan_node_direction_ */
|
||||
void RRSwitchBlock::add_chan_node(t_rr_node* node, enum e_side node_side, enum PORTS node_direction) {
|
||||
Side side_manager(node_side);
|
||||
assert(validate_side(node_side));
|
||||
/* resize the array if needed, node is placed in the sequence of node->ptc_num */
|
||||
if (size_t(node->ptc_num + 1) > chan_rr_node_[side_manager.to_size_t()].size()) {
|
||||
chan_rr_node_[side_manager.to_size_t()].resize(node->ptc_num + 1); /* resize to the maximum */
|
||||
chan_rr_node_direction_[side_manager.to_size_t()].resize(node->ptc_num + 1); /* resize to the maximum */
|
||||
if (size_t(node->ptc_num + 1) > chan_node_[side_manager.to_size_t()].size()) {
|
||||
chan_node_[side_manager.to_size_t()].resize(node->ptc_num + 1); /* resize to the maximum */
|
||||
chan_node_direction_[side_manager.to_size_t()].resize(node->ptc_num + 1); /* resize to the maximum */
|
||||
}
|
||||
/* fill the dedicated element in the vector */
|
||||
chan_rr_node_[side_manager.to_size_t()][node->ptc_num] = node;
|
||||
chan_rr_node_direction_[side_manager.to_size_t()][node->ptc_num] = node_direction;
|
||||
chan_node_[side_manager.to_size_t()][node->ptc_num] = node;
|
||||
chan_node_direction_[side_manager.to_size_t()][node->ptc_num] = node_direction;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add a node to the chan_rr_node_ list and also assign its direction in chan_rr_node_direction_ */
|
||||
/* Add a node to the chan_node_ list and also assign its direction in chan_node_direction_ */
|
||||
void RRSwitchBlock::add_ipin_node(t_rr_node* node, enum e_side node_side, enum e_side grid_side) {
|
||||
Side side_manager(node_side);
|
||||
assert(validate_side(node_side));
|
||||
/* push pack the dedicated element in the vector */
|
||||
ipin_rr_node_[side_manager.to_size_t()].push_back(node);
|
||||
ipin_rr_node_grid_side_[side_manager.to_size_t()].push_back(grid_side);
|
||||
ipin_node_[side_manager.to_size_t()].push_back(node);
|
||||
ipin_node_grid_side_[side_manager.to_size_t()].push_back(grid_side);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add a node to the chan_rr_node_ list and also assign its direction in chan_rr_node_direction_ */
|
||||
/* Add a node to the chan_node_ list and also assign its direction in chan_node_direction_ */
|
||||
void RRSwitchBlock::add_opin_node(t_rr_node* node, enum e_side node_side, enum e_side grid_side) {
|
||||
Side side_manager(node_side);
|
||||
assert(validate_side(node_side));
|
||||
/* push pack the dedicated element in the vector */
|
||||
opin_rr_node_[side_manager.to_size_t()].push_back(node);
|
||||
opin_rr_node_grid_side_[side_manager.to_size_t()].push_back(grid_side);
|
||||
opin_node_[side_manager.to_size_t()].push_back(node);
|
||||
opin_node_grid_side_[side_manager.to_size_t()].push_back(grid_side);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void RRSwitchBlock::set_num_reserved_conf_bits(size_t num_reserved_conf_bits) {
|
||||
num_reserved_conf_bits_ = num_reserved_conf_bits;
|
||||
reserved_conf_bits_lsb_ = 0;
|
||||
reserved_conf_bits_msb_ = num_reserved_conf_bits - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
void RRSwitchBlock::set_num_conf_bits(size_t num_conf_bits) {
|
||||
num_conf_bits_ = num_conf_bits;
|
||||
void RRSwitchBlock::set_conf_bits_lsb(size_t conf_bits_lsb) {
|
||||
conf_bits_lsb_ = conf_bits_lsb;
|
||||
return;
|
||||
}
|
||||
|
||||
void RRSwitchBlock::set_conf_bits_msb(size_t conf_bits_msb) {
|
||||
conf_bits_msb_ = conf_bits_msb;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -627,22 +780,26 @@ void RRSwitchBlock::clear() {
|
|||
assert(validate_num_sides());
|
||||
/* Clear the inner vector of each matrix */
|
||||
for (size_t side = 0; side < get_num_sides(); ++side) {
|
||||
chan_rr_node_direction_[side].clear();
|
||||
chan_rr_node_[side].clear();
|
||||
ipin_rr_node_[side].clear();
|
||||
ipin_rr_node_grid_side_[side].clear();
|
||||
opin_rr_node_[side].clear();
|
||||
opin_rr_node_grid_side_[side].clear();
|
||||
chan_node_direction_[side].clear();
|
||||
chan_node_[side].clear();
|
||||
ipin_node_[side].clear();
|
||||
ipin_node_grid_side_[side].clear();
|
||||
opin_node_[side].clear();
|
||||
opin_node_grid_side_[side].clear();
|
||||
}
|
||||
chan_rr_node_direction_.clear();
|
||||
chan_rr_node_.clear();
|
||||
ipin_rr_node_.clear();
|
||||
ipin_rr_node_grid_side_.clear();
|
||||
opin_rr_node_.clear();
|
||||
opin_rr_node_grid_side_.clear();
|
||||
chan_node_direction_.clear();
|
||||
chan_node_.clear();
|
||||
ipin_node_.clear();
|
||||
ipin_node_grid_side_.clear();
|
||||
opin_node_.clear();
|
||||
opin_node_grid_side_.clear();
|
||||
|
||||
set_num_reserved_conf_bits(0);
|
||||
set_num_conf_bits(0);
|
||||
/* Just to make the lsb and msb invalidate */
|
||||
reserved_conf_bits_lsb_ = 1;
|
||||
reserved_conf_bits_msb_ = 0;
|
||||
/* Just to make the lsb and msb invalidate */
|
||||
set_conf_bits_lsb(1);
|
||||
set_conf_bits_msb(0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -652,8 +809,8 @@ void RRSwitchBlock::clear_chan_nodes(enum e_side node_side) {
|
|||
Side side_manager(node_side);
|
||||
assert(validate_side(node_side));
|
||||
|
||||
chan_rr_node_[side_manager.to_size_t()].clear();
|
||||
chan_rr_node_direction_[side_manager.to_size_t()].clear();
|
||||
chan_node_[side_manager.to_size_t()].clear();
|
||||
chan_node_direction_[side_manager.to_size_t()].clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -662,8 +819,8 @@ void RRSwitchBlock::clear_ipin_nodes(enum e_side node_side) {
|
|||
Side side_manager(node_side);
|
||||
assert(validate_side(node_side));
|
||||
|
||||
ipin_rr_node_[side_manager.to_size_t()].clear();
|
||||
ipin_rr_node_grid_side_[side_manager.to_size_t()].clear();
|
||||
ipin_node_[side_manager.to_size_t()].clear();
|
||||
ipin_node_grid_side_[side_manager.to_size_t()].clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -672,8 +829,8 @@ void RRSwitchBlock::clear_opin_nodes(enum e_side node_side) {
|
|||
Side side_manager(node_side);
|
||||
assert(validate_side(node_side));
|
||||
|
||||
opin_rr_node_[side_manager.to_size_t()].clear();
|
||||
opin_rr_node_grid_side_[side_manager.to_size_t()].clear();
|
||||
opin_node_[side_manager.to_size_t()].clear();
|
||||
opin_node_grid_side_[side_manager.to_size_t()].clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -745,25 +902,25 @@ bool RRSwitchBlock::is_node_mirror(RRSwitchBlock& cand,
|
|||
|
||||
/* Validate if the number of sides are consistent among internal data arrays ! */
|
||||
bool RRSwitchBlock::validate_num_sides() const {
|
||||
size_t num_sides = chan_rr_node_direction_.size();
|
||||
size_t num_sides = chan_node_direction_.size();
|
||||
|
||||
if ( num_sides != chan_rr_node_.size() ) {
|
||||
if ( num_sides != chan_node_.size() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( num_sides != ipin_rr_node_.size() ) {
|
||||
if ( num_sides != ipin_node_.size() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( num_sides != ipin_rr_node_grid_side_.size() ) {
|
||||
if ( num_sides != ipin_node_grid_side_.size() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( num_sides != opin_rr_node_.size() ) {
|
||||
if ( num_sides != opin_node_.size() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( num_sides != opin_rr_node_grid_side_.size() ) {
|
||||
if ( num_sides != opin_node_grid_side_.size() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -779,20 +936,52 @@ bool RRSwitchBlock::validate_side(enum e_side side) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Check the track_id is valid for chan_rr_node_ and chan_rr_node_direction_ */
|
||||
/* Check the track_id is valid for chan_node_ and chan_node_direction_ */
|
||||
bool RRSwitchBlock::validate_track_id(enum e_side side, size_t track_id) const {
|
||||
Side side_manager(side);
|
||||
|
||||
if (false == validate_side(side)) {
|
||||
return false;
|
||||
}
|
||||
if ( track_id < chan_rr_node_[side_manager.to_size_t()].size() ) {
|
||||
if ( ( track_id < chan_node_[side_manager.to_size_t()].size())
|
||||
&& ( track_id < chan_node_direction_[side_manager.to_size_t()].size()) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check the opin_node_id is valid for opin_node_ and opin_node_grid_side_ */
|
||||
bool RRSwitchBlock::validate_opin_node_id(enum e_side side, size_t node_id) const {
|
||||
Side side_manager(side);
|
||||
|
||||
if (false == validate_side(side)) {
|
||||
return false;
|
||||
}
|
||||
if ( ( node_id < opin_node_[side_manager.to_size_t()].size())
|
||||
&&( node_id < opin_node_grid_side_[side_manager.to_size_t()].size()) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Validate the number of configuration bits, MSB should be no less than the LSB !!! */
|
||||
bool RRSwitchBlock::validate_num_conf_bits() const {
|
||||
if (conf_bits_msb_ >= conf_bits_lsb_) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Validate the number of configuration bits, MSB should be no less than the LSB !!! */
|
||||
bool RRSwitchBlock::validate_num_reserved_conf_bits() const {
|
||||
if (reserved_conf_bits_msb_ >= reserved_conf_bits_lsb_) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Member Functions of Class RRChan */
|
||||
/* Accessors */
|
||||
|
||||
|
|
|
@ -121,26 +121,43 @@ class DeviceRRChan {
|
|||
class RRSwitchBlock {
|
||||
public: /* Contructors */
|
||||
public: /* Accessors */
|
||||
size_t get_x() const; /* get the x coordinator of this switch block */
|
||||
size_t get_y() const; /* get the y coordinator of this switch block */
|
||||
DeviceCoordinator get_coordinator() const; /* Get the number of sides of this SB */
|
||||
size_t get_num_sides() const; /* Get the number of sides of this SB */
|
||||
size_t get_chan_width(enum e_side side) const; /* Get the number of routing tracks on a side */
|
||||
enum PORTS get_chan_node_direction(enum e_side side, size_t track_id) const; /* Get the direction of a rr_node at a given side and track_id */
|
||||
t_rr_node* get_chan_node(enum e_side side, size_t track_id) const; /* get a rr_node at a given side and track_id */
|
||||
size_t get_num_ipin_rr_nodes(enum e_side side) const; /* Get the number of IPIN rr_nodes on a side */
|
||||
size_t get_num_opin_rr_nodes(enum e_side side) const; /* Get the number of OPIN rr_nodes on a side */
|
||||
size_t get_num_ipin_nodes(enum e_side side) const; /* Get the number of IPIN rr_nodes on a side */
|
||||
size_t get_num_opin_nodes(enum e_side side) const; /* Get the number of OPIN rr_nodes on a side */
|
||||
t_rr_node* get_opin_node(enum e_side side, size_t node_id) const; /* get a rr_node at a given side and track_id */
|
||||
enum e_side get_opin_node_grid_side(enum e_side side, size_t node_id) const; /* get a rr_node at a given side and track_id */
|
||||
enum e_side get_opin_node_grid_side(t_rr_node* opin_node) const; /* get a rr_node at a given side and track_id */
|
||||
int get_node_index(t_rr_node* node, enum e_side node_side, enum PORTS node_direction) const; /* Get the node index in the array, return -1 if not found */
|
||||
void get_node_side_and_index(t_rr_node* node, enum PORTS node_direction, enum e_side* node_side, int* node_index) const; /* Given a rr_node, try to find its side and index in the Switch block */
|
||||
bool is_node_exist_opposite_side(t_rr_node* node, enum e_side node_side) const; /* Check if the node exist in the opposite side of this Switch Block */
|
||||
size_t get_num_reserved_conf_bits() const;
|
||||
size_t get_reserved_conf_bits_lsb() const;
|
||||
size_t get_reserved_conf_bits_msb() const;
|
||||
size_t get_num_conf_bits() const;
|
||||
size_t get_conf_bits_lsb() const;
|
||||
size_t get_conf_bits_msb() const;
|
||||
bool is_node_imply_short_connection(t_rr_node* src_node) const; /* Check if the node imply a short connection inside the SB, which happens to long wires across a FPGA fabric */
|
||||
bool is_mirror(RRSwitchBlock& cand) const; /* check if the candidate SB is a mirror of the current one */
|
||||
public: /* Cooridinator conversion */
|
||||
DeviceCoordinator get_side_block_coordinator(enum e_side side) const;
|
||||
public: /* Verilog writer */
|
||||
char* gen_verilog_module_name() const;
|
||||
char* gen_verilog_instance_name() const;
|
||||
public: /* Mutators */
|
||||
void set_coordinator(size_t x, size_t y);
|
||||
void init_num_sides(size_t num_sides); /* Allocate the vectors with the given number of sides */
|
||||
void add_chan_node(t_rr_node* node, enum e_side node_side, enum PORTS node_direction); /* Add a node to the chan_rr_node_ list and also assign its direction in chan_rr_node_direction_ */
|
||||
void add_ipin_node(t_rr_node* node, enum e_side node_side, enum e_side grid_side); /* Add a node to the chan_rr_node_ list and also assign its direction in chan_rr_node_direction_ */
|
||||
void add_opin_node(t_rr_node* node, enum e_side node_side, enum e_side grid_side); /* Add a node to the chan_rr_node_ list and also assign its direction in chan_rr_node_direction_ */
|
||||
void set_num_reserved_conf_bits(size_t num_reserved_conf_bits);
|
||||
void set_num_conf_bits(size_t num_conf_bits);
|
||||
void set_conf_bits_lsb(size_t conf_bits_lsb);
|
||||
void set_conf_bits_msb(size_t conf_bits_msb);
|
||||
void clear();
|
||||
void clear_chan_nodes(enum e_side node_side); /* Clean the chan_width of a side */
|
||||
void clear_ipin_nodes(enum e_side node_side); /* Clean the number of IPINs of a side */
|
||||
|
@ -152,15 +169,21 @@ class RRSwitchBlock {
|
|||
bool validate_num_sides() const;
|
||||
bool validate_side(enum e_side side) const;
|
||||
bool validate_track_id(enum e_side side, size_t track_id) const;
|
||||
bool validate_opin_node_id(enum e_side side, size_t node_id) const;
|
||||
bool validate_num_reserved_conf_bits() const;
|
||||
bool validate_num_conf_bits() const;
|
||||
private: /* Internal Data */
|
||||
std::vector< std::vector<enum PORTS> > chan_rr_node_direction_;
|
||||
std::vector< std::vector<t_rr_node*> > chan_rr_node_;
|
||||
std::vector< std::vector<t_rr_node*> > ipin_rr_node_;
|
||||
std::vector< std::vector<enum e_side> > ipin_rr_node_grid_side_;
|
||||
std::vector< std::vector<t_rr_node*> > opin_rr_node_;
|
||||
std::vector< std::vector<enum e_side> > opin_rr_node_grid_side_;
|
||||
size_t num_reserved_conf_bits_;
|
||||
size_t num_conf_bits_;
|
||||
DeviceCoordinator coordinator_;
|
||||
std::vector< std::vector<enum PORTS> > chan_node_direction_;
|
||||
std::vector< std::vector<t_rr_node*> > chan_node_;
|
||||
std::vector< std::vector<t_rr_node*> > ipin_node_;
|
||||
std::vector< std::vector<enum e_side> > ipin_node_grid_side_;
|
||||
std::vector< std::vector<t_rr_node*> > opin_node_;
|
||||
std::vector< std::vector<enum e_side> > opin_node_grid_side_;
|
||||
size_t reserved_conf_bits_lsb_;
|
||||
size_t reserved_conf_bits_msb_;
|
||||
size_t conf_bits_lsb_; /* Least Significant Bit (LSB) of configuration port*/
|
||||
size_t conf_bits_msb_; /* Most Significant Bit (MSB) of configuration port*/
|
||||
};
|
||||
|
||||
/* Object Device Routing Resource Switch Block
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
||||
/* Include vpr structs*/
|
||||
#include "util.h"
|
||||
|
@ -24,6 +25,7 @@
|
|||
|
||||
/* Include SPICE support headers*/
|
||||
#include "linkedlist.h"
|
||||
#include "rr_blocks.h"
|
||||
#include "fpga_x2p_types.h"
|
||||
#include "fpga_x2p_utils.h"
|
||||
#include "fpga_x2p_backannotate_utils.h"
|
||||
|
@ -37,6 +39,7 @@
|
|||
#include "verilog_utils.h"
|
||||
#include "verilog_routing.h"
|
||||
|
||||
static
|
||||
void dump_verilog_routing_chan_subckt(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
char* verilog_dir,
|
||||
char* subckt_dir,
|
||||
|
@ -53,7 +56,7 @@ void dump_verilog_routing_chan_subckt(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
/* Print preprocessing flags */
|
||||
verilog_include_defines_preproc_file(fp, verilog_dir);
|
||||
/* Comment lines */
|
||||
fprintf(fp, "//----- Verilog Module of Channel X [%u] -----\n", rr_chan_subckt_id);
|
||||
fprintf(fp, "//----- Verilog Module of Channel X [%lu] -----\n", rr_chan_subckt_id);
|
||||
break;
|
||||
case CHANY:
|
||||
/* Create file handler */
|
||||
|
@ -61,7 +64,7 @@ void dump_verilog_routing_chan_subckt(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
/* Print preprocessing flags */
|
||||
verilog_include_defines_preproc_file(fp, verilog_dir);
|
||||
/* Comment lines */
|
||||
fprintf(fp, "//----- Verilog Module Channel Y [%u] -----\n", rr_chan_subckt_id);
|
||||
fprintf(fp, "//----- Verilog Module Channel Y [%lu] -----\n", rr_chan_subckt_id);
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
|
@ -87,15 +90,15 @@ void dump_verilog_routing_chan_subckt(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
for (size_t itrack = 0; itrack < rr_chan.get_chan_width(); ++itrack) {
|
||||
switch (rr_chan.get_node(itrack)->direction) {
|
||||
case INC_DIRECTION:
|
||||
fprintf(fp, " input in%u, //--- track %u input \n", itrack, itrack);
|
||||
fprintf(fp, " input in%lu, //--- track %lu input \n", itrack, itrack);
|
||||
break;
|
||||
case DEC_DIRECTION:
|
||||
fprintf(fp, " output out%u, //--- track %u output \n", itrack, itrack);
|
||||
fprintf(fp, " output out%lu, //--- track %lu output \n", itrack, itrack);
|
||||
break;
|
||||
case BI_DIRECTION:
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(File: %s [LINE%d]) Invalid direction of rr_node %s[%u]_in/out[%u]!\n",
|
||||
"(File: %s [LINE%d]) Invalid direction of rr_node %s[%lu]_in/out[%lu]!\n",
|
||||
__FILE__, __LINE__,
|
||||
convert_chan_type_to_string(rr_chan.get_type()),
|
||||
rr_chan_subckt_id, itrack);
|
||||
|
@ -105,15 +108,15 @@ void dump_verilog_routing_chan_subckt(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
for (size_t itrack = 0; itrack < rr_chan.get_chan_width(); ++itrack) {
|
||||
switch (rr_chan.get_node(itrack)->direction) {
|
||||
case INC_DIRECTION:
|
||||
fprintf(fp, " output out%u, //--- track %u output\n", itrack, itrack);
|
||||
fprintf(fp, " output out%lu, //--- track %lu output\n", itrack, itrack);
|
||||
break;
|
||||
case DEC_DIRECTION:
|
||||
fprintf(fp, " input in%u, //--- track %u input \n", itrack, itrack);
|
||||
fprintf(fp, " input in%lu, //--- track %lu input \n", itrack, itrack);
|
||||
break;
|
||||
case BI_DIRECTION:
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(File: %s [LINE%d]) Invalid direction of rr_node %s[%u]_in/out[%u]!\n",
|
||||
"(File: %s [LINE%d]) Invalid direction of rr_node %s[%lu]_in/out[%lu]!\n",
|
||||
__FILE__, __LINE__,
|
||||
convert_chan_type_to_string(rr_chan.get_type()),
|
||||
rr_chan_subckt_id, itrack);
|
||||
|
@ -122,11 +125,11 @@ void dump_verilog_routing_chan_subckt(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
}
|
||||
/* Middle point output for connection box inputs */
|
||||
for (size_t itrack = 0; itrack < rr_chan.get_chan_width(); ++itrack) {
|
||||
fprintf(fp, " output mid_out%u", itrack);
|
||||
fprintf(fp, " output mid_out%lu", itrack);
|
||||
if (itrack < (rr_chan.get_chan_width() - 1)) {
|
||||
fprintf(fp, ",");
|
||||
}
|
||||
fprintf(fp, " // Middle output %u to logic blocks \n", itrack);
|
||||
fprintf(fp, " // Middle output %lu to logic blocks \n", itrack);
|
||||
}
|
||||
fprintf(fp, " );\n");
|
||||
|
||||
|
@ -135,15 +138,15 @@ void dump_verilog_routing_chan_subckt(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
/* short connecting inputs and outputs:
|
||||
* length of metal wire and parasitics are handled by semi-custom flow
|
||||
*/
|
||||
fprintf(fp, "assign out%u = in%u; \n", itrack, itrack);
|
||||
fprintf(fp, "assign mid_out%u = in%u; \n", itrack, itrack);
|
||||
fprintf(fp, "assign out%lu = in%lu; \n", itrack, itrack);
|
||||
fprintf(fp, "assign mid_out%lu = in%lu; \n", itrack, itrack);
|
||||
}
|
||||
|
||||
fprintf(fp, "endmodule\n");
|
||||
|
||||
/* Comment lines */
|
||||
fprintf(fp,
|
||||
"//----- END Verilog Module of %s [%u] -----\n\n",
|
||||
"//----- END Verilog Module of %s [%lu] -----\n\n",
|
||||
convert_chan_type_to_string(rr_chan.get_type()),
|
||||
rr_chan_subckt_id);
|
||||
|
||||
|
@ -481,8 +484,6 @@ void dump_verilog_grid_side_pins(FILE* fp,
|
|||
fprintf(fp, " grid_%d__%d__pin_%d__%d__%d_", x, y, height, side, ipin);
|
||||
if (TRUE == dump_port_type) {
|
||||
fprintf(fp, ",\n");
|
||||
} else {
|
||||
fprintf(fp, ",\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -660,6 +661,131 @@ void dump_verilog_switch_box_chan_port(FILE* fp,
|
|||
return;
|
||||
}
|
||||
|
||||
void dump_verilog_unique_switch_box_chan_port(FILE* fp,
|
||||
RRSwitchBlock& rr_sb,
|
||||
enum e_side chan_side,
|
||||
t_rr_node* cur_rr_node,
|
||||
enum PORTS cur_rr_node_direction) {
|
||||
int index = -1;
|
||||
t_rr_type chan_rr_node_type;
|
||||
DeviceCoordinator chan_rr_node_coordinator;
|
||||
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Get the index in sb_info of cur_rr_node */
|
||||
index = rr_sb.get_node_index(cur_rr_node, chan_side, cur_rr_node_direction);
|
||||
/* Make sure this node is included in this sb_info */
|
||||
assert((-1 != index)&&(NUM_SIDES != chan_side));
|
||||
|
||||
chan_rr_node_type = cur_rr_node->type;
|
||||
chan_rr_node_coordinator = rr_sb.get_side_block_coordinator(chan_side);
|
||||
|
||||
fprintf(fp, "%s_%lu__%lu__%s_%d_ ",
|
||||
convert_chan_type_to_string(chan_rr_node_type),
|
||||
chan_rr_node_coordinator.get_x(), chan_rr_node_coordinator.get_y(),
|
||||
convert_chan_rr_node_direction_to_string(cur_rr_node_direction),
|
||||
cur_rr_node->ptc_num);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Print a short interconneciton in switch box
|
||||
* There are two cases should be noticed.
|
||||
* 1. The actual fan-in of cur_rr_node is 0. In this case,
|
||||
the cur_rr_node need to be short connected to itself which is on the opposite side of this switch
|
||||
* 2. The actual fan-in of cur_rr_node is 0. In this case,
|
||||
* The cur_rr_node need to connected to the drive_rr_node
|
||||
*/
|
||||
void dump_verilog_unique_switch_box_short_interc(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
FILE* fp,
|
||||
RRSwitchBlock& rr_sb,
|
||||
enum e_side chan_side,
|
||||
t_rr_node* cur_rr_node,
|
||||
int actual_fan_in,
|
||||
t_rr_node* drive_rr_node) {
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Check */
|
||||
assert((0 == actual_fan_in)||(1 == actual_fan_in));
|
||||
|
||||
char* chan_name = convert_chan_type_to_string(cur_rr_node->type);
|
||||
|
||||
/* Get the index in sb_info of cur_rr_node */
|
||||
int index = rr_sb.get_node_index(cur_rr_node, chan_side, OUT_PORT);
|
||||
char* des_chan_port_name = "out";
|
||||
|
||||
fprintf(fp, "//----- Short connection %s[%lu][%lu]_%s[%d] -----\n",
|
||||
chan_name, rr_sb.get_coordinator().get_x(), rr_sb.get_coordinator().get_y(), des_chan_port_name, cur_rr_node->ptc_num);
|
||||
fprintf(fp, "assign ");
|
||||
|
||||
/* Output port */
|
||||
dump_verilog_unique_switch_box_chan_port(fp, rr_sb, chan_side, cur_rr_node, OUT_PORT);
|
||||
fprintf(fp, " = ");
|
||||
|
||||
/* Check the driver*/
|
||||
if (0 == actual_fan_in) {
|
||||
assert(drive_rr_node == cur_rr_node);
|
||||
} else {
|
||||
/* drive_rr_node = &(rr_node[cur_rr_node->prev_node]); */
|
||||
assert(1 == rr_node_drive_switch_box(drive_rr_node, cur_rr_node, rr_sb.get_coordinator().get_x(), rr_sb.get_coordinator().get_y(), chan_side));
|
||||
}
|
||||
|
||||
int grid_x = drive_rr_node->xlow;
|
||||
int grid_y = drive_rr_node->ylow; /*Plus the offset in function fprint_grid_side_pin_with_given_index */
|
||||
switch (drive_rr_node->type) {
|
||||
/* case SOURCE: */
|
||||
case OPIN:
|
||||
/* Find grid_x and grid_y */
|
||||
/* Print a grid pin */
|
||||
dump_verilog_grid_side_pin_with_given_index(fp, IPIN, /* this is an input of a Switch Box */
|
||||
drive_rr_node->ptc_num,
|
||||
rr_sb.get_opin_node_grid_side(drive_rr_node),
|
||||
grid_x, grid_y,
|
||||
FALSE); /* Do not dump the direction of the port! */
|
||||
break;
|
||||
case CHANX:
|
||||
case CHANY:
|
||||
enum e_side side;
|
||||
/* Should an input */
|
||||
if (cur_rr_node == drive_rr_node) {
|
||||
/* To be strict, the input should locate on the opposite side.
|
||||
* Use the else part if this may change in some architecture.
|
||||
*/
|
||||
Side side_manager(chan_side);
|
||||
side = side_manager.get_opposite();
|
||||
} else {
|
||||
rr_sb.get_node_side_and_index(drive_rr_node, IN_PORT, &side, &index);
|
||||
assert ( -1 != index );
|
||||
assert ( NUM_SIDES != side );
|
||||
}
|
||||
/* We need to be sure that drive_rr_node is part of the SB */
|
||||
dump_verilog_unique_switch_box_chan_port(fp, rr_sb, side, drive_rr_node, IN_PORT);
|
||||
break;
|
||||
/* SOURCE is invalid as well */
|
||||
default: /* IPIN, SINK are invalid*/
|
||||
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid rr_node type! Should be [OPIN|CHANX|CHANY].\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* END */
|
||||
fprintf(fp, ";\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Print a short interconneciton in switch box
|
||||
* There are two cases should be noticed.
|
||||
* 1. The actual fan-in of cur_rr_node is 0. In this case,
|
||||
|
@ -1005,6 +1131,246 @@ void dump_verilog_switch_box_mux(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Print the SPICE netlist of multiplexer that drive this rr_node */
|
||||
void dump_verilog_unique_switch_box_mux(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
FILE* fp,
|
||||
RRSwitchBlock& rr_sb,
|
||||
enum e_side chan_side,
|
||||
t_rr_node* cur_rr_node,
|
||||
int mux_size,
|
||||
t_rr_node** drive_rr_nodes,
|
||||
int switch_index) {
|
||||
int input_cnt = 0;
|
||||
t_spice_model* verilog_model = NULL;
|
||||
int mux_level, path_id, cur_num_sram;
|
||||
int num_mux_sram_bits = 0;
|
||||
int* mux_sram_bits = NULL;
|
||||
int num_mux_conf_bits = 0;
|
||||
int num_mux_reserved_conf_bits = 0;
|
||||
int cur_bl, cur_wl;
|
||||
t_spice_model* mem_model = NULL;
|
||||
char* mem_subckt_name = NULL;
|
||||
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Check */
|
||||
/* Check current rr_node is CHANX or CHANY*/
|
||||
assert((CHANX == cur_rr_node->type)||(CHANY == cur_rr_node->type));
|
||||
|
||||
/* Allocate drive_rr_nodes according to the fan-in*/
|
||||
assert((2 == mux_size)||(2 < mux_size));
|
||||
|
||||
/* Get verilog model*/
|
||||
verilog_model = switch_inf[switch_index].spice_model;
|
||||
/* Specify the input bus */
|
||||
fprintf(fp, "wire [0:%d] %s_size%d_%d_inbus;\n",
|
||||
mux_size - 1,
|
||||
verilog_model->prefix, mux_size, verilog_model->cnt);
|
||||
char* name_mux = (char *) my_malloc(sizeof(char)*(1
|
||||
+ strlen(verilog_model->prefix) + 5
|
||||
+ strlen(my_itoa(mux_size)) + 1
|
||||
+ strlen(my_itoa(verilog_model->cnt)) + 5));
|
||||
sprintf(name_mux, "/%s_size%d_%d_/in", verilog_model->prefix, mux_size, verilog_model->cnt);
|
||||
|
||||
char* path_hierarchy = rr_sb.gen_verilog_instance_name();
|
||||
cur_rr_node->name_mux = my_strcat(path_hierarchy, name_mux);
|
||||
|
||||
/* Input ports*/
|
||||
/* Connect input ports to bus */
|
||||
for (size_t inode = 0; inode < size_t(mux_size); ++inode) {
|
||||
enum e_side side;
|
||||
int index;
|
||||
int grid_x = drive_rr_nodes[inode]->xlow;
|
||||
int grid_y = drive_rr_nodes[inode]->ylow; /*Plus the offset in function fprint_grid_side_pin_with_given_index */
|
||||
switch (drive_rr_nodes[inode]->type) {
|
||||
/* case SOURCE: */
|
||||
case OPIN:
|
||||
/* Indicate a CLB Outpin*/
|
||||
/* Find grid_x and grid_y */
|
||||
/* Print a grid pin */
|
||||
fprintf(fp, "assign %s_size%d_%d_inbus[%d] = ",
|
||||
verilog_model->prefix, mux_size, verilog_model->cnt, input_cnt);
|
||||
dump_verilog_grid_side_pin_with_given_index(fp, IPIN, drive_rr_nodes[inode]->ptc_num,
|
||||
rr_sb.get_opin_node_grid_side(drive_rr_nodes[inode]),
|
||||
grid_x, grid_y, FALSE);
|
||||
fprintf(fp, ";\n");
|
||||
input_cnt++;
|
||||
break;
|
||||
case CHANX:
|
||||
case CHANY:
|
||||
/* Should be an input ! */
|
||||
rr_sb.get_node_side_and_index(drive_rr_nodes[inode], IN_PORT, &side, &index);
|
||||
/* We need to be sure that drive_rr_node is part of the SB */
|
||||
assert((-1 != index) && (NUM_SIDES != side));
|
||||
fprintf(fp, "assign %s_size%d_%d_inbus[%d] = ",
|
||||
verilog_model->prefix, mux_size, verilog_model->cnt, input_cnt);
|
||||
dump_verilog_unique_switch_box_chan_port(fp, rr_sb, side, drive_rr_nodes[inode], IN_PORT);
|
||||
fprintf(fp, ";\n");
|
||||
input_cnt++;
|
||||
break;
|
||||
default: /* IPIN, SINK are invalid*/
|
||||
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid rr_node type! Should be [OPIN|CHANX|CHANY].\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
assert(input_cnt == mux_size);
|
||||
|
||||
/* Print SRAMs that configure this MUX */
|
||||
/* cur_num_sram = sram_verilog_model->cnt; */
|
||||
cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info);
|
||||
get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_bl, &cur_wl);
|
||||
/* connect to reserved BL/WLs ? */
|
||||
num_mux_reserved_conf_bits = count_num_reserved_conf_bits_one_spice_model(verilog_model,
|
||||
cur_sram_orgz_info->type,
|
||||
mux_size);
|
||||
/* Get the number of configuration bits required by this MUX */
|
||||
num_mux_conf_bits = count_num_conf_bits_one_spice_model(verilog_model,
|
||||
cur_sram_orgz_info->type,
|
||||
mux_size);
|
||||
|
||||
/* Dump the configuration port bus */
|
||||
dump_verilog_mux_config_bus(fp, verilog_model, cur_sram_orgz_info,
|
||||
mux_size, cur_num_sram, num_mux_reserved_conf_bits, num_mux_conf_bits);
|
||||
|
||||
/* Dump ports visible only during formal verification */
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag);
|
||||
/*
|
||||
dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info,
|
||||
cur_num_sram,
|
||||
cur_num_sram + num_mux_conf_bits - 1,
|
||||
VERILOG_PORT_WIRE);
|
||||
fprintf(fp, ";\n");
|
||||
*/
|
||||
dump_verilog_formal_verification_mux_sram_ports_wiring(fp, cur_sram_orgz_info,
|
||||
verilog_model, mux_size,
|
||||
cur_num_sram,
|
||||
cur_num_sram + num_mux_conf_bits - 1);
|
||||
|
||||
fprintf(fp, "`endif\n");
|
||||
|
||||
/* Now it is the time print the SPICE netlist of MUX*/
|
||||
fprintf(fp, "%s_size%d %s_size%d_%d_ (",
|
||||
verilog_model->prefix, mux_size,
|
||||
verilog_model->prefix, mux_size, verilog_model->cnt);
|
||||
|
||||
/* Dump global ports */
|
||||
if (0 < rec_dump_verilog_spice_model_global_ports(fp, verilog_model, FALSE, FALSE, FALSE)) {
|
||||
fprintf(fp, ",\n");
|
||||
}
|
||||
|
||||
fprintf(fp, "%s_size%d_%d_inbus, ",
|
||||
verilog_model->prefix, mux_size, verilog_model->cnt);
|
||||
|
||||
/* Output port */
|
||||
dump_verilog_unique_switch_box_chan_port(fp, rr_sb, chan_side, cur_rr_node, OUT_PORT);
|
||||
/* Add a comma because dump_verilog_switch_box_chan_port does not add so */
|
||||
fprintf(fp, ", ");
|
||||
|
||||
/* Different design technology requires different configuration bus! */
|
||||
dump_verilog_mux_config_bus_ports(fp, verilog_model, cur_sram_orgz_info,
|
||||
mux_size, cur_num_sram, num_mux_reserved_conf_bits, num_mux_conf_bits);
|
||||
|
||||
fprintf(fp, ");\n");
|
||||
|
||||
/* Configuration bits for this MUX*/
|
||||
path_id = DEFAULT_PATH_ID;
|
||||
for (int inode = 0; inode < mux_size; ++inode) {
|
||||
if (drive_rr_nodes[inode] == &(rr_node[cur_rr_node->prev_node])) {
|
||||
path_id = inode;
|
||||
cur_rr_node->id_path = inode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Depend on both technology and structure of this MUX*/
|
||||
switch (verilog_model->design_tech) {
|
||||
case SPICE_MODEL_DESIGN_CMOS:
|
||||
decode_cmos_mux_sram_bits(verilog_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level);
|
||||
break;
|
||||
case SPICE_MODEL_DESIGN_RRAM:
|
||||
decode_rram_mux(verilog_model, mux_size, path_id, &num_mux_sram_bits, &mux_sram_bits, &mux_level);
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for verilog model (%s)!\n",
|
||||
__FILE__, __LINE__, verilog_model->name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Print the encoding in SPICE netlist for debugging */
|
||||
switch (verilog_model->design_tech) {
|
||||
case SPICE_MODEL_DESIGN_CMOS:
|
||||
fprintf(fp, "//----- SRAM bits for MUX[%d], level=%d, select_path_id=%d. -----\n",
|
||||
verilog_model->cnt, mux_level, path_id);
|
||||
fprintf(fp, "//----- From LSB(LEFT) TO MSB (RIGHT) -----\n");
|
||||
fprintf(fp, "//-----");
|
||||
fprint_commented_sram_bits(fp, num_mux_sram_bits, mux_sram_bits);
|
||||
fprintf(fp, "-----\n");
|
||||
break;
|
||||
case SPICE_MODEL_DESIGN_RRAM:
|
||||
fprintf(fp, "//----- BL/WL bits for 4T1R MUX[%d], level=%d, select_path_id=%d. -----\n",
|
||||
verilog_model->cnt, mux_level, path_id);
|
||||
fprintf(fp, "//----- From LSB(LEFT) TO MSB (RIGHT) -----\n");
|
||||
fprintf(fp, "//---- BL: ");
|
||||
fprint_commented_sram_bits(fp, num_mux_sram_bits/2, mux_sram_bits);
|
||||
fprintf(fp, "-----\n");
|
||||
fprintf(fp, "//----- From LSB(LEFT) TO MSB (RIGHT) -----\n");
|
||||
fprintf(fp, "//---- WL: ");
|
||||
fprint_commented_sram_bits(fp, num_mux_sram_bits/2, mux_sram_bits + num_mux_sram_bits/2);
|
||||
fprintf(fp, "-----\n");
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for verilog model (%s)!\n",
|
||||
__FILE__, __LINE__, verilog_model->name);
|
||||
}
|
||||
|
||||
get_sram_orgz_info_mem_model(cur_sram_orgz_info, &mem_model);
|
||||
/* Dump sram modules */
|
||||
switch (verilog_model->design_tech) {
|
||||
case SPICE_MODEL_DESIGN_CMOS:
|
||||
/* Call the memory module defined for this SRAM-based MUX! */
|
||||
mem_subckt_name = generate_verilog_mux_subckt_name(verilog_model, mux_size, verilog_mem_posfix);
|
||||
fprintf(fp, "%s %s_%d_ ( ",
|
||||
mem_subckt_name, mem_subckt_name, verilog_model->cnt);
|
||||
dump_verilog_mem_sram_submodule(fp, cur_sram_orgz_info, verilog_model, mux_size, mem_model,
|
||||
cur_num_sram, cur_num_sram + num_mux_conf_bits - 1);
|
||||
fprintf(fp, ");\n");
|
||||
/* update the number of memory bits */
|
||||
update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, cur_num_sram + num_mux_conf_bits);
|
||||
break;
|
||||
case SPICE_MODEL_DESIGN_RRAM:
|
||||
/* RRAM-based MUX does not need any SRAM dumping
|
||||
* But we have to get the number of configuration bits required by this MUX
|
||||
* and update the number of memory bits
|
||||
*/
|
||||
update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, cur_num_sram + num_mux_conf_bits);
|
||||
update_sram_orgz_info_num_blwl(cur_sram_orgz_info,
|
||||
cur_bl + num_mux_conf_bits,
|
||||
cur_wl + num_mux_conf_bits);
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid design technology for verilog model (%s)!\n",
|
||||
__FILE__, __LINE__, verilog_model->name);
|
||||
}
|
||||
|
||||
|
||||
/* update sram counter */
|
||||
verilog_model->cnt++;
|
||||
|
||||
/* Free */
|
||||
my_free(mux_sram_bits);
|
||||
my_free(mem_subckt_name);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Count the number of configuration bits of a rr_node*/
|
||||
int count_verilog_switch_box_interc_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
t_sb cur_sb_info, int chan_side,
|
||||
|
@ -1041,6 +1407,43 @@ int count_verilog_switch_box_interc_conf_bits(t_sram_orgz_info* cur_sram_orgz_in
|
|||
}
|
||||
}
|
||||
|
||||
/* Count the number of configuration bits of a rr_node*/
|
||||
size_t count_verilog_switch_box_interc_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
RRSwitchBlock& rr_sb, enum e_side chan_side,
|
||||
t_rr_node* cur_rr_node) {
|
||||
size_t num_conf_bits = 0;
|
||||
int switch_idx = 0;
|
||||
int num_drive_rr_nodes = 0;
|
||||
|
||||
if (NULL == cur_rr_node) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(File:%s, [LINE%d])NULL cur_rr_node!\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
return num_conf_bits;
|
||||
}
|
||||
|
||||
/* Determine if the interc lies inside a channel wire, that is interc between segments */
|
||||
if (true == rr_sb.is_node_exist_opposite_side(cur_rr_node, chan_side)) {
|
||||
num_drive_rr_nodes = 0;
|
||||
} else {
|
||||
num_drive_rr_nodes = cur_rr_node->num_drive_rr_nodes;
|
||||
}
|
||||
|
||||
/* fan_in >= 2 implies a MUX and requires configuration bits */
|
||||
if (2 > num_drive_rr_nodes) {
|
||||
return num_conf_bits;
|
||||
} else {
|
||||
switch_idx = cur_rr_node->drive_switches[0];
|
||||
assert(-1 < switch_idx);
|
||||
assert(SPICE_MODEL_MUX == switch_inf[switch_idx].spice_model->type);
|
||||
num_conf_bits = count_num_conf_bits_one_spice_model(switch_inf[switch_idx].spice_model,
|
||||
cur_sram_orgz_info->type,
|
||||
num_drive_rr_nodes);
|
||||
return num_conf_bits;
|
||||
}
|
||||
}
|
||||
|
||||
/* Count the number of reserved configuration bits of a rr_node*/
|
||||
int count_verilog_switch_box_interc_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
t_sb cur_sb_info, int chan_side,
|
||||
|
@ -1078,6 +1481,42 @@ int count_verilog_switch_box_interc_reserved_conf_bits(t_sram_orgz_info* cur_sra
|
|||
}
|
||||
}
|
||||
|
||||
/* Count the number of reserved configuration bits of a rr_node*/
|
||||
size_t count_verilog_switch_box_interc_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
RRSwitchBlock& rr_sb, enum e_side chan_side,
|
||||
t_rr_node* cur_rr_node) {
|
||||
size_t num_reserved_conf_bits = 0;
|
||||
int switch_idx = 0;
|
||||
int num_drive_rr_nodes = 0;
|
||||
|
||||
if (NULL == cur_rr_node) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])NULL cur_rr_node!\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
return num_reserved_conf_bits;
|
||||
}
|
||||
|
||||
/* Determine if the interc lies inside a channel wire, that is interc between segments */
|
||||
if (1 == rr_sb.is_node_exist_opposite_side(cur_rr_node, chan_side)) {
|
||||
num_drive_rr_nodes = 0;
|
||||
} else {
|
||||
num_drive_rr_nodes = cur_rr_node->num_drive_rr_nodes;
|
||||
}
|
||||
|
||||
/* fan_in >= 2 implies a MUX and requires configuration bits */
|
||||
if (2 > num_drive_rr_nodes) {
|
||||
return num_reserved_conf_bits;
|
||||
} else {
|
||||
switch_idx = cur_rr_node->drive_switches[0];
|
||||
assert(-1 < switch_idx);
|
||||
assert(SPICE_MODEL_MUX == switch_inf[switch_idx].spice_model->type);
|
||||
num_reserved_conf_bits =
|
||||
count_num_reserved_conf_bits_one_spice_model(switch_inf[switch_idx].spice_model,
|
||||
cur_sram_orgz_info->type,
|
||||
num_drive_rr_nodes);
|
||||
return num_reserved_conf_bits;
|
||||
}
|
||||
}
|
||||
|
||||
void dump_verilog_switch_box_interc(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
FILE* fp,
|
||||
|
@ -1134,6 +1573,54 @@ void dump_verilog_switch_box_interc(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
return;
|
||||
}
|
||||
|
||||
void dump_verilog_unique_switch_box_interc(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
FILE* fp,
|
||||
RRSwitchBlock& rr_sb,
|
||||
enum e_side chan_side,
|
||||
t_rr_node* cur_rr_node) {
|
||||
int num_drive_rr_nodes = 0;
|
||||
t_rr_node** drive_rr_nodes = NULL;
|
||||
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Determine if the interc lies inside a channel wire, that is interc between segments */
|
||||
/* Check each num_drive_rr_nodes, see if they appear in the cur_sb_info */
|
||||
if (true == rr_sb.is_node_imply_short_connection(cur_rr_node)) {
|
||||
/* Double check if the interc lies inside a channel wire, that is interc between segments */
|
||||
assert(true == rr_sb.is_node_exist_opposite_side(cur_rr_node, chan_side));
|
||||
num_drive_rr_nodes = 0;
|
||||
drive_rr_nodes = NULL;
|
||||
} else {
|
||||
num_drive_rr_nodes = cur_rr_node->num_drive_rr_nodes;
|
||||
drive_rr_nodes = cur_rr_node->drive_rr_nodes;
|
||||
}
|
||||
|
||||
if (0 == num_drive_rr_nodes) {
|
||||
/* Print a special direct connection*/
|
||||
dump_verilog_unique_switch_box_short_interc(cur_sram_orgz_info, fp, rr_sb, chan_side, cur_rr_node,
|
||||
num_drive_rr_nodes, cur_rr_node);
|
||||
} else if (1 == num_drive_rr_nodes) {
|
||||
/* Print a direct connection*/
|
||||
dump_verilog_unique_switch_box_short_interc(cur_sram_orgz_info, fp, rr_sb, chan_side, cur_rr_node,
|
||||
num_drive_rr_nodes, drive_rr_nodes[DEFAULT_SWITCH_ID]);
|
||||
} else if (1 < num_drive_rr_nodes) {
|
||||
/* Print the multiplexer, fan_in >= 2 */
|
||||
dump_verilog_unique_switch_box_mux(cur_sram_orgz_info, fp, rr_sb, chan_side, cur_rr_node,
|
||||
num_drive_rr_nodes, drive_rr_nodes,
|
||||
cur_rr_node->drive_switches[DEFAULT_SWITCH_ID]);
|
||||
} /*Nothing should be done else*/
|
||||
|
||||
/* Free */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Count the number of configuration bits of a Switch Box */
|
||||
int count_verilog_switch_box_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
t_sb* cur_sb_info) {
|
||||
|
@ -1166,6 +1653,38 @@ int count_verilog_switch_box_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_
|
|||
return num_reserved_conf_bits;
|
||||
}
|
||||
|
||||
/* Count the number of configuration bits of a Switch Box */
|
||||
size_t count_verilog_switch_box_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
RRSwitchBlock& rr_sb) {
|
||||
size_t num_reserved_conf_bits = 0;
|
||||
size_t temp_num_reserved_conf_bits = 0;
|
||||
|
||||
for (size_t side = 0; side < rr_sb.get_num_sides(); ++side) {
|
||||
Side side_manager(side);
|
||||
for (size_t itrack = 0; itrack < rr_sb.get_chan_width(side_manager.get_side()); ++itrack) {
|
||||
switch (rr_sb.get_chan_node_direction(side_manager.get_side(), itrack)) {
|
||||
case OUT_PORT:
|
||||
temp_num_reserved_conf_bits =
|
||||
count_verilog_switch_box_interc_reserved_conf_bits(cur_sram_orgz_info, rr_sb, side_manager.get_side(),
|
||||
rr_sb.get_chan_node(side_manager.get_side(), itrack));
|
||||
/* Always select the largest number of reserved conf_bits */
|
||||
num_reserved_conf_bits = std::max(num_reserved_conf_bits, temp_num_reserved_conf_bits);
|
||||
break;
|
||||
case IN_PORT:
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(File: %s [LINE%d]) Invalid direction of port Channel node[%d] track[%d]!\n",
|
||||
__FILE__, __LINE__, side, itrack);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return num_reserved_conf_bits;
|
||||
}
|
||||
|
||||
|
||||
/* Count the number of configuration bits of a Switch Box */
|
||||
int count_verilog_switch_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
t_sb* cur_sb_info) {
|
||||
|
@ -1192,6 +1711,216 @@ int count_verilog_switch_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
return num_conf_bits;
|
||||
}
|
||||
|
||||
/* Count the number of configuration bits of a Switch Box */
|
||||
size_t count_verilog_switch_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
RRSwitchBlock& rr_sb) {
|
||||
size_t num_conf_bits = 0;
|
||||
|
||||
for (size_t side = 0; side < rr_sb.get_num_sides(); ++side) {
|
||||
Side side_manager(side);
|
||||
for (size_t itrack = 0; itrack < rr_sb.get_chan_width(side_manager.get_side()); ++itrack) {
|
||||
switch (rr_sb.get_chan_node_direction(side_manager.get_side(), itrack)) {
|
||||
case OUT_PORT:
|
||||
num_conf_bits += count_verilog_switch_box_interc_conf_bits(cur_sram_orgz_info, rr_sb, side_manager.get_side(),
|
||||
rr_sb.get_chan_node(side_manager.get_side(), itrack));
|
||||
break;
|
||||
case IN_PORT:
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(File: %s [LINE%d]) Invalid direction of port Channel node[%d] track[%d]!\n",
|
||||
__FILE__, __LINE__, side, itrack);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return num_conf_bits;
|
||||
}
|
||||
|
||||
|
||||
/* Task: Print the subckt of a Switch Box.
|
||||
* A Switch Box subckt consists of following ports:
|
||||
* 1. Channel Y [x][y] inputs
|
||||
* 2. Channel X [x+1][y] inputs
|
||||
* 3. Channel Y [x][y-1] outputs
|
||||
* 4. Channel X [x][y] outputs
|
||||
* 5. Grid[x][y+1] Right side outputs pins
|
||||
* 6. Grid[x+1][y+1] Left side output pins
|
||||
* 7. Grid[x+1][y+1] Bottom side output pins
|
||||
* 8. Grid[x+1][y] Top side output pins
|
||||
* 9. Grid[x+1][y] Left side output pins
|
||||
* 10. Grid[x][y] Right side output pins
|
||||
* 11. Grid[x][y] Top side output pins
|
||||
* 12. Grid[x][y+1] Bottom side output pins
|
||||
*
|
||||
* -------------- --------------
|
||||
* | | | |
|
||||
* | Grid | ChanY | Grid |
|
||||
* | [x][y+1] | [x][y+1] | [x+1][y+1] |
|
||||
* | | | |
|
||||
* -------------- --------------
|
||||
* ----------
|
||||
* ChanX | Switch | ChanX
|
||||
* [x][y] | Box | [x+1][y]
|
||||
* | [x][y] |
|
||||
* ----------
|
||||
* -------------- --------------
|
||||
* | | | |
|
||||
* | Grid | ChanY | Grid |
|
||||
* | [x][y] | [x][y] | [x+1][y] |
|
||||
* | | | |
|
||||
* -------------- --------------
|
||||
*/
|
||||
void dump_verilog_routing_switch_box_unique_subckt(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
char* verilog_dir, char* subckt_dir,
|
||||
RRSwitchBlock& rr_sb,
|
||||
int LL_num_rr_nodes, t_rr_node* LL_rr_node,
|
||||
t_ivec*** LL_rr_node_indices,
|
||||
t_syn_verilog_opts fpga_verilog_opts) {
|
||||
FILE* fp = NULL;
|
||||
char* fname = NULL;
|
||||
|
||||
/* Count the number of configuration bits to be consumed by this Switch block */
|
||||
int num_conf_bits = count_verilog_switch_box_conf_bits(cur_sram_orgz_info, rr_sb);
|
||||
/* Count the number of reserved configuration bits to be consumed by this Switch block */
|
||||
int num_reserved_conf_bits = count_verilog_switch_box_reserved_conf_bits(cur_sram_orgz_info, rr_sb);
|
||||
/* Estimate the sram_verilog_model->cnt */
|
||||
int cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info);
|
||||
int esti_sram_cnt = cur_num_sram + num_conf_bits;
|
||||
/* Record the index */
|
||||
rr_sb.set_num_reserved_conf_bits(num_reserved_conf_bits);
|
||||
rr_sb.set_conf_bits_lsb(cur_num_sram);
|
||||
rr_sb.set_conf_bits_msb(cur_num_sram + num_conf_bits);
|
||||
|
||||
/* Create file handler */
|
||||
fp = verilog_create_one_subckt_file(subckt_dir, "Unique Switch Block ",
|
||||
sb_verilog_file_name_prefix, rr_sb.get_x(), rr_sb.get_y(), &fname);
|
||||
|
||||
/* Print preprocessing flags */
|
||||
verilog_include_defines_preproc_file(fp, verilog_dir);
|
||||
|
||||
/* Comment lines */
|
||||
fprintf(fp, "//----- Verilog Module of Unique Switch Box[%lu][%lu] -----\n", rr_sb.get_x(), rr_sb.get_y());
|
||||
/* Print the definition of subckt*/
|
||||
fprintf(fp, "module %s ( \n", rr_sb.gen_verilog_module_name());
|
||||
/* dump global ports */
|
||||
if (0 < dump_verilog_global_ports(fp, global_ports_head, TRUE)) {
|
||||
fprintf(fp, ",\n");
|
||||
}
|
||||
|
||||
for (size_t side = 0; side < rr_sb.get_num_sides(); ++side) {
|
||||
Side side_manager(side);
|
||||
/* Print ports */
|
||||
fprintf(fp, "//----- Inputs/outputs of %s side -----\n", side_manager.to_string());
|
||||
DeviceCoordinator port_coordinator = rr_sb.get_side_block_coordinator(side_manager.get_side());
|
||||
|
||||
for (size_t itrack = 0; itrack < rr_sb.get_chan_width(side_manager.get_side()); ++itrack) {
|
||||
switch (rr_sb.get_chan_node_direction(side_manager.get_side(), itrack)) {
|
||||
case OUT_PORT:
|
||||
fprintf(fp, " output %s,\n",
|
||||
gen_verilog_routing_channel_one_pin_name(rr_sb.get_chan_node(side_manager.get_side(), itrack),
|
||||
port_coordinator.get_x(), port_coordinator.get_y(), itrack,
|
||||
rr_sb.get_chan_node_direction(side_manager.get_side(), itrack)));
|
||||
break;
|
||||
case IN_PORT:
|
||||
fprintf(fp, " input %s,\n",
|
||||
gen_verilog_routing_channel_one_pin_name(rr_sb.get_chan_node(side_manager.get_side(), itrack),
|
||||
port_coordinator.get_x(), port_coordinator.get_y(), itrack,
|
||||
rr_sb.get_chan_node_direction(side_manager.get_side(), itrack)));
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(File: %s [LINE%d]) Invalid direction of chan[%d][%d]_track[%d]!\n",
|
||||
__FILE__, __LINE__, rr_sb.get_x(), rr_sb.get_y(), itrack);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
/* Dump OPINs of adjacent CLBs */
|
||||
for (size_t inode = 0; inode < rr_sb.get_num_opin_nodes(side_manager.get_side()); ++inode) {
|
||||
fprintf(fp, " ");
|
||||
dump_verilog_grid_side_pin_with_given_index(fp, OPIN, /* This is an input of a SB */
|
||||
rr_sb.get_opin_node(side_manager.get_side(), inode)->ptc_num,
|
||||
rr_sb.get_opin_node_grid_side(side_manager.get_side(), inode),
|
||||
rr_sb.get_opin_node(side_manager.get_side(), inode)->xlow,
|
||||
rr_sb.get_opin_node(side_manager.get_side(), inode)->ylow,
|
||||
TRUE); /* Dump the direction of the port ! */
|
||||
}
|
||||
}
|
||||
|
||||
/* Put down configuration port */
|
||||
/* output of each configuration bit */
|
||||
/* Reserved sram ports */
|
||||
dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info,
|
||||
rr_sb.get_reserved_conf_bits_lsb(),
|
||||
rr_sb.get_reserved_conf_bits_msb(),
|
||||
VERILOG_PORT_INPUT);
|
||||
if (0 < rr_sb.get_num_reserved_conf_bits()) {
|
||||
fprintf(fp, ",\n");
|
||||
}
|
||||
/* Normal sram ports */
|
||||
dump_verilog_sram_ports(fp, cur_sram_orgz_info,
|
||||
rr_sb.get_conf_bits_lsb(),
|
||||
rr_sb.get_conf_bits_msb(),
|
||||
VERILOG_PORT_INPUT);
|
||||
|
||||
/* Dump ports only visible during formal verification*/
|
||||
if (0 < rr_sb.get_num_conf_bits()) {
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, "`ifdef %s\n", verilog_formal_verification_preproc_flag);
|
||||
fprintf(fp, ",\n");
|
||||
dump_verilog_formal_verification_sram_ports(fp, cur_sram_orgz_info,
|
||||
rr_sb.get_conf_bits_lsb(),
|
||||
rr_sb.get_conf_bits_msb(),
|
||||
VERILOG_PORT_OUTPUT);
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, "`endif\n");
|
||||
}
|
||||
fprintf(fp, "); \n");
|
||||
|
||||
/* Local wires for memory configurations */
|
||||
dump_verilog_sram_config_bus_internal_wires(fp, cur_sram_orgz_info,
|
||||
rr_sb.get_conf_bits_lsb(),
|
||||
rr_sb.get_conf_bits_msb() - 1);
|
||||
|
||||
/* Put down all the multiplexers */
|
||||
for (size_t side = 0; side < rr_sb.get_num_sides(); ++side) {
|
||||
Side side_manager(side);
|
||||
fprintf(fp, "//----- %s side Multiplexers -----\n",
|
||||
side_manager.to_string());
|
||||
for (size_t itrack = 0; itrack < rr_sb.get_chan_width(side_manager.get_side()); ++itrack) {
|
||||
assert((CHANX == rr_sb.get_chan_node(side_manager.get_side(), itrack)->type)
|
||||
||(CHANY == rr_sb.get_chan_node(side_manager.get_side(), itrack)->type));
|
||||
/* We care INC_DIRECTION tracks at this side*/
|
||||
if (OUT_PORT == rr_sb.get_chan_node_direction(side_manager.get_side(), itrack)) {
|
||||
dump_verilog_unique_switch_box_interc(cur_sram_orgz_info, fp, rr_sb,
|
||||
side_manager.get_side(),
|
||||
rr_sb.get_chan_node(side_manager.get_side(), itrack));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fp, "endmodule\n");
|
||||
|
||||
/* Comment lines */
|
||||
fprintf(fp, "//----- END Verilog Module of Switch Box[%lu][%lu] -----\n\n", rr_sb.get_x(), rr_sb.get_y());
|
||||
|
||||
/* Check */
|
||||
assert(esti_sram_cnt == get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info));
|
||||
|
||||
/* Close file handler */
|
||||
fclose(fp);
|
||||
|
||||
/* Add fname to the linked list */
|
||||
routing_verilog_subckt_file_path_head = add_one_subckt_file_name_to_llist(routing_verilog_subckt_file_path_head, fname);
|
||||
|
||||
/* Free chan_rr_nodes */
|
||||
my_free(fname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Task: Print the subckt of a Switch Box.
|
||||
* A Switch Box subckt consists of following ports:
|
||||
* 1. Channel Y [x][y] inputs
|
||||
|
@ -2172,14 +2901,24 @@ void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
}
|
||||
|
||||
/* Switch Boxes*/
|
||||
for (ix = 0; ix < (nx + 1); ix++) {
|
||||
for (iy = 0; iy < (ny + 1); iy++) {
|
||||
/* vpr_printf(TIO_MESSAGE_INFO, "Writing Switch Boxes[%d][%d]...\n", ix, iy); */
|
||||
update_spice_models_routing_index_low(ix, iy, SOURCE, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
dump_verilog_routing_switch_box_subckt(cur_sram_orgz_info, verilog_dir, subckt_dir, &(sb_info[ix][iy]),
|
||||
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
|
||||
fpga_verilog_opts, compact_routing_hierarchy);
|
||||
update_spice_models_routing_index_high(ix, iy, SOURCE, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
if (TRUE == compact_routing_hierarchy) {
|
||||
for (size_t isb = 0; isb < device_rr_switch_block.get_num_unique_mirror(); ++isb) {
|
||||
/* Output unique mirrors */
|
||||
RRSwitchBlock unique_mirror = device_rr_switch_block.get_unique_mirror(isb);
|
||||
dump_verilog_routing_switch_box_unique_subckt(cur_sram_orgz_info, verilog_dir, subckt_dir, unique_mirror,
|
||||
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
|
||||
fpga_verilog_opts);
|
||||
}
|
||||
} else {
|
||||
for (ix = 0; ix < (nx + 1); ix++) {
|
||||
for (iy = 0; iy < (ny + 1); iy++) {
|
||||
/* vpr_printf(TIO_MESSAGE_INFO, "Writing Switch Boxes[%d][%d]...\n", ix, iy); */
|
||||
update_spice_models_routing_index_low(ix, iy, SOURCE, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
dump_verilog_routing_switch_box_subckt(cur_sram_orgz_info, verilog_dir, subckt_dir, &(sb_info[ix][iy]),
|
||||
LL_num_rr_nodes, LL_rr_node, LL_rr_node_indices,
|
||||
fpga_verilog_opts, compact_routing_hierarchy);
|
||||
update_spice_models_routing_index_high(ix, iy, SOURCE, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -368,11 +368,22 @@ FILE* verilog_create_one_subckt_file(char* subckt_dir,
|
|||
}
|
||||
|
||||
/* Generate the descriptions*/
|
||||
file_description = (char*) my_malloc(sizeof(char) * (strlen(subckt_name_prefix) + 2
|
||||
+ strlen(my_itoa(grid_x)) + 2 + strlen(my_itoa(grid_y))
|
||||
+ 10));
|
||||
sprintf(file_description, "%s [%d][%d] in FPGA",
|
||||
subckt_name_prefix, grid_x, grid_y);
|
||||
if (-1 == grid_y) {
|
||||
file_description = (char*) my_malloc(sizeof(char) * (strlen(subckt_name_prefix) + 2
|
||||
+ strlen(my_itoa(grid_x)) + 2
|
||||
+ 10));
|
||||
sprintf(file_description,
|
||||
"%s [%d] in FPGA",
|
||||
subckt_name_prefix, grid_x);
|
||||
} else {
|
||||
file_description = (char*) my_malloc(sizeof(char) * (strlen(subckt_name_prefix) + 2
|
||||
+ strlen(my_itoa(grid_x)) + 2 + strlen(my_itoa(grid_y))
|
||||
+ 10));
|
||||
sprintf(file_description,
|
||||
"%s [%d][%d] in FPGA",
|
||||
subckt_name_prefix, grid_x, grid_y);
|
||||
}
|
||||
|
||||
dump_verilog_file_header(fp, file_description);
|
||||
|
||||
/* Free */
|
||||
|
|
|
@ -247,8 +247,9 @@ char* gen_verilog_one_cb_instance_name(t_cb* cur_cb_info);
|
|||
|
||||
char* gen_verilog_one_sb_module_name(t_sb* cur_sb_info);
|
||||
|
||||
char* gen_verilog_one_sb_instance_name(t_sb* cur_sb_info);
|
||||
char* gen_verilog_one_sb_module_name(size_t rr_sb_id);
|
||||
|
||||
char* gen_verilog_one_sb_instance_name(t_sb* cur_sb_info);
|
||||
|
||||
char* gen_verilog_one_routing_channel_module_name(t_rr_type chan_type,
|
||||
int x, int y);
|
||||
|
|
Loading…
Reference in New Issue