update Verilog generator to use GSB data structure. SDC generator and TCL generator to go
This commit is contained in:
parent
61e359efc5
commit
17bc7fc296
|
@ -734,6 +734,12 @@ enum e_side RRGSB::get_opin_node_grid_side(t_rr_node* opin_node) const {
|
|||
return get_opin_node_grid_side(side, index);
|
||||
}
|
||||
|
||||
/* Get the node index of a routing track of a connection block, return -1 if not found */
|
||||
int RRGSB::get_cb_chan_node_index(t_rr_type cb_type, t_rr_node* node) const {
|
||||
enum e_side chan_side = get_cb_chan_side(cb_type);
|
||||
return get_chan_node_index(chan_side, node);
|
||||
}
|
||||
|
||||
/* Get the node index in the array, return -1 if not found */
|
||||
int RRGSB::get_chan_node_index(enum e_side node_side, t_rr_node* node) const {
|
||||
assert (validate_side(node_side));
|
||||
|
@ -1331,6 +1337,27 @@ DeviceCoordinator RRGSB::get_side_block_coordinator(enum e_side side) const {
|
|||
}
|
||||
|
||||
/* Public Accessors Verilog writer */
|
||||
const char* RRGSB::gen_cb_verilog_routing_track_name(t_rr_type cb_type,
|
||||
size_t track_id) const {
|
||||
char* ret = NULL;
|
||||
|
||||
std::string cb_name(convert_chan_type_to_string(cb_type));
|
||||
std::string x_str = std::to_string(get_cb_x(cb_type));
|
||||
std::string y_str = std::to_string(get_cb_y(cb_type));
|
||||
std::string track_id_str = std::to_string(track_id);
|
||||
|
||||
ret = (char*)my_malloc(cb_name.length()
|
||||
+ 1 + x_str.length()
|
||||
+ 2 + y_str.length()
|
||||
+ 9 + track_id_str.length()
|
||||
+ 1 + 1);
|
||||
|
||||
sprintf(ret, "%s_%s__%s__midout_%s_",
|
||||
cb_name.c_str(), x_str.c_str(), y_str.c_str(), track_id_str.c_str());
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char* RRGSB::gen_sb_verilog_module_name() const {
|
||||
std::string x_str = std::to_string(get_sb_x());
|
||||
std::string y_str = std::to_string(get_sb_y());
|
||||
|
@ -2243,6 +2270,29 @@ RRGSB DeviceRRGSB::get_cb_unique_module(t_rr_type cb_type, size_t index) const {
|
|||
}
|
||||
}
|
||||
|
||||
/* Give a coordinator of a rr switch block, and return its unique mirror */
|
||||
RRGSB DeviceRRGSB::get_cb_unique_module(t_rr_type cb_type, DeviceCoordinator& coordinator) const {
|
||||
assert (validate_cb_type(cb_type));
|
||||
assert(validate_coordinator(coordinator));
|
||||
size_t cb_unique_module_id;
|
||||
|
||||
switch(cb_type) {
|
||||
case CHANX:
|
||||
cb_unique_module_id = cbx_unique_module_id_[coordinator.get_x()][coordinator.get_y()];
|
||||
break;
|
||||
case CHANY:
|
||||
cb_unique_module_id = cby_unique_module_id_[coordinator.get_x()][coordinator.get_y()];
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(File:%s, [LINE%d])Invalid type of connection block!\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return get_cb_unique_module(cb_type, cb_unique_module_id);
|
||||
}
|
||||
|
||||
/* Give a coordinator of a rr switch block, and return its unique mirror */
|
||||
RRGSB DeviceRRGSB::get_sb_unique_module(DeviceCoordinator& coordinator) const {
|
||||
assert(validate_coordinator(coordinator));
|
||||
|
@ -2295,6 +2345,28 @@ bool DeviceRRGSB::is_two_sb_share_same_submodules(DeviceCoordinator& src, Device
|
|||
|
||||
/* Public Mutators */
|
||||
|
||||
/* TODO: TOBE DEPRECATED!!! conf_bits should be initialized when creating a switch block!!! */
|
||||
void DeviceRRGSB::set_cb_num_reserved_conf_bits(DeviceCoordinator& coordinator, t_rr_type cb_type, size_t num_reserved_conf_bits) {
|
||||
assert(validate_coordinator(coordinator));
|
||||
rr_gsb_[coordinator.get_x()][coordinator.get_y()].set_cb_num_reserved_conf_bits(cb_type, num_reserved_conf_bits);
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: TOBE DEPRECATED!!! conf_bits should be initialized when creating a switch block!!! */
|
||||
void DeviceRRGSB::set_cb_conf_bits_lsb(DeviceCoordinator& coordinator, t_rr_type cb_type, size_t conf_bits_lsb) {
|
||||
assert(validate_coordinator(coordinator));
|
||||
rr_gsb_[coordinator.get_x()][coordinator.get_y()].set_cb_conf_bits_lsb(cb_type, conf_bits_lsb);
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: TOBE DEPRECATED!!! conf_bits should be initialized when creating a switch block!!! */
|
||||
void DeviceRRGSB::set_cb_conf_bits_msb(DeviceCoordinator& coordinator, t_rr_type cb_type, size_t conf_bits_msb) {
|
||||
assert(validate_coordinator(coordinator));
|
||||
rr_gsb_[coordinator.get_x()][coordinator.get_y()].set_cb_conf_bits_msb(cb_type, conf_bits_msb);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* TODO: TOBE DEPRECATED!!! conf_bits should be initialized when creating a switch block!!! */
|
||||
void DeviceRRGSB::set_sb_num_reserved_conf_bits(DeviceCoordinator& coordinator, size_t num_reserved_conf_bits) {
|
||||
assert(validate_coordinator(coordinator));
|
||||
|
@ -2417,7 +2489,7 @@ void DeviceRRGSB::build_cb_unique_module(t_rr_type cb_type) {
|
|||
if (true == is_unique_module) {
|
||||
add_cb_unique_module(cb_type, gsb_coordinator);
|
||||
/* Record the id of unique mirror */
|
||||
set_cb_unique_module_id(cb_type, gsb_coordinator, get_num_cb_unique_module(cb_type));
|
||||
set_cb_unique_module_id(cb_type, gsb_coordinator, get_num_cb_unique_module(cb_type) - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -163,6 +163,7 @@ class RRGSB {
|
|||
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_cb_chan_node_index(t_rr_type cb_type, t_rr_node* node) const;
|
||||
int get_chan_node_index(enum e_side node_side, t_rr_node* node) const;
|
||||
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 */
|
||||
|
@ -204,6 +205,7 @@ class RRGSB {
|
|||
const char* gen_sb_verilog_side_instance_name(enum e_side side, size_t seg_id) const;
|
||||
const char* gen_cb_verilog_module_name(t_rr_type cb_type) const;
|
||||
const char* gen_cb_verilog_instance_name(t_rr_type cb_type) const;
|
||||
const char* gen_cb_verilog_routing_track_name(t_rr_type cb_type, size_t track_id) const;
|
||||
public: /* Mutators */
|
||||
void set(const RRGSB& src); /* get a copy from a source */
|
||||
void set_coordinator(size_t x, size_t y);
|
||||
|
@ -293,6 +295,7 @@ class DeviceRRGSB {
|
|||
RRGSB get_sb_unique_module(size_t index) const; /* Get a rr switch block which a unique mirror */
|
||||
RRGSB get_sb_unique_module(DeviceCoordinator& coordinator) const; /* Get a rr switch block which a unique mirror */
|
||||
RRGSB get_cb_unique_module(t_rr_type cb_type, size_t index) const; /* Get a rr switch block which a unique mirror */
|
||||
RRGSB get_cb_unique_module(t_rr_type cb_type, DeviceCoordinator& coordinator) const;
|
||||
size_t get_max_num_sides() const; /* Get the maximum number of sides across the switch blocks */
|
||||
size_t get_num_segments() const; /* Get the size of segment_ids */
|
||||
size_t get_segment_id(size_t index) const; /* Get a segment id */
|
||||
|
@ -301,6 +304,9 @@ class DeviceRRGSB {
|
|||
void set_sb_num_reserved_conf_bits(DeviceCoordinator& coordinator, size_t num_reserved_conf_bits); /* TODO: TOBE DEPRECATED!!! conf_bits should be initialized when creating a switch block!!! */
|
||||
void set_sb_conf_bits_lsb(DeviceCoordinator& coordinator, size_t conf_bits_lsb); /* TODO: TOBE DEPRECATED!!! conf_bits should be initialized when creating a switch block!!! */
|
||||
void set_sb_conf_bits_msb(DeviceCoordinator& coordinator, size_t conf_bits_msb); /* TODO: TOBE DEPRECATED!!! conf_bits should be initialized when creating a switch block!!! */
|
||||
void set_cb_num_reserved_conf_bits(DeviceCoordinator& coordinator, t_rr_type cb_type, size_t num_reserved_conf_bits); /* TODO: TOBE DEPRECATED!!! conf_bits should be initialized when creating a switch block!!! */
|
||||
void set_cb_conf_bits_lsb(DeviceCoordinator& coordinator, t_rr_type cb_type, size_t conf_bits_lsb); /* TODO: TOBE DEPRECATED!!! conf_bits should be initialized when creating a switch block!!! */
|
||||
void set_cb_conf_bits_msb(DeviceCoordinator& coordinator, t_rr_type cb_type, size_t conf_bits_msb); /* TODO: TOBE DEPRECATED!!! conf_bits should be initialized when creating a switch block!!! */
|
||||
void reserve(DeviceCoordinator& coordinator); /* Pre-allocate the rr_switch_block array that the device requires */
|
||||
void reserve_sb_unique_submodule_id(DeviceCoordinator& coordinator); /* Pre-allocate the rr_sb_unique_module_id matrix that the device requires */
|
||||
void resize_upon_need(DeviceCoordinator& coordinator); /* Resize the rr_switch_block array if needed */
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
#include "fpga_x2p_mux_utils.h"
|
||||
#include "fpga_x2p_bitstream_utils.h"
|
||||
|
||||
#include "fpga_bitstream_routing.h"
|
||||
|
||||
/* Include Verilog support headers*/
|
||||
|
||||
/* Generate bitstream for a multiplexer of a switch block */
|
||||
|
@ -445,6 +447,87 @@ void fpga_spice_generate_bitstream_routing_switch_box_subckt(FILE* fp,
|
|||
return;
|
||||
}
|
||||
|
||||
/* SRC rr_node is the IPIN of a grid.*/
|
||||
static
|
||||
void fpga_spice_generate_bitstream_connection_box_mux(FILE* fp,
|
||||
RRGSB& rr_gsb, t_rr_type cb_type,
|
||||
t_sram_orgz_info* cur_sram_orgz_info,
|
||||
t_rr_node* src_rr_node) {
|
||||
int mux_size = 0;
|
||||
t_rr_node** drive_rr_nodes = NULL;
|
||||
int inode, mux_level, path_id, switch_index;
|
||||
t_spice_model* verilog_model = NULL;
|
||||
int num_mux_sram_bits = 0;
|
||||
int* mux_sram_bits = NULL;
|
||||
int ilevel;
|
||||
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Find drive_rr_nodes*/
|
||||
mux_size = src_rr_node->num_drive_rr_nodes;
|
||||
drive_rr_nodes = src_rr_node->drive_rr_nodes;
|
||||
|
||||
/* Configuration bits for MUX*/
|
||||
path_id = DEFAULT_PATH_ID;
|
||||
for (inode = 0; inode < mux_size; inode++) {
|
||||
if (drive_rr_nodes[inode] == &(rr_node[src_rr_node->prev_node])) {
|
||||
path_id = inode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert((DEFAULT_PATH_ID == path_id) ||
|
||||
((DEFAULT_PATH_ID < path_id) &&(path_id < mux_size)));
|
||||
|
||||
switch_index = src_rr_node->drive_switches[DEFAULT_SWITCH_ID];
|
||||
|
||||
verilog_model = switch_inf[switch_index].spice_model;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* Print the encoding in SPICE netlist for debugging */
|
||||
fprintf(fp, "***** Connection Block %s *****\n",
|
||||
rr_gsb.gen_cb_verilog_instance_name(cb_type));
|
||||
|
||||
fprintf(fp, "***** SRAM bits for MUX[%d], level=%d, select_path_id=%d. *****\n",
|
||||
verilog_model->cnt, mux_level, path_id);
|
||||
fprintf(fp, "*****");
|
||||
for (ilevel = 0; ilevel < num_mux_sram_bits; ilevel++) {
|
||||
fprintf(fp, "%d", mux_sram_bits[ilevel]);
|
||||
}
|
||||
fprintf(fp, "*****\n\n");
|
||||
|
||||
/* Store the configuraion bit to linked-list */
|
||||
add_mux_conf_bits_to_llist(mux_size, cur_sram_orgz_info,
|
||||
num_mux_sram_bits, mux_sram_bits,
|
||||
verilog_model);
|
||||
/* Synchronize the sram_orgz_info with mem_bits */
|
||||
add_mux_conf_bits_to_sram_orgz_info(cur_sram_orgz_info, verilog_model, mux_size);
|
||||
|
||||
/* update sram counter */
|
||||
verilog_model->cnt++;
|
||||
|
||||
/* Free */
|
||||
my_free(mux_sram_bits);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* SRC rr_node is the IPIN of a grid.*/
|
||||
static
|
||||
void fpga_spice_generate_bitstream_connection_box_mux(FILE* fp,
|
||||
|
@ -567,6 +650,85 @@ void fpga_spice_generate_bitstream_connection_box_interc(FILE* fp,
|
|||
return;
|
||||
}
|
||||
|
||||
static
|
||||
void fpga_spice_generate_bitstream_connection_box_interc(FILE* fp,
|
||||
RRGSB& rr_gsb, t_rr_type cb_type,
|
||||
t_sram_orgz_info* cur_sram_orgz_info,
|
||||
t_rr_node* src_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);
|
||||
}
|
||||
|
||||
if (1 == src_rr_node->fan_in) {
|
||||
/* No bitstream generation required by a special direct connection*/
|
||||
} else if (1 < src_rr_node->fan_in) {
|
||||
/* Print the multiplexer, fan_in >= 2 */
|
||||
fpga_spice_generate_bitstream_connection_box_mux(fp, rr_gsb, cb_type, cur_sram_orgz_info,
|
||||
src_rr_node);
|
||||
} /*Nothing should be done else*/
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Print connection boxes
|
||||
* Print the sub-circuit of a connection Box (Type: [CHANX|CHANY])
|
||||
* Actually it is very similiar to switch box but
|
||||
* the difference is connection boxes connect Grid INPUT Pins to channels
|
||||
* TODO: merge direct connections into CB
|
||||
* -------------- --------------
|
||||
* | | | |
|
||||
* | Grid | ChanY | Grid |
|
||||
* | [x][y+1] | [x][y] | [x+1][y+1] |
|
||||
* | | Connection | |
|
||||
* -------------- Box_Y[x][y] --------------
|
||||
* ----------
|
||||
* ChanX | Switch | ChanX
|
||||
* [x][y] | Box | [x+1][y]
|
||||
* Connection | [x][y] | Connection
|
||||
* Box_X[x][y] ---------- Box_X[x+1][y]
|
||||
* -------------- --------------
|
||||
* | | | |
|
||||
* | Grid | ChanY | Grid |
|
||||
* | [x][y] | [x][y-1] | [x+1][y] |
|
||||
* | | Connection | |
|
||||
* --------------Box_Y[x][y-1]--------------
|
||||
*/
|
||||
static
|
||||
void fpga_spice_generate_bitstream_routing_connection_box_subckt(FILE* fp,
|
||||
RRGSB& rr_gsb, t_rr_type cb_type,
|
||||
t_sram_orgz_info* cur_sram_orgz_info) {
|
||||
|
||||
/* Check the file handler*/
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid file handler.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Print multiplexers or direct interconnect*/
|
||||
std::vector<enum e_side> cb_sides = rr_gsb.get_cb_ipin_sides(cb_type);
|
||||
|
||||
for (size_t side = 0; side < cb_sides.size(); ++side) {
|
||||
enum e_side cb_ipin_side = cb_sides[side];
|
||||
Side side_manager(cb_ipin_side);
|
||||
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(cb_ipin_side); ++inode) {
|
||||
fpga_spice_generate_bitstream_connection_box_interc(fp, rr_gsb, cb_type, cur_sram_orgz_info,
|
||||
rr_gsb.get_ipin_node(cb_ipin_side, inode));
|
||||
}
|
||||
}
|
||||
|
||||
/* Check */
|
||||
|
||||
/* Free */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Print connection boxes
|
||||
* Print the sub-circuit of a connection Box (Type: [CHANX|CHANY])
|
||||
|
@ -696,32 +858,61 @@ void fpga_spice_generate_bitstream_routing_resources(char* routing_bitstream_log
|
|||
}
|
||||
|
||||
/* Connection Boxes */
|
||||
vpr_printf(TIO_MESSAGE_INFO,"Generating bitstream for Connection blocks - X direction ...\n");
|
||||
/* X - channels [1...nx][0..ny]*/
|
||||
for (int iy = 0; iy < (ny + 1); ++iy) {
|
||||
for (int ix = 1; ix < (nx + 1); ++ix) {
|
||||
/* vpr_printf(TIO_MESSAGE_INFO, "Writing X-direction Connection Boxes[%d][%d]...\n", ix, iy); */
|
||||
update_spice_models_routing_index_low(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
if ((TRUE == is_cb_exist(CHANX, ix, iy))
|
||||
&&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) {
|
||||
fpga_spice_generate_bitstream_routing_connection_box_subckt(fp,
|
||||
&(cbx_info[ix][iy]), cur_sram_orgz_info);
|
||||
if (TRUE == compact_routing_hierarchy) {
|
||||
vpr_printf(TIO_MESSAGE_INFO,"Generating bitstream for Connection blocks - X direction ...\n");
|
||||
/* X - channels [1...nx][0..ny]*/
|
||||
for (int iy = 0; iy < (ny + 1); ++iy) {
|
||||
for (int ix = 1; ix < (nx + 1); ++ix) {
|
||||
RRGSB rr_gsb = device_rr_gsb.get_gsb(ix, iy);
|
||||
if ((TRUE == is_cb_exist(CHANX, ix, iy))
|
||||
&&(true == rr_gsb.is_cb_exist(CHANX))) {
|
||||
fpga_spice_generate_bitstream_routing_connection_box_subckt(fp,
|
||||
rr_gsb, CHANX,
|
||||
cur_sram_orgz_info);
|
||||
}
|
||||
}
|
||||
update_spice_models_routing_index_high(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
}
|
||||
}
|
||||
/* Y - channels [1...ny][0..nx]*/
|
||||
vpr_printf(TIO_MESSAGE_INFO,"Generating bitstream for Connection blocks - Y direction ...\n");
|
||||
for (int ix = 0; ix < (nx + 1); ++ix) {
|
||||
for (int iy = 1; iy < (ny + 1); ++iy) {
|
||||
/* vpr_printf(TIO_MESSAGE_INFO, "Writing Y-direction Connection Boxes[%d][%d]...\n", ix, iy); */
|
||||
update_spice_models_routing_index_low(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
if ((TRUE == is_cb_exist(CHANY, ix, iy))
|
||||
&&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) {
|
||||
fpga_spice_generate_bitstream_routing_connection_box_subckt(fp,
|
||||
&(cby_info[ix][iy]), cur_sram_orgz_info);
|
||||
/* Y - channels [1...ny][0..nx]*/
|
||||
vpr_printf(TIO_MESSAGE_INFO,"Generating bitstream for Connection blocks - Y direction ...\n");
|
||||
for (int ix = 0; ix < (nx + 1); ++ix) {
|
||||
for (int iy = 1; iy < (ny + 1); ++iy) {
|
||||
RRGSB rr_gsb = device_rr_gsb.get_gsb(ix, iy);
|
||||
if ((TRUE == is_cb_exist(CHANY, ix, iy))
|
||||
&&(true == rr_gsb.is_cb_exist(CHANY))) {
|
||||
fpga_spice_generate_bitstream_routing_connection_box_subckt(fp,
|
||||
rr_gsb, CHANY,
|
||||
cur_sram_orgz_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
vpr_printf(TIO_MESSAGE_INFO,"Generating bitstream for Connection blocks - X direction ...\n");
|
||||
/* X - channels [1...nx][0..ny]*/
|
||||
for (int iy = 0; iy < (ny + 1); ++iy) {
|
||||
for (int ix = 1; ix < (nx + 1); ++ix) {
|
||||
/* vpr_printf(TIO_MESSAGE_INFO, "Writing X-direction Connection Boxes[%d][%d]...\n", ix, iy); */
|
||||
update_spice_models_routing_index_low(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
if ((TRUE == is_cb_exist(CHANX, ix, iy))
|
||||
&&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) {
|
||||
fpga_spice_generate_bitstream_routing_connection_box_subckt(fp,
|
||||
&(cbx_info[ix][iy]), cur_sram_orgz_info);
|
||||
}
|
||||
update_spice_models_routing_index_high(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
}
|
||||
}
|
||||
/* Y - channels [1...ny][0..nx]*/
|
||||
vpr_printf(TIO_MESSAGE_INFO,"Generating bitstream for Connection blocks - Y direction ...\n");
|
||||
for (int ix = 0; ix < (nx + 1); ++ix) {
|
||||
for (int iy = 1; iy < (ny + 1); ++iy) {
|
||||
/* vpr_printf(TIO_MESSAGE_INFO, "Writing Y-direction Connection Boxes[%d][%d]...\n", ix, iy); */
|
||||
update_spice_models_routing_index_low(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
if ((TRUE == is_cb_exist(CHANY, ix, iy))
|
||||
&&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) {
|
||||
fpga_spice_generate_bitstream_routing_connection_box_subckt(fp,
|
||||
&(cby_info[ix][iy]), cur_sram_orgz_info);
|
||||
}
|
||||
update_spice_models_routing_index_high(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
}
|
||||
update_spice_models_routing_index_high(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -877,39 +877,24 @@ void dump_compact_verilog_defined_switch_boxes(t_sram_orgz_info* cur_sram_orgz_i
|
|||
static
|
||||
void dump_compact_verilog_defined_one_connection_box(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
FILE* fp,
|
||||
t_cb cur_cb_info) {
|
||||
int itrack, inode, side, x, y;
|
||||
int side_cnt = 0;
|
||||
|
||||
RRGSB& rr_gsb, t_rr_type cb_type) {
|
||||
/* 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 > cur_cb_info.x))&&(!(cur_cb_info.x > (nx + 1))));
|
||||
assert((!(0 > cur_cb_info.y))&&(!(cur_cb_info.y > (ny + 1))));
|
||||
|
||||
x = cur_cb_info.x;
|
||||
y = cur_cb_info.y;
|
||||
|
||||
/* Comment lines */
|
||||
/* Comment lines */
|
||||
fprintf(fp,
|
||||
"//----- BEGIN Call Connection Box for %s direction [%d][%d] module -----\n",
|
||||
convert_chan_type_to_string(cur_cb_info.type),
|
||||
x, y);
|
||||
"//----- BEGIN Call Connection Box module %s -----\n",
|
||||
rr_gsb.gen_cb_verilog_module_name(cb_type));
|
||||
|
||||
/* Print module */
|
||||
/* If we have an mirror SB, we should the module name of the mirror !!! */
|
||||
if (NULL != cur_cb_info.mirror) {
|
||||
fprintf(fp, "%s ", gen_verilog_one_cb_module_name(cur_cb_info.mirror));
|
||||
} else {
|
||||
fprintf(fp, "%s ", gen_verilog_one_cb_module_name(&cur_cb_info));
|
||||
}
|
||||
|
||||
fprintf(fp, "%s ", gen_verilog_one_cb_instance_name(&cur_cb_info));
|
||||
|
||||
DeviceCoordinator coordinator = rr_gsb.get_sb_coordinator();
|
||||
RRGSB unique_mirror = device_rr_gsb.get_cb_unique_module(cb_type, coordinator);
|
||||
fprintf(fp, "%s ", unique_mirror.gen_cb_verilog_module_name(cb_type));
|
||||
fprintf(fp, "%s ", rr_gsb.gen_cb_verilog_instance_name(cb_type));
|
||||
fprintf(fp, "(");
|
||||
fprintf(fp, "\n");
|
||||
/* dump global ports */
|
||||
|
@ -919,71 +904,57 @@ void dump_compact_verilog_defined_one_connection_box(t_sram_orgz_info* cur_sram_
|
|||
|
||||
/* Print the ports of channels*/
|
||||
/* connect to the mid point of a track*/
|
||||
side_cnt = 0;
|
||||
for (side = 0; side < cur_cb_info.num_sides; side++) {
|
||||
/* Bypass side with zero channel width */
|
||||
if (0 == cur_cb_info.chan_width[side]) {
|
||||
continue;
|
||||
}
|
||||
assert (0 < cur_cb_info.chan_width[side]);
|
||||
side_cnt++;
|
||||
fprintf(fp, "//----- %s side inputs: channel track middle outputs -----\n", convert_side_index_to_string(side));
|
||||
for (itrack = 0; itrack < cur_cb_info.chan_width[side]; itrack++) {
|
||||
fprintf(fp, "%s, ",
|
||||
gen_verilog_routing_channel_one_midout_name(&cur_cb_info, itrack));
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
fprintf(fp, "//----- %s side inputs: channel track middle outputs -----\n",
|
||||
convert_side_index_to_string(rr_gsb.get_cb_chan_side(cb_type)));
|
||||
for (size_t itrack = 0; itrack < rr_gsb.get_cb_chan_width(cb_type); ++itrack) {
|
||||
fprintf(fp, "%s, ",
|
||||
rr_gsb.gen_cb_verilog_routing_track_name(cb_type, itrack));
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
/*check side_cnt */
|
||||
assert(1 == side_cnt);
|
||||
|
||||
side_cnt = 0;
|
||||
/* Print the ports of grids*/
|
||||
for (side = 0; side < cur_cb_info.num_sides; side++) {
|
||||
/* Bypass side with zero IPINs*/
|
||||
if (0 == cur_cb_info.num_ipin_rr_nodes[side]) {
|
||||
continue;
|
||||
}
|
||||
side_cnt++;
|
||||
assert(0 < cur_cb_info.num_ipin_rr_nodes[side]);
|
||||
assert(NULL != cur_cb_info.ipin_rr_node[side]);
|
||||
fprintf(fp, "//----- %s side outputs: CLB input pins -----\n", convert_side_index_to_string(side));
|
||||
for (inode = 0; inode < cur_cb_info.num_ipin_rr_nodes[side]; inode++) {
|
||||
|
||||
std::vector<enum e_side> cb_sides = rr_gsb.get_cb_ipin_sides(cb_type);
|
||||
|
||||
for (size_t side = 0; side < cb_sides.size(); ++side) {
|
||||
enum e_side cb_ipin_side = cb_sides[side];
|
||||
Side side_manager(cb_ipin_side);
|
||||
fprintf(fp, "//----- %s side outputs: CLB input pins -----\n",
|
||||
side_manager.c_str());
|
||||
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(cb_ipin_side); ++inode) {
|
||||
/* Print each INPUT Pins of a grid */
|
||||
dump_verilog_grid_side_pin_with_given_index(fp, OPIN,
|
||||
cur_cb_info.ipin_rr_node[side][inode]->ptc_num,
|
||||
cur_cb_info.ipin_rr_node_grid_side[side][inode],
|
||||
cur_cb_info.ipin_rr_node[side][inode]->xlow,
|
||||
cur_cb_info.ipin_rr_node[side][inode]->ylow,
|
||||
FALSE); /* Do not specify direction of port */
|
||||
rr_gsb.get_ipin_node(cb_ipin_side, inode)->ptc_num,
|
||||
rr_gsb.get_ipin_node_grid_side(cb_ipin_side, inode),
|
||||
rr_gsb.get_ipin_node(cb_ipin_side, inode)->xlow,
|
||||
rr_gsb.get_ipin_node(cb_ipin_side, inode)->ylow,
|
||||
FALSE); /* Do not specify direction of port */
|
||||
fprintf(fp, ", \n");
|
||||
}
|
||||
}
|
||||
/* Make sure only 2 sides of IPINs are printed */
|
||||
assert((1 == side_cnt)||(2 == side_cnt));
|
||||
|
||||
/* Configuration ports */
|
||||
/* Reserved sram ports */
|
||||
if (0 < (cur_cb_info.num_reserved_conf_bits)) {
|
||||
if (0 < (rr_gsb.get_cb_num_reserved_conf_bits(cb_type))) {
|
||||
dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info,
|
||||
0, cur_cb_info.num_reserved_conf_bits - 1,
|
||||
rr_gsb.get_cb_reserved_conf_bits_lsb(cb_type),
|
||||
rr_gsb.get_cb_reserved_conf_bits_msb(cb_type),
|
||||
VERILOG_PORT_CONKT);
|
||||
fprintf(fp, ",\n");
|
||||
}
|
||||
/* Normal sram ports */
|
||||
if (0 < (cur_cb_info.conf_bits_msb - cur_cb_info.conf_bits_lsb)) {
|
||||
if (0 < rr_gsb.get_cb_num_conf_bits(cb_type)) {
|
||||
dump_verilog_sram_local_ports(fp, cur_sram_orgz_info,
|
||||
cur_cb_info.conf_bits_lsb, cur_cb_info.conf_bits_msb - 1,
|
||||
rr_gsb.get_cb_conf_bits_lsb(cb_type),
|
||||
rr_gsb.get_cb_conf_bits_msb(cb_type),
|
||||
VERILOG_PORT_CONKT);
|
||||
}
|
||||
/* Dump ports only visible during formal verification*/
|
||||
if (0 < (cur_cb_info.conf_bits_msb - 1 - cur_cb_info.conf_bits_lsb)) {
|
||||
if (0 < rr_gsb.get_cb_num_conf_bits(cb_type)) {
|
||||
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,
|
||||
cur_cb_info.conf_bits_lsb,
|
||||
cur_cb_info.conf_bits_msb - 1,
|
||||
rr_gsb.get_cb_conf_bits_lsb(cb_type),
|
||||
rr_gsb.get_cb_conf_bits_msb(cb_type),
|
||||
VERILOG_PORT_CONKT);
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, "`endif\n");
|
||||
|
@ -991,20 +962,9 @@ void dump_compact_verilog_defined_one_connection_box(t_sram_orgz_info* cur_sram_
|
|||
fprintf(fp, ");\n");
|
||||
|
||||
/* Comment lines */
|
||||
switch(cur_cb_info.type) {
|
||||
case CHANX:
|
||||
fprintf(fp, "//----- END call Connection Box-X direction [%d][%d] module -----\n\n", x, y);
|
||||
break;
|
||||
case CHANY:
|
||||
fprintf(fp, "//----- END call Connection Box-Y direction [%d][%d] module -----\n\n", x, y);
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR, "(File:%s, [LINE%d])Invalid type of channel!\n", __FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Check */
|
||||
assert((1 == side_cnt)||(2 == side_cnt));
|
||||
fprintf(fp,
|
||||
"//----- END call Connection Box module %s -----\n\n",
|
||||
rr_gsb.gen_cb_verilog_module_name(cb_type));
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1025,18 +985,20 @@ void dump_compact_verilog_defined_connection_boxes(t_sram_orgz_info* cur_sram_or
|
|||
/* X - channels [1...nx][0..ny]*/
|
||||
for (iy = 0; iy < (ny + 1); iy++) {
|
||||
for (ix = 1; ix < (nx + 1); ix++) {
|
||||
RRGSB rr_gsb = device_rr_gsb.get_gsb(ix, iy);
|
||||
if ((TRUE == is_cb_exist(CHANX, ix, iy))
|
||||
&&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) {
|
||||
dump_compact_verilog_defined_one_connection_box(cur_sram_orgz_info, fp, cbx_info[ix][iy]);
|
||||
&&(true == rr_gsb.is_cb_exist(CHANX))) {
|
||||
dump_compact_verilog_defined_one_connection_box(cur_sram_orgz_info, fp, rr_gsb, CHANX);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Y - channels [1...ny][0..nx]*/
|
||||
for (ix = 0; ix < (nx + 1); ix++) {
|
||||
for (iy = 1; iy < (ny + 1); iy++) {
|
||||
RRGSB rr_gsb = device_rr_gsb.get_gsb(ix, iy);
|
||||
if ((TRUE == is_cb_exist(CHANY, ix, iy))
|
||||
&&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) {
|
||||
dump_compact_verilog_defined_one_connection_box(cur_sram_orgz_info, fp, cby_info[ix][iy]);
|
||||
&&(true == rr_gsb.is_cb_exist(CHANY))) {
|
||||
dump_compact_verilog_defined_one_connection_box(cur_sram_orgz_info, fp, rr_gsb, CHANY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
/* Include vpr structs*/
|
||||
|
@ -1818,6 +1819,35 @@ void update_routing_switch_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
return;
|
||||
}
|
||||
|
||||
static
|
||||
void update_routing_connection_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
RRGSB& rr_gsb, t_rr_type cb_type) {
|
||||
int cur_num_bl, cur_num_wl;
|
||||
|
||||
get_sram_orgz_info_num_blwl(cur_sram_orgz_info, &cur_num_bl, &cur_num_wl);
|
||||
|
||||
/* Record the index: TODO: clean this mess, move to FPGA_X2P_SETUP !!!*/
|
||||
DeviceCoordinator gsb_coordinator(rr_gsb.get_sb_x(), rr_gsb.get_sb_y());
|
||||
|
||||
/* Count the number of configuration bits to be consumed by this Switch block */
|
||||
int num_conf_bits = count_verilog_connection_box_conf_bits(cur_sram_orgz_info, rr_gsb, cb_type);
|
||||
/* Count the number of reserved configuration bits to be consumed by this Switch block */
|
||||
int num_reserved_conf_bits = count_verilog_connection_box_reserved_conf_bits(cur_sram_orgz_info, rr_gsb, cb_type);
|
||||
/* Estimate the sram_verilog_model->cnt */
|
||||
int cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info);
|
||||
|
||||
device_rr_gsb.set_cb_num_reserved_conf_bits(gsb_coordinator, cb_type, num_reserved_conf_bits);
|
||||
device_rr_gsb.set_cb_conf_bits_lsb(gsb_coordinator, cb_type, cur_num_sram);
|
||||
device_rr_gsb.set_cb_conf_bits_msb(gsb_coordinator, cb_type, cur_num_sram + num_conf_bits - 1);
|
||||
|
||||
/* Update the counter */
|
||||
update_sram_orgz_info_num_mem_bit(cur_sram_orgz_info, cur_num_sram + num_conf_bits);
|
||||
update_sram_orgz_info_num_blwl(cur_sram_orgz_info, cur_num_bl + num_conf_bits, cur_num_wl + num_conf_bits);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Dump port list of a subckt describing a side of a switch block
|
||||
* Only output ports will be printed on the specified side
|
||||
* Only input ports will be printed on the other sides
|
||||
|
@ -2729,6 +2759,16 @@ int count_verilog_connection_box_interc_reserved_conf_bits(t_sram_orgz_info* cur
|
|||
}
|
||||
|
||||
|
||||
int count_verilog_connection_box_one_side_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
RRGSB& rr_gsb, enum e_side cb_side) {
|
||||
int num_conf_bits = 0;
|
||||
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(cb_side); ++inode) {
|
||||
num_conf_bits += count_verilog_connection_box_interc_conf_bits(cur_sram_orgz_info, rr_gsb.get_ipin_node(cb_side, inode));
|
||||
}
|
||||
|
||||
return num_conf_bits;
|
||||
}
|
||||
|
||||
int count_verilog_connection_box_one_side_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
int num_ipin_rr_nodes,
|
||||
t_rr_node** ipin_rr_node) {
|
||||
|
@ -2742,6 +2782,19 @@ int count_verilog_connection_box_one_side_conf_bits(t_sram_orgz_info* cur_sram_o
|
|||
return num_conf_bits;
|
||||
}
|
||||
|
||||
int count_verilog_connection_box_one_side_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
RRGSB& rr_gsb, enum e_side cb_side) {
|
||||
int num_reserved_conf_bits = 0;
|
||||
|
||||
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(cb_side); ++inode) {
|
||||
int temp_num_reserved_conf_bits = count_verilog_connection_box_interc_reserved_conf_bits(cur_sram_orgz_info, rr_gsb.get_ipin_node(cb_side, inode));
|
||||
num_reserved_conf_bits = std::max(temp_num_reserved_conf_bits, num_reserved_conf_bits);
|
||||
}
|
||||
|
||||
return num_reserved_conf_bits;
|
||||
}
|
||||
|
||||
|
||||
int count_verilog_connection_box_one_side_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
int num_ipin_rr_nodes,
|
||||
t_rr_node** ipin_rr_node) {
|
||||
|
@ -2760,6 +2813,73 @@ int count_verilog_connection_box_one_side_reserved_conf_bits(t_sram_orgz_info* c
|
|||
return num_reserved_conf_bits;
|
||||
}
|
||||
|
||||
/* SRC rr_node is the IPIN of a grid.*/
|
||||
static
|
||||
void dump_verilog_connection_box_short_interc(FILE* fp,
|
||||
RRGSB& rr_gsb, t_rr_type cb_type,
|
||||
t_rr_node* src_rr_node) {
|
||||
t_rr_node* drive_rr_node = NULL;
|
||||
int iedge, check_flag;
|
||||
int xlow, ylow, height, index;
|
||||
enum e_side side;
|
||||
|
||||
/* 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(1 == src_rr_node->fan_in);
|
||||
|
||||
/* Check the driver*/
|
||||
drive_rr_node = &(rr_node[src_rr_node->prev_node]);
|
||||
assert((CHANX == drive_rr_node->type)||(CHANY == drive_rr_node->type));
|
||||
check_flag = 0;
|
||||
for (iedge = 0; iedge < drive_rr_node->num_edges; iedge++) {
|
||||
if (src_rr_node == &(rr_node[drive_rr_node->edges[iedge]])) {
|
||||
check_flag++;
|
||||
}
|
||||
}
|
||||
assert(1 == check_flag);
|
||||
|
||||
xlow = src_rr_node->xlow;
|
||||
ylow = src_rr_node->ylow;
|
||||
height = grid[xlow][ylow].offset;
|
||||
|
||||
/* Call the zero-resistance model */
|
||||
fprintf(fp, "//----- short connection %s[%lu][%lu]_grid[%d][%d]_pin[%d] -----\n",
|
||||
convert_cb_type_to_string(cb_type),
|
||||
rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type),
|
||||
xlow, ylow + height, src_rr_node->ptc_num);
|
||||
|
||||
fprintf(fp, "assign ");
|
||||
/* output port -- > connect to the output at middle point of a channel */
|
||||
int drive_node_index = rr_gsb.get_cb_chan_node_index(cb_type, drive_rr_node);
|
||||
assert (-1 != drive_node_index);
|
||||
fprintf(fp, "%s ", rr_gsb.gen_cb_verilog_routing_track_name(cb_type, drive_node_index));
|
||||
fprintf(fp, "= ");
|
||||
|
||||
/* Input port*/
|
||||
assert(IPIN == src_rr_node->type);
|
||||
/* Search all the sides of a SB, see this drive_rr_node is an INPUT of this SB */
|
||||
rr_gsb.get_node_side_and_index(src_rr_node, OUT_PORT, &side, &index);
|
||||
/* We need to be sure that drive_rr_node is part of the SB */
|
||||
assert((-1 != index)&&(NUM_SIDES != side));
|
||||
dump_verilog_grid_side_pin_with_given_index(fp, OPIN, /* This is an output of a Connection Box */
|
||||
rr_gsb.get_ipin_node(side, index)->ptc_num,
|
||||
rr_gsb.get_ipin_node_grid_side(side, index),
|
||||
xlow, ylow, /* Coordinator of Grid */
|
||||
FALSE); /* Do not specify the direction of this pin */
|
||||
|
||||
/* End */
|
||||
fprintf(fp, ";\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* SRC rr_node is the IPIN of a grid.*/
|
||||
void dump_verilog_connection_box_short_interc(FILE* fp,
|
||||
t_cb* cur_cb_info,
|
||||
|
@ -2835,6 +2955,234 @@ void dump_verilog_connection_box_short_interc(FILE* fp,
|
|||
return;
|
||||
}
|
||||
|
||||
static
|
||||
void dump_verilog_connection_box_mux(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
FILE* fp,
|
||||
RRGSB& rr_gsb, t_rr_type cb_type,
|
||||
t_rr_node* src_rr_node) {
|
||||
int mux_size, cur_num_sram, input_cnt = 0;
|
||||
t_rr_node** drive_rr_nodes = NULL;
|
||||
int mux_level, path_id, switch_index;
|
||||
t_spice_model* verilog_model = NULL;
|
||||
int num_mux_sram_bits = 0;
|
||||
int* mux_sram_bits = NULL;
|
||||
t_rr_type drive_rr_node_type = NUM_RR_TYPES;
|
||||
int xlow, ylow, index;
|
||||
enum e_side side;
|
||||
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);
|
||||
}
|
||||
|
||||
/* Find drive_rr_nodes*/
|
||||
mux_size = src_rr_node->num_drive_rr_nodes;
|
||||
drive_rr_nodes = src_rr_node->drive_rr_nodes;
|
||||
|
||||
/* Configuration bits for MUX*/
|
||||
path_id = DEFAULT_PATH_ID;
|
||||
for (int inode = 0; inode < mux_size; ++inode) {
|
||||
if (drive_rr_nodes[inode] == &(rr_node[src_rr_node->prev_node])) {
|
||||
path_id = inode;
|
||||
src_rr_node->id_path = inode;
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch_index = src_rr_node->drive_switches[DEFAULT_SWITCH_ID];
|
||||
|
||||
verilog_model = switch_inf[switch_index].spice_model;
|
||||
|
||||
|
||||
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);
|
||||
const char* path_hierarchy = rr_gsb.gen_cb_verilog_instance_name(cb_type);
|
||||
src_rr_node->name_mux = my_strcat(path_hierarchy, name_mux);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Check drive_rr_nodes type, should be the same*/
|
||||
for (int inode = 0; inode < mux_size; inode++) {
|
||||
if (NUM_RR_TYPES == drive_rr_node_type) {
|
||||
drive_rr_node_type = drive_rr_nodes[inode]->type;
|
||||
} else {
|
||||
assert(drive_rr_node_type == drive_rr_nodes[inode]->type);
|
||||
assert((CHANX == drive_rr_nodes[inode]->type)||(CHANY == drive_rr_nodes[inode]->type));
|
||||
}
|
||||
}
|
||||
/* input port*/
|
||||
for (int inode = 0; inode < mux_size; ++inode) {
|
||||
fprintf(fp, "assign %s_size%d_%d_inbus[%d] = ",
|
||||
verilog_model->prefix, mux_size, verilog_model->cnt, input_cnt);
|
||||
int drive_node_index = rr_gsb.get_cb_chan_node_index(cb_type, drive_rr_nodes[inode]);
|
||||
assert (-1 != drive_node_index);
|
||||
fprintf(fp, "%s;", rr_gsb.gen_cb_verilog_routing_track_name(cb_type, drive_node_index));
|
||||
input_cnt++;
|
||||
}
|
||||
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, "`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");
|
||||
|
||||
|
||||
/* Call the MUX SPICE model */
|
||||
fprintf(fp, "%s_size%d %s_size%d_%d_ (",
|
||||
verilog_model->name, 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");
|
||||
}
|
||||
|
||||
/* connect to input bus*/
|
||||
fprintf(fp, "%s_size%d_%d_inbus,",
|
||||
verilog_model->prefix, mux_size, verilog_model->cnt);
|
||||
|
||||
/* output port*/
|
||||
xlow = src_rr_node->xlow;
|
||||
ylow = src_rr_node->ylow;
|
||||
|
||||
assert(IPIN == src_rr_node->type);
|
||||
/* Search all the sides of a CB, see this drive_rr_node is an INPUT of this SB */
|
||||
rr_gsb.get_node_side_and_index(src_rr_node, OUT_PORT, &side, &index);
|
||||
/* We need to be sure that drive_rr_node is part of the CB */
|
||||
assert((-1 != index)&&(NUM_SIDES != side));
|
||||
dump_verilog_grid_side_pin_with_given_index(fp, OPIN, /* This is an output of a connection box */
|
||||
rr_gsb.get_ipin_node(side, index)->ptc_num,
|
||||
rr_gsb.get_ipin_node_grid_side(side, index),
|
||||
xlow, ylow, /* Coordinator of Grid */
|
||||
FALSE); /* Do not specify the direction of port */
|
||||
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");
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void dump_verilog_connection_box_mux(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
FILE* fp,
|
||||
t_cb* cur_cb_info,
|
||||
|
@ -3063,6 +3411,30 @@ void dump_verilog_connection_box_mux(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
return;
|
||||
}
|
||||
|
||||
static
|
||||
void dump_verilog_connection_box_interc(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
FILE* fp,
|
||||
RRGSB& rr_gsb, t_rr_type cb_type,
|
||||
t_rr_node* src_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);
|
||||
}
|
||||
|
||||
if (1 == src_rr_node->fan_in) {
|
||||
/* Print a direct connection*/
|
||||
dump_verilog_connection_box_short_interc(fp, rr_gsb, cb_type, src_rr_node);
|
||||
} else if (1 < src_rr_node->fan_in) {
|
||||
/* Print the multiplexer, fan_in >= 2 */
|
||||
dump_verilog_connection_box_mux(cur_sram_orgz_info, fp, rr_gsb, cb_type, src_rr_node);
|
||||
} /*Nothing should be done else*/
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void dump_verilog_connection_box_interc(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
FILE* fp,
|
||||
t_cb* cur_cb_info,
|
||||
|
@ -3089,6 +3461,24 @@ void dump_verilog_connection_box_interc(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Count the number of configuration bits of a connection box */
|
||||
int count_verilog_connection_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
RRGSB& rr_gsb, t_rr_type cb_type) {
|
||||
int num_conf_bits = 0;
|
||||
|
||||
std::vector<enum e_side> cb_sides = rr_gsb.get_cb_ipin_sides(cb_type);
|
||||
|
||||
for (size_t side = 0; side < cb_sides.size(); ++side) {
|
||||
enum e_side cb_ipin_side = cb_sides[side];
|
||||
/* Count the number of configuration bits */
|
||||
num_conf_bits += count_verilog_connection_box_one_side_conf_bits(cur_sram_orgz_info,
|
||||
rr_gsb, cb_ipin_side);
|
||||
}
|
||||
|
||||
return num_conf_bits;
|
||||
}
|
||||
|
||||
|
||||
/* Count the number of configuration bits of a connection box */
|
||||
int count_verilog_connection_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
t_cb* cur_cb_info) {
|
||||
|
@ -3115,6 +3505,24 @@ int count_verilog_connection_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
return num_conf_bits;
|
||||
}
|
||||
|
||||
/* Count the number of reserved configuration bits of a connection box */
|
||||
int count_verilog_connection_box_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
RRGSB& rr_gsb, t_rr_type cb_type) {
|
||||
int num_reserved_conf_bits = 0;
|
||||
std::vector<enum e_side> cb_sides = rr_gsb.get_cb_ipin_sides(cb_type);
|
||||
|
||||
for (size_t side = 0; side < cb_sides.size(); ++side) {
|
||||
enum e_side cb_ipin_side = cb_sides[side];
|
||||
/* Count the number of reserved configuration bits */
|
||||
int temp_num_reserved_conf_bits = count_verilog_connection_box_one_side_reserved_conf_bits(cur_sram_orgz_info, rr_gsb, cb_ipin_side);
|
||||
/* Only consider the largest reserved configuration bits */
|
||||
num_reserved_conf_bits = std::max(num_reserved_conf_bits, temp_num_reserved_conf_bits);
|
||||
}
|
||||
|
||||
return num_reserved_conf_bits;
|
||||
}
|
||||
|
||||
|
||||
/* Count the number of reserved configuration bits of a connection box */
|
||||
int count_verilog_connection_box_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
t_cb* cur_cb_info) {
|
||||
|
@ -3146,6 +3554,167 @@ int count_verilog_connection_box_reserved_conf_bits(t_sram_orgz_info* cur_sram_o
|
|||
return num_reserved_conf_bits;
|
||||
}
|
||||
|
||||
/* Print connection boxes
|
||||
* Print the sub-circuit of a connection Box (Type: [CHANX|CHANY])
|
||||
* Actually it is very similiar to switch box but
|
||||
* the difference is connection boxes connect Grid INPUT Pins to channels
|
||||
* TODO: merge direct connections into CB
|
||||
* -------------- --------------
|
||||
* | | | |
|
||||
* | Grid | ChanY | Grid |
|
||||
* | [x][y+1] | [x][y] | [x+1][y+1] |
|
||||
* | | Connection | |
|
||||
* -------------- Box_Y[x][y] --------------
|
||||
* ----------
|
||||
* ChanX | Switch | ChanX
|
||||
* [x][y] | Box | [x+1][y]
|
||||
* Connection | [x][y] | Connection
|
||||
* Box_X[x][y] ---------- Box_X[x+1][y]
|
||||
* -------------- --------------
|
||||
* | | | |
|
||||
* | Grid | ChanY | Grid |
|
||||
* | [x][y] | [x][y-1] | [x+1][y] |
|
||||
* | | Connection | |
|
||||
* --------------Box_Y[x][y-1]--------------
|
||||
*/
|
||||
static
|
||||
void dump_verilog_routing_connection_box_unique_module(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
char* verilog_dir, char* subckt_dir,
|
||||
RRGSB& rr_gsb, t_rr_type cb_type) {
|
||||
FILE* fp = NULL;
|
||||
char* fname = NULL;
|
||||
int cur_num_sram, num_conf_bits, num_reserved_conf_bits, esti_sram_cnt;
|
||||
|
||||
/* Count the number of configuration bits */
|
||||
/* Count the number of configuration bits to be consumed by this Switch block */
|
||||
num_conf_bits = count_verilog_connection_box_conf_bits(cur_sram_orgz_info, rr_gsb, cb_type);
|
||||
/* Count the number of reserved configuration bits to be consumed by this Switch block */
|
||||
num_reserved_conf_bits = count_verilog_connection_box_reserved_conf_bits(cur_sram_orgz_info, rr_gsb, cb_type);
|
||||
/* Estimate the sram_verilog_model->cnt */
|
||||
cur_num_sram = get_sram_orgz_info_num_mem_bit(cur_sram_orgz_info);
|
||||
esti_sram_cnt = cur_num_sram + num_conf_bits;
|
||||
/* Record index */
|
||||
rr_gsb.set_cb_num_reserved_conf_bits(cb_type, num_reserved_conf_bits);
|
||||
rr_gsb.set_cb_conf_bits_lsb(cb_type, cur_num_sram);
|
||||
rr_gsb.set_cb_conf_bits_msb(cb_type, cur_num_sram + num_conf_bits - 1);
|
||||
|
||||
/* Print the definition of subckt*/
|
||||
/* Create file handler */
|
||||
fp = verilog_create_one_subckt_file(subckt_dir,
|
||||
"Connection Block - X/Y direction ",
|
||||
rr_gsb.gen_cb_verilog_module_name(cb_type),
|
||||
&fname);
|
||||
|
||||
/* Print preprocessing flags */
|
||||
verilog_include_defines_preproc_file(fp, verilog_dir);
|
||||
|
||||
/* Comment lines */
|
||||
fprintf(fp,
|
||||
"//----- Verilog Module of Connection block %s[%lu][%lu] -----\n",
|
||||
convert_cb_type_to_string(cb_type), rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type));
|
||||
fprintf(fp, "module ");
|
||||
fprintf(fp, "%s ", rr_gsb.gen_cb_verilog_module_name(cb_type));
|
||||
fprintf(fp, "(\n");
|
||||
/* dump global ports */
|
||||
if (0 < dump_verilog_global_ports(fp, global_ports_head, TRUE)) {
|
||||
fprintf(fp, ",\n");
|
||||
}
|
||||
/* Print the ports of channels*/
|
||||
/*connect to the mid point of a track*/
|
||||
/* Get the chan_rr_nodes: Only one side of a cb_info has chan_rr_nodes*/
|
||||
for (size_t inode = 0; inode < rr_gsb.get_cb_chan_width(cb_type); ++inode) {
|
||||
fprintf(fp, "input %s, \n",
|
||||
rr_gsb.gen_cb_verilog_routing_track_name(cb_type, inode));
|
||||
}
|
||||
|
||||
/* Print the ports of grids*/
|
||||
/* only check ipin_rr_nodes of cur_cb_info */
|
||||
std::vector<enum e_side> cb_ipin_sides = rr_gsb.get_cb_ipin_sides(cb_type);
|
||||
for (size_t iside = 0; iside < cb_ipin_sides.size(); ++iside) {
|
||||
enum e_side cb_ipin_side = cb_ipin_sides[iside];
|
||||
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(cb_ipin_side); ++inode) {
|
||||
/* Print each INPUT Pins of a grid */
|
||||
dump_verilog_grid_side_pin_with_given_index(fp, IPIN, /* This is an output of a connection box */
|
||||
rr_gsb.get_ipin_node(cb_ipin_side, inode)->ptc_num,
|
||||
rr_gsb.get_ipin_node_grid_side(cb_ipin_side, inode),
|
||||
rr_gsb.get_ipin_node(cb_ipin_side, inode)->xlow,
|
||||
rr_gsb.get_ipin_node(cb_ipin_side, inode)->ylow,
|
||||
TRUE);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Put down configuration port */
|
||||
/* output of each configuration bit */
|
||||
/* Reserved sram ports */
|
||||
if (0 < rr_gsb.get_cb_num_reserved_conf_bits(cb_type)) {
|
||||
dump_verilog_reserved_sram_ports(fp, cur_sram_orgz_info,
|
||||
rr_gsb.get_cb_reserved_conf_bits_lsb(cb_type),
|
||||
rr_gsb.get_cb_reserved_conf_bits_msb(cb_type),
|
||||
VERILOG_PORT_INPUT);
|
||||
fprintf(fp, ",\n");
|
||||
}
|
||||
/* Normal sram ports */
|
||||
dump_verilog_sram_ports(fp, cur_sram_orgz_info,
|
||||
rr_gsb.get_cb_conf_bits_lsb(cb_type),
|
||||
rr_gsb.get_cb_conf_bits_msb(cb_type),
|
||||
VERILOG_PORT_INPUT);
|
||||
|
||||
/* Dump ports only visible during formal verification*/
|
||||
if (0 < rr_gsb.get_cb_num_conf_bits(cb_type)) {
|
||||
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_gsb.get_cb_conf_bits_lsb(cb_type),
|
||||
rr_gsb.get_cb_conf_bits_msb(cb_type),
|
||||
VERILOG_PORT_INPUT);
|
||||
fprintf(fp, "\n");
|
||||
fprintf(fp, "`endif\n");
|
||||
}
|
||||
|
||||
/* subckt definition ends with svdd and sgnd*/
|
||||
fprintf(fp, ");\n");
|
||||
|
||||
/* Local wires for memory configurations */
|
||||
dump_verilog_sram_config_bus_internal_wires(fp, cur_sram_orgz_info,
|
||||
rr_gsb.get_cb_conf_bits_lsb(cb_type),
|
||||
rr_gsb.get_cb_conf_bits_msb(cb_type));
|
||||
|
||||
/* Record LSB and MSB of reserved_conf_bits and normal conf_bits */
|
||||
|
||||
/* Print multiplexers or direct interconnect*/
|
||||
for (size_t iside = 0; iside < cb_ipin_sides.size(); ++iside) {
|
||||
enum e_side cb_ipin_side = cb_ipin_sides[iside];
|
||||
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(cb_ipin_side); ++inode) {
|
||||
dump_verilog_connection_box_interc(cur_sram_orgz_info, fp, rr_gsb, cb_type,
|
||||
rr_gsb.get_ipin_node(cb_ipin_side, inode));
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fp, "endmodule\n");
|
||||
|
||||
/* Comment lines */
|
||||
fprintf(fp,
|
||||
"//----- END Verilog Module of Connection Box %s [%lu][%lu] -----\n\n",
|
||||
convert_cb_type_to_string(cb_type), rr_gsb.get_cb_x(cb_type), rr_gsb.get_cb_y(cb_type));
|
||||
|
||||
/* 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 */
|
||||
my_free(fname);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Print connection boxes
|
||||
* Print the sub-circuit of a connection Box (Type: [CHANX|CHANY])
|
||||
* Actually it is very similiar to switch box but
|
||||
|
@ -3494,30 +4063,76 @@ void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
}
|
||||
|
||||
/* Connection Boxes */
|
||||
/* X - channels [1...nx][0..ny]*/
|
||||
for (int iy = 0; iy < (ny + 1); iy++) {
|
||||
for (int ix = 1; ix < (nx + 1); ix++) {
|
||||
/* vpr_printf(TIO_MESSAGE_INFO, "Writing X-direction Connection Boxes[%d][%d]...\n", ix, iy); */
|
||||
update_spice_models_routing_index_low(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
if ((TRUE == is_cb_exist(CHANX, ix, iy))
|
||||
&&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) {
|
||||
dump_verilog_routing_connection_box_subckt(cur_sram_orgz_info, verilog_dir, subckt_dir, &(cbx_info[ix][iy]),
|
||||
compact_routing_hierarchy);
|
||||
if (TRUE == compact_routing_hierarchy) {
|
||||
/* Create a snapshot on sram_orgz_info */
|
||||
t_sram_orgz_info* stamped_sram_orgz_info = snapshot_sram_orgz_info(cur_sram_orgz_info);
|
||||
/* Restore sram_orgz_info to the base */
|
||||
copy_sram_orgz_info (cur_sram_orgz_info, stamped_sram_orgz_info);
|
||||
|
||||
DeviceCoordinator cb_range = device_rr_gsb.get_gsb_range();
|
||||
|
||||
/* X - channels [1...nx][0..ny]*/
|
||||
for (int iy = 0; iy < (ny + 1); iy++) {
|
||||
for (int ix = 1; ix < (nx + 1); ix++) {
|
||||
for (size_t icb = 0; icb < device_rr_gsb.get_num_cb_unique_module(CHANX); ++icb) {
|
||||
RRGSB unique_mirror = device_rr_gsb.get_cb_unique_module(CHANX, icb);
|
||||
dump_verilog_routing_connection_box_unique_module(cur_sram_orgz_info, verilog_dir, subckt_dir, unique_mirror, CHANX);
|
||||
}
|
||||
}
|
||||
update_spice_models_routing_index_high(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
}
|
||||
}
|
||||
/* Y - channels [1...ny][0..nx]*/
|
||||
for (int ix = 0; ix < (nx + 1); ix++) {
|
||||
for (int iy = 1; iy < (ny + 1); iy++) {
|
||||
/* vpr_printf(TIO_MESSAGE_INFO, "Writing Y-direction Connection Boxes[%d][%d]...\n", ix, iy); */
|
||||
update_spice_models_routing_index_low(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
if ((TRUE == is_cb_exist(CHANY, ix, iy))
|
||||
&&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) {
|
||||
dump_verilog_routing_connection_box_subckt(cur_sram_orgz_info, verilog_dir, subckt_dir, &(cby_info[ix][iy]),
|
||||
compact_routing_hierarchy);
|
||||
/* TODO: when we follow a tile organization,
|
||||
* updating the conf bits should follow a tile organization: CLB, SB and CBX, CBY */
|
||||
for (size_t ix = 0; ix < cb_range.get_x(); ++ix) {
|
||||
for (size_t iy = 0; iy < cb_range.get_y(); ++iy) {
|
||||
RRGSB rr_gsb = device_rr_gsb.get_gsb(ix, iy);
|
||||
update_routing_connection_box_conf_bits(cur_sram_orgz_info, rr_gsb, CHANX);
|
||||
}
|
||||
}
|
||||
|
||||
/* Y - channels [1...ny][0..nx]*/
|
||||
for (int ix = 0; ix < (nx + 1); ix++) {
|
||||
for (int iy = 1; iy < (ny + 1); iy++) {
|
||||
for (size_t icb = 0; icb < device_rr_gsb.get_num_cb_unique_module(CHANY); ++icb) {
|
||||
RRGSB unique_mirror = device_rr_gsb.get_cb_unique_module(CHANY, icb);
|
||||
dump_verilog_routing_connection_box_unique_module(cur_sram_orgz_info, verilog_dir, subckt_dir, unique_mirror, CHANY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t ix = 0; ix < cb_range.get_x(); ++ix) {
|
||||
for (size_t iy = 0; iy < cb_range.get_y(); ++iy) {
|
||||
RRGSB rr_gsb = device_rr_gsb.get_gsb(ix, iy);
|
||||
update_routing_connection_box_conf_bits(cur_sram_orgz_info, rr_gsb, CHANY);
|
||||
}
|
||||
}
|
||||
/* Free */
|
||||
free_sram_orgz_info(stamped_sram_orgz_info, stamped_sram_orgz_info->type);
|
||||
} else {
|
||||
/* X - channels [1...nx][0..ny]*/
|
||||
for (int iy = 0; iy < (ny + 1); iy++) {
|
||||
for (int ix = 1; ix < (nx + 1); ix++) {
|
||||
/* vpr_printf(TIO_MESSAGE_INFO, "Writing X-direction Connection Boxes[%d][%d]...\n", ix, iy); */
|
||||
update_spice_models_routing_index_low(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
if ((TRUE == is_cb_exist(CHANX, ix, iy))
|
||||
&&(0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy]))) {
|
||||
dump_verilog_routing_connection_box_subckt(cur_sram_orgz_info, verilog_dir, subckt_dir, &(cbx_info[ix][iy]),
|
||||
compact_routing_hierarchy);
|
||||
}
|
||||
update_spice_models_routing_index_high(ix, iy, CHANX, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
}
|
||||
}
|
||||
/* Y - channels [1...ny][0..nx]*/
|
||||
for (int ix = 0; ix < (nx + 1); ix++) {
|
||||
for (int iy = 1; iy < (ny + 1); iy++) {
|
||||
/* vpr_printf(TIO_MESSAGE_INFO, "Writing Y-direction Connection Boxes[%d][%d]...\n", ix, iy); */
|
||||
update_spice_models_routing_index_low(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
if ((TRUE == is_cb_exist(CHANY, ix, iy))
|
||||
&&(0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy]))) {
|
||||
dump_verilog_routing_connection_box_subckt(cur_sram_orgz_info, verilog_dir, subckt_dir, &(cby_info[ix][iy]),
|
||||
compact_routing_hierarchy);
|
||||
}
|
||||
update_spice_models_routing_index_high(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
}
|
||||
update_spice_models_routing_index_high(ix, iy, CHANY, arch.spice->num_spice_model, arch.spice->spice_models);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
#ifndef VERILOG_ROUTING_H
|
||||
#define VERILOG_ROUTING_H
|
||||
void dump_verilog_routing_chan_subckt(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
char* verilog_dir,
|
||||
char* subckt_dir,
|
||||
|
@ -88,17 +89,29 @@ void dump_verilog_connection_box_interc(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
int count_verilog_connection_box_interc_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
t_rr_node* cur_rr_node);
|
||||
|
||||
int count_verilog_connection_box_one_side_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
RRGSB& rr_gsb, enum e_side cb_side);
|
||||
|
||||
int count_verilog_connection_box_interc_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
t_rr_node* cur_rr_node);
|
||||
|
||||
int count_verilog_connection_box_one_side_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
RRGSB& rr_gsb, enum e_side cb_side);
|
||||
|
||||
int count_verilog_connection_box_one_side_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
int num_ipin_rr_nodes,
|
||||
t_rr_node** ipin_rr_node);
|
||||
|
||||
int count_verilog_connection_box_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
RRGSB& rr_gsb, t_rr_type cb_type);
|
||||
|
||||
int count_verilog_connection_box_one_side_reserved_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
int num_ipin_rr_nodes,
|
||||
t_rr_node** ipin_rr_node);
|
||||
|
||||
int count_verilog_connection_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
RRGSB& rr_gsb, t_rr_type cb_type);
|
||||
|
||||
int count_verilog_connection_box_conf_bits(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
t_cb* cur_cb_info);
|
||||
|
||||
|
@ -122,3 +135,4 @@ void dump_verilog_routing_resources(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
t_syn_verilog_opts fpga_verilog_opts,
|
||||
boolean compact_routing_hierarchy);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <assert.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
/* Include vpr structs*/
|
||||
#include "util.h"
|
||||
|
@ -1092,14 +1093,80 @@ void verilog_generate_sdc_disable_unused_sbs_muxs(FILE* fp, int LL_nx, int LL_ny
|
|||
return;
|
||||
}
|
||||
|
||||
void verilog_generate_sdc_disable_unused_cbs_muxs(FILE* fp) {
|
||||
static
|
||||
void verilog_generate_sdc_disable_one_unused_cb_mux(FILE* fp, RRGSB& rr_gsb, t_rr_type cb_type) {
|
||||
std::vector<enum e_side> cb_sides = rr_gsb.get_cb_ipin_sides(cb_type);
|
||||
|
||||
for (size_t side = 0; side < cb_sides.size(); ++side) {
|
||||
enum e_side cb_ipin_side = cb_sides[side];
|
||||
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(cb_ipin_side); ++inode) {
|
||||
t_rr_node* ipin_node = rr_gsb.get_ipin_node(cb_ipin_side, inode);
|
||||
for (int imux = 0 ; imux < ipin_node->fan_in; ++imux) {
|
||||
if (imux == ipin_node->id_path) {
|
||||
fprintf(fp, "#"); // comments out if the node is active
|
||||
}
|
||||
fprintf(fp, "set_disable_timing %s[%d]\n",
|
||||
ipin_node->name_mux, imux);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static
|
||||
void verilog_generate_sdc_disable_unused_cbs_muxs(FILE* fp, int LL_nx, int LL_ny, DeviceRRGSB& LL_device_rr_gsb) {
|
||||
|
||||
for (int iy = 0; iy < (LL_ny + 1); ++iy) {
|
||||
for (int ix = 1; ix < (LL_nx + 1); ++ix) {
|
||||
RRGSB rr_gsb = LL_device_rr_gsb.get_gsb(ix, iy);
|
||||
if ((TRUE == is_cb_exist(CHANX, ix, iy))
|
||||
&&(true == rr_gsb.is_cb_exist(CHANX))) {
|
||||
/* Print comments */
|
||||
fprintf(fp,
|
||||
"##############################################################\n");
|
||||
fprintf(fp,
|
||||
"### Disable Timing for MUXES in Connection block X[%d][%d] ###\n",
|
||||
ix, iy);
|
||||
fprintf(fp,
|
||||
"##############################################################\n");
|
||||
|
||||
verilog_generate_sdc_disable_one_unused_cb_mux(fp, rr_gsb, CHANX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int iy = 1; iy < (LL_ny + 1); iy++) {
|
||||
for (int ix = 0; ix < (LL_nx + 1); ix++) {
|
||||
RRGSB rr_gsb = LL_device_rr_gsb.get_gsb(ix, iy);
|
||||
if ((TRUE == is_cb_exist(CHANY, ix, iy))
|
||||
&&(true == rr_gsb.is_cb_exist(CHANY))) {
|
||||
/* Print comments */
|
||||
fprintf(fp,
|
||||
"##############################################################\n");
|
||||
fprintf(fp,
|
||||
"### Disable Timing for MUXES in Connection block Y[%d][%d] ###\n",
|
||||
ix, iy);
|
||||
fprintf(fp,
|
||||
"##############################################################\n");
|
||||
verilog_generate_sdc_disable_one_unused_cb_mux(fp, rr_gsb, CHANY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void verilog_generate_sdc_disable_unused_cbs_muxs(FILE* fp,
|
||||
int LL_nx, int LL_ny) {
|
||||
|
||||
int ix, iy, iside, inode, imux;
|
||||
t_cb* cur_cb_info;
|
||||
t_rr_node* cur_rr_node;
|
||||
|
||||
for (iy = 0; iy < (ny + 1); iy++) {
|
||||
for (ix = 1; ix < (nx + 1); ix++) {
|
||||
for (iy = 0; iy < (LL_ny + 1); iy++) {
|
||||
for (ix = 1; ix < (LL_nx + 1); ix++) {
|
||||
if (0 < count_cb_info_num_ipin_rr_nodes(cbx_info[ix][iy])) {
|
||||
cur_cb_info = &(cbx_info[ix][iy]);
|
||||
/* Print comments */
|
||||
|
@ -1126,8 +1193,8 @@ void verilog_generate_sdc_disable_unused_cbs_muxs(FILE* fp) {
|
|||
}
|
||||
}
|
||||
}
|
||||
for (iy = 1; iy < (ny + 1); iy++) {
|
||||
for (ix = 0; ix < (nx + 1); ix++) {
|
||||
for (iy = 1; iy < (LL_ny + 1); iy++) {
|
||||
for (ix = 0; ix < (LL_nx + 1); ix++) {
|
||||
if (0 < count_cb_info_num_ipin_rr_nodes(cby_info[ix][iy])) {
|
||||
cur_cb_info = &(cby_info[ix][iy]);
|
||||
/* Print comments */
|
||||
|
@ -1286,6 +1353,53 @@ void verilog_generate_sdc_disable_unused_sbs(FILE* fp,
|
|||
return;
|
||||
}
|
||||
|
||||
static
|
||||
void verilog_generate_sdc_disable_one_unused_cb(FILE* fp,
|
||||
RRGSB& rr_gsb, t_rr_type cb_type) {
|
||||
/* Check the file handler */
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s,LINE[%d])Invalid file handler for SDC generation",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Print comments */
|
||||
fprintf(fp,
|
||||
"##################################################\n");
|
||||
fprintf(fp,
|
||||
"### Disable Timing for an unused %s ###\n",
|
||||
rr_gsb.gen_cb_verilog_module_name(cb_type));
|
||||
fprintf(fp,
|
||||
"##################################################\n");
|
||||
|
||||
std::vector<enum e_side> cb_sides = rr_gsb.get_cb_ipin_sides(cb_type);
|
||||
|
||||
for (size_t side = 0; side < cb_sides.size(); ++side) {
|
||||
enum e_side cb_ipin_side = cb_sides[side];
|
||||
for (size_t inode = 0; inode < rr_gsb.get_num_ipin_nodes(cb_ipin_side); ++inode) {
|
||||
t_rr_node* ipin_node = rr_gsb.get_ipin_node(cb_ipin_side, inode);
|
||||
if (FALSE == is_rr_node_to_be_disable_for_analysis(ipin_node)) {
|
||||
continue;
|
||||
}
|
||||
if (0 == ipin_node->fan_in) {
|
||||
continue;
|
||||
}
|
||||
fprintf(fp, "set_disable_timing ");
|
||||
fprintf(fp, "%s/",
|
||||
rr_gsb.gen_cb_verilog_instance_name(cb_type));
|
||||
dump_verilog_grid_side_pin_with_given_index(fp, IPIN,
|
||||
ipin_node->ptc_num,
|
||||
rr_gsb.get_ipin_node_grid_side(cb_ipin_side, inode),
|
||||
ipin_node->xlow,
|
||||
ipin_node->ylow,
|
||||
FALSE); /* Do not specify direction of port */
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static
|
||||
void verilog_generate_sdc_disable_one_unused_cb(FILE* fp,
|
||||
|
@ -1345,6 +1459,43 @@ void verilog_generate_sdc_disable_one_unused_cb(FILE* fp,
|
|||
return;
|
||||
}
|
||||
|
||||
static
|
||||
void verilog_generate_sdc_disable_unused_cbs(FILE* fp,
|
||||
int LL_nx, int LL_ny,
|
||||
DeviceRRGSB& LL_device_rr_gsb) {
|
||||
/* Check the file handler */
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s,LINE[%d])Invalid file handler for SDC generation",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Connection Boxes */
|
||||
/* X - channels [1...nx][0..ny]*/
|
||||
for (int iy = 0; iy < (LL_ny + 1); iy++) {
|
||||
for (int ix = 1; ix < (LL_nx + 1); ix++) {
|
||||
RRGSB rr_gsb = LL_device_rr_gsb.get_gsb(ix, iy);
|
||||
if ((TRUE == is_cb_exist(CHANX, ix, iy))
|
||||
&&(true == rr_gsb.is_cb_exist(CHANX))) {
|
||||
verilog_generate_sdc_disable_one_unused_cb(fp, rr_gsb, CHANX);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Y - channels [1...ny][0..nx]*/
|
||||
for (int ix = 0; ix < (LL_nx + 1); ix++) {
|
||||
for (int iy = 1; iy < (LL_ny + 1); iy++) {
|
||||
RRGSB rr_gsb = LL_device_rr_gsb.get_gsb(ix, iy);
|
||||
if ((TRUE == is_cb_exist(CHANY, ix, iy))
|
||||
&&(true == rr_gsb.is_cb_exist(CHANY))) {
|
||||
verilog_generate_sdc_disable_one_unused_cb(fp, rr_gsb, CHANY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static
|
||||
void verilog_generate_sdc_disable_unused_cbs(FILE* fp,
|
||||
int LL_nx, int LL_ny) {
|
||||
|
@ -2124,8 +2275,13 @@ void verilog_generate_sdc_analysis(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
}
|
||||
|
||||
/* Apply to Connection blocks */
|
||||
verilog_generate_sdc_disable_unused_cbs(fp, LL_nx, LL_ny);
|
||||
verilog_generate_sdc_disable_unused_cbs_muxs(fp);
|
||||
if (TRUE == compact_routing_hierarchy) {
|
||||
verilog_generate_sdc_disable_unused_cbs(fp, LL_nx, LL_ny, device_rr_gsb);
|
||||
verilog_generate_sdc_disable_unused_cbs_muxs(fp, LL_nx, LL_ny, device_rr_gsb);
|
||||
} else {
|
||||
verilog_generate_sdc_disable_unused_cbs(fp, LL_nx, LL_ny);
|
||||
verilog_generate_sdc_disable_unused_cbs_muxs(fp, LL_nx, LL_ny);
|
||||
}
|
||||
|
||||
/* Apply to Switch blocks */
|
||||
if (TRUE == compact_routing_hierarchy) {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#ifndef VERILOG_SDC_H
|
||||
#define VERILOG_SDC_H
|
||||
|
||||
void verilog_generate_sdc_pnr(t_sram_orgz_info* cur_sram_orgz_info,
|
||||
char* sdc_dir,
|
||||
|
@ -19,7 +21,7 @@ void verilog_generate_sdc_analysis(t_sram_orgz_info* cur_sram_orgz_info,
|
|||
|
||||
void verilog_generate_sdc_disable_unused_sbs_muxs(FILE* fp, int LL_nx, int LL_ny);
|
||||
|
||||
void verilog_generate_sdc_disable_unused_cbs_muxs(FILE* fp);
|
||||
void verilog_generate_sdc_disable_unused_cbs_muxs(FILE* fp, int LL_nx, int LL_ny);
|
||||
|
||||
void verilog_generate_sdc_disable_unused_grids_muxs(FILE* fp,
|
||||
int LL_nx, int LL_ny,
|
||||
|
@ -47,3 +49,4 @@ void dump_sdc_pb_graph_pin_muxes(FILE* fp,
|
|||
t_rr_graph* rr_graph,
|
||||
t_pb_graph_pin pb_graph_pin);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -345,6 +345,43 @@ void verilog_include_simulation_defines_file(FILE* fp,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Create a file handler for a subckt Verilog netlist */
|
||||
FILE* verilog_create_one_subckt_file(char* subckt_dir,
|
||||
const char* subckt_name_prefix,
|
||||
const char* verilog_subckt_file_name_prefix,
|
||||
char** verilog_fname) {
|
||||
FILE* fp = NULL;
|
||||
char* file_description = NULL;
|
||||
|
||||
char* temp = my_strcat(subckt_dir, verilog_subckt_file_name_prefix);
|
||||
(*verilog_fname) = my_strcat(temp, verilog_netlist_file_postfix);
|
||||
|
||||
/* Create a file*/
|
||||
fp = fopen((*verilog_fname), "w");
|
||||
|
||||
if (NULL == fp) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s,LINE[%d])Failure in create Verilog netlist %s",
|
||||
__FILE__, __LINE__, (*verilog_fname));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Generate the descriptions*/
|
||||
file_description = (char*) my_malloc(sizeof(char) * (strlen(subckt_name_prefix) + 9));
|
||||
sprintf(file_description,
|
||||
"%s in FPGA",
|
||||
subckt_name_prefix);
|
||||
|
||||
dump_verilog_file_header(fp, file_description);
|
||||
|
||||
/* Free */
|
||||
my_free(temp);
|
||||
my_free(file_description);
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
|
||||
/* Create a file handler for a subckt Verilog netlist */
|
||||
FILE* verilog_create_one_subckt_file(char* subckt_dir,
|
||||
const char* subckt_name_prefix,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
|
||||
#ifndef VERILOG_UTILS_H
|
||||
#define VERILOG_UTILS_H
|
||||
|
||||
void init_list_include_verilog_netlists(t_spice* spice);
|
||||
|
||||
|
@ -30,6 +31,11 @@ void verilog_include_simulation_defines_file(FILE* fp,
|
|||
void verilog_include_defines_preproc_file(FILE* fp,
|
||||
char* formatted_verilog_dir);
|
||||
|
||||
FILE* verilog_create_one_subckt_file(char* subckt_dir,
|
||||
const char* subckt_name_prefix,
|
||||
const char* verilog_subckt_file_name_prefix,
|
||||
char** verilog_fname);
|
||||
|
||||
FILE* verilog_create_one_subckt_file(char* subckt_dir,
|
||||
const char* subckt_name_prefix,
|
||||
const char* verilog_subckt_file_name_prefix,
|
||||
|
@ -282,3 +288,5 @@ char* gen_verilog_top_module_io_port_prefix(char* global_prefix,
|
|||
char* io_port_prefix);
|
||||
|
||||
char* gen_verilog_one_pb_graph_node_full_name_in_hierarchy(t_pb_graph_node* cur_pb_graph_node);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue