EmbDev.net

Forum: FPGA, VHDL & Verilog Verilog buffer implementation problem


von H Karim (Guest)


Rate this post
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:
1
ADC_memA[0] ch0
2
ADC_memA[1] ch0
3
ADC_memA[2] ch0
4
ADC_memA[3] ch0
5
.
6
.
7
ADC_memA[n]   ch1
8
ADC_memA[n+1] ch1
9
ADC_memA[n+2] ch1
10
.
11
ADC_memA[n+10] ch0
12
ADC_memA[n+11] ch0
13
ADC_memA[n+12] ch0
14
.
15
.
16
ADC_memA[511] ch0
17
18
19
Any Explanations? Why does this happen? 
20
21
// Shift register to capture the serial data from DIG_A port on positive edge 
22
always@(negedge CLK) // changed from negedge CLK to posedge CLK 2/27/2015
23
begin
24
25
        data_in_A[11]   <= data_in_A[10];
26
        data_in_A[10]   <= data_in_A[9];
27
        data_in_A[9]    <= data_in_A[8];
28
        data_in_A[8]    <= data_in_A[7];
29
        data_in_A[7]    <= data_in_A[6];
30
        data_in_A[6]    <= data_in_A[5];
31
        data_in_A[5]    <= data_in_A[4];
32
        data_in_A[4]    <= data_in_A[3];
33
        data_in_A[3]    <= data_in_A[2];
34
        data_in_A[2]    <= data_in_A[1];
35
        data_in_A[1]    <= data_in_A[0];
36
        data_in_A[0]    <= DIG_A;
37
38
        data_in_B[11]   <= data_in_B[10];
39
        data_in_B[10]   <= data_in_B[9];
40
        data_in_B[9]    <= data_in_B[8];
41
        data_in_B[8]    <= data_in_B[7];
42
        data_in_B[7]    <= data_in_B[6];
43
        data_in_B[6]    <= data_in_B[5];
44
        data_in_B[5]    <= data_in_B[4];
45
        data_in_B[4]    <= data_in_B[3];
46
        data_in_B[3]    <= data_in_B[2];
47
        data_in_B[2]    <= data_in_B[1];
48
        data_in_B[1]    <= data_in_B[0];
49
        data_in_B[0]    <= DIG_B;
50
51
end
52
53
always@(posedge CLK, negedge RESETn)
54
begin
55
  if ( RESETn == 1'b0) // GET RID OF XFER_RESET
56
  begin
57
    CSn               <= 1'b1; 
58
        clk_cnt                 <= 4'b0;
59
        FSM_read_state          <= ADC_Channel;
60
        ADC_CH                  <= 3'b111; // invalid channel
61
        channel_changed         <= 1'b0;
62
        ch_cng_cnt              <= 0;
63
  end
64
    else
65
    begin
66
        case(FSM_read_state)
67
        ADC_Channel: 
68
        begin
69
            sample_valid    <= 1'b0;
70
            ADC_CH      <= DMA_ADC_CH;
71
            if(ADC_CH == DMA_ADC_CH)
72
                FSM_read_state  <= ADC_Select;
73
            else
74
            begin
75
                channel_changed <= 1'b1;
76
                ch_cng_cnt      <= 0;
77
                FSM_read_state  <= ADC_Wait;
78
            end
79
        end
80
81
        ADC_Wait: 
82
        begin
83
            FSM_read_state  <= ADC_Select;
84
        end
85
86
        ADC_Select: 
87
        begin
88
            CSn        <= 1'b0;
89
            FSM_read_state  <= ADC_ReadBits;
90
        end
91
92
        ADC_ReadBits: 
93
        begin
94
            if(clk_cnt == 4'b1101)
95
            begin
96
                CSn      <= 1'b1;
97
                clk_cnt     <= 4'b0;
98
                // The AD7266 output coding is set to twos complement by selecting 2 × VREF range
99
                sample              <= {~data_in_B[11], data_in_B[10:0], ~data_in_A[11], data_in_A[10:0]};
100
                sample_ch           <= ADC_CH;
101
102
                if(ch_cng_cnt == 32'd2000)
103
                    channel_changed <= 1'b0;
104
                else
105
                    ch_cng_cnt      <= ch_cng_cnt + 1;
106
107
                if(channel_changed == 1'b0)
108
                    sample_valid        <= 1'b1;
109
                
110
                FSM_read_state      <= ADC_Channel;
111
            end
112
            else
113
                clk_cnt     <= clk_cnt + 1;
114
        end
115
        endcase
116
        
117
    end
118
end
119
120
reg last_sample;
121
122
always@(posedge CLK160, negedge RESETn) 
123
begin
124
  if ( RESETn == 1'b0) 
125
  begin
126
        FSM_buffer_state    <= BUFFER_Init;
127
        cntr1               <= 4'b0;
128
        first_ch            <= 3'b0;
129
130
  end
131
    else
132
    begin
133
        case (FSM_buffer_state)
134
135
        BUFFER_Init:
136
        begin
137
            adc_buf_index       <= 0;
138
            ADC_BUFFER_READY    <= 1'b0;
139
            FSM_buffer_state    <= BUFFER_Record;
140
        end    
141
142
        BUFFER_Record:
143
        begin
144
            last_sample     <= sample_valid;
145
            if(sample_valid == 1'b1 && last_sample == 1'b0)
146
            begin
147
                ADC_memA[adc_buf_index]     <= {1'b0, ADC_CH, sample[23:12], cntr1[3:0], sample[11:0]};
148
                FSM_buffer_state    <= BUFFER_Check;
149
            end
150
            else
151
                FSM_buffer_state    <= BUFFER_Record;
152
        end
153
154
        BUFFER_Check:
155
        begin
156
            if(adc_buf_index == 9'b0)
157
            begin
158
                first_ch            <= sample_ch;
159
                adc_buf_index       <= adc_buf_index + 1;
160
                FSM_buffer_state    <= BUFFER_Record;
161
            end
162
            else if(adc_buf_index == 9'd511)
163
            begin
164
                cntr1   <= cntr1 + 1;
165
                if(sample_ch == first_ch)
166
                    FSM_buffer_state    <= BUFFER_Full;
167
                else
168
                    FSM_buffer_state    <= BUFFER_Init;    
169
            end
170
            else
171
            begin
172
                adc_buf_index           <= adc_buf_index + 1;
173
                FSM_buffer_state        <= BUFFER_Record;
174
            end    
175
        end
176
177
        BUFFER_Full:
178
        begin
179
            ADC_BUFFER_READY    <= 1'b1;
180
            if(ADC_READ_ACK == 1'b1 || channel_changed == 1'b1)
181
                FSM_buffer_state    <= BUFFER_Init;
182
            else
183
                FSM_buffer_state    <= BUFFER_Full;
184
            
185
        end
186
187
        endcase
188
    end
189
end

: Edited by Moderator
von Lothar M. (Company: Titel) (lkmiller) (Moderator)


Rate this post
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...
1
Reply
2
Rules — please read before posting
3
    Post long source code as attachment, not in the text
4
    Posting advertisements is forbidden.
5
6
Formatting options
7
    ...
8
    [code]code in other languages, ASCII drawings[/code]

: Edited by Moderator
Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.