Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

how to write a tesbench with reading input from text and writting output in text?

Status
Not open for further replies.

milan.km

Member level 3
Joined
Sep 14, 2015
Messages
55
Helped
0
Reputation
0
Reaction score
0
Trophy points
6
Activity points
435
hi....
I am trying to write a testbench for reading inputs from textfile then write the output in a textfile.
I know some parts of the code, but its incomplete.
I put the original code that corresponds to the clk, reading input and writing output, but some other parts should be written too.
If other people say I am grateful to have the information what other things should be observed :
here is the architecture of the testbench :

Code:
   -- Clock process definitions
   clk_process :process
   begin
		clk <= '0';
		wait for clk_period/2;
		clk <= '1';
		wait for clk_period/2;
   end process;

   -- Stimulus process
   stim_proc: process
	file IN1:text ;
	variable line_input:line;
	variable p1:integer;
   begin		
      file_open(IN1,"E:\OUT1.txt",read_mode);
    
       while not endfile( IN1 ) loop
readline( IN1, line_input );
		  read( line_input, p1 );
			 p_in <=to_unsigned(p1,8);
			 wait for 3 ns;
        end loop;
		file_close(IN1);
	end process;
stim_proc2: process
file OUT1:text;
	variable TEMP:integer;
	variable line_output:line;
   begin
	  file_open(OUT1,"E:\OUT1.txt", write_mode);
             wait for 3 ns;
				 TEMP:=to_integer(p_out);
	          write(line_output,TEMP); 
				 writeline( OUT1 ,line_output ) ;
        end loop;
        file_close(OUT1);
	 
   end process; 

END;
Thanks
 

i changed the code like this :
Code:
 -- Clock process definitions
   clk_process :process
   begin
		clk <= '0';
		wait for clk_period/2;
		clk <= '1';
		wait for clk_period/2;
   end process;

   -- Stimulus process
   stim_proc: process
	file IN1:text ;
	variable line_input:line;
	variable p1:integer;
   begin		
      file_open(IN1,"E:\IN1.txt",read_mode);
    
       while not endfile( IN1 ) loop
readline( IN1, line_input );
		  read( line_input, p1 );
			 p_in <=to_unsigned(p1,8);
			 wait for 3 ns;
        end loop;
		file_close(IN1);
	end process;
stim_proc2: process
file OUT1:text;
	variable TEMP:integer;
	variable line_output:line;
   begin
	  file_open(OUT1,"E:\OUT1.txt", write_mode);
             wait for 3 ns;
				 TEMP:=to_integer(p_out);
	          write(line_output,TEMP); 
				 writeline( OUT1 ,line_output ) ;
        end loop;
        file_close(OUT1);
	 
   end process; 

END;
if any body know what should I do,please help:|
 

You probably haven't gotten any answers because...

1) lack of a discernible question
2) lacks context for the testbench, i.e. how you need to use the input file and the output file for stimulating the UUT
3) missing the rest of the testbench code, i.e. you aren't testing anything (a UUT) with this code.
4) we don't know how this p_in and p_out interface to the UUT, so how can anyone make any suggestions.
5) the code looks like it won't work due to the wait for 3 ns stuff (my opinion only, i.e. no timing relationship to any UUT interface)
 
