This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Weird Verilog code of adc12d1000rfrb

Other Parts Discussed in Thread: ADC12D1000, WAVEVISION5

I am trying to modify the Verilog came with adc12d1000rfrb to do some own test. But running into a weird part of the code in file adc12d1000_rfrb.v, To my mind the FIFO would not work as the rd_clk(hdclk_i) is half the frequency of wr_clk(dclk_i) and the FIFO only got depth of 16. Could someone help me to understand how this works?

Thank you,

fifo_48x16 di_syncfifo (
.rst(rst),
.wr_clk(dclk_i),
.rd_clk(hdclk_i),
.din(di2_reg),
.wr_en(1'b1),
.rd_en(1'b1),
.dout(di_sync),
.full(),
.empty());

  • Hi xundong

    I understand that this bit of code is confusing. What actually happens is that once the FIFO is filled after the first 16 writes, every second write (at dclk_i rate) will be inhibited because the FIFO is still full (since it is being read at hdclk_i rate). The code above works equivalent to the following modified version which includes the explicit write enabling as a function of the variable "demux_wen". This variable is used in the demuxing code earlier in the file which determines the values loaded into the FIFO.

    fifo_48x16 di_syncfifo (
    .rst(rst),
    .wr_clk(dclk_i),
    .rd_clk(hdclk_i),
    .din(di2_reg),
    .wr_en(demux_wen),
    .rd_en(1'b1),
    .dout(di_sync),
    .full(),
    .empty());

    So the Write and Read rates are effectively the same once the FIFO is loaded. I reviewed the code with our FPGA expert and while he did not create the original code, he believes it was probably implemented that way to eliminate the extra gate delays associated with using demux_wen to gate the FIFO write and ensure timing closure at the high clock rates required.

    This method requires that the first set of data values loaded into the storage FIFOs are discarded to avoid using the duplicated data stored during the startup of the "fifo_48x16". I believe this is taken care of in the WaveVision5 script for these boards.

    I hope this is helpful. Please let me know if you have additional questions.

    Best regards,

    Jim B

  • Thanks for the answer Jim

  • Hi Jim,  another question following this. If every second write write will be inhibited, does that mean we actually only get half of the sample data in Wavevision when we using this board. I notice the same code is also used in another prototype board.

  • Hi Xundong

    I am copying in some additional code from earlier in the design that should help.

    // time demuxing of the data bus into sample n and sample n+1
       // (di "n" and "n+1" and did "n" and "n+1" for example)
       // When demux_wen is 1, this takes 2 samples of 24 bit data at a time from previous steps and puts into 48 bit FIFO  

       always @(posedge fpga_reset or posedge dclk_i)
         if (fpga_reset)
           begin
       demux_wen <= 1'b0;
      
       di1_reg   <= 48'h0;
       di2_reg   <= 48'h0;

       did1_reg  <= 48'h0;
       did2_reg  <= 48'h0;
      
       dq1_reg   <= 48'h0;
       dq2_reg   <= 48'h0;

       dqd1_reg  <= 48'h0;
       dqd2_reg  <= 48'h0;
           end
         else
           begin

     if(demux_wen)
         begin
            demux_wen <= 1'b0;
           
            di1_reg   <= {di_f,di_r,di_reg};
            di2_reg   <= di1_reg;

            did1_reg  <= {did_f,did_r,did_reg}; 
            did2_reg  <= did1_reg;

            dq1_reg   <= {dq_f,dq_r,dq_reg};
            dq2_reg   <= dq1_reg;

            dqd1_reg  <= {dqd_f,dqd_r,dqd_reg};
            dqd2_reg  <= dqd1_reg;
         end
       else
         begin
            demux_wen <= 1'b1;
           
            di1_reg   <= di1_reg;
            di2_reg   <= di2_reg;
           
            did1_reg  <= did1_reg;
            did2_reg  <= did2_reg;

            dq1_reg   <= dq1_reg;
            dq2_reg   <= dq2_reg;

            dqd1_reg  <= dqd1_reg;
            dqd2_reg  <= dqd2_reg;
         end   
           end

    The function of this code is to only update the di1_reg, di2_reg, did1_reg, did2_reg, dq1_reg, dq2_reg, dqd1_reg, dqd2_reg registers when demux_wen=1. When demux_wen=0 the registers just hold the previous value. This effectively slows down the data by a factor of 2 before it gets written to the following FIFO on every second wr_clk. So all of the data is still being loaded into the fifo_48x16. No ADC samples are lost.

    Let me know if this is not clear.

    Best regards,

    Jim B