reading an array of parallel input data

Guest
Hi,

Thanks first of all for the previous responses that have been of great
help to me.
I have to write another test bench for a unit that takes on 8 inputs
(each of 10 bits)parallely. There will be an array of minimum of 1024
such elements(integer number of 1024 in general) in the data file.
What should be the format of the data file and how should be the
reading operation in VHDL. It's similar to corner memory where we
input data horizontally and read out vertically.

thanks.
 
On Thu, 19 Jun 2008 03:05:15 -0700 (PDT), koyel.aphy@gmail.com wrote:

I have to write another test bench for a unit that takes on 8 inputs
(each of 10 bits)parallely. There will be an array of minimum of 1024
such elements(integer number of 1024 in general) in the data file.
What should be the format of the data file and how should be the
reading operation in VHDL.
Choose a format that's easy to handle with VHDL's rather limited
string functions, but also can be easily manipulated by external
software. Comma-separated values (CSV) are a good choice, since
they are fairly easy to handle in VHDL but also work nicely with
spreadsheets and other programs - and they're human-readable.

Since your data are only 10 bits wide, it seems natural to
represent them as simple (decimal) integers. Each line
of your CSV file then looks like

25,1021,42,0,1000,58,1,76

You can simply work through the input file in VHDL until you
reach end-of-file.

It will also be OK if you permit spaces before the integers:

25, 1021, 42, 0, 1000, 58, 1, 76

since read() automatically skips over these spaces. Don't allow
spaces before the comma, though - that would need extra work.

Here's a piece of VHDL code that should be able to read such
data into a signal that's an array of 10-bit std_logic_vector.
Testing and debugging is left as an exercise :)
In the real world you would also want a great deal more
error checking than I have provided. Note that both
file_open() and read() have options to check for success;
if you don't use these options, then they will simply
fail with a fatal error if anything goes wrong.

