1
\$\begingroup\$

I am working with altera QuartusII version 13.I want to write a program that reads data from a text file and outputs this data serially at every positive clk edge.

I have tried writing a code,but it did not work.The simulation result shows a value '1' for y(data read from) all the time even when reset is set '1' initially .Could someone help me in resolving this problem.

--code 
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use STD.textio.all; 

ENTITY readfile IS
port(rst,clk:in std_logic;
EOR:out std_logic;
y:out std_logic );
END readfile;

ARCHITECTURE behav OF readfile IS 
BEGIN
process (rst,clk) 
  file file_pointer : text;
    variable line_content : character;
  variable line_num : line;
    variable j : integer := 0;
    variable char : character:='0'; 
    variable cnt:integer range 0 to 80:=0;
begin
if rst='1'then
    EOR<='0';
    file_open(file_pointer,"C:\input.txt",READ_MODE);
elsif rising_edge(clk) then 
    if cnt<80 then
  readline (file_pointer,line_num);  
  READ (line_num,line_content);  

        EOR<='1';
        char := line_content;
        if(char = '0') then
            y <= '0';
        else
            y <= '1';
        end if; 
cnt:=cnt+1;
 end if;
end if;
  file_close(file_pointer);     
end process;
end behav; 

--text file(input.txt) 1 1 0 0 1 1 1 1 0 0 1 1 1 1 0 1 0 0 0 1 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 1 0 0 1 1 0 1 0 0 0 1 0 0 0 1 0 1 0 1 0 1 0 1 1 0 0 1 1 0 0 1 1 1 0 1 1 1 1 0 0 0 1 0 0 0

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Isn't this why people use soft-core CPUs? :) \$\endgroup\$
    – pipe
    Jun 14, 2016 at 6:29
  • 2
    \$\begingroup\$ Altera Quartus does not support VHDL's text-I/O. Altera considers text-I/O as not synthesizable. \$\endgroup\$
    – Paebbels
    Jun 14, 2016 at 8:54

2 Answers 2

4
\$\begingroup\$

Not surprisingly, readline reads one line of text and stores it into the variable you confusingly named line_num. Your input file seem to have only one line of text, which starts with 1.

read is called with a line_content output argument which is a single character, so it reads the first character of the line and outputs it in line_content. That's why you only see a single 1 in the output.

You have to split your input file into multiple lines (each containing a single character). Alternatively, you can make a single call to readline and then iterate through your line_num variable by calling read on it multiple times.

In any case, rename line_num to line_buf or something similar. It looks confusing, especially side by side with line_content, which doesn't hold the line contents as its name advertises.

\$\endgroup\$
1
  • \$\begingroup\$ I've actually written single character in a line. Sorry for not mentioning this in the question. I'll try the alternate method you have suggested. \$\endgroup\$
    – srujana
    Jun 14, 2016 at 11:35
4
\$\begingroup\$

You're trying to readline from a file you've closed.

I wrote a little testbench:

library ieee;
use ieee.std_logic_1164.all;

entity readfile_tb is
end entity;

architecture foo of readfile_tb is
    signal rst:     std_logic := '1';
    signal clk:     std_logic := '0';
    signal eor:     std_logic;
    signal y:       std_logic;
begin

DUT:
    entity work.readfile
        port map (
            rst => rst,
            clk => clk,
            eor => eor,
            y => y
        );
CLOCK:
    process
    begin
        wait for 5 ns;
        clk <= not clk;
        if now > 830 ns then
            wait;
        end if;
    end process;
STIMULUS:
    process 
    begin
        wait for 10 ns;
        rst <= '0';
        wait; 
    end process;
end architecture;

I created input.txt from the 1 and 0 values in your question, one per line.

The first thing my simulator told me was there was a null access (pointer), which would have been the line (line_num). It occurred on the rising edge clock edge after rst is released in the READLINE procedure call.

On closer look, at the end of process you're obliviously doing a FILE_CLOSE, and the next READLINE will fail.

The solution to that is to perform a FILE_OPEN and FILE_CLOSE only once. This also raises the point that we're hanging our hat on rst to hold off readlines, and we could add an enable as an embellishment.

So, modifying the process:

        process (rst, clk) 
            file file_pointer:         text;
            variable line_content:  character;
            variable line_num:      line;
            -- variable j:             integer := 0;
            variable char:          character := '0'; 
            variable cnt:           integer range 0 to 80 := 0; -- defaults to 0
        begin
            if rst = '1' then
                eor <= '0';
                -- file_open (file_pointer, "c:\input.txt", read_mode);
            elsif rising_edge(clk) then 
                if cnt < 80 then
                    if cnt = 0 then  -- open file once
                        file_open (file_pointer, "input.txt", READ_MODE);
                        eor <= '1';   
                    end if;
                    readline (file_pointer, line_num); 
                    read (line_num, line_content);  
                    -- eor <= '1';
                    char := line_content;
                    if char = '0' then
                        y <= '0';
                    else
                        y <= '1';
                    end if; 
                    cnt := cnt + 1;
                end if;
                if cnt = 80 then     -- variable updated immediately
                    file_close (file_pointer);   -- close only once
                    eor <= '0';      -- signal end of input
                end if;  
            end if;
        end process;

We get only one file_open and one file_close. I modified eor to show when y is valid from the file. That can easily be changed.

And this gives us:

readfile_tb.png

I made a change to the path to input.txt for my environment. I can imagine adding an enable to the elsif rising_edge(clk) portion of the if statement so you don't have to hold readfile in reset.

Another useful modification might be to enclose the readline and read in an if statement with a condition test using function ENDFILE for the case of a short file being read.

\$\endgroup\$
2
  • \$\begingroup\$ PlayDough's suggestions don't provide any insight in this case. The file opened just fine, it was subsequently closed. The error occurs in READLINE following FILE_CLOSE prior to the process suspending from any event. The READ procedure call was unreached. Note calling ENDFILE on an un-opened file is also simulation fatal. See IEEE 1076-2008, 16.4 Package TEXTIO, 5.5.2 File operations. \$\endgroup\$
    – user8352
    Jun 16, 2016 at 0:00
  • \$\begingroup\$ @user115120 Ok. You win. I've deleted my comments as irrelevant. \$\endgroup\$
    – PlayDough
    Jun 16, 2016 at 19:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.