FPGA学习笔记(七): DSB调制解调的仿真

笔记七是DSB调制解调的仿真实现。

DSB调制解调的实现原理:首先使用DDS产生低频正弦波信号作为调制信号,再用DDS产生高频信号作为载波信号,然后使用乘法器将两者相乘产生DSB信号,DSB信号与载波信号相乘之后,再经过FIR低通滤波器解调出原调制信号。

 1. 打开VIVADO,点击IP Catalog

2. 搜索DDS,点击DDS Complier

 

 3. DDS参数配置 依照之前配置两个DDS IP核

 

 

 依照上述步骤,加另外一个DDS IP核

 

 4. 点击IP Catalog,搜索mult,选择Multiplier

5. 参数配置 

同样配置另外一个Multiplier 

 

 6. 点击IP Catalog,搜索fir,选择FIR Complier

7. 配置参数

(1) 选择coe文件格式,将FIR 的coe文件加载进去

 FIR的COE文件生成参考FPGA学习笔记(六): FIR IP核的使用_qq_47598782的博客-CSDN博客

 

 (2) 采样频率 4MHz,时钟频率 50MHz

(3) 输入信号位宽为16bit,选择Symmetric

8. 调制模块文件 

module DSB_modulation(
    input clk,					// 输入clk
    output [15:0] dds_out1,		// 输出正弦信号1
    output [15:0] dds_out2,     // 输出正弦信号2
    output [31:0] dout			// 输出混频信号,即DSB信号
    );
wire clk;
wire [15:0] dds_out1;
wire [15:0] dds_out2;
// 例化
dds_compiler_0 U0_dds_compiler (
  .aclk(clk),                              // input wire aclk
  .m_axis_data_tvalid(m_axis_data_tvalid),  // output wire m_axis_data_tvalid
  .m_axis_data_tdata(dds_out1)    // output wire [15 : 0] m_axis_data_tdata
);
// 例化
dds_compiler_1 U1_dds_compiler (
  .aclk(clk),                              // input wire aclk
  .m_axis_data_tvalid(m_axis_data_tvalid),  // output wire m_axis_data_tvalid
  .m_axis_data_tdata(dds_out2)    // output wire [15 : 0] m_axis_data_tdata
);

// 例化
mult_gen_0 U0_mult (
  .CLK(clk),  // input wire CLK
  .A(dds_out1),      // input wire [15 : 0] A
  .B(dds_out2),      // input wire [15 : 0] B
  .P(dout)      // output wire [31 : 0] P
);
endmodule

 9. 解调模块文件

module DSB_demodulation(
    input clk,					// 输入clk
    output dout,				// 输出DSB信号
    output dds_out1,			// 输出正弦信号1
    output dds_out2,			// 输出正弦信号2
    output sin_demodulation		// 输出DSB与载波相乘信号
    );
    wire clk;
    wire [32:0] dout;
    wire [15:0] dds_out1;
    wire [15:0] dds_out2;
    wire [31:0] sin_demodulation;
    // DSB_modulation的例化
    DSB_modulation DSB_modulation_inst(
        .clk(clk),
        .dds_out1(dds_out1),
        .dds_out2(dds_out2),
        .dout(dout)
    );
    
    
   // 乘法器的例化
    mult_gen_1 U1_mult_gen (
  .CLK(clk),  // input wire CLK
  .A(dds_out1),      // input wire [15 : 0] A
  .B(dout[31:16]),      // input wire [15 : 0] B
  .P(sin_demodulation)      // output wire [31 : 0] P
);
endmodule

 10. 顶层文件

module top_dds_fir(
    input clk,					// 输入clk
    output dout,				// 输出DSB信号
    output dds_out1,			// 输出正弦信号1
    output dds_out2,			// 输出正弦信号2
    output sin_demodulation,	// 输出DSB信号与载波信号相乘
    output fir_din,				// 输出DSB信号与载波信号相乘的截断
    output fir_dout,			// 输出经过滤波器的信号
    output finall_out			// 输出经过滤波器的信号的截断信号
    );
    wire clk;
    wire [31:0] dout,sin_demodulation;
    wire [15:0] dds_out1,dds_out2,fir_din;
    //DSB_demodulation的例化
    DSB_demodulation U_DSB_demodulation(
        .clk(clk),
        .dout(dout),
        .dds_out1(dds_out1),
        .dds_out2(dds_out2),
        .sin_demodulation(sin_demodulation)
    );
	// DSB信号与载波信号相乘的截断
     assign fir_din = sin_demodulation[31:16];
     
     wire [39:0] fir_dout;
     
     wire  [15:0] finall_out;
     wire t_valid;
     assign t_valid = 1'b1;
	 //  fir_compiler_0 的例化
fir_compiler_0 U1_fir_compiler_0 (
  .aclk(clk),                              // input wire aclk
  .s_axis_data_tvalid(t_valid),  // input wire s_axis_data_tvalid
  .s_axis_data_tready(),  // output wire s_axis_data_tready
  .s_axis_data_tdata(fir_din),    // input wire [15 : 0] s_axis_data_tdata
  .m_axis_data_tvalid(),  // output wire m_axis_data_tvalid
  .m_axis_data_tdata(fir_dout)    // output wire [39 : 0] m_axis_data_tdata
);
// 经过滤波器的信号的截断信号
    assign finall_out = fir_dout[39:24];
endmodule

 11. 测试文件

module DSB_modulation_tb();

reg clk;						// 输入clk
wire [15:0] dds_out1;			
wire [15:0] dds_out2;			
wire [31:0] dout;
wire [31:0] sin_demodulation;
wire [15:0] fir_din;
wire [39:0] fir_dout;
wire [15:0] finall_out;

// 例化
top_dds_fir top_dds_fir_inst(
     .clk(clk),
     .dout(dout),
     .dds_out1(dds_out1),
     .dds_out2(dds_out2),
     .sin_demodulation(sin_demodulation),
     .fir_din(fir_din),
     .fir_dout(fir_dout),
     .finall_out(finall_out)
);

//fir filter
initial begin
    clk = 0;
    end
    always #10 clk = ~clk;
endmodule

 12. 结果显示