指令集并行流水线CPU设计

来源:互联网 发布:linux源码搭建lamp 编辑:程序博客网 时间:2024/04/29 23:57

ISE环境,verilog编写:



`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date:    15:04:43 07/02/2015 // Design Name: // Module Name:    PC // Project Name: // Target Devices: // Tool versions: // Description: //// Dependencies: //// Revision: // Revision 0.01 - File Created// Additional Comments: ////////////////////////////////////////////////////////////////////////////////////module PC(CLK_OUT1,Jump,Branch2,zero_flow,ImemRdAddr,Ext_Im,Ins);input CLK_OUT1;input Jump,Branch2,zero_flow;input [31:0]Ext_Im;input  [31:0]Ins;output [31:0] ImemRdAddr;reg [31:0] next_pc;reg [31:0] ImemRdAddr;initialbegin   ImemRdAddr=-4;endalways@(posedge CLK_OUT1)begin    next_pc=ImemRdAddr+4;if(Jump)                                           //若是jump指令,取当前PC基址+偏移量      next_pc={next_pc[31:28],(Ins[25:0]<<2)};else                                               //否则,若是分支指令,段内跳转     if(Branch2&zero_flow)      next_pc=next_pc+(Ext_Im<<2);<span style="white-space:pre"></span>    ImemRdAddr=next_pc;endendmodule<pre name="code" class="plain">`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date:    09:24:28 07/02/2015 // Design Name: // Module Name:    instr_memory // Project Name: // Target Devices: // Tool versions: // Description: //// Dependencies: //// Revision: // Revision 0.01 - File Created// Additional Comments: ////////////////////////////////////////////////////////////////////////////////////module instr_memory(CLK_OUT1,ImemRdAddr,Ins0);input CLK_OUT1;input[31:0] ImemRdAddr;output[31:0] Ins0;reg[31:0] Ins0;reg[31:0] InstMem [0:255];                      //指令存储器的大小initial begin   $readmemh("Instruction.txt",InstMem);       //读指令文件endalways @(ImemRdAddr)begin    Ins0 <= InstMem[ImemRdAddr/4];              //注意点%4endendmodule

