Increasing the FIFO size

Dear Colin,

I am using the FIFO (and not DDR) in the FPGA openADC module. My FPGA resources allow an increase of FIFO write depth from the ‘default’ 8k to a maximum of 32k which theoratically allows for 100k samples per acquisition.

Implementing this FIFO change allows me to increase the samples beyond the original 25k max. Unfortunately, I can only capture 49k samples, which is still less than 100k. Increasing the sample size above 49k, sendMessage(CODE_READ, ADDR_ADCDATA, None, False, bytesToRead + 1) causes a timeout, with no data sent by the FPGA. This is strange as the FPGA FIFO responds that it contains up to 100k samples using getBytesInFifo()

I suspect this is because 49k samples take up 0xffff bytes of space in the FIFO and bytecnt in reg_openadc_adcfifo.v is only 2 bytes long.

However, I have trouble debugging this as I don’t understand how the FPGA calculates the response size for a read request to ADDR_ADCDATA. In reg_main.v for example, the response size is taken from the Write/Read Size LSB fields sent by the control SW. However, for sendMessage(CODE_READ, ADDR_ADCDATA, None, False, bytesToRead + 1) , these fields are zero…

I hope you can shed some light! :bulb:

Yeah, I remember this part being a bit shady, my apologies :wink: To avoid an issue with the 16-bit bytecnt, when you issue a read command I believe it was designed to actually empty the entire FIFO. The use of the ‘stream’ flag effectively overrides any byte count, see line 345 of reg_main.v:

if ( (reg_stream == 1) || ((bytecnt < (total_bytes-16'd1)) && (total_bytes != 0)) ) begin

This is why the system FIRST reads the number of bytes waiting before actually reading them. This way it knows when to stop the USB transfer based on how many bytes should be dumped over the USB line.

But I don’t know if I ever tested it with FIFOs that large, so there might be an error causing some problem there. The largest I had used was with the SASEBO-W which I had a MAX_SAMPLES of 49K samples too. Looking at the code around line 354 in reg_main.v is suspicious:

							//Will select next byte
							bytecnt <= bytecnt + 16'd1;

I bet if you add code that pegs it to 0xFFFF instead of rolling over, it might work? From memory I thought it DID peg at 0xFFFF, so that might have been an oversight by myself.



EDIT: PS I feel I should explain this entire module came from when I was using the OpenADC on a serially-connected FPGA. Unfortunately it added some craziness to the design (i.e. I wanted almost zero overhead, the protocol had to work over a serial line), which wasn’t helped by grafting this onto several different USB solutions! But it hasn’t fallen over badly enough to bother rewriting…

Thanks Colin, your suggestion to modify reg_main.v (line 354) works beautifully.

//Will select next byte
if (bytecnt == 16'hFFFF) begin
	bytecnt <= bytecnt;
end else begin
	bytecnt <= bytecnt + 16'd1;

Great, I’ll add that into the main GIT repo to avoid catching other people!