DDS
参考文章:基于FPGA的DDS
SPI
参看文章:基于Stm32+FPGA的SPI
功能实现:
设备:MCU:STM32 +FPGA:DE0开发板 + DA/AD 实验板
通过在SPI接口下挂接上DDS模块,通过单片机向FPGA发送频率字,实现任意频率正弦波的波形产生,并通过DAC模块输出,并通过示波器检测
FPGA系统结构
单片机部分
通过按键输入待产生的信号频率,通过公式转化为32位频率字,通过SPI发给FPGA
FPGA部分
接受单片机的频率字输入,通过DDS输出输入的正弦波波形
主体模块
module spi_bus_test(
I_CLK,
I_CS,
I_SCLK,
I_SDIN,
SW,
RST,
O_SDOUT,
OUTCNT0,
OUTCNT1,
OUTCNT2,
OUTRD,
DDSfwq,
DDSOUT
);
input wire RST;
input wire I_CLK;
input wire I_CS;
input wire I_SCLK;
input wire I_SDIN;
input wire [0:0] SW;
output wire O_SDOUT;
output wire [15:0] OUTCNT0;
output wire [15:0] OUTCNT1;
output wire [31:0] OUTCNT2;
output wire [31:0] DDSfwq;
output wire [15:0] OUTRD;
output wire [11:0] DDSOUT;
wire W_I_CLK;
wire [15:0] W_O_WD;
wire [31:0] W_O_WE;
wire [15:0] W_spi_bus_in;
wire [15:0] SYNTHESIZED_WIRE_0;
wire [15:0] SYNTHESIZED_WIRE_1;
spi_bus_32b_A15RD1WR0 b2v_U1(
.I_CLK(W_I_CLK),
.I_CS(I_CS),
.I_SCLK(I_SCLK),
.I_SDIN(I_SDIN),
.I_DIN(W_spi_bus_in),
.O_SDOUT(O_SDOUT),
.O_WD(W_O_WD),
.O_WE(W_O_WE));
cnt16_spi_wr_test b2v_U2(
.I_CLK(W_I_CLK),
.I_ENA(W_O_WE[0]),
.I_INC(W_O_WD),
.O_CNT(OUTCNT0));
cnt16_spi_wr_test b2v_U3(
.I_CLK(W_I_CLK),
.I_ENA(W_O_WE[1]),
.I_INC(W_O_WD),
.O_CNT(OUTCNT1));
cnt32_spi_wr_test b2v_U4(
.I_CLK(W_I_CLK),
.I_ENA_H(W_O_WE[2]),
.I_ENA_L(W_O_WE[3]),
.I_UPDATE(W_O_WE[4]),
.I_INC_H(W_O_WD),
.I_INC_L(W_O_WD),
.O_CNT(OUTCNT2));
cnt32_spi_wr_test DDS(
.I_CLK(W_I_CLK),
.I_ENA_H(W_O_WE[10]),
.I_ENA_L(W_O_WE[11]),
.I_UPDATE(W_O_WE[12]),
.I_INC_H(W_O_WD),
.I_INC_L(W_O_WD),
.O_CNT(DDSfwq));
top_sin_wave(
.CLK(W_I_CLK) , // clock, posedge valid
.fqwd_W(DDSfwq) , // input freq word
.fwen_W(1) , // inpue freq word enable
.BUTRST(RST) , // reset button
.SINOUT(DDSOUT) );
dpram16_spi_wr_test b2v_U5(
.I_CLK(W_I_CLK),
.I_WAE(W_O_WE[5]),
.I_WDE(W_O_WE[6]),
.I_WA(W_O_WD),
.I_WD(W_O_WD),
.O_RD(OUTRD));
select_in_to_out b2v_U6(
.I_CLK(W_I_CLK),
.I_ENSEL(W_O_WE[7]),
.I_DIN00(SYNTHESIZED_WIRE_0),
.I_DIN01(SYNTHESIZED_WIRE_1),
.I_SEL(W_O_WD),
.O_DOUT(W_spi_bus_in));
cnt16_spi_read_test b2v_U7(
.I_CLK(W_I_CLK),
.I_SW(SW),
.O_CNT(SYNTHESIZED_WIRE_0));
rom_A7b_D8b_spi_rd_test b2v_U8(
.I_CLK(W_I_CLK),
.I_RE(W_O_WE[8]),
.I_RA(W_O_WD),
.O_RD(SYNTHESIZED_WIRE_1));
assign W_I_CLK = I_CLK;
endmodule
实际测试
如下所示:输出1MHz和500kHz正弦波输出:
DAC子板一定别只给数据,不给时钟@_@。由下图看出波形有明显的毛刺,这是时钟和数据不同步造成的,我采用DAC的时钟由主频直接分频产生,时钟不干净(主要是因为我懒);将DAC的时钟改为由PLL产生。
通过按键输入的频率分别为10MHz,1MHz,500kHz,100kHz,1kHz,500Hz,100Hz,123456Hz
示波器输出如下
可以看出示波器的波形比较平滑,输出的频率在误差允许范围内,基本符合要求。