C/C++教程

Altera SCFIFO同时读写问题探究

本文主要是介绍Altera SCFIFO同时读写问题探究,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

在网上看到关于Altera的SCFIFO核的介绍中,都提到了它可以支持同时读写的功能,但未看到具体的仿真情况。Altera官方的ug中,也未看到关于此的明确描述(也可能是我读文档不仔细)。因此,对该问题进行modelsim仿真,将仿真情况记录于此,大家一起探讨。
首先生成一个256B的SCFIFO核,其主要参数如下:

defparam
		scfifo_component.add_ram_output_register = "ON",
		scfifo_component.almost_empty_value = 64,
		scfifo_component.almost_full_value = 128,
		scfifo_component.intended_device_family = "Cyclone III",
		scfifo_component.lpm_numwords = 256,
		scfifo_component.lpm_showahead = "OFF",
		scfifo_component.lpm_type = "scfifo",
		scfifo_component.lpm_width = 8,
		scfifo_component.lpm_widthu = 8,
		scfifo_component.overflow_checking = "ON",
		scfifo_component.underflow_checking = "ON",
		scfifo_component.use_eab = "ON";

生成的模块外形如下图所示。
在这里插入图片描述
编写测试代码如下


`timescale 1ns / 1ns
module fifo_buf_tb;
	reg	  hclk;
	reg	[7:0]  data;
	reg	  rdreq;
	reg	  sclr=0;
	reg	  wrreq;
	
	wire	  almost_empty;
	wire	  almost_full;
	wire	  empty;
	wire	  full;
	wire	[7:0]  q;
	wire	[7:0]  usedw;
	
FIFO_BUF	DUT (
	.clock ( hclk ),
	.data ( data ),
	.rdreq ( rdreq ),
	.sclr ( sclr ),
	.wrreq ( wrreq ),
	.almost_empty ( almost_empty ),
	.almost_full ( almost_full ),
	.empty ( empty ),
	.full ( full ),
	.q ( q ),
	.usedw ( usedw )
	);
	
//20MHz高钟
  initial
  begin
   hclk  = 1'b1  ;
   forever	   
	  #25  hclk  = !hclk  ;
  end
  
 //每1us更新一次data,每次更新自加1
 initial
 begin
	data=1;
	forever
		#1000	data=data+1;
 end
 
//给出一个高钟周期的wrreq信号
initial
begin
	wrreq=0;
	forever
	begin
		#(0) wrreq=1;
		#50	wrreq=0;
		#(1000-50) ;
	end
end

//FIFO写入64字节后,进行读取试验
initial
begin
	rdreq=0;
	forever
	begin
		#0 rdreq=(usedw>64?1:0);
		#50	rdreq=0;
		#(1000-50) ;
	end
end 

//Start Time = 0 ns, End Time = 1ms  
initial
	#1000000 $stop;
endmodule

modelsim仿真结果如下图所示。
在这里插入图片描述
由此可以看出,当输入数据的跳变和wrreq、rdreq同时发生时,SCFIFO中的数据无法正常读取,但非常奇怪的是,降低wrreq和rdreq的操作频率后,即时三者的跳变沿仍然是同步的,读取却是正常了。
相关代码调整如下

//给出一个高钟周期的wrreq信号
initial
begin
	wrreq=0;
	forever
	begin
		#(1000) wrreq=1;	//wrreq的操作频率降低一半
		#50	wrreq=0;
		#(1000-50) ;
	end
end

//FIFO写入64字节后,进行读取试验
initial
begin
	rdreq=0;
	forever
	begin
		#1000 rdreq=(usedw>64?1:0);	rdreq的操作频率降低一半
		#50	rdreq=0;
		#(1000-50) ;
	end
end 

仿真结果如下图。
在这里插入图片描述
可见此时SCFIFO的同时读写就正常了,但原因百思不得其解。
继续探讨SCFIFO不能正常同时读写的场景,一开始以为是wrreq与data同时跳变引起的,修改测试代码,使wrreq分别提前、错后一个高钟周期,仿真结果如下图所示。
wrreq提前一个高钟周期
wrreq错后一个高钟周期
由此可以看出,wrreq提前还是错后对仿真结果没有影响,都不能正常读取SCFIFO中的数据。
调整测试方式,固定wrreq与data同时跳变,调整rdreq的产生时间,仿真结果如下图所示。
rdreq提前一个高钟周期
rdreq错后一个高钟周期
由此可以看出,只要rdreq不与输入的data同时跳变,SCFIFO中的数据就可以正常读出。
继续针对读写频次的问题进行单变量测试,只降低读频次,仿真结果如下图(读触发条件改为usedw>96)。
在这里插入图片描述
此时SCFIFO的同时读写是正常的。
降低写频次进行仿真,结果如下图所示。
在这里插入图片描述
此时SCFIFO中的数据不能正常读出。
加密读频次,仿真结果如下图所示。
在这里插入图片描述
此时SCFIFO的读取扔不正常,推测是由于rdreq与输入data同频同相,导致SCFIFO输出出现异常,其它的rdreq信号也无法正常工作。
由上面的试验可以得出结论:当rdreq信号的周期和跳变沿与输入data完全一致时,SCFIFO中的数据无法正常读出
虽然有了这个结论,但问题的机理仍不清楚,不知道与SCFIFO核的实现机制有无关系。在altera的文档中也未看到相关描述。因此,结论的正确性不能得到充分保证,期望各路大神进行指导。

这篇关于Altera SCFIFO同时读写问题探究的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!