`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) begin
if (Is_load==1'b1) begin
if ((OpCode[25:21]==Execute_reg && OpCode[25:21]!=5'b00000)
|| OpCode[20:16]==Execute_reg) begin
stall_id<=1'b1;
end else begin
stall_id<=1'b0;
end
end else begin
stall_id<=1'b0;
end
end else begin
stall_id<=1'b0;
end
if (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;
end
end
always @(OpCode,Execute_reg,Is_First) begin//判断分支指令
if (OpCode[31:26]==`Beq) begin
stall_branch <= 1'b1;
end else begin
stall_branch <= 1'b0;
end
end
always @(OpCode,Execute_reg,Is_First) begin //**********************************
case (OpCode[31:26])
`lb: begin
RegDst<=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: begin
RegDst<=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: begin
RegDst<=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: begin
RegDst<=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: begin
RegDst<=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: begin
RegDst<=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: begin
RegDst<=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 : begin
case (OpCode[5:0])
`And : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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
endcase
end
`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: begin
case (OpCode[5:0])
`Mul : begin
RegDst<=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
endcase
end
`Addi : 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
`Addiu : 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
`Slti : 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
`Sltiu : 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
`Beq : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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 : begin
RegDst<=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];//子操作码
end
default: begin
RegDst<=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;//子操作码
end
endcase
end
endmodule
CPU之CPU_ctrl
最新推荐文章于 2022-11-09 00:39:47 发布