support wired LUT in FPGA-SPICE and FPGA-Verilog
This commit is contained in:
parent
f7d7a056da
commit
861c449606
Binary file not shown.
|
@ -876,14 +876,28 @@ void set_one_pb_rr_node_default_prev_node_edge(t_rr_node* pb_rr_graph,
|
|||
|
||||
/* Mark the prev_edge and prev_node of all the rr_nodes in complex blocks */
|
||||
static
|
||||
void back_annotate_one_pb_rr_node_map_info_rec(t_pb* cur_pb) {
|
||||
void back_annotate_one_pb_rr_node_map_info_rec(t_pb* cur_pb,
|
||||
t_pb_graph_node* cur_pb_graph_node,
|
||||
t_rr_node* pb_rr_nodes) {
|
||||
int ipb, jpb, select_mode_index;
|
||||
int iport, ipin, node_index;
|
||||
t_rr_node* pb_rr_nodes = NULL;
|
||||
t_pb_graph_node* child_pb_graph_node;
|
||||
|
||||
/* Return when we meet a null pb */
|
||||
if (NULL == cur_pb) {
|
||||
/* Skip non-LUT pb*/
|
||||
if (LUT_CLASS != cur_pb_graph_node->pb_type->class_type) {
|
||||
return;
|
||||
}
|
||||
for (iport = 0; iport < cur_pb_graph_node->num_output_ports; iport++) {
|
||||
for (ipin = 0; ipin < cur_pb_graph_node->num_output_pins[iport]; ipin++) {
|
||||
node_index = cur_pb_graph_node->output_pins[iport][ipin].pin_count_in_cluster;
|
||||
if (OPEN != pb_rr_nodes[node_index].net_num) {
|
||||
pb_rr_nodes[node_index].vpack_net_num = pb_rr_nodes[node_index].net_num;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -971,7 +985,21 @@ void back_annotate_one_pb_rr_node_map_info_rec(t_pb* cur_pb) {
|
|||
for (ipb = 0; ipb < cur_pb->pb_graph_node->pb_type->modes[select_mode_index].num_pb_type_children; ipb++) {
|
||||
for (jpb = 0; jpb < cur_pb->pb_graph_node->pb_type->modes[select_mode_index].pb_type_children[ipb].num_pb; jpb++) {
|
||||
if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) {
|
||||
back_annotate_one_pb_rr_node_map_info_rec(&(cur_pb->child_pbs[ipb][jpb]));
|
||||
back_annotate_one_pb_rr_node_map_info_rec(&(cur_pb->child_pbs[ipb][jpb]),
|
||||
&(cur_pb->pb_graph_node->child_pb_graph_nodes[select_mode_index][ipb][jpb]),
|
||||
cur_pb->rr_graph);
|
||||
} else {
|
||||
/* For wired LUT */
|
||||
if (TRUE == is_pb_wired_lut(&(cur_pb->pb_graph_node->child_pb_graph_nodes[select_mode_index][ipb][jpb]),
|
||||
&(cur_pb->pb_graph_node->pb_type->modes[select_mode_index].pb_type_children[ipb]),
|
||||
cur_pb->rr_graph)) {
|
||||
/* Reach here means that this LUT is in wired mode (a buffer)
|
||||
* synchronize the net num
|
||||
*/
|
||||
back_annotate_one_pb_rr_node_map_info_rec(NULL,
|
||||
&(cur_pb->pb_graph_node->child_pb_graph_nodes[select_mode_index][ipb][jpb]),
|
||||
cur_pb->rr_graph);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -990,7 +1018,9 @@ void back_annotate_pb_rr_node_map_info() {
|
|||
if (IO_TYPE == block[iblk].type) {
|
||||
continue;
|
||||
}
|
||||
back_annotate_one_pb_rr_node_map_info_rec(block[iblk].pb);
|
||||
back_annotate_one_pb_rr_node_map_info_rec(block[iblk].pb,
|
||||
block[iblk].pb->pb_graph_node,
|
||||
block[iblk].pb->rr_graph);
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
|
@ -37,3 +37,7 @@ enum e_pin2pin_interc_type {
|
|||
|
||||
|
||||
extern char* renaming_report_postfix;
|
||||
|
||||
#define PRIMITIVE_WIRED_LUT -1
|
||||
#define PRIMITIVE_IDLE 1
|
||||
#define PRIMITIVE_NORMAL 0
|
||||
|
|
|
@ -5797,6 +5797,103 @@ void get_lut_logical_block_input_pin_vpack_net_num(t_logical_block* lut_logical_
|
|||
return;
|
||||
}
|
||||
|
||||
/* Find the vpack_net_num of the outputs of the logical_block */
|
||||
void get_logical_block_output_vpack_net_num(t_logical_block* cur_logical_block,
|
||||
int* num_lb_output_ports, int** num_lb_output_pins,
|
||||
int*** lb_output_vpack_net_num) {
|
||||
int iport, ipin;
|
||||
int num_output_ports = 0;
|
||||
int* num_output_pins = NULL;
|
||||
t_model_ports* head = NULL;
|
||||
int** output_vpack_net_num = NULL;
|
||||
|
||||
assert (NULL != cur_logical_block);
|
||||
|
||||
/* Count how many outputs we have */
|
||||
head = cur_logical_block->model->outputs;
|
||||
while (NULL != head) {
|
||||
num_output_ports++;
|
||||
head = head->next;
|
||||
}
|
||||
/* Allocate */
|
||||
num_output_pins = (int*) my_calloc(num_output_ports, sizeof(int));
|
||||
output_vpack_net_num = (int**) my_calloc(num_output_ports, sizeof(int*));
|
||||
/* Fill the array */
|
||||
iport = 0;
|
||||
head = cur_logical_block->model->outputs;
|
||||
while (NULL != head) {
|
||||
num_output_pins[iport] = head->size;
|
||||
output_vpack_net_num[iport] = (int*) my_calloc(num_output_pins[iport], sizeof(int));
|
||||
/* Fill the array */
|
||||
for (ipin = 0; ipin < num_output_pins[iport]; ipin++) {
|
||||
output_vpack_net_num[iport][ipin] = cur_logical_block->output_nets[iport][ipin];
|
||||
}
|
||||
/* Go to the next */
|
||||
head = head->next;
|
||||
/* Update counter */
|
||||
iport++;
|
||||
}
|
||||
|
||||
assert (iport == num_output_ports);
|
||||
|
||||
/* Assign return values */
|
||||
(*num_lb_output_ports) = num_output_ports;
|
||||
(*num_lb_output_pins) = num_output_pins;
|
||||
(*lb_output_vpack_net_num) = output_vpack_net_num;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Adapt the truth from the actual connection from the input nets of a LUT,
|
||||
*/
|
||||
char** assign_post_routing_wired_lut_truth_table(t_logical_block* wired_lut_logical_block,
|
||||
int lut_size, int* lut_pin_vpack_net_num,
|
||||
int* truth_table_length) {
|
||||
int inet, iport;
|
||||
char** tt = (char**) my_malloc(sizeof(char*));
|
||||
int num_lut_output_ports;
|
||||
int* num_lut_output_pins;
|
||||
int** lut_output_vpack_net_num;
|
||||
|
||||
/* The output of this mapped block is the wires routed through this LUT */
|
||||
/* Find the vpack_net_num of the output of the lut_logical_block */
|
||||
get_logical_block_output_vpack_net_num(wired_lut_logical_block,
|
||||
&num_lut_output_ports,
|
||||
&num_lut_output_pins,
|
||||
&lut_output_vpack_net_num);
|
||||
|
||||
/* Check */
|
||||
assert ( 1 == num_lut_output_ports);
|
||||
assert ( 1 == num_lut_output_pins[0]);
|
||||
assert ( OPEN != lut_output_vpack_net_num[0][0]);
|
||||
|
||||
/* truth_table_length will be always 1*/
|
||||
(*truth_table_length) = 1;
|
||||
|
||||
/* Malloc */
|
||||
tt[0] = (char*)my_malloc((lut_size + 3) * sizeof(char));
|
||||
/* Fill the truth table !!! */
|
||||
for (inet = 0; inet < lut_size; inet++) {
|
||||
/* Find the vpack_num in the lut_input_pin, we fix it to be 1 */
|
||||
if (lut_output_vpack_net_num[0][0] == lut_pin_vpack_net_num[inet]) {
|
||||
tt[0][inet] = '1';
|
||||
} else {
|
||||
/* Otherwise it should be don't care */
|
||||
tt[0][inet] = '-';
|
||||
}
|
||||
}
|
||||
memcpy(tt[0] + lut_size, " 1", 3);
|
||||
|
||||
/* Free */
|
||||
my_free(num_lut_output_pins);
|
||||
for (iport = 0; iport < num_lut_output_ports; iport++) {
|
||||
my_free(lut_output_vpack_net_num);
|
||||
}
|
||||
|
||||
return tt;
|
||||
}
|
||||
|
||||
|
||||
/* Provide the truth table of a mapped logical block
|
||||
* 1. Reorgainze the truth table to be consistent with the mapped nets of a LUT
|
||||
|
@ -7480,5 +7577,47 @@ void rec_stats_spice_model_global_ports(t_spice_model* cur_spice_model,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Identify if this child_pb is actually used for wiring!!! */
|
||||
boolean is_pb_used_for_wiring(t_pb_graph_node* cur_pb_graph_node,
|
||||
t_pb_type* cur_pb_type,
|
||||
t_rr_node* pb_rr_graph) {
|
||||
boolean is_used = FALSE;
|
||||
int node_index;
|
||||
int port_index = 0;
|
||||
int iport, ipin;
|
||||
|
||||
for (iport = 0; iport < cur_pb_type->num_ports && !is_used; iport++) {
|
||||
if (OUT_PORT == cur_pb_type->ports[iport].type) {
|
||||
for (ipin = 0; ipin < cur_pb_type->ports[iport].num_pins; ipin++) {
|
||||
node_index = cur_pb_graph_node->output_pins[port_index][ipin].pin_count_in_cluster;
|
||||
if ((OPEN != pb_rr_graph[node_index].net_num)
|
||||
|| (OPEN != pb_rr_graph[node_index].vpack_net_num)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
port_index++;
|
||||
}
|
||||
}
|
||||
|
||||
return is_used;
|
||||
}
|
||||
|
||||
|
||||
/* Identify if this is an unallocated pb that is used as a wired LUT */
|
||||
boolean is_pb_wired_lut(t_pb_graph_node* cur_pb_graph_node,
|
||||
t_pb_type* cur_pb_type,
|
||||
t_rr_node* pb_rr_graph) {
|
||||
boolean is_used = FALSE;
|
||||
|
||||
is_used = is_pb_used_for_wiring(cur_pb_graph_node,
|
||||
cur_pb_type,
|
||||
pb_rr_graph);
|
||||
/* Return TRUE if this block is not used and it is a LUT ! */
|
||||
if ((TRUE == is_used)
|
||||
&& (LUT_CLASS == cur_pb_type->class_type)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -457,6 +457,14 @@ char** assign_lut_truth_table(t_logical_block* mapped_logical_block,
|
|||
void get_lut_logical_block_input_pin_vpack_net_num(t_logical_block* lut_logical_block,
|
||||
int* num_lut_pin, int** lut_pin_net);
|
||||
|
||||
void get_logical_block_output_vpack_net_num(t_logical_block* cur_logical_block,
|
||||
int* num_lb_output_ports, int** num_lb_output_pins,
|
||||
int*** lb_output_vpack_net_num);
|
||||
|
||||
char** assign_post_routing_wired_lut_truth_table(t_logical_block* wired_lut_logical_block,
|
||||
int lut_size, int* lut_pin_vpack_net_num,
|
||||
int* truth_table_length);
|
||||
|
||||
char** assign_post_routing_lut_truth_table(t_logical_block* mapped_logical_block,
|
||||
int lut_size, int* lut_pin_vpack_net_num,
|
||||
int* truth_table_length);
|
||||
|
@ -642,3 +650,11 @@ void get_mapped_lut_pb_input_pin_vpack_net_num(t_pb* lut_pb,
|
|||
void rec_stats_spice_model_global_ports(t_spice_model* cur_spice_model,
|
||||
boolean recursive,
|
||||
t_llist** spice_model_head);
|
||||
|
||||
boolean is_pb_used_for_wiring(t_pb_graph_node* cur_pb_graph_node,
|
||||
t_pb_type* cur_pb_type,
|
||||
t_rr_node* pb_rr_graph);
|
||||
|
||||
boolean is_pb_wired_lut(t_pb_graph_node* cur_pb_graph_node,
|
||||
t_pb_type* cur_pb_type,
|
||||
t_rr_node* pb_rr_graph);
|
||||
|
|
|
@ -177,7 +177,8 @@ void fprint_pb_primitive_lut(FILE* fp,
|
|||
t_logical_block* mapped_logical_block,
|
||||
t_pb_graph_node* cur_pb_graph_node,
|
||||
int index,
|
||||
t_spice_model* spice_model) {
|
||||
t_spice_model* spice_model,
|
||||
int lut_status) {
|
||||
int i;
|
||||
int num_sram = 0;
|
||||
int* sram_bits = NULL; /* decoded SRAM bits */
|
||||
|
@ -217,7 +218,22 @@ void fprint_pb_primitive_lut(FILE* fp,
|
|||
assert(SPICE_MODEL_LUT == spice_model->type);
|
||||
|
||||
/* Check if this is an idle logical block mapped*/
|
||||
if (NULL != mapped_logical_block) {
|
||||
switch (lut_status) {
|
||||
case PRIMITIVE_WIRED_LUT:
|
||||
/* Give a special truth table */
|
||||
assert (VPACK_COMB == mapped_logical_block->type);
|
||||
/* Get the mapped vpack_net_num of this physical LUT pb */
|
||||
get_mapped_lut_pb_input_pin_vpack_net_num(prim_pb, &num_lut_pin_nets, &lut_pin_net);
|
||||
/* consider LUT pin remapping when assign lut truth tables */
|
||||
/* Match truth table and post-routing results */
|
||||
truth_table = assign_post_routing_wired_lut_truth_table(mapped_logical_block,
|
||||
num_lut_pin_nets, lut_pin_net, &truth_table_length);
|
||||
break;
|
||||
case PRIMITIVE_IDLE:
|
||||
break;
|
||||
case PRIMITIVE_NORMAL:
|
||||
assert (NULL != mapped_logical_block);
|
||||
/* Back-annotate to logical block */
|
||||
/* Back-annotate to logical block */
|
||||
mapped_logical_block->mapped_spice_model = spice_model;
|
||||
mapped_logical_block->mapped_spice_model_index = spice_model->cnt;
|
||||
|
@ -229,7 +245,12 @@ void fprint_pb_primitive_lut(FILE* fp,
|
|||
/* Match truth table and post-routing results */
|
||||
truth_table = assign_post_routing_lut_truth_table(mapped_logical_block,
|
||||
num_lut_pin_nets, lut_pin_net, &truth_table_length);
|
||||
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s, [LINE%d]) Invalid status(=%d) for LUT!\n",
|
||||
__FILE__, __LINE__, lut_status);
|
||||
exit(1);
|
||||
}
|
||||
/* Determine size of LUT*/
|
||||
input_ports = find_spice_model_ports(spice_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE);
|
||||
|
|
|
@ -15,4 +15,5 @@ void fprint_pb_primitive_lut(FILE* fp,
|
|||
t_logical_block* mapped_logical_block,
|
||||
t_pb_graph_node* cur_pb_graph_node,
|
||||
int index,
|
||||
t_spice_model* spice_model);
|
||||
t_spice_model* spice_model,
|
||||
int lut_status);
|
||||
|
|
|
@ -989,24 +989,47 @@ void fprint_pb_primitive_spice_model(FILE* fp,
|
|||
|
||||
/* Initialize */
|
||||
prim_pb_type = prim_pb_graph_node->pb_type;
|
||||
if (is_idle) {
|
||||
|
||||
switch (is_idle) {
|
||||
case PRIMITIVE_WIRED_LUT:
|
||||
mapped_logical_block = NULL;
|
||||
} else {
|
||||
break;
|
||||
case PRIMITIVE_IDLE:
|
||||
mapped_logical_block = NULL;
|
||||
break;
|
||||
case PRIMITIVE_NORMAL:
|
||||
mapped_logical_block = &logical_block[prim_pb->logical_block];
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s, [LINE%d]) Invalid ID(=%d) for primitive Verilog block!\n",
|
||||
__FILE__, __LINE__, is_idle);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Asserts*/
|
||||
assert(pb_index == prim_pb_graph_node->placement_index);
|
||||
assert(0 == strcmp(spice_model->name, prim_pb_type->spice_model->name));
|
||||
|
||||
if (is_idle) {
|
||||
switch (is_idle) {
|
||||
case PRIMITIVE_WIRED_LUT:
|
||||
assert(NULL == prim_pb);
|
||||
} else {
|
||||
break;
|
||||
case PRIMITIVE_IDLE:
|
||||
assert(NULL == prim_pb);
|
||||
break;
|
||||
case PRIMITIVE_NORMAL:
|
||||
if (NULL == prim_pb) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s, [LINE%d]) Invalid ID(=%d) for primitive Verilog block!\n",
|
||||
__FILE__, __LINE__, is_idle);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* According to different type, we print netlist*/
|
||||
|
@ -1014,7 +1037,7 @@ void fprint_pb_primitive_spice_model(FILE* fp,
|
|||
case SPICE_MODEL_LUT:
|
||||
/* If this is a idle block we should set sram_bits to zero*/
|
||||
fprint_pb_primitive_lut(fp, subckt_prefix, prim_pb, mapped_logical_block, prim_pb_graph_node,
|
||||
pb_index, spice_model);
|
||||
pb_index, spice_model, is_idle);
|
||||
break;
|
||||
case SPICE_MODEL_FF:
|
||||
assert(NULL != spice_model->model_netlist);
|
||||
|
@ -1234,6 +1257,17 @@ void fprint_spice_pb_graph_node_rec(FILE* fp,
|
|||
exit(1);
|
||||
}
|
||||
cur_pb_type = cur_pb_graph_node->pb_type;
|
||||
|
||||
/* For wired LUTs only */
|
||||
if (NULL == cur_pb) {
|
||||
assert(NULL != cur_pb_type->spice_model);
|
||||
assert (LUT_CLASS == cur_pb_type->class_type);
|
||||
fprint_pb_primitive_spice_model(fp, formatted_subckt_prefix,
|
||||
NULL, cur_pb_graph_node,
|
||||
pb_type_index, cur_pb_type->spice_model, PRIMITIVE_WIRED_LUT);
|
||||
return;
|
||||
}
|
||||
|
||||
mode_index = cur_pb->mode;
|
||||
|
||||
/* Recursively finish all the child pb_types*/
|
||||
|
@ -1254,6 +1288,16 @@ void fprint_spice_pb_graph_node_rec(FILE* fp,
|
|||
if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) {
|
||||
fprint_spice_pb_graph_node_rec(fp, pass_on_prefix, &(cur_pb->child_pbs[ipb][jpb]),
|
||||
cur_pb->child_pbs[ipb][jpb].pb_graph_node, jpb);
|
||||
/* For wired LUT */
|
||||
} else if (TRUE == is_pb_wired_lut(&(cur_pb->pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]),
|
||||
&(cur_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb]),
|
||||
cur_pb->rr_graph)) {
|
||||
/* Reach here means that this LUT is in wired mode (a buffer)
|
||||
* Print the Verilog of wired LUTs
|
||||
*/
|
||||
fprint_spice_pb_graph_node_rec(fp, pass_on_prefix, NULL,
|
||||
&(cur_pb->pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]),
|
||||
jpb);
|
||||
} else {
|
||||
/* Check if this pb has no children, no children mean idle*/
|
||||
fprint_spice_idle_pb_graph_node_rec(fp, pass_on_prefix,
|
||||
|
|
|
@ -39,7 +39,8 @@ void dump_verilog_pb_primitive_lut(FILE* fp,
|
|||
t_logical_block* mapped_logical_block,
|
||||
t_pb_graph_node* cur_pb_graph_node,
|
||||
int index,
|
||||
t_spice_model* verilog_model) {
|
||||
t_spice_model* verilog_model,
|
||||
int lut_status) {
|
||||
int i;
|
||||
int* sram_bits = NULL; /* decoded SRAM bits */
|
||||
int truth_table_length = 0;
|
||||
|
@ -95,7 +96,21 @@ void dump_verilog_pb_primitive_lut(FILE* fp,
|
|||
assert(SPICE_MODEL_LUT == verilog_model->type);
|
||||
|
||||
/* Check if this is an idle logical block mapped*/
|
||||
if (NULL != mapped_logical_block) {
|
||||
switch (lut_status) {
|
||||
case PRIMITIVE_WIRED_LUT:
|
||||
/* Give a special truth table */
|
||||
assert (VPACK_COMB == mapped_logical_block->type);
|
||||
/* Get the mapped vpack_net_num of this physical LUT pb */
|
||||
get_mapped_lut_pb_input_pin_vpack_net_num(prim_pb, &num_lut_pin_nets, &lut_pin_net);
|
||||
/* consider LUT pin remapping when assign lut truth tables */
|
||||
/* Match truth table and post-routing results */
|
||||
truth_table = assign_post_routing_wired_lut_truth_table(mapped_logical_block,
|
||||
num_lut_pin_nets, lut_pin_net, &truth_table_length);
|
||||
break;
|
||||
case PRIMITIVE_IDLE:
|
||||
break;
|
||||
case PRIMITIVE_NORMAL:
|
||||
assert (NULL != mapped_logical_block);
|
||||
/* Back-annotate to logical block */
|
||||
mapped_logical_block->mapped_spice_model = verilog_model;
|
||||
mapped_logical_block->mapped_spice_model_index = verilog_model->cnt;
|
||||
|
@ -107,7 +122,14 @@ void dump_verilog_pb_primitive_lut(FILE* fp,
|
|||
/* Match truth table and post-routing results */
|
||||
truth_table = assign_post_routing_lut_truth_table(mapped_logical_block,
|
||||
num_lut_pin_nets, lut_pin_net, &truth_table_length);
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s, [LINE%d]) Invalid status(=%d) for LUT!\n",
|
||||
__FILE__, __LINE__, lut_status);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Determine size of LUT*/
|
||||
input_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_INPUT, &num_input_port, TRUE);
|
||||
output_ports = find_spice_model_ports(verilog_model, SPICE_MODEL_PORT_OUTPUT, &num_output_port, TRUE);
|
||||
|
|
|
@ -5,4 +5,5 @@ void dump_verilog_pb_primitive_lut(FILE* fp,
|
|||
t_logical_block* mapped_logical_block,
|
||||
t_pb_graph_node* cur_pb_graph_node,
|
||||
int index,
|
||||
t_spice_model* spice_model);
|
||||
t_spice_model* spice_model,
|
||||
int lut_status);
|
||||
|
|
|
@ -1598,23 +1598,46 @@ void dump_verilog_pb_primitive_verilog_model(FILE* fp,
|
|||
|
||||
/* Initialize */
|
||||
prim_pb_type = prim_pb_graph_node->pb_type;
|
||||
if (is_idle) {
|
||||
|
||||
switch (is_idle) {
|
||||
case PRIMITIVE_WIRED_LUT:
|
||||
mapped_logical_block = NULL;
|
||||
} else {
|
||||
break;
|
||||
case PRIMITIVE_IDLE:
|
||||
mapped_logical_block = NULL;
|
||||
break;
|
||||
case PRIMITIVE_NORMAL:
|
||||
mapped_logical_block = &logical_block[prim_pb->logical_block];
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s, [LINE%d]) Invalid ID(=%d) for primitive Verilog block!\n",
|
||||
__FILE__, __LINE__, is_idle);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Asserts*/
|
||||
assert(pb_index == prim_pb_graph_node->placement_index);
|
||||
assert(0 == strcmp(verilog_model->name, prim_pb_type->spice_model->name));
|
||||
if (is_idle) {
|
||||
switch (is_idle) {
|
||||
case PRIMITIVE_WIRED_LUT:
|
||||
assert(NULL == prim_pb);
|
||||
} else {
|
||||
break;
|
||||
case PRIMITIVE_IDLE:
|
||||
assert(NULL == prim_pb);
|
||||
break;
|
||||
case PRIMITIVE_NORMAL:
|
||||
if (NULL == prim_pb) {
|
||||
vpr_printf(TIO_MESSAGE_ERROR,"(File:%s,[LINE%d])Invalid prim_pb.\n",
|
||||
__FILE__, __LINE__);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
vpr_printf(TIO_MESSAGE_ERROR,
|
||||
"(FILE:%s, [LINE%d]) Invalid ID(=%d) for primitive Verilog block!\n",
|
||||
__FILE__, __LINE__, is_idle);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* According to different type, we print netlist*/
|
||||
|
@ -1622,7 +1645,7 @@ void dump_verilog_pb_primitive_verilog_model(FILE* fp,
|
|||
case SPICE_MODEL_LUT:
|
||||
/* If this is a idle block we should set sram_bits to zero*/
|
||||
dump_verilog_pb_primitive_lut(fp, subckt_prefix, prim_pb, mapped_logical_block, prim_pb_graph_node,
|
||||
pb_index, verilog_model);
|
||||
pb_index, verilog_model, is_idle);
|
||||
break;
|
||||
case SPICE_MODEL_FF:
|
||||
assert(NULL != verilog_model->model_netlist);
|
||||
|
@ -1960,6 +1983,25 @@ void dump_verilog_pb_graph_node_rec(FILE* fp,
|
|||
exit(1);
|
||||
}
|
||||
cur_pb_type = cur_pb_graph_node->pb_type;
|
||||
|
||||
/* For wired LUTs only */
|
||||
if (NULL == cur_pb) {
|
||||
assert(NULL != cur_pb_type->spice_model);
|
||||
assert (LUT_CLASS == cur_pb_type->class_type);
|
||||
dump_verilog_pb_primitive_verilog_model(fp, formatted_subckt_prefix,
|
||||
NULL, cur_pb_graph_node,
|
||||
pb_type_index, cur_pb_type->spice_model, PRIMITIVE_WIRED_LUT);
|
||||
/* update the number of SRAM, I/O pads */
|
||||
/* update stamped iopad counter */
|
||||
stamped_iopad_cnt += cur_pb->num_iopads;
|
||||
/* update stamped sram counter */
|
||||
stamped_sram_cnt += cur_pb->num_conf_bits;
|
||||
/* Check */
|
||||
assert(stamped_sram_cnt == get_sram_orgz_info_num_mem_bit(sram_verilog_orgz_info));
|
||||
assert(stamped_iopad_cnt == iopad_verilog_model->cnt);
|
||||
return;
|
||||
}
|
||||
|
||||
mode_index = cur_pb->mode;
|
||||
|
||||
/* Recursively finish all the child pb_types*/
|
||||
|
@ -1980,10 +2022,20 @@ void dump_verilog_pb_graph_node_rec(FILE* fp,
|
|||
if ((NULL != cur_pb->child_pbs[ipb])&&(NULL != cur_pb->child_pbs[ipb][jpb].name)) {
|
||||
dump_verilog_pb_graph_node_rec(fp, pass_on_prefix, &(cur_pb->child_pbs[ipb][jpb]),
|
||||
cur_pb->child_pbs[ipb][jpb].pb_graph_node, jpb);
|
||||
/* For wired LUT */
|
||||
} else if (TRUE == is_pb_wired_lut(&(cur_pb->pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]),
|
||||
&(cur_pb->pb_graph_node->pb_type->modes[mode_index].pb_type_children[ipb]),
|
||||
cur_pb->rr_graph)) {
|
||||
/* Reach here means that this LUT is in wired mode (a buffer)
|
||||
* Print the Verilog of wired LUTs
|
||||
*/
|
||||
dump_verilog_pb_graph_node_rec(fp, pass_on_prefix, NULL,
|
||||
&(cur_pb->pb_graph_node->child_pb_graph_nodes[mode_index][ipb][jpb]),
|
||||
jpb);
|
||||
} else {
|
||||
/* Check if this pb has no children, no children mean idle*/
|
||||
dump_verilog_idle_pb_graph_node_rec(fp, pass_on_prefix,
|
||||
cur_pb->child_pbs[ipb][jpb].pb_graph_node, jpb);
|
||||
cur_pb->child_pbs[ipb][jpb].pb_graph_node, jpb);
|
||||
}
|
||||
/* Free */
|
||||
my_free(pass_on_prefix);
|
||||
|
|
Loading…
Reference in New Issue