Solved

Pipelined Datapath Simulation

Posted on 1998-02-01
11
445 Views
Last Modified: 2008-03-06
Hello.

I need some help with this one. Data should 'flow' through
all parts of the datapath, after EVERY instruction, including what are referred to as NOPs(No operation). This
program DOES show the flow, but NOT through the last 4
operations, which are NOPs. Each of the instructions causes
the "values" in the "registers" to move through each stage
of the pipeline. Here's a 2 cycle example:

What instruction to fetch next( 0=add, 1=addi, 2=sub,3=nop)?
What is the first register/immediate value?  
What is the second register/immediate value?
What is the third register/immediate value?  
********************* CYCLE 1 ***********************

PC = 1

IF/ID pipeline register:
 write_Register = 3, register1 = 4 register2 = 3, value = 3444

ID/EX pipeline register:
data_Read_1=x, data_Read_2=x, write_Register=x, register_1=x, register_2=x

EX/MEM pipeline register:
result=x, write_Register=x

MEM/WB pipeline register:
Result = x, write_Register = x

****************** End of Cycle 1 **************************

What instruction to fetch next( 0=add, 1=addi, 2=sub,3=nop)?
What is the first register/immediate value?  
What is the second register/immediate value?
 What is the third register/immediate value?  
********************* CYCLE 2 ***********************

PC = 2

IF/ID pipeline register:
 write_Register = 4, register1 = 4 register2 = 1, value = 3444

ID/EX pipeline register:
data_Read_1=4, read-data2=3, write_Register=3, register_1=4, register_2 = 3

EX/MEM pipeline register:
result=x, write_Register=x

MEM/WB pipeline register:
Result = x, write_Register = x

****************** End of Cycle 2 **************************

What instruction to fetch next( 0=add, 1=addi, 2=sub,3=nop)?

I would like to make a selection for NOPs. I would like to
modularize the code better than it presently is.

Here's the code.......................................

// 3a.C

// Jim Nowlin


/* This program simulates how a "pipelined" datapath works.
      Pipeline regiters are set up as 4 structures. Each pipeline
      register's structure is different, as each structure depends
      on information being passed to it from the previous stage.

      The following operations are to be performed:

      add      $3, $4, $3
      sub      $4, $4, $1
      add      $7, $5, $6
      sub      $19, $19, $4
      addi      $9, $8, 55
      sub      $12, $11, $4
      addi      $13, $20, -22
      sub      $25, $25, $5
      addi      $14, $25, 99
      sub      $24, $10, $8
      nop
      nop
      nop                  These 4 nops let other instructions go through the pipeline.
      nop


      This is a five-stage pipeline simulation. Each stage will pass information
      to the next stage's pipeline register. There are 10 instructions, followed
   by FOUR NOPs, so there should be 14 cycles total shown.
*/

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

#define TOTAL_CYCLES 14
#define TOTAL_REGISTERS 32
#define INITIAL_VALUE 0


struct IF_ID {

      int write_Register;
      int register1;
      int register2;
      int value;
      };

struct ID_EX  {

      int data_Read_1;
      int data_Read_2;
      int register_1;
      int register_2;
      int write_Register;
      };

struct EX_MEM  {

      int result;
      int write_Register;
      };

struct MEM_WB  {
      int Result;
      int write_Register;
      };



typedef struct IF_ID IF_STAGE;
typedef struct ID_EX ID_STAGE;
typedef struct EX_MEM EXMEM_STAGE;
typedef struct MEM_WB MEMWB_STAGE;

/* Function display_Datapath()to display the PC ( Program Counter )
            and the four-pipeline registers.  */

void display_Datapath(int PC, int fetch[TOTAL_CYCLES],
        IF_STAGE if_id[TOTAL_CYCLES],
        ID_STAGE id_ex[TOTAL_CYCLES], EXMEM_STAGE ex_mem[TOTAL_CYCLES],
        MEMWB_STAGE mem_wb[TOTAL_CYCLES]);

void Initialize_Registers(void);

// The following integer variables are used THROUGHOUT the program.

int Regs[TOTAL_REGISTERS];  // The 32 registers in this simulation
int PC = INITIAL_VALUE;