`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date:    09:17:40 07/05/2015 // Design Name: // Module Name:    IF_ID // Project Name: // Target Devices: // Tool versions: // Description: //// Dependencies: //// Revision: // Revision 0.01 - File Created// Additional Comments: ////////////////////////////////////////////////////////////////////////////////////module IF_ID(CLK_OUT1,Ins0,Ins);input CLK_OUT1;input [31:0]Ins0;output[31:0] Ins;reg[31:0] Ins; always@(posedge CLK_OUT1) begin            Ins=Ins0; endendmodule

`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date:    16:01:04 07/01/2015 // Design Name: // Module Name:    ctrl // Project Name: // Target Devices: // Tool versions: // Description: //// Dependencies: //// Revision: // Revision 0.01 - File Created// Additional Comments: ////////////////////////////////////////////////////////////////////////////////////module ctrl(CLK_OUT1,rst,Ins,RegDst,Branch,MemRead,MemtoReg,MemWrite,ALUSrc,RegWrite,Jump,ALU_Ctrl);input CLK_OUT1;input rst;input[31:0] Ins; output Jump;            //控制跳转output Branch;          //分支控制output MemRead;         //读数据output MemtoReg;        //读数据到寄存器组output MemWrite;        //写到存储器output [3:0] ALU_Ctrl;   //控制ALUoutput ALUSrc;          //alu操作数来源output RegWrite;        //写到寄存器组output RegDst;           //reg[5:0] IR_26_31;       //存放指令高六位操作码  针对IR指令 reg[5:0] funct;          //存放指令高六位操作码  针对IR指令reg RegDst=1;            // 有效时  写寄存器的目标寄存器号来自rd字段(位15:11)                         //无效时    写寄存器的目标寄存器号来自rt字段(位20:16)reg Branch=0;            //是否分支reg MemRead=0;            //是否d在存储器读reg MemtoReg=0;           // reg [3:0] ALU_Ctrl=4'b0000;     //reg MemWrite=0;reg ALUSrc=0;            //有效时,第二个ALU操作数为指令低16位的符号扩展                          //无效时  第二个ALU操作数来自寄存器堆的第二个输出(读数据2)reg RegWrite=0;reg Jump=0;parameter  // 常量的设定:对应IR的高六位opcode,判断指令类型   R_type=6'b000000,   LW_type=6'b100011,   SW_type=6'b101011,   BEQ_type=6'b000100,BGEZ=6'b000001,BNE=6'b000101,ADDI=6'b001000,   ANDI=6'b001100,LUI=6'b001111,                  //立即数加载至高位ORI=6'b001101,XORI=6'b001110,JAL=6'b000011,               //跳转并连接:跳转后,GPR[31] 《-PC + 4,是函数指令,PC 转向被调用函数   JUMP=6'b000010;//funct编码parametermyadd=6'b100000,mysub=6'b100010,myand=6'b100100,myor=6'b100101,mylessthan=6'b101010,myxor=6'b100110,mynor=6'b100111,mysllv=6'b000100,mysrlv=6'b000110;always@(Ins)begin   IR_26_31=Ins[31:26];   funct=Ins[5:0]; case(IR_26_31)                R_type :  begin              //寄存器-寄存器指令                 RegDst<=1'b1;        //目的操作数写到A3                  ALUSrc<=1'b0;             MemtoReg<=1'b0;            //不需要从存储器读数据到寄存器             RegWrite<=1'b1;            //需要往寄存器组写结果 (所有的R指令都写)             MemRead<=1'b0;              //不需要读存储器             MemWrite<=1'b0;              //    xie             Branch<=1'b0;               Jump<=0;                          if(funct==myadd)   ALU_Ctrl<=4'b0010;else if(funct==mysub)                  ALU_Ctrl<=4'b0110;else if(funct==myand)   ALU_Ctrl<=4'b0000;else if(funct==myor)   ALU_Ctrl<=4'b0001;else if(funct==mylessthan)                  ALU_Ctrl<=4'b0111;               else if(funct==myxor)                  ALU_Ctrl<=4'b1000;               else if(funct==mynor)                 ALU_Ctrl<=4'b1001;               else if(funct==mysllv)                  ALU_Ctrl<=4'b1010;               else if(funct==mysrlv)                  ALU_Ctrl<=4'b1011;               end     LW_type:  begin              RegDst<=1'b0;                    ALUSrc<=1'b1;             MemtoReg<=1'b1;             RegWrite<=1'b1;               //往寄存器写结果             MemRead<=1'b1;             MemWrite<=1'b0;             Branch<=1'b0;             Jump<=0; ALU_Ctrl<=4'b0010;              end      SW_type:begin             RegDst<=1'b1;                      ALUSrc<=1'b1;             MemtoReg<=1'bx;             RegWrite<=1'b0;             MemRead<=1'b0;             MemWrite<=1'b1;             Branch<=1'b0; Jump<=0; ALU_Ctrl<=4'b0010;              end       BEQ_type:begin             RegDst<=1'bx;             ALUSrc<=1'b0;             MemtoReg<=1'bx;             RegWrite<=1'b0;             MemRead<=1'b0;             MemWrite<=1'b0;             Branch<=1'b1;             Jump<=0; ALU_Ctrl<=4'b0110;              endBNE:begin             RegDst<=1'bx;             ALUSrc<=1'b0;             MemtoReg<=1'bx;             RegWrite<=1'b0;             MemRead<=1'b0;             MemWrite<=1'b0;             Branch<=1'b1;             Jump<=0; ALU_Ctrl<=4'b1110;              end  BGEZ:begin             RegDst<=1'bx;             ALUSrc<=1'b0;             MemtoReg<=1'bx;             RegWrite<=1'b0;             MemRead<=1'b0;             MemWrite<=1'b0;             Branch<=1'b1;             Jump<=0; ALU_Ctrl<=4'b1101;              end         JUMP: begin             RegDst<=1'b1;             ALUSrc<=1'b0;                     MemtoReg<=1'b0;             RegWrite<=1'b0;             MemRead<=1'b0;             MemWrite<=1'b0;             Branch<=1'b0; Jump<=1;             endJAL: begin             RegDst<=1'b1;             ALUSrc<=1'b0;                     MemtoReg<=1'b0;             RegWrite<=1'b1;             MemRead<=1'b0;             MemWrite<=1'b0;             Branch<=1'b0; Jump<=1;             end   ADDI:           begin             RegDst<=1'b0;             ALUSrc<=1'b1;                     MemtoReg<=1'b0;             RegWrite<=1'b1;             MemRead<=1'b0;             MemWrite<=1'b0;             Branch<=1'b0; Jump<=0; ALU_Ctrl<=4'b0010;             end   ANDI:           begin             RegDst<=1'b0;             ALUSrc<=1'b1;                     MemtoReg<=1'b0;             RegWrite<=1'b1;             MemRead<=1'b0;             MemWrite<=1'b0;             Branch<=1'b0; Jump<=0; ALU_Ctrl<=4'b0000;             end         LUI:           begin             RegDst<=1'b0;             ALUSrc<=1'b1;                     MemtoReg<=1'b0;             RegWrite<=1'b1;             MemRead<=1'b0;             MemWrite<=1'b0;             Branch<=1'b0; Jump<=0; ALU_Ctrl<=4'b1100;             end         ORI:           begin             RegDst<=1'b0;             ALUSrc<=1'b1;                     MemtoReg<=1'b0;             RegWrite<=1'b1;             MemRead<=1'b0;             MemWrite<=1'b0;             Branch<=1'b0; Jump<=0; ALU_Ctrl<=4'b0001;             end         XORI:           begin             RegDst<=1'b0;             ALUSrc<=1'b1;                     MemtoReg<=1'b0;             RegWrite<=1'b1;             MemRead<=1'b0;             MemWrite<=1'b0;             Branch<=1'b0; Jump<=0; ALU_Ctrl<=4'b1000;             end            default : begin              RegDst<=1'b1;             ALUSrc<=1'b0;             MemtoReg<=1'b0;             RegWrite<=1'b0;             MemRead<=1'b0;             MemWrite<=1'b0;             Branch<=1'b0;             Jump<=0;            end       endcaseendendmodule

