FPGA纯逻辑控制AD936x/AD9361配置寄存器/AD9361纯硬件设计/AD9361配置流程/zynq配置ad9361//AD936x教程/纯Verilog配置AD9361(三)

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

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

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

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

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

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

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

一、新建一个vivado工程

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

二、AD9361配置脚本文件

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

 三、顶层设计

顶层主要连接各个模块例化

部分代码:

module system_top(
//系统输入时钟
    input               i_clk,
//AD936X SPI配置
    output              o_spi_clk,
    output              o_spi_csn,
    input               i_spi_miso,
    output              o_spi_mosi,
//AD936X 状态控制引脚
    output              en_agc,
    output reg          enable,
    output reg          txnrx,
    output              chip_rst_n,
    output              sync_in,
    output      [3:0]   ctrl_in,
//AD936X 接收通道数据引脚
    input               rx_clk_in_p,
    input               rx_clk_in_n,
    input       [5:0]   rx_data_in_n,
    input       [5:0]   rx_data_in_p,
    input               rx_frame_in_n,
    input               rx_frame_in_p,
//AD936X 发射通道数据引脚
字
数
太
多
省
略
一
部
分
//接收数据信号
    .rx0_i_data                 (rx0_i_data ),
    .rx0_q_data                 (rx0_q_data ),
    .rx1_i_data                 (rx1_i_data ),
    .rx1_q_data                 (rx1_q_data ),
      /*   
    .tx0_i_data                 (tx0_i_data1),
    .tx0_q_data                 (tx0_q_data1),
    .tx1_i_data                 (tx1_i_data1),
    .tx1_q_data                 (tx1_q_data1)*/
     
    .tx0_i_data                 (tx0_i_data),
    .tx0_q_data                 (tx0_q_data),
    .tx1_i_data                 (tx1_i_data),
    .tx1_q_data                 (tx1_q_data),
    .clk_200M                   (clk_200M  )
    );

endmodule

四、数据处理模块

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

部分代码:

module data_process(
//接收数据通道
    input                   rx_clk_in_p,
    input                   rx_clk_in_n,
    input                   rx_frame_in_p,   
    input                   rx_frame_in_n,
    input         [5:0]     rx_data_in_p,
    input         [5:0]     rx_data_in_n,
//发送数据通道  
    output                  tx_clk_out_p,
    output                  tx_clk_out_n,
    output                  tx_frame_out_p,
    output                  tx_frame_out_n,
    output        [5:0]     tx_data_out_p,
    output        [5:0]     tx_data_out_n,
//复位信号  
    input                   reset,
    output                  sample_clk,
//接收数据信号  
    output   reg [11:0]     rx0_i_data,
    output   reg [11:0]     rx0_q_data,
    output   reg [11:0]     rx1_i_data,
    output   reg [11:0]     rx1_q_data,
//发送数据信号  
    input        [11:0]     tx0_i_data,
    input        [11:0]     tx0_q_data,
    input        [11:0]     tx1_i_data,
    input        [11:0]     tx1_q_data,
    input wire clk_200M
    );
/****************************SELECTIO IO***********************************/
//selectIO输入和输出的数据
wire [13:0] selectio_rx_data_delay,selectio_rx_data;
reg  [13:0] selectio_tx_data;   
//selectIO输出的单端时钟
// wire data_clk;
//物理接口
wire [6:0] selectio_rx_data_in_p;
wire [6:0] selectio_rx_data_in_n;
wire [6:0] selectio_tx_data_out_p;
wire [6:0] selectio_tx_data_out_n;

assign selectio_rx_data_in_p = {rx_frame_in_p,rx_data_in_p};
assign selectio_rx_data_in_n = {rx_frame_in_n,rx_data_in_n};

wire [4:0]DELAY;//步长78ps,最大步数31约为2.418ns
vio_0 vio_0_inst (
  .clk(clk_200M),                // input wire clk
  .probe_out0(DELAY)  // output wire [4 : 0] probe_out0
);

 五、ad9361初始化模块

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

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

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

 通过ad9361_config_writedata传输到SPI读写模块进行读写操作,实现对9361配置脚本的读写,从而配置9361

 部分代码:

module AD936X_Init#
(
    parameter           SPI_CLK_FREQ = 25
)
    (
	input 				i_clk       ,
	input 				i_rst       ,
    output              o_spi_clk   , 
    output              o_spi_cs    , 
    output              o_spi_mosi  ,
    input               i_spi_miso  ,
	output	reg			chip_rst_n  ,
	output 	reg			init_done
);


    /************************reg****************************/
    reg	       [11:0]	            index       ;       //初始化参数索引
    reg         [18:0]	            command     ;       //配置参数命令
    reg         [7:0]                readdata   ;       //读出的8位数据
    /************************wire***************************/
    wire                            w_active;            //SPI总线激活信号
    reg         [23:0]              i_user_data ;        //SPI写数据信号
    reg                             i_user_valid;        //SPI写有效信号
    wire                            o_user_ready;        //SPI驱动准备好信号
    wire        [23:0]              o_user_read_data;    //读出数据
    wire                            o_user_read_valid;   //读出数据有效信号
    /*********************component*************************/

/*****配置命令索引控制*****/
always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)
        index <= 'd0;
    else if(st_current == P_ST_ADD)
        index <= index + 1;
    else 
        index <= index;
end

/*****初始化完成信号*****/
always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)
        init_done <= 'd0;
    else if(st_current == P_ST_END)
        init_done <= 'd1;
    else 
        init_done <= init_done;
end

六、SPI驱动模块

基于上一节读取脚本文件读出的地址和数据,我们可以设计一个通用的SPI控制器,用于读写各种配置寄存器。同时,我们可以使用一个always语句来实时输入数据,实现对寄存器的配置。

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

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

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

部分代码:

module spi_drive#(
    parameter                   P_DATA_WIDTH    = 8 ,
    parameter                   P_CPOL          = 0 ,
    parameter                   P_CPHA          = 0 
)(
    input                       i_clk               ,
    input                       i_rst               ,

    output                      o_spi_clk           ,
    output                      o_spi_cs            ,
    output                      o_spi_mosi          ,
    input                       i_spi_miso          ,

    input   [P_DATA_WIDTH-1:0]  i_user_data         ,
    input                       i_user_valid        ,
    output                      o_user_ready        ,

    output  [P_DATA_WIDTH-1:0]  o_user_read_data    ,
    output                      o_user_read_valid   
);

字
数
限
制
省
略
always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)
        ro_user_read_data <= 'd0;
    else if(!r_spi_cnt && P_CPHA==0 && r_run)
        ro_user_read_data <= {ro_user_read_data[P_DATA_WIDTH - 2:0],i_spi_miso}; 
    else if(r_spi_cnt && P_CPHA==1  && r_run)
       ro_user_read_data <= {ro_user_read_data[P_DATA_WIDTH - 2:0],i_spi_miso}; 
    else
       ro_user_read_data <= ro_user_read_data;         
end

always @(posedge i_clk or posedge i_rst) begin
    if(i_rst)
        ro_user_read_valid <= 'd0;
    else if(r_spi_cnt && r_cnt == P_DATA_WIDTH - 1)
        ro_user_read_valid <= 'd1;       
    else
        ro_user_read_valid <= 'd0;
end

endmodule

七、下板测试

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

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

 

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

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

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值