blob: 2f26ee04b7da2c29f40c8a8c036fd7589d02a58c [file] [log] [blame]
/*
*
* channel.c
*
*/
#define CHANNEL_CODE
/*
*
* Includes.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include "types.h"
#include "channel.h"
/*
*
* Code.
*
*/
void
BuildChannel(void)
{
/*
* What is the length dimension of the channel?
* That is, how many columns in the channel?
*/
DimensionChannel();
/*
* What are the particulargs of the channel?
* That is, what are the nets and pin locations?
*/
DescribeChannel();
/*
* What is the maximum density of the channel?
* That is, what is the lower bound on the number of tracks
* required to route the channel?
*/
DensityChannel();
}
void
DimensionChannel(void)
{
FILE *channelFP;
ulong line;
ulong dim;
ulong net;
ulong col;
ulong bot;
ulong top;
long stat;
/*
* Open channel description file.
*/
channelFP = fopen(channelFile, "r");
if (channelFP == NULL) {
/*
* Error in channel file description.
*/
printf("Error:\n");
printf("\tChannel file cannot be opened.\n");
exit(1);
}
/*
* Scan the file to find the last column
* number. The channel file description
* contains non-negative integers in the
* format...
*
* [column #] [bottom net #] [top net #]
*/
line = 0;
dim = 0;
net = 0;
do {
line++;
unsigned int c1, b1, t1;
stat = fscanf(channelFP, "%u%u%u", &c1, &b1, &t1);
col = c1; bot = b1; top = t1;
if (stat != EOF) {
if (stat == 3) {
/*
* Update column #.
*/
if (col > dim) {
dim = col;
}
/*
* Determine how many channel nets.
*/
if (bot > net) {
net = bot;
}
if (top > net) {
net = top;
}
}
else {
/*
* Error in channel file description.
*/
printf("Error:\n");
printf("\tChannel file description invalid at line %d.\n", line);
printf("\tIncorrect number of specifiers.\n");
exit(1);
}
}
} while (stat != EOF);
/*
* Close channel description file.
*/
if (fclose(channelFP) == EOF) {
/*
* Error in channel file description.
*/
printf("Error:\n");
printf("\tChannel file cannot be closed.\n");
exit(1);
}
/*
* Check channel dimension.
*/
if (dim == 0) {
/*
* Error in channel file description.
*/
printf("Error:\n");
printf("\tChannel description invalid.\n");
printf("\tChannel has null dimension.\n");
exit(1);
}
/*
* Set global channel info.
*/
channelColumns = dim;
channelNets = net;
}
void
DescribeChannel(void)
{
FILE *channelFP;
ulong line;
ulong col;
ulong bot;
ulong top;
long stat;
/*
* Top terminals of channel.
*/
TOP = (ulong *)malloc((channelColumns+1) * sizeof(ulong));
/*
* Bottom terminals of channel.
*/
BOT = (ulong *)malloc((channelColumns+1) * sizeof(ulong));
/*
* Initialize terminals of channel.
*/
for (col = 0; col <= channelColumns; col++) {
TOP[col] = 0;
BOT[col] = 0;
}
/*
* Open channel description file.
*/
channelFP = fopen(channelFile, "r");
if (channelFP == NULL) {
/*
* Error in channel file description.
*/
printf("Error:\n");
printf("\tChannel file cannot be opened.\n");
exit(1);
}
/*
* Scan the file to find the last column
* number. The channel file description
* contains non-negative integers in the
* format...
*
* [column #] [bottom net #] [top net #]
*/
line = 0;
do {
line++;
unsigned int c1, b1, t1;
stat = fscanf(channelFP, "%u%u%u", &c1, &b1, &t1);
col = c1; bot = b1; top = t1;
if (stat != EOF) {
if (stat == 3) {
/*
* Build column.
*/
if (col > channelColumns) {
/*
* Error in channel file description.
*/
printf("Error:\n");
printf("\tChannel file description invalid at line %d.\n", line);
printf("\tColumn number out of range.\n");
exit(1);
}
else {
/*
* Doit.
*/
BOT[col] = bot;
TOP[col] = top;
}
}
else {
/*
* Error in channel file description.
*/
printf("Error:\n");
printf("\tChannel file description invalid at line %d.\n", line);
printf("\tIncorrect number of specifiers.\n");
exit(1);
}
}
} while (stat != EOF);
/*
* Close channel description file.
*/
if (fclose(channelFP) == EOF) {
/*
* Error in channel file description.
*/
printf("Error:\n");
printf("\tChannel file cannot be closed.\n");
exit(1);
}
}
void
DensityChannel(void)
{
ulong init;
ulong which;
ulong col;
ulong bound;
ulong boundColumn;
/*
* Allocate track dimension structures.
*/
FIRST = (ulong *)malloc((channelNets+1) * sizeof(ulong));
LAST = (ulong *)malloc((channelNets+1) * sizeof(ulong));
DENSITY = (ulong *)malloc((channelColumns+1) * sizeof(ulong));
CROSSING = (ulong *)malloc((channelNets+1) * sizeof(ulong));
/*
* Initialize track dimension structures.
*/
for (init = 0; init <= channelNets; init++) {
FIRST[init] = 0;
LAST[init] = 0;
CROSSING[init] = 0;
}
for (init = 0; init <= channelColumns; init++) {
DENSITY[init] = 0;
}
/*
* Compute the span for each net.
*/
for (which = 1; which <= channelNets; which++) {
/*
* Compute first. This is the location of
* the first column for this net.
*/
for (col = 1; col <= channelColumns; col++) {
if ((BOT[col] == which) || (TOP[col] == which)) {
FIRST[which] = col;
break;
}
}
/*
* Compute last. This is the location of
* the last column for this net.
*/
for (col = channelColumns; col >= 1; col--) {
if ((BOT[col] == which) || (TOP[col] == which)) {
LAST[which] = col;
break;
}
}
/*
* Increment the track for each column
* of the channel which this net spans.
*/
for (col = FIRST[which]; col <= LAST[which]; col++) {
DENSITY[col]++;
}
}
/*
* Compute lower bound on channel tracks.
*/
#ifdef SCOTT
bound = 0;
for (col = 1; col <= channelColumns; col++) {
if (DENSITY[col] > bound) {
bound = DENSITY[col];
boundColumn = col;
}
}
#else
bound = 0;
for (col = channelColumns; col >= 1; col--) {
if (DENSITY[col] > bound) {
bound = DENSITY[col];
boundColumn = col;
}
}
#endif
/*
* Set global channel info.
*/
channelTracks = bound; /* tracks available for routing */
channelDensity = bound; /* max channel density */
channelDensityColumn = boundColumn; /* column of max channel density */
}