file array read for ROM

Discussion in 'VHDL' started by jack kilby, Nov 25, 2003.

  1. jack kilby

    jack kilby Guest

    I have a array (ROM with 32 bits columns and 128 rows)in my VHDL code
    and need to give the values to it through test bench.(from a Textio
    file)
    Does anybody know how to do it for a ROM block.Thanks in advance
     
    jack kilby, Nov 25, 2003
    #1
    1. Advertising

  2. (jack kilby) wrote:

    :I have a array (ROM with 32 bits columns and 128 rows)in my VHDL code
    :and need to give the values to it through test bench.(from a Textio
    :file)
    : Does anybody know how to do it for a ROM block.Thanks in advance

    Here's a package to read Motorola S-records into a memory (assumed to
    be a shared variable). Usual disclaimers apply:

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

    package memory is

    -- Memory array which can be loaded/dumped to files
    type T_MEMARRAY is array(natural range <>, natural range <>) of
    std_logic;

    procedure load_memory ( -- Load from Motorola
    S-records
    constant FNAME : in string; -- File name
    variable MEMORY : inout T_MEMARRAY); -- Memory array

    procedure clear_memory (
    variable MEMORY : out T_MEMARRAY); -- Memory array

    end memory;

    -------------------------------------------------------------------

    package body memory is

    subtype T_8B is unsigned(7 downto 0);

    constant f_void : natural := 16#101#; -- Null input line
    constant f_error : natural := 16#102#; -- Input-error flag
    constant f_eof : natural := 16#103#; -- Input EOF flag
    constant maxlen : natural := 32; -- Max. data bytes in
    S-record

    type hexdata is array(0 to maxlen-1) of T_8B;

    type hex_rec is record
    locn : natural; -- Memory start address
    size : natural; -- Byte count
    data : hexdata; -- Byte data
    end record;

    procedure getbyte( -- Get next byte from line
    data : inout line; -- Line to read from
    csum : inout natural; -- Checksum
    ans : out natural -- Byte value
    );

    procedure gethexline( -- Read a Motorola S-record
    file infile : text; -- File to read
    ans : out hex_rec; -- Decoded record
    LINUM : inout natural -- Line counter
    );

    -- purpose: Load memory array from Motorola S-records
    procedure load_memory (
    constant FNAME : in string; -- File name
    variable MEMORY : inout T_MEMARRAY) is
    file ROMDAT : text open read_mode is FNAME;
    variable XREC : hex_rec; -- Decoded line from file
    variable LINUM : natural; -- Line count
    variable ONEB : T_8B; -- Byte from file
    variable WIDTH, HEIGHT, NBYTES : natural;
    variable CLIN, BITO : natural;
    begin -- load_memory
    WIDTH := MEMORY'length(2); -- Get array dimensions
    HEIGHT := MEMORY'length(1);
    NBYTES := (WIDTH/8)*HEIGHT;
    LINUM := 0;
    while not endfile(ROMDAT) loop
    gethexline(ROMDAT, XREC, LINUM); -- Process one line
    case XREC.size is
    when f_void => -- Skip this line
    next;
    when f_eof =>
    exit; -- Done with it
    when f_error =>
    assert false
    report "Error in " & FNAME & ": line " &
    natural'image(LINUM)
    severity error;
    when others => -- Process the data
    assert (XREC.locn + XREC.size <= NBYTES)
    report "Address over-range in " & FNAME & ": line " &
    natural'image(LINUM)
    severity warning;
    for i in XREC.size-1 downto 0 loop -- Copy in data
    ONEB := XREC.data(i);
    CLIN := (XREC.locn+i)/(WIDTH/8); -- Cache line / memory
    locn.
    BITO := 8*((XREC.locn+i) mod (WIDTH/8)); -- Bit offset
    for j in ONEB'range loop
    MEMORY(CLIN, BITO+j) := ONEB(j);
    end loop; -- j
    end loop; -- i
    end case;
    end loop;
    end load_memory;

    -----------------------------------------------------------------------

    -- purpose: Clear memory contents to zero
    procedure clear_memory (
    variable MEMORY : out T_MEMARRAY) is -- Memory array
    begin -- clear_memory
    for i in MEMORY'range(1) loop
    for j in MEMORY'range(2) loop
    MEMORY(i,j) := '0'; -- Clear out
    end loop; -- j
    end loop; -- i
    end clear_memory;

    -----------------------------------------------------------------------


    --------------------------------------------------------------------------
    -- Function: gethex
    -- Purpose: Convert ASCII to hexadecimal
    -- Input: character
    -- Output: natural

    --------------------------------------------------------------------------
    function gethex( -- Convert ASCII to
    hexadecimal
    ch : character -- Character to convert
    ) return natural is -- Decoded value, or f_error

    begin
    if ('0' <= ch) and (ch <= '9') then
    return character'pos(ch) - character'pos('0');
    elsif ('A' <= ch) and (ch <= 'F') then
    return character'pos(ch) - character'pos('A') + 10;
    elsif ('a' <= ch) and (CH <= 'f') then
    return character'pos(ch) - character'pos('a') + 10;
    else
    return f_error;
    end if;
    end gethex;


    --------------------------------------------------------------------------
    -- Procedure: getbyte
    -- Purpose: Get next byte from line
    -- InOut: line, natural
    -- Output: natural

    --------------------------------------------------------------------------
    -- Since the line must be INOUT, this cannot be a function.
    procedure getbyte( -- Get next byte from line
    data : inout line; -- Line to read from
    csum : inout natural; -- Checksum
    ans : out natural -- Byte value
    ) is
    variable ch : character;
    variable x : natural;
    variable res : natural := 0;
    variable rdok : boolean; -- Read-function check
    begin
    ans := f_error; -- Pre-set to trap errors
    for i in 1 to 2 loop -- Process two input
    characters
    if (data'length = 0) then -- End of line?
    return;
    end if;
    read(data, ch, rdok); -- Next character
    if not rdok then
    return; -- Read errors
    end if;
    x := gethex(ch); -- To hexadecimal
    if (x = f_error) then
    ans := f_error; -- Invalid data
    return;
    end if;
    res := (res * 16) + x; -- Big-endian data
    end loop;
    ans := res; -- Post the result
    csum := csum + res;
    end getbyte;


    --------------------------------------------------------------------------
    -- Procedure: gethexline
    -- Purpose: Read a line from file, & decode it as a Motorola
    S-record
    -- Input: text
    -- Output: hex_rec

    --------------------------------------------------------------------------
    -- Since the file must be INOUT, this cannot be a function.
    procedure gethexline( -- Read a Motorola S-record
    file infile : text; -- File to read
    ans : out hex_rec; -- Decoded record
    LINUM : inout natural -- Line number
    ) is
    variable data : line; -- Source-file line
    variable outrec : hex_rec; -- Record for output
    variable ch : character;
    variable csum : natural; -- Checksum
    variable adlen : natural; -- No. of address bytes
    variable bcount : natural; -- Byte counter
    variable x : natural;
    variable rdok : boolean; -- Read-function check
    begin
    ans.locn := 0; -- Pre-set to trap errors
    ans.size := f_error;
    csum := 0;

    if endfile(infile) then -- Trap EOF
    ans.size := f_eof;
    return;
    end if;

    LINUM := LINUM + 1;
    readline(infile, data); -- Fetch the line
    read(data, ch, rdok); -- Record type-mark
    if not rdok then -- Catch read errors
    return;
    end if;

    case ch is
    when '$' => -- Block header data
    while not endfile(infile) loop
    LINUM := LINUM + 1;
    readline(infile, data); -- Get next line
    read(data, ch, rdok); -- Record type-mark
    if not rdok then -- Catch read errors
    return;
    end if;
    if ch = '$' then -- Mating block-mark
    ans.size := f_void;
    return; -- Let the caller skip this
    line
    end if;
    end loop;
    ans.size := f_eof; -- Premature EOF
    return;

    when 'S' => -- S-record data
    read(data, ch, rdok); -- Record sub-type
    if not rdok then
    return;
    end if;

    case ch is
    when '1' => -- 2-byte address
    adlen := 2;
    when '2' => -- 3-byte address
    adlen := 3;
    when '3' => -- 4-byte address
    adlen := 4;
    when others => -- Unrecognised type
    return;
    end case;

    getbyte(data, csum, bcount); -- Get byte counter
    if (bcount = f_error) or (bcount > maxlen) then
    return;
    end if;
    outrec.size := bcount;

    outrec.locn := 0; -- Get the start address
    for i in 1 to adlen loop
    getbyte(data, csum, x);
    if x = f_error then
    return; -- Read error
    end if;
    outrec.locn := (outrec.locn * 256) + x;
    end loop; -- i

    for i in 0 to bcount-1 loop
    getbyte(data, csum, x); -- Get next data byte
    if x = f_error then
    return;
    end if;
    outrec.data(i) := to_unsigned(x, 8);
    end loop; -- i

    getbyte(data, csum, x); -- Get checksum (& add to
    count)

    while csum > 255 loop -- Reduce modulo-256
    csum := csum - 256; -- "mod" can behave oddly!
    end loop;

    if csum /= 255 then
    return; -- Checksum error
    end if;

    ans := outrec; -- Return data from file

    when others => -- Corrupt line
    return;
    end case;

    end gethexline;

    end memory;
     
    David R Brooks, Nov 26, 2003
    #2
    1. Advertising

  3. jack kilby wrote:
    > I have a array (ROM with 32 bits columns and 128 rows)in my VHDL code
    > and need to give the values to it through test bench.(from a Textio
    > file)
    > Does anybody know how to do it for a ROM block.Thanks in advance


    related thread:

    http://groups.google.com/groups?q=this_rom goel

    -- Mike Treseler
     
    Mike Treseler, Nov 26, 2003
    #3
  4. jack kilby

    jack kilby Guest

    lookup table -read from testbench file ?

    hello,
    i think my question was not clear.I want to know if it is possible to
    give the values to a look up table from the TESTBENCH through a text
    I/O File (I dont want to force the values through source code ).If
    yes.Kindly explain how.
    Thanks and regards
    jack


    Mike Treseler <> wrote in message news:<>...
    > jack kilby wrote:
    > > I have a array (ROM with 32 bits columns and 128 rows)in my VHDL code
    > > and need to give the values to it through test bench.(from a Textio
    > > file)
    > > Does anybody know how to do it for a ROM block.Thanks in advance

    >
    > related thread:
    >
    > http://groups.google.com/groups?q=this_rom goel
    >
    > -- Mike Treseler
     
    jack kilby, Nov 26, 2003
    #4
  5. Re: lookup table -read from testbench file ?

    jack kilby wrote:

    > i think my question was not clear.I want to know if it is possible to
    > give the values to a look up table from the TESTBENCH through a text
    > I/O File (I dont want to force the values through source code ).If
    > yes.Kindly explain how.


    A VHDL testbench can only drive or check VHDL data types.
    If you intend to enter this data by hand anyway,
    consider using VHDL constants as in my previous example.

    If you already have the data file, and you don't want
    to type anything in, then you have to make the
    testbench do the conversion as in David's previous
    example of Motorola S-records, which is a very
    common format for generated binary data.

    -- Mike Treseler
     
    Mike Treseler, Nov 26, 2003
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Brad Smallridge

    Cypress Warp2 ROM Module File Format

    Brad Smallridge, Jan 10, 2004, in forum: VHDL
    Replies:
    1
    Views:
    613
    Brad Smallridge
    Jan 10, 2004
  2. tanukichu
    Replies:
    2
    Views:
    1,284
    jeppe
    Jul 21, 2008
  3. hangeonos
    Replies:
    0
    Views:
    804
    hangeonos
    May 24, 2009
  4. dkbauter
    Replies:
    1
    Views:
    2,209
    dkbauter
    Aug 4, 2009
  5. Alex Dowad
    Replies:
    4
    Views:
    326
    Michel Demazure
    May 1, 2010
Loading...

Share This Page