VHDL: leer números enteros de un archivo de texto, almacenarlos en una matriz y volver a escribir en formato de texto

0

En un determinado banco de pruebas de simulación que usa questasim, estoy tratando de leer los archivos con números enteros que parecen,

0000
0001
0005
3864
2290
1234
.
.
.
0002
0004
0006
4532
3457
.
.
.

Mi objetivo aquí es leer el archivo de texto, almacenar los primeros números en una matriz de enteros y escribir esa matriz en la salida de texto, mi intento de código parece,

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_textio.all;
use std.textio.all;



entity HFA_tb is
end HFA_tb;

architecture behave of HFA_tb is

--clock 100 MHz change to any value suitable
constant c_CLOCK_PERIOD : time:= 100 ns;
signal r_CLOCK      : std_logic  := '0';
--**signal r_ENABLE     : std_logic  := '0';
signal r_adcpulse   : integer; 
signal r_hitstart   : integer;   ---output of single threshold
signal r_hitend     : integer;
signal r_hitpeak    : integer;
signal r_peaktime   : integer;
signal r_hitsum     : integer;
signal r_opready    : std_logic := '0';





--more signal

--describe HFA component here (Unit Under Test)

component HFA is
 port (
   adcpulse_i     : in integer;
   clk          : in std_logic;
   hitstart_o   : out integer;   ---output of single threshold
   hitend_o     : out integer;
   hitpeak_o    : out integer;
   peaktime_o   : out integer;
   hitsum_o     : out integer;
   opready_o    : out std_logic

   );
 end component HFA;

begin

  --Instatiate the unit under test
  UUT : HFA
  port map (
    clk         => r_CLOCK,
    adcpulse_i    => r_adcpulse,
    hitstart_o  => r_hitstart,
    hitend_o    => r_hitend,
    hitpeak_o   => r_hitpeak,
    peaktime_o  => r_peaktime,
    hitsum_o    => r_hitsum,
    opready_o   => r_opready
  );

 p_CLK_GEN : process is
  begin
   wait for c_CLOCK_PERIOD/2;
   r_CLOCK <= not r_CLOCK;
 end process p_CLK_GEN;


  --main testing logic for reading from text file; feed in the loop and     check output

  process
file in_buffer       :   text;
file out_buffer      :   text;
variable v_ILINE     :   line;
variable v_OLINE     :   line;
variable v_adcValue  :   integer;
variable line_counter :  integer :=0;
variable block_length :  integer :=0;
variable block_counter : integer :=0;
variable header_length : integer :=0;
type header is array (0 to 2) of integer;
variable H: header;

begin

file_open(in_buffer,"/home/eu18461/Data/DUNE/QuestaSim_Examples/HFA_test4_SliceTest/sample.txt",read_mode);

file_open(out_buffer,"/home/eu18461/Data/DUNE/QuestaSim_Examples/HFA_test4_SliceTest/results.txt",write_mode);


while not endfile(in_buffer) loop
  if line_counter=0 then
    f1 : for k in 0 to 2 loop
      readline(in_buffer, v_ILINE);
      read(v_ILINE, v_adcValue);
      H(k) := v_adcValue;
      line_counter := line_counter+1;
    end loop f1;
  end if;

  if line_counter /= 2 and block_length /= 9 then
     f2 : for k in 0 to 2 loop
       readline(in_buffer, v_ILINE);
       read(v_ILINE, v_adcValue);
       r_adcpulse <= v_adcValue;
       line_counter := line_counter+1;
       block_length := block_length+1;
     end loop f2;
  end if;

   if block_length=9 then
    f3 : for k in 0 to 2 loop
      readline(in_buffer, v_ILINE);
      read(v_ILINE, v_adcValue);
      H(k) := v_adcValue;
      line_counter := line_counter+1;
      header_length := header_length+1;
      if header_length=3 then
        block_length := 0;
        exit;
      end if;
    end loop f3;
   end if;



  wait for c_CLOCK_PERIOD;




end loop;

