Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
9 years ago

Help needed in VHDL Testbench

Hi all,

I have written the testbench file in such a manner that I need to perform updowncounting and downcounting based on the value of dir_s. But the problem is, when I execute the code, the dir_s is incremented only for one value ie. when fmcw_ramp_o >= fmcw_bw_i and for all other values its zero. Because of this, Ì am getting this error "wrong output: addition should take place". I don't know how to solve this problem.

I know for sure that dir_s should be 1 till it reaches the condition. I need to know how dir_s will be 1 continuously till fmcw_ramp_o< fstep_i or = "0000". The code looks like this:

p_check_step: process(delayed_rst_s, clk_128meg_i)
 begin
   if (delayed_rst_s = '0') then
    dir_s <= '0';
    old_fmcw_ramp_s <= (others => '0');
   elsif (clk_128meg_i'event and clk_128meg_i = '0') then
     if (enable_i = '1' and fmcw_trig_i = '1') then
      if( dir_s = '0') then
        assert fmcw_ramp_o = std_logic_vector(unsigned(old_fmcw_ramp_s) + unsigned(fstep_i)) report " wrong output: addition should take place" severity error;
      else
        assert fmcw_ramp_o = std_logic_vector(unsigned(old_fmcw_ramp_s) - unsigned(fstep_i)) report " wrong output: subtraction should take place" severity error;
      end if;
      if (fmcw_ramp_o >= fmcw_bw_i) then
        dir_s <= '1';
      elsif (fmcw_ramp_o < fstep_i) then
        dir_s <= '0';
      elsif (fmcw_ramp_o = "000000000000000000000000") then
 dir_s <= '0';
      end if;
      old_fmcw_ramp_s <= fmcw_ramp_o;
      else
       dir_s <= '0';
       old_fmcw_ramp_s <= (others => '0');
     end if;
   end if;
  end process;

Also the VHDL code looks like this:

begin
    if (reset_n_i = '0') then
      temp_s <= 0;
      cnt_s <= '0';
    elsif (clk_128meg_i'event and clk_128meg_i = '1') then
      if (enable_i = '1' and fmcw_trig_i = '1') then
        if (temp_s <= to_integer(unsigned(fstep_i))) then
   temp_s <= temp_s + to_integer(unsigned(fstep_i));   -- Accumulated values of temp_s and fstep_i
   cnt_s <= '0';
   elsif (temp_s = 0) then
    temp_s <= temp_s - to_integer(unsigned(fstep_i));
  cnt_s <= '0';
 elsif (temp_s >= (to_integer(unsigned(fmcw_bw_i)))) then
   temp_s <= temp_s - to_integer(unsigned(fstep_i));
   cnt_s <= '1';
 elsif (cnt_s = '0') then
   temp_s <= temp_s + to_integer(unsigned(fstep_i));   -- Up counter
 else
   temp_s <= temp_s - to_integer(unsigned(fstep_i));   -- Down counter
 end if;
      else
       temp_s <= 0;
       cnt_s <= '0';
      end if;
    end if;
  end process;

36 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Ok, so here is the testbench code for tdc_decode (unfortunately I DONT HAVE THE SOURCE CODE)

    architecture beh of tb_tdc_decode is
    component tdc_decode 
        port (reset_n_i      : in std_logic;      -- asynch reset
              clk_128meg_i   : in std_logic;      -- 128 meg system clock
          enable_i       : in std_logic;      -- enable signal
          tdc_i          : in std_logic_vector(63 downto 0);    -- tdc data
          rise_o         : out std_logic_vector(5 downto 0);    -- value for rise
          rise_fall_o    : out std_logic_vector(6 downto 0));   -- rise - fall value
    end component;
    --constant definition:
    constant clk_128meg_i_period : time := 10 ns;
    -- signal definition:
    signal reset_n_i : std_logic := '0';  
    signal clk_128meg_i : std_logic := '0';
    signal rise_o : std_logic_vector(5 downto 0) := (others => '0');
    signal rise_fall_o : std_logic_vector(6 downto 0) := (others => '0');
    begin
    --UUT Instance: 
      uut: tdc_decode
      port map (reset_n_i => reset_n_i,
                clk_128meg_i => clk_128meg_i,
                enable_i => enable_i,
                tdc_i => tdc_i,
                rise_o => rise_o,
                rise_fall_o => rise_fall_o
               );
    --clock generation:
      p_clock_gen :process
      begin
        clk_128meg_i <= '0';
        
        wait for clk_128meg_i_period/2;  
        clk_128meg_i <= '1';
        
        wait for clk_128meg_i_period/2;
      end process;
     
    --stimulus:  
      stim_proc: process
      
      begin
        
        wait for 10 ns;
        reset_n_i <= '1';
       
        wait for 15 ns;
        enable_i <= '1';
        tdc_i <= "0000111111111111111111111000000001111111111111100000000111111000";
        
        wait for 1 ms;
        reset_n_i <= '0';
      
        wait for 1 ms;
        reset_n_i <= '1';
        wait for 1 ms;
        enable_i <= '0';
        wait for 1 ms;
        enable_i <= '1';
        wait for 1 ms;
        assert False report "End simulation!" severity Failure;
      end process;
       
      p_check_tdc_out: process(reset_n_i, clk_128meg_i)
      variable tdc_vec_v : std_logic_vector(63 downto 0) := (others => '0');
      variable tdc_newvec_v : std_logic_vector(63 downto 0) := (others => '0'); 
       ......................................................... (Sorry I don't have space to post the entire code but its not important)
       end process;
      
      p_check_tdcmodule: process(clk_128meg_i)
      begin
        if (clk_128meg_i'event and clk_128meg_i = '0') then
          assert rise_o = std_logic_vector(to_unsigned(tdc_rise_s, 6)) report "Wrong output: Rise time is not calculated properly" severity error;
          assert rise_fall_o = tdc_rise_fall_s report "Wrong output : Rise time - fall time is not calculated properly" severity error;
        end if;
      end process;
    end beh;

    And this is the tdc_readout source code:

    entity tdc_readout is
        port (reset_n_i : in std_logic;
          enable_i : in std_logic;
          clk_128meg_i : in std_logic;
          tdc_i : in std_logic_vector(63 downto 0);         --tdc data
          scale_i : in std_logic_vector(7 downto 0);        --scaling value from spi reg
          rise_fall_o : out std_logic_vector(6 downto 0);   --calculated rise fall value to spi
          phi_frac_o : out std_logic_vector(13 downto 0));  --phi fractional value to add3
    end tdc_readout;
    architecture rtl of tdc_readout is
    signal rise_s : std_logic_vector(5 downto 0);
    signal result_s : std_logic_vector(13 downto 0);
    signal phi_frac_s : std_logic_vector(15 downto 0);
    signal tdc_reg_s : std_logic_vector(63 downto 0);
    constant operand_c : std_logic_vector(15 downto 0) := "0100000000000000";
    component tdc_decode is    
        port (reset_n_i      : in std_logic;      --asynch reset
              clk_128meg_i   : in std_logic;   --128 meg system clock
          enable_i       : in std_logic;   -- enable signal
          tdc_i          : in std_logic_vector(63 downto 0);    -- tdc data
          rise_o         : out std_logic_vector(5 downto 0);    -- value for rise
          rise_fall_o    : out std_logic_vector(6 downto 0));  -- rise - fall value
    end component;  
    component mult_6t8 is
        port (reset_n_i : in std_logic;
          enable_i : in std_logic;
          clk_128meg_i : in std_logic;
          rise_i : in std_logic_vector(5 downto 0);
          scale_i : in std_logic_vector(7 downto 0);
          result_o : out std_logic_vector(13 downto 0));
    end component;
    begin
    i_tdc_decode : tdc_decode
      port map (reset_n_i       => reset_n_i,      -- reset from pad
                clk_128meg_i    => clk_128meg_i,   -- system clock
                enable_i        => enable_i,
            tdc_i           => tdc_reg_s,
            rise_o          => rise_s,
            rise_fall_o     => rise_fall_o);   
            
    i_mult: mult_6t8
      port map (reset_n_i       => reset_n_i,
            enable_i        => enable_i,
                clk_128meg_i    => clk_128meg_i,
            rise_i          => rise_s,
            scale_i         => scale_i,
            result_o        => result_s);
    p_reg_tdc: process(reset_n_i, clk_128meg_i)
    begin
      if(reset_n_i = '0') then
        tdc_reg_s <= (others => '0');
      elsif(clk_128meg_i'event and clk_128meg_i = '1') then
        if(enable_i = '1') then
          tdc_reg_s <= tdc_i;
        else
          tdc_reg_s <= (others => '0');
        end if;
      end if;
    end process;
            
    p_phi_frac: process(reset_n_i, clk_128meg_i)
    begin
      if(reset_n_i = '0') then
        phi_frac_s <= (others => '0');
      elsif(clk_128meg_i'event and clk_128meg_i = '1') then
        if(enable_i = '1') then
           phi_frac_s <= std_logic_vector(unsigned(operand_c) - unsigned(result_s & "00"));
        else
          phi_frac_s <= (others => '0');
        end if;
      end if;
    end process;
    phi_frac_o <= phi_frac_s(13 downto 0);
    end rtl;

    And the testbench code is as follows:

    entity tb_tdc_readout is
    end tb_tdc_readout; 
    architecture beh of tb_tdc_readout is
    component tdc_readout
        port (reset_n_i : in std_logic;
          enable_i : in std_logic;
          clk_128meg_i : in std_logic;
          tdc_i : in std_logic_vector(63 downto 0);         --tdc data
          scale_i : in std_logic_vector(7 downto 0);        --scaling value from spi reg
          rise_fall_o : out std_logic_vector(6 downto 0);   --calculated rise fall value to spi
          phi_frac_o : out std_logic_vector(13 downto 0));  --phi fractional value to add3
    end component;
    --constant definition:
    constant clk_128meg_i_period : time := 10 ns;
    --signal definition:
    signal reset_n_i : std_logic := '0';  
    signal clk_128meg_i : std_logic := '0';
    signal enable_i : std_logic := '0';
    signal tdc_i : std_logic_vector(63 downto 0) := (others => '0');
    signal scale_i : std_logic_vector(7 downto 0) := (others => '0');
    signal doub_rise_fall_s : std_logic_vector(7 downto 0) := (others => '0');
    signal shif_scale_s : std_logic_vector(11 downto 0) := (others => '0');
    signal mult_s : std_logic_vector(13 downto 0) := (others => '0');
    signal ph_frac_s : std_logic_vector(13 downto 0) := (others => '0');
    signal rise_s : std_logic_vector(5 downto 0) := (others => '0');
    signal rise_fall_o : std_logic_vector(6 downto 0) := (others => '0');
    signal phi_frac_o : std_logic_vector(13 downto 0) := (others => '0');
    begin
    --UUT Instance: 
      uut: tdc_readout
       port map (reset_n_i => reset_n_i,
                 clk_128meg_i => clk_128meg_i,
                 enable_i => enable_i,
                 tdc_i => tdc_i,
                 scale_i => scale_i,
                 rise_fall_o => rise_fall_o,
                 phi_frac_o => phi_frac_o
                );
    .....................................................................code continues
    ..................................................................................................code continues
      p_check_spi_phfrac: process(reset_n_i, clk_128meg_i)
      begin
        if (reset_n_i = '0') then
          doub_rise_fall_s <= (others => '0');
          shif_scale_s <= (others => '0');
          mult_s <= (others => '0');
          ph_frac_s <= (others => '0');
          rise_s <= (others => '0');
        elsif (clk_128meg_i'event and clk_128meg_i = '1') then
          if (enable_i = '1') then
        doub_rise_fall_s <= (rise_fall_o & '0');
            shif_scale_s <= ("0000" & scale_i) ;
            mult_s <= std_logic_vector(unsigned(rise_s) * unsigned(shif_scale_s));
            ph_frac_s <= std_logic_vector("00000000000001" - unsigned(mult_s));
          else
            doub_rise_fall_s <= (others => '0'); 
            shif_scale_s <= (others => '0');
            mult_s <= (others => '0');
            ph_frac_s <= (others => '0');
            rise_s <= (others => '0');
          end if;
        end if;
      end process;
      
      
    end beh;
    

    Don't worry about the logic. Its not important right now. What's important is I need to use the values of rise_o from tb_tdc_decode/tdc_decode and use it in tb_tdc_readout because if you have a look at the tb_tdc_readout, you can see a statement " mult_s <= std_logic_vector(unsigned(rise_s) * unsigned(shif_scale_s));". This need to be executed. So, in order to execute this, I need the values of rise_o from either the testbench or the source file of tdc_decode. This is what I can provide you as extra information. I hope so you will figure it out from this. Thanks in advance
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I still dont see the problem. Why cant you just route rise_o in tb_tdc_decode to tb_tdc_readout? Whats wrong with copy/paste if you dont want to instantiate tb_tdc_decode inside tb_tdc_readout?

    What is the error you're having trying to implement what you want.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Am I missing anything in the Hierarchy part of the simulation, or should I need to include any component declaration so that I can port map the results of the rise_o to rise_s of the testbench. Thanks in advance

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You said you dont have the source code for tdc_readout, how are you simulating it?