0
\$\begingroup\$

Hi I am trying to read data from a file which contains 62500 lines of 12-bit binary numbers in order to instantiate my 2D array(sort of a RAM). However, my problem is that this process happens in one clock cycle, which puts extreme amount of pressure on the hardware and synthesis does not end. I want to read one line of data from file in every clock cycle. However, I cannot because the function I call is not very open to modification. How can I read a single line of data in every clock cycle??

Here is what I have so far after weeks of research and experimentation

 type RamType is array(0 to PICTURE_WIDTH_HEIGHT - 1, 0 to 
 PICTURE_WIDTH_HEIGHT - 1) of bit_vector(11 downto 0);

 impure function InitRamFromFile (RamFileName : in string) return RamType is
 FILE RamFile : text is in RamFileName;
 variable RamFileLine : line;
 variable RAM : RamType;
 begin
 for y in 0 to 249 loop
 for x in 0 to 249 loop
 readline (RamFile, RamFileLine);
 read (RamFileLine, RAM(x,y));
 end loop;
 end loop;
 return RAM;
 end function;

 signal RAM : RamType := 
 InitRamFromFile("\\ASUS\Users\AsusPc\Desktop\project_son\pictureData.data");

I tried to replace nested FOR loops above with nested IFs and convert variables above to signals in order to make this process suitable for my purpose but I received errors which simply says RamFile and RamFileLine must be variable. I have already run out of ideas. Please help me. I am using BASYS3 board and Vivado2017.2 environment.

By the way, picture_height_width is 250 and I did not do what I said above in function. I got rid of function decleration and tried to do it in classic manner.

pictureData.data contains pure binary data and nothing else.

\$\endgroup\$
  • \$\begingroup\$ Calling readline on a binary file isn't going to do what you seem to expect since it reads until it sees a 0x0A (new line character). If you want to use readline you need to put each pixel on its own line... Also, this isn't going to work on a real fpga \$\endgroup\$ – ks0ze Apr 30 '18 at 13:02
4
\$\begingroup\$

It is pointless to try this approach. Synthesis can ONLY read from a file at initialisation time - there are no "files" on an actual FPGA. Reading data in a clocked process requires a hardware interface ranging from a simple serial UART to an Ethernet MAC or a SD card interface (with an SD card socket on your FPGA board), all these re significant projects in their own right.

If your synthesis tool has performance problems initialising memory via e.g. a function call which reads a file (and I know some do) you have to find another approach.

Test this by adding a "Report" statement each time you start reading a new row from the file. If you're using Xilinx ISE of a certain vintage you'll see it slow down quadratically as it progresses, a sufficiently large array taking hours for a job any other tool can complete in under a second. (Alternatively the "Report" statements may flash past in seconds, showing you that something else is taking the time.

One simple alternative approach (if the "Report" test shows this is the problem) is to use a small program written in whatever language you choose, to read that file, and write another file consisting of the same data, but preceded by something like

library ieee;
use ieee.numeric_std.all;

package ROM is
   subtype byte is unsigned (7 downto 0);
   type ROM_type is array(0 to 249, 0 to 249) of byte;
   constant My_ROM : ROM_type := (

and followed by

   );
end package My_ROM;

And use that package in your design.

But I suspect the problem lies elsewhere and you're going to have to stop, spend a year or two learning digital systems design, and come back to this problem later.

\$\endgroup\$
  • \$\begingroup\$ Thanks a lot, I am doing package thing you suggested. I wonder if there is any settings I can change to speed up sythesis. Do you know any? Such as flatten hierarchy or sythesis strategy. \$\endgroup\$ – OnurTR Apr 29 '18 at 13:49
  • 1
    \$\begingroup\$ Find out why it's so slow and rewrite that. Start with a 10 x 10 picture, see how long that takes. How much does it slow down moving to 20 x 20? 30 x 30? Actually processing 250 x 250 is a totally lost cause with your current approach but you ought to be able to synthesise the ROM holding the image itself easily enough. \$\endgroup\$ – Brian Drummond Apr 29 '18 at 14:18
  • \$\begingroup\$ "Speeding up synthesis " -- it depends on in how simple manner your code convey your requirement to the synthesizer, which is a dedicate tool. Improving the performance depends heavily on how you code, then followed by tool specific options like design strategies , and the FPGA you have chosen. If you are looking for "strategies " in HDL code, refer to Xilinx and Altera HDL design guidelines document. But still as Brian said: some strong basement in Digital systems design is must ... \$\endgroup\$ – Mitu Raj Apr 29 '18 at 16:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.