1. 设计要求
设计一个位宽8bit,地址深度为128,可以同时读写的双端口RAM
要求:模块名字为RAM_DUAL
输入端口:ADDR_W,ADDR_R
CLK_R,CLK_W,RSTn
ADDR_R[6:0],ADDR_W[6:0]
DATA_WRT[7:0]
RD_EN,WRT_EN
输出端口:
DATA_RD[7:0]
2. 补充
一般大容量的RAM由专门的IP厂商提供,有单口RAM(读写不能同时进行),双口RAM等各种样式。IP厂商会提供behavior model,综合以及后端库文件
小容量的RAM可以自己用触发器阵列搭建。属于双口RAM(读写可以同时进行,但是必须是不同地址的读写),可支持同时读写。常用在FIFO中
(自己用触发器搭的ram一般都是双口的,因为触发器是支持读写的,读的话就是读触发器Q端的数据,写的话就是往触发器D端写数据)
3. 设计代码
如上图:ram用二维数组表示,在给ram赋值的时候,由于向量 不能直接给二维数组赋值,所以mem[127:0] <= 0是不被允许的,我们可以使用for循环为mem赋值,但是仿真工具不识别for语句,我们需要使用generate语句
使用generate会让仿真工具把for循环里面的代码展开,循环128次就是分别写128个always语句。分别针对mem[0],mem[1],mem[2] ...... mem[127]。
而变量定义需要使用genvar。
4. 仿真代码和波形
不能直接将二维数组mem拖入波形中观察(这是仿真工具verdi节约资源的做法)。如果想让mem二维数组直接拖入波形,我们需要在main.v仿真文件中加入$fsdbDumpMDA选项。