ADS9224R这款芯片是德州仪器(TI)的一款SAR ADC,笔者写这芯片IP核大概有段时间了,这款ADC采集芯片挺复杂的。笔者当时对写axi4_lite的IP核还不是很熟悉,就接下了含有这款芯片的项目,当时看了手册觉得亚历山大。因为当时项目允许开发一款IP的时间就2周左右,不过笔者还是顶住了压力把芯片驱动的IP核写了出来。现在想想大概是有过了一些挑战之后,后面写IP核变得更加顺畅。
这款芯片的datasheet可自行查找,最大采样频率是3MSPS,16bit。说真的当时笔者想着的是尽量把该芯片的IP核写的通用些,看了手册才发现过于乐观,这款芯片的采样模式实在是太多了,笔者真有被吓到。由于开发时间很短,数据手册都是英文阅读需要不少时间,后面就只能尽可能把代码些通用些了,这次之后笔者获益匪浅。
这款芯片的大体框架如下:
根据当时项目的设计及调试结果,笔者设计的IP核是为了更多的适应项目需求,所以会对代码的接收SDI引脚加些延时。硬件上的限制,当时是设计最大采样率为1.5MSPS。笔者用的采样模式为下图模式:
笔者看到这时序图有点疑惑不知道是不是手册有问题,上图中的ADC采样过程中READY/STROBE为高电平,而下面对于采样时序的时序图分析中居然是拉低的,这让笔者很是疑惑,后面就根据实际情况来分析的,实际调试过程中这个信号应该是低的。
笔者根据手册共设计了SPI-00-S-SDR,SPI-10-S-SDR,SPI-01-S-SDR,SPI-11-S-SDR;SPI-00-D-SDR,SPI-10-D-SDR,SPI-01-D-SDR,SPI-11-D-SDR;SPI-00-Q-SDR,SPI-10-Q-SDR,SPI-01-Q-SDR,SPI-11-Q-SDR这12种模式,还有DDR等其他模式笔者没有设计。不过这么多模式笔者碍于时间紧迫,并没有一一调试,可能会多少存在些问题,笔者就把SPI-00-S-SDR,SPI-00-D-SDR,SPI-00-Q-SDR这三种最常用的模式调试了。
ADS9224R_IF.v:
1 //**************************************************************************
2 // *** file name : ADS9224R_IF.v
3 // *** version : 1.0
4 // *** Description : ADS9224R interface driver
5 // *** Blogs : https://www.cnblogs.com/WenGalois123/
6 // *** Author : Galois_V
7 // *** Date : 2020.04.21
8 // *** Changes : Initial
9 //**************************************************************************
10 `timescale 1ns/1ps
11 module ADS9224R_IF
12 #(
13 parameter SDI_WIDTH =4
14 )
15 (
16 input i_sys_clk ,
17 input i_sys_reset ,
18 input i_spi_enable ,
19 input [31:0] i_spi_sclk_ctrl ,
20 input [31:0] i_spi_sample_time ,
21 input [23:0] i_fre_sample ,
22
23 input i_spi_tx_valid ,
24 input [23:0] i_spi_tx_data ,
25 output reg o_spi_tx_ready ,
26 output [31:0] o_spi_rx_data ,
27 output o_spi_rx_single_valid ,
28 output o_spi_rx_valid ,
29 output o_time_sample_en ,
30 output o_spi_bus_busy ,
31 output o_spi_ready ,
32
33 input [1:0] i_spi_type ,
34 output o_spi_cnv ,
35 input i_spi_ready ,
36 output o_spi_cs ,
37 output reg o_spi_sclk ,
38 output o_spi_sdout ,
39 input [SDI_WIDTH-1:0] i_spi_sdina ,
40 input [SDI_WIDTH-1:0] i_spi_sdinb
41
42 );
43
44 parameter T_DRDY = 2;
45 localparam DEJITTER_LEVEL = 2;
46 localparam SPI_IDLE = 0,
47 SPI_START = 1,
48 SPI_READY = 2,
49 SPI_WAIT_READY = 3,
50 SPI_SCLKNEG = 4,
51 SPI_DEAL = 5,
52 SPI_CNVEND = 6;
53 parameter CH_DEJITTER = DEJITTER_LEVEL*SDI_WIDTH;
54 parameter BIT_SHIFT = SDI_WIDTH>>1;
55
56 reg [CH_DEJITTER-1:0] r_spi_sdina_s ;
57 reg [SDI_WIDTH-1:0] r_spi_sdina_temp ;
58 reg [CH_DEJITTER-1:0] r_spi_sdinb_s ;
59 reg [SDI_WIDTH-1:0] r_spi_sdinb_temp ;
60 reg r_spi_ready_s ;
61 wire w_spi_sclk_neg ;
62 wire w_spi_sclk_pos ;
63 reg [31:0] r_spi_sclk_ctrl_temp ;
64 reg [31:0] r_spi_sclk_cnt ;
65 reg r_spi_sclk_temp ;
66 reg [8:0] r_spi_state ;
67 reg [8:0] r_spi_state_next ;
68 wire w_spi_wait_over ;
69 wire w_spi_reset ;
70 reg [5:0] r_spi_bit_cnt ;
71 reg [23:0] r_tx_data_temp ;
72 reg [15:0] r_rx_data_tempa ;
73 reg [15:0] r_rx_data_tempb ;
74 reg [31:0] r_spi_sample_cnt ;
75 wire w_rx_data_en ;
76 wire w_rx_data_over ;
77 reg [DEJITTER_LEVEL-1+13:0] r_rx_data_en_s ;
78 reg [DEJITTER_LEVEL-1+13:0] r_rx_data_over_s ;
79 wire w_spi_clk_temp_00 ;
80 wire w_spi_clk_temp_01 ;
81 wire w_spi_clk_temp_10 ;
82 wire w_spi_clk_temp_11 ;
83 reg [15:0] r_run_time_cnt ;
84 reg [31:0] r_cnv_cnt ;
85 wire w_time_clr ;
86 wire w_wait_ready_cnt_over ;
87 wire [15:0] w_rx_data_tempa ;
88 wire [15:0] w_rx_data_tempb ;
89 reg r_sample_end ;
90 reg r_spi_bus_busy ;
91
92 /******************************************************************************\
93 输入i_spi_ready
94 \******************************************************************************/
95 always @ (posedge i_sys_clk)
96 begin
97 if(~i_sys_reset)
98 begin
99 r_spi_ready_s <= 1'b0;
100 end
101 else
102 begin
103 r_spi_ready_s <= i_spi_ready;
104 end
105 end
106 assign o_spi_ready = r_spi_ready_s ;
107 assign w_spi_ready_pos = ~r_spi_ready_s & i_spi_ready;
108
109 /******************************************************************************\
110 SPI时钟控制
111 \******************************************************************************/
112 always @ (posedge i_sys_clk)
113 begin
114 if(~i_sys_reset)
115 begin
116 r_spi_sclk_ctrl_temp <= 32'd0;
117 end
118 else
119 begin
120 r_spi_sclk_ctrl_temp <= i_spi_sclk_ctrl;
121 end
122 end
123
124 always @ (posedge i_sys_clk)
125 begin
126 if(~w_spi_reset)
127 begin
128 r_spi_sclk_cnt <= 32'd0;
129 end
130 else
131 begin
132 if(r_spi_state[SPI_CNVEND])
133 begin
134 r_spi_sclk_cnt <= 32'd0;
135 end
136 else
137 begin
138 r_spi_sclk_cnt <= r_spi_sclk_cnt + r_spi_sclk_ctrl_temp;
139 end
140 end
141 end
142
143 always @ (posedge i_sys_clk)
144 begin
145 if(~w_spi_reset)
146 begin
147 r_spi_sclk_temp <= 1'd0;
148 end
149 else
150 begin
151 r_spi_sclk_temp <= r_spi_sclk_cnt[31];
152 end
153 end
154
155 assign w_spi_sclk_neg = r_spi_sclk_temp & ~r_spi_sclk_cnt[31];
156 assign w_spi_sclk_pos = ~r_spi_sclk_temp & r_spi_sclk_cnt[31];
157
158 /******************************************************************************\
159 时间计数
160 \******************************************************************************/
161 always @(posedge i_sys_clk)
162 begin
163 if(~w_spi_reset | w_time_clr |r_spi_state[SPI_IDLE])
164 begin
165 r_run_time_cnt <= 16'd0;
166 end
167 else if(r_spi_state[SPI_READY])
168 begin
169 r_run_time_cnt <= r_run_time_cnt + 1'b1;
170 end
171 else
172 begin
173 r_run_time_cnt <= 16'd0;
174 end
175 end
176
177 assign w_wait_ready_cnt_over = r_spi_state[SPI_READY]&(r_run_time_cnt == T_DRDY);
178
179 assign w_time_clr = w_wait_ready_cnt_over;
180 /******************************************************************************\
181 SPI状态控制
182 \******************************************************************************/
183 assign w_spi_reset = i_spi_enable & i_sys_reset;
184
185 always @ (posedge i_sys_clk)
186 begin
187 if(~w_spi_reset)
188 begin
189 r_spi_state <= 'd0;
190 r_spi_state[SPI_IDLE] <= 1'b1;
191 end
192 else
193 begin
194 r_spi_state <= r_spi_state_next;
195 end
196 end
197
198 always @ (*)
199 begin
200 r_spi_state_next = 'd0;
201 case(1'b1)
202 r_spi_state[SPI_IDLE] : begin
203 if(i_spi_tx_valid & w_spi_sclk_neg )
204 begin
205 r_spi_state_next[SPI_START] = 1'b1;
206 end
207 else
208 begin
209 r_spi_state_next[SPI_IDLE] = 1'b1;
210 end
211 end
212
213 r_spi_state[SPI_START] : begin
214 if(~r_tx_data_temp[16])
215 begin
216 r_spi_state_next[SPI_SCLKNEG] = 1'b1;
217 end
218 else if(~i_spi_ready)//刚上电时i_spi_ready为高,0.9ms之后为低
219 begin
220 r_spi_state_next[SPI_READY] = 1'b1;
221 end
222 else
223 begin
224 r_spi_state_next[SPI_START] = 1'b1;
225 end
226 end
227 r_spi_state[SPI_READY] : begin
228 if(w_wait_ready_cnt_over)
229 begin
230 r_spi_state_next[SPI_WAIT_READY] = 1'b1;
231 end
232 else
233 begin
234 r_spi_state_next[SPI_READY] = 1'b1;
235 end
236 end
237 r_spi_state[SPI_WAIT_READY] :begin
238 if(w_spi_ready_pos)
239 begin
240 r_spi_state_next[SPI_SCLKNEG] = 1'b1;
241 end
242 else
243 begin
244 r_spi_state_next[SPI_WAIT_READY] = 1'b1;
245 end
246 end
247 r_spi_state[SPI_SCLKNEG]: begin
248 if(w_spi_sclk_neg)
249 r_spi_state_next[SPI_DEAL] = 1'b1;
250 else
251 r_spi_state_next[SPI_SCLKNEG] = 1'b1;
252 end
253 r_spi_state[SPI_DEAL] : begin
254 if(w_spi_sclk_neg & (r_spi_bit_cnt == 6'd15) & (~r_tx_data_temp[17]))
255 begin
256 r_spi_state_next[SPI_CNVEND] = 1'b1;
257 end
258 else if(w_spi_sclk_neg & (r_spi_bit_cnt == 6'd15>>BIT_SHIFT) & r_tx_data_temp[17])
259 begin
260 r_spi_state_next[SPI_CNVEND] = 1'b1;
261 end
262 else
263 begin
264 r_spi_state_next[SPI_DEAL] = 1'b1;
265 end
266 end
267 r_spi_state[SPI_CNVEND] : begin
268 if(~r_tx_data_temp[16])
269 begin
270 r_spi_state_next[SPI_IDLE] = 1'b1;
271 end
272 else if(r_cnv_cnt==i_fre_sample)
273 begin
274 if(r_tx_data_temp[19] & (~r_sample_end))
275 begin
276 r_spi_state_next[SPI_READY] = 1'b1;
277 end
278 else
279 begin
280 r_spi_state_next[SPI_IDLE] = 1'b1;
281 end
282 end
283 else
284 begin
285 r_spi_state_next[SPI_CNVEND] = 1'b1;
286 end
287 end
288 default : begin
289 r_spi_state_next[SPI_IDLE] = 1'b1;
290 end
291 endcase
292 end
293 /******************************************************************************\
294 获取数据
295 \******************************************************************************/
296 always @ (*)
297 begin
298 case(1'b1)
299 r_spi_state[SPI_IDLE] : begin
300 if(i_spi_tx_valid & w_spi_sclk_neg )
301 begin
302 o_spi_tx_ready = 1'b1;
303 end
304 else
305 begin
306 o_spi_tx_ready = 1'b0;
307 end
308 end
309 default : begin
310 o_spi_tx_ready = 1'b0;
311 end
312 endcase
313 end
314 /******************************************************************************\
315 bit计数
316 \******************************************************************************/
317 always @ (posedge i_sys_clk)
318 begin
319 if(~w_spi_reset | ~r_spi_state[SPI_DEAL])
320 begin
321 r_spi_bit_cnt <= 6'd0;
322 end
323 else if(w_spi_sclk_neg)
324 begin
325 if(r_spi_bit_cnt == 6'd15 && (~r_tx_data_temp[17]))
326 begin
327 r_spi_bit_cnt <= 6'd0;
328 end
329 else if(r_spi_bit_cnt == 6'd15>>BIT_SHIFT && r_tx_data_temp[17])
330 begin
331 r_spi_bit_cnt <= 6'd0;
332 end
333 else
334 begin
335 r_spi_bit_cnt <= r_spi_bit_cnt + 6'd1;
336 end
337 end
338 end
339 /******************************************************************************\
340 发送数据
341 \******************************************************************************/
342 always @ (posedge i_sys_clk)
343 begin
344 if(~w_spi_reset)
345 begin
346 r_tx_data_temp <= 24'd0;
347 end
348 else if(o_spi_tx_ready & i_spi_tx_valid)
349 begin
350 r_tx_data_temp <= i_spi_tx_data;
351 end
352 else if(w_spi_sclk_neg & r_spi_state[SPI_DEAL] & r_tx_data_temp[18])
353 begin
354 r_tx_data_temp[15:0] <= {r_tx_data_temp[14:0],1'b0};
355 end
356 end
357
358 assign o_spi_sdout = r_tx_data_temp[15];
359 assign o_time_sample_en = r_tx_data_temp[19];
360
361 /******************************************************************************\
362 输入去抖动
363 \******************************************************************************/
364 genvar ch_i;
365 generate
366 for(ch_i=0;ch_i
428 {r_rx_data_tempb[(16>>BIT_SHIFT)*(ch_i+1)-1:(16>>BIT_SHIFT)*ch_i]} <= {(16>>BIT_SHIFT){1'b0}};
429 end
430 else if(r_rx_data_en_s[DEJITTER_LEVEL-1+13])
431 begin
432 {r_rx_data_tempa[(16>>BIT_SHIFT)*(ch_i+1)-1:(16>>BIT_SHIFT)*ch_i]} <= {r_rx_data_tempa[(16>>BIT_SHIFT)*(ch_i+1)-2:(16>>BIT_SHIFT)*ch_i],r_spi_sdina_temp[ch_i]};
433 {r_rx_data_tempb[(16>>BIT_SHIFT)*(ch_i+1)-1:(16>>BIT_SHIFT)*ch_i]} <= {r_rx_data_tempb[(16>>BIT_SHIFT)*(ch_i+1)-2:(16>>BIT_SHIFT)*ch_i],r_spi_sdinb_temp[ch_i]};
434 end
435 end
436
437 end
438 endgenerate
439 /******************************************************************************\
440 接收数据
441 \******************************************************************************/
442 assign w_rx_data_en = w_spi_sclk_pos & r_spi_state[SPI_DEAL] & r_tx_data_temp[17];
443 assign w_rx_data_over = w_spi_sclk_neg & (r_spi_bit_cnt == 6'd15>>BIT_SHIFT) & r_spi_state[SPI_DEAL] & r_tx_data_temp[17];//17位是读操作
444
445 always @ (posedge i_sys_clk)
446 begin
447 if(~i_sys_reset)
448 begin
449 r_rx_data_en_s <= {(DEJITTER_LEVEL+13){1'b0}};
450 r_rx_data_over_s <= {(DEJITTER_LEVEL+13){1'b0}};
451 end
452 else
453 begin
454 r_rx_data_en_s <= {r_rx_data_en_s[DEJITTER_LEVEL-2+13:0],w_rx_data_en};
455 r_rx_data_over_s <= {r_rx_data_over_s[DEJITTER_LEVEL-2+13:0],w_rx_data_over};
456 end
457 end
458
459 generate
460 if(SDI_WIDTH==1)
461 begin:One_SDI
462 assign w_rx_data_tempa = r_rx_data_tempa;
463 assign w_rx_data_tempb = r_rx_data_tempb;
464 end
465 if(SDI_WIDTH==2)
466 begin:Dual_SDI
467 assign w_rx_data_tempa[3:0] = {r_rx_data_tempa[9],r_rx_data_tempa[1],r_rx_data_tempa[8],r_rx_data_tempa[0]};
468 assign w_rx_data_tempa[7:4] = {r_rx_data_tempa[11],r_rx_data_tempa[3],r_rx_data_tempa[10],r_rx_data_tempa[2]};
469 assign w_rx_data_tempa[11:8] = {r_rx_data_tempa[13],r_rx_data_tempa[5],r_rx_data_tempa[12],r_rx_data_tempa[4]};
470 assign w_rx_data_tempa[15:12] = {r_rx_data_tempa[15],r_rx_data_tempa[7],r_rx_data_tempa[14],r_rx_data_tempa[6]};
471 assign w_rx_data_tempb[3:0] = {r_rx_data_tempb[9],r_rx_data_tempb[1],r_rx_data_tempb[8],r_rx_data_tempb[0]};
472 assign w_rx_data_tempb[7:4] = {r_rx_data_tempb[11],r_rx_data_tempb[3],r_rx_data_tempb[10],r_rx_data_tempb[2]};
473 assign w_rx_data_tempb[11:8] = {r_rx_data_tempb[13],r_rx_data_tempb[5],r_rx_data_tempb[12],r_rx_data_tempb[4]};
474 assign w_rx_data_tempb[15:12] = {r_rx_data_tempb[15],r_rx_data_tempb[7],r_rx_data_tempb[14],r_rx_data_tempb[6]};
475 end
476 else
477 begin
478 assign w_rx_data_tempa[3:0] = {r_rx_data_tempa[12],r_rx_data_tempa[8],r_rx_data_tempa[4],r_rx_data_tempa[0]};
479 assign w_rx_data_tempa[7:4] = {r_rx_data_tempa[13],r_rx_data_tempa[9],r_rx_data_tempa[5],r_rx_data_tempa[1]};
480 assign w_rx_data_tempa[11:8] = {r_rx_data_tempa[14],r_rx_data_tempa[10],r_rx_data_tempa[6],r_rx_data_tempa[2]};
481 assign w_rx_data_tempa[15:12] = {r_rx_data_tempa[15],r_rx_data_tempa[11],r_rx_data_tempa[7],r_rx_data_tempa[3]};
482 assign w_rx_data_tempb[3:0] = {r_rx_data_tempb[12],r_rx_data_tempb[8],r_rx_data_tempb[4],r_rx_data_tempb[0]};
483 assign w_rx_data_tempb[7:4] = {r_rx_data_tempb[13],r_rx_data_tempb[9],r_rx_data_tempb[5],r_rx_data_tempb[1]};
484 assign w_rx_data_tempb[11:8] = {r_rx_data_tempb[14],r_rx_data_tempb[10],r_rx_data_tempb[6],r_rx_data_tempb[2]};
485 assign w_rx_data_tempb[15:12] = {r_rx_data_tempb[15],r_rx_data_tempb[11],r_rx_data_tempb[7],r_rx_data_tempb[3]};
486 end
487 endgenerate
488
489 assign o_spi_rx_data = {w_rx_data_tempa,w_rx_data_tempb};
490 assign o_spi_rx_single_valid = r_tx_data_temp[19] ? 1'b0 : r_rx_data_over_s[DEJITTER_LEVEL-1+13];
491 assign o_spi_rx_valid = r_rx_data_over_s[DEJITTER_LEVEL-1+13];
492 /******************************************************************************\
493 等待时间
494 \******************************************************************************/
495 always @ (posedge i_sys_clk)
496 begin
497 if(~w_spi_reset | (~r_tx_data_temp[19]))
498 begin
499 r_spi_sample_cnt <= 32'd1;
500 end
501 else
502 begin
503 r_spi_sample_cnt <= r_spi_sample_cnt + 32'd1;
504 end
505 end
506
507 always @ (posedge i_sys_clk)
508 begin
509 if(~w_spi_reset | (~r_tx_data_temp[19]))
510 begin
511 r_sample_end <= 1'b0;
512 end
513 else if(w_spi_wait_over)
514 begin
515 r_sample_end <= 1'b1;
516 end
517 end
518 assign w_spi_wait_over = (i_spi_sample_time == r_spi_sample_cnt);
519
520 /******************************************************************************\
521 CONVST
522 \******************************************************************************/
523
524 always@(posedge i_sys_clk)
525 begin
526 if(~w_spi_reset | r_spi_state[SPI_IDLE])
527 begin
528 r_cnv_cnt <= 32'd1;
529 end
530 else if(r_cnv_cnt==i_fre_sample)
531 begin
532 r_cnv_cnt <= 32'd1;
533 end
534 else
535 begin
536 r_cnv_cnt <=r_cnv_cnt + 32'd1;
537 end
538 end
539
540 reg r_spi_cnv;
541 always@(posedge i_sys_clk)
542 begin
543 if(~w_spi_reset | r_spi_state[SPI_IDLE])
544 begin
545 r_spi_cnv <= 1'b0;
546 end
547 else if(r_tx_data_temp[16])
548 begin
549 if(r_cnv_cnt <= (i_fre_sample>>1))
550 begin
551 r_spi_cnv <= 1'b1;
552 end
553 else
554 begin
555 r_spi_cnv <= 1'b0;
556 end
557 end
558 else
559 begin
560 r_spi_cnv <= 1'b0;
561 end
562 end
563
564 assign o_spi_cnv = r_spi_cnv;
565 /******************************************************************************\
566 CS
567 \******************************************************************************/
568 assign o_spi_cs = ~r_spi_state[SPI_DEAL] ;
569 /******************************************************************************\
570 CLK
571 \******************************************************************************/
572 assign w_spi_clk_temp_10 = o_spi_cs ? 1'b1 : ( r_spi_sclk_temp);
573 assign w_spi_clk_temp_00 = o_spi_cs ? 1'b0 : ( r_spi_sclk_temp);
574 assign w_spi_clk_temp_11 = o_spi_cs ? 1'b1 : ~( r_spi_sclk_temp);
575 assign w_spi_clk_temp_01 = o_spi_cs ? 1'b0 : ~( r_spi_sclk_temp);
576
577 always @ (*)
578 begin
579 case(i_spi_type)
580 2'b00 : o_spi_sclk = w_spi_clk_temp_00;
581 2'b01 : o_spi_sclk = w_spi_clk_temp_01;
582 2'b10 : o_spi_sclk = w_spi_clk_temp_10;
583 2'b11 : o_spi_sclk = w_spi_clk_temp_11;
584 endcase
585 end
586 /******************************************************************************\
587 SPI BUS status
588 \******************************************************************************/
589
590 always @ (posedge i_sys_clk)
591 begin
592 if(~w_spi_reset)
593 begin
594 r_spi_bus_busy <= 1'b0;
595 end
596 else if(r_tx_data_temp[19])
597 begin
598 if(r_spi_state[SPI_IDLE] && r_sample_end)
599 r_spi_bus_busy <= 1'b0;
600 else
601 r_spi_bus_busy <= 1'b1;
602 end
603 else
604 begin
605 if(r_spi_state[SPI_IDLE]&&(~i_spi_tx_valid))
606 r_spi_bus_busy <= 1'b0;
607 else
608 r_spi_bus_busy <= 1'b1;
609 end
610 end
611
612 assign o_spi_bus_busy = r_spi_bus_busy;
613 endmodule
以上便是芯片ADS9224R的驱动代码块,其他模块这里就不贴出了,可以结合datasheet的时序来阅读代码。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章