DDS信号发生器出问题

DDS任意波形发生器出现问题没有输出
代码如下

  1. 总图

img

2.各部分代码 1.消抖模块

module key_debounce (   
    input  wire     clk,     //系统时钟 50MHz
    input  wire     rst_n,   //复位信号
    input  wire     key,     //按键输入信号
    output reg      key_done //消抖之后的按键信号
);

reg                 key_r0;  //同步信号(滤波作用,滤除小于一个周期的抖动)
reg                 key_r1;  //打拍
reg                 flag;    //标志位
wire                nedge;   //下降沿检测(检测到下降沿代表开始抖动)

//计时器定义
reg [19:0]          cnt;
wire                add_cnt;  //计时器开启
wire                end_cnt;  //计时记满

parameter           MAX_CNT=20'd1_000_000;  //20ms延时

//同步
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        key_r0<=1'b1;
    end
    else
        key_r0<=key;
end

//打拍
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        key_r1<=1'b1;    
    end
    else
        key_r1<=key_r0;
end

assign nedge = ~key_r0 & key_r1;  //检测到下降沿拉高

//标志位
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        flag<=1'b0; 
    end
    else if (nedge) begin
        flag<=1'b1; 
    end
    else if (end_cnt) begin
        flag<=1'b0;
    end
end

//延时模块
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cnt<=20'b0;
    end
    else if (add_cnt) begin
        if (end_cnt) begin
            cnt<=20'b0;
        end
        else
            cnt<=cnt+1;
    end
end

assign add_cnt=flag;                    //计时器开启
assign end_cnt=add_cnt&&cnt==MAX_CNT-1; //计时器关闭

//key_done输出
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        key_done<=1'b0; 
    end
    else if (end_cnt) begin            //延时满20ms采样
        key_done<=~key_r0;
    end
    else
        key_done<=1'b0;
end

endmodule //key_debounce

3.频率控制字和相位控制字改变模块

module Fre_counter(adder,minus,out,reset);

output out;
input adder,minus,reset;
parameter Leopard=32'd858993; //在50MHz时钟信号下,按一次+-10kHZ

reg [31:0]cnt;
wire [31:0] out ;

always@(negedge adder or negedge minus or negedge reset )
if(!reset)
cnt<=32'd858993;
else
if(!adder)
begin
cnt <= cnt + Leopard;
end
else if (!minus)
begin
cnt <= cnt - Leopard;
end
else if(!(!minus || !adder))
cnt<=cnt;
assign out =cnt ;

endmodule

相位控制字

module Ph_counter(plus,out,rst_n);
input [1:0]plus;
output out;
input rst_n;

parameter pharse=1024;

reg[10:0] cnt;
wire [10:0]out;

always@(negedge plus or negedge rst_n)
if(!rst_n)
cnt <= 1024;
else if(!plus)
begin
cnt <= cnt + pharse;
end
else if(!(!plus))
begin
cnt <= cnt;
end

assign out = cnt;

endmodule

4.相位累加器模块

module acc(
clk,
rst_n,
Fword,
Pword,
rom_adder);

input clk,rst_n;
input [31:0]Fword;
input [10:0]Pword;
output [9:0]rom_adder;

reg [31:0] r_Fword,F_counter;
reg [10:0] r_Pword;

wire [10:0]rom_adder;

always@(posedge clk)
begin
r_Fword <= Fword;
r_Pword <= Pword;
end

always @(posedge clk or negedge rst_n)
if(!rst_n)
  F_counter <=32'd0;
  else
  F_counter <= F_counter + r_Fword;
  
  assign rom_adder = F_counter [31:21] + r_Pword; 
  
  endmodule

5.个个波形的rom,rom是没问题的
6.数据选择器

// megafunction wizard: %LPM_MUX%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: LPM_MUX 

// ============================================================
// File Name: lpm_mux1.v
// Megafunction Name(s):
//             LPM_MUX
//
// Simulation Library Files(s):
//             lpm
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 13.1.0 Build 162 10/23/2013 SJ Full Version
// ************************************************************


//Copyright (C) 1991-2013 Altera Corporation
//Your use of Altera Corporation's design tools, logic functions 
//and other software and tools, and its AMPP partner logic 
//functions, and any output files from any of the foregoing 
//(including device programming or simulation files), and any 
//associated documentation or information are expressly subject 
//to the terms and conditions of the Altera Program License 
//Subscription Agreement, Altera MegaCore Function License 
//Agreement, or other applicable license agreement, including, 
//without limitation, that your use is for the sole purpose of 
//programming logic devices manufactured by Altera and sold by 
//Altera or its authorized distributors.  Please refer to the 
//applicable agreement for further details.


// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module lpm_mux1 (
    data0x,
    data1x,
    data2x,
    data3x,
    sel,
    result);

    input    [9:0]  data0x;
    input    [9:0]  data1x;
    input    [9:0]  data2x;
    input    [9:0]  data3x;
    input    [1:0]  sel;
    output    [9:0]  result;

    wire [9:0] sub_wire0;
    wire [9:0] sub_wire5 = data3x[9:0];
    wire [9:0] sub_wire4 = data2x[9:0];
    wire [9:0] sub_wire3 = data1x[9:0];
    wire [9:0] result = sub_wire0[9:0];
    wire [9:0] sub_wire1 = data0x[9:0];
    wire [39:0] sub_wire2 = {sub_wire5, sub_wire4, sub_wire3, sub_wire1};

    lpm_mux    LPM_MUX_component (
                .data (sub_wire2),
                .sel (sel),
                .result (sub_wire0)
                // synopsys translate_off
                ,
                .aclr (),
                .clken (),
                .clock ()
                // synopsys translate_on
                );
    defparam
        LPM_MUX_component.lpm_size = 4,
        LPM_MUX_component.lpm_type = "LPM_MUX",
        LPM_MUX_component.lpm_width = 10,
        LPM_MUX_component.lpm_widths = 2;


endmodule

// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: new_diagram STRING "1"
// Retrieval info: LIBRARY: lpm lpm.lpm_components.all
// Retrieval info: CONSTANT: LPM_SIZE NUMERIC "4"
// Retrieval info: CONSTANT: LPM_TYPE STRING "LPM_MUX"
// Retrieval info: CONSTANT: LPM_WIDTH NUMERIC "10"
// Retrieval info: CONSTANT: LPM_WIDTHS NUMERIC "2"
// Retrieval info: USED_PORT: data0x 0 0 10 0 INPUT NODEFVAL "data0x[9..0]"
// Retrieval info: USED_PORT: data1x 0 0 10 0 INPUT NODEFVAL "data1x[9..0]"
// Retrieval info: USED_PORT: data2x 0 0 10 0 INPUT NODEFVAL "data2x[9..0]"
// Retrieval info: USED_PORT: data3x 0 0 10 0 INPUT NODEFVAL "data3x[9..0]"
// Retrieval info: USED_PORT: result 0 0 10 0 OUTPUT NODEFVAL "result[9..0]"
// Retrieval info: USED_PORT: sel 0 0 2 0 INPUT NODEFVAL "sel[1..0]"
// Retrieval info: CONNECT: @data 0 0 10 0 data0x 0 0 10 0
// Retrieval info: CONNECT: @data 0 0 10 10 data1x 0 0 10 0
// Retrieval info: CONNECT: @data 0 0 10 20 data2x 0 0 10 0
// Retrieval info: CONNECT: @data 0 0 10 30 data3x 0 0 10 0
// Retrieval info: CONNECT: @sel 0 0 2 0 sel 0 0 2 0
// Retrieval info: CONNECT: result 0 0 10 0 @result 0 0 10 0
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mux1.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mux1.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mux1.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mux1.bsf TRUE FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mux1_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL lpm_mux1_bb.v TRUE
// Retrieval info: LIB_FILE: lpm


7.顶层模块

module DDS_Final(
clk,
rst_n,
minus,adder,plus,sel,
DA_data);

input clk,rst_n;
//input [31:0]Fword;
//input [10:0]Pword;
output [9:0] DA_data;
input minus,adder,plus;
input [1:0]sel;


wire [10:0]rom_adder1,Pword;
wire [9:0] sin,saw,squ,sanjiao;
wire [31:0] Fword;
wire minus0,adder0,plus0;

key_debounce u_debo_plus(
.clk(clk),
.rst_n(rst_n),
.key(plus),
.key_done(plus0));

Ph_counter u_Pcounter(
.plus(plus0),
.rst_n(rst_n),
.out(Pword));

key_debounce u_debo_add(
.clk(clk),
.rst_n(rst_n),
.key(adder),
.key_done(adder0));

key_debounce u_debo_min(
.clk(clk),
.rst_n(rst_n),
.key(minus),
.key_done(minus0));