int main()
{

             // Declare and initialize variables for use by main() program.

             int fetch_instruction[TOTAL_CYCLES];
             int read_register1 = INITIAL_VALUE, read_register2 = INITIAL_VALUE;
             int write_register = INITIAL_VALUE, write_data = INITIAL_VALUE;
             int ALU_result = INITIAL_VALUE;


             // Following are the FOUR arrays of structs representing
             // the FOUR stages of a "pipelined" datapath.

             IF_STAGE if_id[TOTAL_CYCLES];

             ID_STAGE id_ex[TOTAL_CYCLES];

             EXMEM_STAGE ex_mem[TOTAL_CYCLES];

             MEMWB_STAGE mem_wb[TOTAL_CYCLES];


             // initialize simulated registers and PC HERE.......

             Initialize_Registers();



             while (PC < TOTAL_CYCLES)
                  {
                   while(1) { // begin while(1)
                                      // IF stage of pipeline; fetch the next instruction
                                      // into IF/ID register.

                   ++PC;  // incrememt the PC (program counter) HERE.
                   printf("What instruction to fetch next( 0=add, 1=addi, 2=sub, 3=nop)? ");
                   scanf("%d", &fetch_instruction[PC]);
                   if (fetch_instruction[PC] == 4) exit(0);

                   if(fetch_instruction[PC]!=3)   // As long as instruction is NOT a nop.
                         {
                          printf("What is the first register/immediate value?   ");
                          scanf("%d",  &if_id[PC].write_Register);
                          printf("What is the second register/immediate value?  ");
                          scanf("%d",  &if_id[PC].register1);
                          printf("What is the third register/immediate value?   ");
                          if(fetch_instruction[PC] !=1)
                               scanf("%d", &if_id[PC].register2);
                          else
                               scanf("%d", &if_id[PC].value);
                          printf("\n");


                        if (PC==1)    // print out cycle 1
                          {
                                display_Datapath(PC,fetch_instruction,if_id,id_ex,ex_mem,mem_wb);
                                break;  // stops the while(1) loop; fetch new register
                          }



/* ID stage of the pipeline; take info from IF/ID pipeline register */

      if(fetch_instruction[PC-1]!=3)  // As long as instruction is NOT a nop.
        {
              read_register1 = if_id[PC-1].register1;
              if(fetch_instruction[PC-1]!=1)  // exception for addi instruction.
                    read_register2 = if_id[PC-1].register2;

/* ID stage, fetch register and pass value to ID/EX pipeline register. */

id_ex[PC-1].data_Read_1 = Regs[if_id[PC-1].register1];

      if(fetch_instruction[PC-1]!=1)  // exception for addi instruction.
            id_ex[PC-1].data_Read_2 = Regs[if_id[PC-1].register2];
      else                    // address the addi instruction HERE.
            id_ex[PC-1].data_Read_2 = if_id[PC-1].value;

id_ex[PC-1].register_1 = read_register1;
if(fetch_instruction[PC-1]!=1)  // exception for addi instruction.
      id_ex[PC-1].register_2 = read_register2;
id_ex[PC-1].write_Register = if_id[PC-1].write_Register;

if(PC==2)    // print out cycle 2
  {
        display_Datapath(PC,fetch_instruction,if_id,id_ex,ex_mem,mem_wb);
        break;  // stops the while(1) loop; fetch new register
  }


}


/* EX stage of pipeline */

if(fetch_instruction[PC-2]!=3)  // As long as instruction is NOT a nop.
  {
       /* Forwarding control in the EX stage */

       if(ex_mem[PC-3].write_Register == id_ex[PC-2].register_1)  // EX hazard
                  id_ex[PC-2].data_Read_1 = ex_mem[PC-3].result;

       if(ex_mem[PC-3].write_Register == id_ex[PC-2].register_2)  // EX hazard
                  id_ex[PC-2].data_Read_2 = ex_mem[PC-3].result;



       if(mem_wb[PC-4].write_Register == id_ex[PC-2].register_1)  // MEM hazard
                  id_ex[PC-2].data_Read_1 = mem_wb[PC-4].Result;

       if(mem_wb[PC-4].write_Register == id_ex[PC-2].register_2)  // MEM hazard
                  id_ex[PC-2].data_Read_2 = mem_wb[PC-4].Result;


       /* take info from ID/EX pipeline register */

       if(fetch_instruction[PC-2] == 0 || fetch_instruction[PC-2] == 1)  // for add & addi
             ALU_result = id_ex[PC-2].data_Read_1 + id_ex[PC-2].data_Read_2;
       else
             ALU_result = id_ex[PC-2].data_Read_1 - id_ex[PC-2].data_Read_2;

       ex_mem[PC-2].result = ALU_result;  // into EX/MEM pipeline register
       ex_mem[PC-2].write_Register = id_ex[PC-2].write_Register;  // to EX/MEM pipeline


       if(PC==3)  // print out cycle 3
       {
                  display_Datapath(PC,fetch_instruction,if_id,id_ex,ex_mem,mem_wb);
                  break;  // stops the while(1) loop; fetch new register
             }

  }

/* MEM stage, take info from EX/MEM to MEM/WB pipeline register.  */

      if(fetch_instruction[PC-3]!=3)  // As long as instruction is NOT a nop.
       {
             mem_wb[PC-3].Result = ex_mem[PC-3].result;
             mem_wb[PC-3].write_Register = ex_mem[PC-3].write_Register;

            if(PC==4)   // print out the cycle 4
                  {
                  display_Datapath(PC,fetch_instruction,if_id,id_ex,ex_mem,mem_wb);
                  break;  // stops the while(1) loop; fetch new register
                  }

       }


/* WB stage pipelining, update the registers and data. */

      if(fetch_instruction[PC-4]!=3)  // As long as instruction is NOT a nop.
        {
              // return ID stage
        write_register = mem_wb[PC-4].write_Register;
        write_data = mem_wb[PC-4].Result;
        Regs[write_register] = write_data;  // update the register value here.
        }

            if(PC > 5)  // print out from cycle 5 through cycle 14.
         {
                  display_Datapath(PC,fetch_instruction,if_id,id_ex,ex_mem,mem_wb);
                  break;  // stops the while(1) loop; fetch new register
                  }

                                     } // end while (1)

                  } // end while (PC < 14)
             }

return 0;
}  // END MAIN FUNCTION


