当前位置:   article > 正文

纯逻辑控制AD936x/AD9361配置寄存器/AD9361纯硬件设计/AD9361配置流程/zynq配置ad9361/AD9361手把手教程/AD936x教程/——纯Verilog配置AD9361_ad9361 interface

ad9361 interface

因最近公司需要,借此机会和大家一起学习AD9361

制作不易,记得三连哦,给我动力,持续更新!

工程文件下载:纯硬件SPI配置AD9361   提取码:g9jy 

----------------------------------------------------------------------------------------

因为ADI官方,只提供了利用软件(SDK)和硬件平台(vivado)去配置AD936x,但是在一些工程中,这种方法很难去应用到实际的项目中,所以给大家介绍一个纯硬件配置AD936x的一个详细教程。因为是手把手教程,所以有些大佬不要嫌麻烦。同时后期会更新工程上的项目设计。废话不多说了,直接进入主题!和我一起学习神秘而又神奇AD936x吧!少年!

我用的是zedboard+ad9361,和我的硬件一样的伙伴,可以完全按照我的步骤进行,FPGA芯片为zynq7020的应该也可以。其余的根据自身芯片要求略微修改即可

根据前两章的讲解,相信大家已经完成了AD936x的脚本准备工作,这节将给大家讲解如果通过SPI把上一节生成的脚本文件,配置到AD9361上。

一、新建一个vivado工程

新建vivado硬件工程,然后分别把图中这几个文件代码导入工程中,

二、AD9361配置脚本文件

此文件就是上一节,通过AD936X Evaluation Software软件配置好的,脚本文件转化成Verilog的脚本文件,里面包含了所有的ad9361的寄存器配置信息。

 三、ad9361接口文件

ad9361接口文件,此模块设计了采用LVDS传输模式的接口,接口设计清晰,可以嫁接到任何ad9361和其他FPGA开发板的接口连接,并且接口均为ad9361的接口,并没有其余无用的端口,移植起来非常方便。

通过设置adc_r1_modedac_r1_mode来选择单通道或双通道读写功能。这些配置选项允许您在单通道模式下只使用一个通道进行数据读写,或者在双通道模式下同时使用两个通道进行数据读写。

通过设置adc_r1_modedac_r1_mode,您可以根据系统需求选择合适的模式。在单通道模式下,您只需使用一个通道进行数据读取或写入,这可能在某些应用中更为简单和高效。而在双通道模式下,您可以同时使用两个通道进行数据读取和写入,这可能在一些需要同时处理多个信号的应用中更为有用。