`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date:    10:56:58 07/02/2015 // Design Name: // Module Name:    reg_file // Project Name: // Target Devices: // Tool versions: // Description: //// Dependencies: //// Revision: // Revision 0.01 - File Created// Additional Comments: ////////////////////////////////////////////////////////////////////////////////////module reg_file(Ins,CLK_OUT1,RegWrite3,RegDst,DatatoReg,RD10,RD20,Ext_Im0,Jump,ImemRdAddr,A30,A33,A10,A20);   input [31:0] Ins;input CLK_OUT1;input RegWrite3,RegDst;                            //控制信号input [31:0] DatatoReg;input Jump;input [31:0]ImemRdAddr;input [4:0]A33;output [31:0] RD10,RD20;output [31:0] Ext_Im0;output [4:0] A30;output [4:0]A10;output [4:0]A20;reg [4:0] A1,A2,A3,A30,A10,A20;reg [31:0] RD10,RD20;reg [31:0] Ext_Im0;reg [31:0] R_f [31:0];initial begin   $readmemh("D_F.txt",R_f);   //读文件endalways@( Ins)  //Ins posedge CLK_OUT1 orbegin      A1=Ins[25:21];   A2=Ins[20:16];    if(RegDst)                                 //确定数据来源    A3=Ins[15:11];    else        A3=Ins[20:16];    A30=A3;   Ext_Im0={16'h0000,Ins[15:0]};    A10=A1;A20=A2;   RD10=R_f[A1];RD20=R_f[A2];//if((Jump&RegWrite3)==1)//  R_f[31]=ImemRdAddr+4;endalways@( RegWrite3 or DatatoReg or A33)           //只有数据到来,而且是要写寄存器时情况才会被写入寄存器组 posedge CLK_OUT1 orbegin  if(RegWrite3)    R_f[A33]<=DatatoReg;  end  endmodule

`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date:    09:32:15 07/05/2015 // Design Name: // Module Name:    ID_EX // Project Name: // Target Devices: // Tool versions: // Description: //// Dependencies: //// Revision: // Revision 0.01 - File Created// Additional Comments: ////////////////////////////////////////////////////////////////////////////////////module ID_EX(CLK_OUT1,RD10,RD20,RD1,RD2,Ext_Im,Ext_Im0, Branch,MemRead,MemtoReg,MemWrite,ALUSrc,RegWrite,Jump,ALU_Ctrl,Branch1,MemRead1,MemtoReg1,MemWrite1,ALUSrc1,RegWrite1,Jump1,ALU_Ctrl1,A30,A31,A10,A20,A11,A21);input CLK_OUT1;input [31:0] RD10,RD20;input [31:0] Ext_Im0;input Jump;            //控制跳转input Branch;          //分支控制input MemRead;         //读数据input MemtoReg;        //读数据到寄存器组input MemWrite;        //写到存储器input [3:0] ALU_Ctrl;   //控制ALUinput ALUSrc;          //alu操作数来源input RegWrite;        //写到寄存器组input [4:0] A30;input [4:0] A10;input [4:0] A20;output [4:0] A11;output [4:0] A21;output [4:0] A31;output [31:0] RD1,RD2;output [31:0] Ext_Im;output Jump1;            //控制跳转output Branch1;          //分支控制output MemRead1;         //读数据output MemtoReg1;        //读数据到寄存器组output MemWrite1;        //写到存储器output [3:0] ALU_Ctrl1;   //控制ALUoutput ALUSrc1;          //alu操作数来源output RegWrite1;        //写到寄存器组reg [4:0]A31;reg [4:0]A11;reg [4:0]A21;reg [31:0] RD1,RD2;reg [31:0] Ext_Im;reg Jump1;            //控制跳转reg Branch1;          //分支控制reg MemRead1;         //读数据reg MemtoReg1;        //读数据到寄存器组reg MemWrite1;        //写到存储器reg [3:0] ALU_Ctrl1;   //控制ALUreg ALUSrc1;          //alu操作数来源reg RegWrite1;        //写到寄存器组always@(posedge CLK_OUT1)begin       A11<=A10; A21<=A20; A31<=A30;       RD1<=RD10; RD2<=RD20; Ext_Im<=Ext_Im0; Jump1<=Jump;                //控制跳转    Branch1<=Branch;           //分支控制    MemRead1<=MemRead;         //读数据    MemtoReg1<=MemtoReg;        //读数据到寄存器组    MemWrite1<=MemWrite;        //写到存储器    ALU_Ctrl1<=ALU_Ctrl;        //控制ALU    ALUSrc1<=ALUSrc;           //alu操作数来源    RegWrite1<=RegWrite;        //写到寄存器组end   endmodule

