FIFO存储深度(容量)计算

如果数据流连续不断则FIFO深度无论多少,只要读写时钟不同源同频则都会丢数;
FIFO用于缓冲块数据流,一般用在写快读慢时,
FIFO深度 / (写入速率 - 读出速率) = FIFO被填满时间   应大于 数据包传送时间= 数据量 / 写入速率

例:A/D采样率50MHz,dsp读A/D读的速率40MHz,要不丢失地将10万个采样数据送入DSP,在A/D在和DSP之间至少加多大容量(深度)的FIFO才行?
100,000 / 50MHz =   1/ 500 s = 2ms
(50MHz - 40MHz) * 1/500 = 20k既是FIFO深度。

一种错误的算法(我也犯了同样的错误):
100,000/40MHZ=   1/400s = 2.50ms

(50M - 400M)*1/400 =25K.那么这样进去的数据就不是100K了,而是100K+50M*(0.0025-0.002)=125,000bit,错误在时间的计算

异步FIFO设计注意事项
异步FIFO的设计与同步FIFO的设计具有很大差距;设计的时候需要考虑跨时钟域处理带来的问题;
1、FIFO的设计必须解决empty和full控制问题;
2、异步FIFO可以考虑把写Addr在写时钟域转换成gray码,然后通过读时钟来寄存器,转换到读时钟域中,解决empty标记信号;
3、异步FIFO可以考虑把读Addr在读时钟域转换成gray码,然后通过写时钟来寄存器,转换到写时钟域中,解决full标记信号;
4、使用gray码的原因在gray码可以把Addr值连续变化的规例(但是Addr的会有多个bit跳变)转换成gray码中只有1个bit跳变,这样在跨时钟域传输中不会出现异步采取出现很大差异(异步时钟采样会出现亚稳态现象),最多是原始Addr值加1或者减1,这样不会使得FIFO状态出现错误;

当fifo的尺寸很大时候。用gray code 变得不太合算。
因为要从binary变成gray,再变回来。

这个时候,要用异步handshake来把地址转到另一个
时钟域里面。简单的说用 request  和 ack。
具体我也没有做过。

不过这是几乎每个美国公司面视毕问的问题。
所以研究透一点有好处。

计算FIFO深度-翻译-英汉对照版

introduction   
One of the most common questions in interviews is how to calculate the depth of a  FIFO.
在而试过程中,经常被问及的问题之一就是如何计算一个FIFO的深度。
Fifo is used as buffering element or queueing element in the system, which is by common sense is required only when you slow at reading than the write operation.
FIFO在统中用来作缓冲或者队列,通常情况下,当读速率比写速率慢的时候,需要采用FIFO。
So size of the FIFO b asically im plies the amount of data required to buffer, which depends upon data rate at which data is written and the data rate at which data is read.
所以 FIFO的深度取决于需要缓冲的数据量,缓冲的数据量取决于写速率和读速率
Statistically, Data rate varies in the system majorily depending upon the load in the system. So to obtain safer FIFO size we need to consider the worst case scenario for the data transfer across the FIFO under consideration.
统计表明,系统中数据率的变化主要依赖于系统的负载。所以,为了得到安全的FIFO,在 设计时,我们需要考虑最坏情形下的通过FIFO进行的数据传输。
For worst case scenario, Difference between the data rate between write and read should be maximum. Hence, for write operation maximum data rate should be considered and for read operation minimum data rate should be considered.
最坏情况下,读写数据间的速率差,应该为最大值。也就是说,写操作速率应该取最大的写速率,而读操作应该取选小的读速率。
So in the question itself, data rate of read operation is specified by the number of idle cycles and for write operation, maximum data rate should be considered with no idle cycle.
如问题本身,读操作的数据速率是由空闲周期决定的,而对于写操作,最大的写数据率,应该不考虑空闲周期。
So for write operation, we need to know Data rate = Number of data * rate of clock. Writing side is the source and reading side becomes sink, data rate of reading side depends upon the writing side data rate and its own reading rate which is Frd/Idle_cycle_rd.
因而,对于读操作,我们有 Data rate = Number of data * rate of clock。写方是数据流入的方,而读方是数据露出方。读方的速率取决于写方的速率和自身的读速率(Frd/Idle_cycle_rd.)
In order to know the data rate of write operation, we need to know Number of data in a Burst which we have assumed to be B.
为了获知写方数据速率,我们需要知道在突发 模式下的数据量,我们假设其为B.
So following up with the equation as explained below: Fifo size = Size to be buffered = B - B * Frd / (Fwr* Idle_cycle _rd ).
参考如下的等式:Fifo size = Size to be buffered = B - B * Frd / (Fwr* Idle_cycle _rd ).
Here we have not considered the sychnronizing latency if Write and Read clocks are Asynchronous. Greater the Synchronizing latency, higher the FIFO size requirement to buffer more additional data written.
这里,我们没有考虑由于异步读写需要同步,所引入的延时。越大的延时,需要越大的FIFO来缓冲更多和写数据。
Example : FIFO Depth Calculation   
              例子:计算FIFO深度
Assume that we have to  design a FIFO with following requirements and We want to calculate minumum FIFO depth,
假充我们需要设计如下需求的FIFO,我们需要计算它的最小深度。
  A synchronized fifo 异就FIFO
