存储器的扩展
一、实验目的和要求
- 掌握利用 vivado 的 IP 核设计和实现 RAM 存储器的方法;
- 掌握存储器位扩展的方法;
- 掌握存储器字节扩展的方法;
- 学会初始化存储器;
- 熟悉存储器的存取方法。
二、实验内容和原理
实验内容:
使用 IP 核和存储器位扩展技术设计存储器
- 通过 vivado 工具,利用它的 IP 核,构建 4 个 16×2 位的存储器;
- 利用位扩展技术将上述 4 个存储器组成 1 个 16×8 位的存储器;
- 通过仿真验证;
- 将设计封装成 IP 核。
使用 IP 核和存储器字扩展技术设计存储器
- 通过 vivado 工具,利用它的 IP 核,构建 4 个 16×8 位的存储器;
- 利用字扩展技术将上述 4 个存储器组成 1 个 64×8 位的存储器;
- 通过仿真、下板验证;
原理: - 位拓展
2. 字拓展
三、主要仪器设备
个人电脑:Huawei Matebook 14 Windows 11 家庭中文版
类型:64位
处理器:Intel® Core™ i5-10210U CPU @ 1.60GHz 2.11 GHz
内存:16GB
四、操作方法与实验步骤
使用 IP 核和存储器位扩展技术设计存储器
创建项目ram16x8
在ram16x8文件夹下,用记事本创建4个文件,分别是ram16x2-1.coe、ram16x2-2.coe、ram16x2-3.coe、ram16x2-4.coe。内容相同,均为:
memory_initialization_radix=2;
memory_initialization_vector=00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00;
利用IP核创建16x2位的存储器
- 点击IP Catelog
- 在打开的IP Catelog中双击图中的Block Memory Generator 图4-2双击图中的Block Memory Generator
- 按照图示设置各个数据页,之后点击OK
图4-3 设置各个数据页_1
图4-4 设置各个数据页_2
图4-5 设置各个数据页_3
- 点击Generate,再点击OK,完成IP核的定制 图4-6 点击Generate 图4-7 点击OK
- 按照上述方法分别生成 ram16x2_2,ram16x2_3 和 ram16x2_4 这三个存储器,他们的初始化文件分别是 ram16x2-2.coe,ram16x2-3.coe,ram16x2-4.coe。
创建一个verilog设计源文件ram16x8.v,并向其中填入如下内容:
`timescale 1ns / 1ps
module ram16x8(
input clk, //时钟信号
input we, //写使能
input en, //使能信号
input [3:0] addr, // 地址线
input [7:0] datain, // 输入数据线
output [7:0] dataout // 输出数据线
);
ram16x2_1 u1(clk, en, we, addr, datain[1:0], dataout[1:0]);
ram16x2_2 u2(clk, en, we, addr, datain[3:2], dataout[3:2]);
ram16x2_3 u3(clk, en, we, addr, datain[5:4], dataout[5:4]);
ram16x2_4 u4(clk, en, we, addr, datain[7:6], dataout[7:6]);
endmodule
创建仿真文件ram16x8_sim.v,对上述设计文件进行仿真
`timescale 1ns / 1ps
module ram16x8_sim( );
//input
reg clk = 0;
reg en = 0;
reg we = 0;
reg [3:0] addr = 4'b0000;
reg [7:0] din = 8'h00;
//output
wire [7:0] dout;
//instantiate the Unit under test
ram16x8 ut(
.clk(clk),
.we(we),
.en(en),
.addr(addr),
.datain(din),
.dataout(dout)
);
initial begin
#100 begin we = 1;en = 1; addr = 4'b0011; din = 8'b10101010; end
#100 begin addr = 4'b0100; din = 8'b01010101; end
#100 begin addr = 4'b0101; din = 8'b10100101; end
#100 begin addr = 4'b0110; din = 8'b01011010; end
#100 begin we = 0; en = 0; addr = 4'b0011; end
#100 addr = 4'b0100;
#100 addr = 4'b0101;
#100 addr = 4'b0110;
#100 en = 1;
#100 addr = 4'b0011;
#100 addr = 4'b0100;
#100 addr = 4'b0101;
#100 addr = 4'b0110;
#100 addr = 4'b0000;
#100 begin en = 0; addr = 4'b0100; end
end
always #5 clk = ~clk;
endmodule
仿真结束,生成波形图
图4-8 16×8 存储器仿真
使用 IP 核和存储器字扩展技术设计存储器
- 创建一个项目ram64x8
- 在 ram64x8 文件夹下,用记事本创建 4 个文件,分别是 ram16x8-1.coe,ram16x8-2.coe, ram16x8-3.coe,ram16x8-4.coe。内容相同,均为:
memory_initialization_radix=16;
memory_initialization_vector=00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00; - 利用上述方法创建16x8位的存储器
- 创建一个verilog设计文件ram64x8.v,并向其中填入如下内容:
`timescale 1ns / 1ps
module ram64x8(
input clk, //时钟信号
input en, //使能信号
input we, //写信号
input [5:0] addr, //地址信号
input [7:0] din, //输入信号
output reg [7:0] dout //输出信号
);
wire enable1 = en && (addr[5:4] == 2'b00);
wire enable2 = en && (addr[5:4] == 2'b01);
wire enable3 = en && (addr[5:4] == 2'b10);
wire enable4 = en && (addr[5:4] == 2'b11);
wire [7:0] res1;
wire [7:0] res2;
wire [7:0] res3;
wire [7:0] res4;
ram16x8_1 u1(.clka(clk), .ena(enable1), .wea(we), .addra(addr[3:0]), .dina(din), .douta(res1));
ram16x8_2 u2(.clka(clk), .ena(enable2), .wea(we), .addra(addr[3:0]), .dina(din), .douta(res2));
ram16x8_3 u3(.clka(clk), .ena(enable3), .wea(we), .addra(addr[3:0]), .dina(din), .douta(res3));
ram16x8_4 u4(.clka(clk), .ena(enable4), .wea(we), .addra(addr[3:0]), .dina(din), .douta(res4));
always @(*) begin
if (en) begin
if (addr[5:4] == 2'b00) begin
dout <= res1;
end else if (addr[5:4] == 2'b01) begin
dout <= res2;
end else if (addr[5:4] == 2'b10) begin
dout <= res3;
end else begin
dout <= res4;
end
end
end
endmodule
- 建立仿真文件ram64x8_sim.v,并填入如下内容,对上述文件进行仿真:
`timescale 1ns / 1ps
module ram64x8_sim( );
//input
reg clk = 0;
reg en = 0;
reg we = 0;
reg [5:0] addr = 6'd0;
reg [7:0] din = 8'h00;
//output
wire [7:0] dout;
//instantiate the Unit under test
ram64x8 ut(
.clk(clk),
.we(we),
.en(en),
.addr(addr),
.din(din),
.dout(dout)
);
initial begin
#100 begin we = 1;en = 1; addr = 6'd10; din = 8'b10101010; end
#100 begin addr = 6'd20; din = 8'b01010101; end
#100 begin addr = 6'd40; din = 8'b10100101; end
#100 begin addr = 6'd60; din = 8'b01011010; end
#100 begin we = 0; en = 0; addr = 6'd10; end
#100 addr = 6'd20;
#100 addr = 6'd40;
#100 addr = 6'd60;
#100 en = 1;
#100 addr = 6'd10;
#100 addr = 6'd20;
#100 addr = 6'd40;
#100 addr = 6'd60;
#100 addr = 6'd0;
#100 begin en = 0; addr = 6'd20; end
end
always #5 clk = ~clk;
endmodule
- 完成仿真之后,得到下述波形图:
图4-9 64X8RAM 仿真波形图
五、实验数据记录和处理
1. 位拓展实验中使用的仿真文件ram16x8_sim.v:
`timescale 1ns / 1ps
module ram16x8_sim( );
//input
reg clk = 0;
reg en = 0;
reg we = 0;
reg [3:0] addr = 4'b0000;
reg [7:0] din = 8'h00;
//output
wire [7:0] dout;
//instantiate the Unit under test
ram16x8 ut(
.clk(clk),
.we(we),
.en(en),
.addr(addr),
.datain(din),
.dataout(dout)
);
initial begin
#100 begin we = 1;en = 1; addr = 4'b0011; din = 8'b10101010; end
#100 begin addr = 4'b0100; din = 8'b01010101; end
#100 begin addr = 4'b0101; din = 8'b10100101; end
#100 begin addr = 4'b0110; din = 8'b01011010; end
#100 begin we = 0; en = 0; addr = 4'b0011; end
#100 addr = 4'b0100;
#100 addr = 4'b0101;
#100 addr = 4'b0110;
#100 en = 1;
#100 addr = 4'b0011;
#100 addr = 4'b0100;
#100 addr = 4'b0101;
#100 addr = 4'b0110;
#100 addr = 4'b0000;
#100 begin en = 0; addr = 4'b0100; end
end
always #5 clk = ~clk;
endmodule
2. 字拓展实验中使用的仿真文件ram64x8_sim.v:
`timescale 1ns / 1ps
module ram64x8_sim( );
//input
reg clk = 0;
reg en = 0;
reg we = 0;
reg [5:0] addr = 6'd0;
reg [7:0] din = 8'h00;
//output
wire [7:0] dout;
//instantiate the Unit under test
ram64x8 ut(
.clk(clk),
.we(we),
.en(en),
.addr(addr),
.din(din),
.dout(dout)
);
initial begin
#100 begin we = 1;en = 1; addr = 6'd10; din = 8'b10101010; end
#100 begin addr = 6'd20; din = 8'b01010101; end
#100 begin addr = 6'd40; din = 8'b10100101; end
#100 begin addr = 6'd60; din = 8'b01011010; end
#100 begin we = 0; en = 0; addr = 6'd10; end
#100 addr = 6'd20;
#100 addr = 6'd40;
#100 addr = 6'd60;
#100 en = 1;
#100 addr = 6'd10;
#100 addr = 6'd20;
#100 addr = 6'd40;
#100 addr = 6'd60;
#100 addr = 6'd0;
#100 begin en = 0; addr = 6'd20; end
end
always #5 clk = ~clk;
endmodule
六、实验结果与分析
- 位拓展实验中仿真产生的波形图:
图4-10 16×8 存储器仿真 - 字拓展实验中仿真产生的波形图: 图4-11 64X8RAM 仿真波形图
七、讨论、心得
- 通过对存储器进行位拓展或字拓展,可以扩充存储器的容量。
- 起初在设计中,直接按照"clk、we、en"的顺序将信号输入到RAM芯片,但是输出的值总是有问题。后来通过查看RAM芯片的veo文件才知道原因。
- 通过本实验,我学会了使用 Vivado 软件进行存储器位扩展的方法。对计算机如何进行扩展有了更深入的了解。在进行实验验证时,对照约束文件的管脚接口,注意存储器的使能信号和读写信号的开关都要处于开启状态。
- 仿真波形结果是ZZZ(信号未连接使用),结果为XXX(信号未初始化或信号错误)