AD9361芯片进行数据接口逻辑代码的编写

fpga实现ad9361数据接口逻辑
1 引言
本文通过以高速ad9361芯片为例进行数据接口逻辑代码的编写,利用selectio ip快速高效完成芯片驱动的生成。
2 ad9361
2.1 芯片简介
  ad9361是一款面向3g和4g基站应用的高性能、高集成度的射频(rf)agile transceiver捷变收发器。该器件的可编程性和宽带能力使其成为多种收发器应用的理想选择。该器件集rf前端与灵活的混合信号基带部分为一体,集成频率合成器,为处理器提供可配置数字接口,从而简化设计导入。ad9361接收器lo工作频率范围为70 mhz至6.0 ghz,发射器lo工作频率范围为47 mhz至6.0 ghz,涵盖大部分特许执照和免执照频段,支持的通道带宽范围为200 khz以下至56 mhz,整体结构图如图 1 ad9361整体结构图所示。
图 1 ad9361整体结构图
• 集成12位dac和adc的rf 2 × 2收发器• tx频段:47 mhz至6.0 ghz• rx频段:70 mhz至6.0 ghz• 支持tdd和fdd操作• 可调谐通道带宽:<200 khz至56 mhz• 双通道接收器:6路差分或12路单端输入• 出色的接收器灵敏度,噪声系数为2 db (800 mhz lo)• rx增益控制  o 实时监控和控制信号用于手动增益  o 独立的自动增益控制• 双发射器:4路差分输出• 高线性度宽带发射器  o tx evm:≤−40 db  o tx噪声:≤−157 dbm/hz本底噪声  o tx监控器:动态范围≥66 db,精度=1 db• 集成式小数n分频频率合成器• 2.4 hz最大本振(lo)步长• 多器件同步• cmos/lvds数字接口  
2.2 参数配置
  用户可以根据自己的需求将数据接口通过spi配置成lvds或cmos接口,也可以还可以选择fdd或tdd工作方式,以及数据速率可以选择sdr或ddr。只需要通过配置软件设置即可,如图 2 ad9361数据接口配置参数所示,详细的配置教程见ad936x evaluation software 详细配置。
图 2 ad9361数据接口配置参数
  在进行数据验证时,也可以使用测试模式,对收发数据进行验证以保证系统的正确性。另外,还可以对输入时钟进行延时调节或者通过selectio的delay、delayctrl功能对时钟信号进行微调,以满足时序要求。芯片数据时钟与数据之间的时序可靠性也可以通过芯片内部的延时寄存器0x006、0x007进行条件,以此达到要求,具体的spi配置寄存器时序如图 3 ad9361 寄存器配置接口spi时序所示。此方面不是本文重点,不做展开,更多内容参考官方data sheet。
图 3 ad9361 寄存器配置接口spi时序
  本小节使用的数据接口参数:lvds、fdd、ddr,对应的时序逻辑也是根据该参数进行设计。
2.3 引脚
rx数据时序接口如下:
tx数据时序接口如下:
2.4 接口时序
  以下使用的数据接口参数:lvds、fdd、ddr,根据不同的通道数可以得到不同的数据时序,用户在解析数据时只要按照对应的结构进行拼接即可。
图 4 ad9361接收数据路径 图 5 ad9361发射接口路径
3 参考代码
3.1 selectio配置
  根据以上对ad9361的了解,就可以轻松的配置selectio ip的gui界面了。芯片既包括发射模块tx又包括接收模块rx,所以io类型选择chip to chip。
图 6 selectio配置界面1
  根据上述参数配置部分,自然就选择ddr。数据接口包括时钟clk、frame对齐信号与差分数据端data[05:0],要同时对frame与data信号进行时序解析,所以端口宽度设置为7.
图 7 selectio配置界面2
  由于芯片内部寄存器0x006、0x007可以确保时钟与数据满足时序要求,所以不需要延时模块,以节约fpga逻辑资源。
