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"
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); }
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; }
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); }
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; }
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; } } }
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; }
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); }