`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date:    14:58:43 07/02/2015 // Design Name: // Module Name:    ALU_src_opB // Project Name: // Target Devices: // Tool versions: // Description: //// Dependencies: //// Revision: // Revision 0.01 - File Created// Additional Comments: ////////////////////////////////////////////////////////////////////////////////////module ALU_src_opB(ALUSrc1,RD2,Ext_Im,op_B0);input ALUSrc1;input [31:0]RD2;input [31:0]Ext_Im;output [31:0]op_B0;reg [31:0]op_B0;always@(ALUSrc1 or RD2 or Ext_Im)begin   if(ALUSrc1)    op_B0=Ext_Im;         //立即数else      op_B0=RD2;endendmodule

`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date:    20:55:14 07/01/2015 // Design Name: // Module Name:    alu // Project Name: // Target Devices: // Tool versions: // Description: //// Dependencies: //// Revision: // Revision 0.01 - File Created// Additional Comments: ////////////////////////////////////////////////////////////////////////////////////module alu(CLK_OUT1,ALU_Ctrl1,RD1,op_B0,ans0,zero_flow0,A11,A21,RegWrite2,A32,ans);input CLK_OUT1;input [3:0] ALU_Ctrl1;input RegWrite2;input [31:0] ans;input [31:0] RD1;input [31:0] op_B0;input [4:0] A11,A21,A32;output [31:0] ans0;output zero_flow0;reg [31:0] ans0;reg zero_flow0;parameter      myLW =4'b0010,   mySW =4'b0010,   myBE=4'b0110,   myADD=4'b0010,   mySUB=4'b0110,   myAND=4'b0000,   myOR =4'b0001,   mySTL=4'b0111,myXOR=4'b1000,myNOR=4'b1001,mySLLV=4'b1010,mySRLV=4'b1011,myLUI=4'b1100,myBGEZ=4'b1101,myBNE=4'b1110;reg [31:0] op_A,op_B;always@(  ALU_Ctrl1 or RD1 or op_B0 )//posedge CLK_OUT1 orbegin op_A=RD1; op_B=op_B0;     if(RegWrite2==1)    begin    if(A11==A32)          op_A=ans;       if(A21==A32)    op_B=ans; end      case(ALU_Ctrl1)  myLW:  ans0=op_A+op_B;  mySW:  ans0=op_A+op_B;  myADD: ans0=op_A+op_B;        myBE: zero_flow0=(op_A==op_B?1'b1:1'b0);    mySUB: ans0=op_A-op_B;        myAND: ans0=op_A&op_B;  myOR:  ans0=op_A|op_B;  mySTL: ans0=op_A<op_B?1:0;  myXOR: ans0=op_A^op_B;  myNOR: ans0=~(op_A|op_B);  mySLLV: ans0=op_B<<op_A;  mySRLV: ans0=op_B>>op_A;  myLUI:  ans0=op_B<<16;  myBGEZ: zero_flow0=(op_A>=0?1:0);   myBNE:  zero_flow0=(op_A==op_B?1'b0:1'b1); endcase       endendmodule

