0
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_SIGNED.all;
use std.env.all;
USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE STD.TEXTIO.ALL;


ENTITY tb_top IS
END tb_top;

ARCHITECTURE behavior OF tb_top IS 

-- Component Declaration for the Unit Under Test (UUT)

COMPONENT c4b
PORT(
     clock : IN  std_logic;
     reset : IN  std_logic;
     count : OUT  std_logic_vector(3 downto 0)
    );
END COMPONENT;


--Inputs
signal clock : std_logic := '0';
signal reset : std_logic := '0';

--Outputs
signal count : STD_LOGIC_vector(3 downto 0) := "0000";

-- Clock period definitions
constant period : time := 100 ns;

-- Opening the file in write mode
file myfile : TEXT open write_mode is "fileio.txt";

BEGIN
    -- Instantiate the Unit Under Test (UUT)
    uut: c4b PORT MAP (
        clock => clock,
        reset => reset,
        count => count
    );

clock_process :process      --providing clock to the counter
begin
    clock <= '1';
    wait for period/2;
    clock <= '0';
    wait for period/2;
end process;

write_process: process
    variable abd: LINE;
    --variable val1: integer;
    begin
        --val1 := CONV_INTEGER(count);          --saw this in another program. even they converted a std_logic_vector to integer. didn't work!
        loop                                                --tried the infinite loop to check for the value 1111,
            if (count = "1111") then                --so that as soon as count reaches the value 1111, 
                finish (0);                             --it would stop, because i only need to write one entire sequence of the cycle to the file!!
            else
                write (abd, count);                 
                writeline (myfile, abd);            
            end if;
        end loop;
    end process;

-- Stimulus process
stim_process: process
begin
    reset <= '0';                                   --because it only works when reset is 0!
    wait for 100 ns;
    if (count = "1111") then                        --the value is written to the text file in a continuous loop,
        finish (0);                                     --which makes he file size go to as much as 1 GB
    end if;                                             --thus to stop it at exactly one cycle!
end process;
END;

So, basically what I want to do here is let the counter count up from 0000 too 1111 and then write the entire sequence to a text file. But I only wish to write exactly just one cycle. Hence I've added a loop to check the same. Here in the code above I'm not able to simulate the testbench properly. When I don't include the write_process part of the code, the simulation works perfectly, giving me exactly just one cycle! (Simulator result w/o write_process picture no 1). But when I try to use the write_process, not only does it not simulate (Simulator result after adding the write_process) picture no 2, it also writes UUUU continuously to the file, until I close the ISim, and file size goes to at least a few hundred MBs! Please help!

  • Sounds like the testbench is working. It seems like a C4B (whatever that is) outputs `'UUUU'` until it has been reset. Perhaps you only want to output the `count` value once per clock cycle rather than in an infinite loop with no 'wait'. I would add 'wait for rising_edge(clock);` at te end of the loop... –  Jul 19 '16 at 17:44

1 Answers1

1

Without the entity/architecture for c4b no one can duplicate your error, it's visible however.

Note that the write process has no sensitivity list nor wait statement and a loop statement that won't exit unless external stimuli is provided - if (count = "1111") then ...

It doesn't seem proper to be using finish in both stim_process and write_process, there's no guarantee of execution order you can lose the last write (if you cure the write process defect).

You have four unused use clauses (numeric_std, std_logic_arith, std_logic_signed, std_logic_textio, with VHDL -2008).

So, basically what I want to do here is let the counter count up from 0000 too 1111 and then write the entire sequence to a text file.

There's nothing in your code that spools up output until your simulation finishes. Writing a line to file textio.txt occurs for events driving the write process.

Adding a model for c4b:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std_unsigned.all;

entity c4b is
    port (
        clock:  in  std_logic;
        reset:  in  std_logic;
        count:  out std_logic_vector(3 downto 0)
    );
end entity;

architecture foo of c4b is 
begin
    process (clock, reset)
    begin
        if reset = '1' then
            count <= (others => '0');
        elsif rising_edge (clock) then
            count <= count + 1;
        end if;
    end process;
end architecture;

Removing unused use clauses (not strictly necessary):

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
-- USE IEEE.NUMERIC_STD.ALL;
--  IEEE.STD_LOGIC_ARITH.all;
-- use IEEE.STD_LOGIC_SIGNED.all;
use std.env.all;
-- USE IEEE.STD_LOGIC_TEXTIO.ALL;
USE STD.TEXTIO.ALL;

Changing the write_process to not endlessly loop:

-- write_process: process
--     variable abd: LINE;
--     --variable val1: integer;
--     begin
--         --val1 := CONV_INTEGER(count);          --saw this in another program. even they converted a std_logic_vector to integer. didn't work!
--         loop                                                --tried the infinite loop to check for the value 1111,
--             if (count = "1111") then                --so that as soon as count reaches the value 1111,
--                 finish (0);                             --it would stop, because i only need to write one entire sequence of the cycle to the file!!
--             else
--                 write (abd, count);
--                 writeline (myfile, abd);
--             end if;
--         end loop;
--     end process;

write_process: 
    process
        variable abd: LINE;
    begin
        wait on count;
        wait for 100 ns;
        write (abd, count);                 
        writeline (myfile, abd);   
        if count = "1111" then
            finish (0);
        elsif IS_X(count) then
            report "count contains a metavalue and may not increment";
            finish (-1);
        end if;
    end process;

The wait 100 ns; accommodates a reset to insure the counter can increment. It's possible to provide a design description of c4b that doesn't depend on reset. For purposes here, the supplied c4b doesn't do that. The wait 100 ns also provides the sample interval for count, which from the component declaration for c4b is free running, driven by clock events.

Changing the stim_process to not finish and wait instead:

-- -- Stimulus process
-- stim_process: process
-- begin
--     reset <= '0';                                   --because it only works when reset is 0!
--     wait for 100 ns;
--     if (count = "1111") then                        --the value is written to the text file in a continuous loop,
--         finish (0);                                     --which makes he file size go to as much as 1 GB
--     end if;                                             --thus to stop it at exactly one cycle!
-- end process;
-- END;

stim_process: 
    process
    begin
        reset <= '1';
        wait for 100 ns;
        reset <= '0';
        wait for 100 ns;
        wait;
    end process;

Notice this also provides a reset interval seen on the following waveform.

And that gives us:

tb_top.png

With the contents of textio.txt:

more fileio.txt  

0000
0001
0010
0011
0100
0101
0110
0111
1000
1001
1010
1011
1100
1101
1110
1111

It's also possible to end simulation after detecting count is "1111" by stopping clock, avoiding the use of the finish procedure. Along with a write procedure supplied using the Synopsys package std_logic_texio:

procedure WRITE(L:inout LINE; VALUE:in STD_LOGIC_VECTOR;

This would allow the use of VHDL simulators complying to VHDL standard revisions earlier than -2008.