3.2 数据解析
//-------------------------------------------------------------------// 用于将接收时钟与数据进行单端与差分的变换//-------------------------------------------------------------------selectio_ip u_selectio_ip ( // from the system into the device   .data_in_from_pins_p (ad_rx_data_in_p),    //从ad接收端接收到的单端数据与标志   .data_in_from_pins_n (ad_rx_data_in_n),    //从ad接收端接收到的单端数据与标志   .data_in_to_device  (ad_rx_data),    //将ad接收端接收到的数据与标志转换为单端数据    // from the device out to the system   .data_out_from_device (ad_tx_data),    //将要发送的da数据与标志转换为单端数据   .data_out_to_pins_p  (ad_tx_data_out_p),    //发送端的单端da数据与标志   .data_out_to_pins_n  (ad_tx_data_out_n),   //发送端的单端da数据与标志   .clk_to_pins_p   (ad_fb_clk_p),      //将ad接收端的输入时钟用于发射时钟   .clk_to_pins_n   (ad_fb_clk_n),      //将ad接收端的输入时钟用于发射时钟   .clk_in_p     (ad_data_clk_p),        //ad接收端的单端输入时钟   .clk_in_n     (ad_data_clk_n),        //ad接收端的单端输入时钟   .clk_out     (ad9361_data_clk),          //将ad接收端的差分输入时钟转变为单端时钟   .clk_reset     (reset),        //用于ad输入时钟的复位,高有效   .io_reset     (reset)        //用于单端、差分变换的复位,高有效 );//-------------------------------------------------------------------//发送数据的生成//------------------------------------------------------------------- assign ad_tx0_msb_q=ad_tx0_data[23:18]; assign ad_tx0_lsb_q=ad_tx0_data[17:12]; assign ad_tx0_msb_i=ad_tx0_data[11:06]; assign ad_tx0_lsb_i=ad_tx0_data[05:00]; assign ad_tx1_msb_q=ad_tx1_data[23:18]; assign ad_tx1_lsb_q=ad_tx1_data[17:12]; assign ad_tx1_msb_i=ad_tx1_data[11:06]; assign ad_tx1_lsb_i=ad_tx1_data[05:00];  reg [13:0] ad_tx_data;//-------------------------------------------------------------------//选择要发送的i与q数据//------------------------------------------------------------------- always @(posedge ad9361_data_clk or posedge reset) begin  if(reset)   ad_tx_data<=0;  else if((ad_tx_frame_reg==0)&&(ad_tx_frame==1))   ad_tx_data<={ad_tx_frame,ad_tx0_msb_q,ad_tx_frame,ad_tx0_msb_i};  else if((ad_tx_frame_reg==1)&&(ad_tx_frame==1))   ad_tx_data<={ad_tx_frame,ad_tx0_lsb_q,ad_tx_frame,ad_tx0_lsb_i};  else if((ad_tx_frame_reg==1)&&(ad_tx_frame==0))   ad_tx_data<={ad_tx_frame,ad_tx1_msb_q,ad_tx_frame,ad_tx1_msb_i};  else if((ad_tx_frame_reg==0)&&(ad_tx_frame==0))   ad_tx_data<={ad_tx_frame,ad_tx1_lsb_q,ad_tx_frame,ad_tx1_lsb_i};   end //-------------------------------------------------------------------//选择接收的i与q数据//------------------------------------------------------------------- always @(posedge ad9361_data_clk or posedge reset) begin  if(reset) begin   ad_rx0_msb_i<=0;   ad_rx0_msb_q<=0;   ad_rx0_lsb_i<=0;   ad_rx0_lsb_q<=0;   ad_rx1_msb_i<=0;   ad_rx1_msb_q<=0;   ad_rx1_lsb_i<=0;   ad_rx1_lsb_q<=0;     end  else if((ad_rx_frame_reg==0)&&(ad_rx_frame==1)) begin   ad_rx0_msb_i<=ad_rx_data[05:0];   ad_rx0_msb_q<=ad_rx_data[12:7];  end  else if((ad_rx_frame_reg==1)&&(ad_rx_frame==1)) begin   ad_rx0_lsb_i<=ad_rx_data[05:0];   ad_rx0_lsb_q<=ad_rx_data[12:7];  end  else if((ad_rx_frame_reg==1)&&(ad_rx_frame==0)) begin   ad_rx1_msb_i<=ad_rx_data[05:0];   ad_rx1_msb_q<=ad_rx_data[12:7];  end  else if((ad_rx_frame_reg==0)&&(ad_rx_frame==0)) begin   ad_rx1_lsb_i<=ad_rx_data[05:0];   ad_rx1_lsb_q<=ad_rx_data[12:7];  end  end  wire [23:0]  ad_rx0_fifo_data; wire [23:0]  ad_rx1_fifo_data; assign ad_rx0_fifo_data={ad_rx0_msb_q,ad_rx0_lsb_q,ad_rx0_msb_i,ad_rx0_lsb_i}; assign ad_rx1_fifo_data={ad_rx1_msb_q,ad_rx1_lsb_q,ad_rx1_msb_i,ad_rx1_lsb_i};
原文标题:fpga实现ad9361数据接口逻辑
文章出处:【微信公众号:fpga之家】欢迎添加关注!文章转载请注明出处。


推进“互联网+”便捷交通_促进智能交通发展的实施方案
开箱国货征拓SuperTank Pro 100W移动电源:支持固件更新
满足DALI规范需求 恩智浦32位MCU助力打造智能灯控系统
镜面电视带你打开高质量生活的大门
使用CENTAURI 200物联网网关将Alexa与您的物联网解决方案集成
AD9361芯片进行数据接口逻辑代码的编写
致2016机器人市场:僧多肉少之时 合作才是王道
高空抛物智能监测系统为数据分析处理提供有力的信息和技术支撑
Silicon Labs Gecko MCU确保Misfit Shine 可穿戴健身追踪器“节能省电”
国产嵌入式工业主板安装的独特优势
如何用深度学习模型,模仿人类的教练过程?
空调省电六大决招
塑料光纤传输和通信系统的优势和应用分析
传统安防的升级,视频监控系统呈燎原之势
数字孪生的新应用,通过智能技术提高建筑安全性
无线热像仪WiFi模组技术的应用
ST的MP1系列MPU
!销售/收购/维修HP8562E頻譜分析儀HP 8562E小
i.MX RT600 BCLK受干扰影响WS频率解决方案
波士顿动力机器人组团跳舞:跳舞背后的原理是什么呢