if endfile(in_buffer) then

  write(v_OLINE, string'("hit_start_time"));
  writeline(out_buffer, v_OLINE);

  write(v_OLINE, r_hitstart);
  writeline(out_buffer, v_OLINE);

end if;

wait for c_CLOCK_PERIOD;

file_close(in_buffer);

file_close(out_buffer);

wait;

end process;
end behave; 

Se actualizó el código, el texto de salida deseado debería ser similar,

 Int1 int2 int3 Op1 op2 op3 Op3 ...
 Int11 int12 int13 op1 op2 op3 ...
.
.
 .
 Intx inty intZ op1 op2 op3 ...

Aquí int1, Int2 ... etc. representan los enteros del archivo de texto de entrada, estos no. Sube hasta una longitud de bloque fija. Quiero almacenarlos, y enviar los enteros restantes a mi bloque de procesamiento, después del proceso quiero que se muestren en formato de fila como se muestra en el archivo de texto y repito el proceso nuevamente. Cualquier consejo será muy apreciado. Aquí el bucle for no. indique los enteros que almacenan la longitud y la longitud del bloque después de lo cual se repite el proceso.

    
pregunta rooter

1 respuesta

1

Desearía poder comentar, b / c hay muchos problemas sintácticos aquí.

Definió un type llamado H y luego intentó asignar algo al tipo: H(0) := v_adcValue , lo cual es ilegal y puede explicar la primera parte del error. Debe definir el tipo y luego declarar una variable o señal del tipo definido, que luego puede recibir la asignación.

Parece que puede haber querido declarar una señal llamada header de type H , según esta línea: header(k) <= v_adcValue , pero falta la declaración de header . O tal vez lo eliminó, como lo sugiere:

  

** Error: (vcom-1583) Tipo converson no válido de 'std.STANDARD.INTEGER' a 'header' (numérico a matriz).

También estás intentando usar to_string() en la señal inexistente header . La función está sobrecargada para muchos tipos incorporados a partir de VHDL-2008, pero no para los tipos definidos por el usuario, como una matriz de enteros.

Su proceso MONITOR no tiene una sentencia de espera. Se ejecutará inmediatamente al inicio del simulador y creará un bucle infinito. Necesita algo para activarlo periódicamente, de lo contrario, la simulación se atascará ejecutando ese proceso continuamente y nunca avanzará más allá de un ciclo delta hasta que alcance el límite de iteración.

Por favor, aborde estas cosas primero.

EDIT

Puede escribir los primeros valores directamente en la línea de salida a medida que se leen. Esto conservará el formato de relleno de 4 dígitos que tiene el archivo de entrada. Nota : agregué otra variable line llamada temp al proceso de archivo:

...

  if line_counter=0 then
    v_OLINE := new string'(""); --Needs to be initialized
    f1 : for k in 0 to 2 loop
      readline(in_buffer, v_ILINE);
      temp := new string'(v_ILINE.all&" "); --Create new line with added space
      v_OLINE := new string'(v_OLINE.all&temp.all); --Concatenate new line to existing
      read(v_ILINE, v_adcValue);
      H(k) := v_adcValue;
      line_counter := line_counter+1;
    end loop f1;
...

Si luego genera la línea (después del bucle f1 ):

    v_OLINE := new string'(v_OLINE(1 to v_OLINE'length-1)); --Remove ending space
    writeline(out_buffer,v_OLINE);

luego, para la entrada de:

  

0000
  0001
  0005

Tu salida sería:

  

0000 0001 0005

Por supuesto, querrá esperar para escribir esa línea en el archivo hasta que recupere los valores de su otro proceso. Después de su wait for c_CLOCK_PERIOD; , simplemente escribiría otro bucle para colocar sus datos adicionales en la línea de salida antes de escribir en el archivo.

Necesitará otra matriz además de H para su parte secundaria de enteros del archivo de entrada y para escribir los datos procesados. Ya que está procesando esos datos en otro lugar, recomiendo que estas matrices muestren señales en lugar de variables.

Si necesita enviar sus datos procesados con campos de 4 anchos (como '0000', '0002', etc.), puede definir una variable string , " zeros ", de longitud 4 en su archivo proceso para ayudar a rellenar tus valores:

-- "proc_data" is your processed data array
for k in 0 to <needed_length> loop
  zeros := (others=>'0');
  zeros(zeros'length-integer'image(proc_data(k))'length+1 to zeros'length) := integer'image(proc_data(k));
  write(v_OLINE,zeros);
  write(v_OLINE,string'(" "));
end loop;
v_OLINE := new string'(v_OLINE(1 to v_OLINE'length-1)); --Remove ending space
writeline(out_buffer,v_OLINE);

Asegúrese de que ninguno de sus enteros procesados sea más largo y luego 4, o obtendrá una falta de coincidencia de longitud. O simplemente ajuste los ceros al máximo. longitud necesaria.

Esto es todo lo que puedo sugerir. Tendrá que resolver los detalles sobre la cantidad de iteraciones de bucle que necesita para sus datos, etc., pero esto debería proporcionarle lo suficiente.

    
respondido por el user_007

Lea otras preguntas en las etiquetas