`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date:    09:52:01 07/05/2015 // Design Name: // Module Name:    EX_MEM // Project Name: // Target Devices: // Tool versions: // Description: //// Dependencies: //// Revision: // Revision 0.01 - File Created// Additional Comments: ////////////////////////////////////////////////////////////////////////////////////module EX_MEM(CLK_OUT1,Branch1,MemRead1,MemtoReg1,MemWrite1,RegWrite1,Jump1, Branch2,MemRead2,MemtoReg2,MemWrite2,RegWrite2,Jump2,  RD2,ans0,RD21,ans,zero_flow0,zero_flow,  A31,A32    );input CLK_OUT1; input Jump1;            //控制跳转input Branch1;          //分支控制input MemRead1;         //读数据input MemtoReg1;        //读数据到寄存器组input MemWrite1;        //写到存储器input RegWrite1;        //写到寄存器组input [31:0] RD2;input [31:0]ans0;input zero_flow0;input [4:0]A31;output [4:0]A32;output [31:0] ans;output [31:0] RD21;output zero_flow;output Jump2;            //控制跳转output Branch2;          //分支控制output MemRead2;         //读数据output MemtoReg2;        //读数据到寄存器组output MemWrite2;        //写到存储器output RegWrite2;        //写到寄存器组reg [4:0]A32;reg [31:0] RD21;reg [31:0]  ans;reg zero_flow;reg Jump2;            //控制跳转reg Branch2;          //分支控制reg MemRead2;         //读数据reg MemtoReg2;        //读数据到寄存器组reg MemWrite2;        //写到存储器reg RegWrite2;        //写到寄存器组always@(posedge CLK_OUT1)begin RD21<=RD2; ans<=ans0; Jump2<=Jump1;               //控制跳转    Branch2<=Branch1;          //分支控制    MemRead2<=MemRead1;         //读数据    MemtoReg2<=MemtoReg1;        //读数据到寄存器组    MemWrite2<=MemWrite1;        //写到存储    RegWrite2<=RegWrite1;        //写到寄存器组 zero_flow<=zero_flow0;       A32<=A31;endendmodule

`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date:    09:32:21 07/02/2015 // Design Name: // Module Name:    data_memory // Project Name: // Target Devices: // Tool versions: // Description: //// Dependencies: //// Revision: // Revision 0.01 - File Created// Additional Comments: ////////////////////////////////////////////////////////////////////////////////////module data_memory(CLK_OUT1,Data_out0,MemWrite2,MemRead2,RD21,ans);input CLK_OUT1;input MemWrite2,MemRead2;      //读写控制信号input [31:0] ans ;            //ALU输出input [31:0] RD21;            //数据来源output [31:0] Data_out0;      //数据输出reg [31:0] Data_out0;reg [31:0] Dmem [0:255];     //数据内存reg [31:0] ADDR;            //地址initial begin   $readmemh("DM.txt",Dmem);//读指令文件endalways@(posedge CLK_OUT1 ) //or ans or MemRead2 or MemWrite2 begin                            if(MemRead2)     Data_out0=Dmem[ans];       //读内存    if(MemWrite2)        Dmem[ans]=RD21;           //写内存    endendmodule