/* Function Initialize_Registers(), does just that. */
void Initialize_Registers(void)
{

int i = 0;
for (i=0; i < TOTAL_REGISTERS; ++i )
                        Regs[i] = i;
                        PC = 0;

}




/* Function to display Regs, PC and four-pipeline register.  */

void display_Datapath(int PC, int fetch[TOTAL_CYCLES],
        IF_STAGE if_id[TOTAL_CYCLES],
        ID_STAGE id_ex[TOTAL_CYCLES], EXMEM_STAGE ex_mem[TOTAL_CYCLES],
        MEMWB_STAGE mem_wb[TOTAL_CYCLES])

{

   clrscr();
      
      printf("********************* CYCLE %d ***********************\n", PC);

                  printf("\n");
                  printf("PC = %d\n\n", PC);

                  printf("IF/ID pipeline register:\n ");

        if(fetch[PC]!=3)
              {
printf("write_Register = %d, register1 = %d", if_id[PC].write_Register,if_id[PC].register1);

              if(fetch[PC]==1)  /* 'x' means nothing, for addi */
                    printf(" register2 = %d, value = %d\n\n"); //, if_id[PC].value);
              else
                    printf(" register2 = %d, value = %d\n\n", if_id[PC].register2);

              }  /// end if (fetch[PC]!=3)

        else
              printf("write_Register = x, register1 = x, register2 = x, value = x\n\n");

              printf("ID/EX pipeline register: \n");
              if( (PC-1) <= 0 || fetch[PC-1] == 3 )
                    printf("data_Read_1=x, data_Read_2=x, write_Register=x, register_1=x, register_2=x\n\n");
              else
                   {
                          printf("data_Read_1=%d, read-data2=%d, write_Register=%d, register_1=%d, ",
                          id_ex[PC-1].data_Read_1, id_ex[PC-1].data_Read_2, id_ex[PC-1].write_Register,
                          id_ex[PC-1].register_1);

                          if(fetch[PC-1] == 1)
                                    printf("register_2 = x\n\n");
                          else
                                    printf("register_2 = %d\n\n", id_ex[PC-1].register_2);

                   }  // end else

                  printf("EX/MEM pipeline register: \n");
                  if( (PC-2) <= 0 || fetch[PC-2] == 3 )
                        printf("result=x, write_Register=x\n\n");
                  else
                        printf("result = %d, write_Register = %d\n\n", ex_mem[PC-2].result,
                        ex_mem[PC-2].write_Register);

                  printf("MEM/WB pipeline register: \n");

                  if( (PC-3) <= 0 || fetch[PC-3] == 3 )
                        printf("Result = x, write_Register = x\n\n");
                  else
                        printf("result = %d, write_Register = %d\n\n", mem_wb[PC-3].Result,
                        mem_wb[PC-3].write_Register);

      printf("****************** End of Cycle %d ************************** \n\n",PC);

}


