• 0
charlieho

How to connect an external FIFO to FPGA

Question

Hello Community,

I am a newbie and am using Xilinx Vivado 2018.1.

I have a project with Kintex 7. I want to connect an external FIFO ( 72T18125L4 )  to Kintex 7 and I want to implement an interface in Kintex 7 to communicate with this FIFO.

Please give me the idea!

Sorry if I posted in wrong place! :(

Thank you very much!

Best regards,

Charlie.

Share this post


Link to post
Share on other sites

10 answers to this question

Recommended Posts

  • 0
Posted (edited)

Thinking of which... actually I do have a plain-Verilog FIFO around from an old design.

It's not a showroom piece but I think it did work as expected (whatever that is...) For 131072 elements you'd set ADDRBITS to 17 and DATABITS to 18 for 18 bit width.

module FIFO(i_clk, i_reset, 
	    i_push, i_pushData, 
	    i_pop, o_popAck, o_popData, 
	    o_empty,
	    o_full,
	    o_error, 
	    o_nItems, o_nFree);
   parameter DATABITS = -1;   
   parameter ADDRBITS = -1;
   localparam ADDR_ZERO = {{(ADDRBITS){1'b0}}};
   localparam ADDR_ONE = {{(ADDRBITS-1){1'b0}}, 1'b1};   
   localparam DATA_X = {{(DATABITS){1'bx}}};
   input wire i_clk;
   input wire i_push;
   input wire i_reset;   
   input wire [DATABITS-1:0] i_pushData;
   input wire 		     i_pop;
   output reg 		     o_popAck = 1'b0;
   output wire [DATABITS-1:0] o_popData;
   output reg 		      o_error = 1'b0;   
   output wire [31:0] 	      o_nItems;
   output wire [31:0] 	      o_nFree;   
   output wire 		      o_empty;  
   output wire 		      o_full;   
   reg 			      popAckB = 1'b0;
      
   reg [DATABITS-1:0] 	      mem[((1 << ADDRBITS)-1):0];
   reg [ADDRBITS-1:0] 	      pushPtr = ADDR_ZERO;
   reg [ADDRBITS-1:0] 	      popPtr = ADDR_ZERO;
   reg [DATABITS-1:0] 	      readReg = DATA_X;
   reg [DATABITS-1:0] 	      readRegB = DATA_X;
   wire [ADDRBITS-1:0] 	      nextPushPtr = i_push ? pushPtr + ADDR_ONE : pushPtr;
   wire [ADDRBITS-1:0] 	      nextPopPtr = i_pop ? popPtr + ADDR_ONE : popPtr;
   
   assign o_popData = o_popAck ? readReg : DATA_X;

   // === items counter ===
   // note: needs extra bit (e.g. 4 slots may hold [0, 1, 2, 3, 4] elements)
   reg [ADDRBITS:0] 	      nItems;
   assign o_nItems = {{{31-ADDRBITS-1}{1'b0}}, nItems};
   assign o_nFree = (1 << ADDRBITS) - nItems;
   
   localparam NITEMS_ONE = {{(ADDRBITS){1'b0}}, 1'b1};
   assign o_empty = nItems == 0;
   assign o_full = nItems == {1'b1, {{ADDRBITS}{1'b0}}};
   
   always @(posedge i_clk) begin
      // === preliminary assignments ===
      readRegB <= DATA_X;
      popAckB <= 1'b0;

      case ({i_push, i_pop})
	2'b10: nItems <= nItems + NITEMS_ONE;
	2'b01: nItems <= nItems - NITEMS_ONE;
	default: begin end
      endcase
      o_error <= (i_push && ~i_pop && o_full) || (i_pop && o_empty);
      
      // === output register (delay 1) ===
      o_popAck <= popAckB;
      readReg <= readRegB;
      
      pushPtr <= nextPushPtr;
      popPtr <= nextPopPtr;      
            
      if (i_push)
	mem[pushPtr] <= i_pushData;
      if (i_pop) begin
	 readRegB <= mem[popPtr];
	 popAckB <= 1'b1;
      end
	 
      if (i_reset) begin
	 pushPtr 	<= ADDR_ZERO;
	 popPtr 	<= ADDR_ZERO;
	 o_error 	<= 1'b0;
	 o_popAck 	<= 1'b0;
	 popAckB 	<= 1'b0;
	 readReg 	<= DATA_X;
	 readRegB 	<= DATA_X;	 
	 nItems 	<= 0;	 
      end
   end
endmodule

 

Edited by xc6lx45

Share this post


Link to post
Share on other sites
  • 0

you might give a bit more information to not be mistaken for a lazy student.
My first thought is simply "do not". The component is EOL and you can have the same using the FPGA's BRAM with a LOT less hassle.

Share this post


Link to post
Share on other sites
  • 0

Hi @xc6lx45,

Thank for your response!

I have read this data sheet https://www.idt.com/document/dst/72t1845-72t18125-datasheet. There are a lot of listed pins. 

In my old design, I used an internal IP FIFO for this function and I only used some signals, for example: data_out,fifo_full, fifo_empty, fifo_threshold, fifo_overflow, fifo_underflow,clk, rst_n, wr, rd, data_in,...

How can I apply my old design with the external FIFO via an interface instead the internal FIFO? Do I must use all pins of external FIFO? I followed this example (for ADC) https://surf-vhdl.com/how-to-connect-an-adc-to-an-fpga/ but it is so simple.

Please correct me or give me suggestion!

Thanks!

Charlie.

Share this post


Link to post
Share on other sites
  • 0

I'm going to echo @xc6lx45 and suggest that you reconsider. Does your Kintex have insufficient BRAM for an on-chip FIFO? Using BRAM would be so much easier.

If you choose to use the external FIFO, you'll have to adapt the logic that you use to interface to the FIFO to use the signaling of this other FIFO.

Sometimes it helps to post more context: what do you want the system to be able to do that it does not now?

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)

Hi @jamey.hicks,

We are going to use Kintex 7 XC7K160T and want to store 131071 samples (18 bits per sample) in FIFO. However, maximum RAM block of Kintex 7 is 36 Kb. I think we have not enough RAM capacity (Please correct me!).

This is the reason why we have to use an external FIFO.

Please give us suggestion!

Thank you!

Best regards,

Charlie.

Edited by charlieho

Share this post


Link to post
Share on other sites
  • 0

Well, to be honest, I didn't read the datasheet to the high-capacity devices with 9M bits. So this one isn't even EOL.

Well, it depends.
Have a look at https://www.xilinx.com/support/documentation/data_sheets/ds180_7Series_Overview.pdf table 6.
There are 325 of those 36 kB blocks on the FPGA (11700 kB in total), so you need about 1/4 of the total FPGA for memory.
Technically feasible and easiest to implement but a very expensive FIFO.

Now, connecting this chip to realize its full performance potential (e.g. 225 MHz) is not straightforward.

From between the lines ...
>> Do I must use all pins of external FIFO?
... I read that you don't have hands-on experience with e.g. CMOS ICs (the answer is "you must drive any input at any time, unless the data sheet says explicitly otherwise", or strange things will happen. "Strange" in a sense that the circuit may respond to waving my hands over it, and that's not an exaggeration).
If I'm correct in this, it may be a good idea to get e.g. a few CD4017 or some other standard CMOS chip with simple functionality for < $1 and use this to bring up your FPGA IOs. If the FIFO chip doesn't work because of IO issues, it will be near-impossible to debug.





Share this post


Link to post
Share on other sites
  • 0
Posted (edited)

Hi @xc6lx45,

Thank for your response!

Well, to be honest, I don't have hands-on experience with e.g. CMOS ICs and your advices is very useful.

My understanding is I can implement on-chip FIFO for my project without any memory capacity problem? Does it mean that I can use more than 1 block RAM for 1 FIFO? (Sorry, I am not clear about your saying "...but a very expensive FIFO.").

Thank you very much!

Best regards,

Charlie.

Edited by charlieho

Share this post


Link to post
Share on other sites
  • 0

Yes, you can combine more than one block RAM.
There is more than one way to implement a FIFO. If I had to do it for myself, I'd write it in plain Verilog, it's about two or three screen lengths of code if the interface requirements are "clean" (such as, one clock and freedom to leave a few clock cycles of latency, before the first input appears at the output).
I didn't check but I think there is an "IP block wizard" for FIFOs in Vivado that may do what you need.
With "expensive" I meant just that, it costs a lot of money to use half an FPGA just for memory.

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)

I have a few random thoughts on the subject ( is anyone surprised? )

I looked over an old project where just for fun I used a 128Kx32 single clock FIFO built with BRAM. It was for the Nexys Video Artix device which has the same 36Kb BRAMs. it used 116 BRAMs and worked at 100 Mhz with a mid-range speed part. 36Kb/9 = 4096 bytes plus parity, 131072/4906 = 32 9-bit BRAMs, 4x32 = 128 BRAMs to implement a 128Kx32 FIFO so Vivado must have found some way to save 12 BRAMs. If you have 18-bit data that's fine as the BRAMs can be organized as 32Kx9 where the extra bit is meant for parity. From experience I can tell you that using the parity bit for data can get tricky but is entirely possible. If you need a dual clock FIFO then expect to use more BRAMs. If there isn't much else in your design timing won't be a problem. If you are trying to place 116 BRAMs into a complicated high speed design then you will find yourself needing to leanr about timing closure strategies. 

If I don't have to worry about resource usage, timing issues I'd use an HDL to implement RAM or FIFO structures as it's portable, more or less. I tend to just bite the bullet and use the vendors tools to implement resources like block memory, PLLs, and such as these resources aren't really that compatible between vendors and I usually do care about resource usage and timing. Also, vendor IP 'wizards' sometimes creates constraints for them and take care of a lot of little details that ultimately save time.

Edited by zygot

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now