概述
杭电计算机组成原理实验RISC-V 实验 寄存器堆与运算器设计实验实验报告
- 一、实验目的与要求
- 1、 实验目的:
- a) 学习寄存器堆的结构传送原理,掌握三端寄存器堆的设计方法
- b) 掌握运算器的结构与工作原理,能将寄存器堆与暂存器ALU进行正确连接,构成运算器
- 2、 实验要求:首先设计一个RVI321指令集架构的寄存器堆(32*32),然后将其与前述实验中的暂存器A、B、F和ALU进行链接,构成一个完整的运算器。
- 二、实验设计与程序代码
- 1、 模块设计说明
- 2、 实验程序源代码及注释等
- 1、 仿真波形
- 2、 仿真结果分析
- 四、电路图
- 五、引脚配置
- 六、思考与探索
- 1、实验结果记录:
- 2、实验结论:
- 3、问题与解决方案:
- 4、思考题:
- a) 寄存器堆的判断写入成功,通过写入的寄存器和零号寄存器单元进行加法来计算判断是否写入成功(零号寄寄存器永远为0)
- b) ALU_OP可以为一个部分,CLK_A和CLK_B为一个部分,clk_write为一个部分,这三个部分可以分开写。那么一共只需要10个开关。
- c) 不能,因为clk_RR是将寄存器堆模块的数据打入到寄存器模块中,clk_F是将寄存器模块的A,B计算出F放入到寄存器模块中,而clk_WB是将寄存器的F打入到寄存器堆当中,这其中功能不同,所以不能合并。
- d) 可以将寄存器堆设置一个使能控制,表示单一输出,那么则只需要一个输出接口了,同时还可以加上一个相关的立即数存入B中,再进行后续的计算。
- e) 在这个寄存器堆设计实验中,这个实验理解起来稍微困难,起初已经写好了代码,进行了仿真,出现了波形,但是后来老师要求读操作和写操作输出了不同的数据,在不同的单元。于是我就把仿真代码改了一下,将W_Data,W_Addr等数据做了修改。这个实验也就成功了。通过做这个寄存器堆设计实验,我对寄存器堆的读写操作有了一个新的认识和理解了。也对ISE这个软件的运用更加熟练,对寄存器堆这个概念也有了更深层次的理解,增长了我的只是,强化了我的实践能力以及思考能力。这次实验收获巨大。
一、实验目的与要求
1、 实验目的:
a) 学习寄存器堆的结构传送原理,掌握三端寄存器堆的设计方法
b) 掌握运算器的结构与工作原理,能将寄存器堆与暂存器ALU进行正确连接,构成运算器
2、 实验要求:首先设计一个RVI321指令集架构的寄存器堆(32*32),然后将其与前述实验中的暂存器A、B、F和ALU进行链接,构成一个完整的运算器。
二、实验设计与程序代码
1、 模块设计说明
(描述整个实验的设计方案,分几个模块,各模块的功能,各模块之间的连接关系,板级验证方案等,可附图)
2、 实验程序源代码及注释等
(实验各个模块的代码,包含功能注释)
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date:
23:38:21 05/07/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 wire clk_WB,reg_Write,
input wire [4:0] R_Addr_A,R_Addr_B,W_Addr,
input wire [3:0] ALU_OP,
input wire clk_F,res_n,
input wire clk_RR,
input wire clk_25M,
output wire ZF,SF,CF,OF,
output wire [3:0] AN,
output wire [7:0] seg
);
wire [31:0] R_DataA,R_DataB,W_Data,R_DataF;
wire [31:0] A,B;
wire [31:0] F;
DataInput mydatainput(res_n,W_Addr,clk_WB,reg_Write,R_Addr_A,R_Addr_B,F,R_DataA,R_DataB);//寄存器堆的区块
ALU myalu(A,B,clk_F,ALU_OP,R_DataF,ZF,SF,CF,OF);//ALU计算的模块
ShowNum myShowNum(clk_25M,F,seg,AN);//数码管显示的模块
ABIPUT myabinput(clk_RR,R_DataA,R_DataB,R_DataF,A,B,F);//AB暂存器赋值模块
endmodule
module ABIPUT(//暂存器AB进行赋值模块
input clk_RR,
input [31:0] R_DataA,R_DataB,R_DataF,
output reg [31:0] A,B,F
);
always@(posedge clk_RR)
begin
A<=R_DataA;
B<=R_DataB;
end
always@(*)
begin
F<=R_DataF;
end
endmodule
module DataInput(//暂存器堆的重置清零和R_Addr_A,R_Addr_B,的赋值
input wire res_n,
input wire [4:0] W_Addr,
input wire clk_Regs,reg_Write,
input wire [4:0] R_Addr_A,R_Addr_B,
input wire [31:0] F,
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]=32'b10000000000000000000000000000000;
regs[31]=32'b01111111111111111111111111111111;
end
always@(posedge clk_Regs or posedge res_n)
begin
if(res_n)
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]<=32'b10000000000000000000000000000000;
regs[31]<=32'b01111111111111111111111111111111;
end
else
begin
if(reg_Write==1'b1)
begin
if(W_Addr!=0)
begin
regs[W_Addr]<=F;
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,
input clk_F,
input [3:0] ALU_OP,
output reg [31:0] F,
output reg ZF,SF,CF,OF
);
reg F32;
always@(posedge clk_F)
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'b1001: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
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)
0: begin AN=4'b1111;end
1: begin AN=4'b1110;end
2: begin AN=4'b1101;end
3: begin AN=4'b1100;end
4: begin AN=4'b1011;end
5: begin AN=4'b1010;end
6: begin AN=4'b1001;end
7: 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
end
initial begin
res_n=1;
#100
R_Addr_A=8;
R_Addr_B=8;
#100
clk_RR=1;
ALU_OP=0;
#100
clk_F=1;
#100
R_Addr_A=8;
R_Addr_B=8;
#100
clk_RR=1;
ALU_OP=6;
#100
clk_F=1;
end
endmodule
1、 仿真波形
(运行仿真时,波形截图)
2、 仿真结果分析
(对仿真波形进行分析)
主要是验证寄存器堆里面的存取以及赋值和运算模块的验证
四、电路图
(开发工具中显示的电路模块图)
五、引脚配置
(引脚约束文件的内容,描述主要配置情况)
NET “clk_F” CLOCK_DEDICATED_ROUTE = FALSE;
NET “clk_WB” CLOCK_DEDICATED_ROUTE = FALSE;
#PlanAhead Generated physical constraints
NET “ALU_OP[3]” LOC = T3;
NET “ALU_OP[2]” LOC = U3;
NET “ALU_OP[1]” LOC = T4;
NET “ALU_OP[0]” LOC = V3;
NET “AN[3]” LOC = L21;
NET “AN[2]” LOC = M22;
NET “AN[1]” LOC = M21;
NET “AN[0]” LOC = N22;
NET “R_Addr_A[4]” LOC = V4;
NET “R_Addr_A[3]” LOC = W4;
NET “R_Addr_A[2]” LOC = Y4;
NET “R_Addr_A[1]” LOC = Y6;
NET “R_Addr_A[0]” LOC = W7;
NET “R_Addr_B[4]” LOC = Y8;
NET “R_Addr_B[3]” LOC = Y7;
NET “R_Addr_B[2]” LOC = T1;
NET “R_Addr_B[1]” LOC = U1;
NET “R_Addr_B[0]” LOC = U2;
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 “W_Addr[4]” LOC = W1;
NET “W_Addr[3]” LOC = W2;
NET “W_Addr[2]” LOC = Y1;
NET “W_Addr[1]” LOC = AA1;
NET “W_Addr[0]” LOC = V2;
NET “clk_RR” LOC = R4;
NET “clk_F” LOC = AA4;
NET “reg_Write” LOC = AB8;
NET “clk_WB” LOC = AB6;
NET “res_n” LOC = T5;
NET “ZF” LOC = R1;
NET “SF” LOC = P2;
NET “CF” LOC = P1;
NET “OF” LOC = N2;
NET “clk_25M” LOC = H4;
#PlanAhead Generated IO constraints
NET “ALU_OP[3]” IOSTANDARD = LVCMOS18;
NET “ALU_OP[2]” IOSTANDARD = LVCMOS18;
NET “ALU_OP[1]” IOSTANDARD = LVCMOS18;
NET “ALU_OP[0]” IOSTANDARD = LVCMOS18;
NET “AN[3]” IOSTANDARD = LVCMOS18;
NET “AN[2]” IOSTANDARD = LVCMOS18;
NET “AN[1]” IOSTANDARD = LVCMOS18;
NET “AN[0]” IOSTANDARD = LVCMOS18;
NET “R_Addr_A[4]” IOSTANDARD = LVCMOS18;
NET “R_Addr_A[3]” IOSTANDARD = LVCMOS18;
NET “R_Addr_A[2]” IOSTANDARD = LVCMOS18;
NET “R_Addr_A[1]” IOSTANDARD = LVCMOS18;
NET “R_Addr_A[0]” IOSTANDARD = LVCMOS18;
NET “R_Addr_B[4]” IOSTANDARD = LVCMOS18;
NET “R_Addr_B[3]” IOSTANDARD = LVCMOS18;
NET “R_Addr_B[2]” IOSTANDARD = LVCMOS18;
NET “R_Addr_B[1]” IOSTANDARD = LVCMOS18;
NET “R_Addr_B[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 “W_Addr[0]” IOSTANDARD = LVCMOS18;
NET “W_Addr[1]” IOSTANDARD = LVCMOS18;
NET “W_Addr[2]” IOSTANDARD = LVCMOS18;
NET “W_Addr[3]” IOSTANDARD = LVCMOS18;
NET “W_Addr[4]” IOSTANDARD = LVCMOS18;
NET “CF” IOSTANDARD = LVCMOS18;
NET “clk_25M” IOSTANDARD = LVCMOS18;
NET “clk_WB” IOSTANDARD = LVCMOS18;
NET “clk_RR” IOSTANDARD = LVCMOS18;
NET “clk_F” IOSTANDARD = LVCMOS18;
NET “OF” IOSTANDARD = LVCMOS18;
NET “reg_Write” IOSTANDARD = LVCMOS18;
NET “res_n” IOSTANDARD = LVCMOS18;
NET “SF” IOSTANDARD = LVCMOS18;
NET “ZF” IOSTANDARD = LVCMOS18;
NET “ALU_OP[3]” PULLDOWN;
NET “ALU_OP[2]” PULLDOWN;
NET “ALU_OP[1]” PULLDOWN;
NET “ALU_OP[0]” PULLDOWN;
NET “R_Addr_A[4]” PULLDOWN;
NET “R_Addr_A[3]” PULLDOWN;
NET “R_Addr_A[2]” PULLDOWN;
NET “R_Addr_A[1]” PULLDOWN;
NET “R_Addr_A[0]” PULLDOWN;
NET “R_Addr_B[4]” PULLDOWN;
NET “R_Addr_B[3]” PULLDOWN;
NET “R_Addr_B[2]” PULLDOWN;
NET “R_Addr_B[1]” PULLDOWN;
NET “R_Addr_B[0]” PULLDOWN;
NET “W_Addr[4]” PULLDOWN;
NET “W_Addr[3]” PULLDOWN;
NET “W_Addr[2]” PULLDOWN;
NET “W_Addr[1]” PULLDOWN;
NET “W_Addr[0]” PULLDOWN;
NET “clk_25M” PULLDOWN;
NET “clk_F” PULLDOWN;
NET “clk_RR” PULLDOWN;
NET “clk_WB” PULLDOWN;
NET “reg_Write” PULLDOWN;
NET “res_n” PULLDOWN;
六、思考与探索
1、实验结果记录:
先将reg[FFFFFFFFH]和reg[FFFFFFFEH]相加,再存入reg[1]中,最后对reg[1]与reg[1]相加得到FFFFFFFEH,则实验成功。
(实验操作的过程及结果记录)
2、实验结论:
本实验主要是为了寄存器堆的实现,我们发现寄存器堆的实现需要很多接口的输入和输出。同时也需要很多的时间去验收。
(分析实验结果,给出实验结论)
3、问题与解决方案:
本次实验的书写中我们主要发现问题还是分布在各个模块的关联性上面,同时没有满足相关的模块的逻辑顺序。
解决方案:具体读文件的顺序同时更多了解里面的实验原理。
(整个实验过程中发生了什么问题?你是如何解决的。)
4、思考题:
a) 寄存器堆的判断写入成功,通过写入的寄存器和零号寄存器单元进行加法来计算判断是否写入成功(零号寄寄存器永远为0)
b) ALU_OP可以为一个部分,CLK_A和CLK_B为一个部分,clk_write为一个部分,这三个部分可以分开写。那么一共只需要10个开关。
c) 不能,因为clk_RR是将寄存器堆模块的数据打入到寄存器模块中,clk_F是将寄存器模块的A,B计算出F放入到寄存器模块中,而clk_WB是将寄存器的F打入到寄存器堆当中,这其中功能不同,所以不能合并。
d) 可以将寄存器堆设置一个使能控制,表示单一输出,那么则只需要一个输出接口了,同时还可以加上一个相关的立即数存入B中,再进行后续的计算。
e) 在这个寄存器堆设计实验中,这个实验理解起来稍微困难,起初已经写好了代码,进行了仿真,出现了波形,但是后来老师要求读操作和写操作输出了不同的数据,在不同的单元。于是我就把仿真代码改了一下,将W_Data,W_Addr等数据做了修改。这个实验也就成功了。通过做这个寄存器堆设计实验,我对寄存器堆的读写操作有了一个新的认识和理解了。也对ISE这个软件的运用更加熟练,对寄存器堆这个概念也有了更深层次的理解,增长了我的只是,强化了我的实践能力以及思考能力。这次实验收获巨大。
最后
以上就是义气大米为你收集整理的杭电计算机组成原理实验RISC-V 实验 寄存器堆与运算器设计实验实验报告一、实验目的与要求二、实验设计与程序代码四、电路图五、引脚配置六、思考与探索的全部内容,希望文章能够帮你解决杭电计算机组成原理实验RISC-V 实验 寄存器堆与运算器设计实验实验报告一、实验目的与要求二、实验设计与程序代码四、电路图五、引脚配置六、思考与探索所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复