DDS任意波形发生器出现问题没有输出
代码如下
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没有输出信号
如图
可能是模型没有正确设置,请检查模型设置是否正确,确保DA_data信号有输出。
该回答引用ChatGPT
根据提供的代码,我们可以看到 DA_data 信号是由 lpm_mux1 模块输出的,因此需要检查 lpm_mux1 模块的实例化和连接是否正确。
另外,也需要检查时序是否正确。可能需要增加仿真时间或者调整时钟频率,确保 DA_data 有足够的时间输出。
亲,你这个问题看起来比较复杂,需要逐一排查,希望对你有帮助。
仅供参考:
如果编译没有报错,但是在仿真过程中某些信号没有输出,可能有几个原因:
1.检查你的仿真波形文件或者波形窗口的设置是否正确,确保你正在查看正确的信号。
2.如果你的模块存在多个时钟,确保所有时钟的相位和频率都正确。如果时钟有误,会导致数据在错误的时刻被采样,导致仿真输出不正确。
3.检查你的代码中是否有遗漏的信号连接,特别是在测试平台和测试bench中。如果某个信号没有正确连接,那么它的值可能永远不会被更新。
4.检查你的代码中是否存在死循环或死代码,这些代码可能会导致仿真无法进行。确保你的测试bench中有合适的终止条件,以避免死循环。
5.检查你的模块输入是否正确,并确保模块输出的信号与预期一致。如果你的模块有多个输入信号,确保所有输入信号都正确连接并在仿真开始前被初始化为预期值。
6.最后,如果以上步骤都无法解决问题,那么你可能需要更详细地检查你的代码并进行调试,例如使用verilog中的$display或$monitor语句,以了解信号在仿真过程中的状态。