use ieee.std_logic_1164.all, ieee.numeric_std.all;
...
subtype slv10 is std_logic_vector(9 downto 0);
type arr_slv10 is array(natural range <>) of slv10;
...
signal stimulus: arr_slv10(0 to 7);
file StimCSV: text;
...
process ReadAndApply;
variable c: character;
variable i: integer;
variable L: line;
begin
file_open(StimCSV, "my/file/name.csv", READ_MODE);
while not endfile(StimCSV) loop
wait until .... you need some more stimulus ....
readline(StimCSV, L); -- Get the next stimulus line
for j in s'range loop
read(L, i); -- Get the next integer
if j /= s'right then
-- it's not the last item; skip the next comma
read(L, c);
assert c = ',' report "Oops, bad separator";
end if;
stimulus(j) <= std_logic_vector(
to_unsigned(i, slv10'length));
end loop;
end loop;
file_close(StimCSV);
wait;
end process;


hth
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Wed, 25 Jun 2008 04:41:53 -0700 (PDT), koyel.aphy@gmail.com wrote:

"for j in s'range loop
read(L, i); -- Get the next integer
if j /= s'right then"

what is s and /= here?
sorry, that should have been

for j in stimulus'range loop
read(L, i); -- Get the next integer
if j /= stimulus'right then

(I started with a signal called "s", later changed
its name to "stimulus", and forgot to change those
two places).

The /= operator is standard VHDL: "not equal".
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
"for j in s'range loop
read(L, i); -- Get the next integer
if j /= s'right then"


what is s and /= here?
 
On Thu, 26 Jun 2008 05:18:42 -0700 (PDT), koyel.aphy@gmail.com wrote:

Here is what I am able to edit when I got few errors though there seem
to be no reason for those.
I have no idea what you mean. When I tried out my own code
just now I found a few silly errors that prevented it from
compiling; it took me about a minute to fix them.
What's the problem?

I don't want to change this code much
Why not? You'll learn far more if you *do* change it.
Hack around, add plenty of diagnostics, try things out,
see what happens, until you are confident that you
know how to do it all for yourself.

ReadAndApply:process
variable c: character;
variable i: integer;
variable L: line;
begin
file_open(StimCSV, "StimCSV.csv", READ_MODE);
wait until (clk'event and clk = '1');
[...]
din <= stimulus;
end if;
file_close(StimCSV);
wait;
You're OK with just getting exactly one line of stimulus
from the file? Doesn't sound very interesting to me.

Since you don't seem to want to debug for yourself,
here's my code fully debugged and working. I didn't
need to change very much. I've put in some fixed
time delays so that you can see the values on signal
"stimulus" in a wave viewer.

entity read_csv_test is end;

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

architecture A of read_csv_test is

subtype slv10 is std_logic_vector(9 downto 0);
type arr_slv10 is array(natural range <>) of slv10;

signal stimulus: arr_slv10(0 to 7);
file StimCSV: text;

begin

ReadAndApply: process
variable c: character;
variable i: integer;
variable L: line;
begin
file_open(StimCSV, "test.csv", READ_MODE);
while not endfile(StimCSV) loop
wait for 10 ns;
readline(StimCSV, L); -- Get the next stimulus line
for j in stimulus'range loop
read(L, i); -- Get the next integer
if j /= stimulus'right then
-- it's not the last item; skip the next comma
read(L, c);
assert c = ',' report "Oops, bad separator";
end if;
stimulus(j) <= std_logic_vector(
to_unsigned(i, slv10'length));
end loop;
end loop;
file_close(StimCSV);
wait for 20 ns;
wait;
end process;

end;

--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
Hi,

Here is what I am able to edit when I got few errors though there seem
to be no reason for those. But now I am getting undefined values at
the output and I checked that the stimulus signal is not taking the
values. I don't want to change this code much so it would be good if
you can see if I have missed something.

ReadAndApply:process
variable c: character;
variable i: integer;
variable L: line;
begin
file_open(StimCSV, "StimCSV.csv", READ_MODE);
wait until (clk'event and clk = '1');

if not endfile(StimCSV) and res= '1' and reset2 = '1' then

readline(StimCSV, L); -- Get the next stimulus line
for j in stimulus'range loop
read(L, i); -- Get the next integer
if j /= stimulus'right then
-- it's not the last item; skip the next comma
read(L, c);
assert c = ',' report "Oops, bad separator";
end if;
stimulus(j) <= std_logic_vector(
to_unsigned(i, WORD8'length));
end loop;
din <= stimulus;
end if;
file_close(StimCSV);
wait;
end process;
dout1 <= doutf1;
dout2 <= doutf2;

Thank you vary much again!
 
On Jun 26, 1:40 pm, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
On Thu, 26 Jun 2008 05:18:42 -0700 (PDT), koyel.a...@gmail.com wrote:
Here is what I am able to edit when I got few errors though there seem
to be no reason for those.

I have no idea what you mean.  When I tried out my own code
just now I found a few silly errors that prevented it from
compiling; it took me about a minute to fix them.  
What's the problem?

But now I am getting undefined values [...]
I don't want to change this code much

Why not?  You'll learn far more if you *do* change it.
Hack around, add plenty of diagnostics, try things out,
see what happens, until you are confident that you
know how to do it all for yourself.



ReadAndApply:process
   variable c: character;
   variable i: integer;
   variable L: line;
 begin
   file_open(StimCSV, "StimCSV.csv", READ_MODE);
    wait until (clk'event and clk = '1');
[...]
           din <= stimulus;
           end if;
   file_close(StimCSV);
   wait;

You're OK with just getting exactly one line of stimulus
from the file?  Doesn't sound very interesting to me.

Since you don't seem to want to debug for yourself,
here's my code fully debugged and working.  I didn't
need to change very much.  I've put in some fixed
time delays so that you can see the values on signal
"stimulus" in a wave viewer.

entity read_csv_test is end;

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

architecture A of read_csv_test is

  subtype slv10 is std_logic_vector(9 downto 0);
  type arr_slv10 is array(natural range <>) of slv10;

  signal stimulus: arr_slv10(0 to 7);
  file StimCSV: text;

begin

  ReadAndApply: process
    variable c: character;
    variable i: integer;
    variable L: line;
  begin
    file_open(StimCSV, "test.csv", READ_MODE);
    while not endfile(StimCSV) loop
      wait for 10 ns;
      readline(StimCSV, L);   -- Get the next stimulus line
      for j in stimulus'range loop
        read(L, i);    -- Get the next integer
        if j /= stimulus'right then
          -- it's not the last item; skip the next comma
          read(L, c);
          assert c = ',' report "Oops, bad separator";
        end if;
        stimulus(j) <= std_logic_vector(
                          to_unsigned(i, slv10'length));
      end loop;
    end loop;
    file_close(StimCSV);
    wait for 20 ns;
    wait;
  end process;

end;
Okay, the test bench has more than this part so that can also be the
reason for my wrong outputs. No I am not interested to read one line.
Sorry I forgot to include the count to be incremented for not using a
loop. However, I will now use the loop instead. I was not sure if I
can use the clock'event statement under loop and if all the statements
for one line in the input file will be executed for one clock pulse
then. That's all.
 
On Fri, 27 Jun 2008 06:34:39 -0700 (PDT), koyel.aphy@gmail.com wrote:

This is what I am using right now and I get the errors

Error at 30.000 ns(1): Textio read:: called on empty string or line
at 30.000 ns(1): Error: Oops, bad separator
this continues upto 100 ns.
Is it time for me to get angry? Surely not.

ADD SOME DIAGNOSTICS.

There is a CLUE here...
Textio read:: called on empty string or line

Now, I can't even start to guess why this might be so.
But if I were trying to debug it, I would begin by
printing each line of text that I read from the file,
before I start doing the read() operations. Something
like this would do the job:

...
readline(F, L); -- get line of text
-- Let's have a look at that line, before we read it
report "Got line from file: '" & L.all & "'";
...

And we'll probably find that there's a blank line, or
some spurious separator character, or something of the sort,
that's preventing our simple-minded read() operation from
working. And then we can fix it. This is a technique
that we skilled engineers have come to know as "debugging".

Alternatively, of course, we could continue to pester
a newsgroup with incomplete error reports.

Choose which you think is likely to be more productive
and a better learning experience.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
This is what I am using right now and I get the errors

Error at 30.000 ns(1): Textio read:: called on empty string or line
at 30.000 ns(1): Error: Oops, bad separator
this continues upto 100 ns.

even if I do not use the clock, I get the same errors. I have checked
the simulation in modelsim without the testbench that gives correct
result.


ReadAndApply: process
variable c: character;
variable i: integer;
variable L: line;
begin
file_open(StimCSV, "StimCSV.csv", READ_MODE);
while not endfile(StimCSV) loop
wait until(clk'event and clk = '1') and reset2 ='1';
readline(StimCSV, L); -- Get the next stimulus line
for j in stimulus'range loop
read(L, i); -- Get the next integer
if j /= stimulus'right then
-- it's not the last item; skip the next comma
read(L, c);
assert c = ',' report "Oops, bad separator";
end if;
stimulus(j) <= std_logic_vector(
to_unsigned(i, word10'length));
end loop;
din<= stimulus;
end loop;
file_close(StimCSV);
wait for 20 ns;
wait;
end process;
 
Thank you very much for all the information so much.

It worked out ultimately.

Yours sincerely.
 
Thanks a lot for all the information so far!

It worked out ultimately.
no more annoying questions :)

Best Regards
 

Welcome to EDABoard.com

Sponsor

Back
Top