cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
chevalier
Mentor
Mentor
1,812 Views
Registered: ‎10-07-2011

VHDL Testbench: Unable to read HEX data from data file

Jump to solution

Hi folks,

Using 2018.2 on Win10x64 and having trouble using hread() to read HEX data from a TEXT file and return it as STD_LOGIC_VECTOR(63 downto 0).

Data file is as folow:

8
00006D20
‭007FE180‬
‭007FE180‬
‭007FE180‬
‭007FE180‬
‭007FE180‬
‭007FE180‬
‭007FE180‬

The first line (8) is read successfully as an INTEGER value using read(). The second line is failing (using hread()).

I guess the functions below (from the <ieee.std_logic_textio> package) are called one after the other, with the last one (BIT_VECTOR) failing for some reason.

procedure HREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR) is
  variable tmp: STD_ULOGIC_VECTOR(VALUE'length-1 downto 0);
begin
  HREAD(L, tmp);
  VALUE := STD_LOGIC_VECTOR(tmp);
end HREAD;



procedure HREAD(L:inout LINE; VALUE:out STD_LOGIC_VECTOR; GOOD: out BOOLEAN) is
  variable tmp: STD_ULOGIC_VECTOR(VALUE'length-1 downto 0);
begin
  HREAD(L, tmp, GOOD);
  VALUE := STD_LOGIC_VECTOR(tmp);
end HREAD;



procedure HREAD(L:inout LINE; VALUE:out BIT_VECTOR;GOOD: out BOOLEAN) is
  variable ok: boolean;
  variable c:  character;
  constant ne: integer := value'length/4;
  variable bv: bit_vector(0 to value'length-1);
  variable s:  string(1 to ne-1);
begin
  if value'length mod 4 /= 0 then
    good := FALSE;
    return;
  end if;

  loop					-- skip white space
    read(l,c);
    exit when ((c /= ' ') and (c /= CR) and (c /= HT));
  end loop;

  Char2QuadBits(c, bv(0 to 3), ok, FALSE);
  if not ok then
    good := FALSE;
    return;
  end if;

  read(L, s, ok);
  if not ok then
    good := FALSE;
    return;
  end if;

  for i in 1 to ne-1 loop
    Char2QuadBits(s(i), bv(4*i to 4*i+3), ok, FALSE);
    if not ok then
      good := FALSE;
      return;
    end if;
  end loop;
  good := TRUE;
  value := bv;
end HREAD;

And the Char2QuadBits() is as below:

procedure Char2QuadBits(C: Character;
      RESULT: out Bit_Vector(3 downto 0);
      GOOD: out Boolean;
      ISSUE_ERROR: in Boolean) is
begin
  case c is
    when '0' => result :=  x"0"; good := TRUE;
    when '1' => result :=  x"1"; good := TRUE;
    when '2' => result :=  x"2"; good := TRUE;
    when '3' => result :=  x"3"; good := TRUE;
    when '4' => result :=  x"4"; good := TRUE;
    when '5' => result :=  x"5"; good := TRUE;
    when '6' => result :=  x"6"; good := TRUE;
    when '7' => result :=  x"7"; good := TRUE;
    when '8' => result :=  x"8"; good := TRUE;
    when '9' => result :=  x"9"; good := TRUE;
    when 'A' => result :=  x"A"; good := TRUE;
    when 'B' => result :=  x"B"; good := TRUE;
    when 'C' => result :=  x"C"; good := TRUE;
    when 'D' => result :=  x"D"; good := TRUE;
    when 'E' => result :=  x"E"; good := TRUE;
    when 'F' => result :=  x"F"; good := TRUE;

    when 'a' => result :=  x"A"; good := TRUE;
    when 'b' => result :=  x"B"; good := TRUE;
    when 'c' => result :=  x"C"; good := TRUE;
    when 'd' => result :=  x"D"; good := TRUE;
    when 'e' => result :=  x"E"; good := TRUE;
    when 'f' => result :=  x"F"; good := TRUE;
    when others =>
       if ISSUE_ERROR then
         assert FALSE report
        "HREAD Error: Read a '" & c &
           "', expected a Hex character (0-F).";
       end if;
       good := FALSE;
  end case;
end;

Any idea of what I may be doing wrong???

Cheers,

Claude

0 Kudos
1 Solution

Accepted Solutions
richardhead
Scholar
Scholar
1,745 Views
Registered: ‎08-01-2012

@chevalier 

I understand. In your original post you specified the slv to be STD_LOGIC_VECTOR(63 downto 0). But the hex values were 32 bits in your example eg. 007FE180‬

Why not add some debug in to see what line was actually read:

report "Line read = " & pLINE.all severity NOTE;

This prints the line out without modifying it

View solution in original post

Tags (3)
5 Replies
richardhead
Scholar
Scholar
1,780 Views
Registered: ‎08-01-2012

can you post your code - not the code from the non-standard std_logic_textio library. I know that works just fine. The problem is more likely in your code.

As a note - you suggest you're trying to read into a 64 bit std_logic_vector, yet the hex values are only 32 bit. This would result in a failed read.

0 Kudos
chevalier
Mentor
Mentor
1,757 Views
Registered: ‎10-07-2011

Hello @richardhead,

See the code below. As far as I know, HEX values are limited to 32 bits. INTEGERs are. STD_LOGIC_VECTORs have no length limitation. I did try reading 32-bit HEX value and it fails as well.

I'm NOT trying to read an HEX-Format INTEGER. I'm trying to read a STD_LOGIC_VECTOR.

I wonder if the HEX values in my data file are formatted OK. Is it OK to write DEADBEEF or is it needed to write x"DEADBEEF" or 16#DEADBEEF?

Is it OK to use underscore '_' between groups of digits (DEAD_BEEF) to ease reading?

Thanks for helping!

 

 

library std;
use std.standard.all;
use std.textio.all;

library ieee;
use ieee.std_logic_1164.all;

  -- ---------------------------------------------------------------------------
  -- This one is working since I'm able to read the integer on the first line of
  -- the file. It is reporting no FAILURE. A failure would terminate the simulation.
  procedure OpenFile(
      pFILENAME: in STRING;
      pMODE: in FILE_OPEN_KIND;
      pFD: out TEXT
    ) is

    variable vSTATUS: FILE_OPEN_STATUS;
  begin
    file_open(vSTATUS,pFD,pFILENAME,pMODE);

    if (vSTATUS /= OPEN_OK) then
      case vSTATUS is
        when STATUS_ERROR =>
          report "OpenFile(): File " & pFILENAME & " is already open; Exiting... :-("
          severity FAILURE;

        when NAME_ERROR =>
          report "OpenFile(): File " & pFILENAME & " is not found or inaccessible; Exiting... :-("
          severity FAILURE;

        when MODE_ERROR =>
          report "OpenFile(): File " & pFILENAME & " could not be opened with requested access mode; Exiting... :-("
          severity FAILURE;

        when others =>
          report "OpenFile(): Unknown error returned while opening " & pFILENAME & "; Exiting... :-("
          severity FAILURE;
      end case;
    end if;
  end procedure OpenFile;

  -- ---------------------------------------------------------------------------
  -- This one is working since I'm able to read the integer on the first line of
  -- the file. It is reporting no FAILURE. A failure would terminate the simulation.
  procedure ReadLineFromTextFile(
      file pFD: TEXT;
      pLINE: out LINE
    ) is
  begin
    while (not(endfile(pFD))) loop
      readline(pFD,pLINE);
      exit when (pLINE'length > 0);
    end loop;

    assert (pLINE'length > 0)
      report "ReadLineFromTextFile(): Unexpected end of file..."
      severity FAILURE;
  end procedure ReadLineFromTextFile;

  -- ---------------------------------------------------------------------------
  -- This one is used to read INTEGER values from the first line of the file. It
  -- is working. File data is decimal radix and must be within the usual INTEGER
  -- range (-‭2,147,483,6487 to ‭2,147,483,648‬).
  procedure ReadDataFromTextLine(
      pLINE: inout LINE;
      pDATA: out INTEGER             -- <<<<<<<<< Returned data is INTEGER
    ) is

    variable vGOOD: BOOLEAN;
  begin
    read(pLINE,pDATA,vGOOD);         -- <<<<<<<<< Calling read()

    assert (vGOOD)
      report "ReadDataFromTextLine(): Failed to read INTEGER value from LINE."
      severity FAILURE;
  end procedure ReadDataFromTextLine;

  -- ---------------------------------------------------------------------------
  -- This one is used to read STD_LOGIC_VECTOR values from all but the first line
  -- of the file. It is NOT working. File data is HEX radix and with unrestricted
  -- range.
  procedure ReadDataFromTextLine(
      pLINE: inout LINE;
      pDATA: out STD_LOGIC_VECTOR    -- <<<<<<<<< Returned data is 
    ) is

    variable vGOOD: BOOLEAN;
  begin
    hread(pLINE,pDATA,vGOOD);        -- <<<<<<<<< Calling hread().
                                     --           Returning vGOOD = FALSE
                                     --           Returning pDATA = x"UUUUUUUU"
                                     -- I can trace down to here but I'm unable
                                     -- to trace INTO hread().

    assert (vGOOD)
      report "ReadDataFromTextLine(): Failed to read STD_LOGIC_VECTOR value from LINE."
      severity FAILURE;
  end procedure ReadDataFromTextLine;


-- -----------------------------------------------------------------------------
entity Testbench is
end entity;

-- -----------------------------------------------------------------------------
architecture Simulation of Testbench is
  ...
begin
 ...
 
  Verify: process
    file vFD: TEXT;

    variable vLINE: LINE;
    variable vVECTORS: NATURAL;
    variable vDATA: STD_LOGIC_VECTOR(63 downto 0);
    variable n: NATURAL;             -- Run index
    variable i: NATURAL;             -- Test vector index
    variable checked: NATURAL := 0;  -- Verification counter
    variable errcnt: NATURAL := 0;   -- Error counter
  begin
    for n in 1 to cRUNS loop
      -- Open source data file
      OpenFile(cTEST_CASE & "Golden.txt",read_mode,vFD);

      -- Read header
      ReadLineFromTextFile(vFD,vLINE);
      ReadDataFromTextLine(vLINE,vVECTORS);    -- <<<<<<<<<<< This one succeeds!

      for i in 0 to vVECTORS - 1 loop
        -- Read golden vector
        ReadLineFromTextFile(vFD,vLINE);
        ReadDataFromTextLine(vLINE,vDATA);     -- <<<<<<<<<<< This one fails!

        wait until ((M_AXIS_TVALID = '1') and (M_AXIS_TREADY = '1'));
        wait until falling_edge(CLOCK);

        if (abs(SIGNED(M_AXIS_TDATA) - SIGNED(vDATA)) > cTOLERANCE) then
          errcnt := errcnt + 1;
          report "Test run " & NATURAL'image(n) & ": Test vector " & NATURAL'image(i) & " FAILED! Expected " & to_hstring(vDATA) & "; Got " & to_hstring(M_AXIS_TDATA) & "."
            severity ERROR;
        end if;

        checked := checked + 1;
        wait until rising_edge(CLOCK);
      end loop;

      CloseFile(vFD);

      if (errcnt > 0) then
        report "Test run " & NATURAL'image(n) & " FAILED with " & NATURAL'image(errcnt) & " error(s) (" & NATURAL'image(checked) & " verifications performed)! :-("
          severity ERROR;

        errcnt := 0;
      else
        report "Test run " & NATURAL'image(n) & " PASSED (" & NATURAL'image(checked) & " verifications performed)! :-)"
          severity NOTE;
      end if;

      checked := 0;
    end loop;

    wait;
  end process;
end architecture;

 

 

Claude

0 Kudos
richardhead
Scholar
Scholar
1,746 Views
Registered: ‎08-01-2012

@chevalier 

I understand. In your original post you specified the slv to be STD_LOGIC_VECTOR(63 downto 0). But the hex values were 32 bits in your example eg. 007FE180‬

Why not add some debug in to see what line was actually read:

report "Line read = " & pLINE.all severity NOTE;

This prints the line out without modifying it

View solution in original post

Tags (3)
chevalier
Mentor
Mentor
1,733 Views
Registered: ‎10-07-2011

@richardhead

Graet thanks Richard! I didn't know about the "pLINE.all" you suggested. Thanks as well for pointing out my data were 32 bits... When 2 x 3 starts to make 5, it remains 5 for a long time...

With the report line you suggested, I found out there were some weird characters in my strings, not visible in the text editor.

 

# EXECUTION:: NOTE   : Line read = '0000000000006D20'.
# EXECUTION:: NOTE   : Line read = '‭00000000007FE180‬'.
# EXECUTION:: NOTE   : Line read = '00000000007FE180‬'.

 

I finally cleaned-up my file and everything is working fine now.

In the mean time, I thought of using the hread() version of the procedure that doesn't have the third parameter. That was helpful as well.

 

Using read(pLINE,pDATA) rather than read(pLINE,pDATA,vGOOD)

# EXECUTION:: ERROR  : STD_LOGIC_1164.HREAD End of string encountered
# EXECUTION:: ERROR  : STD_LOGIC_1164.HREAD Error: Read a 'â', expected a Hex character (0-F).

 

Thanks again!

Claude

0 Kudos
richardhead
Scholar
Scholar
1,726 Views
Registered: ‎08-01-2012

For reference, a line type is simple a pointer to a string. (called an access type in VHDL). Any access type can be dereferenced using   .all

0 Kudos