代码:

  1. module axi_ad9361_dev_if (
  2. // 物理接口(接收)
  3. input rx_clk_in_p,
  4. input rx_clk_in_n,
  5. input rx_frame_in_p, //每个数据包起始位置(n:下降 p:上升)
  6. input rx_frame_in_n,
  7. input [5:0] rx_data_in_p,
  8. input [5:0] rx_data_in_n,
  9. // 物理接口(发送)
  10. output tx_clk_out_p,
  11. output tx_clk_out_n,
  12. output tx_frame_out_p,
  13. output tx_frame_out_n,
  14. output [5:0] tx_data_out_p,
  15. output [5:0] tx_data_out_n,
  16. // 数据时钟
  17. output data_clk,
  18. // 接收数据路径接口
  19. output reg adc_valid,
  20. output reg [11:0] adc_data_i1,
  21. output reg [11:0] adc_data_q1,
  22. output reg [11:0] adc_data_i2,
  23. output reg [11:0] adc_data_q2,
  24. output reg adc_status,
  25. input adc_r1_mode,
  26. // 发送数据路径接口
  27. input dac_valid,
  28. input [11:0] dac_data_i1,
  29. input [11:0] dac_data_q1,
  30. input [11:0] dac_data_i2,
  31. input [11:0] dac_data_q2,
  32. input dac_r1_mode
  33. );
  34. // 发送帧接口, oddr -> obuf
  35. ODDR #(
  36. .DDR_CLK_EDGE ("SAME_EDGE" ))
  37. i_tx_frame_oddr (
  38. .CE (1'b1 ),
  39. .R (1'b0 ),
  40. .S (1'b0 ),
  41. .C (data_clk ),
  42. .D1 (tx_frame ),
  43. .D2 (tx_frame ),
  44. .Q (tx_frame_oddr_s ));
  45. OBUFDS i_tx_frame_obuf (
  46. .I(tx_frame_oddr_s),
  47. .O(tx_frame_out_p),
  48. .OB(tx_frame_out_n)
  49. );
  50. // 发送时钟接口, oddr -> obuf (需要和data_clk,相同频率和占空比)
  51. ODDR #(
  52. .DDR_CLK_EDGE ("SAME_EDGE" ))
  53. i_tx_clk_oddr (
  54. .CE (1'b1 ),
  55. .R (1'b0 ),
  56. .S (1'b0 ),
  57. .C (data_clk ),
  58. .D1 (1'b0 ),
  59. .D2 (1'b1 ),
  60. .Q (tx_clk_oddr_s ));
  61. OBUFDS i_tx_clk_obuf (
  62. .I(tx_clk_oddr_s),
  63. .O(tx_clk_out_p),
  64. .OB(tx_clk_out_n)
  65. );
  66. endmodule

 四、ad9361读取脚本文件

根据上一节的ad9361_lut.v脚本文件,可以将读取脚本用状态机实现,分为三个状态为写状态、读状态和延时状态,并通过循环来反复执行这些状态,直到所有寄存器都被配置完毕。最后,可以将状态机设置为一个固定状态,并发出配置结束的标志信号。

为了确保正常操作,我建议将时钟频率设置为20MHz,并与SPI读写时钟保持一致。这样可以确保数据传输的稳定性和可靠性。

通过这种方式,您可以有效地配置AD9361芯片的寄存器,并在配置完成后获得一个明确的结束标志,以确保配置的正确性和完整性。

 通过ad9361_config_writedata传输到SPI读写模块进行读写操作,

 代码:

  1. module ad9361_init(
  2. input clk,
  3. input rst_n,
  4. output reg read,
  5. output reg write,
  6. output reg [9:0] address,
  7. output reg [7:0] writedata,
  8. input [7:0] readdata,
  9. input waitrequest,
  10. output reg chip_rst_n,
  11. output [12:0] init_index,
  12. output reg init_done
  13. );
  14. //`define MODELSIM
  15. `define SPI_CLK_FREQ 20 //MHz
  16. `include "ad9361_lut.v"
  17. reg [12:0] index;
  18. reg [2:0] state;
  19. reg [31:0] delay_cnt;
  20. reg [18:0] command;
  21. assign init_index = index;
  22. always @ (posedge clk) command <= ad9361_lut(index);
  23. 3'd4 : begin
  24. index <= index + 1;
  25. state <= state + 1;
  26. end
  27. 3'd5 : begin
  28. state <= state + 1;
  29. end
  30. 3'd6 : begin
  31. state <= 1;
  32. end
  33. 3'd7 : begin
  34. init_done <= 1;
  35. end
  36. default : state <= 0;
  37. endcase
  38. end
  39. endmodule

五、SPI读写文件

基于上一节读取脚本文件读出的地址和数据,我们可以设计一个通用的SPI控制器,用于读写各种配置寄存器。该控制器采用三个状态机来实现不同的功能:开始传输、传输状态和传输完成。同时,我们可以使用一个always语句来实时输入数据,实现对寄存器的配置。

这个通用SPI控制器具有以下特点:

  1. 灵活性:它可以适应不同的寄存器配置需求,根据脚本文件中的地址和数据选择相应的寄存器进行读写操作。
  2. 可重用性:由于其通用性,该控制器可以在不同的工程中被重复使用,以满足不同的寄存器配置需求。
  3. 状态机驱动:通过三个状态机(开始传输、传输状态和传输完成),控制器可以在不同的阶段执行相应的操作,以确保正确的数据传输和操作完成。

通过使用这个通用SPI控制器,您可以方便地配置各种寄存器,并在传输完成后获得相应的状态信号,以确保配置的成功和完整性。

 代码:

  1. module ad9361_spi(
  2. input clk,
  3. input rst_n,
  4. //ad9361 interface
  5. input read,
  6. input write,
  7. input [9:0] address,
  8. input [7:0] writedata,
  9. output reg [7:0] readdata,
  10. output reg waitrequest,
  11. //SPI interface
  12. output spi_clk,
  13. output reg spi_csn,
  14. output reg spi_sdo,
  15. input spi_sdi
  16. );
  17. reg [4:0] bit_cnt;
  18. reg [23:0] command;
  19. reg [1:0] state;
  20. //SPI state
  21. localparam START = 0,
  22. TR = 1,
  23. DONE = 2;
  24. wire wr_rdn; //只写不读
  25. assign wr_rdn = write && !read;
  26. reg [7:0] readdata_shift = 0;
  27. always @ (posedge clk)
  28. begin
  29. readdata_shift <= {readdata_shift[6:0], spi_sdi};
  30. end
  31. always @ (posedge clk)
  32. begin
  33. if (bit_cnt == 24 && read)begin
  34. readdata <= {readdata_shift[6:0], spi_sdi};
  35. end
  36. end
  37. endmodule

六、工程顶层的设计

需要注意完成配置后,dac_valid才拉高,然后把dac_data传给tx_data,保证传输数据的正确。防止数据进行错位。

 代码:

  1. module system_top(
  2. //USER GPIO (PL GCLK 100MHz)
  3. input pl_gclk,
  4. output led7,
  5. output reg led0,
  6. input SW0,
  7. //ad9361 spi
  8. output spi_clk,
  9. output spi_csn,
  10. input spi_sdi,
  11. output spi_sdo,
  12. //ad9361 control
  13. output en_agc,
  14. output reg enable,
  15. output reg txnrx,
  16. output resetb,
  17. output sync_in,
  18. output [3:0] ctrl_in,
  19. input [7:0] ctrl_out,
  20. //ad9361 rx channel
  21. input rx_clk_in_p,
  22. input rx_clk_in_n,
  23. input [5:0] rx_data_in_n,
  24. input [5:0] rx_data_in_p,
  25. input rx_frame_in_n,
  26. input rx_frame_in_p,
  27. ad9361_spi ad9361_spi_0(
  28. .clk ( gclk_div ),
  29. .rst_n ( rstr ),
  30. .read ( ad9361_config_read ),
  31. .write ( ad9361_config_write ),
  32. .address ( ad9361_config_address ),
  33. .writedata ( ad9361_config_writedata ),
  34. .readdata ( ad9361_config_readdata ),
  35. .waitrequest ( ad9361_config_waitrequest ),
  36. .spi_clk ( spi_clk ),
  37. .spi_csn ( spi_csn ),
  38. .spi_sdo ( spi_sdo ),
  39. .spi_sdi ( spi_sdi )
  40. );
  41. endmodule

七、下板测试

把上述文件全部加入工程之后,然后分配管脚,进行编译和实现,产生bit流文件

AD9361应处在FDD工作状态,tx1和rx1单通道收发,收的频率2.4GHz,发的频率2.4GHz,为了测试方便本次设计产生一个稳定的正弦波信号,用频谱仪和ila分别测试,得出实验结果如下所示:

 

并且通过ila查看了每个读寄存器的值,均符合要求。  

本次纯逻辑配置ad9361设计完成,更多设计后续继续更新,,,

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/462811
推荐阅读
相关标签
  

闽ICP备14008679号