详细代码及仿真源文件已同步上传至个人主页资源(原创不易,转载请注明出处)
目录
HMC7044介绍
一、概述
HMC7044是带有 JESD204B 接口的高性能、3.2 GHz、14 路输出抖动衰减器,提供 14 路低噪声且可配置的输出,可以灵活地与许多不同器件接口,包括数据转换器、现场可编程门阵列(FPGA)和混频器本振(LO)。
查阅官方手册,这里我们需要关心的是:
1.查找SPI总线频率
2.SPI的发送时序,发送模式,发送多少数据
由官网手册可知,每次通过SPI发送24bit数据,且SPI工作模式为模式0
模块图
模块分析:
PLL模块:用于生成所需时钟,这里低于10MHZ即可,本实验设置为5MHZ
SPI_send模块:用于发送配置的24bit数据
SPI_ctrl模块:用于对所需要发送的数据进行控制,以满足HMC7044芯片的时序要求
代码实现
module spi_send(
input wire div_clk ,//分频时钟5MHz
input wire sys_rst_n ,//复位信号,低电平有效
input wire str_flag ,//开始标志信号
input wire [23:0]data ,//数据24位
/* input wire spi_done ,//全部配置完成信号 */
output reg slen ,//cs#片选信号,低电平有效
output wire sclk ,//spi传输时钟
output reg sdata ,//spi传输数据,MSB
output reg send_done
);
/**************define code*********************/
parameter IDLE = 5'd0 ,
S0 = 5'd1 ,
S1 = 5'd2 ,
S2 = 5'd3 ,
S3 = 5'd4 ;
reg[2:0] state ;//状态机5个状态
reg[4:0] cnt_bit ;//对数计数0-23
reg clk_en ;//时钟使能信号
wire div_clk_n ;//对分频时钟取反
/**************main code*********************/
//describe div_clk_n
assign div_clk_n = ~div_clk ;
//describe cnt_bit
always@(posedge div_clk , negedge sys_rst_n)
begin
if(~sys_rst_n)
cnt_bit <= 5'd0 ;
else if(cnt_bit == 5'd25)
cnt_bit <= 5'd0 ;
else if(state == S1)
cnt_bit <= cnt_bit + 1'd1 ;
end
//describe clk_en
always@(posedge div_clk , negedge sys_rst_n)
begin
if(~sys_rst_n)
clk_en <= 1'd0 ;
else if(((cnt_bit >= 5'd0) && (cnt_bit <= 5'd23))&&(state == S1))
clk_en <= 1'd1 ;
else
clk_en <= 1'd0 ;
end
//两段式状态机,第一段,时序逻辑,描述状态转移
always@(posedge div_clk , negedge sys_rst_n)
begin
if(~sys_rst_n)
state <= IDLE ;
else case(state)
IDLE :
begin
if(str_flag)
state <= S0 ;
else
state <= state ;
end
S0 : state <= S1 ;
S1 :
begin
if(cnt_bit == 5'd24)
state <= S2 ;
else
state <= state ;
end
S2 : state <= S3 ;
S3 :
begin
if(send_done)
state <= IDLE ;
else
state <= state ;
end
default : state <= IDLE ;
endcase
end
//第二段,时序逻辑,描述输出
always@(posedge div_clk , negedge sys_rst_n)
begin
if(~sys_rst_n)
slen <= 1'd1 ;
else if(str_flag)
slen <= 1'd0 ;
else if(state == S2)
slen <= 1'd1 ;
else
slen <= slen ;
end
//describe sclk
assign sclk = (clk_en == 1'd1) ? div_clk_n : 1'd0 ;
//describe sdata
always@(posedge div_clk , negedge sys_rst_n)
begin
if(~sys_rst_n)
sdata <= 1'd0 ;
else case(cnt_bit)
5'd1 : sdata <= data[23] ;//MSB
5'd2 : sdata <= data[22] ;
5'd3 : sdata <= data[21] ;
5'd4 : sdata <= data[20] ;
5'd5 : sdata <= data[19] ;
5'd6 : sdata <= data[18] ;
5'd7 : sdata <= data[17] ;
5'd8 : sdata <= data[16] ;
5'd9 : sdata <= data[15] ;
5'd10 : sdata <= data[14] ;
5'd11 : sdata <= data[13] ;
5'd12 : sdata <= data[12] ;
5'd13 : sdata <= data[11] ;
5'd14 : sdata <= data[10] ;
5'd15 : sdata <= data[9] ;
5'd16 : sdata <= data[8] ;
5'd17 : sdata <= data[7] ;
5'd18 : sdata <= data[6] ;
5'd19 : sdata <= data[5] ;
5'd20 : sdata <= data[4] ;
5'd21 : sdata <= data[3] ;
5'd22 : sdata <= data[2] ;
5'd23 : sdata <= data[1] ;
5'd24 : sdata <= data[0] ;
default : sdata <= 1'd0 ;
endcase
end
//describe send_done
always@(posedge div_clk , negedge sys_rst_n)
begin
if(~sys_rst_n)
send_done <= 1'd0 ;
else if(state == S2)
send_done <= 1'd1 ;
else
send_done <= 1'd0 ;
end
endmodule
由于篇幅有限,其他模块已经上传至个人主页资源
时序图
参考SPI发送数据时序,将数据位改为24bit即可
仿真图
可以看到FPGA通过SPI发送了8'h98条数据进行HMC7044配置,当配置完成的时候,进行正常工作,即配置完成