【计算机组成原理】实验3
使用Verilog语言实现一个寄存器堆,测试平台:Vivado
①代码:
REG.v :
`timescale 1ns / 1ps
module regfile(
input clk,
input wen, //写使能
input [4 :0] raddr1, //读地址
input [4 :0] raddr2,
input [4 :0] waddr, //写地址
input [31:0] wdata,
output reg [31:0] rdata1, //读数据
output reg [31:0] rdata2,
input [4 :0] test_addr,
output reg [31:0] test_data
);
reg [31:0] rf[31:0];
// three ported register file
// read two ports combinationally
// write third port on rising edge of clock
// register 0 hardwired to 0
//写端口
integer i;
always @(posedge clk)
if(wen)
begin
for (i = 0; i < 32; i = i +1)
rf[i] <= 0;
end
else
begin
if(wdata)
rf[waddr] <= wdata;
end
//读端口1
always @(*)
begin
assign rdata1 = rf[raddr1];
end
//读端口2
always @(*)
begin
assign rdata2 = rf[raddr2];
end
//调试端口,读出寄存器值显示在触摸屏上
always @(*)
begin
case (test_addr)
5'd1 : test_data <= rf[1 ];
5'd2 : test_data <= rf[2 ];
5'd3 : test_data <= rf[3 ];
5'd4 : test_data <= rf[4 ];
5'd5 : test_data <= rf[5 ];
5'd6 : test_data <= rf[6 ];
5'd7 : test_data <= rf[7 ];
5'd8 : test_data <= rf[8 ];
5'd9 : test_data <= rf[9 ];
5'd10: test_data <= rf[10];
5'd11: test_data <= rf[11];
5'd12: test_data <= rf[12];
5'd13: test_data <= rf[13];
5'd14: test_data <= rf[14];
5'd15: test_data <= rf[15];
5'd16: test_data <= rf[16];
5'd17: test_data <= rf[17];
5'd18: test_data <= rf[18];
5'd19: test_data <= rf[19];
5'd20: test_data <= rf[20];
5'd21: test_data <= rf[21];
5'd22: test_data <= rf[22];
5'd23: test_data <= rf[23];
5'd24: test_data <= rf[24];
5'd25: test_data <= rf[25];
5'd26: test_data <= rf[26];
5'd27: test_data <= rf[27];
5'd28: test_data <= rf[28];
5'd29: test_data <= rf[29];
5'd30: test_data <= rf[30];
5'd31: test_data <= rf[31];
default : test_data <= 32'd0;
endcase
end
endmodule
TestBench.v :
`timescale 1ns / 1ps
module tb;
//Inputs
reg clk;
reg wen;
reg [4 :0] raddr1;
reg [4 :0] raddr2;
reg [4 :0] waddr;
reg [31:0] wdata;
reg [4 :0] test_addr;
//Outputs
wire [31:0] rdata1;
wire [31:0] rdata2;
wire [31:0] test_data;
regfile rf(
.clk(clk),
.wen(wen),
.raddr1(raddr1),
.raddr2(raddr2),
.waddr(waddr),
.wdata(wdata),
.rdata1(rdata1),
.rdata2(rdata2),
.test_addr(test_addr),
.test_data(test_data)
);
initial begin
//Initialize
clk = 0;
wen = 0;
raddr1 = 0;
raddr2 = 0;
waddr = 0;
wdata = 0;
test_addr = 0;
//write
#10;
waddr = 5'h17;
wdata = 32'h7F;
#40;
wen = 1'b1;
#50;
wen = 1'b0;
//read
#100;
raddr1 = 5'h17;
#100;
raddr2 = 5'h17;
#100;
test_addr = 5'h17;
end
always #5 clk = ~clk;
endmodule
②仿真图像及其分析:
先向waddr地址17写入数据wdata = 000007f,
随后第一次读取地址raddr1 = 17中的数据,得到rdata1 = 000007f,
随后第二次读取地址raddr2 = 17中的数据,得到rdata2 = 000007f.
随后第三次读取地址test_addr = 17中的数据,得到test_data = 000007f.