Fre_counter u_Fre_counter(
.adder(adder0),
.minus(minus0),
.reset(rst_n),
.out(Fword));

acc inst_acc(
.clk(clk),
.Fword(Fword),
.Pword(Pword),
.rst_n(rst_n),
.rom_adder(rom_adder1));

  rom u_romsin
  (.address(rom_adder1),
  .clock(clk),
  .q(sin));
  
  rom_tri u_rom_tri(
  .address(rom_adder1),
  .clock(clk),
  .q(sanjiao));
  
  rom_saw u_rom_saw(
  .address(rom_adder1),
  .clock(clk),
  .q(saw));
  
  rom_squ u_rom_squ(
  .address(rom_adder1),
  .clock(clk),
  .q(squ));
  
  lpm_mux1 inst_mux1(
   .data0x(squ),
    .data1x(sin),
    .data2x(saw),
    .data3x(sanjiao),
    .sel(sel),
    .result(DA_data));
  

  
endmodule


8.tb文件

`timescale 1ns/1ns

module DDS_Final_tb;
reg clk;
reg rst_n;
reg [1:0] add,min,plu;
reg [1:0] sel;
wire [9:0] DA_data;

DDS_Final uDDS (
.clk(clk),
.rst_n(rst_n),
.adder(add),
.minus(min),
.plus(plu),
.DA_data(DA_data));

initial clk = 1;
always #10 clk =~clk; //50M的时钟信号

initial begin
rst_n = 0;
add=1;
min=1;
plu=1;
sel = 2'b00;
#201;
rst_n=1;
#5000
sel = 2'b01;
end

endmodule

编译都没有报错,就是modelsim仿真的时候DA_data没有输出信号
如图

img

可能是模型没有正确设置,请检查模型设置是否正确,确保DA_data信号有输出。

该回答引用ChatGPT

根据提供的代码,我们可以看到 DA_data 信号是由 lpm_mux1 模块输出的,因此需要检查 lpm_mux1 模块的实例化和连接是否正确。

另外,也需要检查时序是否正确。可能需要增加仿真时间或者调整时钟频率,确保 DA_data 有足够的时间输出。

亲,你这个问题看起来比较复杂,需要逐一排查,希望对你有帮助。

  1. 首先,我注意到你提供的两个图片是在modelsim中打开的,那么是否能够在modelsim中找到DA_data信号的波形,检查一下该信号是否被正确赋值?
  2. 如果DA_data信号没有赋值,那么问题可能出在你的ROM模块上。你可以检查你的ROM模块,看看是否在正确的位置输出数据。
  3. 另外,我注意到你在代码中使用了很多的异步边沿触发模块,这可能会引入很多的时序问题。你可以考虑使用同步边沿触发模块,以避免时序问题。此外,如果你在设计时没有考虑到时序问题,那么可能需要对你的设计进行一些修改。
  4. 最后,我建议你仔细检查下每个模块的输出,以确定每个模块是否按照预期工作。你可以使用仿真器中的信号探针来检查每个模块的输出。

仅供参考:
如果编译没有报错,但是在仿真过程中某些信号没有输出,可能有几个原因:

1.检查你的仿真波形文件或者波形窗口的设置是否正确,确保你正在查看正确的信号。

2.如果你的模块存在多个时钟,确保所有时钟的相位和频率都正确。如果时钟有误,会导致数据在错误的时刻被采样,导致仿真输出不正确。

3.检查你的代码中是否有遗漏的信号连接,特别是在测试平台和测试bench中。如果某个信号没有正确连接,那么它的值可能永远不会被更新。

4.检查你的代码中是否存在死循环或死代码,这些代码可能会导致仿真无法进行。确保你的测试bench中有合适的终止条件,以避免死循环。

5.检查你的模块输入是否正确,并确保模块输出的信号与预期一致。如果你的模块有多个输入信号,确保所有输入信号都正确连接并在仿真开始前被初始化为预期值。

6.最后,如果以上步骤都无法解决问题,那么你可能需要更详细地检查你的代码并进行调试,例如使用verilog中的$display或$monitor语句,以了解信号在仿真过程中的状态。

https://www.baidu.com/link?url=6F4FILQRfQQ_7jLQsKpfnMo0PmtMYrFJ3Oxytu5l1jLxyZ7zwqQklPYJdDeTB-ZlTV-FoUETHVSUlNdsLcE2yMMPx1gQo8apnNCgvgM6tKG&wd=&eqid=bac4f0a90012cd1b0000000663f32168