xilinx fifo核使用时注意的问题

          最近一个月在使用fifo做一个数据的缓存和不同数据域的同步,用FPGA驱动AD的spi接口,系统中有8片AD,每片AD由两个独立的并行AD通道组成,采样率1Msps,量化位数16bit,每次采集的数据为256bit,xilinx fifo的输入输出最大数据宽度比例为1:8或者8:1,意思就是256bit输入时,输出要大于等于32bit。采集的数据经由fifo缓存以后,通过usb发送给电脑。选用的usb芯片是FTDI公司的ft232h (具体介绍在另外日志上说明)的USB接口芯片,它的数据接口是8位宽度的双向数据总线。由于fifo的32bit输出和usb接口芯片的8bit数据总线之间存在差异,为了解决这个差异,笔者最先考虑到的是通过逻辑来控制对fifo的读,将读取的数据分4次传入usb接口芯片,这种方案尝试了近两周的时间,总是会出现不同程度数据的遗漏,基本上隔几个周期会漏掉一个字节或者两个字节的数据,这里最容易想到的就是逻辑控制上有问题,debug了近一周的时间,没有取得成功。

          最后在fifo的32bit数据输出和8bit usb接口芯片之间再次加入了一个fifo,相当于这个fifo是用于将32bit数据转换成8bit数据输出的。最后的数据传送方式是: 256bit->fifo1->32bit->fifo2->8bit->usb;通过这种方式,数据可以稳定无误的传输。

          本文提及到了两个fifo,所以说说在使用fifo的过程中遇到的那些问题,不过这些问题都是由于没有仔细看ug(user guaid)导致的。

          一、IP的复位问题:

          xilinx 对D触发器的复位采用高电平复位,而不是我们常常喜欢使用的低电平复位。当然,如果使用低电平复位时,编译器会自动的插入一个非门,将边沿翻转一下。但是对于IP情况有所不同,例如下面的代码和RLT示意图:其中wclk_32是写时钟域的时钟信号,always块是一种常用的异步复位同步释放的写法,要注意的是如果产生的nrst_32to8不取反以后给fifo用于复位时,会是一个比较隐晦的错误,数据不能够被写入,fifo的ug上说到,用block ram产生的异步fifo时,要复位才能工作。但是没有提到是高电平复位。IP核是低到高的上升降沿复位,在综合的时候,其不会自动的加入非门(如果采用常用的下降沿低电平方式去复位IP核时),要手动添加非门(在信号前加入“!”)。

reg nrst_32to8,rff;
always @(posedge wclk_32 or negedge nrst)
  if (!nrst)   {nrst_32to8,rff} <= 2'b0;
  else         {nrst_32to8,rff} <= {rff,1'b1};<pre name="code" class="cpp">fifo32to8 ins_fifo32to8 (
  .rst(!nrst_32to8), // input rst
  .wr_clk(wclk_32), // input wr_clk
  .rd_clk(rclk_8), // input rd_clk
  .din(din_32), // input [31 : 0] din
  .wr_en(wen_32), // input wr_en
  .rd_en(ren_8), // input rd_en
  .dout(dout_8), // output [7 : 0] dout
  .full(full_32), // output full  //full_32
  .empty(empty_8), // output empty
  .valid(valid_8), // output valid
  .wr_ack(wr_ack) // output wr_ack
);



展开阅读全文

没有更多推荐了,返回首页