`timescale1ns/1ps
//////////////////////////////////////////////////////////////////////////////////
//Two sine wave outputs -10V ~ +10V
//////////////////////////////////////////////////////////////////////////////////
module ad9767_test
(
input sys_clk,//  input clock  50Mhz
output da1_clk,//AD9767 CH1 clock
output da1_wrt,//AD9767 CH1 enable
output[13:0] da1_data,//AD9767 CH1 data output
output da2_clk,//AD9767 CH2 clock
output da2_wrt,//AD9767 CH2 enable
output[13:0] da2_data      //AD9767 CH2 data output
);
reg[9:0] rom_addr;
wire[13:0] rom_data;
wire clk_125M;
assign da1_clk=clk_125M;
assign da1_wrt=clk_125M;
assign da1_data=rom_data;
assign da2_clk=clk_125M;
assign da2_wrt=clk_125M;
assign da2_data=rom_data;
//DA output sin waveform
always@(negedge clk_125M)
begin
rom_addr <= rom_addr +1'b1;//The output sine wave frequency is 122Khz
// rom_addr <= rom_addr + 4 ;              //The output sine wave frequency is 488Khz
// rom_addr <= rom_addr + 128 ;            //The output sine wave frequency is 15.6Mhz
end
ROM ROM_inst
(
.clka(clk_125M),// input clka
.addra(rom_addr),// input [8 : 0] addra
.douta(rom_data)// output [7 : 0] douta
);
PLL PLL_inst
(// Clock in ports
.clk_in1    (sys_clk        ),// IN
// Clock out ports
.clk_out1   (),// OUT
.clk_out2   (clk_125M       ),// OUT
// Status and control signals
.reset      (1'b0),// IN
.locked     ()
);
endmodule
为了编写一个测试基准(testbench)来验证 AD9767 的输出正弦波的功能,我们需要创建一个模块,该模块将模拟输入时钟并驱动 ad9767_test 模块。测试基准将生成一个时钟信号,模拟外部输入,并观察 AD9767 的输出信号。
以下是一个简单的测试基准代码示例,它将为 ad9767_test 模块提供输入信号,并监视其输出:
`timescale 1ns/1ps
//////////////////////////////////////////////////////////////////////////////////
// Testbench for AD9767 Test Module
//////////////////////////////////////////////////////////////////////////////////
module ad9767_testbench;
    // Parameters
    parameter SYS_CLK_PERIOD = 20; // 50MHz clock period (20ns)
    parameter SIM_DURATION = 1000000; // Simulation duration in ns (1ms)
    // Signals
    reg sys_clk; // Input clock
    wire da1_clk; // AD9767 CH1 clock
    wire da1_wrt; // AD9767 CH1 enable
    wire [13:0] da1_data; // AD9767 CH1 data output
    wire da2_clk; // AD9767 CH2 clock
    wire da2_wrt; // AD9767 CH2 enable
    wire [13:0] da2_data; // AD9767 CH2 data output
    // Instantiate the DUT (Device Under Test)
    ad9767_test dut (
        .sys_clk(sys_clk),
        .da1_clk(da1_clk),
        .da1_wrt(da1_wrt),
        .da1_data(da1_data),
        .da2_clk(da2_clk),
        .da2_wrt(da2_wrt),
        .da2_data(da2_data)
    );
    // Clock generation for sys_clk
    initial begin
        sys_clk = 0;
        forever #(SYS_CLK_PERIOD / 2) sys_clk = ~sys_clk; // Toggle clock every 10ns
    end
    // Monitor outputs
    initial begin
        // Open a VCD file to visualize the signals
        $dumpfile("ad9767_testbench.vcd");
        $dumpvars(0, ad9767_testbench);
        // Wait for a certain duration and then finish the simulation
        #(SIM_DURATION);
        $finish;
    end
    // Monitor the outputs
    initial begin
        $monitor("Time: %0dns | da1_clk: %b | da1_wrt: %b | da1_data: %h | da2_clk: %b | da2_wrt: %b | da2_data: %h",
                 $time, da1_clk, da1_wrt, da1_data, da2_clk, da2_wrt, da2_data);
    end
endmodule
时钟生成:
sys_clk 信号模拟 50MHz 的输入时钟。时钟周期为 20ns,因此在 initial 块中使用 forever 循环每 10ns 切换一次 sys_clk。实例化 DUT:
ad9767_test 模块的实例 dut,将 sys_clk 连接到输入信号,并将输出信号连接到测试基准的相应信号。输出监视:
$monitor 语句监视输出信号的变化,并在每次输出变化时打印当前时间和信号值。波形输出:
$dumpfile 和 $dumpvars 生成 VCD 文件,以便后续使用波形查看工具(如 GTKWave)可视化信号。仿真时间控制:
#(SIM_DURATION) 指定仿真持续时间(在此例中为 1ms),然后调用 $finish 来结束仿真。在支持 Verilog 的仿真器中(如 ModelSim、Vivado Simulator 或其他),编译并运行上述测试基准代码。您可以使用波形查看工具查看生成的 VCD 文件,观察 da1_data 和 da2_data 的输出是否符合预期的正弦波形。
ROM 模块和 PLL 模块的实现正确,并且能够生成适当的正弦波数据。希望这个测试基准能帮助您验证 AD9767 的功能。如果您有特定的需求或问题,请随时询问!