sorry :(.I didnt put them because the question would be too long,and nobody read it.


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
 
use std.textio.all; 
use ieee.std_logic_textio.all;  
 
 
ENTITY x1_tb IS
END x1_tb;
 
ARCHITECTURE behavior OF x1_tb IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT x1
    PORT(
         clk : in  std_logic;
         p_in : in  unsigned(7 downto 0);
         p_out : out  unsigned(7 downto 0)
        );
    END COMPONENT;
    
 
   --Inputs
   signal clk : std_logic := '0';
   signal p_in : unsigned(7 downto 0) := (others => '0');
 
    --Outputs
  signal p_out : unsigned(7 downto 0):=(others => '0');
 
   -- Clock period definitions
constant clk_period : time := 10 ns;
 
signal i:integer:=0;
signal p1:integer;
BEGIN
 
    -- Instantiate the Unit Under Test (UUT)
   uut: x1 PORT MAP (
          clk => clk,
          p_in => p_in,
          p_out => p_out
        );
 
   -- Clock process definitions
   clk_process :process
   begin
        clk <= '0';
        wait for clk_period/2;
        clk <= '1';
        wait for clk_period/2;
   end process;
 
   -- Stimulus process
   stim_proc: process
    file infile:text ;
    variable fstatus:File_open_status;
    variable in_line:line;
    variable p1:integer;
   begin        
      file_open(infile,"E:\in1.txt",read_mode); 
 
       while not endfile( infile ) loop
readline( infile, in_line );
          read( in_line, p1 );
             p_in <=to_unsigned(p1,8);
             wait for 10 ns;
        end loop;
        file_close(infile);
    end process;
stim_proc2: process
file outfile:text;
    variable fstatus:File_open_status;
    variable p2:integer;
    variable out_line:line;
   begin
    i<=0;
      file_open(fstatus,outfile,"E:\out1.txt", write_mode);
    
       for i in 0 to 4095 loop
             wait for 10 ns;
                 p2:=to_integer(p_out);
              write(out_line,p2); 
                 writeline( outfile ,out_line ) ;
        end loop;
        file_close(outfile);
     
   end process; 
 
END;



- - - Updated - - -

thu uut is a simulation code :

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use ieee.fixed_float_types.all;
use ieee.fixed_pkg.all;
----
entity x1 is
generic (m,n : Integer := 64);
port(clk : in std_logic;
     p_in : in unsigned(7 downto 0);
     p_out : out unsigned(7 downto 0));
end x1;
-----
architecture x1_arch of x1 is
subtype ufixed7_8 is ufixed (7 downto -8) ;
type mat is array (0 to 4355) of unsigned(7 downto 0); --size of image with zero padarray
type mat1 is array (0 to 4095) of unsigned(7 downto 0); --size of image without zero padarray
type mat2 is array (0 to 4095) of ufixed7_8;
 
signal a,memory : mat :=(others => "00000000");
signal wr_ena : std_logic := '1';
signal temp2 : mat1 :=(others => "00000000");
constant k : integer := (m+2);
-------- ufixed-----
signal b1 : ufixed7_8 := to_ufixed (0.4, 7, -8);
signal b2 : ufixed7_8 := to_ufixed (0.6, 7, -8);
signal ip : ufixed7_8 := to_ufixed (1/255 , 7, -8);
begin
--Read the data in process one to RAM
process(clk,wr_ena)
variable addr : integer range 0 to 4356 := 0;
begin
IF (clk'event AND clk = '1') THEN
  if (wr_ena ='1') then
    memory(addr) <= p_in;
    addr :=addr+1;
    if addr = 4356 then
      wr_ena <= '0';
    end if;
  else 
    a <= memory ;
  end if;
end if;
end process;
-- pause the first process forever, Start the second process doing the actual simulation.
process(a)
  variable temp : unsigned(7 downto 0) := "00000000";
  variable l : integer := 0;
  variable temp1 : mat1 :=(others => "00000000");
  
  begin
    l := 0;
  for i in 0 to 63 loop
    for j in 0 to 63 loop
      temp := a((k)*i+j)+a((k)*i+j+1)+a((k)*i+j+2)+
              a((k)*(i+1)+j)+a((k)*(i+1)+j+1)+a((k)*(i+1)+j+2)+
              a((k)*(i+2)+j)+a((k)*(i+2)+j+1)+a((k)*(i+2)+j+2);
              temp1(l) := temp/"00001001";
              l := l+1;
              
     end loop;
  end loop;
  temp2 <= temp1 ;
end process;
process(temp2)
  variable temp3 : mat2 :=(others => "0000000000000000");   --???fixed
  begin
  for i in temp2'range loop
  temp3(i) := to_ufixed(temp2(i), 7, -8);
  --temp3(i) := temp3(i) * ip ;
  temp3(i) := resize(temp3(i) * ip,7,-8) ;
     if ( temp3(i) < b1 ) then
     temp3(i) := to_ufixed(0,7,-8);   --??
   elsif (temp3(i) > b2) then
    temp3(i) := to_ufixed(1,7,-8) ;
  else
  temp3(i) := resize(to_ufixed(5,7,-8)*temp3(i),7,-8);
  temp3(i) := temp3(i) - to_ufixed(2,8,-7);  
end if;
temp3(i) := resize(temp3(i)* to_ufixed(255,7,-8),7,-8) ;  
p_out <= unsigned(to_slv(temp3(i)(7 downto 0)));
   end loop;
    end process;
end x1_arch;

 
Last edited by a moderator:

when I run the simulation,the simulation wont stop,Its first time I write this kind of testbench(reading and writting textfile) and I think I miss sth but I dont know what?!.
thanks
 

when I run the simulation,the simulation wont stop,Its first time I write this kind of testbench(reading and writting textfile) and I think I miss sth but I dont know what?!.
thanks

All of your testbench processes have no ending. Once they finish they will start up again. In your 'stim_proc' and 'stim_proc2' processes, it looks like you should have a 'wait' statement immediately before the 'end process'.

Your clock generator program will never stop either. You probably should add the following immediately before the 'end process'
Code:
if (Simulation_Complete = '1') then
    wait;
end if;

Declare Simulation_Complete to be a std_ulogic, initialize it to '0' and then set it to '1' inside of the 'stim_proc2' process.

Kevin Jennings
 
thanks a lot ,now I can see the output file,
but all the arrays are zero.do u know why this is happening???
 

As Kevin suggests you probably want to stop it shortly after the file_close line, I'd probably stop it a few clocks later, by using a wait for 3*CLOCK_PERIOD; statement, which will be followed by the Simulation_Complete <= '1'; statement.

- - - Updated - - -

I would also change using the wait for 10 ns; stuff in the file reading and use the same clock that is used to run the DUT. Use something like wait until rising_edge(clock);. Things like changing the clock period or the starting state of the clock could change the way the simulation runs. Using the clock edge will ensure that doesn't happen. You might also end up with scheduling problems when you use wait delays to line up the signals and the clocks.
 
u mean like this :
Code:
stim_proc2: process
file outfile:text;
	variable fstatus:File_open_status;
	variable p2:integer;
	variable out_line:line;
   begin
	i<=0;
	  file_open(fstatus,outfile,"E:\out1.txt", write_mode);
	
       for i in 0 to 4095 loop
             wait for 10 ns;
				 p2:=to_integer(p_out);
	          write(out_line,p2); 
				 writeline( outfile ,out_line ) ;
        end loop;
        file_close(outfile);
        wait for 3*clk_period;
        Simulation_Complete <= '1';
        
        
	 
   end process; 

END;

- - - Updated - - -

thanks ads-ee . i change the code like this :
Code:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
 
use std.textio.all;	
use ieee.std_logic_textio.all;	

 
ENTITY x1_tb IS
END x1_tb;
 
ARCHITECTURE behavior OF x1_tb IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT x1
    PORT(
         clk : in  std_logic;
         p_in : in  unsigned(7 downto 0);
         p_out : out  unsigned(7 downto 0)
        );
    END COMPONENT;
    

   --Inputs
   signal clk : std_logic := '0';
   signal p_in : unsigned(7 downto 0) := (others => '0');

 	--Outputs
  signal p_out : unsigned(7 downto 0):=(others => '0');
  signal Simulation_Complete : std_ulogic := '0';
   -- Clock period definitions
constant clk_period : time := 10 ns;

signal i:integer:=0;
signal p1:integer;
BEGIN
 
	-- Instantiate the Unit Under Test (UUT)
   uut: med3 PORT MAP (
          clk => clk,
          p_in => p_in,
          p_out => p_out
        );

   -- Clock process definitions
   clk_process :process
   begin
		clk <= '0';
		wait for clk_period/2;
		clk <= '1';
		wait for clk_period/2;
		if (Simulation_Complete = '1') then
    wait;
   end if;
   end process;

   -- Stimulus process
   stim_proc: process
	file infile:text ;
	variable fstatus:File_open_status;
	variable in_line:line;
	variable p1:integer;
   begin		
      file_open(infile,"D:\IP1\in1.txt",read_mode);
      --wait for 5 ns; 	

		-- Add stimulus here
       while not endfile( infile ) loop
readline( infile, in_line );
		  read( in_line, p1 );
			 p_in <=to_unsigned(p1,8);
			 wait until rising_edge(clk);
        end loop;
		file_close(infile);
		wait;
	end process;
stim_proc2: process
file outfile:text;
	variable fstatus:File_open_status;
	variable p2:integer;
	variable out_line:line;
   begin
	i<=0;
	  file_open(fstatus,outfile,"D:\IP1\out1.txt", write_mode);
	
       for i in 0 to 4095 loop
             wait until rising_edge(clk);
				 p2:=to_integer(p_out);
	          write(out_line,p2); 
				 writeline( outfile ,out_line ) ;
        end loop;
        file_close(outfile);
        wait for 3*clk_period;
        Simulation_Complete <= '1';
        
        
	 
   end process; 

END;

You might also end up with scheduling problems when you use wait delays to line up the signals and the clocks.
I dont get where u mean?

- - - Updated - - -

i forget to mention that I just have one '0' in output file.
 
Last edited:

You might also end up with scheduling problems when you use wait delays to line up the signals and the clocks.
I dont get where u mean?

The simulator schedules events and the event scheduling queue can end up with unexpected behavior depending on which event gets scheduled first, unless you know how the event scheduler works. This is what people are talking about when they start discussing delta time issues in a simulation.
 

where do u think is wrong(all the outputs are zero)??

- - - Updated - - -

I changed the code like this but I have one entry (0), but according to the tesbench I should have 4096 entry in textfile.
Code:
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
 
use std.textio.all;	
use ieee.std_logic_textio.all;	

 
ENTITY x1_tb IS
END x1_tb;
 
ARCHITECTURE behavior OF x1_tb IS 
 
    -- Component Declaration for the Unit Under Test (UUT)
 
    COMPONENT x1
    PORT(
         clk : in  std_logic;
         p_in : in  unsigned(7 downto 0);
         p_out : out  unsigned(7 downto 0)
        );
    END COMPONENT;
    

   --Inputs
   signal clk : std_logic := '0';
   signal p_in : unsigned(7 downto 0) := (others => '0');

 	--Outputs
  signal p_out : unsigned(7 downto 0):=(others => '0');
  signal Simulation_Complete : std_ulogic := '0';
   -- Clock period definitions
constant clk_period : time := 10 ns;

signal i:integer :=0;
signal p1:integer := 0;
BEGIN
 
	-- Instantiate the Unit Under Test (UUT)
   uut: x1 PORT MAP (
          clk => clk,
          p_in => p_in,
          p_out => p_out
        );

   -- Clock process definitions
   clk_process :process
   begin
		clk <= '0';
		wait for clk_period/2;
		clk <= '1';
		wait for clk_period/2;
		if (Simulation_Complete = '1') then
    wait;
   end if;
   end process;

   -- Stimulus process
   stim_proc: process
	file infile:text ;
	variable fstatus:File_open_status;
	variable in_line:line;
	variable p1:integer;
   begin		
      file_open(infile,"E:\in1.txt",read_mode);	

		-- Add stimulus here
       while not endfile( infile ) loop
readline( infile, in_line );
		  read( in_line, p1 );
			 p_in <=to_unsigned(p1,8);
			 --wait until rising_edge(clk);
			 wait for 10 ns;
        end loop;
		file_close(infile);
		wait;
	end process;
stim_proc2: process
file outfile:text;
	variable fstatus:File_open_status;
	variable p2:integer;
	variable out_line:line;
   begin
	i<=0;
	  file_open(fstatus,outfile,"D:\IP1\out1.txt", write_mode);
	
       for i in 0 to 4095 loop
             --wait until rising_edge(clk);
             wait for 10 ns;
				 p2:=to_integer(p_out);
	          write(out_line,p2); 
				 writeline( outfile ,out_line ) ;
        end loop;
        file_close(outfile);
        wait for 3*clk_period;
        Simulation_Complete <= '1';
      
   end process; 

END;
 

VHDL for loops are unrolled, they are not software for loops. You should be using a counter and a while loop until the count reaches terminal count. Not exactly sure how the for loop would deal with the wait for 10 ns; statement, I suspect it's ignored, but would have to actually try a test case to be sure.
 

thanks for ur answer :
I change the code as u said but I still have one entry in output textfile :
I changed the second process like this :
Code:
stim_proc2: process
file outfile:text;
	variable fstatus:File_open_status;
	variable p2:integer;
	variable out_line:line;
	variable k : integer := 0;
   begin
	k:=0;
	  file_open(fstatus,outfile,"D:\IP1\out1.txt", write_mode);
	
      -- for i in 0 to 4095 loop
       while (k < 4096) loop
      
            wait until rising_edge(clk);
				 p2:=to_integer(p_out);
	          write(out_line,p2); 
				 writeline( outfile ,out_line ) ;
				 k := k+1;
        end loop;
        file_close(outfile);
        wait for 3*clk_period;
        Simulation_Complete <= '1';
        
        
	 
   end process; 

END;
 

VHDL for loops are unrolled, they are not software for loops. You should be using a counter and a while loop until the count reaches terminal count. Not exactly sure how the for loop would deal with the wait for 10 ns; statement, I suspect it's ignored, but would have to actually try a test case to be sure.

Actually, as this is a testbench, they are not unrolled, and behave exactly like in software...
 

Actually, as this is a testbench, they are not unrolled, and behave exactly like in software...

Thanks for the clarification nice to know that. I'm not a big fan of VHDL and only occasionally use it, so currently I'm pretty much a novice when it comes to the specific details of how a piece of code may behave.

Are you running your simulation long enough? That code doesn't seem like it would write more than one line out. You should add some debug statements to the loop to output something like k to the transcript window. At least that is what I would try first to see if the loop is even being iterated over.
 

thanks TrickyDicky .can u help me why this is happening? and I cannot see the output in textfile?
 

When you say you cannot see output in the textfile - do you mean that the text file is empty, or it is full of the correct amount of data but they are all zero?

If it is empty - you are not running the simulation long enough
If has lots of zeros - then there is something wrong with the UUT or the input - you will need to view these on a wave window and debug it.
 
when I change wait for 10 ns; to wait until rising_edge(clk); ,as u said I just have one entry in out1.txt instead of 4096 entry.

- - - Updated - - -

ALL the entries are zero.I checked the input file ,its ok.then I checked the wave window I figured that temp2 is ok and have its value but I dont know whats happen in the third process,and p_out is zero 13.png?
 
Last edited:

is there sth wrong with my division in the codes below :
Code:
 begin
    l := 0;
  for i in 0 to 63 loop
    for j in 0 to 63 loop
      temp := a((k)*i+j)+a((k)*i+j+1)+a((k)*i+j+2)+
              a((k)*(i+1)+j)+a((k)*(i+1)+j+1)+a((k)*(i+1)+j+2)+
              a((k)*(i+2)+j)+a((k)*(i+2)+j+1)+a((k)*(i+2)+j+2);
              temp1(l) := temp/"00001001";
              l := l+1;
              
     end loop;
  end loop;
  temp2 <= temp1 ;
for example for the first entry the answer should be 62 for this divide (0+0+0+0+138+127+140+160)/9 .but the answer is 5!
do u why this is happening?
thanks

16.png17.png
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top