Well, I start at 200 points but I'm off to buy about 500
more. Sorry about the format once I paste it here. I really
wish EE would do something different.

Jim Nowlin

jnowlin@ma.ultranet.com
0
Comment
Question by:jnowlin
  • 6
  • 5
11 Comments
 
LVL 32

Expert Comment

by:jhance
ID: 1257142
In every case above, you have the line:

if(fetch_instruction[PC-4]!=3) // As long as instruction is NOT a nop.

This prevents any of the register values or outputs from being printed if the instruction is a NOP.  You seem to be asking why NOP does nothing but have gone to great lengths to make sure a NOP doesn't do anything.
0
 
LVL 32

Accepted Solution

by:
jhance earned 600 total points
ID: 1257143
OK, so you reject the answer but don't say why.
0
 

Author Comment

by:jnowlin
ID: 1257144
I'm basically in need of a second opinion, if you will, a second set of "eyes". Obviously, I don't do this for a living else I'd be in the unemployment line.

My next thought would be to put all of these functions( add, sub,
addi, NOP) into a switch statememt. This code is the result of someone else's help. I generally have difficulty looking over
someone else's source code. That's the case here. I have had, and still do to some extent, trouble grasping the problem to be solved here. I fully understand, after you pointed it out to me,
that there is nothing going to happen when a NOP instruction is issued. I was unaware that this person had left out the NOP case.

Now, I must finish up where he/she left off. As I said above, it is hard for me to follow the code. There are many instances of what an earlier instructor in C referred to as "Magic numbers."

i.e. PC-3, PC-4

I usually try to use macros ( #define 3_LEVELS_PRIOR 3 ), etc.
It makes for more understandable code and it's easier to see the
"flow" of the program, at least for me personally.

Jim

0
 

Author Comment

by:jnowlin
ID: 1257145
Adjusted points to 600
0
 
LVL 32

Expert Comment

by:jhance
ID: 1257146
I'm still not sure I understand what the question is.  I wonder if you might restate.  As I understood your original post, you wanted to know why the NOP didn't seem to do anything.  We've already covered that.  The only thing that I see remaining from the above dialog is what things like "PC-3, PC-4" mean.  These are just numbers that are used to get data from "memory" locations relative to the PC or program counter.

0
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
LVL 32

Expert Comment

by:jhance
ID: 1257147
To continue (I hit submit by mistake)...

Since you are simulation a pipeline, during each clock, you need to perform the right operation on each instruction in the pipline.  Remember, you've got a 5-stage pipeline going here and you always have 5 instructions moving through.  The way this program is structured, they are mapped as follows:

IF   PC
ID   PC-1
EX   PC-2
MEM  PC-3
WB   PC-4

Since data starts in the IF stage, and then is moved through ID->EX->MEM->WB, and the PC is always advancing, to look back and see the other instruction further along in the pipe, you use the [PC-1] as an index into the array which holds the CPU data.  In looking at the code, I think the NOP was coded wrong.  It's don't as though the NOP is a NOP to the simulation and not to the CPU.  In a real CPU, a NOP doesn't change anything but it does propogate through the CPU and ALL THE OTHER instuctions in the pipe continue to execute.
0
 

Author Comment

by:jnowlin
ID: 1257148
It really seems to me that you have a good grasp of what's going
on with this program/assignment. I only wish I had as concrete an understanding. I would appreciate it if you could help me with the coding of it. I understand C but only where I understand the problem to be solved, usually in an academic setting where (for me) there hasn't been any real challenging problem to solve (until now). I have had trouble understanding this solution from the start as well as the solution to the other assignment. Expert 'thui' was very instrumental in "opening my eyes" with regard to the 1st one.

If you choose not to help, I will most assuredly understand.
Thanks.

Jim
0
 
LVL 32

Expert Comment

by:jhance
ID: 1257149
Again, please help me understand what part of this question you need help with.  I'm not sure whether you are having trouble understanding the C code above (which, if I read what you have written above, didn't write but need to understand), or whether it's the pipelined CPU architecture and how it works.  I'm happy to go into greater detail on either (or both) of the above subjects but it would probably be better to target the actual question.
0
 

