前言:
本专栏旨在记录高频笔面试手撕代码题,以备数字前端秋招,本专栏所有文章提供原理分析、代码及波形,所有代码均经过本人验证。
目录如下:
10.数字IC手撕代码-数据位宽转换器(宽-窄,窄-宽转换)
13.数字IC手撕代码-流水握手(利用握手解决流水线断流、反压问题)
18.数字IC手撕代码-双端口RAM(dual-port-RAM)
...持续更新
更多手撕代码题可以前往 数字IC手撕代码--题库
目录
双端口RAM
这篇文章来介绍双端口RAM,目的是为后续的同步FIFO和异步FIFO打下基础,我们都知道其实FIFO就类似一个RAM,但是它对输入输出的信号做了处理,可以使得数据在跨时钟域的时候不会出错。写FIFO都是要调用RAM的,那么一个双端口RAM怎么写呢?
双端口RAM分很多种,同步双端口RAM(读写同时钟),异步双端口RAM(读写分别用读时钟和写时钟),以及每种双端口RAM又分为伪双端口RAM和真双端口RAM。伪双端口RAM是指有两个读写通道,其中一个用来读另一个用来写。而真双端口 RAM 指的是有两个读写端口,每个端口都可以独立发起读或者写。
而单端口RAM就是对一个通道又读又写。
伪双端口RAM
一个伪双端口RAM,一个通道读,一个通道写,写通道有写数据、写地址和写使能,读通道有读数据、读地址和读使能,再加上输入时钟,构成输入输出的端口。一个简单的双端口RAM可以写成如下:
用两个过程语句块描述,一个通道读,一个通道写。如果是异步的时钟,即读写不是同一时钟的话,可以修改两个过程语句块的敏感事件列表,一个改成always@(posedge clkw),另一个改成always@(posedge clkr)即可。
真双端口RAM
而对于一个真双端口RAM,两个通道即可读又可写,怎么处理呢?
真双端口RAM,每个通道都有通道使能、输入数据、输出数据、数据地址、写使能、通道时钟六个端口,所以真双端口RAM共有12个端口。通道a一套,通道b一套。
对真双端口RAM的一个通道来说,当通道使能时,如果写使能,则把值写入到RAM的addra地址,并读出RAM位于addra地址的旧的值。如果写不使能,则读出RAM位于addra地址的数据。
代码
testbench
波形
之所以输出数据会出现红线,是因为RAM的一开始数值是不确定的,所以在每次切换地址后,读取出来的RAM对应地址的旧的值是不确定的,所以是红线。过一个周期后,改地址被写入新的值,新的值被读出,所以有data_o_a/b有数据。
当然我们这里还要提一下,可能有人会问,你这里不会出现读写冲突吗。你这里怎么判断空满,写满了怎么停止写入,读空了怎么停止读出呢?
对于第一个问题,两个通道对RAM的同一块地址同时进行读写,这个的解决办法是在一开始的时候,就不要让addra=addrb,解决问题的最好办法就是不让问题发生。
对于第二个问题,关于地址指针和空满判断其实不属于RAM的范畴,RAM可以把它理解为一个存储的空间,具体的指针控制和空满判断其实是RAM外部添加的一些控制信号。不属于RAM的范畴,具体如何解决地址指针移动及空满判断问题,会在同步FIFO及异步FIFO中给出详细解答。
更多手撕代码题可以前往 数字IC手撕代码--题库