[c] MIPS SIMULATION

Viewer

copydownloadembedprintName: MIPS SIMULATION
  1. #define _CRT_SECURE_NO_WARNINGS
  2. ////////////////libraries///////////////////
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <stdbool.h>
  7.  
  8. ////////////////defines////////////////////
  9. #define FILE_ERROR "Unable to open file"
  10. #define MAX 50
  11. #define DONE "end of simulation"
  12. #define J 'J'
  13. #define I 'I'
  14. #define R 'R'
  15. #define l 'l'
  16. #define CHECK_HEAD(head)\
  17. if(head == NULL)\
  18. {\
  19. printf(" function got invalid pointer, exit ");\
  20. exit(1);\
  21. }
  22.  
  23. ///////////////////////structs///////////////////////
  24. typedef struct {
  25.         char* instruction_address;
  26.         char* opcode;
  27.         char* operand1; //rd
  28.         char* operand2; //rs
  29.         char* operand3; //rt
  30.         char type;
  31. }Ins_sets;
  32. typedef struct {
  33.         Ins_sets i_f;
  34. }I_F;
  35.  
  36. typedef struct {
  37.         Ins_sets id;
  38.  
  39. }ID;
  40. typedef struct {
  41.         Ins_sets ex;
  42.  
  43. }EX;
  44. typedef struct {
  45.         Ins_sets mem;
  46. }MEM;
  47. typedef struct {
  48.         Ins_sets wb;
  49. }WB;
  50. typedef struct {
  51.         //statges
  52.         I_F i_f;
  53.         ID id;
  54.         EX ex;
  55.         MEM mem;
  56.         WB wb;
  57.         //REGISTERS
  58.  
  59. }PipeLine;
  60. ///////////////////function declaration///////////////////////
  61. Ins_sets* CreateInput(char* argv[]);
  62. void Simulation(char* argv[], Ins_sets*);
  63. char check_type(char*);
  64. bool is_WriteReg(char*);
  65. bool is_Jtype(char*);
  66. void inset_nop(Ins_sets*);
  67. bool jump(char, char*, char*);
  68. //////////////////////////main//////////////////////////
  69. int CYCLE = 0;
  70. int num_of_ins = 0;
  71. void main(int argc, char* argv[]) //notice argv[0] stand for the executable file's path
  72. {
  73.         if (argc < 3) //trace(i) & Forwarding & Branch resolution
  74.         {
  75.                 printf("Apparently not enough arguments were sent to main");
  76.                 exit(1);
  77.         }
  78.         Ins_sets* ins_sets = CreateInput(argv);
  79.         Simulation(argv, ins_sets);
  80.         system("pause");
  81.         free(ins_sets);
  82.         return  0;
  83. }
  84.  
  85. ///////////////////function definitionn///////////////////////
  86. Ins_sets* CreateInput(char* argv[])
  87. {
  88.         FILE* trace = fopen(argv[1], "r+");
  89.         if (trace == NULL) {
  90.                 printf(FILE_ERROR);
  91.                 exit(1);
  92.         }
  93.         char c;
  94.         int cycle = 0;
  95.         int size_of_txt;
  96.         int index_new_line = 0;
  97.         char instruction_address[MAX];
  98.         char opcode[MAX];
  99.         char operand1[MAX];
  100.         char operand2[MAX];
  101.         char operand3[MAX];
  102.         fseek(trace, 0, SEEK_END);
  103.         size_of_txt = ftell(trace);
  104.         // Extract characters from file and store in character c
  105.         fseek(trace, 0, SEEK_SET);
  106.         while (!feof(trace))
  107.         {
  108.                 c = fgetc(trace);
  109.                 if (== '\n')
  110.                         num_of_ins++;
  111.         }
  112.         //////////////////CREATE SETS INSRTUCTIONS////////////////// //       doto:free
  113.         fseek(trace, 0, SEEK_SET);
  114.         int i = 0;
  115.         Ins_sets* ins_sets = (Ins_sets*)calloc(num_of_ins, sizeof(Ins_sets));
  116.         while (ftell(trace) < size_of_txt)
  117.         {
  118.                 fseek(trace, index_new_line, SEEK_SET);
  119.                 fscanf(trace, "%s", instruction_address);//instruction_address
  120.                 ins_sets[i].instruction_address = (char*)malloc(strlen(instruction_address) + 1, sizeof(char));
  121.                 strcpy(ins_sets[i].instruction_address, instruction_address);
  122.                 fscanf(trace, "%s", opcode);//opcode
  123.                 ins_sets[i].type = check_type(opcode);
  124.                 ins_sets[i].opcode = (char*)malloc(strlen(opcode) + 1, sizeof(char));
  125.                 strcpy(ins_sets[i].opcode, opcode);
  126.                 fscanf(trace, "%s", operand1);//operand1
  127.                 ins_sets[i].operand1 = (char*)malloc(strlen(operand1) + 1, sizeof(char));
  128.                 strcpy(ins_sets[i].operand1, operand1);
  129.                 fscanf(trace, "%s", operand2);//operand2
  130.                 ins_sets[i].operand2 = (char*)malloc(strlen(operand2) + 1, sizeof(char));
  131.                 strcpy(ins_sets[i].operand2, operand2);
  132.                 fscanf(trace, "%s", operand3);//operand3
  133.                 ins_sets[i].operand3 = (char*)malloc(strlen(operand3) + 1, sizeof(char));
  134.                 strcpy(ins_sets[i].operand3, operand3);
  135.                 index_new_line = ftell(trace);
  136.                 i++;
  137.         }
  138.         if (fclose(trace) != 0)
  139.                 printf("error closing file");
  140.  
  141.         return ins_sets;
  142.  
  143.  
  144. }
  145.  
  146.  
  147. void Simulation(char* argv[], Ins_sets* ins_sets)
  148. {
  149.         bool flag = false;
  150.         int flag_b = 0;
  151.         int not_taken = 0;
  152.         bool Branch_resolution = atoi(argv[2]);               // Branch resolution
  153.         bool Forwarding = atoi(argv[3]); //Forwarding
  154.         PipeLine* pipeline = (PipeLine*)calloc(1, sizeof(PipeLine));
  155.  
  156.         if (!Branch_resolution && !Forwarding) { //00
  157.                 for (int i = 0; i < num_of_ins + 5; i++)
  158.                 {
  159.                         int counter = 0;
  160.  
  161.                         if (<= num_of_ins + 4) {
  162.                                 pipeline->wb.wb = pipeline->mem.mem;
  163.                         }
  164.                         if (<= num_of_ins + 3) {
  165.                                 pipeline->mem.mem = pipeline->ex.ex; //BRUNCH RESOLUTION IN MEM
  166.                                 if (< num_of_ins) {
  167.                                         // forward_detect stall the pipe for 1 cyclse and hold the pc
  168.                                         if ((ins_sets[i].type == J) && is_WriteReg(pipeline->id.id.opcode) && (!strcmp(pipeline->id.id.operand1, ins_sets[i].operand1) || !strcmp(pipeline->id.id.operand1, ins_sets[i].operand2)))
  169.                                         {
  170.                                                 counter = 2;
  171.                                         }
  172.                                         if (is_WriteReg(pipeline->mem.mem.opcode) && pipeline->mem.mem.type != J && (!strcmp(pipeline->mem.mem.operand1, ins_sets[i].operand2) || !strcmp(pipeline->mem.mem.operand1, ins_sets[i].operand3)) && atoi(pipeline->mem.mem.operand1) != 0)
  173.                                         {
  174.                                                 counter = 2;
  175.                                         }
  176.                                 }
  177.                         }
  178.                         if (<= num_of_ins + 2) {
  179.                                 if (pipeline->mem.mem.type == J && !not_taken)
  180.                                         inset_nop(&pipeline->ex.ex);
  181.                                 else  pipeline->ex.ex = pipeline->id.id;
  182.                                 if (< num_of_ins) {
  183.                                         // forward_detect condition - stall the pipe for 2 cyclse and hold the pc
  184.                                         if ((ins_sets[i].type == J) && is_WriteReg(pipeline->id.id.opcode) && (!strcmp(pipeline->id.id.operand1, ins_sets[i].operand1) || !strcmp(pipeline->id.id.operand1, ins_sets[i].operand2)))
  185.                                         {
  186.                                                 counter = 3;
  187.                                         }
  188.                                         if (is_WriteReg(pipeline->ex.ex.opcode) && pipeline->ex.ex.type != J && (!strcmp(pipeline->ex.ex.operand1, ins_sets[i].operand2) || !strcmp(pipeline->ex.ex.operand1, ins_sets[i].operand3))) // forward_detect stall the pipe for 2 cyclse and hold the pc
  189.                                         {
  190.                                                 counter = 3;
  191.                                         }
  192.                                 }
  193.                         }
  194.  
  195.                         if (<= num_of_ins + 1) {
  196.                                 if (pipeline->mem.mem.type == J && !not_taken) {
  197.                                         inset_nop(&pipeline->id.id);
  198.                                 }
  199.                                 else pipeline->id.id = pipeline->i_f.i_f;
  200.                                 if (< num_of_ins) {
  201.                                         // forward_detect condition - stall the pipe for 3 cyclse and hold the pc
  202.                                         if ((ins_sets[i].type == J) && is_WriteReg(pipeline->id.id.opcode) && (!strcmp(pipeline->id.id.operand1, ins_sets[i].operand1) || !strcmp(pipeline->id.id.operand1, ins_sets[i].operand2)))
  203.                                         {
  204.                                                 counter = 4;
  205.                                         }
  206.                                         if (is_WriteReg(pipeline->id.id.opcode) && pipeline->id.id.type != J && (!strcmp(pipeline->id.id.operand1, ins_sets[i].operand2) || !strcmp(pipeline->id.id.operand1, ins_sets[i].operand3))) // forward_detect condition - stall the pipe for 3 cyclse and hold the pc
  207.                                         {
  208.                                                 counter = 4;
  209.                                         }
  210.                                 }
  211.                         }
  212.                         if (<= num_of_ins) {          //INSRUCTION FETCH
  213.                                 if (pipeline->mem.mem.type == J && !not_taken) {
  214.                                         inset_nop(&pipeline->i_f.i_f);
  215.                                         flag_b = 3;
  216.                                 }
  217.                                 else if (< num_of_ins && flag_b)
  218.                                 {
  219.                                         i -= 3;
  220.                                         pipeline->i_f.i_f = ins_sets[i]; flag_b = 0;
  221.                                 }
  222.                                 else if (< num_of_ins && flag_b == 0)
  223.                                         pipeline->i_f.i_f = ins_sets[i];
  224.                         }
  225.                         //PRINTING STATE OF THE PIPE ACCORDING TO STALLS
  226.                         if (counter != 0) {
  227.                                 for (int j = 0; j < counter; j++)
  228.                                 {
  229.                                         if (<= num_of_ins + 3) printf("Cycle %d\n", ++CYCLE);
  230.                                         if (<= num_of_ins - 1)
  231.                                                 pipeline->mem.mem.type == J && !not_taken ? printf("FLUSH\n") : printf("Fetch instruction: %s %s %s %s %s\n", pipeline->i_f.i_f.instruction_address, pipeline->i_f.i_f.opcode, pipeline->i_f.i_f.operand1, pipeline->i_f.i_f.operand2, pipeline->i_f.i_f.operand3);
  232.                                         if (<= num_of_ins)
  233.                                                 pipeline->mem.mem.type == J && !not_taken ? printf("FLUSH\n") : printf("Decode instruction: %s %s %s %s %s\n", pipeline->id.id.instruction_address, pipeline->id.id.opcode, pipeline->id.id.operand1, pipeline->id.id.operand2, pipeline->id.id.operand3);
  234.                                         if (<= num_of_ins + 1)
  235.                                                 pipeline->mem.mem.type == J && !not_taken ? printf("FLUSH\n") : printf("Execute instruction: %s %s %s %s %s\n", pipeline->ex.ex.instruction_address, pipeline->ex.ex.opcode, pipeline->ex.ex.operand1, pipeline->ex.ex.operand2, pipeline->ex.ex.operand3);
  236.                                         if (<= num_of_ins + 2)
  237.                                                 printf("Memory instruction: %s %s %s %s %s\n", pipeline->mem.mem.instruction_address, pipeline->mem.mem.opcode, pipeline->mem.mem.operand1, pipeline->mem.mem.operand2, pipeline->mem.mem.operand3);
  238.                                         if (<= num_of_ins + 3)
  239.                                                 printf("Writeback instruction: %s %s %s %s %s\n", pipeline->wb.wb.instruction_address, pipeline->wb.wb.opcode, pipeline->wb.wb.operand1, pipeline->wb.wb.operand2, pipeline->wb.wb.operand3);
  240.                                         flag = jump(pipeline->i_f.i_f.type, pipeline->i_f.i_f.instruction_address, ins_sets[+ 1].instruction_address);
  241.                                         if (flag) not_taken++;
  242.                                         printf("\n");
  243.                                         pipeline->wb.wb = pipeline->mem.mem;
  244.                                         pipeline->mem.mem = pipeline->ex.ex;
  245.                                         pipeline->ex.ex = pipeline->id.id;
  246.                                         inset_nop(&pipeline->id.id);
  247.                                 }
  248.                         }
  249.                         else
  250.                         {
  251.                                 if (<= num_of_ins + 3) printf("Cycle %d\n", ++CYCLE);
  252.                                 if (<= num_of_ins - 1)
  253.                                         pipeline->mem.mem.type == J && !not_taken ? printf("FLUSH\n") : printf("Fetch instruction: %s %s %s %s %s\n", pipeline->i_f.i_f.instruction_address, pipeline->i_f.i_f.opcode, pipeline->i_f.i_f.operand1, pipeline->i_f.i_f.operand2, pipeline->i_f.i_f.operand3);
  254.                                 if (<= num_of_ins)
  255.                                         pipeline->mem.mem.type == J && !not_taken ? printf("FLUSH\n") : printf("Decode instruction: %s %s %s %s %s\n", pipeline->id.id.instruction_address, pipeline->id.id.opcode, pipeline->id.id.operand1, pipeline->id.id.operand2, pipeline->id.id.operand3);
  256.                                 if (<= num_of_ins + 1)
  257.                                         pipeline->mem.mem.type == J && !not_taken ? printf("FLUSH\n") : printf("Execute instruction: %s %s %s %s %s\n", pipeline->ex.ex.instruction_address, pipeline->ex.ex.opcode, pipeline->ex.ex.operand1, pipeline->ex.ex.operand2, pipeline->ex.ex.operand3);
  258.                                 if (<= num_of_ins + 2)
  259.                                         printf("Memory instruction: %s %s %s %s %s\n", pipeline->mem.mem.instruction_address, pipeline->mem.mem.opcode, pipeline->mem.mem.operand1, pipeline->mem.mem.operand2, pipeline->mem.mem.operand3);
  260.                                 if (<= num_of_ins + 3)
  261.                                         printf("Writeback instruction: %s %s %s %s %s\n", pipeline->wb.wb.instruction_address, pipeline->wb.wb.opcode, pipeline->wb.wb.operand1, pipeline->wb.wb.operand2, pipeline->wb.wb.operand3);
  262.                                 flag = jump(pipeline->i_f.i_f.type, pipeline->i_f.i_f.instruction_address, ins_sets[+ 1].instruction_address);
  263.                                 if (flag) not_taken++;
  264.                                 printf("\n");
  265.                         }
  266.  
  267.                 }
  268.                 printf("\n CPI = %f\n", (float)CYCLE / num_of_ins);
  269.         }
  270.         /////////////////////////////////////////////////////////////////////////////////////////////////////
  271.  
  272.         else if (Branch_resolution && !Forwarding)  //10
  273.         {
  274.                 for (int i = 0; i < num_of_ins + 5; i++)
  275.                 {
  276.                         int counter = 0;
  277.  
  278.                         if (<= num_of_ins + 4) {
  279.                                 pipeline->wb.wb = pipeline->mem.mem;
  280.                         }
  281.                         if (<= num_of_ins + 3) {
  282.                                 pipeline->mem.mem = pipeline->ex.ex;
  283.                                 if (< num_of_ins) {
  284.                                         // forward_detect stall the pipe for 1 cyclse and hold the pc
  285.                                         if ((ins_sets[i].type == J) && is_WriteReg(pipeline->id.id.opcode) && (!strcmp(pipeline->id.id.operand1, ins_sets[i].operand1) || !strcmp(pipeline->id.id.operand1, ins_sets[i].operand2)))
  286.                                         {
  287.                                                 counter = 2;
  288.                                         }
  289.                                         if (is_WriteReg(pipeline->mem.mem.opcode) && pipeline->mem.mem.type != J && (!strcmp(pipeline->mem.mem.operand1, ins_sets[i].operand2) || !strcmp(pipeline->mem.mem.operand1, ins_sets[i].operand3)) && atoi(pipeline->mem.mem.operand1) !=0)
  290.                                         {
  291.                                                 counter = 2;
  292.                                         }
  293.                                 }
  294.                         }
  295.                         if (<= num_of_ins + 2) {
  296.                                 pipeline->ex.ex = pipeline->id.id;
  297.                                 if (< num_of_ins) {
  298.                                         // forward_detect condition - stall the pipe for 2 cyclse and hold the pc
  299.                                         if ((ins_sets[i].type == J) && is_WriteReg(pipeline->id.id.opcode) && (!strcmp(pipeline->id.id.operand1, ins_sets[i].operand1) || !strcmp(pipeline->id.id.operand1, ins_sets[i].operand2)))
  300.                                         {
  301.                                                 counter = 3;
  302.                                         }
  303.                                         if (is_WriteReg(pipeline->ex.ex.opcode) && pipeline->ex.ex.type != J && (!strcmp(pipeline->ex.ex.operand1, ins_sets[i].operand2) || !strcmp(pipeline->ex.ex.operand1, ins_sets[i].operand3)) && atoi(pipeline->ex.ex.operand1)!=0) // forward_detect stall the pipe for 2 cyclse and hold the pc
  304.                                         {
  305.                                                 counter = 3;
  306.                                         }
  307.                                 }
  308.                         }
  309.  
  310.                         if (<= num_of_ins + 1) {
  311.                                 pipeline->id.id = pipeline->i_f.i_f;  //BRUNCH RESOLUTION IN ID
  312.                                 if (< num_of_ins) {
  313.                                         // forward_detect condition - stall the pipe for 3 cyclse and hold the pc
  314.                                         if ((ins_sets[i].type == J) && is_WriteReg(pipeline->id.id.opcode) && (!strcmp(pipeline->id.id.operand1, ins_sets[i].operand1) || !strcmp(pipeline->id.id.operand1, ins_sets[i].operand2)))
  315.                                         {
  316.                                                 counter = 4;
  317.                                         }
  318.                                         if (is_WriteReg(pipeline->id.id.opcode) && pipeline->id.id.type != J && (!strcmp(pipeline->id.id.operand1, ins_sets[i].operand2) || !strcmp(pipeline->id.id.operand1, ins_sets[i].operand3)) && atoi(pipeline->id.id.operand1)!=0)
  319.                                         {
  320.                                                 counter = 4;
  321.                                         }
  322.                                 }
  323.                         }
  324.                         if (<= num_of_ins) {          //INSRUCTION FETCH
  325.                                 if (pipeline->id.id.type == J && !not_taken) {
  326.                                         inset_nop(&pipeline->i_f.i_f);
  327.                                         flag_b = 1;
  328.                                 }
  329.                                 else if (< num_of_ins && flag_b == 1)
  330.                                 {
  331.                                         i--;
  332.                                         pipeline->i_f.i_f = ins_sets[i]; flag_b = 0;
  333.                                 }
  334.                                 else if (< num_of_ins && flag_b == 0)
  335.                                         pipeline->i_f.i_f = ins_sets[i];
  336.                         }
  337.                         //PRINTING STATE OF THE PIPE ACCORDING TO STALLS
  338.                         if (counter != 0) {
  339.                                 for (int j = 0; j < counter; j++)
  340.                                 {
  341.                                         if (<= num_of_ins + 3) printf("Cycle %d\n", ++CYCLE);
  342.                                         if (<= num_of_ins - 1)
  343.                                                 pipeline->id.id.type == J && !not_taken ? printf("FLUSH\n") : printf("Fetch instruction: %s %s %s %s %s\n", pipeline->i_f.i_f.instruction_address, pipeline->i_f.i_f.opcode, pipeline->i_f.i_f.operand1, pipeline->i_f.i_f.operand2, pipeline->i_f.i_f.operand3);
  344.                                         if (<= num_of_ins)
  345.                                          printf("Decode instruction: %s %s %s %s %s\n", pipeline->id.id.instruction_address, pipeline->id.id.opcode, pipeline->id.id.operand1, pipeline->id.id.operand2, pipeline->id.id.operand3);
  346.                                         if (<= num_of_ins + 1)
  347.                                                 printf("Execute instruction: %s %s %s %s %s\n", pipeline->ex.ex.instruction_address, pipeline->ex.ex.opcode, pipeline->ex.ex.operand1, pipeline->ex.ex.operand2, pipeline->ex.ex.operand3);
  348.                                         if (<= num_of_ins + 2)
  349.                                                 printf("Memory instruction: %s %s %s %s %s\n", pipeline->mem.mem.instruction_address, pipeline->mem.mem.opcode, pipeline->mem.mem.operand1, pipeline->mem.mem.operand2, pipeline->mem.mem.operand3);
  350.                                         if (<= num_of_ins + 3)
  351.                                                 printf("Writeback instruction: %s %s %s %s %s\n", pipeline->wb.wb.instruction_address, pipeline->wb.wb.opcode, pipeline->wb.wb.operand1, pipeline->wb.wb.operand2, pipeline->wb.wb.operand3);
  352.                                         flag = jump(pipeline->i_f.i_f.type, pipeline->i_f.i_f.instruction_address, ins_sets[+ 1].instruction_address);
  353.                                         if (flag) not_taken++;
  354.                                         printf("\n");
  355.                                         pipeline->wb.wb = pipeline->mem.mem;
  356.                                         pipeline->mem.mem = pipeline->ex.ex;
  357.                                         pipeline->ex.ex = pipeline->id.id;
  358.                                         inset_nop(&pipeline->id.id);
  359.                                 }
  360.                         }
  361.                         else
  362.                         {
  363.                                 if (<= num_of_ins + 3) printf("Cycle %d\n", ++CYCLE);
  364.                                 if (<= num_of_ins - 1)
  365.                                         pipeline->id.id.type == J && !not_taken ? printf("FLUSH\n") : printf("Fetch instruction: %s %s %s %s %s\n", pipeline->i_f.i_f.instruction_address, pipeline->i_f.i_f.opcode, pipeline->i_f.i_f.operand1, pipeline->i_f.i_f.operand2, pipeline->i_f.i_f.operand3);
  366.                                 if (<= num_of_ins)
  367.                                          printf("Decode instruction: %s %s %s %s %s\n", pipeline->id.id.instruction_address, pipeline->id.id.opcode, pipeline->id.id.operand1, pipeline->id.id.operand2, pipeline->id.id.operand3);
  368.                                 if (<= num_of_ins + 1)
  369.                                          printf("Execute instruction: %s %s %s %s %s\n", pipeline->ex.ex.instruction_address, pipeline->ex.ex.opcode, pipeline->ex.ex.operand1, pipeline->ex.ex.operand2, pipeline->ex.ex.operand3);
  370.                                 if (<= num_of_ins + 2)
  371.                                         printf("Memory instruction: %s %s %s %s %s\n", pipeline->mem.mem.instruction_address, pipeline->mem.mem.opcode, pipeline->mem.mem.operand1, pipeline->mem.mem.operand2, pipeline->mem.mem.operand3);
  372.                                 if (<= num_of_ins + 3)
  373.                                         printf("Writeback instruction: %s %s %s %s %s\n", pipeline->wb.wb.instruction_address, pipeline->wb.wb.opcode, pipeline->wb.wb.operand1, pipeline->wb.wb.operand2, pipeline->wb.wb.operand3);
  374.                                 flag = jump(pipeline->i_f.i_f.type, pipeline->i_f.i_f.instruction_address, ins_sets[+ 1].instruction_address);
  375.                                 if (flag) not_taken++;
  376.                                 printf("\n");
  377.                         }
  378.                
  379.                 }
  380.                 printf("\n CPI = %f\n", (float)CYCLE / num_of_ins);
  381.         }
  382.         ///////////////////////////////////////////////////////////////////////////////////////////////////
  383.         else if (!Branch_resolution && Forwarding) // 01
  384.         {
  385.                 for (int i = 0; i < num_of_ins + 5; i++)
  386.                 {
  387.                         int counter = 0;
  388.  
  389.                         if (<= num_of_ins + 4) {
  390.                                 pipeline->wb.wb = pipeline->mem.mem;
  391.                         }
  392.                         if (<= num_of_ins + 3) {
  393.                                 pipeline->mem.mem = pipeline->ex.ex; //BRUNCH RESOLUTION IN MEM
  394.  
  395.                         }
  396.                         if (<= num_of_ins + 2) {
  397.                                 if (pipeline->mem.mem.type == J && !not_taken)
  398.                                         inset_nop(&pipeline->ex.ex);
  399.                                 else  pipeline->ex.ex = pipeline->id.id;
  400.  
  401.                         }
  402.  
  403.                         if (<= num_of_ins + 1) {
  404.                                 if (pipeline->mem.mem.type == J && !not_taken) {
  405.                                         inset_nop(&pipeline->id.id);
  406.                                 }
  407.                                 else pipeline->id.id = pipeline->i_f.i_f;
  408.                                 if (< num_of_ins) {
  409.                                        
  410.                                         //ASSUMIMG UNCASUAL FORWARDING NEED 
  411.                                         if (is_WriteReg(ins_sets[i].opcode) && pipeline->id.id.type == l && (!strcmp(pipeline->id.id.operand1, ins_sets[i].operand2) || !strcmp(pipeline->id.id.operand1, ins_sets[i].operand3) && atoi(pipeline->id.id.operand1)!=0)) // forward_detect condition - stall the pipe for 3 cyclse and hold the pc
  412.                                         {
  413.                                                 counter = 2;
  414.                                         }
  415.                                 }
  416.                         }
  417.                         if (<= num_of_ins) {          //INSRUCTION FETCH
  418.                                 if (pipeline->mem.mem.type == J && !not_taken) {
  419.                                         inset_nop(&pipeline->i_f.i_f);
  420.                                         flag_b = 3;
  421.                                 }
  422.                                 else if (< num_of_ins && flag_b)
  423.                                 {
  424.                                         i -= 3;
  425.                                         pipeline->i_f.i_f = ins_sets[i]; flag_b = 0;
  426.                                 }
  427.                                 else if (< num_of_ins && flag_b == 0)
  428.                                         pipeline->i_f.i_f = ins_sets[i];
  429.                         }
  430.                         //PRINTING STATE OF THE PIPE ACCORDING TO STALLS
  431.                         if (counter != 0) {
  432.                                 for (int j = 0; j < counter; j++)
  433.                                 {
  434.                                         if (<= num_of_ins + 3) printf("Cycle %d\n", ++CYCLE);
  435.                                         if (<= num_of_ins - 1)
  436.                                                 pipeline->mem.mem.type == J && !not_taken ? printf("FLUSH\n") : printf("Fetch instruction: %s %s %s %s %s\n", pipeline->i_f.i_f.instruction_address, pipeline->i_f.i_f.opcode, pipeline->i_f.i_f.operand1, pipeline->i_f.i_f.operand2, pipeline->i_f.i_f.operand3);
  437.                                         if (<= num_of_ins)
  438.                                                 pipeline->mem.mem.type == J && !not_taken ? printf("FLUSH\n") : printf("Decode instruction: %s %s %s %s %s\n", pipeline->id.id.instruction_address, pipeline->id.id.opcode, pipeline->id.id.operand1, pipeline->id.id.operand2, pipeline->id.id.operand3);
  439.                                         if (<= num_of_ins + 1)
  440.                                                 pipeline->mem.mem.type == J && !not_taken ? printf("FLUSH\n") : printf("Execute instruction: %s %s %s %s %s\n", pipeline->ex.ex.instruction_address, pipeline->ex.ex.opcode, pipeline->ex.ex.operand1, pipeline->ex.ex.operand2, pipeline->ex.ex.operand3);
  441.                                         if (<= num_of_ins + 2)
  442.                                                 printf("Memory instruction: %s %s %s %s %s\n", pipeline->mem.mem.instruction_address, pipeline->mem.mem.opcode, pipeline->mem.mem.operand1, pipeline->mem.mem.operand2, pipeline->mem.mem.operand3);
  443.                                         if (<= num_of_ins + 3)
  444.                                                 printf("Writeback instruction: %s %s %s %s %s\n", pipeline->wb.wb.instruction_address, pipeline->wb.wb.opcode, pipeline->wb.wb.operand1, pipeline->wb.wb.operand2, pipeline->wb.wb.operand3);
  445.                                         flag = jump(pipeline->i_f.i_f.type, pipeline->i_f.i_f.instruction_address, ins_sets[+ 1].instruction_address);
  446.                                         if (flag) not_taken++;
  447.                                         printf("\n");
  448.                                         if (== 0) {
  449.                                                 pipeline->wb.wb = pipeline->mem.mem;
  450.                                                 pipeline->mem.mem = pipeline->ex.ex;
  451.                                                 pipeline->ex.ex = pipeline->id.id;
  452.                                                 inset_nop(&pipeline->id.id);
  453.                                         }
  454.  
  455.                                 }
  456.                         }
  457.                         else
  458.                         {
  459.                                 if (<= num_of_ins + 3) printf("Cycle %d\n", ++CYCLE);
  460.                                 if (<= num_of_ins - 1)
  461.                                         pipeline->mem.mem.type == J && !not_taken ? printf("FLUSH\n") : printf("Fetch instruction: %s %s %s %s %s\n", pipeline->i_f.i_f.instruction_address, pipeline->i_f.i_f.opcode, pipeline->i_f.i_f.operand1, pipeline->i_f.i_f.operand2, pipeline->i_f.i_f.operand3);
  462.                                 if (<= num_of_ins)
  463.                                         pipeline->mem.mem.type == J && !not_taken ? printf("FLUSH\n") : printf("Decode instruction: %s %s %s %s %s\n", pipeline->id.id.instruction_address, pipeline->id.id.opcode, pipeline->id.id.operand1, pipeline->id.id.operand2, pipeline->id.id.operand3);
  464.                                 if (<= num_of_ins + 1)
  465.                                         pipeline->mem.mem.type == J && !not_taken ? printf("FLUSH\n") : printf("Execute instruction: %s %s %s %s %s\n", pipeline->ex.ex.instruction_address, pipeline->ex.ex.opcode, pipeline->ex.ex.operand1, pipeline->ex.ex.operand2, pipeline->ex.ex.operand3);
  466.                                 if (<= num_of_ins + 2)
  467.                                         printf("Memory instruction: %s %s %s %s %s\n", pipeline->mem.mem.instruction_address, pipeline->mem.mem.opcode, pipeline->mem.mem.operand1, pipeline->mem.mem.operand2, pipeline->mem.mem.operand3);
  468.                                 if (<= num_of_ins + 3)
  469.                                         printf("Writeback instruction: %s %s %s %s %s\n", pipeline->wb.wb.instruction_address, pipeline->wb.wb.opcode, pipeline->wb.wb.operand1, pipeline->wb.wb.operand2, pipeline->wb.wb.operand3);
  470.                                 flag = jump(pipeline->i_f.i_f.type, pipeline->i_f.i_f.instruction_address, ins_sets[+ 1].instruction_address);
  471.                                 if (flag) not_taken++;
  472.                                 printf("\n");
  473.                         }
  474.  
  475.                 }
  476.                 printf("\n CPI = %f\n", (float)CYCLE / num_of_ins);
  477.         }
  478.  
  479.         else if (Branch_resolution && Forwarding) // 11
  480.         {
  481.                 for (int i = 0; i < num_of_ins + 5; i++)
  482.                 {
  483.                         int counter = 0;
  484.  
  485.                         if (<= num_of_ins + 4) {
  486.                                 pipeline->wb.wb = pipeline->mem.mem;
  487.                         }
  488.                         if (<= num_of_ins + 3) {
  489.                                 pipeline->mem.mem = pipeline->ex.ex; //BRUNCH RESOLUTION IN MEM
  490.  
  491.                         }
  492.                         if (<= num_of_ins + 2) {
  493.                                 pipeline->ex.ex = pipeline->id.id;
  494.                         }
  495.  
  496.                         if (<= num_of_ins + 1) {
  497.                                  pipeline->id.id = pipeline->i_f.i_f;
  498.                                 if (< num_of_ins) {
  499.                                        
  500.                                         if (is_WriteReg(ins_sets[i].opcode) && pipeline->id.id.type == l && (!strcmp(pipeline->id.id.operand1, ins_sets[i].operand2) || !strcmp(pipeline->id.id.operand1, ins_sets[i].operand3) && (atoi(pipeline->id.id.operand1) != 0))) // forward_detect condition - stall the pipe for 3 cyclse and hold the pc
  501.                                         {
  502.                                                 counter = 2;
  503.                                         }
  504.                                 }
  505.                         }
  506.                         if (<= num_of_ins) {          //INSRUCTION FETCH
  507.                                 if (pipeline->id.id.type == J && !not_taken) {
  508.                                         inset_nop(&pipeline->i_f.i_f);
  509.                                         flag_b = 1;
  510.                                 }
  511.                                 else if (< num_of_ins && flag_b)
  512.                                 {
  513.                                         i--;
  514.                                         pipeline->i_f.i_f = ins_sets[i]; flag_b = 0;
  515.                                 }
  516.                                 else if (< num_of_ins && flag_b == 0)
  517.                                         pipeline->i_f.i_f = ins_sets[i];
  518.                         }
  519.                         //PRINTING STATE OF THE PIPE ACCORDING TO STALLS
  520.                         if (counter != 0) {
  521.                                 for (int j = 0; j < counter; j++)
  522.                                 {
  523.                                         if (<= num_of_ins + 3) printf("Cycle %d\n", ++CYCLE);
  524.                                         if (<= num_of_ins - 1)
  525.                                                 pipeline->id.id.type == J && !not_taken ? printf("FLUSH\n") : printf("Fetch instruction: %s %s %s %s %s\n", pipeline->i_f.i_f.instruction_address, pipeline->i_f.i_f.opcode, pipeline->i_f.i_f.operand1, pipeline->i_f.i_f.operand2, pipeline->i_f.i_f.operand3);
  526.                                         if (<= num_of_ins)
  527.                                                 printf("Decode instruction: %s %s %s %s %s\n", pipeline->id.id.instruction_address, pipeline->id.id.opcode, pipeline->id.id.operand1, pipeline->id.id.operand2, pipeline->id.id.operand3);
  528.                                         if (<= num_of_ins + 1)
  529.                                             printf("Execute instruction: %s %s %s %s %s\n", pipeline->ex.ex.instruction_address, pipeline->ex.ex.opcode, pipeline->ex.ex.operand1, pipeline->ex.ex.operand2, pipeline->ex.ex.operand3);
  530.                                         if (<= num_of_ins + 2)
  531.                                                 printf("Memory instruction: %s %s %s %s %s\n", pipeline->mem.mem.instruction_address, pipeline->mem.mem.opcode, pipeline->mem.mem.operand1, pipeline->mem.mem.operand2, pipeline->mem.mem.operand3);
  532.                                         if (<= num_of_ins + 3)
  533.                                                 printf("Writeback instruction: %s %s %s %s %s\n", pipeline->wb.wb.instruction_address, pipeline->wb.wb.opcode, pipeline->wb.wb.operand1, pipeline->wb.wb.operand2, pipeline->wb.wb.operand3);
  534.                                         flag = jump(pipeline->i_f.i_f.type, pipeline->i_f.i_f.instruction_address, ins_sets[+ 1].instruction_address);
  535.                                         if (flag) not_taken++;
  536.                                         printf("\n");
  537.                                         if (== 0) {
  538.                                                 pipeline->wb.wb = pipeline->mem.mem;
  539.                                                 pipeline->mem.mem = pipeline->ex.ex;
  540.                                                 pipeline->ex.ex = pipeline->id.id;
  541.                                                 inset_nop(&pipeline->id.id);
  542.                                         }
  543.  
  544.                                 }
  545.                         }
  546.                         else
  547.                         {
  548.                                 if (<= num_of_ins + 3) printf("Cycle %d\n", ++CYCLE);
  549.                                 if (<= num_of_ins - 1)
  550.                                         pipeline->id.id.type == J && !not_taken ? printf("FLUSH\n") : printf("Fetch instruction: %s %s %s %s %s\n", pipeline->i_f.i_f.instruction_address, pipeline->i_f.i_f.opcode, pipeline->i_f.i_f.operand1, pipeline->i_f.i_f.operand2, pipeline->i_f.i_f.operand3);
  551.                                 if (<= num_of_ins)
  552.                                     printf("Decode instruction: %s %s %s %s %s\n", pipeline->id.id.instruction_address, pipeline->id.id.opcode, pipeline->id.id.operand1, pipeline->id.id.operand2, pipeline->id.id.operand3);
  553.                                 if (<= num_of_ins + 1)
  554.                                     printf("Execute instruction: %s %s %s %s %s\n", pipeline->ex.ex.instruction_address, pipeline->ex.ex.opcode, pipeline->ex.ex.operand1, pipeline->ex.ex.operand2, pipeline->ex.ex.operand3);
  555.                                 if (<= num_of_ins + 2)
  556.                                         printf("Memory instruction: %s %s %s %s %s\n", pipeline->mem.mem.instruction_address, pipeline->mem.mem.opcode, pipeline->mem.mem.operand1, pipeline->mem.mem.operand2, pipeline->mem.mem.operand3);
  557.                                 if (<= num_of_ins + 3)
  558.                                         printf("Writeback instruction: %s %s %s %s %s\n", pipeline->wb.wb.instruction_address, pipeline->wb.wb.opcode, pipeline->wb.wb.operand1, pipeline->wb.wb.operand2, pipeline->wb.wb.operand3);
  559.                                 flag = jump(pipeline->i_f.i_f.type, pipeline->i_f.i_f.instruction_address, ins_sets[+ 1].instruction_address);
  560.                                 if (flag) not_taken++;
  561.                                 printf("\n");
  562.                         }
  563.  
  564.                 }
  565.                 printf("\n CPI = %f\n", (float)CYCLE / num_of_ins);
  566.  
  567.         }
  568.         free(pipeline);
  569. }
  570.  
  571.  
  572. char check_type(char* opcode)
  573. {
  574.         //add, sub, or , and, addi, subi, ori, andi, lw, sw, j, beq, bneq
  575.         if (!strcmp(opcode, "j") || !strcmp(opcode, "beq") || !strcmp(opcode, "bneq"))
  576.                 return  J;
  577.         if (!strcmp(opcode, "addi") || !strcmp(opcode, "subi") || !strcmp(opcode, "ori") || !strcmp(opcode, "andi") || !strcmp(opcode, "sw"))
  578.                 return  I;
  579.         if (!strcmp(opcode, "add") || !strcmp(opcode, "sub") || !strcmp(opcode, "or") || !strcmp(opcode, "and"))
  580.                 return  R;
  581.         if (!strcmp(opcode, "lw"))
  582.                 return  l;
  583. }
  584. void inset_nop(Ins_sets* ins)
  585. {
  586.         ins->instruction_address = NULL;
  587.         ins->opcode = NULL;
  588.         ins->operand1 = NULL;
  589.         ins->operand2 = NULL;
  590.         ins->operand3 = NULL;
  591.         ins->type = 'k';
  592. }
  593. bool is_WriteReg(char* opcode)
  594. {
  595.         if (opcode) {
  596.                 if (!strcmp(opcode, "addi") || !strcmp(opcode, "subi") || !strcmp(opcode, "ori") || !strcmp(opcode, "andi"))
  597.                         return  true;
  598.                 if (!strcmp(opcode, "add") || !strcmp(opcode, "sub") || !strcmp(opcode, "or") || !strcmp(opcode, "and") || !strcmp(opcode, "lw"))
  599.                         return  true;
  600.                 if (!strcmp(opcode, "bneq") || !strcmp(opcode, "beq") || !strcmp(opcode, "j"))
  601.                         return  true;
  602.         }
  603.         return false;
  604. }
  605. bool is_Jtype(char* opcode)
  606. {
  607.  return (!strcmp(opcode, "bneq") || !strcmp(opcode, "beq") || !strcmp(opcode, "j"));
  608. }
  609. bool jump(char type, char* fetch_instruction_address, char* PC_instruction_address) {
  610.         return (type == J && atoi(fetch_instruction_address) + 4 == atoi(PC_instruction_address)); // IF TRUE DO NOT JUMP 
  611. }
  612.  
  613.  

Editor

You can edit this paste and save as new:


File Description
  • MIPS SIMULATION
  • Paste Code
  • 14 Jun-2021
  • 27.03 Kb
You can Share it: