Commit 70d20c6f authored by Yuchen Wu's avatar Yuchen Wu
Browse files

lab2

parent 385bf253
PB*.pdf
\ No newline at end of file
PB*.pdf
PB*.zip
report.*
*.txt
\ No newline at end of file
......@@ -13,8 +13,8 @@
// !!! ALL YOU NEED TO CHANGE IS 4 FILE PATH BELOW !!!
// (they are all optional, you can run cpu without change paths here,if files are failed to open, we will not dump the content to .txt and will not try to initial your bram)
//////////////////////////////////////////////////////////////////////////////////
`define DataRamContentLoadPath "D:\\Vivado\\CA_lab\\testbench\\1testAll.data" //修改此处为测试数据路径
`define InstRamContentLoadPath "D:\\Vivado\\CA_lab\\testbench\\1testAll.inst" //修改此处为测试数据路径
`define DataRamContentLoadPath "C:\\Users\\22964\\Documents\\study\\this_semester\\comparch\\ustc_ca2021_lab\\lab2\\TestDataTools\\test.data" //修改此处为测试数据路径
`define InstRamContentLoadPath "C:\\Users\\22964\\Documents\\study\\this_semester\\comparch\\ustc_ca2021_lab\\lab2\\TestDataTools\\test.inst" //修改此处为测试数据路径
`define DataRamContentSavePath "D:\\Vivado\\CA_lab\\testbench\\DataRamContent.txt" //修改此处为测试数据路径
`define InstRamContentSavePath "D:\\Vivado\\CA_lab\\testbench\\InstRamContent.txt" //修改此处为测试数据路径
`define BRAMWORDS 4096 //a word is 32bit, so our bram is 4096*32bit
......
......@@ -31,6 +31,23 @@ module ALU(
);
// 请补全此处代码
always@(*)
begin
case (AluContrl)
`ADD: AluOut = Operand1 + Operand2;
`SUB: AluOut = Operand1 - Operand2;
`AND: AluOut = Operand1 & Operand2;
`OR: AluOut = Operand1 | Operand2;
`XOR: AluOut = Operand1 ^ Operand2;
`SLTU: AluOut = (Operand1 < Operand2)? 32'd1 : 32'd0;
`SLT: AluOut = ($signed(Operand1) < $signed(Operand2))? 32'd1 : 32'd0;
`SRL: AluOut = Operand1 >> Operand2[4:0];
`SLL: AluOut = Operand1 << Operand2[4:0];
`SRA: AluOut = $signed(Operand1) >>> Operand2[4:0];
`LUI: AluOut = Operand2;
default: AluOut = 32'hxxxxxxxx;
endcase
end
endmodule
......@@ -29,6 +29,25 @@ module BranchDecisionMaking(
);
// 请补全此处代码
always @(*)
begin
case (BranchTypeE)
`BEQ:
BranchE = (Operand1==Operand2)? 1'd1 : 1'd0;
`BNE:
BranchE = (Operand1==Operand2)? 1'd0 : 1'd1;
`BLT:
BranchE = ($signed(Operand1)<$signed(Operand2))? 1'd1 : 1'd0;
`BLTU:
BranchE = (Operand1<Operand2)? 1'd1 : 1'd0;
`BGE:
BranchE = ($signed(Operand1)>=$signed(Operand2))? 1'd1 : 1'd0;
`BGEU:
BranchE = (Operand1>=Operand2)? 1'd1 : 1'd0;
default:
BranchE = 1'b0;
endcase
end
endmodule
`timescale 1ns / 1ps
module CSRALU(
input wire [31:0] Operand1,
input wire [31:0] Operand2,
input wire [1:0] AluCTL,
output reg [31:0] AluOut,
output reg [31:0] CSROut
);
always@(*)
begin
case (AluCTL)
`RW: begin
AluOut <= Operand2;
CSROut <= Operand1;
end
`RS: begin
AluOut <= Operand2;
CSROut <= Operand2 | Operand1;
end
`RC: begin
AluOut <= Operand2;
CSROut <= (~Operand1) & Operand2;
end
default:begin
AluOut <= Operand1;
CSROut <= Operand2;
end
endcase
end
endmodule
\ No newline at end of file
`timescale 1ns / 1ps
module CSRF (
input clk,
input rst,
input WE,
input wire [11:0] WA,
input wire [31:0] WD,
input wire [11:0] RA,
output wire[31:0] RD
);
reg [31:0] CSR[4095:0];
integer i;
always@(negedge clk or posedge rst)
begin
if(rst) begin
for(i=0;i<4096;i=i+1)
CSR[i][31:0] <= 32'b0;
end
else if((WA[11:10]!=2'b11)&&WE) begin
CSR[WA] <= WD;
end
end
assign RD = CSR[RA];
endmodule
......@@ -9,33 +9,35 @@
// Tool Versions: Vivado 2017.4.1
// Description: RISC-V Instruction Decoder
//////////////////////////////////////////////////////////////////////////////////
//功能和接口说明
//ControlUnit 是本CPU的指令译码器,组合逻辑电路
//输入
// Op 是指令的操作码部分
// Fn3 是指令的func3部分
// Fn7 是指令的func7部分
//输出
// JalD==1 表示Jal指令到达ID译码阶段
// JalrD==1 表示Jalr指令到达ID译码阶段
// RegWriteD 表示ID阶段的指令对应的寄存器写入模式
// MemToRegD==1 表示ID阶段的指令需要将data memory读取的值写入寄存器,
// MemWriteD 4bit,为1的部分表示有效,对于data memory32bit字按byte进行写入,MemWriteD=0001表示只写入最低1个byte,和xilinx bram的接口类似
// LoadNpcD==1 表示将NextPC输出到ResultM
// RegReadD 表示A1和A2对应的寄存器值是否被使用到了,用于forward的处理
// BranchTypeD 表示不同的分支类型,所有类型定义在Parameters.v
// AluContrlD 表示不同的ALU计算功能,所有类型定义在Parameters.v
// AluSrc2D 表示Alu输入源2的选择
// AluSrc1D 表示Alu输入源1的选择
// ImmType 表示指令的立即数格式
//实验要求
//补全模块
//���ܺͽӿ�˵??
//ControlUnit �DZ�CPU��ָ�������������????����·
//����
// Op ��ָ��IJ�����???
// Fn3 ��ָ���func3����
// Fn7 ��ָ���func7����
//���?
// JalD==1 ��ʾJalָ���ID����׶�?
// JalrD==1 ��ʾJalrָ���ID����׶�?
// RegWriteD ��ʾID�׶ε�ָ���Ӧ�ļĴ���д���???
// MemToRegD==1 ��ʾID�׶ε�ָ����Ҫ��data memory��ȡ��???д��Ĵ���?,
// MemWriteD ??4bit��Ϊ1�IJ��ֱ�ʾ��Ч������data memory??32bit�ְ�byte����д��,MemWriteD=0001��ʾֻд����??1��byte����xilinx bram�Ľӿ���??
// LoadNpcD==1 ��ʾ��NextPC�����ResultM
// RegReadD ��ʾA1��A2��Ӧ�ļĴ���ֵ�Ƿ�ʹ�õ��ˣ�����forward�Ĵ�??
// BranchTypeD ��ʾ��ͬ�ķ�֧���ͣ�??�����Ͷ�����Parameters.v??
// AluContrlD ��ʾ��ͬ��ALU���㹦�ܣ��������Ͷ�����Parameters.v??
// AluSrc2D ��ʾAlu����??2��???��
// AluSrc1D ��ʾAlu����??1��???��
// ImmType ��ʾָ������������?
//ʵ��Ҫ��
//��ȫģ��
`include "Parameters.v"
module ControlUnit(
input wire [6:0] Op,
input wire [2:0] Fn3,
input wire [6:0] Fn7,
input wire [4:0] Rs1D,
input wire [4:0] RdD,
output wire JalD,
output wire JalrD,
output reg [2:0] RegWriteD,
......@@ -47,10 +49,533 @@ module ControlUnit(
output reg [3:0] AluContrlD,
output wire [1:0] AluSrc2D,
output wire AluSrc1D,
output reg CSRAlusrc1D,
output reg AluOutSrcD,
output reg CSRWriteD,
output reg CSRReadD,
output reg [1:0] CSRAluCtlD,
output reg [2:0] ImmType
);
// 请补全此处代码
reg JalD_reg,JalrD_reg,MemToRegD_reg,LoadNpcD_reg,AluSrc1D_reg;
reg [1:0] AluSrc2D_reg;
assign {JalD,JalrD,MemToRegD,LoadNpcD,AluSrc1D} = {JalD_reg,JalrD_reg,MemToRegD_reg,LoadNpcD_reg,AluSrc1D_reg};
assign AluSrc2D = AluSrc2D_reg;
always @(*)
if(Op==7'b1110011)
begin//csr
{JalD_reg,JalrD_reg,MemToRegD_reg,LoadNpcD_reg,AluSrc1D_reg,AluSrc2D_reg} <= 7'b0000000;
BranchTypeD <= `NOBRANCH;
MemWriteD <= 4'b0000;
ImmType <= `ZTYPE;
AluContrlD <= 4'd11;
AluOutSrcD <= 1'b1;
case(Fn3)
3'b001:
begin//csrrw
RegReadD <= 2'b10;
CSRAlusrc1D <= 1'b0;
CSRAluCtlD <= `RW;
CSRReadD <= (RdD==5'b00000)?1'b0:1'b1;
RegWriteD <= (RdD==5'b00000)?`NOREGWRITE:`LW;
CSRWriteD <= 1'b1;
end
3'b101:
begin//csrrwi
RegReadD <= 2'b00;
CSRAlusrc1D <= 1'b1;
CSRAluCtlD <= `RW;
CSRReadD <= (RdD==5'b00000)?1'b0:1'b1;
RegWriteD <= (RdD==5'b00000)?`NOREGWRITE:`LW;
CSRWriteD <= 1'b1;
end
3'b010:
begin//csrrs
RegReadD <= 2'b10;
CSRAlusrc1D <= 1'b0;
CSRAluCtlD <= `RS;
CSRReadD <= 1'b1;
RegWriteD <= `LW;
CSRWriteD <= (Rs1D==5'b00000)?1'b0:1'b1;
end
3'b110:
begin//csrrsi
RegReadD <= 2'b00;
CSRAlusrc1D <= 1'b1;
CSRAluCtlD <= `RS;
CSRReadD <= 1'b1;
RegWriteD <= `LW;
CSRWriteD <= 1'b1;
end
3'b011:
begin//csrrc
RegReadD <= 2'b10;
CSRAlusrc1D <= 1'b0;
CSRAluCtlD <= `RC;
CSRReadD <= 1'b1;
RegWriteD <= `LW;
CSRWriteD <= (Rs1D==5'b00000)?1'b0:1'b1;
end
3'b111:
begin//csrrci
RegReadD <= 2'b00;
CSRAlusrc1D <= 1'b1;
CSRAluCtlD <= `RC;
CSRReadD <= 1'b1;
RegWriteD <= `LW;
CSRWriteD <= 1'b1;
end
default:
begin
RegReadD <= 2'b00;
CSRAlusrc1D <= 1'b0;
CSRAluCtlD <= 2'b00;
CSRReadD <= 1'b0;
RegWriteD <= `NOREGWRITE;
CSRWriteD <= 1'b0;
end
endcase
end
else
begin
CSRAlusrc1D <= 1'b0;
AluOutSrcD <= 1'b0;
CSRWriteD <= 1'b0;
CSRAluCtlD <= 2'b00;
CSRReadD <= 1'b0;
case(Op)
7'b0110011:
begin//Rtype
{JalD_reg,JalrD_reg,MemToRegD_reg,LoadNpcD_reg,AluSrc1D_reg} <= 5'b00000;
AluSrc2D_reg <= 2'b00;
BranchTypeD <= `NOBRANCH;
MemWriteD <= 4'b0000;//32bit
ImmType <= `RTYPE;
case(Fn3)
3'b000:
begin
case(Fn7)
7'b0000000:
begin//ADD
RegWriteD <= `LW;//32bit
RegReadD <= 2'b11;//2regs
AluContrlD <= `ADD;
end
7'b0100000:
begin//SUB
RegWriteD <= `LW;//32bit
RegReadD <= 2'b11;//2regs
AluContrlD <= `SUB;
end
default:
begin
RegWriteD <= `NOREGWRITE;//32bit
RegReadD <= 2'b00;//2regs
AluContrlD <= 4'd11;
end
endcase
end
3'b001:
begin
case(Fn7)
7'b0000000:
begin//SLL
RegWriteD <= `LW;//32bit
RegReadD <= 2'b11;//2regs
AluContrlD <= `SLL;
end
default:
begin
RegWriteD <= `NOREGWRITE;//32bit
RegReadD <= 2'b00;//2regs
AluContrlD <= 4'd11;
end
endcase
end
3'b010:
begin
case(Fn7)
7'b0000000:
begin//SLT
RegWriteD <= `LW;//32bit
RegReadD <= 2'b11;//2regs
AluContrlD <= `SLT;
end
default:
begin
RegWriteD <= `NOREGWRITE;//32bit
RegReadD <= 2'b00;//2regs
AluContrlD <= 4'd11;
end
endcase
end
3'b011:
begin
case(Fn7)
7'b0000000:
begin//SLTU
RegWriteD <= `LW;//32bit
RegReadD <= 2'b11;//2regs
AluContrlD <= `SLTU;
end
default:
begin
RegWriteD <= `NOREGWRITE;//32bit
RegReadD <= 2'b00;//2regs
AluContrlD <= 4'd11;
end
endcase
end
3'b100:
begin
case(Fn7)
7'b0000000:
begin//XOR
RegWriteD <= `LW;//32bit
RegReadD <= 2'b11;//2regs
AluContrlD <= `XOR;
end
default:
begin
RegWriteD <= `NOREGWRITE;//32bit
RegReadD <= 2'b00;//2regs
AluContrlD <= 4'd11;
end
endcase
end
3'b101:
begin
case(Fn7)
7'b0000000:
begin//SRL
RegWriteD <= `LW;//32bit
RegReadD <= 2'b11;//2regs
AluContrlD <= `SRL;
end
7'b0100000:
begin//SRA
RegWriteD <= `LW;//32bit
RegReadD <= 2'b11;//2regs
AluContrlD <= `SRA;
end
default:
begin
RegWriteD <= `NOREGWRITE;//32bit
RegReadD <= 2'b00;//2regs
AluContrlD <= 4'd11;
end
endcase
end
3'b110:
begin
case(Fn7)
7'b0000000:
begin//OR
RegWriteD <= `LW;//32bit
RegReadD <= 2'b11;//2regs
AluContrlD <= `OR;
end
default:
begin
RegWriteD <= `NOREGWRITE;//32bit
RegReadD <= 2'b00;//2regs
AluContrlD <= 4'd11;
end
endcase
end
3'b111:
begin
case(Fn7)
7'b0000000:
begin//AND
RegWriteD <= `LW;//32bit
RegReadD <= 2'b11;//2regs
AluContrlD <= `AND;
end
default:
begin
RegWriteD <= `NOREGWRITE;//32bit
RegReadD <= 2'b00;//2regs
AluContrlD <= 4'd11;
end
endcase
end
default:
begin
RegWriteD <= `NOREGWRITE;//32bit
RegReadD <= 2'b00;//
AluContrlD <= 4'd11;
end
endcase
end
7'b0010011:
begin//Itype
if(Fn3==3'b001)
begin
{JalD_reg,JalrD_reg,MemToRegD_reg,LoadNpcD_reg,AluSrc1D_reg} <= 5'b00000;
AluSrc2D_reg <= 2'b01;
BranchTypeD <= `NOBRANCH;
MemWriteD <= 4'b0000;//32bit
ImmType <= `RTYPE;
case(Fn7)
7'b0000000:
begin//SLLI
RegWriteD <= `LW;//32bit
RegReadD <= 2'b10;//
AluContrlD <= `SLL;
end
default:
begin
RegWriteD <= `NOREGWRITE;//32bit
RegReadD <= 2'b00;//
AluContrlD <= 4'd11;
end
endcase
end
else if(Fn3==3'b101)
begin
{JalD_reg,JalrD_reg,MemToRegD_reg,LoadNpcD_reg,AluSrc1D_reg} <= 5'b00000;
AluSrc2D_reg <= 2'b01;
BranchTypeD <= `NOBRANCH;
MemWriteD <= 4'b0000;//32bit
ImmType <= `RTYPE;
case(Fn7)
7'b0000000:
begin//SRLI
RegWriteD <= `LW;//32bit
RegReadD <= 2'b10;//
AluContrlD <= `SRL;
end
7'b0100000:
begin//SRAI
RegWriteD <= `LW;//32bit
RegReadD <= 2'b10;//
AluContrlD <= `SRA;
end
default:
begin
RegWriteD <= `NOREGWRITE;//32bit
RegReadD <= 2'b00;//
AluContrlD <= 4'd11;
end
endcase
end
else
begin
{JalD_reg,JalrD_reg,MemToRegD_reg,LoadNpcD_reg,AluSrc1D_reg} <= 5'b00000;
AluSrc2D_reg <= 2'b10;
BranchTypeD <= `NOBRANCH;
MemWriteD <= 4'b0000;//32bit
//RegWriteD <= `LW;//32bit
//RegReadD <= 2'b10;//rs1
ImmType <= `ITYPE;
case(Fn3)
3'b000:
begin//ADDI
AluContrlD <= `ADD;
RegWriteD <= `LW;
RegReadD <= 2'b10;
end
3'b010:
begin
AluContrlD <= `SLT;
RegWriteD <= `LW;
RegReadD <= 2'b10;
end
3'b011:
begin
AluContrlD <= `SLTU;
RegWriteD <= `LW;
RegReadD <= 2'b10;
end
3'b100:
begin
AluContrlD <= `XOR;
RegWriteD <= `LW;
RegReadD <= 2'b10;
end
3'b110:
begin
AluContrlD <= `OR;
RegWriteD <= `LW;
RegReadD <= 2'b10;
end
3'b111:
begin
AluContrlD <= `AND;
RegWriteD <= `LW;
RegReadD <= 2'b10;
end
default:
begin
AluContrlD <= 4'd11;
RegWriteD <= `NOREGWRITE;
RegReadD <= 2'b00;
end
endcase
end
end
7'b0100011:
begin//stype
{JalD_reg,JalrD_reg,MemToRegD_reg,LoadNpcD_reg,AluSrc1D_reg} <= 5'b00000;
AluSrc2D_reg <= 2'b10;//imm
BranchTypeD <= `NOBRANCH;
//MemWriteD <= 4'b0000;//32bit
RegWriteD <= `NOREGWRITE;//32bit
RegReadD <= 2'b11;//rs1 rs2
ImmType <= `STYPE;
AluContrlD <= `ADD;
case(Fn3)
3'b000:
begin//store byte
MemWriteD <= 4'b0001;
end
3'b001:
begin//store half word
MemWriteD <= 4'b0011;
end
3'b010:
begin//store word
MemWriteD <= 4'b1111;
end
default:
begin
MemWriteD <= 4'b0000;
end
endcase
end
7'b0000011:
begin//load
{JalD_reg,JalrD_reg,MemToRegD_reg,LoadNpcD_reg,AluSrc1D_reg} <= 5'b00100;
AluSrc2D_reg <= 2'b10;//imm
BranchTypeD <= `NOBRANCH;
MemWriteD <= 4'b0000;//32bit
//RegWriteD <= `NOREGWRITE;//32bit
RegReadD <= 2'b10;//rs1
ImmType <= `ITYPE;
AluContrlD <= `ADD;
case(Fn3)
3'b000:
begin//load byte
RegWriteD <= `LB;
end
3'b001:
begin
RegWriteD <= `LH;
end
3'b010: