在之前的工作中,我们对常见存储器件进行了名词扫盲,通过调用IP核实现了简单的单端口同步读写SRAM、通过Verilog实现了单端口同步读写SRAM、单端口同步写,异步读SRAM、单端口异步读写SRAM,双端口同步读写SRAM,以及双端口异步读写SRAM,这些工作见:

Verilog实现RAM

但是随着深入学习发现,之前实现的异步RAM更像是一个时钟无关的RAM;异步双口SRAM应该是读写时钟不同,才能叫异步,像之前写的“异步”SRAM实际为时钟无关的RAM,都没有时钟,如何称为异步?因此,重新对异步双口SRAM进行设计和验证:

目录

一、原理

二、代码实现与仿真:

三、参考文献:


一、原理

异步双口SRAM与双端口同步读写SRAM类似,唯一区别就在于两组端口时钟不同,分别在其控制信号的作用下(如:片选、使能、地址等)进行读/写操作;

输入端口有:(异步应该有两组时钟)

reg clk1;//端口1对应时钟

reg [3:0]a1;//输入地址(RAM深度为16,对应地址位宽为4)

reg we1;// write enable,写使能时进行RAM写操作

reg oe1;// output enable,输出使能时RAM读取的结果才能输出

reg cs1;// 片选信号,选择读取哪一个RAM

//  第二套

reg clk2;//端口2对应时钟

reg [3:0]a2;//输入地址(RAM深度为16,对应地址位宽为4)

reg we2;// write enable,写使能时进行RAM写操作

reg oe2;// output enable,输出使能时RAM读取的结果才能输出

reg cs2;// 片选信号,选择读取哪一个RAM

输入输出端口有:
    wire [7:0]d1;//读取RAM时数据输出/写入RAM时数据输入

wire [7:0]d2;//读取RAM时数据输出/写入RAM时数据输入

工作过程:

两组端口在各自时钟驱动下,独立的根据各自的控制信号cs/we/oe执行对应的操作;工作过程类似:

cs有效(为1)、we为1时,写使能,将d输入数据写入a对应地址处;

cs有效(为1)、we为0时,读使能,oe有效(为1)时将a地址处的数据读出到d上;

注意:

双端口RAM同时读写时会出现冲突,如:同时对同一地址读操作,此时两个端口能直接同时读出数据吗?存在仲裁吗?再如:同时对同一地址进行写操作,此时写地址的结果应该是啥?是报错?是仲裁?写的内容是哪个端口的内容?还是说内容杂糅在一起;这就想起来之前看过的一句话,编写一个简单的RAM很容易,但是要编写一个稳定的,考虑全面的RAM绝非易事。这也是为什么推荐使用IP核的原因,因为IP核是众多工程师努力的结晶,相对来说更稳定,考虑的更全面。但是此处为了了解RAM的工作流程,暂不考虑复杂的情况,只对RAM的简单功能进行仿真实现。

二、代码实现与仿真:

接着之前的工作----仍旧实现一个位宽8bit,深度16bit的双口异步SRAM;

实现代码:

`timescale 1ns / 1ps
//
// Company:
// Engineer: guoliang CLL
//
// Create Date: 2020/03/04 15:51:18
// Design Name:
// Module Name: dsram
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module dsram
#(parameter DW = 8,AW = 4)
(input clk1,input [AW-1:0]a1,//addressinput cs1,// chip selectinput oe1,// output enableinput we1,// write enableinout [DW-1:0]d1,// data// input clk2,input [AW-1:0]a2,//addressinput cs2,// chip selectinput oe2,// output enableinput we2,// write enableinout [DW-1:0]d2// data);//
parameter DP = 1 << AW;// depth
reg [DW-1:0]mem[0:DP-1];
reg [DW-1:0]reg_d1;
// port2
reg [DW-1:0]reg_d2;
//initialization
// synopsys_translate_off
integer i;
initial beginfor(i=0; i < DP; i = i + 1) beginmem[i] = 8'h00;end
end
// synopsys_translate_on// read declaration
// port1
always@(posedge clk1)
beginif(cs1 & !we1 & oe1)beginreg_d1 <= mem[a1];endelsebeginreg_d1 <= reg_d1;end
end
// port2
always@(posedge clk2)
beginif(cs2 & !we2 & oe2)beginreg_d2 <= mem[a2];endelsebeginreg_d2 <= reg_d2;end
end// wrirte declaration
// port1
always@(posedge clk1)
beginif(cs1 & we1)//port1 higher prioritybeginmem[a1] <= d1;endelsebeginmem[a1] <= mem[a1];end
end
//port2
always@(posedge clk2)
beginif(cs2 & we2)beginmem[a2] <= d2;endelsebeginmem[a2] <= mem[a2];end
end// 三态逻辑
assign d1 = (cs1 & !we1 & oe1) ? reg_d1 : {DW{1'bz}};
assign d2 = (cs2 & !we2 & oe2) ? reg_d2 : {DW{1'bz}};
endmodule

测试文件:

测试设计:port1对应快时钟clk1,port2对应慢时钟clk2;

1、port1在clk1驱动下从地址0-15写数据1-16;port2同时在clk2驱动下从地址0-15读数据;

2、port1在clk1驱动下从地址15-0读数据;port2同时在clk2驱动下从地址15-0写数据oxff;

`timescale 1ns / 1ps
//
// Company:
// Engineer: CLL
//
// Create Date: 2020/03/04 16:42:17
// Design Name:
// Module Name: dsram_tsb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module dsram_tsb();
// port declaration
reg clk1;
reg clk2;
// port1
reg [3:0]a1;//address
reg cs1;
reg oe1;
reg we1;// write enable
wire [7:0]d1;//datain/out
// port2
reg [3:0]a2;//address
reg cs2;
reg oe2;
reg we2;// write enable
wire [7:0]d2;//datain/out
// reg declaration
reg [7:0]din1;
reg [7:0]din2;
// clk1
initial
beginclk1 = 1'b0;forever #10 clk1 = ~clk1;//period = 20
end
// clk2
initial
beginclk2 = 1'b0;forever #25 clk2 = ~clk2;//period = 50
end
//
assign d1 = (cs1 & we1)?din1:8'bzzzz_zzzz;
assign d2 = (cs2 & we2)?din2:8'bzzzz_zzzz;
//port1
initial
begin
///fork// port1写,port2读begina1 = 4'b0000;din1 = 8'd1;we1 = 1'b1;oe1 = 1'b0;cs1 = 1'b1;repeat(15) begin//port1写1-16于地址0-15#20 a1 = a1+1'b1;din1 = din1+1'b1;endendbegina2 = 4'b0000;din2 = 8'd0;we2 = 1'b0;oe2 = 1'b1;cs2 = 1'b1;repeat(15) begin//port2读地址0-15#50 a2 = a2+1'b1;endendjoin
///#50//执行完后,port1读,port2写fork// port1写,port2读beginwe1 = 1'b0;oe1 = 1'b1;cs1 = 1'b1;repeat(15) begin//port1读于地址15-0#20 a1 = a1-1'b1;endendbegindin2 = 8'b1111_1111;we2 = 1'b1;oe2 = 1'b0;cs2 = 1'b1;repeat(15) begin//port2写11111111于地址15-0#50 a2 = a2-1'b1;endendjoin
end
dsram inst (.clk1(clk1),.a1(a1),      // input wire [3 : 0] a.d1(d1),      // input wire [7 : 0] d.we1(we1),    // input wire we.cs1(cs1), .oe1(oe1),.clk2(clk2),  .a2(a2),      // input wire [3 : 0] a.d2(d2),      // input wire [7 : 0] d.we2(we2),    // input wire we.cs2(cs2), .oe2(oe2)
);
endmodule

仿真结果如下:

1、port1在clk1驱动下从地址0-15写数据1-16;port2同时在clk2驱动下从地址0-15读数据;如下:

可以看出,读写分别对应各自的clk上升沿,port1在clk1驱动下将数据1-16写入了mem的[0-15],port2在clk2驱动下以一个较慢的速度从地址0-15读出数据1-16,与设计一致;

2、port1在clk1驱动下从地址15-0读数据;port2同时在clk2驱动下从地址15-0写数据oxff;如下:

可以看出,读写分别对应各自的clk上升沿,port1在clk1驱动下快速从地址15-0读出之前写进去的数据16-1,读数据较快不受port2新写入的oxff影响,port2在clk2驱动下以一个较慢的速度向地址15-0写数据oxff,与设计一致;

RTL电路如下:

三、参考文献:

verilog怎么写能综合出异步的RAM

verilog中的fork...join用法

