重庆邮电大学本科毕业设计(论文)
设计的负担而且浪费资源,为了最大程度上的节约成本和设计时间,我们可以采取在rom中只取50个数据的办法,也就是一个周期取五十个数据,这样在工作频率为50M的情况下输出的载波频率正好为50/50=1,正好是我们所需要的波形。为了产生正交的第二个波形将第一个波形的地址稍微做下改动即可实现相位偏移90度。
编写DDS主程序,设置两个ROM,一个存放sin波形,一个存放cos波形。同时将相位累加器位宽设成16位,即N?16,频率字K位宽范围为0到16位,频率字随着CLK累加,即每个系统频率上升沿,频率字都会在相位累加器中累加
Nf?K?f/2oc一次。在DDS模块中,采用系统时钟10Mhz,由公式可知:但取频率字为K=32'b11001100110011001100110011001, fc=10MHZ, N=32时,可得到输出的正余弦波的频率为1MHz。对每一次的频率字累加值,即相位累加器累加结果截取高8位输出作为地址以查表的方法输出两路正交正弦波的二进制电平值。由公式f0?fcK/2N可知频率字越大,输出正弦载波频率越高,分辨率越低;频率字越小,输出正弦载波频率越低,分辨率越高。
图 3.3为正弦内存单元的原理图。
图 3.3 DDS正弦内存单元
对DDS模块进行编译仿真,进行功能仿真得仿真图 3.4。
图3.4 DDS仿真波形
由图3.3.4可以看出DDS模块在系统时钟为10M的情况下很好地输出了频率为1M,相位差为90?的正交载波。
- 16 -
重庆邮电大学本科毕业设计(论文)
两个PAM信号分别调制同相和正交载波,每一个调制器有4种可能的输出,经线性加法器合并产生16QAM信号。
DDS 和加法器模块源代码
//DDS 和加法器模块
module add(clk_dds, //输入信号时钟 rst, en,
data,
dataout,); //16QAM信号 input rst,en,clk_dds; input [3:0] data;
output signed[17:0] dataout; reg signed[16:0] csignal,ssignal;
wire signed [15:0] cosine; //cos值 wire signed [15:0] sine; //sin值
wire [31:0] addra; // DDS频率字 assign addra='b11001100110011001100110011001;
assign dataout= {csignal[16],csignal}+ {ssignal[16],ssignal}; always @ (posedge clk_dds or posedge rst) begin if(rst) begin
csignal <= 0; ssignal <= 0; end else begin
case(data) 4'b0000: begin //-2cos-2sin csignal[16:1] <= ~cosine[15:0]; csignal[0] <= 0; ssignal[16:1] <= ~sine[15:0]; ssignal[0] <= 0; end 4'b0001: begin // -2cos-sin csignal[16:1] <= ~cosine[15:0]; csignal[0] <= 0; ssignal[16] <= ~sine[15]; ssignal[15:0] <= ~sine[15:0]; end 4'b0010: begin // -2cos+2sin csignal[16:1] <= ~cosine[15:0];
- 17 -
重庆邮电大学本科毕业设计(论文)
csignal[0] <= 0; ssignal[16:1] <= sine[15:0]; ssignal[0] <= 0; end 4'b0011: begin // -2cos+sin csignal[16:1] <= ~cosine[15:0]; csignal[0] <= 0; ssignal[16] <= sine[15]; ssignal[15:0] <= sine[15:0]; end 4'b0100: begin // -cos-2sin csignal[16] <= ~cosine[15]; csignal[15:0] <= ~cosine[15:0]; ssignal[16:1] <= ~sine[15:0]; ssignal[0] <= 0; end
4'b0101: begin // -cos-sin csignal[16] <= ~cosine[15]; csignal[15:0] <= ~cosine[15:0]; ssignal[16] <= ~sine[15]; ssignal[15:0] <= ~sine[15:0]; end 4'b0110: begin// -cos+2sin csignal[16] <= ~cosine[15]; csignal[15:0] <= ~cosine[15:0]; ssignal[16:1] <= sine[15:0]; ssignal[0] <= 0; end 4'b0111: begin // -cos+sin csignal[16] <= ~cosine[15]; csignal[15:0] <= ~cosine[15:0]; ssignal[16] <= sine[15]; ssignal[15:0] <= sine[15:0]; end 4'b1000: begin // 2cos-2sin csignal[16:1] <= cosine[15:0]; csignal[0] <= 0; ssignal[16:1] <= ~sine[15:0]; ssignal[0] <= 0; end 4'b1001: begin // 2cos-sin csignal[16:1] <= cosine[15:0]; csignal[0] <= 0; ssignal[16:1] <= ~sine[15:0];
- 18 -
重庆邮电大学本科毕业设计(论文)
ssignal[0] <= 0; end 4'b1010: begin //2cos+2sin csignal[16:1] <= cosine[15:0]; csignal[0] <= 0; ssignal[16:1] <= sine[15:0]; ssignal[0] <= 0; end 4'b1011: begin // 2cos+sin csignal[16:1] <= cosine[15:0]; csignal[0] <= 0; ssignal[16] <= sine[15]; ssignal[15:0] <= sine[15:0]; end 4'b1100: begin // cos-2sin csignal[16] <= cosine[15]; csignal[15:0] <= cosine[15:0]; ssignal[16:1] <= ~sine[15:0]; ssignal[0] <= 0; end 4'b1101: begin // cos-sin csignal[16] <= cosine[15]; csignal[15:0] <= cosine[15:0]; ssignal[16] <= ~sine[15]; ssignal[15:0] <= ~sine[15:0]; end
4'b1110: begin // cos+2sin csignal[16] <= cosine[15]; csignal[15:0] <= cosine[15:0]; ssignal[16:1] <= sine[15:0]; ssignal[0] <= 0; end
4'b1111: begin // cos+sin csignal[16] <= cosine[15]; csignal[15:0] <= cosine[15:0]; ssignal[16] <= sine[15]; ssignal[15:0] <= sine[15:0]; end default: begin csignal <= 0; ssignal <= 0; end
- 19 -
重庆邮电大学本科毕业设计(论文)
endcase end end
dds ddsqam( .data(addra), .en(en), .reset(rst), .clk(clk_dds), .sine(sine), .cose(cosine) ); Endmodule
/////////////////////////////////////////////////////////////////
module dds(data, en, clk, reset, sine, cose); /// DDS模块 input [31 : 0] data; //频率控制字
input en; //频率控制字写使能 input clk; input reset;
output signed[15 : 0] sine; //正弦信号输出 output signed[15 : 0] cose; //余弦信号输出
reg [31 : 0] ADD_A; //正弦波产生模块的相位累加器 reg [31 : 0] ADD_B; //余弦波产生模块的相位累加器 reg signed [15 : 0] cose_DR; //余弦波的查找表地址 reg signed [15 : 0] sine_DR;
wire [31 : 0] data; //频率控制字 wire [9 : 0] ROM_A;
wire signed [15 : 0] cose_D; wire signed [15 : 0]sine_D; assign cose = cose_DR; assign sine = sine_DR;
assign ROM_A = ADD_B[31 : 22]; begin
if(reset) //系统初始化时,默认的频率控制字为0 ADD_A <= 0; else if(en)
ADD_A <= data; else
ADD_A <= ADD_A ; end
always @ (posedge clk or posedge reset) begin
if(reset)
- 20 -