概述
杭电计算机组成原理实验RISC-V 实验 实现运算及传送指令的CPU设计实验 实现访存指令的CPU设计实验 实现转移指令的CPU设计实验
- 一、实验目的与要求
- 1、 实验目的:
- a) 掌握RISC-V的转移指令的数据通路设计,掌握指令流和数据流的控制方法
- b) 学习依据新增指令,修改多周期CPU的系统结构的方法,具备链接各模块构建整机的能力。
- c) 掌握基于有限状态机,实现控制单元的设计方法。
- d) 在实现RISC-V的R型和I型运算类指令,U型传送类指令,访存指令的基础上,进一步实现转移类指令beq,jal,jalr真的功能。
- 2、 实验要求:
- 二、实验设计与程序代码
- 1、 模块设计说明
- 2、 实验程序源代码及注释等
- 三、实验仿真
- 1、 仿真代码
- 五、引脚配置
- 六、思考与探索
- 1、 实验结果记录:
- 2、 实验结论:
- 3、 问题与解决方案:
- 4、 思考题:
- a) 可以执行三条转移指令,测试例子可以查看实验记录结果
- b) 分析j的指令1111 1110 1101 1111 1111 0000 0110 1111 发现这是opcode 为jar的类型,所以为jal。因为jal是20位的立即数,而jalr只有12位立即数,则需要压缩,同时jalr主要是为了rs1+imm32->PC则需要将PC的数值放入到rs1中。所以rd和rs1需要一致,综合得到jalr指令为:1011 1111 0110 0000 1000 0000 1110 0111。
- c) 可以,但是这里存在的问题在于需要添加一条PC和imm32的加法器,同时在选择w_data_s的时候需要添加更多的选择,所以CU部分也需要添加相应的状态才可以实现。
- d) 判断转移条件只需要是ZF=0即可,其他的判断条件其实只需要在原来的基础上加上非即可。
- e) 问题很多,找老师,跑板子,查数据解决。
一、实验目的与要求
1、 实验目的:
a) 掌握RISC-V的转移指令的数据通路设计,掌握指令流和数据流的控制方法
b) 学习依据新增指令,修改多周期CPU的系统结构的方法,具备链接各模块构建整机的能力。
c) 掌握基于有限状态机,实现控制单元的设计方法。
d) 在实现RISC-V的R型和I型运算类指令,U型传送类指令,访存指令的基础上,进一步实现转移类指令beq,jal,jalr真的功能。
2、 实验要求:
本次实验内容:在前述构建并实现了运算类指令(R型和I型)、转移指令(U型lui指令)、访存指令(I型和S型)的RISC-V CPU基础上,新增三条转移类指令beq、jal、jalr;首先在实验8基础上,添加CP0寄存器、相对转移的地址加法器和PC写入的多路选择器,并与各个逻辑模块正确链接;然后修改寄存器堆的写入数据多路选择器、修改二级译码及控制单元,实现新的目标指令集功能;最后,编写测试程序,检查CPU是否能正确执行基于新目标集的程序。
二、实验设计与程序代码
1、 模块设计说明
(描述整个实验的设计方案,分几个模块,各模块的功能,各模块之间的连接关系,可附图)
实验除了顶层模块之外还有十一个模块,分别为指令的存取,指令放入到IR,ID1对指令的处理,ID2对ID1处理后的数据进行分析,分析出现在的指令的类型,ALU部分为数据的计算,同时还包括了判断B或者imm32,显示数据模块为数码管模块,对数码管进行显示,暂存器模块是为了A,B的赋值,以及对PC,PC0,W_DATA的赋值,CU模块是包含有限自动机,对不同的状态进行转移,数据获得模块,主要是为了查看相关的数据,对不同的数据进行选择。DM模块是存储器模块,主要是为了存储获取,写入相关的数据。
2、 实验程序源代码及注释等
(实验各个模块的代码,包含功能注释)
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 15:57:20 06/04/2021
// Design Name:
// Module Name: main
// Project Name:
// Target Devices:
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module main(
input clk,clk_n,clk_25M,
input [3:0] SW,
output [3:0] AN,
output [7:0] seg,
output ZF,SF,CF,OF
);
wire [31:0] PC,PC0,IR,inst_Code,A,B,F,R_Addr_A,R_Addr_B,W_Data,imm32,MDR;
wire IR_Write,Reg_Write,rs2_imm_s,PC0_write,Mem_Write,PC_Write;
wire [1:0] PC_s,w_data_s;
wire [4:0] rs1,rs2,rd;
wire [6:0] opcode;
wire [2:0] funct3;
wire [6:0] funct7;
wire [3:0] ALU_OP,ALU_OP_o;
wire IS_R,IS_IMM,IS_LUI,IS_LW,IS_SW,IS_BEQ,IS_JAL,IS_JALR;
wire [31:0] shownum;
IM myIM(clk,PC[7:2],inst_Code);//指令集
Get_Order myGet_Order(IR_Write,PC_Write,PC0_Write,PC_s,inst_Code,imm32,F,clk,clk_n,PC,IR,PC0);//获得指令
ID1 myID1(IR,rs1,rs2,rd,imm32,opcode,funct3,funct7);//ID1对指令进行处理
ID2 myID2(opcode,funct3,funct7,IS_R,IS_IMM,IS_LUI,IS_LW,IS_SW,IS_BEQ,IS_JAL,IS_JALR,ALU_OP);//ID2对指令处理
ALU myALU(A,B,imm32,clk,rs2_imm_s,ALU_OP_o,F,ZF,SF,CF,OF);//ALU部分
ShowNum myShowNum(clk_25M,shownum,seg,AN);//显示数据
DataInput myDataInput(clk,rd,clk_n,Reg_Write,rs1,rs2,W_Data,R_Addr_A,R_Addr_B);
ABInput myABInput(clk,R_Addr_A,R_Addr_B,imm32,F,MDR,PC,w_data_s,rs2_imm_s,A,B,W_Data);
CU myCU(clk,clk_n,IS_R,IS_IMM,IS_LUI,IS_LW,IS_SW,IS_BEQ,IS_JAL,IS_JALR,ZF,ALU_OP,PC_Write,PC0_Write,IR_Write,Reg_Write,Mem_Write,rs2_imm_s,w_data_s,PC_s,ALU_OP_o);
getShowNum mygetShowNum(PC,IR,W_Data,A,B,F,MDR,PC0,rd,imm32,rs1,rs2,SW,shownum);
DM myDM(clk,Mem_Write,F[7:2],B,MDR);
endmodule
module getShowNum(
input [31:0] PC,inst,W_Data,A,B,F,MDR,PC0,rd,imm32,rs1,rs2,
input [3:0] sw,
output reg [31:0] shownum
);
always@(*)
begin
case(sw)
0:begin shownum=PC; end
1:begin shownum=inst; end
2:begin shownum=W_Data; end
3:begin shownum=A; end
4:begin shownum=B; end
5:begin shownum=F; end
6:begin shownum=MDR; end
7:begin shownum=PC0; end
8:begin shownum=rd; end
9:begin shownum=imm32; end
10:begin shownum=rs1; end
11:begin shownum=rs2; end
default:
shownum=0;
endcase
end
endmodule
module CU(
input clk,reset,IS_R,IS_IMM,IS_LUI,IS_LW,IS_SW,IS_BEQ,IS_JAL,IS_JALR,
input ZF,
input [3:0] ALU_OP,
output reg PC_Write,PC0_Write,IR_Write,Reg_Write,
output wire Mem_Write,
output reg rs2_imm_s,
output reg [1:0] w_data_s,PC_s,
output reg [3:0] ALU_OP_o
);
reg [3:0] ST,Next_ST;
initial
begin
ST=0;
end
assign Mem_Write=(Next_ST==4'b1010);
always@(posedge clk or posedge reset)
begin
if(reset) ST<=0;
else ST<=Next_ST;
end
always@(*)
begin
case(ST)
4'b0000:begin Next_ST=4'b0001; end
4'b0001:
begin
if(IS_LUI) Next_ST=4'b0110;
else if(IS_R||IS_IMM||IS_LW||IS_SW||IS_JALR||IS_BEQ) Next_ST=4'b0010;
else if(IS_JAL) Next_ST=4'b1011;
end
4'b0010:
begin
if(IS_R) Next_ST=4'b0011;
else if(IS_IMM) Next_ST=4'b0101;
else if(IS_LW||IS_SW||IS_JALR) Next_ST=4'b0111;
else if(IS_BEQ) Next_ST=4'b1101;
end
4'b0011:begin Next_ST=4'b0100; end
4'b0100:begin Next_ST=4'b0001; end
4'b0101:begin Next_ST=4'b0100; end
4'b0110:begin Next_ST=4'b0001; end
4'b0111:
begin
if(IS_LW) Next_ST=4'b1000;
else if(IS_SW) Next_ST=4'b1010;
else if(IS_JALR) Next_ST=4'b1100;
end
4'b1000:begin Next_ST=4'b1001; end
4'b1001:begin Next_ST=4'b1010; end
4'b1010:begin Next_ST=4'b0001; end
4'b1011:begin Next_ST=4'b0001; end
4'b1100:begin Next_ST=4'b0001; end
4'b1101:begin Next_ST=4'b1110; end
4'b1110:begin Next_ST=4'b0001; end
default: Next_ST=4'b0001;
endcase
end
always@(posedge clk or posedge reset)
begin
if(reset)begin PC_Write<=0;PC0_Write<=0;IR_Write<=0;Reg_Write<=0;ALU_OP_o<=0;rs2_imm_s<=0;w_data_s<=0;PC_s<=0;end
else
begin
case(Next_ST)
4'b0001:begin PC_Write<=1;PC0_Write<=1;IR_Write<=1;Reg_Write<=0;ALU_OP_o<=0;rs2_imm_s<=0;w_data_s<=0;PC_s<=0;end
4'b0010:begin PC_Write<=0;PC0_Write<=0;IR_Write<=0;Reg_Write<=0;ALU_OP_o<=0;rs2_imm_s<=0;w_data_s<=0;PC_s<=0;end
4'b0011:begin PC_Write<=0;PC0_Write<=0;IR_Write<=0;Reg_Write<=0;ALU_OP_o<=ALU_OP;rs2_imm_s<=0;w_data_s<=0;PC_s<=0;end
4'b0100:begin PC_Write<=0;PC0_Write<=0;IR_Write<=0;Reg_Write<=1;ALU_OP_o<=0;rs2_imm_s<=0;w_data_s<=0;PC_s<=0;end
4'b0101:begin PC_Write<=0;PC0_Write<=0;IR_Write<=0;Reg_Write<=0;ALU_OP_o<=ALU_OP;rs2_imm_s<=1;w_data_s<=0;PC_s<=0;end
4'b0110:begin PC_Write<=0;PC0_Write<=0;IR_Write<=0;Reg_Write<=1;ALU_OP_o<=0;rs2_imm_s<=0;w_data_s<=1;PC_s<=0;end
4'b0111:begin PC_Write<=0;PC0_Write<=0;IR_Write<=0;Reg_Write<=0;ALU_OP_o<=0;rs2_imm_s<=1;w_data_s<=0;PC_s<=0;end
4'b1000:begin PC_Write<=0;PC0_Write<=0;IR_Write<=0;Reg_Write<=0;ALU_OP_o<=0;rs2_imm_s<=0;w_data_s<=0;PC_s<=0;end
4'b1001:begin PC_Write<=0;PC0_Write<=0;IR_Write<=0;Reg_Write<=1;ALU_OP_o<=0;rs2_imm_s<=0;w_data_s<=2;PC_s<=0;end
4'b1010:begin PC_Write<=0;PC0_Write<=0;IR_Write<=0;Reg_Write<=0;ALU_OP_o<=0;rs2_imm_s<=0;w_data_s<=0;PC_s<=0;end
4'b1011:begin PC_Write<=1;PC0_Write<=0;IR_Write<=0;Reg_Write<=1;ALU_OP_o<=0;rs2_imm_s<=0;w_data_s<=3;PC_s<=1;end
4'b1100:begin PC_Write<=1;PC0_Write<=0;IR_Write<=0;Reg_Write<=1;ALU_OP_o<=0;rs2_imm_s<=0;w_data_s<=3;PC_s<=2;end
4'b1101:begin PC_Write<=0;PC0_Write<=0;IR_Write<=0;Reg_Write<=0;ALU_OP_o<=8;rs2_imm_s<=0;w_data_s<=0;PC_s<=0;end
4'b1110:begin PC_Write<=ZF;PC0_Write<=0;IR_Write<=0;Reg_Write<=0;ALU_OP_o<=0;rs2_imm_s<=0;w_data_s<=0;PC_s<=1;end
endcase
end
end
endmodule
module ID2(
input [6:0] opcode,
input [2:0] funct3,
input [6:0] funct7,
output reg IS_R,IS_IMM,IS_LUI,IS_LW,IS_SW,IS_BEQ,IS_JAL,IS_JALR,
output reg [3:0] ALU_OP
);
always@(*)
begin
case(opcode)
7'b0110011://R
begin IS_R=1;IS_IMM=0;IS_LUI=0;IS_LW=0;IS_SW=0;IS_BEQ=0;IS_JAL=0;IS_JALR=0;ALU_OP={funct7[5],funct3}; end
7'b0010011://I
begin IS_R=0;IS_IMM=1;IS_LUI=0;IS_LW=0;IS_SW=0;IS_BEQ=0;IS_JAL=0;IS_JALR=0;ALU_OP=(funct3==3'b101)?{funct7[5],funct3}:{1'b0,funct3};end
7'b0110111://U
begin IS_R=0;IS_IMM=0;IS_LUI=1;IS_LW=0;IS_SW=0;IS_BEQ=0;IS_JAL=0;IS_JALR=0;ALU_OP=0;end
7'b0000011://IW
begin IS_R=0;IS_IMM=0;IS_LUI=0;IS_LW=1;IS_SW=0;IS_BEQ=0;IS_JAL=0;IS_JALR=0;ALU_OP=0;end
7'b0100011://SW
begin IS_R=0;IS_IMM=0;IS_LUI=0;IS_LW=0;IS_SW=1;IS_BEQ=0;IS_JAL=0;IS_JALR=0;ALU_OP=0;end
7'b1100011://B
begin IS_R=0;IS_IMM=0;IS_LUI=0;IS_LW=0;IS_SW=0;IS_BEQ=1;IS_JAL=0;IS_JALR=0;ALU_OP=0;end
7'b1101111://Jal
begin IS_R=0;IS_IMM=0;IS_LUI=0;IS_LW=0;IS_SW=0;IS_BEQ=0;IS_JAL=1;IS_JALR=0;ALU_OP=0;end
7'b1100111://Jalr
begin IS_R=0;IS_IMM=0;IS_LUI=0;IS_LW=0;IS_SW=0;IS_BEQ=0;IS_JAL=0;IS_JALR=1;ALU_OP=0;end
default:
begin IS_R=0;IS_IMM=0;IS_LUI=0;IS_LW=0;IS_SW=0;IS_BEQ=0;IS_JAL=0;IS_JALR=1;ALU_OP=0;end
endcase
end
endmodule
module ID1(
input [31:0] inst,
output reg [4:0] rs1,rs2,rd,
output reg [31:0] imm32,
output reg [6:0] opcode,
output reg [2:0] funct3,
output reg [6:0] funct7
);
reg [5:0] I_fmt;
always@(*)
begin
opcode=inst[6:0];
rs1=inst[19:15];
rs2=inst[24:20];
rd=inst[11:7];
funct3=inst[14:12];
funct7=inst[31:25];
case(opcode)
7'b0110011: I_fmt=6'b000001;//R
7'b0010011: I_fmt=6'b100000;//I
7'b0000011: I_fmt=6'b100000;//L和I型一致
7'b0100011: I_fmt=6'b010000;//S
7'b1100011: I_fmt=6'b001000;//B
7'b0110111: I_fmt=6'b000100;//U
7'b1101111: I_fmt=6'b000010;//Jal
7'b1100111: I_fmt=6'b100000;//Jalr和I一致
default:
I_fmt=0;
endcase
case(I_fmt)
6'b000001: imm32=0;//R
6'b100000:
begin
if(funct3==3'b101||3'b001) imm32={{27{1'b0}},inst[24:20]};
else imm32={{20{inst[31]}},inst[31:20]};//I
end
6'b010000: imm32={{20{inst[31]}},inst[31:25],inst[11:7]};//S
6'b001000: imm32={{20{inst[31]}},inst[7],inst[30:25],inst[11:8],1'b0};//B
6'b000100: imm32={inst[31:12],{12{1'b0}}};//U
6'b000010: imm32={{12{inst[31]}},inst[19:12],inst[20],inst[30:21],1'b0};//J1,I2
default:
imm32=0;
endcase
end
endmodule
module Get_Order(
input IR_Write,PC_Write,PC0_Write,
input [1:0] PC_s,
input [31:0] inst_Code,imm32,F,
input clk,reset,
output reg [31:0] PC,IR,PC0
);
initial
begin
PC=0;
end
always@(negedge clk or posedge reset)
begin
if(reset)
begin
PC<=0;
IR<=0;
end
else
begin
if(IR_Write==1)
begin
IR<=inst_Code;
end
if(PC_Write==1)
begin
if(PC_s==0) PC<=PC+4;
else if(PC_s==1) PC<=PC0+imm32;
else if(PC_s==2) PC<=F;
end
if(PC0_Write==1)
begin
PC0<=PC;
end
end
end
endmodule
module ABInput(//暂存器AB W_Data进行赋值模块
input clk_RR,
input [31:0] R_DataA,R_DataB,
input [31:0] imm32,F,MDR,PC,
input [1:0]w_data_s,
input rs2_imm_s,
output reg [31:0] A,B,W_Data
);
always@(negedge clk_RR)
begin
A<=R_DataA;
B<=R_DataB;
end
always@(*)
begin
if(w_data_s==0) begin W_Data=F; end
else if(w_data_s==1) begin W_Data=imm32; end
else if(w_data_s==2) begin W_Data=MDR; end
else if(w_data_s==3) begin W_Data=PC;end
end
endmodule
module DataInput(//暂存器堆的重置清零和R_Addr_A,R_Addr_B,的赋值
input wire clk,
input wire [4:0] W_Addr,
input wire reset,reg_Write,
input wire [4:0] R_Addr_A,R_Addr_B,
input wire [31:0] W_Data,
output reg [31:0] R_DataA,R_DataB
);
reg [31:0] regs [31:0];
initial
begin
regs[0]=0;
regs[1]=1;
regs[2]=2;
regs[3]=3;
regs[4]=4;
regs[5]=5;
regs[6]=6;
regs[7]=7;
regs[8]=8;
regs[9]=9;
regs[10]=10;
regs[11]=11;
regs[12]=12;
regs[13]=13;
regs[14]=14;
regs[15]=15;
regs[16]=16;
regs[17]=17;
regs[18]=18;
regs[19]=19;
regs[20]=20;
regs[21]=21;
regs[22]=22;
regs[23]=23;
regs[24]=24;
regs[25]=25;
regs[26]=26;
regs[27]=27;
regs[28]=28;
regs[29]=29;
regs[30]=30;
regs[31]=31;
end
always@(negedge clk or posedge reset)
begin
if(reset)
begin
regs[0]<=0;
regs[1]<=1;
regs[2]<=2;
regs[3]<=3;
regs[4]<=4;
regs[5]<=5;
regs[6]<=6;
regs[7]<=7;
regs[8]<=8;
regs[9]<=9;
regs[10]<=10;
regs[11]<=11;
regs[12]<=12;
regs[13]<=13;
regs[14]<=14;
regs[15]<=15;
regs[16]<=16;
regs[17]<=17;
regs[18]<=18;
regs[19]<=19;
regs[20]<=20;
regs[21]<=21;
regs[22]<=22;
regs[23]<=23;
regs[24]<=24;
regs[25]<=25;
regs[26]<=26;
regs[27]<=27;
regs[28]<=28;
regs[29]<=29;
regs[30]<=30;
regs[31]<=31;
end
else
begin
if(reg_Write==1'b1)
begin
if(W_Addr!=0)
begin
regs[W_Addr]<=W_Data;
end
end
end
end
always@(*)
begin
R_DataA=regs[R_Addr_A];
R_DataB=regs[R_Addr_B];
end
endmodule
module ALU(//ALU的计算模块
input [31:0] A,B,imm32,
input clk_F,
input rs2_imm_s,
input [3:0] ALU_OP,
output reg [31:0] F,
output reg ZF,SF,CF,OF
);
reg F32;
reg ZF_O,SF_O,CF_O,OF_O;
always@(negedge clk_F)
begin
if(rs2_imm_s==0)
begin
case(ALU_OP)
4'b0000:begin {F32,F}=A+B;end
4'b0001:begin F=A<<B;end
4'b0010:begin F=($signed(A)<$signed(B))?1:0;end
4'b0011:begin F=(A<B)?1'b1 : 1'b0;end
4'b0100:begin F=A^B;end
4'b0101:begin F=A>>B;end
4'b0110:begin F=A|B;end
4'b0111:begin F=A&B;end
4'b1000:begin {F32,F}=A-B;F32=~F32; end
4'b1101:begin F=($signed(A))>>>B;end
endcase
ZF=(F>0)?1'b0:1'b1;
SF=F[31];
CF=F32;
OF=A[31]^B[31]^F[31]^F32;
end
else
begin
case(ALU_OP)
4'b0000:begin {F32,F}=A+imm32;end
4'b0001:begin F=A<<imm32;end
4'b0010:begin F=($signed(A)<$signed(imm32))?1:0;end
4'b0011:begin F=(A<imm32)?1'b1 : 1'b0;end
4'b0100:begin F=A^imm32;end
4'b0101:begin F=A>>imm32;end
4'b0110:begin F=A|imm32;end
4'b0111:begin F=A&imm32;end
4'b1000:begin {F32,F}=A-imm32;F32=~F32; end
4'b1101:begin F=($signed(A))>>>imm32;end
endcase
ZF=(F>0)?1'b0:1'b1;
SF=F[31];
CF=F32;
OF=A[31]^B[31]^F[31]^F32;
end
end
endmodule
module ShowNum(//数码管模块用于显示数据
input clk_25M,
input [31:0] F,
output reg [7:0]seg,
output reg [3:0]AN
);
parameter count=10000;
reg [31:0] clk_num;
reg [3:0] digit;
reg [2:0] which;
initial
begin
clk_num=0;
which=0;
digit=0;
end
always@(posedge clk_25M)
begin
if(clk_num<count)
begin clk_num<=clk_num+1;end
else
begin
clk_num<=0;
which<=which+3'b001;
case(which)
0: begin digit<=F[3:0];end
1: begin digit<=F[7:4];end
2: begin digit<=F[11:8];end
3: begin digit<=F[15:12];end
4: begin digit<=F[19:16];end
5: begin digit<=F[23:20];end
6: begin digit<=F[27:24];end
7: begin digit<=F[31:28];end
endcase
end
end
always@(digit,which)
begin
case(which)
1: begin AN=4'b1111;end
2: begin AN=4'b1110;end
3: begin AN=4'b1101;end
4: begin AN=4'b1100;end
5: begin AN=4'b1011;end
6: begin AN=4'b1010;end
7: begin AN=4'b1001;end
0: begin AN=4'b1000;end
default:AN=4'bzzzz;
endcase
case(digit)
0:seg[7:0]=8'b00000011;
1:seg[7:0]=8'b10011111;
2:seg[7:0]=8'b00100101;
3:seg[7:0]=8'b00001101;
4:seg[7:0]=8'b10011001;
5:seg[7:0]=8'b01001001;
6:seg[7:0]=8'b01000001;
7:seg[7:0]=8'b00011111;
8:seg[7:0]=8'b00000001;
9:seg[7:0]=8'b00001001;
10:seg[7:0]=8'b00010001;
11:seg[7:0]=8'b11000001;
12:seg[7:0]=8'b01100011;
13:seg[7:0]=8'b10000101;
14:seg[7:0]=8'b01100001;
15:seg[7:0]=8'b01110001;
default:seg[7:0]=8'b11111111;
endcase
end
endmodule
三、实验仿真
1、 仿真代码
(含仿真源代码、仿真验证方案)
`timescale 1ns / 1ps
// Company:
// Engineer:
//
// Create Date: 22:20:29 06/18/2021
// Design Name: main
// Module Name: D:/ShuZiDianLu/example/exam9.1/test1.v
// Project Name: exam9.1
// Target Device:
// Tool versions:
// Description:
//
// Verilog Test Fixture created by ISE for module: main
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
module test1;
// Inputs
reg clk;
reg clk_n;
reg clk_25M;
reg [3:0] SW;
// Outputs
wire [3:0] AN;
wire [7:0] seg;
wire ZF;
wire SF;
wire CF;
wire OF;
// Instantiate the Unit Under Test (UUT)
main uut (
.clk(clk),
.clk_n(clk_n),
.clk_25M(clk_25M),
.SW(SW),
.AN(AN),
.seg(seg),
.ZF(ZF),
.SF(SF),
.CF(CF),
.OF(OF)
);
initial begin
// Initialize Inputs
clk = 0;
clk_n = 0;
clk_25M = 0;
SW = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
end
initial begin
forever #1000 clk=~clk;
end
initial begin
forever #1 clk_25M=~clk_25M;
end
2、 仿真波形
(运行仿真时,波形截图)
3、 仿真结果分析
(对仿真波形进行分析)
仿真波形基本符合实验要求
四、电路图
(开发工具中显示的电路模块图)
五、引脚配置
(引脚约束文件的内容,描述主要配置情况)
NET "AN[3]" LOC = L21;
NET "AN[2]" LOC = M22;
NET "AN[1]" LOC = M21;
NET "AN[0]" LOC = N22;
NET "seg[7]" LOC = H19;
NET "seg[6]" LOC = G20;
NET "seg[5]" LOC = J22;
NET "seg[4]" LOC = K22;
NET "seg[3]" LOC = K21;
NET "seg[2]" LOC = H20;
NET "seg[1]" LOC = H22;
NET "seg[0]" LOC = J21;
NET "SW[3]" LOC = T3;
NET "SW[2]" LOC = U3;
NET "SW[1]" LOC = T4;
NET "SW[0]" LOC = V3;
NET "ZF" LOC = R1;
NET "SF" LOC = P2;
NET "CF" LOC = P1;
NET "OF" LOC = N2;
NET "clk" LOC = R4;
NET "clk_25M" LOC = H4;
NET "clk_n" LOC = AA4;
#PlanAhead Generated IO constraints
NET "AN[3]" IOSTANDARD = LVCMOS18;
NET "AN[2]" IOSTANDARD = LVCMOS18;
NET "AN[1]" IOSTANDARD = LVCMOS18;
NET "AN[0]" IOSTANDARD = LVCMOS18;
NET "seg[7]" IOSTANDARD = LVCMOS18;
NET "seg[6]" IOSTANDARD = LVCMOS18;
NET "seg[5]" IOSTANDARD = LVCMOS18;
NET "seg[4]" IOSTANDARD = LVCMOS18;
NET "seg[3]" IOSTANDARD = LVCMOS18;
NET "seg[2]" IOSTANDARD = LVCMOS18;
NET "seg[1]" IOSTANDARD = LVCMOS18;
NET "seg[0]" IOSTANDARD = LVCMOS18;
NET "SW[3]" IOSTANDARD = LVCMOS18;
NET "SW[2]" IOSTANDARD = LVCMOS18;
NET "SW[1]" IOSTANDARD = LVCMOS18;
NET "SW[0]" IOSTANDARD = LVCMOS18;
NET "clk" IOSTANDARD = LVCMOS18;
NET "clk_25M" IOSTANDARD = LVCMOS18;
NET "clk_n" IOSTANDARD = LVCMOS18;
NET "OF" IOSTANDARD = LVCMOS18;
NET "SF" IOSTANDARD = LVCMOS18;
NET "ZF" IOSTANDARD = LVCMOS18;
NET "CF" IOSTANDARD = LVCMOS18;
NET "SW[3]" PULLDOWN;
NET "SW[2]" PULLDOWN;
NET "SW[1]" PULLDOWN;
NET "SW[0]" PULLDOWN;
NET "clk_25M" PULLDOWN;
NET "clk" PULLDOWN;
NET "clk_n" PULLDOWN;
六、思考与探索
1、 实验结果记录:
实验8实验结果记录表
序号 | PC | IR | 汇编指令 | 预期执行结果 | 指令clk数 | W_Data | MDR |
---|---|---|---|---|---|---|---|
1 | 0 | 01000f93 | li t6,16 | t6=16 | 4 | 0x10 | 0x10 |
2 | 4 | 000fad03 | lw s10,0(t6) | S10=0x11 | 4 | 0x11 | 0x11 |
3 | 8 | 004fad83 | lw s11,4(t6) | S11=0x22 | 4 | 0x22 | 0x22 |
4 | C | 01bfa023 | sw s11,0(t6) | Mem[4]=0x22 | 4 | 0x22 | |
5 | 10 | 01afa223 | sw s10,4(t6) | Mem[5]=0x11 | 4 | 0x11 | |
6 | 14 | 000fad03 | lw s10,0(t6) | S10=0x22 | 4 | 0x22 | 0x22 |
7 | 18 | 004fad83 | lw s11,4(t6) | S11=0x11 | 4 | 0x11 | 0x11 |
8 | 1c | 01bd0e33 | add t3,s10,s11 | t3=0x33 | 4 | 0x33 | |
9 | 20 | 01c02823 | sw t3,16(zero) | t3=0x33 | 4 | 0x33 | |
10 | 24 | 01002e83 | lw t4,16(zero) | t4=0x33 | 4 | 0x33 | 0x33 |
11 | 28 | 87600093 | li ra,22 | ra=0xFFFF_F876 | 4 | 0xFFFF_F876 | |
12 | 2c | 00400113 | li sp,4 | sp=0x0000_0004 | 4 | 0x0000_0004 | |
13 | 30 | 002081b3 | add gp,ra,sp | gp=0xFFFF_F87A | 4 | 0xFFFF_F87A | |
14 | 34 | 40208233 | sub tp,ra,sp | tp=0xFFFF_F872 | 4 | 0xFFFF_F872 | |
15 | 38 | 002092b3 | sll t0,ra,sp | t0=0xFFFF_8760 | 4 | 0xFFFF_8760 | |
16 | 3c | 0020d333 | srl t1,ra,sp | t1=0x0FFF_FF87 | 4 | 0x0FFF_FF87 | |
17 | 40 | 4020d3b3 | sra t2,ra,sp | t2=0xFFFF_FF87 | 4 | 0xFFFF_FF87 | |
18 | 44 | 0020a433 | slt s0,ra,sp | s0=0x0000_0001 | 4 | 0x0000_0001 | |
19 | 48 | 0020b4b3 | sltu s1,ra,sp | s1=0x0000_0000 | 4 | 0x0000_0000 | |
20 | 4c | 0062f533 | and a0,t0,t1 | s0=0x0FFF_8700 | 4 | 0x0FFF_8700 | |
21 | 50 | 0062e5b3 | or a1,t0,t1 | a1=0xFFFF_FFE7 | 4 | 0xFFFF_FFE7 | |
22 | 54 | 0062c633 | xor a2,t0,t1 | a2=0xF000_78E7 | 4 | 0xF000_78E7 | |
23 | 58 | 800006b7 | lui a3,0x80000 | a3=0x8000_0000 | 2 | 0x8000_0000 | |
24 | 5c | fff68713 | addi a4,a3,-1 | a4=0x7FFF_FFFF | 4 | 0x7FFF_FFFF | |
25 | 60 | 12370793 | addi a5,a4,291 | a5=0x8000_0122 | 4 | 0x8000_0122 | |
26 | 64 | 00379813 | slli a6,a5,0x3 | a6=0x0000_0910 | 4 | 0x0000_0910 | |
27 | 68 | 0037d893 | srli a7,a5,0x3 | a7=0x1000_0024 | 4 | 0x1000_0024 | |
28 | 6c | 4037d913 | srai s2,a5,0x3 | s2=0xF000_0024 | 4 | 0xF000_0024 | |
29 | 70 | fff92993 | slti s3,s2,-1 | s3=0x0000_0001 | 4 | 0x0000_0001 | |
30 | 74 | fff93a13 | sltiu s4,s2,-1 | s4=0x0000_0001 | 4 | 0x0000_0001 | |
31 | 78 | 00192a93 | slti s5,s2,1 | s5=0x0000_0001 | 4 | 0x0000_0001 | |
32 | 7c | 00193b13 | seqz s6,s2 | s6=0x0000_0000 | 4 | 0x0000_0000 | |
33 | 80 | 0ff67b93 | andi s7,a2,255 | s7=0x0000_00E7 | 4 | 0x0000_00E7 | |
34 | 84 | 0ff66b93 | ori s7,a2,255 | s7=0xF000_78FF | 4 | 0xF000_78FF — | |
35 | 88 | 00010c37 | lui s8,0x10 | s8=0x0001_0000 | 2 | 0x0001_0000 | |
36 | 8c | fffc0c13 | addi s8,s8,-1 | s8=0x0000_FFFF | 4 | 0x0000_FFFF | |
37 | 90 | fffc4c93 | not s9,s8 | s9=0xFFFF_0000 | 4 | 0xFFFF_0000 |
表11.1 实验9实验结果记录表
序号 | PC | IR | 汇编指令 | 执行结果 | 下条指令地址 |
---|---|---|---|---|---|
1 | 0 | 01000513 | li a0,16 | a0=16 | 00306593 |
2 | 4 | 00306593 | ori a1,zero,3 | a1=3 | 03004613 |
3 | 8 | 03004613 | xori a2,zero,48 | a2=48 | 008000ef |
4 | C | 008000ef | Jal ra,14 | PC=14 | 000502b3 |
5 | 14 | 000502b3 | add t0,a0,zero | t0=16 | 0005e333 |
6 | 18 | 0005e333 | or t1,a1,zero | a1=3 | 000073b3 |
7 | 1c | 000073b3 | and t2,zero,zero | t2=0 | 0002ae03 |
8 | 20 | 0002ae03 | lw t3,0(t0) | t3=4 | 01c383b3 |
9 | 24 | 01c383b3 | add t2,t2,t3 | t2=4 | 00428293 |
10 | 28 | 00428293 | addi t0,t0,4 | t0=20 | fff30313 |
11 | 2c | fff30313 | addi t1,t1,-1 | t1=2 | 00030463 |
12 | 30 | 00030463 | beqz t1,38 | 0 | fedff06f |
13 | 34 | fedff06f | j 20 | PC=20 | 0002ae03 |
14 | 20 | 0002ae03 | lw t3,0(t0) | t3=5 | 01c383b3 |
15 | 24 | 01c383b3 | add t2,t2,t3 | t2=9 | 00428293 |
16 | 28 | 00428293 | addi t0,t0,4 t | 1 | 00030463 |
18 | 30 | 00030463 | beqz t1,38 | 0 | fedff06f |
19 | 34 | fedff06f | j 20 | PC=20 | 0002ae03 |
20 | 20 | 0002ae03 | lw t3,0(t0) | t3=6 | 01c383b3 |
21 | 24 | 01c383b3 | add t2,t2,t3 | t2=f | 00428293 |
22 | 28 | 00428293 | addi t0,t0,4 | t0=28 | fff30313 |
23 | 2c | fff30313 | addi t1,t1,-1 | t1=0 | 00030463 |
24 | 30 | 00030463 | beqz t1,38 | 1 | 00762023 |
25 | 38 | 00762023 | sw t2,0(a2) | mem©=f | 00008067 |
26 | 3c | 00008067 | Ret | — | 00062403 |
27 | 10 | 00062403 | lw s0,0(a2) | s0=f | ---- |
2、 实验结论:
(分析实验结果,给出实验结论)
实验结果基本符合实验的要求,同时对照数据值发现符合DM提前放进进去的数据值,说明sw和lw没有问题,同时跳转指令也符合要求,则说明beq、jal、jalr也符合要求。
3、 问题与解决方案:
问题:实验中间发现了很多奇怪的问题,比如跳转不对,数据不对,数码管位移这一系列的问题。
解决方案:通过反复实验和查找数据,发现一部分错误在于没有必要的代码,还有一部分代码问题在于写代码时间过长,导致除了代码的前后差异过大,从而也会造成差异。
4、 思考题:
a) 可以执行三条转移指令,测试例子可以查看实验记录结果
代码如下:
00000000 <main>:
0: 01000513 li a0,16
4: 00306593 ori a1,zero,3
8: 03004613 xori a2,zero,48
c: 008000ef jal ra,14 <BankSum>
10: 00062403 lw s0,0(a2)
00000014 <BankSum>:
14: 000502b3 add t0,a0,zero
18: 0005e333 or t1,a1,zero
1c: 000073b3 and t2,zero,zero
00000020 <L>:
20: 0002ae03 lw t3,0(t0)
24: 01c383b3 add t2,t2,t3
28: 00428293 addi t0,t0,4
2c: fff30313 addi t1,t1,-1
30: 00030463 beqz t1,38 <exit>
34: fedff06f j 20 <L>
00000038 <exit>:
38: 00762023 sw t2,0(a2)
3c: 00008067 ret
b) 分析j的指令1111 1110 1101 1111 1111 0000 0110 1111 发现这是opcode 为jar的类型,所以为jal。因为jal是20位的立即数,而jalr只有12位立即数,则需要压缩,同时jalr主要是为了rs1+imm32->PC则需要将PC的数值放入到rs1中。所以rd和rs1需要一致,综合得到jalr指令为:1011 1111 0110 0000 1000 0000 1110 0111。
c) 可以,但是这里存在的问题在于需要添加一条PC和imm32的加法器,同时在选择w_data_s的时候需要添加更多的选择,所以CU部分也需要添加相应的状态才可以实现。
d) 判断转移条件只需要是ZF=0即可,其他的判断条件其实只需要在原来的基础上加上非即可。
e) 问题很多,找老师,跑板子,查数据解决。
最后
以上就是玩命微笑为你收集整理的杭电计算机组成原理实验RISC-V 实验 实现运算及传送指令的CPU设计实验 实现访存指令的CPU设计实验 实现转移指令的CPU设计实验一、实验目的与要求二、实验设计与程序代码三、实验仿真五、引脚配置六、思考与探索的全部内容,希望文章能够帮你解决杭电计算机组成原理实验RISC-V 实验 实现运算及传送指令的CPU设计实验 实现访存指令的CPU设计实验 实现转移指令的CPU设计实验一、实验目的与要求二、实验设计与程序代码三、实验仿真五、引脚配置六、思考与探索所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复