`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date:    10:14:12 07/05/2015 // Design Name: // Module Name:    MEM_WB // Project Name: // Target Devices: // Tool versions: // Description: //// Dependencies: //// Revision: // Revision 0.01 - File Created// Additional Comments: ////////////////////////////////////////////////////////////////////////////////////module MEM_WB(CLK_OUT1,MemtoReg2,RegWrite2,MemtoReg3,RegWrite3,    Data_out0,ans,Data_out,ans1, A32,A33    );input CLK_OUT1; input MemtoReg2;        //读数据到寄存器组input RegWrite2;        //写到寄存器组input [31:0] Data_out0;input [31:0] ans;input [4:0]A32;output [4:0]A33;output MemtoReg3;        //读数据到寄存器组output RegWrite3;        //写到寄存器组output [31:0] Data_out;output [31:0] ans1;reg [4:0]A33;reg [31:0] ans1;reg [31:0] Data_out;reg MemtoReg3;        //读数据到寄存器组reg RegWrite3;        //写到寄存器组always@(posedge CLK_OUT1)begin Data_out<=Data_out0; ans1<=ans;    MemtoReg3<=MemtoReg2;        //读数据到寄存器组    RegWrite3<=RegWrite2;        //写到寄存器组       A33<=A32;endendmodule

`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date:    10:58:20 07/05/2015 // Design Name: // Module Name:    WB // Project Name: // Target Devices: // Tool versions: // Description: //// Dependencies: //// Revision: // Revision 0.01 - File Created// Additional Comments: ////////////////////////////////////////////////////////////////////////////////////module WB(CLK_OUT1,MemtoReg3,DatatoReg,       ans1,Data_out    );input CLK_OUT1; input MemtoReg3;        //读数据到寄存器组input [31:0] Data_out;input [31:0] ans1;output [31:0] DatatoReg;reg [31:0]DatatoReg;           // 二路选择器输出到寄存器组always@(Data_out or ans1 or MemtoReg3)begin  if(MemtoReg3)     DatatoReg=Data_out; else        DatatoReg=ans1;end  endmodule



1 0