DDS生成正弦波
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2018/09/28 13:43:40 // Design Name: // Module Name: DDS // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module DDS( input mclk, input rst_n, input [31:0]fword, //frequency control input [11:0]pword, //phase control output [9:0]da_data ); reg [31:0]r_fword; reg [11:0]r_pword; reg [31:0]fcnt = 0; wire [11:0]addr_rom; //信号存储到寄存器中 always @(posedge mclk) begin r_fword <= fword; r_pword <= pword; end
//累加器,r_fword值的大小决定了fcnt值增加的快慢,调节频率即是调节r_fword的值 always @(posedge mclk or negedge rst_n) begin if(!rst_n) fcnt <= 32'd0; else fcnt <= fcnt + r_fword; end
//fcnt高十位作为ROM的地址,r_pword为偏移相位值,本仿真中r_pword设置为0,即不做偏移 assign addr_rom = fcnt[31:20] + r_pword;
//给ROM时钟和地址,ROM即吐出数据 sin_rom sin_rom ( .clka(mclk), // input wire clka .addra(addr_rom), // input wire [11 : 0] addra .douta(da_data) // output wire [9 : 0] douta ); endmodule /* add_force {/DDS/mclk} -radix hex {1 0ns} {0 5000ps} -repeat_every 10000ps add_force {/DDS/rst_n} -radix hex {0 0ns} {1 200ns} add_force {/DDS/fword} -radix hex {00004000 0ns} add_force {/DDS/pword} -radix hex {0 0ns} */
仿真结果:
关于ROM时序分析:
通过以上分析,明显可以看出当ROM的地址更新后,数据在两个时钟周期内不会更新,而是第三个时钟上升沿到来的时候,ROM输出数据才会更新。