1 Star 3 Fork 0

jmqian1009 / 多周期RISC-V CPU设计

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
ControlUnit.sv 6.55 KB
一键复制 编辑 原始数据 按行查看 历史
jmqian1009 提交于 2022-03-18 09:20 . 修复了算数右移的bug
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2022/03/15 18:13:29
// Design Name:
// Module Name: ControlUnit
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
`include"Parameters.v"
import Params::*;
module ControlUnit(
input logic [6:0] Op,
input logic [2:0] Fn3,
input logic [6:0] Fn7,
output logic JalD, //是否为Jal指令
output logic JalrD, //是否是Jalr指令
output LoadType RegWriteD, //LOAD指令字节选取(LW,LH,LB,...)
output logic MemToRegD, //写入寄存器的值是否来自MEM
output logic [3:0] MemWriteD, //写MEM时字节选中信号,S类型指令
output logic LoadNpcD, //MEM阶段是否计算PC+4,用于Jal和Jalr指令
output BType BranchTypeD, //分支指令类型,BEQ,BNE,...
output AluOp AluControlD, //EXE阶段ALU控制信号,进行何种运算
output logic [1:0] AluSrc2D, //第二个源操作数的来源
output logic AluSrc1D, //第一个源操作数的来源,rs1或者pc
output Type ImmType //立即数类型,不同类型解析不同
);
//jal,jalr
assign JalD=(Op==7'b1101111)?1'b1:1'b0; //是否为Jal指令
assign JalrD=(Op==7'b1100111)?1'b1:1'b0; //是否为jalr指令
//RegWriteD
always_comb
begin
if(Op==7'b0000011) //是load指令
begin
case(Fn3)
3'b000:RegWriteD=LB; //LB
3'b001:RegWriteD=LH; //LH
3'b010:RegWriteD=LW; //LW
3'b100:RegWriteD=LBU; //LBU
3'b101:RegWriteD=LHU; //LHU
default:RegWriteD=NOREGWRITE; //出错,不写寄存器
endcase
end
else if(Op==7'b0010011||Op==7'b0110011||Op==7'b0110111||Op==7'b0010111||Op==7'b1101111||Op==7'b1100111)
begin
RegWriteD=LW; //I型指令(寄存器-立即数指令)、R型指令、U型指令(LUI,AUIPC),J型指令(JAL)和JALR指令,写寄存器
end
else //B型,S型指令,不写寄存器
begin
RegWriteD=NOREGWRITE;
end
end
//MemToRegD
always_comb
begin
if(Op==7'b0000011) //是load指令
MemToRegD=1;
else //其他指令数据均不来自于MEM
MemToRegD=0;
end
//MemWriteD
always_comb
begin
if(Op==7'b0100011) //S型指令,写MEM
case(Fn3)
3'b000:MemWriteD=4'b0001; //SB
3'b001:MemWriteD=4'b0011; //SH
3'b010:MemWriteD=4'b1111; //SW
default:MemWriteD=4'b0000;
endcase
else
MemWriteD=4'b0000;
end
//LoadNpcD
assign LoadNpcD=(JalD|JalrD)?1'b1:1'b0; //只有Jal指令和Jalr指令时会计算PC+4并存入Reg[Rd]
//BranchTypeD
always_comb
begin
if(Op==7'b1100011) //如果是B型指令(条件分支)
case(Fn3)
3'b000:BranchTypeD=BEQ; //BEQ
3'b001:BranchTypeD=BNE; //BNE
3'b100:BranchTypeD=BLT; //BLT
3'b101:BranchTypeD=BGE; //BGE
3'b110:BranchTypeD=BLTU; //BLTU
3'b111:BranchTypeD=BGEU; //BGEU
default:BranchTypeD=NOBRANCH;
endcase
else
BranchTypeD=NOBRANCH;
end
//AluControlD
always_comb
begin
case(Op)
7'b0000011:AluControlD=ADD; //LOAD指令,计算地址,ADD
7'b0100011:AluControlD=ADD; //STORE指令,计算地址,ADD
7'b0110111:AluControlD=LUI; //LUI指令,保持立即数不变
7'b0010111:AluControlD=ADD; //AUIPC指令,Reg[rs1]+Imm,ADD
7'b1100011:AluControlD=ADD; //B型条件分支指令,不使用ALU,dont care(分支跳转地址计算在ID阶段完成)
7'b1101111:AluControlD=ADD; //jal指令,未用到ALU(地址计算在ID阶段完成)
7'b1100111:AluControlD=ADD; //jalr指令,计算跳转地址(Reg[rs1]+Imm)&~1,ADD
7'b0110011: //R型指令
begin
case(Fn3)
3'b000:if(Fn7[5]==0)
AluControlD=ADD;
else
AluControlD=SUB;
3'b001:AluControlD=SLL;
3'b010:AluControlD=SLT;
3'b011:AluControlD=SLTU;
3'b100:AluControlD=XOR;
3'b101:if(Fn7[5]==0)
AluControlD=SRL;
else
AluControlD=SRA;
3'b110:AluControlD=OR;
3'b111:AluControlD=AND;
default:AluControlD=ADD;
endcase
end
7'b0010011: //I型指令(寄存器-立即数和移位指令)
begin
case(Fn3)
3'b000:AluControlD=ADD;
3'b010:AluControlD=SLT;
3'b011:AluControlD=SLTU;
3'b100:AluControlD=XOR;
3'b110:AluControlD=OR;
3'b111:AluControlD=AND;
3'b001:AluControlD=SLL;
3'b101:if(Fn7[5]==0)
AluControlD=SRL;
else
AluControlD=SRA;
default:AluControlD=ADD;
endcase
end
default:AluControlD=ADD;
endcase
end
//AluSrc1D,PC or 寄存器rs1
always_comb
if(Op==7'b0010111) //AUIPC指令,第一个源操作数来自PC
AluSrc1D=1;
else
AluSrc1D=0;
//AluSrc2D
always_comb
begin
if(Op==7'b0010011&&(Fn3==3'b001||Fn3==3'b101)) //移位指令
AluSrc2D=2'b00; //来自rs2
else if(Op==7'b1100011||Op==7'b0110011) //R型指令或者B型指令
AluSrc2D=2'b01; //来自Reg[rs2]
else //其他指令
AluSrc2D=2'b10; //来自立即数
end
//ImmTypeD
always_comb
begin
case(Op)
7'b0110011:ImmType=RTYPE;
7'b0010011:ImmType=ITYPE;
7'b0000011:ImmType=ITYPE;
7'b1100111:ImmType=ITYPE;
7'b1100011:ImmType=BTYPE;
7'b0100011:ImmType=STYPE;
7'b1101111:ImmType=JTYPE;
7'b0110111:ImmType=UTYPE;
7'b0010111:ImmType=UTYPE;
default:ImmType=RTYPE;
endcase
end
endmodule
1
https://gitee.com/jmqian1009/multi-cycle-risc-v-cpu-design.git
git@gitee.com:jmqian1009/multi-cycle-risc-v-cpu-design.git
jmqian1009
multi-cycle-risc-v-cpu-design
多周期RISC-V CPU设计
master

搜索帮助