vivado 仿真ram,rom和fifo

FIFO、RAM、ROM学习文档

一、FIFO

  1. read latency问题

FIFO有两种读模式,第一种是标准fifo,这种模式下读使能为1之后,要延迟一个时钟周期之后fifo输出的第一个数据才是第一个写入fifo的数据。如下图所示:

vivado 仿真ram,rom和fifo

蓝色信号为读使能,18为fifo第一个写入的数据。

第二种是first-word fall through, 这种模式下读使能为1之后,不延迟时钟周期。

vivado 仿真ram,rom和fifo

2.仿真时一直出现问题,full和empty信号一直飘红,后来发现是初始信号full设置的初值问题。

 

vivado 仿真ram,rom和fifo

图中的full flags reset value开始为1,需要设置为0。

3.data count信号

Data count信号是在写入数据是开始从0开始加1,一直加到写满,加到1023(即写满)后为0,此时开始读的话,从0开始减1,减到1为止。(即读空)后为0。

4.wr_ack信号时wr_en的写入数据状态,成功写入一个数据后为1。即相当于wr_en的一个延时信号

5.valid信号,在standard fifo中,rd_en信号为1的下一个时钟valid为1,在first模式中,rd_en为1,valid为1。即此信号为1时,读出的信号为有效信号。

6.empty和full信号,standard模式写入一个数据后empty由1变为0,或者读完全部数据后由0变为1。almost_empty与almost_full相当于full和empty的展宽信号,在full与empty为1的前一个时钟周期它为1.在full与empty为0的后一个时钟周期它为0。如果是first模式,要写入三个数据后empty才由1变为0,同样的,full信号在standard模式时,数据写到1023后面的0时才变为1,而first模式,在数据写到1022时full就变为1。

7.underflow与overflow信号有图可以看出,当信号写满fifo时,wr_en还为1时,此时overflow为1,同样的,若读空时,rd_en还为1,underflow为1。

vivado 仿真ram,rom和fifo

vivado 仿真ram,rom和fifo

这里要注意读写使能的信号给定,不然只给定一个信号的时候,很容易出现full,empty信号出现X的情况。

always @(posedge clk or posedge rst)begin

  if(rst)begin

      wr_en <= 1'b0;

      rd_en <= 1'b0;

  end

  else begin

       if((!full)&(!rd_en))

       begin

           wr_en <= 1'b1;

            rd_en <= 1'b0;

         end

         else if(!empty)begin

          wr_en <= 1'b0;

          rd_en <= 1'b1;

      end

      else begin

         rd_en <= 1'b0;

         end

end 

例如这里初始化和if条件中,wr_en和rd_en都需要给定值。

8.当读写时钟不一样时,即异步fifo时,开始写入数据时,这里设定wr_clk为50MHZ,数据位为10位,rd_clk为100MHZ,数据位为5位,开始写数据时,wr_data_count开始从0累加到1023,同时rd_data_count从0累加到2042(跟着wr_clk,每次累加2)。读信号为1的下一个周期一直到full为0期间,wr_data_count保持1023不变,但在rd为1的下一个周期开始时,rd_data_count已经开始随着rd_clk变化了,每读一个数据,rd_data_count减1。开始读数据后,full信号为0后,wr_data_count开始随着wr_clk自减1。(我也不知道为啥full信号持续时间这么长)

9.prog_full与prog_empty与wr_data_count,rd_data_count有关,当rd_data_count为2(与empty threshold assert value设定的值有关-2)时,prog_empty为1。wr_data_count为1019(与full threshold assert value设定的值有关-2)时,prog_full为1。

vivado 仿真ram,rom和fifo

二、RAM

  这里实验是使用RAM的真双口ram做的,这里的输入信号和输出信号相差一个时钟,即当din信号给定,地址开始加时,douta或doutb延迟2个时钟周期得到din的值,这里需要注意的问题是A口和B口是共享同一个内存地址的,即addra[0]写入的值,用addrb[0]也可读取出来。

vivado 仿真ram,rom和fifo

 

第二个实验是用single RAM做的,开始为了验证wea和ena各自的作用,将ena当作读使能的时候有以下结果:vivado 仿真ram,rom和fifo

此时dout一直为0,说明写使能无效。

  之后将ena置1,其它不变,可以得到以下结果:

vivado 仿真ram,rom和fifo

说明ena不是读使能,是整个ram的使能信号,局部放大看:vivado 仿真ram,rom和fifo

vivado 仿真ram,rom和fifo

  可以看出,douta比dina延迟两个时钟,即输出信号有两个时钟的延迟,另外,从图中可以看出wea为0时,只要地址在加,douta就有数据。说明ram读数据是通过地址来读的,只要使能信号为1,地址在加,内存有数据,读数据就有效。

三、ROM

vivado 仿真ram,rom和fifo

  可以看出,使能信号给出之后,douta数据延迟输出2个时钟,和ram类似。

在实验过程中,coe文件加载不了,原因之一是有中文路径,另外一个原因是深度给的不够,改了路径后成功加载,改了深度后validate通过。