You are on page 1of 15

/*

This file performs the actions:


- reads command line parmameters with format: [trace file name] [num Adder RS] [
num Multiplier RS] [num Divider RS] [num Load RS] [num Store RS]
- extracts number of RS for each FU and stores value in nRS[i]
- opens the specified instruction trace file
- reads each line of trace file with lines of format:
[ADDD/MULD/DIVD operation] F[dest register number] F[src1 register numbe
r] F[src2 register number]
or:
[LD/SD operation] F[dest/src1 register number] [garbage address string]
and extracts and prints the opcode, dest, src1, and src2 from each line of the
trace file.
Here is the linux gcc compile instructions:
gcc tomasulo_reads_input.c -o tomasulo_reads_input
Here is how to run on the command line the file tracefile.txt with parmaters of
3 ADDD RS, 2 MULD RS, 2 DIVD RS, 3 LD RS, 3 SD RS:
./tomasulo_reads_input tracefile.txt 3 2 2 3 3
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ADDD 0
#define MULD 1
#define DIVD 2
#define LD 3
#define SD 4
#define nOPcodes 5 // number of OPcodes
#define maxRS 8 // maximum number of reservation stations per functional unit
// string name corresponding to possible op codes
char *OPnames[nOPcodes] = {
"ADDD",
"MULD",
"DIVD",
"LD",
"SD"
};
struct type1
{
int vj, vk, qj1, qj2, qk1, qk2, freeornot, execctr, useful,flag, src1, s
rc2,dest;
}rs1[5][8];
struct flr
{
int busy, tag1,tag2;
}flrno[8];

FILE *tracefile;
unsigned char nRS[nOPcodes];
int i, j, ctr1, ctr2, ctr3, ctr4, ctr5, ctr6, ctr7, p, q, r, dummy1, dummy2, dum
my3, divcheck, addcheck, mulcheck, loadcheck, q1, noinst, nocycles, checkexecu0,
checkexecu1, checkexecu2, checkexecu3, checkexecu4;
char opcode[5];
char garbagestring[16];
int op,qp;
int dest, src1, src2,d1, d2, stall[5][8], busy[5][8], totstall[5], totbusy[5],w
;
float nocyclesfl, noinstfl;
void execution(void);
void flrinitialize(void);
void readinstructions(void);
void stall_busy(void);

main(argc, argv)
unsigned long argc;
char **argv;
{
printf( "use parameter format: [trace file name] [num Adder RS] [num Mul
tiplier RS] [num Divider RS] [num Load RS] [num Store RS]\n" );
// test if proiveded neccesary number of parameters
if( argc < 7 ) {
printf( "ERROR: Only provided %d arguments...\n", argc );
return 0;
}
// try to open trace file named according to parameter 1
printf("opening trace file %s...\n", argv[1]);
if ((tracefile = fopen( argv[1], "r")) == NULL) {
printf( "ERROR: no %s file found. %d", argv[1] );
return 0;
}
// read the numer of RS for each of the 5 functional units
printf( "running tomasulo with " );
for( i=0; i<5; i++ ) {
nRS[i] = atoi( argv[i+2] ); // get number of RS for Instruct
ion type INST[i]
printf( "%d %s RS, ", nRS[i], OPnames[i]);
}
printf( "and tracefile %s.\n", argv[1] );

for(d1=0;d1<5;d1++)
{
for(d2=0;d2<8;d2++)
{
stall[d1][d2]=0;
busy[d1][d2]=0;
}
}
flrinitialize();//This function initializes all the 8 flrs
readinstructions();//This function includes the execution() function use
d twice per cycle
nocycles = nocycles + noinst ;
//From here the instruction fetch has ended and the remaining instructio
n execution goes
while(checkexecu0==1 || checkexecu1==1 ||checkexecu2==1 || checkexecu3==
1 || checkexecu4==1 )
{
nocycles ++;
execution();
}
printf("\n\nThe folloing are the busy cycles and stall cycles for each R
S\nAnd in RS[a][b], 'a' defines FU and 'b' number of RS for respective FU\na=0,1
,2,3,4 means ADDD, MULD, DIVD, LD, SD respectively\n");
stall_busy();
nocyclesfl=nocycles;
noinstfl=noinst;
printf("\n\nTotal Cycles = %d, Total Instructions = %d", nocycles, noin
st);
printf("\n\nThus CPI = %f", nocyclesfl/noinstfl);
printf( "\ndone\n" );
return(0);
}
void stall_busy(void)
{
for(d1=0;d1<5;d1++)
{
for(d2=0;d2<8;d2++)
{
if(d2<nRS[d1])
{
printf("\nRS[%d][%d] : Stall Cycles = %d", d1, d
2,stall[d1][d2]);
printf("\nRS[%d][%d] : Busy Cycles = %d", d1, d
2,busy[d1][d2]);
}
}
printf("\n");
}

}
void flrinitialize(void)
{

for(ctr1=0;ctr1<8;ctr1++)//This initializes the flrs and all RS to all t


hings zero
{
flrno[ctr1].busy = 9;
flrno[ctr1].tag1 = 9;
flrno[ctr1].tag2 = 9;
for(ctr5=0;ctr5<5;ctr5++)
{ rs1[ctr5][ctr1].vj=9;
rs1[ctr5][ctr1].vk=9;
rs1[ctr5][ctr1].qj1=9;
rs1[ctr5][ctr1].qk1=9;
rs1[ctr5][ctr1].qj2=9;
rs1[ctr5][ctr1].qk2=9;
rs1[ctr5][ctr1].freeornot=9;
rs1[ctr5][ctr1].execctr=0;
rs1[ctr5][ctr1].useful=9;
rs1[ctr5][ctr1].flag=9;
rs1[ctr5][ctr1].src1=9;
rs1[ctr5][ctr1].src2=9;
rs1[ctr5][ctr1].dest=9;
}
}
for( i=0; i<5; i++ ) //defines the useful RS for all FUs
{
for(ctr1=0; ctr1<nRS[i];ctr1++)
{
rs1[i][ctr1].useful=1;
ctr1++;
}
}
}

void readinstructions(void)
{

noinst=0;
nocycles=0;
checkexecu0=0;
checkexecu1=0;
checkexecu2=0;
checkexecu3=0;
checkexecu4=0;

while( fscanf( tracefile, "%s ", opcode ) != EOF)


{
noinst++;
execution();
op = -1;
for( i=0; i<5; i++ )
{
if( strcmp( opcode, OPnames[i] ) == 0 )
{
op = i;
break;
}
}
if( op == -1 )
{
printf( "Error reading opcode.\n" );
//return 0;
}
printf( "%s ", OPnames[op] );
switch(op) {
case ADDD:
case MULD:
case DIVD:
// for ADDD, MULD, and DIVD, need to get 1 dest and 2 op
erands
fscanf( tracefile, "F%d ",&dest);
fscanf( tracefile, "F%d ",&src1);
fscanf( tracefile, "F%d ",&src2);
printf( "F%d F%d F%d\n", dest, src1, src2 );
break;
case LD:
// for LD, need to get 1 dest
fscanf( tracefile, "F%d %s", &src1, garbagestring );
printf( "F%d\n", src1 );
break;
case SD:
// for SD, need to get 1 source
fscanf( tracefile, "F%d %s", &src1, garbagestring );
printf( "F%d\n", src1 );
break;
}

checkRS: ctr4=0;
while(ctr4<nRS[op])//assigns the available RS for a particular F
U by calculating ctr3 as index of RS
{
if(rs1[op][ctr4].freeornot==9)
{
ctr3=ctr4;
rs1[op][ctr3].freeornot=1;
break;
}
else
{
ctr4++;
}
}
if(ctr4==nRS[op])
{
nocycles++;
execution();
goto checkRS;
}
// stall IF and continue the past cycles
if(op==0 || op==1 || op==2)
{
if(flrno[src1].busy!=9)
{
rs1[op][ctr3].qj1=flrno[src1].tag1;
rs1[op][ctr3].qj2=flrno[src1].tag2;
}else if(flrno[src1].busy==9)
{
rs1[op][ctr3].qj1=9;
rs1[op][ctr3].qj2=9;
}
if(flrno[src2].busy!=9)
{
rs1[op][ctr3].qk1=flrno[src2].tag1;
rs1[op][ctr3].qk2=flrno[src2].tag2;
}else if(flrno[src2].busy==9)
{
rs1[op][ctr3].qk1=9;
rs1[op][ctr3].qk2=9;
}
flrno[dest].busy=1;
flrno[dest].tag1=op;
flrno[dest].tag2=ctr3;
//tag gives which rs is holding the given flr.
if(rs1[op][ctr3].qj1==9 && rs1[op][ctr3].qj2==9 && rs1[o
p][ctr3].qk1==9 && rs1[op][ctr3].qk2==9)
{
rs1[op][ctr3].vj=src1;
rs1[op][ctr3].vk=src2;
rs1[op][ctr3].flag=1;

}
else
{
rs1[op][ctr3].vj=9;
rs1[op][ctr3].vk=9;
rs1[op][ctr3].flag=9;
}
}
else if(op==3)
{
flrno[src1].busy=1;
flrno[src1].tag1=op;
flrno[src1].tag2=ctr3;
rs1[op][ctr3].flag=1;
}
else if(op==4)
{
if(flrno[src1].busy!=9)
{
rs1[op][ctr3].qj1=flrno[src1].tag1;
rs1[op][ctr3].qj2=flrno[src1].tag2;
rs1[op][ctr3].flag=9;
}else if(flrno[src1].busy==9)
{
rs1[op][ctr3].qj1=9;
rs1[op][ctr3].qj2=9;
rs1[op][ctr3].flag=1;
}
}

}
}

void execution(void)
{
divcheck = 9;
mulcheck = 9;
addcheck = 9;
loadcheck = 9;
for(p=2;p>=0;p--)
{
for(q=0;q<8;q++)
{
if(rs1[p][q].flag==9 && ((rs1[p][q].qj1!=9 && rs1[p][q].
qj2!=9) || (rs1[p][q].qk1!=9 && rs1[p][q].qk2!=9)))
{stall[p][q]++;}

if(rs1[p][q].flag==1 && p==2)


{
if((rs1[p][q].execctr)<10)
{
rs1[p][q].execctr=(rs1[p][q].execctr)+1;
checkexecu2=1;
busy[p][q]++;
if((rs1[p][q].execctr)<6)
{
for(qp=q+1;qp<8;qp++)
{
if(rs1[p][qp].flag==1 ||
(rs1[p][qp].flag==9 &&((rs1[p][qp].qj1!=9 && rs1[p][qp].qj2!=9) || (rs1[p][qp].q
k1!=9 && rs1[p][qp].qk2!=9))))
stall[p][qp]++;
}
goto again2;
}
}
else if(divcheck ==9 && (rs1[p][q].execctr)==10)
{
busy[p][q]++;
checkexecu2=0;
for(r=0;r<8;r++)
{
if(flrno[r].tag1 ==p && flrno[r]
.tag2 ==q)
{
flrno[r].busy=9;
flrno[r].tag1 =9;
flrno[r].tag2 =9;
}
}
for(dummy1=0;dummy1<5;dummy1++)
{
for(dummy2=0;dummy2<8;dummy2++)
{
if((rs1[dummy1][dummy2].
qj1!=9 && rs1[dummy1][dummy2].qj2!=9) || (rs1[dummy1][dummy2].qk1!=9 && rs1[dumm
y1][dummy2].qk2!=9)){
if(rs1[dummy1][d
ummy2].qj1==p && rs1[dummy1][dummy2].qj2==q)
{
rs1[dumm
y1][dummy2].qj1=9;
rs1[dumm
y1][dummy2].qj2=9;
}
if(rs1[dummy1][d
ummy2].qk1==p && rs1[dummy1][dummy2].qk2==q)
{
rs1[dumm
y1][dummy2].qk1=9;
rs1[dumm
y1][dummy2].qk2=9;
}
if(rs1[dummy1][d
ummy2].qj1==9 && rs1[dummy1][dummy2].qj2==9 && rs1[dummy1][dummy2].qk1==9 && rs1
[dummy1][dummy2].qk2==9)
{
rs1[dumm
y1][dummy2].flag=1;
if(dummy
1==2 && dummy2>q)
{
rs1[dummy1][dummy2].execctr=-1;
busy[dummy1][dummy2]--;
}
if(dummy
1!=2)
{
rs1[dummy1][dummy2].execctr=-1;
busy[dummy1][dummy2]--;
}
stall[du
mmy1][dummy2]++;
}
}
}
}
//release the RS
rs1[p][q].vj=9;
rs1[p][q].vk=9;
rs1[p][q].qj1=9;
rs1[p][q].qk1=9;
rs1[p][q].qj2=9;
rs1[p][q].qk2=9;
rs1[p][q].freeornot=9;
rs1[p][q].execctr=0;
rs1[p][q].flag=9;
rs1[p][q].src1=9;
rs1[p][q].src2=9;
rs1[p][q].dest=9;
divcheck=1;
}
else
stall[p][q]++;
}
if(rs1[p][q].flag==1 && p==1)
{
if((rs1[p][q].execctr)<6)
{
rs1[p][q].execctr=(rs1[p][q].execctr)+1;
checkexecu1=1;
busy[p][q]++;
}
else if(divcheck==9 && mulcheck==9 && (rs1[p][q]
.execctr)==6)
{ busy[p][q]++;
checkexecu1=0;
for(r=0;r<8;r++)
{
if(flrno[r].tag1 ==p && flrno[r]
.tag2 ==q)
{
flrno[r].busy=9;
flrno[r].tag1 =9;
flrno[r].tag2 =9;
}
}
for(dummy1=0;dummy1<5;dummy1++)
{
for(dummy2=0;dummy2<8;dummy2++)
{
if((rs1[dummy1][dummy2].
qj1!=9 && rs1[dummy1][dummy2].qj2!=9) || (rs1[dummy1][dummy2].qk1!=9 && rs1[dumm
y1][dummy2].qk2!=9)){
if(rs1[dummy1][d
ummy2].qj1==p && rs1[dummy1][dummy2].qj2==q)
{
rs1[dumm
y1][dummy2].qj1=9;
rs1[dumm
y1][dummy2].qj2=9;
}
if(rs1[dummy1][d
ummy2].qk1==p && rs1[dummy1][dummy2].qk2==q)
{
rs1[dumm
y1][dummy2].qk1=9;
rs1[dumm
y1][dummy2].qk2=9;
}
if(rs1[dummy1][d
ummy2].qj1==9 && rs1[dummy1][dummy2].qj2==9 && rs1[dummy1][dummy2].qk1==9 && rs1
[dummy1][dummy2].qk2==9)
{
rs1[dumm
y1][dummy2].flag=1;
if(dummy
1!=2)
{
if(dummy1==1 && dummy2>q)
{ rs1[dummy1][dummy2].execctr=-1;
busy[dummy1][dummy2]--;

}
else if(dummy1!=1)
{ rs1[dummy1][dummy2].execctr=-1;
busy[dummy1][dummy2]--;

}
}
stall[du
mmy1][dummy2]++;
}
}
}
}
//release the RS
rs1[p][q].vj=9;
rs1[p][q].vk=9;
rs1[p][q].qj1=9;
rs1[p][q].qk1=9;
rs1[p][q].qj2=9;
rs1[p][q].qk2=9;
rs1[p][q].freeornot=9;
rs1[p][q].execctr=0;
rs1[p][q].flag=9;
rs1[p][q].src1=9;
rs1[p][q].src2=9;
rs1[p][q].dest=9;
mulcheck=1;
}
else
stall[p][q]++;
}
if(rs1[p][q].flag==1 && p==0)
{
if((rs1[p][q].execctr)<4)
{
rs1[p][q].execctr=(rs1[p][q].execctr)+1;
checkexecu0=1;
busy[p][q]++;
}
else if(divcheck==9 && mulcheck==9 && addcheck==
9 && (rs1[p][q].execctr)==4)
{ busy[p][q]++;
checkexecu0=0;
for(r=0;r<8;r++)
{
if(flrno[r].tag1 ==p && flrno[r]
.tag2 ==q)
{
flrno[r].busy=9;
flrno[r].tag1 =9;
flrno[r].tag2 =9;
}
}
for(dummy1=0;dummy1<5;dummy1++)
{
for(dummy2=0;dummy2<8;dummy2++)
{
if((rs1[dummy1][dummy2].
qj1!=9 && rs1[dummy1][dummy2].qj2!=9) || (rs1[dummy1][dummy2].qk1!=9 && rs1[dumm
y1][dummy2].qk2!=9)){
if(rs1[dummy1][d
ummy2].qj1==p && rs1[dummy1][dummy2].qj2==q)
{
rs1[dumm
y1][dummy2].qj1=9;
rs1[dumm
y1][dummy2].qj2=9;
}
if(rs1[dummy1][d
ummy2].qk1==p && rs1[dummy1][dummy2].qk2==q)
{
rs1[dumm
y1][dummy2].qk1=9;
rs1[dumm
y1][dummy2].qk2=9;
}
if(rs1[dummy1][d
ummy2].qj1==9 && rs1[dummy1][dummy2].qj2==9 && rs1[dummy1][dummy2].qk1==9 && rs1
[dummy1][dummy2].qk2==9)
{
rs1[dumm
y1][dummy2].flag=1;
if(dummy
1!=2 && dummy1!=1)
{
if(dummy1==0 && dummy2>q)
{
rs1[dummy1][dummy2].execctr=-1;
busy[dummy1][dummy2]--;

}
else if(dummy1!=0)
{
rs1[dummy1][dummy2].execctr=-1;

}
}
stall[du
mmy1][dummy2]++;
}
}
}
}
//release the RS
rs1[p][q].vj=9;
rs1[p][q].vk=9;
rs1[p][q].qj1=9;
rs1[p][q].qk1=9;
rs1[p][q].qj2=9;
rs1[p][q].qk2=9;
rs1[p][q].freeornot=9;
rs1[p][q].execctr=0;
rs1[p][q].flag=9;
rs1[p][q].src1=9;
rs1[p][q].src2=9;
rs1[p][q].dest=9;
addcheck=1;
}
else
stall[p][q]++;
}
}
again2: printf("");
}
for(p=3;p<=4;p++)
{
for(q=0;q<8;q++)
{
if(rs1[p][q].flag==1 && p==3)
{
if((rs1[p][q].execctr)<3)
{
rs1[p][q].execctr=(rs1[p][q].execctr)+1;
checkexecu3=1;
busy[p][q]++;
}
else if(divcheck==9 && mulcheck==9 && addcheck==
9 && loadcheck==9 && (rs1[p][q].execctr)==3)
{ busy[p][q]++;
checkexecu3=0;
for(r=0;r<8;r++)
{
if(flrno[r].tag1 ==p && flrno[r]
.tag2 ==q)
{
flrno[r].busy=9;
flrno[r].tag1 =9;
flrno[r].tag2 =9;
}
}
for(dummy1=0;dummy1<5;dummy1++)
{
for(dummy2=0;dummy2<8;dummy2++)
{
if((rs1[dummy1][dummy2].
qj1!=9 && rs1[dummy1][dummy2].qj2!=9) || (rs1[dummy1][dummy2].qk1!=9 && rs1[dumm
y1][dummy2].qk2!=9)){
if(rs1[dummy1][d
ummy2].qj1==p && rs1[dummy1][dummy2].qj2==q)
{
rs1[dumm
y1][dummy2].qj1=9;
rs1[dumm
y1][dummy2].qj2=9;
}
if(rs1[dummy1][d
ummy2].qk1==p && rs1[dummy1][dummy2].qk2==q)
{
rs1[dumm
y1][dummy2].qk1=9;
rs1[dumm
y1][dummy2].qk2=9;
}
if(rs1[dummy1][d
ummy2].qj1==9 && rs1[dummy1][dummy2].qj2==9 && rs1[dummy1][dummy2].qk1==9 && rs1
[dummy1][dummy2].qk2==9)
{
rs1[dumm
y1][dummy2].flag=1;
}
}
}
}

//release the RS
rs1[p][q].vj=9;
rs1[p][q].vk=9;
rs1[p][q].qj1=9;
rs1[p][q].qk1=9;
rs1[p][q].qj2=9;
rs1[p][q].qk2=9;
rs1[p][q].freeornot=9;
rs1[p][q].execctr=0;
rs1[p][q].flag=9;
rs1[p][q].src1=9;
rs1[p][q].src2=9;
rs1[p][q].dest=9;
loadcheck=1;
}
else
stall[p][q]++;
}
else if(p==4 && q==0 && rs1[p][q].flag==1)
{
w=q+1;
rs1[p][q].vj=9;
rs1[p][q].vk=9;
rs1[p][q].qj1=9;
rs1[p][q].qk1=9;
rs1[p][q].qj2=9;
rs1[p][q].qk2=9;
rs1[p][q].useful=1;
rs1[p][q].freeornot=9;
rs1[p][q].execctr=0;
rs1[p][q].src1=9;
rs1[p][q].src2=9;
rs1[p][q].dest=9;
rs1[p][q].flag=9;

for(q1=0;q1<7;q1++)
{ if(q1<nRS[p])
{
rs1[p][q1].vj=rs1[p][q1+1].vj;
rs1[p][q1].vk=rs1[p][q1+1].vk;
rs1[p][q1].qj1=rs1[p][q1+1].qj1;
rs1[p][q1].qk1=rs1[p][q1+1].qk1;
rs1[p][q1].qj2=rs1[p][q1+1].qj2;
rs1[p][q1].qk2=rs1[p][q1+1].qk2;
rs1[p][q1].useful=rs1[p][q1+1].useful;
rs1[p][q1].freeornot=rs1[p][q1+1].freeor
not;
rs1[p][q1].execctr=rs1[p][q1+1].execctr;
rs1[p][q1].src1=rs1[p][q1+1].src1;
rs1[p][q1].src2=rs1[p][q1+1].src2;
rs1[p][q1].dest=rs1[p][q1+1].dest;
rs1[p][q1].flag=rs1[p][q1+1].flag;
}
}
if(rs1[p][q].flag==9)
checkexecu4=0;
busy[p][q]++;
}
else if(rs1[p][q].flag==9 && rs1[p][q].qj1!=9 && rs1[p][
q].qj2!=9 && p==4 && q==0)
{
stall[p][q]++;
}
else if(rs1[p][q].flag==1 && p==4 && q<8)
{
stall[p][q]++;
}
}
}

You might also like