芯片ADS9224R的FPGA驱动实现
阅读原文时间:2023年07月08日阅读:1

  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>BIT_SHIFT)*(ch_i+1)-1:(16>>BIT_SHIFT)*ch_i]} <= {(16>>BIT_SHIFT){1'b0}};
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的时序来阅读代码。

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章