Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17255 Discussions

Help needed in VHDL Testbench

Altera_Forum
Honored Contributor II
6,445 Views

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;
0 Kudos
36 Replies
Altera_Forum
Honored Contributor II
1,707 Views

This will be because you have the same assertion error if sel_s is '0' or '1' - so I assume it's going to happen on every clock cycle that enable_i is set.

0 Kudos
Altera_Forum
Honored Contributor II
1,707 Views

@tricky,  

but I need to use this condition to check for the output: is there any other way to solve this.
0 Kudos
Altera_Forum
Honored Contributor II
1,707 Views

Sorry, I missread the code - But you still have the same error reported for two different assertions. maybe you should change the text so that it is clearer which one is firing then you can use the wave window to debug the problem..

0 Kudos
Altera_Forum
Honored Contributor II
1,707 Views

@tricky, 

I have tried all possibilities and I find that the old_phi_e_s is not pushed to phi_e_gr_o as well as phi_e_i is not pushed to phi_e_gr_o. This is the waveform I obtain when I run the simulation. 

 

https://www.alteraforum.com/forum/attachment.php?attachmentid=12710  

 

Also I have changed my testbench because there was a kind of mistake in the design. This is my testbench code: 

 

wait for 10 ns; reset_n_i <= '1'; wait for 15 ns; enable_i <= '1'; phi_e_i <= "101010101111010101101010101101010101"; thresh_i <= "10000000"; wait for 10 ns; phi_e_i <= "111010101101010101010101010101010101"; thresh_i <= "00010110"; wait for 10 ns; phi_e_i <= "100000000000000000010101010101010101"; thresh_i <= "00010101"; wait for 20 ns; phi_e_i <= "110101010101010101010101111110101010"; thresh_i <= "01110000"; wait for 15 ns; phi_e_i <= "000000000000000000000000001010110101"; thresh_i <= "01111111"; 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; delay_rst_s <= reset_n_i after 1 ns; new_thresh_s <= std_logic_vector(thresh_i & "0000000000000000000000000000"); p_check_outp: process(delay_rst_s, clk_128meg_i) begin if (delay_rst_s = '0') then old_phi_e_s <= (others => '0'); assert phi_e_gr_o = "000000000000000000000000000000000000" report "Output not set to default value when reset_n_i= 0" severity error; elsif (clk_128meg_i'event and clk_128meg_i = '0')then if (enable_i = '1') then old_phi_e_s <= phi_e_i; if (abs(signed(phi_e_i) - signed(old_phi_e_s)) >= to_integer(unsigned(new_thresh_s))) then assert phi_e_gr_o = old_phi_e_s report "Wrong output: phi_e_gr_o should be equal to old phi_e_i" severity error; elsif (abs(signed(phi_e_i) - signed(old_phi_e_s)) < to_integer(unsigned(new_thresh_s))) then assert phi_e_gr_o = phi_e_i report "Wrong output: phi_e_gr_o should be equal to phi_e_i" severity error; end if; else old_phi_e_s <= (others => '0'); assert phi_e_gr_o = "000000000000000000000000000000000000" report " Output not set to default value when enable_i= 0" severity error; end if; end if; end process;

 

 

Please help me to solve this issue. I am really fed up of why I am not getting the output
0 Kudos
Altera_Forum
Honored Contributor II
1,707 Views

This is debugging. 

I have no knowledge of your deisgn and you are the best person to fix it. 

Use the testbench and internal wave forms to trace a known input through the design, and ensure it is the correct values at all stages through the design.
0 Kudos
Altera_Forum
Honored Contributor II
1,707 Views

Hello all,  

Once again I have a small clarification to be done regarding testbench. I have written a testbench in which I have used a signal say "XXX_s". Now I use the same signal XXX_s in another source code say "YYY.vhd" by port mapping it. However, I need to again use the same signal, XXX_s for the testbench file that I have written for the source file YYY.vhd. How can I do so?? Thanks in advance
0 Kudos
Altera_Forum
Honored Contributor II
1,707 Views

I dont understand your question? Is it about naming scope in VHDL? Names can be re-used in as many files as long as you dont manage to put the same name twice in the same scope. 

Why not post an example with the problem you're having?
0 Kudos
Altera_Forum
Honored Contributor II
1,707 Views

Ok, i will post an example , I am just writing the entity and the portmap. I hope so this would be enough for you to have an idea of what I trying to ask. 

 

Consider this as the first source code , 

Consider the output port rise_o 

entity 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 tdc_decode;  

 

The testbench (port mapping section) for this source code is as follows: 

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 );  

 

This is the second source code tdc_readout 

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; 

 

However,I am going to port map the inputs of tdc_decode in tdc_readout: 

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);  

 

Now, what I need is to use the output port "rise_o values " which I calculated in tdc_decode in my next testbench that I have written for tdc_readout (i.e. tb_tdc_readout). How can I do that. Was I clear?
0 Kudos
Altera_Forum
Honored Contributor II
1,707 Views

To your information, I have added the source files tdc_readout, tdc_decode and only the testbench tb_tdc_readout to my simulation

0 Kudos
Altera_Forum
Honored Contributor II
1,707 Views

Your question is still not clear, can you please post some code that shows an error? 

You can map anything to anything, you just have to connect things through ports...
0 Kudos
Altera_Forum
Honored Contributor II
1,707 Views

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
0 Kudos
Altera_Forum
Honored Contributor II
1,707 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
1,707 Views

The values of rise_s is always zero in my case. i don't know why. 

This is the result of my simulation: 

https://www.alteraforum.com/forum/attachment.php?attachmentid=12796  

 

And these are the files, I have added to the hierarchy section: 

https://www.alteraforum.com/forum/attachment.php?attachmentid=12797
0 Kudos
Altera_Forum
Honored Contributor II
1,707 Views

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

0 Kudos
Altera_Forum
Honored Contributor II
1,707 Views

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

0 Kudos
Altera_Forum
Honored Contributor II
1,707 Views

@tricky, 

anyways, I got the testbench working. Thanks anyways.
0 Kudos
Reply