Writing clock 30MHz - F1    写 时钟
Reading clock 40MHz - F2       读时钟
Writing Burst Size - B     突发数据量 
Case 1 : There is 1 idle clock cycle for reading side - I  读方一个空闲周期 
Case 2 : There is 10 idle clock cycle for reading side - I  读方10个空闲周期 
FIFO depth calculation = B - B *F2/(F1*I)
If if we have alternate read cycles i.e between two read cycle there is IDLE cycle.
如果我们已经改变了读周期,比如,两个读周期中有一个空闲周期。
FIFO depth calculation = B - B * F2/(F1*2)
In our present problem FIFO depth = B - B *40/(30*2)
= B(1-2/3)= B/3
That means if our Burst amount of data is 10 , FIFODEPTH = 10/3 = 3.333 = 4 (approximatly)
  If B = 20 FIFO depth = 20/3 = 6.6 =  7or 8 (clocks are asynchronous)
  If B = 30 FIFO depth = 30/3 = 10     10+1 = 11 (clocks are asynchronous)
If 10 IDLE cycles betweeen two read cycles .
FIFO DEPTH = B - B *F2/(F1*10) .= B(1-4/30)= B * 26 /30
### 回答1: 我可以给你一些关于如何使用Verilog编写一个异步FIFO的指导方针: 1.使用Verilog的状态机模块,定义FIFO的状态,并设置输入和输出信号; 2.使用Verilog的模拟模块,定义FIFO的读写操作; 3.使用Verilog的时序模块,定义FIFO的时序控制,实现异步FIFO功能; 4.使用Verilog的测试模块,定义FIFO的测试代码,验证FIFO的正确性。 ### 回答2: 在Verilog中,可以使用信号的上升边沿来实现一个简单的异步FIFO(First-In First-Out)。 首先,我们需要定义FIFO的一些参数,如数据宽度、深度等。假设我们定义FIFO的数据宽度为8位,深度为16。 接下来,我们可以定义FIFO的输入和输出端口。输入包括数据输入d_in和写入使能信号wr_en。输出包括数据输出d_out和读取使能信号rd_en。 然后,我们需要定义一个数据存储区域,用于存储来自输入端口的数据。这可以通过定义一个大小为深度乘以数据宽度的数组来实现。 接着,我们可以开始编写模块中的逻辑。首先,我们需要实现写操作。当wr_en为1时,将数据d_in写入数组的下一个可用位置。 然后,我们需要实现读操作。当rd_en为1时,从数组的下一个可读位置输出数据d_out,并将该位置的数据清零。 最后,我们需要处理一些边界情况。当FIFO已满时,写操作应该被忽略。同样,当FIFO为空时,读操作应该被忽略。 需要注意的是,异步FIFO的实现需要考虑时序问题。Verilog提供了多种方法来处理时序逻辑,如使用always块或者使用非阻塞赋值语句。具体的实现方式可以根据需求和个人喜好选择。 总之,通过编写适当的逻辑代码,我们可以实现一个简单的异步FIFO模块。这个模块可以接收并存储来自输入端口的数据,并按照先进先出的顺序将数据输出到输出端口。 ### 回答3: 异步 FIFO 是一种常用的数字电路设计,用于解决不同速度的数据传输问题。下面我会用300字的篇幅来回答如何用 Verilog 语言编写一个异步 FIFO。 异步 FIFO 由读指针、写指针和存储器组成。我们首先需要定义这三部分在 Verilog 中的描述。读指针和写指针由计数器实现,存储器可以使用 Verilog 中的 reg 数组来表示。 module fifo (input wire c1, c2, reset, // 输入时钟信号 input wire d, // 输入数据信号 output reg r, // 读信号 output wire almost_empty, // 非完全空状态信号 output wire almost_full); // 非完全满状态信号 reg [7:0] FIFO [0:255]; // 存储器,这里假设容量为256,每个存储单元8位 reg [7:0] read_ptr, write_ptr, count; // 读写指针和计数器 always @(posedge c1 or posedge reset) begin // 对读指针、写指针和计数器进行操作 if (reset) begin // 复位 read_ptr <= 8'b0; write_ptr <= 8'b0; count <= 0; end else if (c1) begin // 在时钟上升沿进行操作 if (r == 1'b1) read_ptr <= read_ptr + 8'b1; // 读指针加1 if (count < 255 && d == 1'b1) begin // 如果计数器小于255且有数据输入,则写入存储FIFO[write_ptr] <= d; write_ptr <= write_ptr + 8'b1; // 写指针加1 count <= count + 1; // 计数器加1 end end end always @(posedge c2 or posedge reset) begin // 计算非完全空状态和非完全满状态信号 if (reset) begin almost_empty <= 1'bz; almost_full <= 1'bz; end else if (c2) begin almost_empty <= (count <= 0) ? 1'b1 : 1'b0; almost_full <= (count >= 255) ? 1'b1 : 1'b0; end end assign r = (count > 0) ? 1'b1 : 1'b0; // 根据计数器判断是否有可读数据 endmodule 上述 Verilog 代码中的异步 FIFO 模块实现了读信号的输出、非完全空状态和非完全满状态的计算,并在 c1 和 c2 时钟信号上升沿时对读写指针以及计数器进行操作,实现了异步 FIFO 的功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值