1
votes

The diagram of my verilog firmware is like that:

valid signal from fifo

In my diagram, I have 6 16-bit data and 6 valid_data are outputs from 6 same module being generated by generate function. The function of valid_data is to notify when 16-bit data is written into FiFo (Native and IP core) supplied by Xilinx. Because there are two clocks domain in my firmware, so I use synchronous FiFo as a handshaking between two clocks domain to ensure that 6 16-bit data are obtained correctly in clock domain 120 MHz.

After that I put 6 16-bit output data from 6 synchronous FiFo to one 96-bit variable. I would like to use the 6 valid signal from 6 synchronous Fifos to generate the new valid signal to notify to asynchrous FiFo that 96-bit data is ready to be written into the asynchronous FiFo. But I have one problem:

I think that the 6 16-bit data go to the FIFO at the same time so the output from Synchronize of Fifo need to appear at the same time. But when I use chipscope to check the valid signal, I do not understand why the valid signal going out FIFO is not same time at the figure and it makes me very difficult to generate the new valid signal. Someone can tell me the reason why this happened.

6 valid signal from 6 Fifos and new valid signal checked by Chipscope

_ valid check[85:81] are 6 valid signals from 6 FiFos.

_ check_ir_valid is variables to accumulate 6 valid signals

_ valid_to_fifo is the new valid signal.

Because 6 valid signal do not appear at the same time so I also thought another method to so also use the one 6-bit variable to accumulate 6 valid signal. When this variable collect enough 6 valid signal from FiFo, it means that 6-bit variable equal 6'h3F, I will have the new valid signal for asynchronous FiFo. Are there any potential risks with this method ?

1

1 Answers

1
votes

I think I know what you are trying to do but the diagrams and the text are some what incomplete and in places confusing.

First:
In you diagram you show synchronous FIFOs with an input clock of 150MHz and an output clock of 120MHz. That is not possible! The clocks on a synchronous FIFO read and write ports must be the same in frequency and phase.

But what I think you are doing is waiting for each FIFO to have a word and then read then all out simultaneous. The crux here is this: are all six FIFOs running of the same 150MHz clock? If so you can make the logic you just described and it should be running from the 150MHz clock. From that you make a single read pulse which takes the data from the Sync FIFO's and writes them to the Asynchronous FIFO.

I have taken your diagram and changed it to what I think you need to implement:

enter image description here

Note that this only works if:
- The 150 MHz clocks are all the same.
- The data rate at the input is not too high. (Valid max 120/150 of the time)


Post edit:
You have not answered if the 150MHz clocks are the same. If not you should use 6 asynchronous FIFOs. In that case the end FIFO can be synchronous running from the 120 MHz clock.
If it is the same clock, the scheme above will be less logic.

"wait for six valids" logic
Whatever you use, the "wait for six valids" logic must be able to accept any or all to arrive at the same time. I have another problem with that part of the logic. You waveform shows a 'valid' for one clock cycle (Probably, I have no idea where the clock is). I have never seen that coming from a FIFO.

If your FIFOs have an 'empty' signal that would be much better as it remains low as long as there is at least one value to read. The logic when you can read then becomes a 6-input 'NOR' gate.


Using the empty signal
Your 'valid' signals seem to be high for one cycle only. That is difficult to work with. Most FIFOs have status signals like 'full' and 'empty'. In your case you check if all the FIFOs have data (All empty signals are 0). Than you read them. In Verilog it looks like:

wire [5:0] empty;
wire       can_read;
....
   asyncfifo fifo1 (
   ....
      .empty( empty[0] ),

   asyncfifo fifo2 (
   ....
      .empty( empty[1] ),

   // The above for each FIFO

   assign can_read = (empty==6'b000000);