寄存器堆实验
- 实验原理
- 实验内容
- 模块功能说明
- 模块逻辑引脚图
- 寄存器堆模块代码
- REG模块测试用例
- REG-ALU测试用例
- 实验结果记录
- 寄存器堆实验结果及分析
- ALU_REG运算器模块实验结果及分析
- 探索与思考
实验原理
32×32位的寄存器堆模块示意图如图所示,含有32个寄存器,每个寄存器32位。该寄存器堆具有A和B两个读端口,分别由 5 位的寄存器编号 R_Addr_A 和 R_Addr_B 来寻址 2 个寄存器,读出的数据则由 R_Data_A(32 位)和R_Data_B(32 位)输出。读访问时,没有使能或者时钟信号控制,只要给出寄存器地址,就可读出寄存器中的数据。
该寄存器堆只有一个写端口,端口地址为5位的W_Addr,写操作的控制信号是 Write_Reg,写入的数据为32位的W_Data。
寄存器堆功能表如表所示。W_Addr、W_Data和 Write_Reg必须在时钟clk上升沿来临时,已经有效。此外,该寄存器堆具有清零功能,清零信号为 CPU 的 Reset 信号。
实验内容
- 设计一个寄存器堆模块,并仿真验证;
- 修改ALU模块中的ALU_OP为3位,完成前8种功能;
调用ALU模块和寄存器堆模块设计一个图2所示的ALU_REG模块,完成 Ri θ Rj → Rk 的操作,即2 个寄存器数据做某种运算,结果送回第3 个寄存器中;其中运算功能θ则由ALU 模块中的ALU_OP 信号指定。设计仿真测试用例,仿真验证。
ALU_OP[2:0] | ALU功能 | 操作说明 |
---|---|---|
000 | and | 逻辑与运算 |
001 | or | 逻辑或运算 |
010 | xor | 逻辑异或运算 |
011 | nor | 逻辑或非运算 |
100 | add | 算术加运算 |
101 | sub | 算术减运算 |
110 | slt | 若A<B,则输出1;否则输出0 |
111 | sll | B逻辑左移A所指定的位数 |
模块功能说明
本实验共3个模块
模块调用关系说明:ALU-REG模块中调用了ALU模块和REG模块
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46module REGS_ALU( clk,rst,Write_Reg,//控制信号 R_Addr_A,R_Addr_B,W_Addr,//读写地址 R_Data_A,R_Data_B,//数据数据 OP,ZF,OF,ALU_F//ALU运算 );//ALU-REG模块 input clk, rst;//写入时钟信号, 清零信号 input [4:0]R_Addr_A;//A读端口寄存器地址 input [4:0]R_Addr_B;//B读端口寄存器地址 input [4:0]W_Addr;//写寄存器地址 input Write_Reg; //写控制信号 output [31:0]R_Data_A;//A端口读出数据 output [31:0]R_Data_B;//B端口读出数据 input [2:0] OP;//运算符编码 output ZF;//零标志 output OF;//溢出标志(只对有符号数运算有意义) output [31:0]ALU_F;//ALU运算结果 module REGS(R_Data_A,R_Data_B,W_Data,R_Addr_A,R_Addr_B,W_Addr,Write_Reg,rst,clk); //寄存器堆模块 input clk;//写入时钟信号 input rst;//清零信号 input Write_Reg;//写控制信号 input [4:0]R_Addr_A;//A端口读寄存器地址 input [4:0]R_Addr_B;//B端口读寄存器地址 input [4:0]W_Addr;//写寄存器地址 input [31:0]W_Data;//写入数据 output [31:0]R_Data_A;//A端口读出数据 output [31:0]R_Data_B;//B端口读出数据 module ALU(ALU_OP,A,B,F,ZF,OF);//ALU模块 input [2:0] ALU_OP; //运算功能的控制线 input [31:0] A; //运算数 input [31:0]B; //运算数 output [31:0] F; //运算结果 output ZF; //零标志位 output OF; //溢出标志位
模块逻辑引脚图
寄存器堆模块代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81module REGS_ALU( clk,rst,Write_Reg,//控制信号 R_Addr_A,R_Addr_B,W_Addr,//读写地址 R_Data_A,R_Data_B,//数据IO OP,ZF,OF,ALU_F//ALU运算 ); input clk, rst;//写入时钟信号, 清零信号 input [4:0]R_Addr_A;//A读端口寄存器地址 input [4:0]R_Addr_B;//B读端口寄存器地址 input [4:0]W_Addr;//写寄存器地址 input Write_Reg;//读写控制信号 output [31:0]R_Data_A;//A端口读出数据 output [31:0]R_Data_B;//B端口读出数据 input [2:0] OP;//运算符编码 output ZF;//零标志 output OF;//溢出标志(只对有符号数运算有意义) output [31:0]ALU_F;//运算结果F REGS REGS_1(R_Data_A,R_Data_B,ALU_F,R_Addr_A,R_Addr_B,W_Addr,Write_Reg,rst,clk); ALU ALU_1(OP,R_Data_A,R_Data_B,ALU_F,ZF,OF); //assign W_Data = ALU_F; endmodule module REGS(R_Data_A,R_Data_B,W_Data,R_Addr_A,R_Addr_B,W_Addr,Write_Reg,rst,clk); input clk;//写入时钟信号 input rst;//清零信号 input Write_Reg;//写控制信号 input [4:0]R_Addr_A;//A端口读寄存器地址 input [4:0]R_Addr_B;//B端口读寄存器地址 input [4:0]W_Addr;//写寄存器地址 input [31:0]W_Data;//写入数据 output [31:0]R_Data_A;//A端口读出数据 output [31:0]R_Data_B;//B端口读出数据 integer i; reg [31:0] REG_Files[0:31]; initial REG_Files[0]<=32'hF0F0F0F0; initial REG_Files[1]<=32'h00000004; initial for(i=2;i<32;i=i+1) REG_Files[i]<=0; always@(posedge clk or posedge rst) begin if(rst) for(i=0;i<32;i=i+1) REG_Files[i]<=0; else if(Write_Reg) REG_Files[W_Addr]<=W_Data; end assign R_Data_A=REG_Files[R_Addr_A]; assign R_Data_B=REG_Files[R_Addr_B]; endmodule module ALU(ALU_OP,A,B,F,ZF,OF); input [2:0] ALU_OP; input [31:0] A; input [31:0]B; output [31:0] F; output ZF; output OF; reg [31:0] F; reg C,ZF,OF; always@(*) begin C=0; OF=0; case(ALU_OP) 3'b000:begin F=A&B; end 3'b001:begin F=A|B; end 3'b010:begin F=A^B; end 3'b011:begin F=~(A|B); end 3'b100:begin {C,F}=A+B;OF = A[31]^B[31]^F[31]^C; end 3'b101:begin {C,F}=A-B;OF = A[31]^B[31]^F[31]^C; end 3'b110:begin F=A<B; end 3'b111:begin F=B<<A; end endcase ZF = F==0; end endmodule
REG模块测试用例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74initial begin // Initialize Inputs W_Data = 0; R_Addr_A = 10101; R_Addr_B = 0; W_Addr = 0; Write_Reg = 0; rst = 0; clk = 0; #100 W_Data = 32'hAAAAAAAA; R_Addr_A = 0; R_Addr_B = 0; W_Addr = 10101; Write_Reg = 1; #100 W_Data = 0; R_Addr_A = 10101; R_Addr_B = 0; W_Addr = 0; Write_Reg = 0; rst = 0; clk = 0; #100 W_Data = 32'hFFFFFFFF; R_Addr_A = 0; R_Addr_B = 0; W_Addr = 10101; Write_Reg = 1; clk = 1; #100 W_Data = 0; R_Addr_A = 10101; R_Addr_B = 0; W_Addr = 0; Write_Reg = 0; clk = 0; #100 rst = 1; W_Data = 0; R_Addr_A = 10101; R_Addr_B = 0; W_Addr = 0; Write_Reg = 0; #100 rst = 0; W_Data = 0; R_Addr_A = 01010; R_Addr_B = 0; W_Addr = 0; Write_Reg = 0; #100 W_Data = 32'hAABBCCDD; R_Addr_A = 0; R_Addr_B = 0; W_Addr = 01010; Write_Reg = 1; clk = 1; #100 W_Data = 0; R_Addr_A = 01010; R_Addr_B = 0; W_Addr = 0; Write_Reg = 0; #100; W_Data = 0; R_Addr_A = 0; R_Addr_B = 0; W_Addr = 0; Write_Reg = 0; #100; end endmodule
REG-ALU测试用例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63always #33 clk=~clk; initial begin clk = 0; rst = 0; Write_Reg = 0; R_Addr_A = 32'd0; R_Addr_B = 32'd1; W_Addr = 32'd10; OP = 3'b000; #100 Write_Reg = 1; R_Addr_A = 32'd0; R_Addr_B = 32'd1; W_Addr = 32'd10; OP = 3'b000; #100 Write_Reg = 1; R_Addr_A = 32'd0; R_Addr_B = 32'd1; W_Addr = 32'd11; OP = 3'b001; #100 Write_Reg = 1; R_Addr_A = 32'd0; R_Addr_B = 32'd1; W_Addr = 32'd12; OP = 3'b010; #100 Write_Reg = 1; R_Addr_A = 32'd0; R_Addr_B = 32'd1; W_Addr = 32'd13; OP = 3'b011; #100 Write_Reg = 1; R_Addr_A = 32'd0; R_Addr_B = 32'd1; W_Addr = 32'd14; OP = 3'b100; #100 Write_Reg = 1; R_Addr_A = 32'd0; R_Addr_B = 32'd1; W_Addr = 32'd15; OP = 3'b101; #100 Write_Reg = 1; R_Addr_A = 32'd0; R_Addr_B = 32'd1; W_Addr = 32'd16; OP = 3'b110; #100 Write_Reg = 1; R_Addr_A = 32'd1; R_Addr_B = 32'd2; W_Addr = 32'd17; OP = 3'b111; #100 rst=1; #100; end endmodule
实验结果记录
寄存器堆实验结果及分析
1.实验结果记录表
ALU_REG运算器模块实验结果及分析
1.实验结果记录表
2.仿真波形图
探索与思考
与本实验设计的寄存器堆相比,MIPS 计算机的通用寄存器堆结构类似:有 32×32位的寄存器组,具有 2 个读端口和 1 个写端口,读操作不需要时钟信号,写操作在时钟边沿触发;不同之处在于,MIPS 的寄存器堆中, 0 地 址 的 寄 存 器 ( 即 R 0 , 汇 编 符 号 0 地址的寄存器(即 R0,汇编符号 0地址的寄存器(即R0,汇编符号zero)中始终存储常数 0,对 R0 的读操作,直接返回常数 0;且不允许对 R0执行写操作。修改本实验所实现的基本寄存器堆模块,实现 MIPS 计算机的通用寄存器堆,以供后续 MIPS CPU 的设计使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25module REGS(R_Data_A,R_Data_B,W_Data,R_Addr_A,R_Addr_B,W_Addr,Write_Reg,rst,clk); input clk;//写入时钟信号 input rst;//清零信号 input Write_Reg;//写控制信号 input [4:0]R_Addr_A;//A端口读寄存器地址 input [4:0]R_Addr_B;//B端口读寄存器地址 input [4:0]W_Addr;//写寄存器地址 input [31:0]W_Data;//写入数据 output [31:0]R_Data_A;//A端口读出数据 output [31:0]R_Data_B;//B端口读出数据 integer i; reg [31:0] REG_Files[0:31]; initial for(i=0;i<32;i=i+1) REG_Files[i]<=0; always@(posedge clk or posedge rst) begin if(rst) for(i=0;i<32;i=i+1) REG_Files[i]<=0; else if(Write_Reg&&W_Addr!=32'd0) REG_Files[W_Addr]<=W_Data; end assign R_Data_A=REG_Files[R_Addr_A]; assign R_Data_B=REG_Files[R_Addr_B]; endmodule
最后
以上就是体贴舞蹈最近收集整理的关于杭电计算机组成原理课程设计-实验七-寄存器堆设计实验的全部内容,更多相关杭电计算机组成原理课程设计-实验七-寄存器堆设计实验内容请搜索靠谱客的其他文章。
发表评论 取消回复