目录:
0. 前言
关于RAM的分类以及相关知识,可以参考以下几篇文章:
1. BRAM和DRAM
2. 细分与归类
1. VL53 单端口RAM
1.1 题目描述
设计一个单端口RAM,它有: 写接口,读接口,地址接口,时钟接口和复位;存储宽度是4位,深度128。
注意rst为低电平复位
1.1.1 信号示意图
1.1.2 波形示意图
无
1.1.3 输入描述
输入信号 enb, clk, rst addr w_data
类型 wire
在testbench中,clk为周期5ns的时钟,rst为低电平复位
1.1.4 输出描述
输出信号 r_data
类型 wire
1.2 解题思路
该题是一个单端口RAM,读和写是不能同时进行的,要么读,要么写,这里还有一个需要区分的点,那就是关于块RAM(BRAM)和分布式RAM(DRAM),记住一点区别就行,BRAM采用的是读写同步时钟,而DRAM采用的是读写不同步时钟,也就是说,读和写是异步的。
关于手撕RAM,记住结构就行,参考代码实现!!!
1.3 代码实现
`timescale 1ns/1ns
module RAM_1port(
input clk,
input rst,
input enb,
input [6:0]addr,
input [3:0]w_data,
output wire [3:0]r_data
);
//*************code***********//
// [位宽] name [深度] ===> 表示单端口分布式ram,特点是读写时钟异步
//或者说读需要时钟,写不需要时钟。
reg [3:0] s_dram [127:0];
//for 或者 generate...for都可以实现,区别在于后者需要将always块包住,前者写在always块里边
integer i;
always @ (posedge clk or negedge rst) begin
if(!rst) begin
for(i = 0; i < 128; i = i+1) begin
s_dram[i] <= 4'd0;
end
end
else begin
if(enb) begin
s_dram[addr] <= w_data;
end
else begin
s_dram[addr] <= s_dram[addr];
end
end
end
assign r_data = enb ? 4'd0 : s_dram[addr];
//*************code***********//
endmodule
1.4 测试文件
待更新。。。
1.5 仿真波形
待更新。。。
2. VL54 RAM的简单实现
2.1 题目描述
实现一个深度为8,位宽为4bit的双端口RAM,数据全部初始化为0000。具有两组端口,分别用于读数据和写数据,读写操作可以同时进行。当读数据指示信号read_en有效时,通过读地址信号read_addr读取相应位置的数据read_data,并输出;当写数据指示信号write_en有效时,通过写地址信号write_addr 和写数据write-data,向对应位置写入相应的数据。
2.1.1 信号示意图
2.1.2 波形示意图
2.1.3 输入描述
clk:系统时钟信号
rst_n:异步复位信号,低电平有效
read_en,write_en:单比特信号,读/写使能信号,表示进行读/写操作
read_addr,write_addr:8比特位宽的信号,表示读/写操作对应的地址
write_data:4比特位宽的信号,在执行写操作时写入RAM的数据
2.1.4 输出描述
read_data:4比特位宽的信号,在执行读操作时从RAM中读出的数据
2.2 解题思路
该题是一个双端口RAM,读和写可以同时进行的,需要注意的是,写使能为0时,写入的是0哦!读使能为0时,读出的也是0哦!
关于手撕RAM,记住结构就行,参考代码实现!!!
2.3 代码实现
`timescale 1ns/1ns
module ram_mod(
input clk,
input rst_n,
input write_en,
input [7:0]write_addr,
input [3:0]write_data,
input read_en,
input [7:0]read_addr,
output reg [3:0]read_data
);
reg [3:0]d_dram[7:0];
//write
integer i;
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
for(i=0; i<8; i=i+1) begin
d_dram[write_addr] <= 4'd0;
end
end
else begin
if(write_en) begin
d_dram[write_addr] <= write_data;
end
else begin
d_dram[write_addr] <= 4'd0; // 注意:写使能为0时,写入的是0哦!
end
end
end
//read
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
read_data <= 4'd0;
end
else begin
if(read_en) begin
read_data <= d_dram[read_addr];
end
else begin
read_data <= 4'd0; // 注意:读使能为0时,读出的也是0哦!
end
end
end
endmodule
2.4 测试文件
待更新。。。
2.5 仿真波形
待更新。。。
声明
本人所有系列的文章,仅供学习,不可商用,如有侵权,请告知,立删!!!
本人主要是记录学习过程,以供自己回头复习,再就是提供给后人参考,不喜勿喷!!!
如果觉得对你有用的话,记得收藏+评论!!!