Verilog实现RAM(7-异步双口SRAM:原理、实现、仿真、分析)相关推荐

  1. 伪双口ram工作原理单口及RAM、伪双口RAM、双口RAM与FIFO的区别

    FPGA时序时序分析中的基本概念 FPGA设计中,常用到的数据缓存IP有FIFO和RAM,其中RAM又分单口RAM.伪双口RAM.双口RAM. 伪双口ram的工作原理,开始的时候以为有两个wea使能信 ...

  2. 单口RAM、伪双口RAM、双口RAM与FIFO的区别

    单口RAM.伪双口RAM.双口RAM与FIFO的区别 FPGA设计中,常用到的数据缓存IP有FIFO和RAM,其中RAM又分单口RAM.伪双口RAM.双口RAM.        单口与双口的区别在于, ...

  3. 单口RAM、伪双口RAM、真双口RAM、单口ROM、双口ROM的区别

    单口RAM与伪双口RAM.真双口RAM的区别在于: 单口RAM只有一个时钟(clka)(时钟上升沿到来时对数据进行写入或读出).一组输入输出数据线(dina&douta).一组地址线(addr ...

  4. Vivado 双口RAM 的调用和实现

    1.双口RAM概述 双口RAM(dual port RAM)在异构系统中应用广泛,通过双口RAM,不同硬件架构的芯片可以实现数据的交互,从而实现通信.例如,一般情况下,ARM与DSP之间的通信,可以利 ...

  5. 单口RAM、双口RAM、FIFO

    单口RAM.双口RAM.FIFO 单口与双口 单口与双口的区别在于,单口只有一组数据线与地址线,因此读写不能同时进行:而双口有两组数据线与地址线,读写可同时进行:FIFO读写可同时进行,可以看作是双口 ...

  6. 单口RAM,双口RAM,FIFO的区别

    总结:单口ram只有一组数据线.地址线,不能同时读写:双口ram有两组数据线.地址线. 在电路上的区别就是在latch的两边有几个开关管. 单口与双口的区别在于,单口只有一组数据线与地址线,因此读写不 ...

  7. 单口RAM、双口RAM、FIFO三者的关系

    单口与双口 单口与双口的区别在于,单口只有一组数据线与地址线,因此读写不能同时进行:而双口有两组数据线与地址线,读写可同时进行:FIFO读写可同时进行,可以看作是双口: 简单双口RAM与真双口RAM ...

  8. FPGA双口RAM使用

    模块名称: dpram() IP Core 双口RAM,有俩组数据线和地址线,读写可以同时进行,FIFO读写可以同时进行,可以看作是双口.分为Simple two-dual RAM和true two- ...

  9. xilinx 真双口RAM的primitives /core output 区别

    软件平台 Vivado 2016.4 属性设置说明 1在 ip catalog -> block memory generator . 这里仅介绍真双口RAM, 真双口RAM支持A/B两个口可读 ...

最新文章

  1. php删除尾部字符,php如何删除字符串末尾字符
  2. Magento教程 18:Magento功能导览(2) 展示商品
  3. JQuery学习笔记(1)
  4. 做了5年测试连一门语言都没学?逆袭后拿到3个超22K offer!
  5. 添加类库引用后,命名空间出错的解决方案
  6. 数据治理方案技术调研 Atlas VS Datahub VS Amundsen
  7. 【Espruino】NO.18 使用L298N驱动直流电机
  8. BAT文件里注释符号
  9. linux 找不到libaio.h,POSIX AIO和Linux上的libaio之间的区别?
  10. 【C语言编程】切比雪夫多项式
  11. 最新数据:微博Q1季度数据分析报告来了!
  12. 小京东V5.X短信宝插件开发
  13. LaTeX软件安装及简易入门
  14. 淘宝京东天猫电商运营每天都需要做什么?
  15. 计算机网络基础实验(Cisco Packet Tracer 实验)
  16. 图像艺术风格化 Neural-Style
  17. 攻防世界-Crypto-告诉你个秘密(键盘密码)-ISCC2017
  18. 【区块链论文整理】SIGMOD 篇 (二)
  19. termux配置python安装kali_安卓用termux安装kali linux教程
  20. AliExpress绑定万事达虚拟信用卡(Mastercard)测试实操教程

热门文章

  1. Java流程控制:用for循环或while循环计算1~100的和
  2. 读书笔记——《黑客大曝光》(6/8)
  3. 蒙特卡洛方法——高斯分布
  4. 关于echarts实现地图并显示各省份名称及不同块显示不同原因,最后循环播放tooltip信息
  5. 蝴蝶效应(Java版 Python版后期上新)
  6. 物理学专业英语(写作整理)03 物理中常用的数学运算
  7. Mac程序坞只显示正在运行的应用图标
  8. 序章1-前端学子的实习之路探索版
  9. 美联储降息如何影响加密货币市场?| 一周问答热议
  10. python数据分析:流量数据化运营(下)——基于自动K值得KMeans广告效果聚类分析