【FPGA作业】第五章 单音信号对载波信号进行双边带幅度调制

五 单音信号对载波信号进行双边带幅度调制

5.1 实验内容

  • 合成一个双边带AM调制信号,载波频率1MHz,调制信号1KHz,采样率50MHz
  • 使用Modelsim仿真,观察波形,使用Matlab观察频谱
  • 使用Signaltap抓取电路输出波形,使用Matlab观察频谱
    方案描述
  • 使用两个DDS,一个DDS为1MHz,另一个为1KHz,直接相乘
  • ROM表由Matlab生成,10bit地址,10bit量化
  • 相位累加器32bit

5.2 原理

(1)DDS原理

这里写图片描述

(2)双边带调幅原理

时域表达式
这里写图片描述
这里写图片描述
图5. 1 DSB时域图像
频域表达式
这里写图片描述
图5. 2 DSB频域图像

5.3 双边带幅度调制Verilog实现

5.3.1 DDS模块实现

(1)dds_core.v
完成ROM地址改变的功能

`timescale 1ns/1ns
module dds_core_sin(
    CLK,    //clock
    RST,    //button reset, high level reset
//  FWEN,   //button frequency word update enable, high level enable
    FWIN,   //input frequency word
    CLKOUT, //output clock
    SINOUT, //sine signal output, 2's complement format
    AccCNT
);

input CLK;
input RST;
//input FWEN;
input[31:0] FWIN;
output CLKOUT;
output[9:0]SINOUT;
output[31:0]AccCNT;

parameter FW_WL=32; // frequency word 32bit
parameter RA_WL=10; // rom address input length
parameter RD_WL=10; // rom data output length

//reg   [FW_WL-1 : 0] fwin_R;   // frequency word 
reg [FW_WL-1 : 0] acc_R;    // acc register record frequency + acc
reg [RA_WL-1 : 0] addr_R;   // addr_R related to rom input 
reg [RD_WL-1 : 0] sinout_R; // sinout_R is the register of rom output
wire [RD_WL-1 : 0] romout_W;// related to rom output

always @ (posedge CLK ) begin
    if(!RST) 
    begin // all registers clear out
//      fwin_R <= 0;
        acc_R <= 0;
        addr_R <= 0;
        sinout_R <= 0;
    end
    else begin
        // fwin_R update
//      if(FWEN) fwin_R <= #5 FWIN;
//      else fwin_R <= #5 fwin_R;
//      fwin_R <= FWIN;
        // acc_R update
//      acc_R <= fwin_R + acc_R;
        acc_R <= FWIN +acc_R;
        // addr_R update, the acc_R high RA_WL is rom address
        addr_R <= acc_R[FW_WL-1 : FW_WL-1 - (RA_WL-1)];

        // sinout_R update
        sinout_R <= romout_W;

    end
end
sine_rom_10bit u_sinrom(
    .rst (RST),
    .clk    (CLK),
    .RA     (addr_R),
    .RD     (romout_W)
);
assign SINOUT = sinout_R;
assign CLKOUT = CLK;
assign AccCNT = acc_R;
endmodule

(2)sine_rom_10bit.v
ROM表,根据matlab函数生成,此处略过大部分具体值

// 10bit量化,10bit地址
`timescale 1ns/1ns
module sine_rom_10bit(
    input rst,
    input clk,
    input [9:0] RA,
    output reg[9:0] RD );
always @ (posedge clk)
    if(!rst)
        begin RD=10'd0; end 
    else 
    begin case(RA)
        10'd 0 :RD=#1 10'b 0000000000 ;
        10'd 1 :RD=#1 10'b 0000000100 ;
        10'd 2 :RD=#1 10'b 0000000111 ;
        10'd 3 :RD=#1 10'b 0000001010 ;
… …
        10'd 1020 :RD=#1 10'b 1111110100 ;
        10'd 1021 :RD=#1 10'b 1111110111 ;
        10'd 1022 :RD=#1 10'b 1111111010 ;
        10'd 1023 :RD=#1 10'b 1111111101 ;
        default: RD=#1 0;
        endcase
end
endmodule

5.3.2 双边带幅度调制Verilog文件top_DSB_wave.v

双边带幅度调制Verilog文件,作为quartus的顶层文件使用

