作为纪录学习过程使用
1 准备事项
软件部分
ise14.7主要是完成对FPGA开发板的程序编写和引脚绑定,modelsim则是对verilog程序的spi通信过程进行仿真,判断程序是否可以有效执行,ADF435X则是一款针对ADF4351芯片的仿真软件,通过设置内部寄存器数值,根据输入来判断输出的理论数值。AD软件则是画PCB板要用到的软件,然后通过嘉立创下单PCB板。
硬件部分
硬件部分主要是一个信号发生器,示波器或者一个频率计,以及一块FPGA的开发板(开发板我使用的是alinx的黑金开发板,搭载的是spartan-6),以及ADF4351的芯片(芯片性能不再介绍,网上都有芯片的手册可以搜到)。
主要流程
流程其实主要也分为两部分,一部分是软件方便的程序编写,一部分是硬件方面的pcb板制作和焊接。
ISE程序写入开发板
ISE完整工程的建立不再赘述,本人参考的这篇文章,一个完整ise工程的建立以及alinx的教学文件。这一步其实是最复杂的,想我这样的初学者花了很多时间,其中引脚的绑定可以参考开发板使用手册,以及教学文件的demo文件作为参考,在这里我使用modelsim进行的仿真。
verilog程序如下:设置写入寄存器的数值也已经设定好,
`timescale 1ns / 1ps
//
module ADF4351#
(
parameter r0=32'h0fa00000,
parameter r1=32'h00008011,
parameter r2=32'h0c08dfc2,
parameter r3=32'h004004b3,
parameter r4=32'h00b040bc,
parameter r5=32'h00580005
)
(
input clk,
input config_start,
output reg config_end=1'b0,
output reg sclk=1'b0,
output reg csn=1'b1,
output reg le=1'b0,
output reg dout=1'b0
);
///*edge_config_start*
reg [1:0] edge_config_check=2'b00;
wire edge_config_start;
assign edge_config_start=~edge_config_check[1] & edge_config_check[0];
always@(posedge clk) edge_config_check<={edge_config_check[0],config_start};
vb///*trans_data*//
localparam addr_r0=3'b000,addr_r1=3'b001,addr_r2=3'b010,addr_r3=3'b011,addr_r4=3'b100,addr_r5=3'b101;
reg [2:0] addr_reg=3'b101;
reg delay=1'b0;
reg [31:0] trans_data=32'h00000000;
always@(*)
case(addr_reg)
addr_r0:trans_data<=r0;
addr_r1:trans_data<=r1;
addr_r2:trans_data<=r2;
addr_r3:trans_data<=r3;
addr_r4:trans_data<=r4;
addr_r5:trans_data<=r5;
default:;
endcase
///*dout*/
localparam start=1'b0,process=1'b1;
reg status=start;
reg [4:0] addr_bit=5'b00000;
always@(posedge clk)
case(status)
start:
if(edge_config_start)
begin csn<=1'b0;
dout<=r5[31];
addr_bit<=5'b11111;
addr_reg<=3'b101;
config_end<=1'b0;
status<=process;
end
else if(~csn)
if(~sclk && ~delay)
sclk<=1'b1;
else if(sclk)
begin sclk<=1'b0;
dout<=r5[31];
addr_bit<=5'b11111;
addr_reg<=3'b101;
end
else if(~config_end)
begin csn<=1'b1;
config_end<=1'b1;
end
else ;
else ;
process:
if(~sclk && ~delay && ~le)
sclk<=1'b1;
else if(~sclk && delay) ;
else if((addr_reg==3'b000) && (addr_bit==5'b00001))
begin dout<=trans_data[addr_bit-1'b1];
addr_bit<=addr_bit-1'b1;
sclk<=1'b0;
status<=start;
end
else if(addr_bit==5'b00000)
begin dout<=trans_data[31];
addr_bit<=5'b11111;
addr_reg<=addr_reg-1'b1;
sclk<=1'b0;
end
else begin dout<=trans_data[addr_bit-1'b1];
addr_bit<=addr_bit-1'b1;
sclk<=1'b0;
end
default:;
endcase
///*delay*/
always@(posedge clk)
if((addr_bit==5'b00000) && ~sclk)
delay<=1'b1;
else if(~(addr_bit==5'b00000) && ~sclk && le)
delay<=1'b0;
else ;
*le*
always@(posedge clk)
if(delay && ~sclk)
le<=1'b1;
else if(le)
le<=1'b0;
else ;
endmodule
在仿真的text fixture文件中设置停止时间、时钟信号和复位信号,然后调用modelsim进行仿真可以得到下图
可以看到依次将data写入到指定的寄存器,spi通信成功建立。与ADF4351手册中时序图一致。
然后将verilog程序刻录进开发板即可。开发板程序已经准备好。
PCB板的设计与焊接
直接上成品吧,设计过程的话我主要参考的这个视频,ad软件的一个流程讲解视频,这里焊接的话还是建议用回流焊炉焊接,QFN封装还是有点难焊接的,而且容易虚焊和短路,我是使用钢网+锡膏+加回流焊炉的解决方式,出了炉子之后还需要用焊刀拖焊一下,基本就完美了。
两个PCB效果一样,只是电子元器件型号不同,使用杜邦线将PCB板引脚与FPGA开发板的引脚连接就可以了。注意电压和地也要连接,按照在ise中设定好的引脚连接,黑金开发板扩展口如下。
实验结果
这样设置寄存器时,通过仿真软件的模拟可以得到,如果17.5mhz的输入就可以得到500mhz的输出。程序中寄存器数值就是如此设置的。
上图中信号发生器产生一个17mhz的的正弦波,输出频率为490.256mhz,17.5的话就是500mhz,跟软件仿真的结果一致。初步证明FPGA控制ADF4351已经实现,后续只要改变程序中寄存器数值,然后重新写入开发板,开发板将数值写入adf芯片寄存器中,便可以实现控制。
[1]王晗,程诚,施嘉儒.基于ADF4351和FPGA的合成频率源的设计[J].电子技术应用,2017,43(10):34-38+43.DOI:10.16157/j.issn.0258-7998.171271.