Author Comment

by:jnowlin
ID: 1257150
Hello jhance,

I understand, conceptually, how a pipelined datapath works on paper. This is perhaps the most difficult C code I've been asked to write up to this point in my short code-writing life.My 'main' question is:
The code above *works* for the first 10 'actual' instructions. It does *not* work for the remaining 4 NOPs. There is indeed NO case
made for the NOP instruction. While I understand the flow of data
through a pipelined datapath, I am unable to follow it in the C code above. Data continues to flow through the pipelined datapath
even when a non-instruction, NOP, is issued. This code does not do that.

Question:
Could you please help me complete the above code to include the case for a NOP instruction?

As I said before, it's difficult for me to follow someone else's code, unless it is thoroughly commented. The above code is not.
It would seem that incrementing the Program Counter(PC) alone would do it for a NOP, perhaps together with a slew of assignment
statememts re-assigning all of the variables to push them all through the pipeline.

Jim
0
 
LVL 32

Expert Comment

by:jhance
ID: 1257151
I've modified the program slightly to do what I think if the right thing for a NOP.  The pipeline still move along (as it should).

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

#define TOTAL_CYCLES 14
#define TOTAL_REGISTERS 32
#define INITIAL_VALUE 0


struct IF_ID {

int write_Register;
int register1;
int register2;
int value;
};

struct ID_EX {

int data_Read_1;
int data_Read_2;
int register_1;
int register_2;
int write_Register;
};

struct EX_MEM {

int result;
int write_Register;
};

struct MEM_WB {
int Result;
int write_Register;
};



typedef struct IF_ID IF_STAGE;
typedef struct ID_EX ID_STAGE;
typedef struct EX_MEM EXMEM_STAGE;
typedef struct MEM_WB MEMWB_STAGE;

/* Function display_Datapath()to display the PC ( Program Counter )
and the four-pipeline registers. */

void display_Datapath(int PC, int fetch[TOTAL_CYCLES],
IF_STAGE if_id[TOTAL_CYCLES],
ID_STAGE id_ex[TOTAL_CYCLES], EXMEM_STAGE ex_mem[TOTAL_CYCLES],
MEMWB_STAGE mem_wb[TOTAL_CYCLES]);

void Initialize_Registers(void);

// The following integer variables are used THROUGHOUT the program.

int Regs[TOTAL_REGISTERS]; // The 32 registers in this simulation
int PC = INITIAL_VALUE;

