Cómo leer un archivo de texto usando vhdl

0

Estoy trabajando con Altera QuartusII versión 13. Quiero escribir un programa que lea datos de un archivo de texto y genere estos datos en serie en cada borde de clk positivo.

He intentado escribir un código, pero no funcionó. El resultado de la simulación muestra un valor de '1' para y (datos leídos) todo el tiempo, incluso cuando el restablecimiento está configurado como '1' inicialmente. Podría ayudarme alguien resolviendo este problema.

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

- archivo de texto (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

    
pregunta celeritas

2 respuestas

3

No es sorprendente que readline lea una línea de texto y lo almacene en la variable que usted denominó confusamente line_num . Su archivo de entrada parece tener solo una línea de texto, que comienza con 1 .

read se invoca con un argumento de salida line_content que es un solo carácter, por lo que lee el primer carácter de la línea y lo genera en line_content . Es por eso que solo ves un 1 en la salida.

Tienes que dividir el archivo de entrada en varias líneas (cada una contiene un solo carácter). Alternativamente, puede hacer una sola llamada a readline y luego iterar a través de su variable line_num llamando a read en ella varias veces.

En cualquier caso, cambie el nombre de line_num a line_buf o algo similar. Parece confuso, especialmente al lado de line_content , que no contiene el contenido de la línea como su nombre lo anuncia.

    
respondido por el Dmitry Grigoryev
3

Estás intentando leer en línea desde un archivo que has cerrado.

Escribí un pequeño banco de pruebas:

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;

Creé input.txt a partir de los valores 1 y 0 en tu pregunta, uno por línea.

Lo primero que me dijo mi simulador fue que había un acceso nulo (puntero), que habría sido la línea (line_num). Ocurrió en el flanco ascendente del reloj después de que se libera la primera vez en la llamada de procedimiento READLINE.

En una mirada más cercana, al final del proceso estás haciendo un FILE_CLOSE de manera inconsciente, y la próxima LISTA DE REPARACIÓN fallará.

La solución a eso es realizar FILE_OPEN y FILE_CLOSE solo una vez. Esto también resalta el hecho de que estamos colgando nuestro sombrero para evitar líneas de lectura, y podríamos agregar una habilitación como un adorno.

Entonces, modificando el proceso:

        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;

Solo obtenemos un file_open y un file_close. Modifiqué eor para mostrar cuándo y es válido desde el archivo. Eso se puede cambiar fácilmente.

Y esto nos da:

Hice un cambio en la ruta a input.txt para mi entorno. Me imagino agregando una habilitación a la parte elsif rising_edge (clk) de la sentencia if para que no tenga que mantener el archivo de lectura en el reinicio.

Otra modificación útil podría ser encerrar la línea de lectura y leer en una declaración if con una prueba de condición utilizando la función ENDFILE para el caso de que se lea un archivo corto.

    
respondido por el user8352

Lea otras preguntas en las etiquetas