五 单音信号对载波信号进行双边带幅度调制
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
endmodule5.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;
endmodule5.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版权协议,转载请附上原文出处链接和本声明。