`timescale 1ns/1ns
module top_DSB_wave(
    CLK,
    BUTRST,
    SINOUT,
    SINOUT_DDS1,
    SINOUT_DDS2
);
input CLK, BUTRST;
output [20:0] SINOUT;
output [9:0] SINOUT_DDS1;
output [9:0] SINOUT_DDS2;
wire rst;
wire signed [9:0] dds_out_2c_W_1;
wire signed [9:0] dds_out_2c_W_2;
reg [20:0] dds_out_2c_W_DSB;

parameter VAL_FREQ_1M = 32'd85_899_345;// k = 2 ^ 32 / 50
parameter VAL_FREQ_1K = 32'd85_899; // k = 2 ^ 32 / 50 / 10

assign rst = BUTRST;

dds_core_sin U_DDS1(
  .CLK      (CLK            ),   // clock, posedge valid
  .RST      (rst          ),   // reset, high level reset
  .FWIN     (VAL_FREQ_1M         ),   // input frequency word
  .SINOUT   (dds_out_2c_W_1   ));  // sine signal output, 2's complement format

dds_core_sin U_DDS2(
  .CLK      (CLK            ),   // clock, posedge valid
  .RST      (rst          ),   // reset, high level reset
  .FWIN     (VAL_FREQ_1K         ),   // input frequency word
  .SINOUT   (dds_out_2c_W_2   ));  // sine signal output, 2's complement format

always @(dds_out_2c_W_1 or dds_out_2c_W_2)
begin
    dds_out_2c_W_DSB = dds_out_2c_W_1 * dds_out_2c_W_2;
end

assign SINOUT = dds_out_2c_W_DSB;
assign SINOUT_DDS1 = dds_out_2c_W_1;
assign SINOUT_DDS2 = dds_out_2c_W_2;

endmodule

5.4 DSB RTL结构

这里写图片描述
图5. 3 DSB RTL结构
这里写图片描述
图5. 4 DDS RTL结构

5.5 Modelsim仿真

(1)testbench.v测试文件

`timescale 1ns/1ns
module testbench();
    wire W_clk,W_rst;
    wire signed [20:0] W_sin_out;
    wire signed [9:0] W_sin_dds1;
    wire signed [9:0] W_sin_dds2;

    initial begin
    #2_500_00 $stop();
    end
    gen_clk_rst U_gen_clk_rst(
        .O_CLK(W_clk),
        .O_RST(W_rst)
    );


    top_DSB_wave U_top_DSB_wave(
    .CLK     (  W_clk   )  ,   // clock, posedge valid
    .BUTRST  (  W_rst   )  ,   // reset button
    .SINOUT  (  W_sin_out   ),
    .SINOUT_DDS1(W_sin_dds1),
    .SINOUT_DDS2(W_sin_dds2)

    );  // DDS sine wave out, to DAC

    integer w_file_dds1;
        initial w_file_dds1 = $fopen("data_out_dds1.m");
        always @(W_sin_dds1)
            $fdisplay(w_file_dds1, "%d", W_sin_dds1);
    integer w_file_dds2;
        initial w_file_dds2 = $fopen("data_out_dds2.m");
        always @(W_sin_dds2)
            $fdisplay(w_file_dds2, "%d", W_sin_dds2);      

    integer w_file;
        initial w_file = $fopen("data_out_DSB.m");
        always @(W_sin_out)
            $fdisplay(w_file, "%d", W_sin_out);
endmodule
/////////////////////////////////////
module gen_clk_rst(
    O_CLK,
    O_RST
);
parameter CLK_PERIOD_HALF = 1;

output reg O_CLK;
output reg O_RST;

initial begin
    O_CLK   = 0;
    O_RST   = 0;
    # 100 O_RST = 1'b0;
    # 200 O_RST = 1'b1;
end

always begin 
    #CLK_PERIOD_HALF O_CLK = ~O_CLK;
end
endmodule

(2)仿真过程

仿真脚本文件和具体过程参考第四章

(3)仿真结果

这里写图片描述
图5. 5 modelsim仿真图像
图像中第一行为1MHz正弦信号,第二行1KHz正弦信号,第三行为DSB信号。

