├── screenshots ├── state.png └── guidline.jpg ├── tb.v ├── adder32bit.v ├── concatforJump.v ├── signExt.v ├── PC.v ├── shiftleft.v ├── IFID.v ├── MUX.v ├── RegFile.v ├── ALUcontrol.v ├── DM.v ├── README.md ├── ALU.v ├── Controlstall.v ├── MEMWB.v ├── IDEX.v ├── EXMEM.v ├── stall.v ├── controlunit.v ├── mypip.v └── InstMem.v /screenshots/state.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maze1377/pipeline-mips-verilog/HEAD/screenshots/state.png -------------------------------------------------------------------------------- /screenshots/guidline.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maze1377/pipeline-mips-verilog/HEAD/screenshots/guidline.jpg -------------------------------------------------------------------------------- /tb.v: -------------------------------------------------------------------------------- 1 | module TB; 2 | reg clk; 3 | initial begin 4 | clk=1'b0; 5 | end 6 | always 7 | begin 8 | //write your test here 9 | #3 clk=~clk; 10 | end 11 | Mypip sc1(clk); 12 | endmodule 13 | -------------------------------------------------------------------------------- /adder32bit.v: -------------------------------------------------------------------------------- 1 | module adder32bit(in1,in2,out); 2 | input [31:0]in1; 3 | input [31:0]in2; 4 | output [31:0]out; 5 | reg [31:0]out; 6 | always@(in1,in2)begin 7 | out=in1+in2; 8 | end 9 | endmodule 10 | -------------------------------------------------------------------------------- /concatforJump.v: -------------------------------------------------------------------------------- 1 | module concatForJump(part1, part2,result); 2 | input [3:0]part1; 3 | input [27:0]part2; 4 | output reg [31:0]result; 5 | always @(part1,part2)begin 6 | result={part1,part2}; 7 | end 8 | endmodule 9 | -------------------------------------------------------------------------------- /signExt.v: -------------------------------------------------------------------------------- 1 | module signExt(inData,outData); 2 | input[15:0] inData; 3 | output[31:0] outData; 4 | reg[31:0] outData; 5 | always@(inData) 6 | begin 7 | outData[15:0]=inData[15:0]; 8 | outData[31:16]={16{inData[15]}}; 9 | end 10 | endmodule 11 | -------------------------------------------------------------------------------- /PC.v: -------------------------------------------------------------------------------- 1 | module PCRegWrite(clock,in,out,enable); 2 | input [31:0] in; 3 | input clock,enable; 4 | output reg [31:0] out; 5 | 6 | initial begin 7 | out=32'b0; 8 | end 9 | always @(in) begin 10 | if(enable==1'b1) 11 | out=in; 12 | end 13 | endmodule 14 | -------------------------------------------------------------------------------- /shiftleft.v: -------------------------------------------------------------------------------- 1 | module shiftLeft32bitLeft(inData,outData); 2 | input[31:0] inData; 3 | output reg[31:0] outData; 4 | always@(inData)begin 5 | outData=inData<<2; 6 | end 7 | endmodule 8 | 9 | module shiftLeftForJump(inData,outData); 10 | input[25:0] inData; 11 | output reg[27:0] outData; 12 | always@(inData) 13 | begin 14 | outData={inData,2'b0}; 15 | end 16 | endmodule 17 | -------------------------------------------------------------------------------- /IFID.v: -------------------------------------------------------------------------------- 1 | module IFID(clock,nextPC,instrWireID,nextPCID,instrWireIF,enable); 2 | input clock, enable; 3 | input [31:0] nextPC; 4 | input [31:0] instrWireIF; 5 | output [31:0] nextPCID, instrWireID; 6 | reg [31:0] nextPCID,instrWireID; 7 | always @(posedge clock) begin 8 | if (enable) begin 9 | instrWireID <= instrWireIF; 10 | nextPCID <= nextPC; 11 | end 12 | end 13 | endmodule 14 | -------------------------------------------------------------------------------- /MUX.v: -------------------------------------------------------------------------------- 1 | module mux2(select,a,b,y); 2 | input select; 3 | input[31:0] a,b; 4 | output reg [31:0] y; 5 | always@(select,a,b) begin 6 | 7 | case(select) 8 | 1'b0:y=a; 9 | 1'b1:y=b; 10 | endcase 11 | end 12 | endmodule 13 | 14 | module mux2A(select,a,b,y); 15 | input select; 16 | input[4:0] a,b; 17 | output reg [4:0] y; 18 | always@(select,a,b) begin 19 | 20 | case(select) 21 | 1'b0:y=a; 22 | 1'b1:y=b; 23 | endcase 24 | end 25 | endmodule -------------------------------------------------------------------------------- /RegFile.v: -------------------------------------------------------------------------------- 1 | module RegFile (clk, readreg1, readreg2, writereg, writedata, RegWrite, readdata1, readdata2); 2 | input [4:0] readreg1, readreg2, writereg; 3 | input [31:0] writedata; 4 | input clk, RegWrite; 5 | output [31:0] readdata1, readdata2; 6 | 7 | reg [31:0] regfile [31:0]; 8 | integer i; 9 | initial begin 10 | for (i=1; i<32; i=i+1) 11 | begin 12 | regfile[i]=i*10; 13 | end 14 | end 15 | always @(posedge clk) 16 | begin 17 | if (RegWrite) 18 | regfile[writereg] <= writedata; 19 | regfile[0]=0; 20 | end 21 | 22 | assign readdata1 = regfile[readreg1]; 23 | assign readdata2 = regfile[readreg2]; 24 | endmodule 25 | 26 | -------------------------------------------------------------------------------- /ALUcontrol.v: -------------------------------------------------------------------------------- 1 | module ALUcontrol(clk,funct,ALUOp,ALUsignal); 2 | input clk; 3 | input[5:0] funct; 4 | input[2:0] ALUOp; 5 | output[3:0] ALUsignal; 6 | reg[3:0] ALUsignal; 7 | always@(funct , ALUOp ,posedge clk)begin 8 | case(ALUOp) 9 | 3'b010:case(funct) 10 | 6'b100000:ALUsignal=4'b00;//add 11 | 6'b100010:ALUsignal=4'b01;//sub 12 | 6'b100100:ALUsignal=4'b10;//and 13 | 6'b100101:ALUsignal=4'b11;//or 14 | 6'b101010:ALUsignal=4'b101;//stl 15 | endcase 16 | 3'b001:ALUsignal=4'b0001;//branch 17 | 3'b000:ALUsignal=4'b0000;//Lw and sw 18 | 3'b011:ALUsignal=4'b0010;//andi 19 | 3'b100:ALUsignal=4'b0011;//ori 20 | 3'b111:ALUsignal=4'b0101; //slti 21 | endcase 22 | end 23 | endmodule 24 | -------------------------------------------------------------------------------- /DM.v: -------------------------------------------------------------------------------- 1 | module DMemBank(input memread, input memwrite, input [31:0] address, input [31:0] writedata, output reg [31:0] readdata); 2 | 3 | reg [31:0] mem_array [127:0]; 4 | wire[6:0]finalAddress; 5 | assign finalAddress=address[8:0]; 6 | integer i; 7 | initial 8 | begin 9 | for (i=0; i<127; i=i+1) 10 | mem_array[i]=i*10; 11 | end 12 | 13 | always@(memread, memwrite, address, mem_array[address], writedata) 14 | begin 15 | if(memread)begin 16 | readdata=mem_array[finalAddress]; 17 | end 18 | 19 | if(memwrite) 20 | begin 21 | mem_array[finalAddress]= writedata; 22 | end 23 | 24 | end 25 | 26 | endmodule 27 | 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # MIPS pipline 3 | A classic 5-stage pipeline MIPS 32-bit processor. 4 | 5 | five stages of a microprocessor: instruction fetch (IF), 6 | instruction decode (ID), execution(EX), 7 | memory access and write (MEM) e write back (WB). 8 | 9 | #name of wire and guideline 10 | ![wirename](https://github.com/maze1377/pipeline-mips-verilog/blob/master/screenshots/guidline.jpg) 11 | 12 | #states 13 | ![state](https://github.com/maze1377/pipeline-mips-verilog/blob/master/screenshots/state.png) 14 | 15 | support most of MIPS instruction and solve every hazard with stall.(Data Hazards and Control Hazards) Verilog code. 16 | 17 | Developed during the winter 2019 Computer Architecture Laboratory course at the University of Ferdowsi Mashhad. 18 | # Modular design 19 | code start from mypip 20 | 21 | other modular named same to original model 22 | -------------------------------------------------------------------------------- /ALU.v: -------------------------------------------------------------------------------- 1 | module ALU(input [31:0] data1,data2,input [3:0] aluoperation,output reg [31:0] result,output reg zero,lt,gt); 2 | always@(aluoperation,data1,data2) 3 | begin 4 | case (aluoperation) 5 | 4'b0000 : result = data1 + data2; // ADD 6 | 4'b0001 : result = data1 - data2; // SUB 7 | 4'b0010 : result = data1 & data2; // AND 8 | 4'b0011 : result = data1 | data2; // OR 9 | 4'b0100 : result = data1 ^ data2; // XOR 10 | 4'b0101 : result = {31'b0,lt};//slt 11 | // if you want to add new Alu instructions add here 12 | default : result = data1 + data2; // ADD 13 | endcase 14 | if(data1>data2) 15 | begin 16 | gt = 1'b1; 17 | lt = 1'b0; 18 | end else if(data1>2; 16 | readdata=mem_array[temp]; 17 | end 18 | //////////////////////////////////////////////////////////////////////////////////////////////////////// test bench! 19 | //lvl 1 20 | /*mem_array[0]={6'b0,5'b10,5'b1,5'b11,5'b0,6'b100000};//add reg3,reg2,reg1 =30 21 | mem_array[1]={6'b0,5'b10,5'b1,5'b100,5'b0,6'b100010};//sub reg4,reg2,reg1 =10 22 | mem_array[2]={6'b0,5'b10,5'b1,5'b101,5'b0,6'b100101};//or reg5,reg2,reg1 =30 23 | mem_array[3]={6'b0,5'b10,5'b1,5'b110,5'b0,6'b100100};//and reg6,reg2,reg1 =0 24 | mem_array[4]={6'b0,5'b10,5'b1,5'b111,5'b0,6'b101010};//stl reg7,reg2,reg1 =0 25 | 26 | mem_array[5]={6'b001000,5'b10,5'b1000,16'b1010};//addi r8,r2,10 =30 27 | mem_array[6]={6'b001010,5'b10,5'b1001,16'b1010};//slti r9,r2,10 =0 28 | mem_array[7]={6'b001101,5'b10,5'b1010,16'b1010};//ori r10,r2,10 =30 29 | mem_array[8]={6'b001100,5'b10,5'b1011,16'b1010};//andi r11,r2,10 =0 30 | 31 | mem_array[9]={6'b101011,5'b10,5'b0,16'b1};//sw reg0,1(reg2) =mem[21]<=0 32 | mem_array[10]={6'b100011,5'b0,5'b1100,16'b0};//lw reg12,0(reg0) =reg[12]<=0 33 | */ 34 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////// 35 | //lvl 2 36 | /*mem_array[0]={6'b0,5'b10,5'b1,5'b11,5'b0,6'b100000};//add reg3,reg2,reg1 =30 37 | mem_array[1]={6'b0,5'b11,5'b1,5'b100,5'b0,6'b100010};//sub reg4,reg3,reg1 =20 38 | mem_array[2]={6'b0,5'b100,5'b1,5'b101,5'b0,6'b100101};//or reg5,reg4,reg1 =30 39 | mem_array[3]={6'b0,5'b10,5'b1,5'b110,5'b0,6'b100100};//and reg6,reg2,reg1 =0 40 | mem_array[4]={6'b0,5'b10,5'b1,5'b111,5'b0,6'b101010};//stl reg7,reg2,reg1 =0 41 | 42 | mem_array[5]={6'b001000,5'b10,5'b1000,16'b1010};//addi r8,r2,10 =30 43 | mem_array[6]={6'b001010,5'b1000,5'b1001,16'b1000000};//slti r9,r8,32 =1 44 | mem_array[7]={6'b001101,5'b10,5'b1010,16'b1010};//ori r10,r2,10 =30 45 | mem_array[8]={6'b001100,5'b1001,5'b1011,16'b1010};//andi r11,r9,10 =0 46 | 47 | mem_array[9]={6'b101011,5'b1010,5'b1011,16'b1};//sw reg11,1(reg10) =mem[31]<=0 48 | mem_array[10]={6'b100011,5'b1010,5'b1100,16'b01};//lw reg12,1(reg10) =reg[12]<=0*/ 49 | /////////////////////////////////////////////////////////////////////////////////////////////////////////// 50 | //lvl 3 51 | // mem_array[0]={6'b0,5'b10,5'b1,5'b11,5'b0,6'b100000};//add reg3,reg2,reg1 =30 52 | // mem_array[1]={6'b0,5'b11,5'b1,5'b100,5'b0,6'b100010};//sub reg4,reg3,reg1 =20 53 | // mem_array[2]={6'b0,5'b100,5'b1,5'b101,5'b0,6'b100101};//or reg5,reg4,reg1 =30 54 | 55 | // mem_array[3]={6'b100,5'b100,5'b101,16'b10};//beq r4,r5,2ta 56 | 57 | // mem_array[4]={6'b0,5'b10,5'b1,5'b110,5'b0,6'b100100};//and reg6,reg2,reg1 =0 58 | 59 | // mem_array[5]={6'b101,5'b110,5'b101,16'b1000};//bne r6,r5,2ta 60 | 61 | // mem_array[6]={6'b0,5'b10,5'b1,5'b111,5'b0,6'b101010};//stl reg7,reg2,reg1 =0 62 | 63 | // mem_array[7]={6'b10,26'b100};//jump lable4 13 ya 14 64 | 65 | // mem_array[8]={6'b001000,5'b10,5'b1000,16'b1010};//addi r8,r2,10 =30 66 | // mem_array[9]={6'b001010,5'b1000,5'b1001,16'b1000000};//slti r9,r8,32 =1 67 | // mem_array[10]={6'b001101,5'b10,5'b1010,16'b1010};//ori r10,r2,10 =30 68 | // mem_array[11]={6'b001100,5'b1001,5'b1011,16'b1010};//andi r11,r9,10 =0 69 | 70 | // mem_array[12]={6'b101011,5'b1010,5'b1011,16'b1};//sw reg11,1(reg10) =mem[31]<=0 71 | // mem_array[13]={6'b100011,5'b1010,5'b1100,16'b01};//lw reg12,1(reg10) =reg[12]<=0 72 | 73 | 74 | /* 75 | //r2=max , r3=min , r4=1 , r5=i , r6=adress , r7=current 76 | mem_array[0]={6'b001000,5'b0,5'b10,16'b1010};//addi r2,r0,10 77 | mem_array[1]={6'b001000,5'b0,5'b11,16'b1010};//addi r3,r0,10 78 | mem_array[2]={6'b001000,5'b0,5'b100,16'b1};//addi r4,r0,1 79 | mem_array[3]={6'b001000,5'b0,5'b101,16'b1};//addi r5,r0,1 80 | //loop: 81 | mem_array[4]={6'b0,5'b0,5'b00101,5'b00110,11'b0};//add r6,r0,r5 82 | mem_array[5]={6'b100011,5'b00110,5'b00111,16'b0};//lw r7,0(r6) 83 | mem_array[6]={6'b0,5'b10,5'b111,5'b01000,5'b0,6'b101010};//slt r8,r7,r2 84 | mem_array[7]={6'b100,5'b1000,5'b0,16'b10};//beq r8,r0,lable1 85 | mem_array[8]={6'b10,26'b1010};//jump lable2 adrese 9 ya 8 86 | //lable1 87 | mem_array[9]={6'b1000,5'b111,5'b10,16'b0};//addi r2,r7,0 88 | //lable2: 89 | mem_array[10]={6'b0,5'b11,5'b111,5'b1000,5'b0,6'b101010};//slt r8,r3,r7 90 | mem_array[11]={6'b100,5'b1000,5'b0,16'b10};//beq r8,r0,lable3 91 | mem_array[12]={6'b10,26'b1110};//jump lable4 13 ya 14 92 | //lable3: 93 | mem_array[13]={6'b1000,5'b111,5'b11,16'b0};//addi r3,r7,0 94 | //lable4 95 | mem_array[14]={6'b1000,5'b101,5'b101,16'b1};//addi r5,r5,1 96 | mem_array[15]={6'b1010,5'b100,5'b1001,16'b1011};//slti r9,r5,11 97 | mem_array[16]={6'b100,5'b1001,5'b100,16'b1111111111110100};//beq r9,r4,loop 98 | */ 99 | end 100 | endmodule 101 | 102 | --------------------------------------------------------------------------------