DDS的verilog实现(波形切换、幅度控制、相位控制、频率控制)

1、端口变量声明

module DDS(
input   wire         clk,
input   wire         rst_n,
input   wire         key_f,
input   wire         key_s,
input   wire         key_p,
output  wire [16:0]  wave_data);
parameter 			SINE 	= 4'b0001;
parameter 			FANGBO  = 4'b0010;
parameter 			SANJIAO = 4'b0100;
parameter 			JUCHI   = 4'b1000;reg  		[15:0]  AM_ctrl='d400;   //控制幅度的参数
reg  		[31:0]  phase_ctrl=429496729/500000;//控制频率的步进
reg  		[31:0]  phase_data; //用于控制当前波形频率,受到按键key_f控制
reg 		[6:0] 	M ;     //用于控制占空比,受到按键key_p控制
reg  		[3:0]   state; //四个状态切换,受按键key_s控制
reg  		[31:0]  phase_data_1;
reg  				key_f_n;
reg  				key_s_n;
reg  				key_p_n;
reg 		[31:0]  cnt;
reg 		[31:0]  cnt_1;
reg  				phase_valid =1;
reg  		[15:0]  sine_buchang='d32766;
reg 		[15:0]  fangbo_data; //方波信号
wire signed [15:0]  sine_data_signed; 
wire 		[15:0]  sine_data;     //正弦波
wire  		[15:0]  sanjiao_data;  //三角波
wire 		[15:0]  juchi_data;    //锯齿波
wire                data_valid;
wire  				s_axis_divisor_tvalid= 'd1;
wire  				s_axis_dividend_tvalid= 'd1;
wire  				m_axis_dout_tvalid;
wire  		[63:0]  zhankong_ctrl;
wire  		[31:0]  zhankong=42949673;
wire		[63:0]  zhangkong_ctrl_n;
wire 		[32:0]  fuzhi;
wire 		[16:0]  fuzhi_data=AM_ctrl+16'd1;

2、打拍操作,用于识别按键按下状态

always @(posedge clk ) beginkey_f_n<=key_f;
endalways @(posedge clk ) beginkey_s_n<=key_s;
endalways @(posedge clk ) beginkey_p_n<=key_p;
end

3、按键按下,频率增加一个phase_ctrl

always @(posedge clk or negedge rst_n) beginif (!rst_n) beginphase_data <= phase_ctrl;endelse if (key_f=='d1 && key_f_n=='d0) beginphase_data <= phase_data+ phase_ctrl;endelse beginphase_data <=phase_data;end
end

4、根据当前phase_data生成指定频率的锯齿波和三角波

always @(posedge clk or negedge rst_n) beginif (!rst_n) beginphase_data_1 <=0;endelse beginphase_data_1 <=phase_data_1+phase_data;end
endassign sanjiao_data = phase_data_1[31]? (~phase_data_1[30:15]): phase_data_1[30:15]; //三角波assign juchi_data = phase_data_1[31:15]; //锯齿波

5、生成正弦波

dds_compiler_0 your_instance_name (.aclk(clk),                                .aclken(rst_n),                            .s_axis_phase_tvalid(phase_valid),  .s_axis_phase_tdata(phase_data),    .m_axis_data_tvalid(data_valid),    .m_axis_data_tdata(sine_data_signed)      
);assign sine_data = sine_data_signed+sine_buchang; //ip核产生的是有符号数,根据题目要求幅度范围,加一个补偿变成无符号数

6、生成占空比可调的方波

div_gen_0 div (   //除法是为了计算2的32次方除以100然后除以当前phase_data.aclk(clk),     //计算一下当前频率下,占空比百分之一需要经过几个clk                                   .s_axis_divisor_tvalid(s_axis_divisor_tvalid),    .s_axis_divisor_tdata(phase_data),     .s_axis_dividend_tvalid(s_axis_dividend_tvalid),  .s_axis_dividend_tdata(zhankong),      //2的32次方除以100.m_axis_dout_tvalid(m_axis_dout_tvalid),          .m_axis_dout_tdata(zhankong_ctrl)            
);always @(posedge clk or negedge rst_n) begin  //M=1  就是占空比为百分之一if (!rst_n) beginM <= 1;endelse if (key_p=='d1 && key_p_n=='d0) beginM<= M+1;endelse beginM <= M;end
endassign zhangkong_ctrl_n = zhankong_ctrl[63:32] *M;always @(posedge clk or negedge rst_n) beginif (!rst_n) begincnt<='d0;cnt_1<='d0;fangbo_data<=16'd0;endelse if (cnt_1==zhankong_ctrl[63:32] *100 || (key_f=='d1 && key_f_n=='d0) )begincnt_1<='d0;cnt<='d0;fangbo_data<=16'd0;endelse if (cnt==zhangkong_ctrl_n-1) begincnt<=cnt;cnt_1<=cnt_1+1;fangbo_data<=16'd0;endelse begincnt<=cnt+1;cnt_1<=cnt_1+1;fangbo_data<=16'd65535;end
end

7、选择波形

always @(posedge clk or negedge rst_n) beginif (!rst_n) beginstate<= SINE;endelse case (state)SINE:if (key_s=='d1 && key_s_n=='d0) beginstate <= FANGBO;endelse beginstate <=SINE;endFANGBO:if (key_s=='d1 && key_s_n=='d0) beginstate <=SANJIAO;endelse beginstate <=FANGBO;endSANJIAO:if (key_s=='d1 && key_s_n=='d0) beginstate <=JUCHI;endelse beginstate <=SANJIAO;endJUCHI:if (key_s=='d1 && key_s_n=='d0) beginstate <=SINE;endelse beginstate <=JUCHI;enddefault:state <=SINE;endcase
endreg [15:0] data_temp;always @(posedge clk or negedge rst_n) beginif (!rst_n) begindata_temp <= 'd0;endelse if (state == SINE) begindata_temp<=sine_data;endelse if (state == FANGBO) begindata_temp<=fangbo_data;endelse if (state == JUCHI) begindata_temp<=juchi_data;endelse if (state == SANJIAO) begindata_temp<=sanjiao_data;endelse begindata_temp <=sine_data;endend

8、幅度控制

mult_gen_0 chengfa (.CLK(clk),  // input wire CLK.A(data_temp),      // input wire [15 : 0] A.B(fuzhi_data),      // input wire [16 : 0] B.P(fuzhi)      // output wire [32 : 0] P
);

9、输出最终波形

assign wave_data =fuzhi[32:16];
endmodule

10、仿真结果图

本代码可作参考,里面用到了几个ip核,工程文件可以关注后私信。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部