(4)Matlab分析Modelsim数据

  • 数据文件分别为data_out_dds1_file.m、data_out_dds2_file.m和data_out_DSB_file.m
  • 处理数据主程序check_modelsim_data.m
data_out_dds1_file;
data_out_dds2_file;
data_out_DSB_file;
signal_len1 = length(data_out_dds1);
signal_len2 = length(data_out_dds2);
signal_out = length(data_out_DSB);

cfftwinplot(data_out_dds1,50E6,'DDS1 MODELSIM OUTPUT SPECTRUM', 'red');
cfftwinplot(data_out_dds2,50E6,'DDS2 MODELSIM OUTPUT SPECTRUM', 'red');
cfftwinplot(data_out_DSB,50E6,'DSB MODELSIM OUTPUT SPECTRUM', 'red');
  • 绘频谱图程序cfftwinplot.m
% ********************************************************************************
% file      : cfftwinplot.m
% usuage    : complex signal spectrum plot
% author    : duweitao@cuc.edu.cn
% date      : 2007 Mar 5th
% version   : 0.1
% revise history
%   0.1 initial version
% ********************************************************************************

function cfftwinplot(data,fs,ttStr,color)
% function cfftwinplot(data,fs,ttStr,color)
% complex signal spectrum viewer
% data  : input data sequence
% fs    : sample rate
% ttStr : plot title string 
% color : Plot colors

dataLen     = length(data);
lenLog2     = floor(log2(dataLen)) ;
procLen     = 2 ^ lenLog2;
fftLen      = procLen;
fftLenMax   = 128*1024;
if(fftLen > fftLenMax)
  fftLen = fftLenMax;
end
winLen      = fftLen;

noverlap    = 0;
order       = 10;
win         = kaiser(winLen, order);

data = data(1:procLen);

[S,W] = pwelch (data, win, noverlap, fftLen);

lenS= length(S);
S   = S./max(S);
S   = 10*log10(S+1e-15);

% when data is a real signal, S ~ [0, pi]
% copy a symmetric spectrum
if(lenS == ceil((fftLen+1)/2) )
 S(lenS) = [];
 SRot = S;
 SRot = rot90(SRot);
 SRot = rot90(SRot);
 S = [SRot;S];
else
% data is complex signal, S ~[0~2pi]
 S   = fftshift(S);
end

N = fftLen;
xvals = linspace(-floor(fs/2), floor(fs/2)-floor((fs/N)), N);
figure;    
plot(xvals(1:N),S(1:N),color), grid on,axis([-floor(fs/2), floor(fs/2)-1,-150,20]);

xlabel('Frequency (Hz)');
ylabel('Magnitude (dB)');
title(ttStr);
end    

这里写图片描述
图5. 6 1MHz modelsim 频谱

这里写图片描述
图5. 7 1KHz modelsim频谱

这里写图片描述
图5. 8 DSB modelsim频谱
如图分别为modelsim仿真的1MHz载波、1KHz单音信号和调制后信号的频谱。

5.6 signaltap分析

这里写图片描述
图5. 9 signaltap抓取的1MHz、1KHz和DSB信号

(1)matlab分析signaltap数据

  • 数据放在signaltap_data.m文件中
  • 分析数据主程序check_board_data.m
signaltap_data;
signal_len1 = length(data_dds1);
cfftwinplot(data_dds1,5E6,'DDS1 OUTPUT SPECTRUM', 'red');

signal_len2 = length(data_dds2);
cfftwinplot(data_dds2,5E6,'DDS2 OUTPUT SPECTRUM', 'red');

signal_len2 = length(data_dds2);
cfftwinplot(data_dsb,5E6,'DSB OUTPUT SPECTRUM', 'red');
  • 绘图程序cfftwinplot()前文已写。
    这里写图片描述
    图5. 10 1MHz信号signaltap频谱
    这里写图片描述
    图5. 11 1KHz信号signaltap频谱
    这里写图片描述
    图5. 12 DSB信号signaltap频谱

(2)分析结果

signaltap容量过小,1KHz的信号采样不足一周期,频谱峰值落在0点左右,对结果影响较大。若在实际中对信号进行采样,需使用FIFO记录采样值,或直接使用DAC模块。


版权声明:本文为joyjun_1原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。