int main()
{

// Declare and initialize variables for use by main() program.

int fetch_instruction[TOTAL_CYCLES];
int read_register1 = INITIAL_VALUE, read_register2 = INITIAL_VALUE;
int write_register = INITIAL_VALUE, write_data = INITIAL_VALUE;
int ALU_result = INITIAL_VALUE;


// Following are the FOUR arrays of structs representing
// the FOUR stages of a "pipelined" datapath.

IF_STAGE if_id[TOTAL_CYCLES];

ID_STAGE id_ex[TOTAL_CYCLES];

EXMEM_STAGE ex_mem[TOTAL_CYCLES];

MEMWB_STAGE mem_wb[TOTAL_CYCLES];


// initialize simulated registers and PC HERE.......

Initialize_Registers();



while (PC < TOTAL_CYCLES)
{
      while(1) { // begin while(1)
             // IF stage of pipeline; fetch the next instruction
            // into IF/ID register.

            ++PC; // incrememt the PC (program counter) HERE.
            printf("What instruction to fetch next( 0=add, 1=addi, 2=sub, 3=nop, 4=quit)? ");
            scanf("%d", &fetch_instruction[PC]);

            // If given a 4, quit the simulation
            if (fetch_instruction[PC] == 4)
                  exit(0);

            if(1 /*fetch_instruction[PC]!=3 */) // As long as instruction is NOT a nop.
            {
                  if(fetch_instruction[PC] != 3){  // Don't need data for a nop
                        printf("What is the first register/immediate value? ");
                        scanf("%d", &if_id[PC].write_Register);
                        printf("What is the second register/immediate value? ");
                        scanf("%d", &if_id[PC].register1);
                        printf("What is the third register/immediate value? ");

                        if(fetch_instruction[PC] !=1)
                              scanf("%d", &if_id[PC].register2);
                        else
                              scanf("%d", &if_id[PC].value);

                        printf("\n");
                  }

                  if (PC==1) // print out cycle 1
                  {
                        display_Datapath(PC,fetch_instruction,if_id,id_ex,ex_mem,mem_wb);
                        break; // stops the while(1) loop; fetch new register
                  }



                  /* ID stage of the pipeline; take info from IF/ID pipeline register */

                  if(fetch_instruction[PC-1]!=3) // As long as instruction is NOT a nop.
                  {
                        read_register1 = if_id[PC-1].register1;
                        if(fetch_instruction[PC-1]!=1) // exception for addi instruction.
                              read_register2 = if_id[PC-1].register2;

                        /* ID stage, fetch register and pass value to ID/EX pipeline register. */
                        id_ex[PC-1].data_Read_1 = Regs[if_id[PC-1].register1];

                        if(fetch_instruction[PC-1]!=1) // exception for addi instruction.
                              id_ex[PC-1].data_Read_2 = Regs[if_id[PC-1].register2];
                        else // address the addi instruction HERE.
                              id_ex[PC-1].data_Read_2 = if_id[PC-1].value;

                        id_ex[PC-1].register_1 = read_register1;

                        if(fetch_instruction[PC-1]!=1) // exception for addi instruction.
                              id_ex[PC-1].register_2 = read_register2;

                        id_ex[PC-1].write_Register = if_id[PC-1].write_Register;

                  }

                  if(PC==2) // print out cycle 2
                  {
                        display_Datapath(PC,fetch_instruction,if_id,id_ex,ex_mem,mem_wb);
                        break; // stops the while(1) loop; fetch new register
                  }




                  /* EX stage of pipeline */
            
                  if(fetch_instruction[PC-2]!=3) // As long as instruction is NOT a nop.
                  {
                        /* Forwarding control in the EX stage */

                        if(ex_mem[PC-3].write_Register == id_ex[PC-2].register_1) // EX hazard
                              id_ex[PC-2].data_Read_1 = ex_mem[PC-3].result;

                        if(ex_mem[PC-3].write_Register == id_ex[PC-2].register_2) // EX hazard
                              id_ex[PC-2].data_Read_2 = ex_mem[PC-3].result;

                        if(mem_wb[PC-4].write_Register == id_ex[PC-2].register_1) // MEM hazard
                              id_ex[PC-2].data_Read_1 = mem_wb[PC-4].Result;

                        if(mem_wb[PC-4].write_Register == id_ex[PC-2].register_2) // MEM hazard
                              id_ex[PC-2].data_Read_2 = mem_wb[PC-4].Result;


                        /* take info from ID/EX pipeline register */

                        if(fetch_instruction[PC-2] == 0 || fetch_instruction[PC-2] == 1) // for add & addi
                              ALU_result = id_ex[PC-2].data_Read_1 + id_ex[PC-2].data_Read_2;
                        else
                              ALU_result = id_ex[PC-2].data_Read_1 - id_ex[PC-2].data_Read_2;

                        ex_mem[PC-2].result = ALU_result; // into EX/MEM pipeline register
                        ex_mem[PC-2].write_Register = id_ex[PC-2].write_Register; // to EX/MEM pipeline


                  }

                  if(PC==3) // print out cycle 3
                  {
                        display_Datapath(PC,fetch_instruction,if_id,id_ex,ex_mem,mem_wb);
                        break; // stops the while(1) loop; fetch new register
                  }

                  /* MEM stage, take info from EX/MEM to MEM/WB pipeline register. */

                  if(fetch_instruction[PC-3]!=3) // As long as instruction is NOT a nop.
                  {
                        mem_wb[PC-3].Result = ex_mem[PC-3].result;
                        mem_wb[PC-3].write_Register = ex_mem[PC-3].write_Register;

                  }

                  if(PC==4) // print out the cycle 4
                  {
                        display_Datapath(PC,fetch_instruction,if_id,id_ex,ex_mem,mem_wb);
                        break; // stops the while(1) loop; fetch new register
                  }


                  /* WB stage pipelining, update the registers and data. */

                  if(fetch_instruction[PC-4]!=3) // As long as instruction is NOT a nop.
                  {
                        // return ID stage
                        write_register = mem_wb[PC-4].write_Register;
                        write_data = mem_wb[PC-4].Result;
                        Regs[write_register] = write_data; // update the register value here.
                  }

                  if(PC > 5) // print out from cycle 5 through cycle 14.
                  {
                        display_Datapath(PC,fetch_instruction,if_id,id_ex,ex_mem,mem_wb);
                        break; // stops the while(1) loop; fetch new register
                  }

            } // end while (1)

      } // end while (PC < 14)
}

return 0;
} // END MAIN FUNCTION


