CPU之CPU_ctrl

来源:互联网 发布:软件开发基础知识 编辑:程序博客网 时间:2024/06/08 05:23
`include "defines.v"module CPU_ctrl(input wire[31:0] OpCode,input wire[4:0] Execute_reg,//判断是否相关input wire Is_First,//判断是第几次译码output reg stall_id,//来自译码阶段的暂停output reg stall_branch,//来自分支的暂停output reg Branch,output reg Jump,//跳转指令output reg MemRead,output reg MemtoReg,output reg MemWrite,output reg[5:0]  ALUControl_a,output reg[5:0]  ALUControl_b,output reg ALUSrc,output reg ALUSrc1,//选择另一个寄存器output reg RegWrite,output reg[1:0] RegDst);reg Is_load;  //判断是否是load指令always @(OpCode,Execute_reg,Is_First) begin //判断访存是否暂停if (Is_First==1'b1) beginif (Is_load==1'b1) beginif ((OpCode[25:21]==Execute_reg && OpCode[25:21]!=5'b00000)             || OpCode[20:16]==Execute_reg) beginstall_id<=1'b1;end else beginstall_id<=1'b0;endend else beginstall_id<=1'b0;endend else beginstall_id<=1'b0;endif (OpCode[31:26]==`lb || OpCode[31:26]==`lbu ||    OpCode[31:26]==`lh || OpCode[31:26]==`lhu ||    OpCode[31:26]==`lw || OpCode[31:26]==`lwl ||    OpCode[31:26]==`lwr) begin    Is_load<=1'b1;    end else begin    Is_load<=1'b0;    endendalways @(OpCode,Execute_reg,Is_First) begin//判断分支指令if (OpCode[31:26]==`Beq) beginstall_branch <= 1'b1;end else beginstall_branch <= 1'b0;endendalways @(OpCode,Execute_reg,Is_First) begin //**********************************case (OpCode[31:26]) `lb: beginRegDst<=2'b00;  //选择目标寄存器ALUSrc<=1;  //选择的是立即数作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=1;//主存到寄存器RegWrite<=1;//写寄存器MemRead<=1; //读存储器MemWrite<=0;//写存储器Branch<=0;  //分支指令Jump <=0;ALUControl_a <= OpCode[31:26];//操作码end`lbu: beginRegDst<=2'b00;  //选择目标寄存器ALUSrc<=1;  //选择的是立即数作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=1;//主存到寄存器RegWrite<=1;//写寄存器MemRead<=1; //读存储器MemWrite<=0;//写存储器Branch<=0;  //分支指令Jump <=0;ALUControl_a <= OpCode[31:26];//操作码end`lh: beginRegDst<=2'b00;  //选择目标寄存器ALUSrc<=1;  //选择的是立即数作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=1;//主存到寄存器RegWrite<=1;//写寄存器MemRead<=1; //读存储器MemWrite<=0;//写存储器Branch<=0;  //分支指令Jump <=0;ALUControl_a <= OpCode[31:26];//操作码end`lhu: beginRegDst<=2'b00;  //选择目标寄存器ALUSrc<=1;  //选择的是立即数作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=1;//主存到寄存器RegWrite<=1;//写寄存器MemRead<=1; //读存储器MemWrite<=0;//写存储器Branch<=0;  //分支指令Jump <=0;ALUControl_a <= OpCode[31:26];//操作码end`lw: beginRegDst<=2'b00;  //选择目标寄存器ALUSrc<=1;  //选择的是立即数作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=1;//主存到寄存器RegWrite<=1;//写寄存器MemRead<=1; //读存储器MemWrite<=0;//写存储器Branch<=0;  //分支指令Jump <=0;ALUControl_a <= OpCode[31:26];//操作码end`lwl: beginRegDst<=2'b00;  //选择目标寄存器ALUSrc<=1;  //选择的是立即数作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=1;//主存到寄存器RegWrite<=1;//写寄存器MemRead<=1; //读存储器MemWrite<=0;//写存储器Branch<=0;  //分支指令Jump <=0;ALUControl_a <= OpCode[31:26];//操作码end`lwr: beginRegDst<=2'b00;  //选择目标寄存器ALUSrc<=1;  //选择的是立即数作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=1;//主存到寄存器RegWrite<=1;//写寄存器MemRead<=1; //读存储器MemWrite<=0;//写存储器Branch<=0;  //分支指令  Jump <=0;ALUControl_a <= OpCode[31:26];//操作码end`sb : begin  RegDst <=2'b10;ALUSrc<=1;ALUSrc1<=0;//选择的是寄存器作为第一个操作数  MemtoReg<=0;RegWrite<=0;MemRead<=0;MemWrite<=1;Branch<=0;Jump <=0;ALUControl_a <= OpCode[31:26];//操作码end`sh : begin  RegDst<=2'b10;ALUSrc<=1;ALUSrc1<=0;//选择的是寄存器作为第一个操作数  MemtoReg<=0;RegWrite<=0;MemRead<=0;MemWrite<=1;Branch<=0;Jump <=0;ALUControl_a <= OpCode[31:26];//操作码end`sw: begin  RegDst <=2'b10;ALUSrc<=1;ALUSrc1<=0;//选择的是寄存器作为第一个操作数  MemtoReg <=0;RegWrite<=0;MemRead<=0;MemWrite<=1;Branch<=0;Jump <=0;ALUControl_a <= OpCode[31:26];//操作码end`swl: begin  RegDst<=2'b10;ALUSrc<=1;ALUSrc1<=0;//选择的是寄存器作为第一个操作数  MemtoReg<=0;RegWrite<=0;MemRead<=0;MemWrite<=1;Branch<=0;Jump <=0;ALUControl_a <= OpCode[31:26];//操作码end`swr: begin  RegDst<=2'b10;ALUSrc<=1;ALUSrc1<=0;//选择的是寄存器作为第一个操作数  MemtoReg<=0;RegWrite<=0;MemRead<=0;MemWrite<=1;Branch<=0;Jump <=0;ALUControl_a <= OpCode[31:26];//操作码end//逻辑操作指令`SPECIAL : begincase (OpCode[5:0]) `And : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器中的值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Or : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器中的值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Xor : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器中的值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Nor : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器中的值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Sll : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=1;  //选择的是立即数值作为第二个操作数    ALUSrc1<=1;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Srl : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=1;  //选择的是立即数值作为第二个操作数    ALUSrc1<=1;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Sra : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=1;  //选择的是立即数值作为第二个操作数    ALUSrc1<=1;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Sllv : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Srlv : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Srav : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Movn : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Movz : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Add : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Addu : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Sub : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Subu : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Slt : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码end`Sltu : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码endendcaseend`Andi : begin RegDst<=2'b00;  //选择目标寄存器 ALUSrc<=1;  //选择的是零扩展立即数值作为第二个操作数 ALUSrc1<=0;//选择的是寄存器作为第一个操作数 MemtoReg<=0;//主存到寄存器 RegWrite<=1;//写寄存器 MemRead<=0; //读存储器 MemWrite<=0;//写存储器 Branch<=0;  //分支指令 Jump <=0; ALUControl_a <= OpCode[31:26];//操作码 ALUControl_b <= OpCode[5:0];//子操作码end  `Xori : begin RegDst<=2'b00;  //选择目标寄存器 ALUSrc<=1;  //选择的是零扩展立即数值作为第二个操作数 ALUSrc1<=0;//选择的是寄存器作为第一个操作数 MemtoReg<=0;//主存到寄存器 RegWrite<=1;//写寄存器 MemRead<=0; //读存储器 MemWrite<=0;//写存储器 Branch<=0;  //分支指令 Jump <=0; ALUControl_a <= OpCode[31:26];//操作码 ALUControl_b <= OpCode[5:0];//子操作码end`Lui : begin RegDst<=2'b00;  //选择目标寄存器 ALUSrc<=1;  //选择的是零扩展立即数值作为第二个操作数 ALUSrc1<=0;//选择的是寄存器作为第一个操作数 MemtoReg<=0;//主存到寄存器 RegWrite<=1;//写寄存器 MemRead<=0; //读存储器 MemWrite<=0;//写存储器 Branch<=0;  //分支指令 Jump <=0; ALUControl_a <= OpCode[31:26];//操作码 ALUControl_b <= OpCode[5:0];//子操作码end`Ori : begin RegDst<=2'b00;  //选择目标寄存器 ALUSrc<=1;  //选择的是零扩展立即数值作为第二个操作数 ALUSrc1<=0;//选择的是寄存器作为第一个操作数 MemtoReg<=0;//主存到寄存器 RegWrite<=1;//写寄存器 MemRead<=0; //读存储器 MemWrite<=0;//写存储器 Branch<=0;  //分支指令 Jump <=0; ALUControl_a <= OpCode[31:26];//操作码 ALUControl_b <= OpCode[5:0];//子操作码end`SPECIAL2: begincase (OpCode[5:0])`Mul : beginRegDst<=2'b01;  //选择目标寄存器    ALUSrc<=0;  //选择的是寄存器值作为第二个操作数    ALUSrc1<=0;//选择的是寄存器作为第一个操作数    MemtoReg<=0;//主存到寄存器    RegWrite<=1;//写寄存器    MemRead<=0; //读存储器    MemWrite<=0;//写存储器    Branch<=0;  //分支指令    Jump <=0;    ALUControl_a <= OpCode[31:26];//操作码    ALUControl_b <= OpCode[5:0];//子操作码endendcaseend`Addi : beginRegDst<=2'b00;  //选择目标寄存器ALUSrc<=1;  //选择的是符号扩展值作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=0;//主存到寄存器RegWrite<=1;//写寄存器MemRead<=0; //读存储器MemWrite<=0;//写存储器Branch<=0;  //分支指令  Jump <=0;ALUControl_a <= OpCode[31:26];//操作码  ALUControl_b <= OpCode[5:0];//子操作码end`Addiu : beginRegDst<=2'b00;  //选择目标寄存器ALUSrc<=1;  //选择的是符号扩展值作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=0;//主存到寄存器RegWrite<=1;//写寄存器MemRead<=0; //读存储器MemWrite<=0;//写存储器Branch<=0;  //分支指令  Jump <=0;ALUControl_a <= OpCode[31:26];//操作码  ALUControl_b <= OpCode[5:0];//子操作码end`Slti : beginRegDst<=2'b00;  //选择目标寄存器ALUSrc<=1;  //选择的是符号扩展值作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=0;//主存到寄存器RegWrite<=1;//写寄存器MemRead<=0; //读存储器MemWrite<=0;//写存储器Branch<=0;  //分支指令  Jump <=0;ALUControl_a <= OpCode[31:26];//操作码  ALUControl_b <= OpCode[5:0];//子操作码end`Sltiu : beginRegDst<=2'b00;  //选择目标寄存器ALUSrc<=1;  //选择的是符号扩展值作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=0;//主存到寄存器RegWrite<=1;//写寄存器MemRead<=0; //读存储器MemWrite<=0;//写存储器Branch<=0;  //分支指令  Jump <=0;ALUControl_a <= OpCode[31:26];//操作码  ALUControl_b <= OpCode[5:0];//子操作码end`Beq : beginRegDst<=2'b10;  //选择目标寄存器ALUSrc<=0;  //选择的是寄存器值作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=0;//主存到寄存器RegWrite<=0;//写寄存器MemRead<=0; //读存储器MemWrite<=0;//写存储器Branch<=1;  //分支指令  Jump <=0;ALUControl_a <= OpCode[31:26];//操作码  ALUControl_b <= OpCode[5:0];//子操作码end`Bgtz : beginRegDst<=2'b10;  //选择目标寄存器ALUSrc<=0;  //选择的是寄存器值作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=0;//主存到寄存器RegWrite<=0;//写寄存器MemRead<=0; //读存储器MemWrite<=0;//写存储器Branch<=1;  //分支指令  Jump <=0;ALUControl_a <= OpCode[31:26];//操作码  ALUControl_b <= OpCode[5:0];//子操作码end`Blez : beginRegDst<=2'b10;  //选择目标寄存器ALUSrc<=0;  //选择的是寄存器值作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=0;//主存到寄存器RegWrite<=0;//写寄存器MemRead<=0; //读存储器MemWrite<=0;//写存储器Branch<=1;  //分支指令  Jump <=0;ALUControl_a <= OpCode[31:26];//操作码  ALUControl_b <= OpCode[5:0];//子操作码end`Bne : beginRegDst<=2'b10;  //选择目标寄存器ALUSrc<=0;  //选择的是寄存器值作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=0;//主存到寄存器RegWrite<=0;//写寄存器MemRead<=0; //读存储器MemWrite<=0;//写存储器Branch<=1;  //分支指令  Jump <=0;ALUControl_a <= OpCode[31:26];//操作码  ALUControl_b <= OpCode[5:0];//子操作码end`J : beginRegDst<=2'b10;  //选择目标寄存器ALUSrc<=0;  //选择的是寄存器值作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=0;//主存到寄存器RegWrite<=0;//写寄存器MemRead<=0; //读存储器MemWrite<=0;//写存储器Branch<=0;  //分支指令  Jump <=1;ALUControl_a <= OpCode[31:26];//操作码  ALUControl_b <= OpCode[5:0];//子操作码enddefault: beginRegDst<=2'b10;  //选择目标寄存器ALUSrc<=0;  //选择的是寄存器值作为第二个操作数ALUSrc1<=0;//选择的是寄存器作为第一个操作数MemtoReg<=0;//主存到寄存器RegWrite<=0;//写寄存器MemRead<=0; //读存储器MemWrite<=0;//写存储器Branch<=0;  //分支指令  Jump <=0;ALUControl_a <= 6'b000000;//操作码  ALUControl_b <= 6'b000000;//子操作码endendcaseendendmodule