Search code examples
vhdlxilinxvivado

XADC testbench vivado simulation - analog signal problems


I've finished my project that pass the data from XADC to other components once UART_RXD_PIN is set to "1". I'm using BASYS3 board for this project. And now its time to create testbench that simulate ANALOG signal and pass it to 4 different xadc's pins.

I've tried few examples out there (in the internet), however they are using VERILOG instead of VHDL and XADC isn't used as component like in my project. I've created "supermain.vhdl" in which top_main is component so vivado might simulate XADC for itself, however it doesnt work.

Here is my code:

entity top_main is
    Port (
        CLK              : IN  STD_LOGIC;   
        UART_TXD_pin     : IN  STD_LOGIC;
        UART_RXD_pin     : OUT STD_LOGIC
    );  
end top_main;

architecture Behavioral of top_main is

    -- COMPONENTS --
-- XADC --
COMPONENT XADC_block_input
PORT (
    di_in               : IN  STD_LOGIC_VECTOR(15 DOWNTO 0);
    daddr_in            : IN  STD_LOGIC_VECTOR(6 DOWNTO 0);
    den_in              : IN  STD_LOGIC;
    dwe_in              : IN  STD_LOGIC;
    drdy_out            : OUT STD_LOGIC;
    do_out              : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
    dclk_in             : IN  STD_LOGIC;
    vp_in               : IN  STD_LOGIC;
    vn_in               : IN  STD_LOGIC;
    reset_in            : IN  STD_LOGIC;
    ------------------------------------    
    vauxp6              : IN  STD_LOGIC;
    vauxn6              : IN  STD_LOGIC;
    vauxp7              : IN  STD_LOGIC;
    vauxn7              : IN  STD_LOGIC;
    vauxp14             : IN  STD_LOGIC;
    vauxn14             : IN  STD_LOGIC;
    vauxp15             : IN  STD_LOGIC;
    vauxn15             : IN  STD_LOGIC;
    ------------------------------------    
    channel_out         : OUT STD_LOGIC_VECTOR(4 DOWNTO 0);
    eoc_out             : OUT STD_LOGIC;
    alarm_out           : OUT STD_LOGIC;
    eos_out             : OUT STD_LOGIC;
    busy_out            : OUT STD_LOGIC
);
END COMPONENT;








type    pmod_addresses is array (0 to 3) of std_logic_vector(6 downto 0); 
constant adress_pmod        : pmod_addresses :=("0010110","0010111","0011110","0011111");   -- 6/7/14/15 -> PORTS XADC --
signal  DataValid           : STD_LOGIC;                                                    -- DATA IN VALID
signal  DataReady           : STD_LOGIC;                                                    -- DATA READY (FOR FFT)
signal  index               : INTEGER := 0;                                                 -- INDEX FOR ADC
signal  DataOut             : STD_LOGIC_VECTOR(15 DOWNTO 0);                                -- DATA ADC OUT
signal  nr_adc              : STD_LOGIC_VECTOR(6 downto 0) := adress_pmod(0);   

    -- PORT MAPS --
-- ADC --
XADC_PORT_MAP: XADC_block_input
PORT MAP (
    di_in       => X"0000",
    daddr_in    => nr_adc,
    den_in      => DataValid,
    dwe_in      => '0',
    drdy_out    => DataReady,
    do_out      => DataOut,
    dclk_in     => CLK_128MHz,
    vp_in       => '0',
    vn_in       => '0',
    reset_in    => MASTER_RESET, 
    ------------------------------------    
    vauxp6      => ADC_6P_J3,
    vauxn6      => ADC_6N_K3,
    vauxp7      => ADC_7P_M2,
    vauxn7      => ADC_7N_M1,
    vauxp14     => ADC_14P_L3,
    vauxn14     => ADC_14N_M3,
    vauxp15     => ADC_15P_N2,
    vauxn15     => ADC_15N_N1,
    ------------------------------------    
    channel_out => open,
    eoc_out     => DataValid,
    alarm_out   => open,
    eos_out     => open,
    busy_out    => open
);

-- ADC DATA FORWARDING --
p_XADC_PORT_ADDRESING: process(CLK_128MHz)
begin
    if(rising_edge(CLK_128MHz)) then
        if(DataReady = '1') then       
            case nr_adc is
                when adress_pmod(0) =>   
                    XADC_1_FIR_1 <= DataOut ;
                when adress_pmod(1) =>   
                    XADC_2_FIR_2 <= DataOut ;
                when adress_pmod(2) =>   
                    XADC_3_FIR_3 <= DataOut ;
                when adress_pmod(3) =>   
                    XADC_4_FIR_4 <= DataOut ;
                when others =>
                    XADC_1_FIR_1 <= (others=>'0'); 
                    XADC_2_FIR_2 <= (others=>'0'); 
                    XADC_3_FIR_3 <= (others=>'0'); 
                    XADC_4_FIR_4 <= (others=>'0'); 
                end case;
            if index = 0 then
                index <= 1;
            else 
                index <= 0;
            end if;
            nr_adc  <= adress_pmod(index);
        end if;
    end if;
end process p_XADC_PORT_ADDRESING;

And here is super main with just entity and testbench code.

entity supermain is
     Port (
    CLK              : IN  STD_LOGIC;    
    UART_TXD_pin     : IN  STD_LOGIC;
    UART_RXD_pin     : OUT STD_LOGIC
);

end supermain;

architecture Behavioral of supermain is

component top_main
    Port (
        CLK              : IN  STD_LOGIC;   
        UART_TXD_pin     : IN  STD_LOGIC;
        UART_RXD_pin     : OUT STD_LOGIC
    );  
end component;

begin

symulacja : top_main
  PORT MAP (
    CLK                 => CLK,
    UART_TXD_pin        => UART_TXD_pin,
    UART_RXD_pin        => UART_RXD_pin
    );  



    end Behavioral;


    entity supermain_tb is
end;

architecture bench of supermain_tb is

  component supermain
       Port (
      CLK              : IN  STD_LOGIC;    
      UART_TXD_pin     : IN  STD_LOGIC;
      UART_RXD_pin     : OUT STD_LOGIC
  );
  end component;

  signal CLK: STD_LOGIC;
  signal UART_TXD_pin: STD_LOGIC;
  signal UART_RXD_pin: STD_LOGIC ;

  constant clock_period: time := 1 ms;
  signal stop_the_clock: boolean;


begin

  uut: supermain port map ( CLK          => CLK,
                            UART_TXD_pin => UART_TXD_pin,
                            UART_RXD_pin => UART_RXD_pin );

  stimulus: process
  begin
   UART_TXD_pin <= '1' after 100 ns, '0' after 100 ns;
    -- Put initialisation code here


    -- Put test bench stimulus code here
    wait;
  end process;

  clocking: process
  begin
    while not stop_the_clock loop
      CLK <= '0', '1' after clock_period / 2;
      wait for clock_period;
    end loop;
    wait;
  end process;

end;

Could you please tell me how to simulate ANALOG signal in testbench? Because for now it doesn't even


Solution

  • To simulate the Analog input you need to use the Analog Stimulus file.

    In UG480 http://www.xilinx.com/support/documentation/user_guides/ug480_7Series_XADC.pdf there is an example including the Stimulus file and testbench.

    SIM_MONITOR_FILE => "design.txt" -- Analog simulation data file name

    You can also see an example of the stimulus file in the Vivado Language Templates Vivado Language Template