/* Function Initialize_Registers(), does just that. */
void Initialize_Registers(void)
{

      int i = 0;
      for (i=0; i < TOTAL_REGISTERS; ++i )
            Regs[i] = i;

      PC = 0;

}




/* Function to display Regs, PC and four-pipeline register. */

void display_Datapath(int PC, int fetch[TOTAL_CYCLES],
IF_STAGE if_id[TOTAL_CYCLES],
ID_STAGE id_ex[TOTAL_CYCLES], EXMEM_STAGE ex_mem[TOTAL_CYCLES],
MEMWB_STAGE mem_wb[TOTAL_CYCLES])

{

//clrscr();

      printf("********************* CYCLE %d ***********************\n", PC);

      printf("\n");
      printf("PC = %d\n", PC);
      
      printf("IF/ID pipeline register:\n ");

      if(fetch[PC]!=3)
      {
            printf("write_Register = %d, register1 = %d", if_id[PC].write_Register,if_id[PC].register1);

            if(fetch[PC]==1) /* 'x' means nothing, for addi */
                  printf(" register2 = %d, value = %d\n"); //, if_id[PC].value);
            else
                  printf(" register2 = %d, value = %d\n", if_id[PC].register2);

      } /// end if (fetch[PC]!=3)

      else
            printf("write_Register = x, register1 = x, register2 = x, value = x\n");

      printf("ID/EX pipeline register: \n");
      if( (PC-1) <= 0 || fetch[PC-1] == 3 )
            printf("data_Read_1=x, data_Read_2=x, write_Register=x, register_1=x, register_2=x\n");
      else
      {
            printf("data_Read_1=%d, read-data2=%d, write_Register=%d, register_1=%d, ",
            id_ex[PC-1].data_Read_1, id_ex[PC-1].data_Read_2, id_ex[PC-1].write_Register,
            id_ex[PC-1].register_1);

            if(fetch[PC-1] == 1)
                  printf("register_2 = x\n");
            else
                  printf("register_2 = %d\n", id_ex[PC-1].register_2);

      } // end else

      printf("EX/MEM pipeline register: \n");
      if( (PC-2) <= 0 || fetch[PC-2] == 3 )
            printf("result=x, write_Register=x\n");
      else
            printf("result = %d, write_Register = %d\n", ex_mem[PC-2].result,

      ex_mem[PC-2].write_Register);

      printf("MEM/WB pipeline register: \n");

      if( (PC-3) <= 0 || fetch[PC-3] == 3 )
            printf("Result = x, write_Register = x\n");
      else
            printf("result = %d, write_Register = %d\n", mem_wb[PC-3].Result,

            mem_wb[PC-3].write_Register);

      printf("****************** End of Cycle %d ************************** \n\n",PC);

}
0
 

Author Comment

by:jnowlin
ID: 1257152
Thnaks jhance. It works fine! Sorry it took so long to get back
to you to grade your answer.

Jim
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use while-loops in the C programming language.

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now