EmbDev.net

Forum: FPGA, VHDL & Verilog Verilog buffer implementation problem


Author: H Karim (Guest)
Posted on:

Rate this post
0 useful
not useful
Hey everyone,

I am writing a Verilog code to get 512 samples from an analog to digital 
converter IC (AD7266) and then stores them in a buffer. the ADC has got 
5 channels and the ADC_CH determines which channel should be sampled. 
when the buffer is filled this block of code asserts ADC_BUFFER_READY 
and waits for ADC_READ_ACK. If channel is changed then the buffer should 
be filled again.

The current issue is that when the channel is changed and filled again, 
some of the data in the buffer are still related to the old channel. I 
suspect there is something wrong with writing data to the buffer. i mean 
sometimes the new data is not written and the buffer keeps the old 
value.

for example:
ADC_memA[0] ch0
ADC_memA[1] ch0
ADC_memA[2] ch0
ADC_memA[3] ch0
.
.
ADC_memA[n]   ch1
ADC_memA[n+1] ch1
ADC_memA[n+2] ch1
.
ADC_memA[n+10] ch0
ADC_memA[n+11] ch0
ADC_memA[n+12] ch0
.
.
ADC_memA[511] ch0


Any Explanations? Why does this happen? 

// Shift register to capture the serial data from DIG_A port on positive edge 
always@(negedge CLK) // changed from negedge CLK to posedge CLK 2/27/2015
begin

        data_in_A[11]   <= data_in_A[10];
        data_in_A[10]   <= data_in_A[9];
        data_in_A[9]    <= data_in_A[8];
        data_in_A[8]    <= data_in_A[7];
        data_in_A[7]    <= data_in_A[6];
        data_in_A[6]    <= data_in_A[5];
        data_in_A[5]    <= data_in_A[4];
        data_in_A[4]    <= data_in_A[3];
        data_in_A[3]    <= data_in_A[2];
        data_in_A[2]    <= data_in_A[1];
        data_in_A[1]    <= data_in_A[0];
        data_in_A[0]    <= DIG_A;

        data_in_B[11]   <= data_in_B[10];
        data_in_B[10]   <= data_in_B[9];
        data_in_B[9]    <= data_in_B[8];
        data_in_B[8]    <= data_in_B[7];
        data_in_B[7]    <= data_in_B[6];
        data_in_B[6]    <= data_in_B[5];
        data_in_B[5]    <= data_in_B[4];
        data_in_B[4]    <= data_in_B[3];
        data_in_B[3]    <= data_in_B[2];
        data_in_B[2]    <= data_in_B[1];
        data_in_B[1]    <= data_in_B[0];
        data_in_B[0]    <= DIG_B;

end

always@(posedge CLK, negedge RESETn)
begin
  if ( RESETn == 1'b0) // GET RID OF XFER_RESET
  begin
    CSn               <= 1'b1; 
        clk_cnt                 <= 4'b0;
        FSM_read_state          <= ADC_Channel;
        ADC_CH                  <= 3'b111; // invalid channel
        channel_changed         <= 1'b0;
        ch_cng_cnt              <= 0;
  end
    else
    begin
        case(FSM_read_state)
        ADC_Channel: 
        begin
            sample_valid    <= 1'b0;
            ADC_CH      <= DMA_ADC_CH;
            if(ADC_CH == DMA_ADC_CH)
                FSM_read_state  <= ADC_Select;
            else
            begin
                channel_changed <= 1'b1;
                ch_cng_cnt      <= 0;
                FSM_read_state  <= ADC_Wait;
            end
        end

        ADC_Wait: 
        begin
            FSM_read_state  <= ADC_Select;
        end

        ADC_Select: 
        begin
            CSn        <= 1'b0;
            FSM_read_state  <= ADC_ReadBits;
        end

        ADC_ReadBits: 
        begin
            if(clk_cnt == 4'b1101)
            begin
                CSn      <= 1'b1;
                clk_cnt     <= 4'b0;
                // The AD7266 output coding is set to twos complement by selecting 2 × VREF range
                sample              <= {~data_in_B[11], data_in_B[10:0], ~data_in_A[11], data_in_A[10:0]};
                sample_ch           <= ADC_CH;

                if(ch_cng_cnt == 32'd2000)
                    channel_changed <= 1'b0;
                else
                    ch_cng_cnt      <= ch_cng_cnt + 1;

                if(channel_changed == 1'b0)
                    sample_valid        <= 1'b1;
                
                FSM_read_state      <= ADC_Channel;
            end
            else
                clk_cnt     <= clk_cnt + 1;
        end
        endcase
        
    end
end

reg last_sample;

always@(posedge CLK160, negedge RESETn) 
begin
  if ( RESETn == 1'b0) 
  begin
        FSM_buffer_state    <= BUFFER_Init;
        cntr1               <= 4'b0;
        first_ch            <= 3'b0;

  end
    else
    begin
        case (FSM_buffer_state)

        BUFFER_Init:
        begin
            adc_buf_index       <= 0;
            ADC_BUFFER_READY    <= 1'b0;
            FSM_buffer_state    <= BUFFER_Record;
        end    

        BUFFER_Record:
        begin
            last_sample     <= sample_valid;
            if(sample_valid == 1'b1 && last_sample == 1'b0)
            begin
                ADC_memA[adc_buf_index]     <= {1'b0, ADC_CH, sample[23:12], cntr1[3:0], sample[11:0]};
                FSM_buffer_state    <= BUFFER_Check;
            end
            else
                FSM_buffer_state    <= BUFFER_Record;
        end

        BUFFER_Check:
        begin
            if(adc_buf_index == 9'b0)
            begin
                first_ch            <= sample_ch;
                adc_buf_index       <= adc_buf_index + 1;
                FSM_buffer_state    <= BUFFER_Record;
            end
            else if(adc_buf_index == 9'd511)
            begin
                cntr1   <= cntr1 + 1;
                if(sample_ch == first_ch)
                    FSM_buffer_state    <= BUFFER_Full;
                else
                    FSM_buffer_state    <= BUFFER_Init;    
            end
            else
            begin
                adc_buf_index           <= adc_buf_index + 1;
                FSM_buffer_state        <= BUFFER_Record;
            end    
        end

        BUFFER_Full:
        begin
            ADC_BUFFER_READY    <= 1'b1;
            if(ADC_READ_ACK == 1'b1 || channel_changed == 1'b1)
                FSM_buffer_state    <= BUFFER_Init;
            else
                FSM_buffer_state    <= BUFFER_Full;
            
        end

        endcase
    end
end

: Edited by Moderator
Author: Lothar Miller (lkmiller) (Moderator)
Posted on:

Rate this post
0 useful
not useful
H Karim wrote:
> for example:
Pls surround your Verilog code with the formatting tags (as described in 
the "manual" just above the edit-box). Or you attach simply a *.v 
Verilog file...
Reply
Rules — please read before posting
    Post long source code as attachment, not in the text
    Posting advertisements is forbidden.

Formatting options
    ...
    [code]code in other languages, ASCII drawings[/code]

: Edited by Moderator

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.