本人需要利用Vivado軟件中的DDS核生成一個正弦信號。由于后期還要生成線性調頻信號,如果直接編寫代碼生成比特流文件下載到板子上進行驗證會使工作的效率大大下降,所有想利用Vivado軟件功能仿真,這樣可以極大的提高效率。Vivado軟件自帶仿真功能,不需要對IP核進行特別的處理,所以很方便。
DDS核的基本原理,看以下一個鏈接: https://www.xilinx.com/support/documentation/ip_documentation/dds_compil.。。
此處對DDS核的配置如下:DDS核命名DDS_Signal
注意:上圖中紅色標記是更改的配置的參數,其他都默認設置。
生成DDS核后,自己利用Verilog寫了一個很簡單的測試平臺,頻率控制字配置好。
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2017/10/14 14:43:25
// Design Name:
// Module Name: Signal_DDS_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module Signal_DDS_tb(
);
parameter PERIOD=10;
reg CLK=0;
always begin
#(PERIOD/2) CLK=~CLK;
end
reg s_axis_phase_tvalid = 1‘d1;
reg [31:0] s_axis_phase_tdata = 32’d42949673;//此處是頻率控制字,生成1M的正余弦信號
wire m_axis_data_tvalid;
wire [31:0] m_axis_data_tdata;
DDS_Signal DDS_Signal_inst (
.aclk (CLK ), // input wire aclk
.s_axis_phase_tvalid (s_axis_phase_tvalid), // input wire s_axis_phase_tvalid
.s_axis_phase_tdata (s_axis_phase_tdata ), // input wire [31 : 0] s_axis_phase_tdata
.m_axis_data_tvalid (m_axis_data_tvalid ), // output wire m_axis_data_tvalid
.m_axis_data_tdata (m_axis_data_tdata ) // output wire [31 : 0] m_axis_data_tdata
);
endmodule
至此,認為任務完成,進行仿真。
仿真結果如下:
輸出的結果m_axis_data_tdata[31:0]的沒有數據。
開始查找原因,抓取DDS核的輸入是否正確即s_axis_phase_tvalid和s_axis_phase_tdata是否正確,抓取的結果如下:
上圖的中DDS核的輸入不是綠色,而是橙色(目前還不知道橙色是什么,需要查資料)說明有問題,DDS核的輸入沒有拿到數據。
剛開始認為是IP庫哪里沒有配置對,于是決定下載到項目組正在調試的板子上進行驗證程序是否有問題,將沒有改動的代碼下載到板子上進行調試,發現結果是正確的。
詢問了單位中資歷老師父也不知道為什么會出現這個問題。
后來發現DDS核有自己的testbench文件
于是利用它的測試平臺去測試這個IP。
--------------------------------------------------------------------------------
-- (c) Copyright 2010 - 2013 Xilinx, Inc. All rights reserved.
--
-- This file contains confidential and proprietary information
-- of Xilinx, Inc. and is protected under U.S. and
-- international copyright and other intellectual property
-- laws.
--
-- DISCLAIMER
-- This disclaimer is not a license and does not grant any
-- rights to the materials distributed herewith. Except as
-- otherwise provided in a valid license issued to you by
-- Xilinx, and to the maximum extent permitted by applicable
-- law: (1) THESE MATERIALS ARE MADE AVAILABLE “AS IS” AND
-- WITH ALL FAULTS, AND XILINX HEREBY DISCLAIMS ALL WARRANTIES
-- AND CONDITIONS, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
-- BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-
-- INFRINGEMENT, OR FITNESS FOR ANY PARTICULAR PURPOSE; and
-- (2) Xilinx shall not be liable (whether in contract or tort,
-- including negligence, or under any other theory of
-- liability) for any loss or damage of any kind or nature
-- related to, arising under or in connection with these
-- materials, including for any direct, or any indirect,
-- special, incidental, or consequential loss or damage
-- (including loss of data, profits, goodwill, or any type of
-- loss or damage suffered as a result of any action brought
-- by a third party) even if such damage or loss was
-- reasonably foreseeable or Xilinx had been advised of the
-- possibility of the same.
--
-- CRITICAL APPLICATIONS
-- Xilinx products are not designed or intended to be fail-
-- safe, or for use in any application requiring fail-safe
-- performance, such as life-support or safety devices or
-- systems, Class III medical devices, nuclear facilities,
-- applications related to the deployment of airbags, or any
-- other applications that could lead to death, personal
-- injury, or severe property or environmental damage
-- (individually and collectively, “Critical
-- Applications”)。 Customer assumes the sole risk and
-- liability of any use of Xilinx products in Critical
-- Applications, subject only to applicable laws and
-- regulations governing limitations on product liability.
--
-- THIS COPYRIGHT NOTICE AND DISCLAIMER MUST BE RETAINED AS
-- PART OF THIS FILE AT ALL TIMES.
--------------------------------------------------------------------------------
-- Description:
-- This is an example testbench for the DDS Compiler IP core.
-- The testbench has been generated by Vivado to accompany the IP core
-- instance you have generated.
--
-- This testbench is for demonstration purposes only. See note below for
-- instructions on how to use it with your core.
--
-- See the DDS Compiler product guide for further information
-- about this core.
--
--------------------------------------------------------------------------------
-- Using this testbench
--
-- This testbench instantiates your generated DDS Compiler core
-- instance named “DDS_Signal”。
--
-- Use Vivado‘s Run Simulation flow to run this testbench. See the Vivado
-- documentation for details.
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
entity tb_DDS_Signal is
end tb_DDS_Signal;
architecture tb of tb_DDS_Signal is
-----------------------------------------------------------------------
-- Timing constants
-----------------------------------------------------------------------
constant CLOCK_PERIOD : time := 100 ns;
constant T_HOLD : time := 10 ns;
constant T_STROBE : time := CLOCK_PERIOD - (1 ns);
-----------------------------------------------------------------------
-- DUT input signals
-----------------------------------------------------------------------
-- General inputs
signal aclk : std_logic := ’0‘; -- the master clock
-- Phase slave channel signals
signal s_axis_phase_tvalid : std_logic := ’0‘; -- payload is valid
signal s_axis_phase_tdata : std_logic_vector(31 downto 0) := (others =》 ’0‘); -- data payload
-- Data master channel signals
signal m_axis_data_tvalid : std_logic := ’0‘; -- payload is valid
signal m_axis_data_tdata : std_logic_vector(31 downto 0) := (others =》 ’0‘); -- data payload
-----------------------------------------------------------------------
-- Aliases for AXI channel TDATA and TUSER fields
-- These are a convenience for viewing data in a simulator waveform viewer.
-- If using ModelSim or Questa, add “-voptargs=+acc=n” to the vsim command
-- to prevent the simulator optimizing away these signals.
-----------------------------------------------------------------------
-- Phase slave channel alias signals
signal s_axis_phase_tdata_inc : std_logic_vector(31 downto 0) := (others =》 ’0‘);
-- Data master channel alias signals
signal m_axis_data_tdata_cosine : std_logic_vector(15 downto 0) := (others =》 ’0‘);
signal m_axis_data_tdata_sine : std_logic_vector(15 downto 0) := (others =》 ’0‘);
signal end_of_simulation : boolean := false;
begin
-----------------------------------------------------------------------
-- Instantiate the DUT
-----------------------------------------------------------------------
dut : entity work.DDS_Signal
port map (
aclk =》 aclk
,s_axis_phase_tvalid =》 s_axis_phase_tvalid
,s_axis_phase_tdata =》 s_axis_phase_tdata
,m_axis_data_tvalid =》 m_axis_data_tvalid
,m_axis_data_tdata =》 m_axis_data_tdata
);
-----------------------------------------------------------------------
-- Generate clock
-----------------------------------------------------------------------
clock_gen : process
begin
aclk 《= ’0‘;
if (end_of_simulation) then
wait;
else
wait for CLOCK_PERIOD;
loop
aclk 《= ’0‘;
wait for CLOCK_PERIOD/2;
aclk 《= ’1‘;
wait for CLOCK_PERIOD/2;
end loop;
end if;
end process clock_gen;
-----------------------------------------------------------------------
-- Generate inputs
-----------------------------------------------------------------------
stimuli : process
begin
-- Drive inputs T_HOLD time after rising edge of clock
wait until rising_edge(aclk);
wait for T_HOLD;
-- Input a constant phase increment each cycle, and run for long enough to produce 5 periods of outputs
for cycle in 0 to 159 loop
s_axis_phase_tvalid 《= ’1‘;
s_axis_phase_tdata 《= (others =》 ’0‘); -- set unused TDATA bits to zero
s_axis_phase_tdata(31 downto 0) 《= “00000010100011110101110000101001”; -- constant phase increment//頻率控制字,需要改動的參數,原來為全為0
wait for CLOCK_PERIOD;
end loop;
s_axis_phase_tvalid 《= ’0‘;
-- End of test
end_of_simulation 《= true;
report “Not a real failure. Simulation finished successfully. Test completed successfully” severity failure;
wait;
end process stimuli;
-----------------------------------------------------------------------
-- Check outputs
-----------------------------------------------------------------------
check_outputs : process
variable check_ok : boolean := true;
begin
-- Check outputs T_STROBE time after rising edge of clock
wait until rising_edge(aclk);
wait for T_STROBE;
-- Do not check the output payload values, as this requires the behavioral model
-- which would make this demonstration testbench unwieldy.
-- Instead, check the protocol of the data master channel:
-- check that the payload is valid (not X) when TVALID is high
if m_axis_data_tvalid = ’1‘ then
if is_x(m_axis_data_tdata) then
report “ERROR: m_axis_data_tdata is invalid when m_axis_data_tvalid is high” severity error;
check_ok := false;
end if;
end if;
assert check_ok
report “ERROR: terminating test with failures.” severity failure;
end process check_outputs;
-----------------------------------------------------------------------
-- Assign TDATA fields to aliases, for easy simulator waveform viewing
-----------------------------------------------------------------------
-- Phase slave channel alias signals
s_axis_phase_tdata_inc 《= s_axis_phase_tdata(31 downto 0);
-- Data master channel alias signals: update these only when they are valid
m_axis_data_tdata_cosine 《= m_axis_data_tdata(15 downto 0) when m_axis_data_tvalid = ’1‘;
m_axis_data_tdata_sine 《= m_axis_data_tdata(31 downto 16) when m_axis_data_tvalid = ’1‘;
end tb;
利用軟件給的測試平臺仿真如下:
發現用他的仿真平臺是正確的,通過對比發現,模板的仿真平臺的valid信號是在仿真后有數個clock才有效。于是自己修改自己的測試平臺,加入一個rst信號,讓仿真運行起來后10clock后在進行工作。修改后的測試平臺代碼如下:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2017/10/14 14:43:25
// Design Name:
// Module Name: Signal_DDS_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module Signal_DDS_tb(
);
parameter PERIOD=10;
reg CLK=0;
always begin
#(PERIOD/2) CLK=~CLK;
end
reg rst=1’d1;
reg [4:0] rst_cnt = 4‘d0;
always @ (posedge CLK)
begin
if(rst_cnt《= 4’d9)begin
rst_cnt 《= rst_cnt +1‘d1;
end
else begin
rst_cnt 《= rst_cnt;
end
end
always @ (posedge CLK)
begin
if(rst_cnt==10)begin
rst 《= 1’d0;
end
else begin
rst 《= rst;
end
end
reg s_axis_phase_tvalid = 1‘d0;
reg [31:0] s_axis_phase_tdata = 32’d0;
wire m_axis_data_tvalid;
wire [31:0] m_axis_data_tdata;
always @ (posedge CLK)
begin
if(rst == 0)begin
s_axis_phase_tvalid 《= 1‘d1;
s_axis_phase_tdata 《= 32’d42949673;
end
else begin
s_axis_phase_tvalid 《= 1‘d0;
s_axis_phase_tdata 《= 32’d0;
end
end
DDS_Signal DDS_Signal_inst (
.aclk (CLK ), // input wire aclk
.s_axis_phase_tvalid (s_axis_phase_tvalid ), // input wire s_axis_phase_tvalid
.s_axis_phase_tdata (s_axis_phase_tdata ), // input wire [31 : 0] s_axis_phase_tdata
.m_axis_data_tvalid (m_axis_data_tvalid ), // output wire m_axis_data_tvalid
.m_axis_data_tdata (m_axis_data_tdata ) // output wire [31 : 0] m_axis_data_tdata
);
endmodule
修改代碼后仿真的結果:
至此,找到問題原因。得出結論:現在仿真軟件做的都盡可能的接近實際情況,在實際的電路中IP核要正常工作需要消耗一定的clock,所以以后在對IP進行仿真時需要加入rst信號即要仿真運行數個clock后再對IP核進行操作。
評論
查看更多