|
VPR-6.0
|
#include <stdio.h>#include <string.h>#include "util.h"#include "vpr_types.h"#include "globals.h"#include "hash.h"#include "vpr_utils.h"#include "check_netlist.h"#include "assert.h"#include "read_xml_arch_file.h"
Include dependency graph for check_netlist.c:Go to the source code of this file.
Defines | |
| #define | ERROR_THRESHOLD 100 |
Functions | |
| static int | check_connections_to_global_clb_pins (int inet) |
| static int | check_for_duplicated_names (void) |
| static int | check_clb_conn (int iblk, int num_conn) |
| static int | check_clb_internal_nets (int iblk) |
| static int | check_subblock_internal_nets (int iblk, int isub) |
| static void | check_for_multiple_sink_connections (void) |
| static int | get_num_conn (int bnum) |
| static int | check_subblocks (int iblk) |
| static int | check_primitives (int iblk, int isub) |
| void | check_netlist () |
| #define ERROR_THRESHOLD 100 |
Definition at line 13 of file check_netlist.c.
| static int check_clb_conn | ( | int | iblk, |
| int | num_conn | ||
| ) | [static] |
Checks that the connections into and out of the clb make sense.
Definition at line 167 of file check_netlist.c.
{
int iclass, ipin, error;
t_type_ptr type;
error = 0;
type = block[iblk].type;
if(type == IO_TYPE)
{
if(num_conn != 1)
{
printf(ERRTAG "io blk #%d (%s) has %d pins.\n",
iblk, block[iblk].name, num_conn);
error++;
}
}
else if(num_conn < 2)
{
printf(WARNTAG "logic block #%d (%s) has only %d pin.\n",
iblk, block[iblk].name, num_conn);
/* Allow the case where we have only one OUTPUT pin connected to continue. *
* This is used sometimes as a constant generator for a primary output, *
* but I will still warn the user. If the only pin connected is an input, *
* abort. */
if(num_conn == 1)
{
for(ipin = 0; ipin < type->num_pins; ipin++)
{
if(block[iblk].nets[ipin] != OPEN)
{
iclass = type->pin_class[ipin];
if(type->class_inf[iclass].type != DRIVER)
{
error++;
}
else
{
printf
("\tPin is an output -- may be a constant generator.\n"
"\tNon-fatal, but check this.\n");
}
break;
}
}
}
else
{
error++;
}
}
/* This case should already have been flagged as an error -- this is *
* just a redundant double check. */
if(num_conn > type->num_pins)
{
printf(ERRTAG "logic block #%d with output %s has %d pins.\n",
iblk, block[iblk].name, num_conn);
error++;
}
return (error);
}
Here is the caller graph for this function:| static int check_clb_internal_nets | ( | int | iblk | ) | [static] |
Definition at line 237 of file check_netlist.c.
{
/* TODO:
* Check if the internal CLB nets makes sense and are connected properly
* Consists of 3 main loops
* 1. a) Check name uniqueness
b) Check all net connections are to CLB pins or subblock pins and that they match the net examined
* 2. Check all connected CLB pins are connected to valid internal nets
* 3. Check all connected subblock pins are connected to valid internal nets and that these match the net indexes
*/
return 0;
}
Here is the caller graph for this function:| static int check_connections_to_global_clb_pins | ( | int | inet | ) | [static] |
Checks that a global net (inet) connects only to global CLB input pins and that non-global nets never connects to a global CLB pin. Either global or non-global nets are allowed to connect to pads.
Definition at line 110 of file check_netlist.c.
{
int ipin, num_pins, iblk, node_block_pin, error;
num_pins = (clb_net[inet].num_sinks + 1);
error = 0;
/* For now global signals can be driven by an I/O pad or any CLB output *
* although a CLB output generates a warning. I could make a global CLB *
* output pin type to allow people to make architectures that didn't have *
* this warning. */
for(ipin = 0; ipin < num_pins; ipin++)
{
iblk = clb_net[inet].node_block[ipin];
node_block_pin = clb_net[inet].node_block_pin[ipin];
if(block[iblk].type->is_global_pin[node_block_pin] !=
clb_net[inet].is_global && block[iblk].type != IO_TYPE)
{
/* Allow a CLB output pin to drive a global net (warning only). */
if(ipin == 0 && clb_net[inet].is_global)
{
printf
(WARNTAG "in check_connections_to_global_clb_pins:\n"
"\tnet #%d (%s) is driven by CLB output pin (#%d)\n"
"\ton block #%d (%s).\n", inet,
clb_net[inet].name, node_block_pin, iblk,
block[iblk].name);
}
else
{ /* Otherwise -> Error */
printf
(ERRTAG "in check_connections_to_global_clb_pins:\n"
"\tpin %d on net #%d (%s) connects to CLB input pin (#%d)\n"
"\ton block #%d (%s).\n", ipin, inet,
clb_net[inet].name, node_block_pin, iblk,
block[iblk].name);
error++;
}
if(clb_net[inet].is_global)
printf("\tNet is global, but CLB pin is not.\n\n");
else
printf("\tCLB pin is global, but net is not.\n\n");
}
} /* End for all pins */
return (error);
}
Here is the caller graph for this function:| static int check_for_duplicated_names | ( | void | ) | [static] |
Definition at line 286 of file check_netlist.c.
{
#if 0
int iblk, isub, iprim, error;
int clb_count, sub_count, prim_count;
struct s_hash **clb_hash_table, *clb_h_ptr;
struct s_hash **sub_hash_table, *sub_h_ptr;
struct s_hash **prim_hash_table, *prim_h_ptr;
clb_hash_table = alloc_hash_table();
sub_hash_table = alloc_hash_table();
prim_hash_table = alloc_hash_table();
error = clb_count = sub_count = prim_count = 0;
for(iblk = 0; iblk < num_blocks; iblk++)
{
clb_h_ptr = insert_in_hash_table(clb_hash_table, block[iblk].name, clb_count);
if(clb_h_ptr->count > 1) {
printf(ERRTAG "block %s has duplicated name\n", block[iblk].name);
error++;
} else {
clb_count++;
}
for(isub = 0; isub < block[iblk].num_subblocks; isub++)
{
sub_h_ptr = insert_in_hash_table(sub_hash_table, block[iblk].subblocks[isub].name, sub_count);
if(sub_h_ptr->count > 1) {
printf(ERRTAG "subblock %s has duplicated name\n", block[iblk].subblocks[isub].name);
error++;
} else {
sub_count++;
}
for(iprim = 0; iprim < block[iblk].subblocks[isub].num_primitives; iprim++)
{
prim_h_ptr = insert_in_hash_table(prim_hash_table, block[iblk].subblocks[isub].primitives[iprim].name, prim_count);
if(prim_h_ptr->count > 1) {
printf(ERRTAG "primitive %s has duplicated name\n", block[iblk].subblocks[isub].primitives[iprim].name);
error++;
} else {
prim_count++;
}
}
}
}
return error;
#endif
return 0;
}
Here is the call graph for this function:
Here is the caller graph for this function:| static void check_for_multiple_sink_connections | ( | void | ) | [static] |
| void check_netlist | ( | ) |
This routine checks that the netlist makes sense.
Definition at line 41 of file check_netlist.c.
{
int i, error, num_conn;
int net_count;
struct s_hash **net_hash_table, *h_net_ptr;
net_hash_table = alloc_hash_table();
net_count = 0;
error = 0;
/* Check that nets fanout and have a driver. */
for(i = 0; i < num_nets; i++)
{
h_net_ptr = insert_in_hash_table(net_hash_table, clb_net[i].name, i);
if(h_net_ptr->count != 1) {
printf(ERRTAG "net %s has multiple drivers.\n", clb_net[i].name);
error++;
}
error += check_connections_to_global_clb_pins(i);
if(error >= ERROR_THRESHOLD) {
printf("Too many errors in netlist, exiting\n");
exit(1);
}
}
free_hash_table(net_hash_table);
/* Check that each block makes sense. */
for(i = 0; i < num_blocks; i++)
{
num_conn = get_num_conn(i);
error += check_clb_conn(i, num_conn);
error += check_clb_internal_nets(i);
error += check_subblocks(i);
if(error >= ERROR_THRESHOLD) {
printf("Too many errors in netlist, exiting\n");
exit(1);
}
}
error += check_for_duplicated_names();
if(error != 0)
{
printf("Found %d fatal Errors in the input netlist.\n", error);
exit(1);
}
/* HACK: Jason Luu January 17, 2011 Do not route common constants gnd and vcc
Todo: Need to make architecture driven.
*/
for(i = 0; i < num_nets; i++)
{
if(strcmp(clb_net[i].name, "vcc") == 0) {
clb_net[i].is_global = TRUE;
} else if(strcmp(clb_net[i].name, "gnd") == 0) {
clb_net[i].is_global = TRUE;
}
}
}
Here is the call graph for this function:
Here is the caller graph for this function:| static int check_primitives | ( | int | iblk, |
| int | isub | ||
| ) | [static] |
Definition at line 274 of file check_netlist.c.
{
/* TODO:
This routine checks the subblocks of iblk (which must be a CLB). It *
* returns the number of errors found. */
return 0;
}
| static int check_subblock_internal_nets | ( | int | iblk, |
| int | isub | ||
| ) | [static] |
Definition at line 250 of file check_netlist.c.
{
/*
* TODO
* Check if the internal CLB nets makes sense and are connected properly
* Consists of 3 main checks
* 1. a) Check name uniqueness
b) Check all net connections are to CLB pins or subblock pins and that they match the net examined
* 2. Check all connected CLB pins are connected to valid internal nets
* 3. Check all connected subblock pins are connected to valid internal nets and that these match the net indexes
*/
return 0;
}
| static int check_subblocks | ( | int | iblk | ) | [static] |
Definition at line 264 of file check_netlist.c.
{
/* TODO */
/* This routine checks the subblocks of iblk (which must be a CLB). It *
* returns the number of errors found. */
return 0;
}
Here is the caller graph for this function:| static int get_num_conn | ( | int | bnum | ) | [static] |
This routine returns the number of connections to a block.
Definition at line 339 of file check_netlist.c.
{
int i, num_conn;
t_type_ptr type;
type = block[bnum].type;
num_conn = 0;
for(i = 0; i < type->num_pins; i++)
{
if(block[bnum].nets[i] != OPEN)
num_conn++;
}
return (num_conn);
}
Here is the caller graph for this function: