├── Pipelined_Processor_Design ├── bincode.rom ├── pipelined_cpu_frwding_prediction.v └── testbench.v ├── README.md └── Superscaler_Processor_Design_Issue_2 ├── bincode.rom ├── superscalar.v └── testbench.v /Pipelined_Processor_Design/bincode.rom: -------------------------------------------------------------------------------- 1 | 8c1fffff 2 | 8c01000a 3 | 54201000 4 | 5c210001 5 | 5bff0001 6 | 17e10000 7 | 5c420001 8 | 00000000 9 | 90400004 10 | 90200002 11 | 8c1e0005 12 | 8c1d0000 13 | 07e20000 14 | 5fff0001 15 | 87e7ffff 16 | 00000000 17 | 90e0001a 18 | 4fc23000 19 | 00000000 20 | 94c0000c 21 | 5bbd0001 22 | 9800000c 23 | 00000000 24 | 00000000 25 | 00000000 26 | 00000000 27 | a8000000 28 | 00000000 29 | 00000000 30 | 00000000 31 | -------------------------------------------------------------------------------- /Pipelined_Processor_Design/pipelined_cpu_frwding_prediction.v: -------------------------------------------------------------------------------- 1 | module pipelined_cpu(clk); 2 | input clk ; //system clock 3 | 4 | /******************* Mnemonic op codes ***************************/ 5 | parameter NOP = 6'd0; 6 | /***** Memory reference (load 1-4) ********/ 7 | parameter LW = 6'd1; parameter LB = 6'd2; parameter LBU = 6'd3; parameter LH = 6'd4; 8 | 9 | /***** Memory reference (store 5-7) ********/ 10 | parameter SW = 6'd5; parameter SB = 6'd6; parameter SH = 6'd7; /*Srore Half Word*/ 11 | 12 | /***** Register-Register operations(8-21) ********/ 13 | parameter ADD = 6'd8; parameter SUB = 6'd9; parameter MULT = 6'd10; parameter DIV = 6'd11; 14 | parameter AND = 6'd12; parameter OR = 6'd13; parameter XOR = 6'd14; parameter SLT = 6'd15; 15 | parameter SGT = 6'd16; parameter SLE = 6'd17; parameter SGE = 6'd18; parameter EQ = 6'd19; 16 | parameter NEQ = 6'd20; parameter MV = 6'd21; 17 | 18 | /***** Register-Immediate operations(21-35) **********/ 19 | parameter ADDI = 6'd22; parameter SUBI = 6'd23; parameter MULTI = 6'd24; parameter DIVI = 6'd25; 20 | parameter ANDI = 6'd26; parameter ORI = 6'd27; parameter XORI = 6'd28; parameter SLTI = 6'd29; 21 | parameter SGTI = 6'd30; parameter SLEI = 6'd31; parameter SGEI = 6'd32; parameter EQI = 6'd33; 22 | parameter NEQI = 6'd34; parameter MVI = 6'd35; 23 | 24 | /***** Control operations(35-43) ******************/ 25 | parameter BNEZ = 6'd36;parameter BEQZ = 6'd37;parameter J = 6'd38;parameter JR = 6'd39; 26 | parameter CALL = 6'd40;parameter CALLR = 6'd41; parameter HALT = 6'd42; parameter RET = 6'd43; 27 | 28 | 29 | /******************* Core cpu parameters *********************** 30 | ** Memory : Word addressable; Big Endian mode ; 32-bit address; Separate Instruction & Data memory 31 | ** Register File : 32 general purpose registers(32-bit) 32 | ** Instruction Memory : size 1024; 33 | ** Instruction Size : 32 bit; 34 | ****************************************************************/ 35 | parameter INSTRUCTION_MEMORY_SIZE = 10 ; parameter REGISTER_FILE_SIZE = 5; 36 | parameter OPCODE_SIZE = 6 ; parameter DATA_MEMORY_SIZE = 10; 37 | 38 | reg [ 0:31 ] IMEM [0: 2 ** INSTRUCTION_MEMORY_SIZE -1 ] ; // Instruction Memory 39 | reg [ 0:31 ] DMEM [0: 2 ** DATA_MEMORY_SIZE -1 ]; // Data Memory 40 | reg [ 0:31 ] REGFILE [0: 2 ** REGISTER_FILE_SIZE -1 ]; // General Purpose Registers 41 | reg [ 0 : INSTRUCTION_MEMORY_SIZE -1] PC; // program counter 42 | 43 | reg [ 0:31 ] IF_ID_IR, IF_ID_NPC; //Pipeline Registers : IF Stage 44 | reg [ 0:31 ] ID_EX_IR, ID_EX_NPC, ID_EX_A, ID_EX_B, ID_EX_IMM; //Pipeline Registers : ID Stage 45 | reg [ 0:31 ] EX_MEM_IR, EX_MEM_B, EX_MEM_ALUOUTPUT, EX_MEM_COND; //Pipeline Registers : EX Stage 46 | reg [ 0:31 ] MEM_WB_IR, MEM_WB_ALUOUTPUT, MEM_WB_LMD; //Pipeline Registers : MEM Stage 47 | 48 | wire [0 : OPCODE_SIZE -1] EX_MEM_OP, MEM_WB_OP, ID_EX_OP, IF_ID_OP; //Access opcodes 49 | wire [0:31] Ain, Bin; //The ALU inputs 50 | wire branchtaken, stall, bypassAfromMEM, bypassAfromALUinWB,bypassBfromMEM, bypassBfromALUinWB, bypassAfromLWinWB, bypassBfromLWinWB; //Bypass Signals 51 | wire [0:REGISTER_FILE_SIZE - 1] IF_ID_rs, ID_EX_rs, ID_EX_rt, EX_MEM_rd, MEM_WB_rd; //hold register fields 52 | wire bypassAfromEX_MEMforbranch, bypassAfromMEM_WBforbranch; 53 | 54 | assign EX_MEM_OP = EX_MEM_IR[0:OPCODE_SIZE -1]; 55 | assign MEM_WB_OP = MEM_WB_IR[0:OPCODE_SIZE -1]; 56 | assign ID_EX_OP = ID_EX_IR[0:OPCODE_SIZE -1] ; 57 | assign IF_ID_OP = IF_ID_IR[0:OPCODE_SIZE -1] ; 58 | reg [5:0] i; 59 | reg finish; 60 | 61 | assign ID_EX_rs = ID_EX_IR[6:10]; 62 | assign ID_EX_rt = ID_EX_IR[11:15]; 63 | assign IF_ID_rs = IF_ID_IR[6:10]; //For branch instruction only 64 | assign EX_MEM_rd = EX_MEM_OP >= ADDI & EX_MEM_OP <= MVI ? EX_MEM_IR[11:15] : EX_MEM_IR[16:20]; 65 | assign MEM_WB_rd = MEM_WB_OP >= ADDI & MEM_WB_OP <= MVI ? MEM_WB_IR[11:15] : MEM_WB_IR[16:20]; 66 | 67 | // The bypass to input A in ID_EX buffer from the EX_MEM buffer for an ALU operation 68 | 69 | assign bypassAfromEX_MEMforbranch = (IF_ID_rs == EX_MEM_rd) & (IF_ID_rs!=0) & (EX_MEM_OP >= ADD & EX_MEM_OP <= MVI) & (IF_ID_OP == BNEZ | IF_ID_OP 70 | ==BEQZ); 71 | assign bypassAfromMEM_WBforbranch = (IF_ID_rs == MEM_WB_rd) & (IF_ID_rs!=0) & (MEM_WB_OP >= ADD & EX_MEM_OP <= MVI) & (IF_ID_OP == BNEZ | IF_ID_OP 72 | ==BEQZ); 73 | 74 | assign bypassAfromMEM = (ID_EX_rs == EX_MEM_rd) & (ID_EX_rs!=0) & (EX_MEM_OP >= ADD & EX_MEM_OP <= MVI) & (ID_EX_OP != MVI); 75 | //MVI doesn't make any sense for 'A' frwding*/ 76 | 77 | // The bypass to input B in ID_EX buffer from the EX_MEM buffer for an ALU operation 78 | assign bypassBfromMEM = (ID_EX_rt== EX_MEM_rd)&(ID_EX_rt!=0) & (EX_MEM_OP >= ADD & EX_MEM_OP <= MVI) & !(ID_EX_OP >= ADDI & ID_EX_OP <= MVI) 79 | & (ID_EX_OP != MV) ; 80 | //MVI, MV, or any alu immediate instruction doesn't make any sense for 'B' frwding*/ 81 | 82 | // The bypass to input A in ID_EX buffer from the MEM_WB buffer for an ALU operation 83 | assign bypassAfromALUinWB = (ID_EX_rs == MEM_WB_rd) & (ID_EX_rs!=0) & (MEM_WB_OP >= ADD & MEM_WB_OP <= MVI) & (ID_EX_OP != MVI); 84 | //MVI doesn't make any sense for 'A' frwding 85 | 86 | // The bypass to input B in ID_EX buffer from the MEM_WB buffer for an ALU operation 87 | assign bypassBfromALUinWB = (ID_EX_rt== MEM_WB_rd)&(ID_EX_rt!=0) & (MEM_WB_OP >= ADD & MEM_WB_OP <= MVI) & !(ID_EX_OP >= ADDI & ID_EX_OP <= MVI) 88 | & (ID_EX_OP != MV) ; 89 | //MVI, MV, or any alu immediate instruction doesn't make any sense for 'B' frwding 90 | 91 | // The bypass to input A in ID_EX buffer from the MEM_WB buffer corresponding to LW operation. 92 | assign bypassAfromLWinWB =( ID_EX_rs == MEM_WB_IR[11:15]) & (ID_EX_rs!=0) & ((MEM_WB_OP == LW) |(MEM_WB_OP == LB) | 93 | (MEM_WB_OP == LBU) | (MEM_WB_OP == LH)); 94 | 95 | // The bypass to input A in ID_EX buffer from the MEM_WB buffer corresponding to LW operation. 96 | assign bypassBfromLWinWB = (ID_EX_rt==MEM_WB_IR[11:15]) & (ID_EX_rt!=0) & (((MEM_WB_OP == LW) |(MEM_WB_OP == LB) | 97 | (MEM_WB_OP == LBU) | (MEM_WB_OP == LH))); 98 | 99 | // The A input to the ALU is bypassed from EX_MEM buffer if there is a bypass there, 100 | // Otherwise from MEM_WB if there is a bypass there, and otherwise comes from the ID_EX register 101 | assign Ain = bypassAfromMEM? EX_MEM_ALUOUTPUT : bypassAfromALUinWB ? MEM_WB_ALUOUTPUT : bypassAfromLWinWB ? MEM_WB_LMD : ID_EX_A; 102 | 103 | // The B input to the ALU is bypassed from EX_MEM if there is a bypass there, 104 | // Otherwise from MEM_WB if there is a bypass there, and otherwise comes from the ID_EX register 105 | assign Bin = bypassBfromMEM? EX_MEM_ALUOUTPUT : bypassBfromALUinWB ? MEM_WB_ALUOUTPUT : bypassBfromLWinWB? MEM_WB_LMD: ID_EX_B; 106 | 107 | // The signal for detecting a stall based on the use of a result from LW 108 | assign stall = (MEM_WB_IR[0:5]==LW) && // source instruction is a load 109 | ( (((ID_EX_OP==LW)|(ID_EX_OP==SW)) && (ID_EX_rs==MEM_WB_rd)) | // stall for address calc 110 | ((ID_EX_OP <= ADD & ID_EX_OP <= NEQ) && ((ID_EX_rs==MEM_WB_rd)|(ID_EX_rt==MEM_WB_rd))) | // ALU use 111 | ((ID_EX_OP <= ADDI & ID_EX_OP <= NEQI) && (ID_EX_rs==MEM_WB_rd)) | 112 | ((ID_EX_OP == MV) && (ID_EX_rs==MEM_WB_rd)) ); 113 | 114 | // Signal for a taken branch: instruction is BEQ and registers are equal bypassAfromMEM bypassAfromALUinWB 115 | /*assign branchtaken = ((IF_ID_IR[0:5] == BEQZ) && (REGFILE[IF_ID_IR[6:10]] == 32'd0)) | 116 | ((IF_ID_IR[0:5] == BNEZ) && (REGFILE[IF_ID_IR[6:10]] != 32'd0)) | 117 | IF_ID_IR[0:5] == JR | IF_ID_IR[0:5] == J | IF_ID_IR[0:5] == CALL | IF_ID_IR[0:5] == CALLR;*/ 118 | /*Branch decision is taken at the begining of the ID stage and forwarding (if necessary) is to be done from ID_EX, EX_MEM, and MEM_WB buffers 119 | **Also the instruction forwarding the result should not be SW. 120 | ** 121 | */ 122 | assign branchtaken = ((IF_ID_IR[0:5] == BEQZ) && (bypassAfromEX_MEMforbranch ? EX_MEM_ALUOUTPUT == 32'd0 : bypassAfromMEM_WBforbranch ? 123 | MEM_WB_ALUOUTPUT == 32'd0 :REGFILE[IF_ID_IR[6:10]] == 32'd0)) | 124 | ((IF_ID_IR[0:5] == BNEZ) && (bypassAfromEX_MEMforbranch ? EX_MEM_ALUOUTPUT != 32'd0 : bypassAfromMEM_WBforbranch ? 125 | MEM_WB_ALUOUTPUT != 32'd0 :REGFILE[IF_ID_IR[6:10]] != 32'd0)) | 126 | IF_ID_IR[0:5] == JR | IF_ID_IR[0:5] == J | IF_ID_IR[0:5] == CALL | IF_ID_IR[0:5] == CALLR; 127 | 128 | 129 | /************** The initial cpu state bootstrap **************************/ 130 | initial begin 131 | PC = 0; 132 | finish =0; 133 | $readmemh("bincode.rom",IMEM); 134 | IF_ID_IR = 32'b0; ID_EX_IR = 32'b0; EX_MEM_IR=32'b0; MEM_WB_IR = 32'b0; 135 | 136 | 137 | 138 | IMEM[22] = {BEQZ, 5'd21,21'd38}; 139 | IMEM[23] = {EQ, 5'd2,5'd7,5'd21,11'd0}; 140 | 141 | /*** Test Program Branch ************************************ 142 | IMEM[0] = { MVI , 5'd0, 5'd1, 16'd10 }; //R1 <- 10 ; 143 | IMEM[1] = { MVI , 5'd0, 5'd2, 16'd501 }; //R2<-500 144 | IMEM[2] = { MVI , 5'd0, 5'd3, 16'd0 }; //R3<-0 145 | IMEM[3] = { MV , 5'd1, 5'd0, 5'd4,11'd0 }; //R4<-R1 146 | IMEM[4] = { ADDI , 5'd3, 5'd3, 16'd100 }; //R3 <- R3+100 ; 147 | IMEM[5] = { SUBI , 5'd4, 5'd4, 16'd1 }; //R4 <- R4-1 148 | IMEM[6] = { SW, 5'd4, 5'd3, 16'd0 }; //M[R4] <- R3 149 | IMEM[7] = { BNEZ, 5'd4, 5'd0, 16'd4 }; // R4 != 0 ? Jump to 4 150 | IMEM[8] = { MVI , 5'd0, 5'd4, 16'd0 }; //R4<-0 151 | IMEM[9] = { LW, 5'd4, 5'd3, 16'd0 }; // R3 <- M[R4] 152 | IMEM[10] = { ADDI , 5'd4, 5'd4, 16'd1 }; // R4 <- R4+1 153 | IMEM[11] = { EQ , 5'd3, 5'd2, 5'd6, 11'd0 }; // R6 <- R3 == R2 154 | IMEM[12] = {NOP, 26'd0}; //NOP 155 | IMEM[13] = { BNEZ, 5'd6, 5'd0, 16'd19 }; // R6 != 0 ? Jump to 19 156 | IMEM[14] = { EQI , 5'd4, 5'd7, 16'd9 }; // R7 <- R4 == 9 157 | IMEM[15] = {NOP, 26'd0}; //NOP 158 | IMEM[16] = { BEQZ, 5'd7, 5'd0, 16'd9 }; // R7 == 0 ? Jump to 9 159 | IMEM[17] = { MVI , 5'd0, 5'd5, 16'h00ff }; //R5 <- failure 160 | IMEM[18] = { HALT , 26'd0 }; //HALT 161 | IMEM[19] = { MVI , 5'd0, 5'd5, 16'hff00 }; //R5 <- success 162 | IMEM[20] = { HALT , 26'd0 }; //HALT 163 | */ 164 | /*** Basic Program Branch (Returns the number of occurences of a number in an array)************************************ 165 | IMEM[0] = { MVI , 5'd0, 5'd31, -16'd1 }; //R31 <- -1 ; 166 | IMEM[1] = { MVI , 5'd0, 5'd1, 16'd10 }; //R1 <- 10 ; ********** SEED POINT 167 | IMEM[2] = { MV , 5'd1, 5'd0, 5'd2,11'd0 }; //R2<-R1 168 | IMEM[3] = { SUBI , 5'd1, 5'd1, 16'd1 }; //R1 <- R1-1 169 | IMEM[4] = { ADDI , 5'd31, 5'd31, 16'd1 }; //R31 <- R31+1 170 | IMEM[5] = { SW, 5'd31, 5'd1, 16'd0 }; //M[R31] <- R1 171 | IMEM[6] = { SUBI , 5'd2, 5'd2, 16'd1 }; //R2 <- R2-1 172 | IMEM[7] = { NOP , 26'd0 }; //NOP 173 | IMEM[8] = { BNEZ, 5'd2, 5'd0, 16'd4 }; // R2 != 0 ? Jump to 4 174 | IMEM[9] = { BNEZ, 5'd1, 5'd0, 16'd2 }; // R1 != 0 ? Jump to 2 175 | 176 | IMEM[10] = { MVI , 5'd0, 5'd30, 16'd5 }; //R30 <- 5 ;QUERY************** 177 | IMEM[11] = { MVI , 5'd0, 5'd29, 16'd0 }; //R29 <- 0 ; Count number of matches -1 178 | 179 | IMEM[12] = { LW ,5'd31, 5'd2, 16'd0 }; // R2 <- M[R31] 180 | IMEM[13] = { SUBI , 5'd31, 5'd31, 16'd1 }; //R31 <- R31-1 181 | IMEM[14] = { EQI , 5'd31, 5'd7, -16'd1 }; // R7 <- R31 == -1 182 | IMEM[15] = { NOP , 26'd0 }; //NOP 183 | IMEM[16] = { BNEZ, 5'd7, 5'd0, 16'd26 }; // R7 != 0 ? Jump to 26 184 | IMEM[17] = { EQ , 5'd30, 5'd2, 5'd6, 11'd0 }; // R6 <- R30 == R2 185 | IMEM[18] = { NOP , 26'd0 }; //NOP 186 | IMEM[19] = { BEQZ, 5'd6, 5'd0, 16'd12 }; // R6 == 0 ? Jump to 12 187 | IMEM[20] = { ADDI , 5'd29, 5'd29, 16'd1 }; //R29<- R29+1 188 | IMEM[21] = {J , 26'd12 }; //Jump to 12 189 | IMEM[22] = { NOP , 26'd0 }; //NOP 190 | IMEM[23] = { NOP , 26'd0 }; //NOP 191 | IMEM[24] = { NOP , 26'd0 }; //NOP 192 | IMEM[25] = { NOP , 26'd0 }; //NOP 193 | IMEM[26] = { HALT , 26'd0 }; //HALT 194 | */ 195 | end 196 | 197 | always @ (posedge clk) begin 198 | if (~stall) begin // the first three pipeline stages stall if there is a load hazard 199 | // IF STAGE 200 | if (~branchtaken) begin 201 | IF_ID_IR <= IMEM[PC]; 202 | PC <= PC + 1; 203 | end else begin 204 | IF_ID_IR <= 32'd0; 205 | if(IF_ID_IR[0:5] == BEQZ | IF_ID_IR[0:5] == BNEZ) begin 206 | PC <= { {16{IF_ID_IR[16]}},IF_ID_IR[16:31]}; 207 | end else if(IF_ID_IR[0:5] == J) begin 208 | PC <= { {6{IF_ID_IR[6]}},IF_ID_IR[6:31]}; 209 | end else if(IF_ID_IR[0:5] == JR) begin 210 | PC <= REGFILE[IF_ID_IR[6:10]]; 211 | end else if(IF_ID_IR[0:5] == CALL) begin 212 | REGFILE[31] <= PC; 213 | PC <= { {6{IF_ID_IR[6]}},IF_ID_IR[6:31]}; 214 | end else if(IF_ID_IR[0:5] == CALLR) begin 215 | REGFILE[31] <= PC; 216 | PC <= REGFILE[IF_ID_IR[6:10]]; 217 | end 218 | end 219 | 220 | // ID STAGE 221 | if(MEM_WB_IR[0:5] != SW && (IF_ID_IR[6:10] != 5'd0) && (IF_ID_IR[6:10] == MEM_WB_IR[11:15] | IF_ID_IR[6:10] == MEM_WB_IR[16:20])) begin 222 | ID_EX_A <= MEM_WB_ALUOUTPUT; 223 | end else begin 224 | ID_EX_A <= REGFILE[IF_ID_IR[6:10]]; 225 | end 226 | if(MEM_WB_IR[0:5] != SW && (IF_ID_IR[11:15] != 5'd0) && (IF_ID_IR[11:15] == MEM_WB_IR[11:15] | IF_ID_IR[11:15] == MEM_WB_IR[16:20])) begin 227 | ID_EX_B <= MEM_WB_ALUOUTPUT; 228 | end else begin 229 | ID_EX_B <= REGFILE[IF_ID_IR[11:15]]; 230 | end 231 | ID_EX_IMM <= { {16{IF_ID_IR[16]}},IF_ID_IR[16:31]}; 232 | ID_EX_IR <= IF_ID_IR; 233 | ID_EX_NPC <= IF_ID_NPC; 234 | 235 | // EX STAGE 236 | case (ID_EX_OP) 237 | LW , LB , LBU , LH: begin EX_MEM_ALUOUTPUT <= Ain + ID_EX_IMM; EX_MEM_COND <= 0; end 238 | SW , SB , SH: begin EX_MEM_ALUOUTPUT <= Ain + ID_EX_IMM; EX_MEM_COND <= 0; end 239 | ADD : begin EX_MEM_ALUOUTPUT <= Ain + Bin; EX_MEM_COND <= 0; end 240 | SUB : begin EX_MEM_ALUOUTPUT <= Ain - Bin; EX_MEM_COND <= 0; end 241 | MULT : begin EX_MEM_ALUOUTPUT <= Ain * Bin; EX_MEM_COND <= 0; end 242 | DIV : begin EX_MEM_ALUOUTPUT <= Ain / Bin; EX_MEM_COND <= 0; end 243 | AND : begin EX_MEM_ALUOUTPUT <= Ain & Bin; EX_MEM_COND <= 0; end 244 | OR : begin EX_MEM_ALUOUTPUT <= Ain | Bin; EX_MEM_COND <= 0; end 245 | XOR : begin EX_MEM_ALUOUTPUT <= Ain ^ Bin; EX_MEM_COND <= 0; end 246 | SLT : begin 247 | if(Ain < Bin) begin 248 | EX_MEM_ALUOUTPUT <= 1; 249 | end else begin 250 | EX_MEM_ALUOUTPUT <= 0; 251 | end 252 | EX_MEM_COND <= 0; 253 | end 254 | SGT : begin 255 | if(Ain > Bin) begin 256 | EX_MEM_ALUOUTPUT <= 1; 257 | end else begin 258 | EX_MEM_ALUOUTPUT <= 0; 259 | end 260 | EX_MEM_COND <= 0; 261 | end 262 | SLE : begin 263 | if(Ain <= Bin) begin 264 | EX_MEM_ALUOUTPUT <= 1; 265 | end else begin 266 | EX_MEM_ALUOUTPUT <= 0; 267 | end 268 | EX_MEM_COND <= 0; 269 | end 270 | SGE : begin 271 | if(Ain >= Bin) begin 272 | EX_MEM_ALUOUTPUT <= 1; 273 | end else begin 274 | EX_MEM_ALUOUTPUT <= 0; 275 | end 276 | EX_MEM_COND <= 0; 277 | end 278 | EQ : begin 279 | if(Ain == Bin) begin 280 | EX_MEM_ALUOUTPUT <= 1; 281 | end else begin 282 | EX_MEM_ALUOUTPUT <= 0; 283 | end 284 | EX_MEM_COND <= 0; 285 | end 286 | NEQ : begin 287 | if(Ain != Bin) begin 288 | EX_MEM_ALUOUTPUT <= 1; 289 | end else begin 290 | EX_MEM_ALUOUTPUT <= 0; 291 | end 292 | EX_MEM_COND <= 0; 293 | end 294 | MV : begin EX_MEM_ALUOUTPUT <= Ain; EX_MEM_COND <= 0; end 295 | ADDI : begin EX_MEM_ALUOUTPUT <= Ain + ID_EX_IMM; EX_MEM_COND <= 0; end 296 | SUBI : begin EX_MEM_ALUOUTPUT <= Ain - ID_EX_IMM; EX_MEM_COND <= 0; end 297 | MULTI : begin EX_MEM_ALUOUTPUT <= Ain * ID_EX_IMM; EX_MEM_COND <= 0; end 298 | DIVI : begin EX_MEM_ALUOUTPUT <= Ain / ID_EX_IMM; EX_MEM_COND <= 0; end 299 | ANDI : begin EX_MEM_ALUOUTPUT <= Ain & ID_EX_IMM; EX_MEM_COND <= 0; end 300 | ORI : begin EX_MEM_ALUOUTPUT <= Ain | ID_EX_IMM; EX_MEM_COND <= 0; end 301 | XORI : begin EX_MEM_ALUOUTPUT <= Ain ^ ID_EX_IMM; EX_MEM_COND <= 0; end 302 | SLTI : begin 303 | if(Ain < ID_EX_IMM) begin 304 | EX_MEM_ALUOUTPUT <= 1; 305 | end else begin 306 | EX_MEM_ALUOUTPUT <= 0; 307 | end 308 | EX_MEM_COND <= 0; 309 | end 310 | SGTI : begin 311 | if(Ain > ID_EX_IMM) begin 312 | EX_MEM_ALUOUTPUT <= 1; 313 | end else begin 314 | EX_MEM_ALUOUTPUT <= 0; 315 | end 316 | EX_MEM_COND <= 0; 317 | end 318 | SLEI : begin 319 | if(Ain <= ID_EX_IMM) begin 320 | EX_MEM_ALUOUTPUT <= 1; 321 | end else begin 322 | EX_MEM_ALUOUTPUT <= 0; 323 | end 324 | EX_MEM_COND <= 0; 325 | end 326 | SGEI : begin 327 | if(Ain >= ID_EX_IMM) begin 328 | EX_MEM_ALUOUTPUT <= 1; 329 | end else begin 330 | EX_MEM_ALUOUTPUT <= 0; 331 | end 332 | EX_MEM_COND <= 0; 333 | end 334 | EQI : begin 335 | if(Ain == ID_EX_IMM) begin 336 | EX_MEM_ALUOUTPUT <= 1; 337 | end else begin 338 | EX_MEM_ALUOUTPUT <= 0; 339 | end 340 | EX_MEM_COND <= 0; 341 | end 342 | NEQI : begin 343 | if(Ain != ID_EX_IMM) begin 344 | EX_MEM_ALUOUTPUT <= 1; 345 | end else begin 346 | EX_MEM_ALUOUTPUT <= 0; 347 | end 348 | EX_MEM_COND <= 0; 349 | end //REGFILE 350 | MVI : begin EX_MEM_ALUOUTPUT <= ID_EX_IMM; EX_MEM_COND <= 0; end 351 | RET: begin EX_MEM_ALUOUTPUT <= REGFILE[31]; EX_MEM_COND = 0; end 352 | NOP: EX_MEM_COND <= 0; 353 | HALT: begin 354 | finish =1; 355 | end 356 | default: begin end 357 | endcase 358 | EX_MEM_IR <= ID_EX_IR; EX_MEM_B <= Bin; 359 | 360 | end 361 | else EX_MEM_IR <= 32'd0; //Freeze first three stages of pipeline; inject a nop into the EX_MEM_IR 362 | 363 | //MEM STAGE 364 | if (EX_MEM_OP == LW || EX_MEM_OP == LB || EX_MEM_OP == LBU || EX_MEM_OP == LH) MEM_WB_LMD <= DMEM[EX_MEM_ALUOUTPUT]; 365 | else if (EX_MEM_OP == SW || EX_MEM_OP == SB || EX_MEM_OP == SH) DMEM[EX_MEM_ALUOUTPUT] <= EX_MEM_B; 366 | MEM_WB_IR <= EX_MEM_IR; 367 | MEM_WB_ALUOUTPUT <= EX_MEM_ALUOUTPUT; 368 | 369 | //WB STAGE 370 | case(MEM_WB_OP) 371 | ADD, SUB , MULT, DIV ,AND ,OR , XOR ,SLT,SGT ,SLE, SGE ,EQ , NEQ , MV : REGFILE[MEM_WB_IR[16:20]] <= MEM_WB_ALUOUTPUT; 372 | ADDI, SUBI , MULTI, DIVI ,ANDI ,ORI , XORI ,SLTI ,SGTI ,SLEI , SGEI ,EQI , NEQI , MVI : REGFILE[MEM_WB_IR[11:15]] <= MEM_WB_ALUOUTPUT; 373 | LW , LB , LBU , LH : REGFILE[MEM_WB_IR[11:15]] = MEM_WB_LMD; 374 | endcase 375 | end 376 | endmodule 377 | -------------------------------------------------------------------------------- /Pipelined_Processor_Design/testbench.v: -------------------------------------------------------------------------------- 1 | 2 | // ============================================================================ 3 | // TESTBENCH FOR CPU CORE 4 | // ============================================================================ 5 | 6 | module tb (); 7 | reg clk; 8 | 9 | 10 | pipelined_cpu cpu ( 11 | clk 12 | ); 13 | 14 | initial begin 15 | clk = 1; 16 | #13000 clk = 0; 17 | $stop; 18 | end 19 | 20 | always clk = #1 ~clk; 21 | 22 | endmodule 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Parallel-Processor-Design 2 | ========================= 3 | 4 | To design a customized processor (using parallel processing concepts) for the application of document retrieval system. We developed a superscalar processor (with an issue rate of 2) using verilog hdl, and an assembler for that processor using flex and bison. 5 | -------------------------------------------------------------------------------- /Superscaler_Processor_Design_Issue_2/bincode.rom: -------------------------------------------------------------------------------- 1 | 8c1fffff 2 | 8c01000a 3 | 54201000 4 | 5c210001 5 | 5bff0001 6 | 00000000 7 | 17e10000 8 | 5c420001 9 | 00000000 10 | 00000000 11 | 90400004 12 | 00000000 13 | 90200002 14 | 00000000 15 | 8c1e0005 16 | 8c1d0000 17 | 07e20000 18 | 5fff0001 19 | 87e7ffff 20 | 00000000 21 | 00000000 22 | 00000000 23 | 90e00020 24 | 4fc23000 25 | 00000000 26 | 00000000 27 | 94c00010 28 | 00000000 29 | 5bbd0001 30 | 98000010 31 | 00000000 32 | 00000000 33 | a8000000 34 | 00000000 35 | 00000000 36 | 00000000 37 | -------------------------------------------------------------------------------- /Superscaler_Processor_Design_Issue_2/superscalar.v: -------------------------------------------------------------------------------- 1 | module superscalar_cpu(clk); 2 | input clk ; //system clock 3 | 4 | /******************* Mnemonic op codes ***************************/ 5 | parameter NOP = 6'd0; 6 | /***** Memory reference (load 1-4) ********/ 7 | parameter LW = 6'd1; parameter LB = 6'd2; parameter LBU = 6'd3; parameter LH = 6'd4; 8 | 9 | /***** Memory reference (store 5-7) ********/ 10 | parameter SW = 6'd5; parameter SB = 6'd6; parameter SH = 6'd7; /*Srore Half Word*/ 11 | 12 | /***** Register-Register operations(8-21) ********/ 13 | parameter ADD = 6'd8; parameter SUB = 6'd9; parameter MULT = 6'd10; parameter DIV = 6'd11; 14 | parameter AND = 6'd12; parameter OR = 6'd13; parameter XOR = 6'd14; parameter SLT = 6'd15; 15 | parameter SGT = 6'd16; parameter SLE = 6'd17; parameter SGE = 6'd18; parameter EQ = 6'd19; 16 | parameter NEQ = 6'd20; parameter MV = 6'd21; 17 | 18 | /***** Register-Immediate operations(21-35) **********/ 19 | parameter ADDI = 6'd22; parameter SUBI = 6'd23; parameter MULTI = 6'd24; parameter DIVI = 6'd25; 20 | parameter ANDI = 6'd26; parameter ORI = 6'd27; parameter XORI = 6'd28; parameter SLTI = 6'd29; 21 | parameter SGTI = 6'd30; parameter SLEI = 6'd31; parameter SGEI = 6'd32; parameter EQI = 6'd33; 22 | parameter NEQI = 6'd34; parameter MVI = 6'd35; 23 | 24 | /***** Control operations(35-43) ******************/ 25 | parameter BNEZ = 6'd36;parameter BEQZ = 6'd37;parameter J = 6'd38;parameter JR = 6'd39; 26 | parameter CALL = 6'd40;parameter CALLR = 6'd41; parameter HALT = 6'd42; parameter RET = 6'd43; 27 | 28 | 29 | /******************* Core cpu parameters *********************** 30 | ** Memory : Word addressable; Big Endian mode ; 32-bit address; Separate Instruction & Data memory 31 | ** Register File : 32 general purpose registers(32-bit) 32 | ** Instruction Memory : size 1024; 33 | ** Instruction Size : 32 bit; 34 | ** Superscalar Degree : 2 35 | ****************************************************************/ 36 | parameter INSTRUCTION_MEMORY_SIZE = 10 ; parameter REGISTER_FILE_SIZE = 5; 37 | parameter OPC = 6 ; parameter DATA_MEMORY_SIZE = 10; 38 | parameter S_DEGREE = 2; 39 | 40 | reg [ 0:31 ] IMEM [0: 2 ** INSTRUCTION_MEMORY_SIZE -1 ] ; // Instruction Memory 41 | reg [ 0:31 ] DMEM [0: 2 ** DATA_MEMORY_SIZE -1 ]; // Data Memory 42 | reg [ 0:31 ] REGFILE [0: 2 ** REGISTER_FILE_SIZE -1 ]; // General Purpose Registers 43 | reg [ 0 : INSTRUCTION_MEMORY_SIZE -1] PC; // program counter 44 | 45 | /*************************************************** Pipeline Registers ********************************************/ 46 | /************Pipeline Registers : IF Stage *****************/ 47 | reg [ 0:31 ] IF_ID_IR[0:S_DEGREE-1] ; 48 | 49 | /************Pipeline Registers : ID Stage **************/ 50 | reg [ 0:31 ] ID_EX_IR[0:S_DEGREE-1], ID_EX_A[0:S_DEGREE-1], ID_EX_B[0:S_DEGREE-1], ID_EX_IMM[0:S_DEGREE-1]; 51 | 52 | /************Pipeline Registers : EX Stage *****************/ 53 | reg [ 0:31 ] EX_MEM_IR[0:S_DEGREE-1], EX_MEM_B[0:S_DEGREE-1], EX_MEM_ALUOUTPUT[0:S_DEGREE-1]; 54 | 55 | /************Pipeline Registers : MEM Stage *****************/ 56 | reg [ 0:31 ] MEM_WB_IR[0:S_DEGREE-1], MEM_WB_ALUOUTPUT[0:S_DEGREE-1], MEM_WB_LMD[0:S_DEGREE-1]; 57 | 58 | 59 | /*********** Opcode Registers *********************************/ 60 | wire [0 : OPC -1] EX_MEM_OP[0:S_DEGREE-1], MEM_WB_OP[0:S_DEGREE-1]; //Access opcodes 61 | wire [0 : OPC -1] ID_EX_OP[0:S_DEGREE-1], IF_ID_OP[0:S_DEGREE-1]; //Access opcodes 62 | wire [0:31] Ain[0:S_DEGREE-1], Bin[0:S_DEGREE-1]; //The ALU inputs 63 | 64 | /************ Bypassing Registers ********************************/ 65 | wire [0:REGISTER_FILE_SIZE - 1] ID_EX_rs[0:S_DEGREE-1], ID_EX_rt[0:S_DEGREE-1]; //Sources 66 | wire [0:REGISTER_FILE_SIZE - 1] EX_MEM_rd[0:S_DEGREE-1], MEM_WB_rd[0:S_DEGREE-1]; //Destinations 67 | wire bypassAfrom_EX_MEM[0:S_DEGREE-1][0:S_DEGREE-1], bypassAfrom_MEM_WB[0:S_DEGREE-1][0:S_DEGREE-1]; //Bypass Signals from EX_MEM & 68 | //MEM_WB stage for source A 69 | wire bypassBfrom_EX_MEM[0:S_DEGREE-1][0:S_DEGREE-1], bypassBfrom_MEM_WB[0:S_DEGREE-1][0:S_DEGREE-1]; //Bypass Signals from EX_MEM & 70 | //MEM_WB stage for source B 71 | wire bypassAfromLWin_MEM_WB[0:S_DEGREE-1][0:S_DEGREE-1], bypassBfromLWin_MEM_WB[0:S_DEGREE-1][0:S_DEGREE-1]; //Bypass Signals from Load 72 | //instructions 73 | 74 | /************ Branch Prediction Registers ********************************/ 75 | wire bypassAfromEX_MEMforbranch[0:S_DEGREE-1][0:S_DEGREE-1], 76 | bypassAfromMEM_WBforbranch[0:S_DEGREE-1][0:S_DEGREE-1]; //Bypass signals for branch instructions 77 | wire branchtaken[0:S_DEGREE-1]; 78 | wire [0:REGISTER_FILE_SIZE - 1] IF_ID_rs[0:S_DEGREE-1]; //Sources 79 | 80 | 81 | /***************************************** At each stage determining the opcodes *********************************************/ 82 | assign IF_ID_OP[0] = IF_ID_IR[0][0:OPC -1]; assign IF_ID_OP[1] = IF_ID_IR[1][0:OPC -1]; 83 | assign ID_EX_OP[0] = ID_EX_IR[0][0:OPC -1]; assign ID_EX_OP[1] = ID_EX_IR[1][0:OPC -1]; 84 | assign EX_MEM_OP[0] = EX_MEM_IR[0][0:OPC -1]; assign EX_MEM_OP[1] = EX_MEM_IR[1][0:OPC -1]; 85 | assign MEM_WB_OP[0] = MEM_WB_IR[0][0:OPC -1]; assign MEM_WB_OP[1] = MEM_WB_IR[1][0:OPC -1]; 86 | 87 | /**************************************** Detection for Conflict between symultaneous issues's ALU operations************************/ 88 | wire [0:REGISTER_FILE_SIZE - 1]first_instr_destination; 89 | wire [0:REGISTER_FILE_SIZE - 1]second_instr_source_1, second_instr_source_2; 90 | wire one_cycle_stall; 91 | assign first_instr_destination = (IF_ID_OP[0] >= ADDI && IF_ID_OP[0] <= MVI) | IF_ID_OP[0] == LW 92 | ? IF_ID_IR[0][11:15] : (IF_ID_OP[0] >= ADD && IF_ID_OP[0] <= MV) ? IF_ID_IR[0][16:20]: 32'd0; 93 | 94 | assign second_instr_source_1 = IF_ID_OP[1] != MVI & IF_ID_OP[1] != J & IF_ID_OP[1] != CALL & IF_ID_OP[1] != HALT & IF_ID_OP[1] != RET ? 95 | IF_ID_IR[1][6:10] : 32'd0; 96 | assign second_instr_source_2 = IF_ID_OP[1] >= ADD && IF_ID_OP[1] <= NEQ ? IF_ID_IR[1][11:15] : 32'd0; 97 | assign one_cycle_stall = ( second_instr_source_1 == first_instr_destination && second_instr_source_1 != 32'd0) | 98 | ( second_instr_source_2 == first_instr_destination && second_instr_source_2 != 32'd0) ? 1 : 0; 99 | 100 | 101 | /**************************************** Detection for Load Conflict between symultaneous issues************************/ 102 | 103 | wire two_cycle_stall; 104 | assign two_cycle_stall = IF_ID_OP[0] == LW && (second_instr_source_1 == first_instr_destination || 105 | second_instr_source_2 == first_instr_destination) && first_instr_destination != 32'd0 ; 106 | 107 | 108 | /**************************************** Computation for Data-forwarding ***********************************************/ 109 | //Computing Source 'A' form the ID_EX register for the current instruction. 110 | assign ID_EX_rs[0] = ID_EX_IR[0][6:10]; assign ID_EX_rs[1] = ID_EX_IR[1][6:10]; 111 | 112 | //Computing Source 'B' form the ID_EX register for the current instruction. 113 | assign ID_EX_rt[0] = ID_EX_IR[0][11:15]; assign ID_EX_rt[1] = ID_EX_IR[1][11:15]; 114 | 115 | //Destination at EX_MEM Stage 116 | assign EX_MEM_rd[0] = EX_MEM_OP[0] >= ADDI & EX_MEM_OP[0] <= MVI ? EX_MEM_IR[0][11:15] : EX_MEM_IR[0][16:20]; 117 | assign EX_MEM_rd[1] = EX_MEM_OP[1] >= ADDI & EX_MEM_OP[1] <= MVI ? EX_MEM_IR[1][11:15] : EX_MEM_IR[1][16:20]; 118 | 119 | //Destination at MEM_WB Stage 120 | assign MEM_WB_rd[0] = MEM_WB_OP[0] >= ADDI & MEM_WB_OP[0] <= MVI ? MEM_WB_IR[0][11:15] : MEM_WB_IR[0][16:20]; 121 | assign MEM_WB_rd[1] = MEM_WB_OP[1] >= ADDI & MEM_WB_OP[1] <= MVI ? MEM_WB_IR[1][11:15] : MEM_WB_IR[1][16:20]; 122 | 123 | 124 | // Bypassing source operand 'A' from the EX_MEM buffer of the previous instruction to the ID_EX operands 125 | //Note: MVI doesn't make any sense for 'A' frwding 126 | 127 | //case 00: current 0th instruction gets value farwarded from previous 0th instruction. 128 | assign bypassAfrom_EX_MEM[0][0] = (ID_EX_rs[0] == EX_MEM_rd[0]) & (ID_EX_rs[0]!=0) & (EX_MEM_OP[0] >= ADD & 129 | EX_MEM_OP[0] <= MVI) & (ID_EX_OP[0] != MVI); 130 | //case 01: current 0th instruction gets value farwarded from previous 1th instruction. 131 | assign bypassAfrom_EX_MEM[0][1] = (ID_EX_rs[0] == EX_MEM_rd[1]) & (ID_EX_rs[0]!=0) & (EX_MEM_OP[1] >= ADD & 132 | EX_MEM_OP[1] <= MVI) & (ID_EX_OP[0] != MVI); 133 | 134 | //case 10: current 1th instruction gets value farwarded from previous 0th instruction. 135 | assign bypassAfrom_EX_MEM[1][0] = (ID_EX_rs[1] == EX_MEM_rd[0]) & (ID_EX_rs[1]!=0) & (EX_MEM_OP[0] >= ADD & 136 | EX_MEM_OP[0] <= MVI) & (ID_EX_OP[1] != MVI); 137 | //case 11: current 1th instruction gets value farwarded from previous 1th instruction. 138 | assign bypassAfrom_EX_MEM[1][1] = (ID_EX_rs[1] == EX_MEM_rd[1]) & (ID_EX_rs[1]!=0) & (EX_MEM_OP[1] >= ADD & 139 | EX_MEM_OP[1] <= MVI) & (ID_EX_OP[1] != MVI); 140 | 141 | //Bypassing source operand 'B' from the EX_MEM buffer of the previous instruction to the ID_EX operands 142 | //Note : MVI, MV, or any alu immediate instruction doesn't make any sense for 'B' frwding 143 | assign bypassBfrom_EX_MEM[0][0] = (ID_EX_rt[0]== EX_MEM_rd[0])&(ID_EX_rt[0]!=0) & (EX_MEM_OP[0] >= ADD & 144 | EX_MEM_OP[0] <= MVI) & !(ID_EX_OP[0] >= ADDI & ID_EX_OP[0] <= MVI) & (ID_EX_OP[0] != MV) ; 145 | assign bypassBfrom_EX_MEM[0][1] = (ID_EX_rt[0]== EX_MEM_rd[1])&(ID_EX_rt[0]!=0) & (EX_MEM_OP[1] >= ADD & 146 | EX_MEM_OP[1] <= MVI) & !(ID_EX_OP[0] >= ADDI & ID_EX_OP[0] <= MVI) & (ID_EX_OP[0] != MV) ; 147 | assign bypassBfrom_EX_MEM[1][0] = (ID_EX_rt[1]== EX_MEM_rd[0])&(ID_EX_rt[1]!=0) & (EX_MEM_OP[0] >= ADD & 148 | EX_MEM_OP[0] <= MVI) & !(ID_EX_OP[1] >= ADDI & ID_EX_OP[1] <= MVI) & (ID_EX_OP[1] != MV) ; 149 | assign bypassBfrom_EX_MEM[1][1] = (ID_EX_rt[1]== EX_MEM_rd[1])&(ID_EX_rt[1]!=0) & (EX_MEM_OP[1] >= ADD & 150 | EX_MEM_OP[1] <= MVI) & !(ID_EX_OP[1] >= ADDI & ID_EX_OP[1] <= MVI) & (ID_EX_OP[1] != MV) ; 151 | 152 | 153 | //Bypassing source operand 'A' from the MEM_WB buffer of the previous instruction to the ID_EX operands 154 | //Note: MVI doesn't make any sense for 'A' frwding 155 | assign bypassAfrom_MEM_WB[0][0] = (ID_EX_rs[0] == MEM_WB_rd[0]) & (ID_EX_rs[0]!=0) & (MEM_WB_OP[0] >= ADD & 156 | MEM_WB_OP[0] <= MVI) & (ID_EX_OP[0] != MVI); 157 | assign bypassAfrom_MEM_WB[0][1] = (ID_EX_rs[0] == MEM_WB_rd[1]) & (ID_EX_rs[0]!=0) & (MEM_WB_OP[1] >= ADD & 158 | MEM_WB_OP[1] <= MVI) & (ID_EX_OP[0] != MVI); 159 | assign bypassAfrom_MEM_WB[1][0] = (ID_EX_rs[1] == MEM_WB_rd[0]) & (ID_EX_rs[1]!=0) & (MEM_WB_OP[0] >= ADD & 160 | MEM_WB_OP[0] <= MVI) & (ID_EX_OP[1] != MVI); 161 | assign bypassAfrom_MEM_WB[1][1] = (ID_EX_rs[1] == MEM_WB_rd[1]) & (ID_EX_rs[1]!=0) & (MEM_WB_OP[1] >= ADD & 162 | MEM_WB_OP[1] <= MVI) & (ID_EX_OP[1] != MVI); 163 | 164 | //Bypassing source operand 'B' from the MEM_WB buffer of the previous instruction to the ID_EX operands 165 | //Note : MVI, MV, or any alu immediate instruction doesn't make any sense for 'B' frwding 166 | assign bypassBfrom_MEM_WB[0][0] = (ID_EX_rt[0]== MEM_WB_rd[0])&(ID_EX_rt[0]!=0) & (MEM_WB_OP[0] >= ADD & 167 | MEM_WB_OP[0] <= MVI) & !(ID_EX_OP[0] >= ADDI & ID_EX_OP[0] <= MVI) & (ID_EX_OP[0] != MV) ; 168 | assign bypassBfrom_MEM_WB[0][1] = (ID_EX_rt[0]== MEM_WB_rd[1])&(ID_EX_rt[0]!=0) & (MEM_WB_OP[1] >= ADD & 169 | MEM_WB_OP[1] <= MVI) & !(ID_EX_OP[0] >= ADDI & ID_EX_OP[0] <= MVI) & (ID_EX_OP[0] != MV) ; 170 | assign bypassBfrom_MEM_WB[1][0] = (ID_EX_rt[1]== MEM_WB_rd[0])&(ID_EX_rt[1]!=0) & (MEM_WB_OP[0] >= ADD & 171 | MEM_WB_OP[0] <= MVI) & !(ID_EX_OP[1] >= ADDI & ID_EX_OP[1] <= MVI) & (ID_EX_OP[1] != MV) ; 172 | assign bypassBfrom_MEM_WB[1][1] = (ID_EX_rt[1]== MEM_WB_rd[1])&(ID_EX_rt[1]!=0) & (MEM_WB_OP[1] >= ADD & 173 | MEM_WB_OP[1] <= MVI) & !(ID_EX_OP[1] >= ADDI & ID_EX_OP[1] <= MVI) & (ID_EX_OP[1] != MV) ; 174 | 175 | 176 | // The bypass to input A in ID_EX buffer from the MEM_WB buffer corresponding to LW operation. 177 | assign bypassAfromLWin_MEM_WB[0][0] =( ID_EX_rs[0] == MEM_WB_IR[0][11:15]) & (ID_EX_rs[0]!=0) & (MEM_WB_OP[0] >= LW && MEM_WB_OP[0] <= LH); 178 | assign bypassAfromLWin_MEM_WB[0][1] =( ID_EX_rs[0] == MEM_WB_IR[1][11:15]) & (ID_EX_rs[0]!=0) & (MEM_WB_OP[1] >= LW && MEM_WB_OP[1] <= LH); 179 | assign bypassAfromLWin_MEM_WB[1][0] =( ID_EX_rs[1] == MEM_WB_IR[0][11:15]) & (ID_EX_rs[1]!=0) & (MEM_WB_OP[0] >= LW && MEM_WB_OP[0] <= LH); 180 | assign bypassAfromLWin_MEM_WB[1][1] =( ID_EX_rs[1] == MEM_WB_IR[1][11:15]) & (ID_EX_rs[1]!=0) & (MEM_WB_OP[1] >= LW && MEM_WB_OP[1] <= LH); 181 | 182 | 183 | // The bypass to input B in ID_EX buffer from the MEM_WB buffer corresponding to LW operation. 184 | assign bypassBfromLWin_MEM_WB[0][0] =( ID_EX_rt[0] == MEM_WB_IR[0][11:15]) & (ID_EX_rt[0]!=0) & (MEM_WB_OP[0] >= LW && MEM_WB_OP[0] <= LH); 185 | assign bypassBfromLWin_MEM_WB[0][1] =( ID_EX_rt[0] == MEM_WB_IR[1][11:15]) & (ID_EX_rt[0]!=0) & (MEM_WB_OP[1] >= LW && MEM_WB_OP[1] <= LH); 186 | assign bypassBfromLWin_MEM_WB[1][0] =( ID_EX_rt[1] == MEM_WB_IR[0][11:15]) & (ID_EX_rt[1]!=0) & (MEM_WB_OP[0] >= LW && MEM_WB_OP[0] <= LH); 187 | assign bypassBfromLWin_MEM_WB[1][1] =( ID_EX_rt[1] == MEM_WB_IR[1][11:15]) & (ID_EX_rt[1]!=0) & (MEM_WB_OP[1] >= LW && MEM_WB_OP[1] <= LH); 188 | 189 | /*The A input to the ALU is bypassed from previous 1th instructions' EX_MEM buffer or 190 | from previous 0th instructions' EX_MEM buffer or 191 | from previous 1th instructions' MEM_WB buffer or 192 | from previous 0th instructions' MEM_WB buffer or 193 | from previous 1th instructions'(load instruction) MEM_WB buffer or 194 | from previous 0th instructions'(load instruction) MEM_WB buffer or 195 | from the current instyructions' registers. 196 | */ 197 | assign Ain[0] = bypassAfrom_EX_MEM[0][1]? EX_MEM_ALUOUTPUT[1] : bypassAfrom_EX_MEM[0][0] ? EX_MEM_ALUOUTPUT[0] : 198 | bypassAfrom_MEM_WB[0][1] ? MEM_WB_ALUOUTPUT[1] : bypassAfrom_MEM_WB[0][0] ? MEM_WB_ALUOUTPUT[0]: 199 | bypassAfromLWin_MEM_WB[0][1] ? MEM_WB_LMD[1] : bypassAfromLWin_MEM_WB[0][0] ? MEM_WB_LMD[0] : 200 | ID_EX_A[0]; 201 | 202 | assign Ain[1] = bypassAfrom_EX_MEM[1][1] ? EX_MEM_ALUOUTPUT[1] : bypassAfrom_EX_MEM[1][0] ? EX_MEM_ALUOUTPUT[0] : 203 | bypassAfrom_MEM_WB[1][1] ? MEM_WB_ALUOUTPUT[1] : bypassAfrom_MEM_WB[1][0] ? MEM_WB_ALUOUTPUT[0]: 204 | bypassAfromLWin_MEM_WB[1][1] ? MEM_WB_LMD[1] : bypassAfromLWin_MEM_WB[1][0] ? MEM_WB_LMD[0] : 205 | ID_EX_A[1]; 206 | 207 | /*The B input to the ALU is bypassed from previous 1th instructions' EX_MEM buffer or 208 | from previous 0th instructions' EX_MEM buffer or 209 | from previous 1th instructions' MEM_WB buffer or 210 | from previous 0th instructions' MEM_WB buffer or 211 | from previous 1th instructions'(load instruction) MEM_WB buffer or 212 | from previous 0th instructions'(load instruction) MEM_WB buffer or 213 | from the current instyructions' registers. 214 | */ 215 | assign Bin[0] = bypassBfrom_EX_MEM[0][1]? EX_MEM_ALUOUTPUT[1] : bypassBfrom_EX_MEM[0][0] ? EX_MEM_ALUOUTPUT[0] : 216 | bypassBfrom_MEM_WB[0][1] ? MEM_WB_ALUOUTPUT[1] : bypassBfrom_MEM_WB[0][0] ? MEM_WB_ALUOUTPUT[0]: 217 | bypassBfromLWin_MEM_WB[0][1] ? MEM_WB_LMD[1] : bypassBfromLWin_MEM_WB[0][0] ? MEM_WB_LMD[0] : 218 | ID_EX_B[0]; 219 | 220 | assign Bin[1] = bypassBfrom_EX_MEM[1][1] ? EX_MEM_ALUOUTPUT[1] : bypassBfrom_EX_MEM[1][0] ? EX_MEM_ALUOUTPUT[0] : 221 | bypassBfrom_MEM_WB[1][1] ? MEM_WB_ALUOUTPUT[1] : bypassBfrom_MEM_WB[1][0] ? MEM_WB_ALUOUTPUT[0]: 222 | bypassBfromLWin_MEM_WB[1][1] ? MEM_WB_LMD[1] : bypassBfromLWin_MEM_WB[1][0] ? MEM_WB_LMD[0] : 223 | ID_EX_B[1]; 224 | 225 | /**************************************** Computation for Branch Prediction ***********************************************/ 226 | //Branch decision is taken at the begining of the ID stage and forwarding (if necessary) is to be done from ID_EX, EX_MEM, and MEM_WB buffers 227 | //Also the instruction forwarding the result should not be SW. 228 | //For conditional branch instruction the source register(say R1)(eq. BNEZ R1, ADDR), need to be read and hence forwarding may be needed 229 | //from the EX_MEM stage or from the MEM_WB stage.(NOT FROM THE ID_EX, AS ITS NOT READY BY THEN). 230 | 231 | assign IF_ID_OP[0] = IF_ID_IR[0][0:OPC -1]; assign IF_ID_OP[1] = IF_ID_IR[1][0:OPC -1]; 232 | assign IF_ID_rs[0] = IF_ID_IR[0][6:10]; assign IF_ID_rs[1] = IF_ID_IR[1][6:10]; 233 | 234 | assign bypassAfromEX_MEMforbranch[0][0] = (IF_ID_rs[0] == EX_MEM_rd[0]) & (IF_ID_rs[0]!=0) & (EX_MEM_OP[0] >= ADD & EX_MEM_OP[0] <= MVI) & 235 | (IF_ID_OP[0] == BNEZ | IF_ID_OP[0] == BEQZ); 236 | assign bypassAfromEX_MEMforbranch[0][1] = (IF_ID_rs[0] == EX_MEM_rd[1]) & (IF_ID_rs[0]!=0) & (EX_MEM_OP[1] >= ADD & EX_MEM_OP[1] <= MVI) & 237 | (IF_ID_OP[0] == BNEZ | IF_ID_OP[0] ==BEQZ); 238 | assign bypassAfromEX_MEMforbranch[1][0] = (IF_ID_rs[1] == EX_MEM_rd[0]) & (IF_ID_rs[1]!=0) & (EX_MEM_OP[0] >= ADD & EX_MEM_OP[0] <= MVI) & 239 | (IF_ID_OP[1] == BNEZ | IF_ID_OP[1] ==BEQZ); 240 | assign bypassAfromEX_MEMforbranch[1][1] = (IF_ID_rs[1] == EX_MEM_rd[1]) & (IF_ID_rs[1]!=0) & (EX_MEM_OP[1] >= ADD & EX_MEM_OP[1] <= MVI) & 241 | (IF_ID_OP[1] == BNEZ | IF_ID_OP[1] ==BEQZ); 242 | 243 | 244 | assign bypassAfromMEM_WBforbranch[0][0] = (IF_ID_rs[0] == MEM_WB_rd[0]) & (IF_ID_rs[0]!=0) & (MEM_WB_OP[0] >= ADD & MEM_WB_OP[0] <= MVI) & 245 | (IF_ID_OP[0] == BNEZ | IF_ID_OP[0] ==BEQZ); 246 | assign bypassAfromMEM_WBforbranch[0][1] = (IF_ID_rs[0] == MEM_WB_rd[1]) & (IF_ID_rs[0]!=0) & (MEM_WB_OP[1] >= ADD & MEM_WB_OP[1] <= MVI) & 247 | (IF_ID_OP[0] == BNEZ | IF_ID_OP[0] ==BEQZ); 248 | assign bypassAfromMEM_WBforbranch[1][0] = (IF_ID_rs[1] == MEM_WB_rd[0]) & (IF_ID_rs[1]!=0) & (MEM_WB_OP[0] >= ADD & MEM_WB_OP[0] <= MVI) & 249 | (IF_ID_OP[1] == BNEZ | IF_ID_OP[1] ==BEQZ); 250 | assign bypassAfromMEM_WBforbranch[1][1] = (IF_ID_rs[1] == MEM_WB_rd[1]) & (IF_ID_rs[1]!=0) & (MEM_WB_OP[1] >= ADD & MEM_WB_OP[1] <= MVI) & 251 | (IF_ID_OP[1] == BNEZ | IF_ID_OP[1] ==BEQZ); 252 | 253 | assign branchtaken[0] = ((IF_ID_IR[0][0:5] == BEQZ) && (bypassAfromEX_MEMforbranch[0][1] ? EX_MEM_ALUOUTPUT[1] == 32'd0 : 254 | bypassAfromEX_MEMforbranch[0][0] ? EX_MEM_ALUOUTPUT[0] == 32'd0: 255 | bypassAfromMEM_WBforbranch[0][1] ? MEM_WB_ALUOUTPUT[1] == 32'd0: 256 | bypassAfromMEM_WBforbranch[0][0] ? MEM_WB_ALUOUTPUT[0] == 32'd0: 257 | REGFILE[IF_ID_IR[0][6:10]] == 32'd0)) 258 | || 259 | ((IF_ID_IR[0][0:5] == BNEZ) && (bypassAfromEX_MEMforbranch[0][1] ? EX_MEM_ALUOUTPUT[1] != 32'd0 : 260 | bypassAfromEX_MEMforbranch[0][0] ? EX_MEM_ALUOUTPUT[0] != 32'd0: 261 | bypassAfromMEM_WBforbranch[0][1] ? MEM_WB_ALUOUTPUT[1] != 32'd0: 262 | bypassAfromMEM_WBforbranch[0][0] ? MEM_WB_ALUOUTPUT[0] != 32'd0: 263 | REGFILE[IF_ID_IR[0][6:10]] != 32'd0)) 264 | || 265 | IF_ID_IR[0][0:5] == JR || IF_ID_IR[0][0:5] == J || IF_ID_IR[0][0:5] == CALL || IF_ID_IR[0][0:5] == CALLR; 266 | 267 | assign branchtaken[1] = ((IF_ID_IR[1][0:5] == BEQZ) && (bypassAfromEX_MEMforbranch[1][1] ? EX_MEM_ALUOUTPUT[1] == 32'd0 : 268 | bypassAfromEX_MEMforbranch[1][0] ? EX_MEM_ALUOUTPUT[0] == 32'd0: 269 | bypassAfromMEM_WBforbranch[1][1] ? MEM_WB_ALUOUTPUT[1] == 32'd0: 270 | bypassAfromMEM_WBforbranch[1][0] ? MEM_WB_ALUOUTPUT[0] == 32'd0: 271 | REGFILE[IF_ID_IR[1][6:10]] == 32'd0)) 272 | || 273 | ((IF_ID_IR[1][0:5] == BNEZ) && (bypassAfromEX_MEMforbranch[1][1] ? EX_MEM_ALUOUTPUT[1] != 32'd0 : 274 | bypassAfromEX_MEMforbranch[1][0] ? EX_MEM_ALUOUTPUT[0] != 32'd0: 275 | bypassAfromMEM_WBforbranch[1][1] ? MEM_WB_ALUOUTPUT[1] != 32'd0: 276 | bypassAfromMEM_WBforbranch[1][0] ? MEM_WB_ALUOUTPUT[0] != 32'd0: 277 | REGFILE[IF_ID_IR[1][6:10]] != 32'd0)) 278 | || 279 | IF_ID_IR[1][0:5] == JR || IF_ID_IR[1][0:5] == J || IF_ID_IR[1][0:5] == CALL || IF_ID_IR[1][0:5] == CALLR; 280 | 281 | reg [5:0] i; 282 | reg finish; 283 | 284 | /************** The initial cpu state bootstrap **************************/ 285 | initial begin 286 | PC = 0; 287 | finish =0; 288 | $readmemh("bincode.rom",IMEM); 289 | IF_ID_IR[0] = 32'b0; IF_ID_IR[1] = 32'b0; 290 | ID_EX_IR[0] = 32'b0; ID_EX_IR[1] = 32'b0; 291 | EX_MEM_IR[0] = 32'b0; EX_MEM_IR[1] = 32'b0; 292 | MEM_WB_IR[0] = 32'b0; MEM_WB_IR[1] = 32'b0; 293 | 294 | /*** Test Program Branch ************************************/ 295 | 296 | /*IMEM[0] = { MVI , 5'd0, 5'd1, 16'd0 }; //R1 <- 2 297 | IMEM[1] = { MVI , 5'd0, 5'd3, 16'd0 }; //R3 <- 0 298 | 299 | IMEM[2] = { NOP , 26'd0 }; //NOP 300 | IMEM[3] = { NOP , 26'd0 }; //NOP 301 | 302 | IMEM[4] = { MVI , 5'd0, 5'd3, 16'd1 }; //R3 <- 1 303 | IMEM[5] = { BNEZ , 5'd1, 21'd7 }; //R1 != 0 goto 7 304 | 305 | IMEM[6] = { MVI , 5'd0, 5'd3, 16'd2 }; //R3 <- 2 306 | IMEM[7] = { HALT , 26'd0 }; //HALT 307 | */ 308 | /*** Basic Program Branch (Returns the number of occurences of a number in an array)************************************ 309 | IMEM[0] = { MVI , 5'd0, 5'd31, -16'd1 }; //R31 <- -1 ; 310 | IMEM[1] = { MVI , 5'd0, 5'd1, 16'd10 }; //R1 <- 10 ; ********** SEED POINT 311 | 312 | IMEM[2] = { MV , 5'd1, 5'd0, 5'd2,11'd0 }; //R2<-R1 313 | IMEM[3] = { SUBI , 5'd1, 5'd1, 16'd1 }; //R1 <- R1-1 314 | 315 | IMEM[4] = { ADDI , 5'd31, 5'd31, 16'd1 }; //R31 <- R31+1 316 | IMEM[5] = { NOP , 26'd0 }; 317 | 318 | IMEM[6] = { SW, 5'd31, 5'd1, 16'd0 }; //M[R31] <- R1 319 | IMEM[7] = { SUBI , 5'd2, 5'd2, 16'd1 }; //R2 <- R2-1 320 | 321 | IMEM[8] = { NOP , 26'd0 }; //NOP 322 | IMEM[9] = { NOP , 26'd0 }; //NOP 323 | 324 | IMEM[10] = { BNEZ, 5'd2, 5'd0, 16'd4 }; // R2 != 0 ? Jump to 4 325 | IMEM[11] = { NOP , 26'd0 }; //NOP 326 | 327 | IMEM[12] = { BNEZ, 5'd1, 5'd0, 16'd2 }; // R1 != 0 ? Jump to 2 328 | IMEM[13] = { NOP , 26'd0 }; //NOP 329 | 330 | 331 | IMEM[14] = { MVI , 5'd0, 5'd30, 16'd5 }; //R30 <- 5 ;QUERY************** 332 | IMEM[15] = { MVI , 5'd0, 5'd29, 16'd0 }; //R29 <- 0 ; Count number of matches -1 333 | 334 | IMEM[16] = { LW ,5'd31, 5'd2, 16'd0 }; // R2 <- M[R31] 335 | IMEM[17] = { SUBI , 5'd31, 5'd31, 16'd1 }; //R31 <- R31-1 336 | 337 | IMEM[18] = { EQI , 5'd31, 5'd7, -16'd1 }; // R7 <- R31 == -1 338 | IMEM[19] = { NOP , 26'd0 }; //NOP 339 | 340 | IMEM[20] = { NOP , 26'd0 }; //NOP 341 | IMEM[21] = { NOP , 26'd0 }; //NOP 342 | 343 | IMEM[22] = { BNEZ, 5'd7, 5'd0, 16'd32 }; // R7 != 0 ? Jump to 32 344 | IMEM[23] = { EQ , 5'd30, 5'd2, 5'd6, 11'd0 }; // R6 <- R30 == R2 345 | 346 | IMEM[24] = { NOP , 26'd0 }; //NOP 347 | IMEM[25] = { NOP , 26'd0 }; //NOP 348 | 349 | IMEM[26] = { BEQZ, 5'd6, 5'd0, 16'd16 }; // R6 == 0 ? Jump to 16 350 | IMEM[27] = { NOP , 26'd0 }; //NOP 351 | 352 | IMEM[28] = { ADDI , 5'd29, 5'd29, 16'd1 }; //R29<- R29+1 353 | IMEM[29] = {J , 26'd16 }; //Jump to 16 354 | 355 | IMEM[30] = { NOP , 26'd0 }; //NOP 356 | IMEM[31] = { NOP , 26'd0 }; //NOP 357 | 358 | IMEM[32] = { HALT , 26'd0 }; //HALT 359 | IMEM[33] = { NOP , 26'd0 }; //NOP 360 | */ 361 | end 362 | 363 | always @ (posedge clk) begin 364 | //IF STAGE 365 | //Computation 366 | if (~branchtaken[0] && ~branchtaken[1]) begin 367 | if(one_cycle_stall) begin 368 | IF_ID_IR[0] <= IMEM[PC-1]; 369 | IF_ID_IR[1] <= IMEM[PC]; 370 | PC <= PC + 1; 371 | end else begin 372 | IF_ID_IR[0] <= IMEM[PC]; 373 | IF_ID_IR[1] <= IMEM[PC + 1]; 374 | PC <= PC + 2; 375 | end 376 | end else begin /****We Ignore the possibility that both instructions in a single is is going to be branches****************/ 377 | //Incur one stall for branches 378 | IF_ID_IR[0] <= 32'd0; IF_ID_IR[1] <= 32'd0; 379 | 380 | if(IF_ID_IR[0][0:5] == BEQZ | IF_ID_IR[0][0:5] == BNEZ) begin 381 | PC <= { {16{IF_ID_IR[0][16]}},IF_ID_IR[0][16:31]}; 382 | end else if(IF_ID_IR[0][0:5] == J) begin 383 | PC <= { {6{IF_ID_IR[0][6]}},IF_ID_IR[0][6:31]}; 384 | end else if(IF_ID_IR[0][0:5] == JR) begin 385 | PC <= REGFILE[IF_ID_IR[0][6:10]]; 386 | end else if(IF_ID_IR[0][0:5] == CALL) begin 387 | REGFILE[31] <= PC; 388 | PC <= { {6{IF_ID_IR[0][6]}},IF_ID_IR[0][6:31]}; 389 | end else if(IF_ID_IR[0][0:5] == CALLR) begin 390 | REGFILE[31] <= PC; 391 | PC <= REGFILE[IF_ID_IR[0][6:10]]; 392 | end else if(IF_ID_IR[1][0:5] == BEQZ | IF_ID_IR[1][0:5] == BNEZ) begin 393 | PC <= { {16{IF_ID_IR[1][16]}},IF_ID_IR[1][16:31]}; 394 | end else if(IF_ID_IR[1][0:5] == J) begin 395 | PC <= { {6{IF_ID_IR[1][6]}},IF_ID_IR[1][6:31]}; 396 | end else if(IF_ID_IR[1][0:5] == JR) begin 397 | PC <= REGFILE[IF_ID_IR[1][6:10]]; 398 | end else if(IF_ID_IR[1][0:5] == CALL) begin 399 | REGFILE[31] <= PC; 400 | PC <= { {6{IF_ID_IR[1][6]}},IF_ID_IR[1][6:31]}; 401 | end else if(IF_ID_IR[1][0:5] == CALLR) begin 402 | REGFILE[31] <= PC; 403 | PC <= REGFILE[IF_ID_IR[1][6:10]]; 404 | end 405 | end 406 | 407 | 408 | // ID STAGE 409 | //Computation 410 | ID_EX_A[0] <= REGFILE[IF_ID_IR[0][6:10]]; 411 | ID_EX_A[1] <= REGFILE[IF_ID_IR[1][6:10]]; 412 | ID_EX_B[0] <= REGFILE[IF_ID_IR[0][11:15]]; 413 | ID_EX_B[1] <= REGFILE[IF_ID_IR[1][11:15]]; 414 | ID_EX_IMM[0] <= { {16{IF_ID_IR[0][16]}},IF_ID_IR[0][16:31]}; 415 | ID_EX_IMM[1] <= { {16{IF_ID_IR[1][16]}},IF_ID_IR[1][16:31]}; 416 | 417 | //Buffering 418 | ID_EX_IR[0] <= IF_ID_IR[0]; 419 | 420 | if(one_cycle_stall) begin 421 | ID_EX_IR[1] <= 32'd0; 422 | end else begin 423 | ID_EX_IR[1] <= IF_ID_IR[1]; 424 | end 425 | 426 | // EX STAGE 427 | //Computation 428 | case (ID_EX_OP[0]) 429 | LW , LB , LBU , LH: begin EX_MEM_ALUOUTPUT[0] <= Ain[0] + ID_EX_IMM[0]; end 430 | SW , SB , SH: begin EX_MEM_ALUOUTPUT[0] <= Ain[0] + ID_EX_IMM[0]; end 431 | ADD : begin EX_MEM_ALUOUTPUT[0] <= Ain[0] + Bin[0]; end 432 | SUB : begin EX_MEM_ALUOUTPUT[0] <= Ain[0] - Bin[0]; end 433 | MULT : begin EX_MEM_ALUOUTPUT[0] <= Ain[0] * Bin[0]; end 434 | DIV : begin EX_MEM_ALUOUTPUT[0] <= Ain[0] / Bin[0]; end 435 | AND : begin EX_MEM_ALUOUTPUT[0] <= Ain[0] & Bin[0]; end 436 | OR : begin EX_MEM_ALUOUTPUT[0] <= Ain[0] | Bin[0]; end 437 | XOR : begin EX_MEM_ALUOUTPUT[0] <= Ain[0] ^ Bin[0]; end 438 | SLT : begin 439 | if(Ain[0] < Bin[0]) begin 440 | EX_MEM_ALUOUTPUT[0] <= 1; 441 | end else begin 442 | EX_MEM_ALUOUTPUT[0] <= 0; 443 | end 444 | end 445 | SGT : begin 446 | if(Ain[0] > Bin[0]) begin 447 | EX_MEM_ALUOUTPUT[0] <= 1; 448 | end else begin 449 | EX_MEM_ALUOUTPUT[0] <= 0; 450 | end 451 | end 452 | SLE : begin 453 | if(Ain[0] <= Bin[0]) begin 454 | EX_MEM_ALUOUTPUT[0] <= 1; 455 | end else begin 456 | EX_MEM_ALUOUTPUT[0] <= 0; 457 | end 458 | end 459 | SGE : begin 460 | if(Ain[0] >= Bin[0]) begin 461 | EX_MEM_ALUOUTPUT[0] <= 1; 462 | end else begin 463 | EX_MEM_ALUOUTPUT[0] <= 0; 464 | end 465 | end 466 | EQ : begin 467 | if(Ain[0] == Bin[0]) begin 468 | EX_MEM_ALUOUTPUT[0] <= 1; 469 | end else begin 470 | EX_MEM_ALUOUTPUT[0] <= 0; 471 | end 472 | end 473 | NEQ : begin 474 | if(Ain[0] != Bin[0]) begin 475 | EX_MEM_ALUOUTPUT[0] <= 1; 476 | end else begin 477 | EX_MEM_ALUOUTPUT[0] <= 0; 478 | end 479 | end 480 | MV : begin EX_MEM_ALUOUTPUT[0] <= Ain[0]; end 481 | ADDI : begin EX_MEM_ALUOUTPUT[0] <= Ain[0] + ID_EX_IMM[0]; end 482 | SUBI : begin EX_MEM_ALUOUTPUT[0] <= Ain[0] - ID_EX_IMM[0]; end 483 | MULTI : begin EX_MEM_ALUOUTPUT[0] <= Ain[0] * ID_EX_IMM[0]; end 484 | DIVI : begin EX_MEM_ALUOUTPUT[0] <= Ain[0] / ID_EX_IMM[0]; end 485 | ANDI : begin EX_MEM_ALUOUTPUT[0] <= Ain[0] & ID_EX_IMM[0]; end 486 | ORI : begin EX_MEM_ALUOUTPUT[0] <= Ain[0] | ID_EX_IMM[0]; end 487 | XORI : begin EX_MEM_ALUOUTPUT[0] <= Ain[0] ^ ID_EX_IMM[0]; end 488 | SLTI : begin 489 | if(Ain[0] < ID_EX_IMM[0]) begin 490 | EX_MEM_ALUOUTPUT[0] <= 1; 491 | end else begin 492 | EX_MEM_ALUOUTPUT[0] <= 0; 493 | end 494 | 495 | end 496 | SGTI : begin 497 | if(Ain[0] > ID_EX_IMM[0]) begin 498 | EX_MEM_ALUOUTPUT[0] <= 1; 499 | end else begin 500 | EX_MEM_ALUOUTPUT[0] <= 0; 501 | end 502 | 503 | end 504 | SLEI : begin 505 | if(Ain[0] <= ID_EX_IMM[0]) begin 506 | EX_MEM_ALUOUTPUT[0] <= 1; 507 | end else begin 508 | EX_MEM_ALUOUTPUT[0] <= 0; 509 | end 510 | 511 | end 512 | SGEI : begin 513 | if(Ain[0] >= ID_EX_IMM[0]) begin 514 | EX_MEM_ALUOUTPUT[0] <= 1; 515 | end else begin 516 | EX_MEM_ALUOUTPUT[0] <= 0; 517 | end 518 | 519 | end 520 | EQI : begin 521 | if(Ain[0] == ID_EX_IMM[0]) begin 522 | EX_MEM_ALUOUTPUT[0] <= 1; 523 | end else begin 524 | EX_MEM_ALUOUTPUT[0] <= 0; 525 | end 526 | 527 | end 528 | NEQI : begin 529 | if(Ain[0] != ID_EX_IMM[0]) begin 530 | EX_MEM_ALUOUTPUT[0] <= 1; 531 | end else begin 532 | EX_MEM_ALUOUTPUT[0] <= 0; 533 | end 534 | 535 | end //REGFILE 536 | MVI : begin EX_MEM_ALUOUTPUT[0] <= ID_EX_IMM[0]; end 537 | RET: begin EX_MEM_ALUOUTPUT[0] <= REGFILE[31]; end 538 | NOP: begin end 539 | HALT: begin 540 | finish =1; 541 | end 542 | default: begin end 543 | endcase 544 | 545 | //Computation 546 | case (ID_EX_OP[1]) 547 | LW , LB , LBU , LH: begin EX_MEM_ALUOUTPUT[1] <= Ain[1] + ID_EX_IMM[1]; end 548 | SW , SB , SH: begin EX_MEM_ALUOUTPUT[1] <= Ain[1] + ID_EX_IMM[1]; end 549 | ADD : begin EX_MEM_ALUOUTPUT[1] <= Ain[1] + Bin[1]; end 550 | SUB : begin EX_MEM_ALUOUTPUT[1] <= Ain[1] - Bin[1]; end 551 | MULT : begin EX_MEM_ALUOUTPUT[1] <= Ain[1] * Bin[1]; end 552 | DIV : begin EX_MEM_ALUOUTPUT[1] <= Ain[1] / Bin[1]; end 553 | AND : begin EX_MEM_ALUOUTPUT[1] <= Ain[1] & Bin[1]; end 554 | OR : begin EX_MEM_ALUOUTPUT[1] <= Ain[1] | Bin[1]; end 555 | XOR : begin EX_MEM_ALUOUTPUT[1] <= Ain[1] ^ Bin[1]; end 556 | SLT : begin 557 | if(Ain[1] < Bin[1]) begin 558 | EX_MEM_ALUOUTPUT[1] <= 1; 559 | end else begin 560 | EX_MEM_ALUOUTPUT[1] <= 0; 561 | end 562 | end 563 | SGT : begin 564 | if(Ain[1] > Bin[1]) begin 565 | EX_MEM_ALUOUTPUT[1] <= 1; 566 | end else begin 567 | EX_MEM_ALUOUTPUT[1] <= 0; 568 | end 569 | end 570 | SLE : begin 571 | if(Ain[1] <= Bin[1]) begin 572 | EX_MEM_ALUOUTPUT[1] <= 1; 573 | end else begin 574 | EX_MEM_ALUOUTPUT[1] <= 0; 575 | end 576 | end 577 | SGE : begin 578 | if(Ain[1] >= Bin[1]) begin 579 | EX_MEM_ALUOUTPUT[1] <= 1; 580 | end else begin 581 | EX_MEM_ALUOUTPUT[1] <= 0; 582 | end 583 | end 584 | EQ : begin 585 | if(Ain[1] == Bin[1]) begin 586 | EX_MEM_ALUOUTPUT[1] <= 1; 587 | end else begin 588 | EX_MEM_ALUOUTPUT[1] <= 0; 589 | end 590 | end 591 | NEQ : begin 592 | if(Ain[1] != Bin[1]) begin 593 | EX_MEM_ALUOUTPUT[1] <= 1; 594 | end else begin 595 | EX_MEM_ALUOUTPUT[1] <= 0; 596 | end 597 | end 598 | MV : begin EX_MEM_ALUOUTPUT[1] <= Ain[1]; end 599 | ADDI : begin EX_MEM_ALUOUTPUT[1] <= Ain[1] + ID_EX_IMM[1]; end 600 | SUBI : begin EX_MEM_ALUOUTPUT[1] <= Ain[1] - ID_EX_IMM[1]; end 601 | MULTI : begin EX_MEM_ALUOUTPUT[1] <= Ain[1] * ID_EX_IMM[1]; end 602 | DIVI : begin EX_MEM_ALUOUTPUT[1] <= Ain[1] / ID_EX_IMM[1]; end 603 | ANDI : begin EX_MEM_ALUOUTPUT[1] <= Ain[1] & ID_EX_IMM[1]; end 604 | ORI : begin EX_MEM_ALUOUTPUT[1] <= Ain[1] | ID_EX_IMM[1]; end 605 | XORI : begin EX_MEM_ALUOUTPUT[1] <= Ain[1] ^ ID_EX_IMM[1]; end 606 | SLTI : begin 607 | if(Ain[1] < ID_EX_IMM[1]) begin 608 | EX_MEM_ALUOUTPUT[1] <= 1; 609 | end else begin 610 | EX_MEM_ALUOUTPUT[1] <= 0; 611 | end 612 | 613 | end 614 | SGTI : begin 615 | if(Ain[1] > ID_EX_IMM[1]) begin 616 | EX_MEM_ALUOUTPUT[1] <= 1; 617 | end else begin 618 | EX_MEM_ALUOUTPUT[1] <= 0; 619 | end 620 | 621 | end 622 | SLEI : begin 623 | if(Ain[1] <= ID_EX_IMM[1]) begin 624 | EX_MEM_ALUOUTPUT[1] <= 1; 625 | end else begin 626 | EX_MEM_ALUOUTPUT[1] <= 0; 627 | end 628 | 629 | end 630 | SGEI : begin 631 | if(Ain[1] >= ID_EX_IMM[1]) begin 632 | EX_MEM_ALUOUTPUT[1] <= 1; 633 | end else begin 634 | EX_MEM_ALUOUTPUT[1] <= 0; 635 | end 636 | 637 | end 638 | EQI : begin 639 | if(Ain[1] == ID_EX_IMM[1]) begin 640 | EX_MEM_ALUOUTPUT[1] <= 1; 641 | end else begin 642 | EX_MEM_ALUOUTPUT[1] <= 0; 643 | end 644 | 645 | end 646 | NEQI : begin 647 | if(Ain[1] != ID_EX_IMM[1]) begin 648 | EX_MEM_ALUOUTPUT[1] <= 1; 649 | end else begin 650 | EX_MEM_ALUOUTPUT[1] <= 0; 651 | end 652 | 653 | end 654 | MVI : begin EX_MEM_ALUOUTPUT[1] <= ID_EX_IMM[1]; end 655 | RET: begin EX_MEM_ALUOUTPUT[1] <= REGFILE[31]; end 656 | NOP: begin end 657 | HALT: begin 658 | finish =1; 659 | end 660 | default: begin end 661 | endcase 662 | 663 | //Buffering 664 | EX_MEM_IR[0] <= ID_EX_IR[0]; EX_MEM_B[0] <= Bin[0]; 665 | EX_MEM_IR[1] <= ID_EX_IR[1]; EX_MEM_B[1] <= Bin[1]; 666 | 667 | //MEM STAGE 668 | //Computation 669 | if (EX_MEM_OP[0] >= LW && EX_MEM_OP[0] <= LH) MEM_WB_LMD[0] <= DMEM[EX_MEM_ALUOUTPUT[0]]; 670 | else if (EX_MEM_OP[0] >= SW && EX_MEM_OP[0] <= SH) DMEM[EX_MEM_ALUOUTPUT[0]] <= EX_MEM_B[0]; 671 | if (EX_MEM_OP[1] >= LW && EX_MEM_OP[1] <= LH) MEM_WB_LMD[1] <= DMEM[EX_MEM_ALUOUTPUT[1]]; 672 | else if (EX_MEM_OP[1] >= SW && EX_MEM_OP[1] <= SH) DMEM[EX_MEM_ALUOUTPUT[1]] <= EX_MEM_B[1]; 673 | 674 | //Buffering 675 | MEM_WB_IR[0] <= EX_MEM_IR[0]; 676 | MEM_WB_ALUOUTPUT[0] <= EX_MEM_ALUOUTPUT[0]; 677 | MEM_WB_IR[1] <= EX_MEM_IR[1]; 678 | MEM_WB_ALUOUTPUT[1] <= EX_MEM_ALUOUTPUT[1]; 679 | 680 | //WB STAGE 681 | //Computation 682 | case(MEM_WB_OP[0]) 683 | ADD, SUB , MULT, DIV ,AND ,OR , XOR ,SLT,SGT ,SLE, SGE ,EQ , NEQ , MV : REGFILE[MEM_WB_IR[0][16:20]] <= MEM_WB_ALUOUTPUT[0]; 684 | ADDI, SUBI , MULTI, DIVI ,ANDI ,ORI , XORI ,SLTI ,SGTI ,SLEI , SGEI ,EQI , NEQI , MVI : REGFILE[MEM_WB_IR[0][11:15]] <= MEM_WB_ALUOUTPUT[0]; 685 | LW , LB , LBU , LH : REGFILE[MEM_WB_IR[0][11:15]] = MEM_WB_LMD[0]; 686 | endcase 687 | 688 | case(MEM_WB_OP[1]) 689 | ADD, SUB , MULT, DIV ,AND ,OR , XOR ,SLT,SGT ,SLE, SGE ,EQ , NEQ , MV : REGFILE[MEM_WB_IR[1][16:20]] <= MEM_WB_ALUOUTPUT[1]; 690 | ADDI, SUBI , MULTI, DIVI ,ANDI ,ORI , XORI ,SLTI ,SGTI ,SLEI , SGEI ,EQI , NEQI , MVI :REGFILE[MEM_WB_IR[1][11:15]] <= MEM_WB_ALUOUTPUT[1]; 691 | LW , LB , LBU , LH : REGFILE[MEM_WB_IR[1][11:15]] = MEM_WB_LMD[1]; 692 | endcase 693 | end 694 | endmodule -------------------------------------------------------------------------------- /Superscaler_Processor_Design_Issue_2/testbench.v: -------------------------------------------------------------------------------- 1 | 2 | // ============================================================================ 3 | // TESTBENCH FOR SUPERSCALAR CPU CORE 4 | // ============================================================================ 5 | 6 | module tb (); 7 | reg clk; 8 | 9 | 10 | superscalar_cpu cpu ( 11 | clk 12 | ); 13 | 14 | initial begin 15 | clk = 1; 16 | #13000 clk = 0; 17 | $stop; 18 | end 19 | 20 | always clk = #1 ~clk; 21 | 22 | endmodule 23 | --------------------------------------------------------------------------------