cancel
Showing results for 
Search instead for 
Did you mean: 
Visitor
Visitor
175 Views
Registered: ‎04-05-2019

Having trouble initialising RAM from file (VHDL)

Hi, I am having trouble initialising the contents of RAM from a file. I am targeting a XC7A35TICSG324-1L FPGA (on the Digilent Arty A7 board). I am not an FPGA expert, so the issue could be something silly I am doing or my own misunderstanding. I would greatly appreciate any help to get this working!

I have a text file that stores the data. Each bit is separated by a space, and each new vector is on a new line. For example, the text file sort of looks like this:

1 1 1 1
1 0 0 1
1 0 0 1

which would correspond to "1111", "1001" then "1001" initialised in RAM. 

The VHDL that I have written is based off the example given in the Synthesis user guide (UG901)  in Chapter 4 HDL Coding Techniques : Initializing RAM Contents. I have reproduced my VHDL below: 

type rom_t is array (0 to DEPTH-1) of std_logic_vector(DATA_WIDTH-1 downto 0);
impure function mem_init(file_name : string)
             return rom_t is
file fp : text open read_mode is file_name;
variable image_data : rom_t;
variable i_line : line; 
variable tmp_bit : bit;
begin
 --iterate though rows in file
 for i in 0 to DEPTH-1 loop
	readline(fp, i_line);
        --iterate though individual bits in the row
	for j in 0 to DATA_WIDTH-1 loop
		read(i_line, tmp_bit);
		image_data(i)(j) := to_stdulogic(tmp_bit);
	end loop;
 end loop;
 return image_data;
end mem_init;
signal rom : rom_t := mem_init("data.txt"); -- I use the absolute file path, just removed it here in the example 

The problem is that the memory is not being initialised after running synthesis in Vivado. The tool is (I think) initialising it as all zeros (I get the message "propagating zeros across element") and as such is trimming away the whole module. When I look at the schematic after synthesis/implementation the outputs are all simply tied together and to ground. 

When I simulate the design in ModelSim and in Vivado's XSIM, I can see the RAM is being initialised correctly as I expect.

To make sure it is not caused by something else written within or outside the RAM module, I have tried initialising the ram with random constants, for example, replacing the initial signal assignment like shown below:

signal rom : rom_t := (0=> (others=> '1'), 1=> (others=> '0'), 2=>(others=> '0'), others=> (others=> '1') );

 This works as expected. The RAM is correctly initialised in synthesis and when I load the design onto the board it works as how I would expect. 

I am unsure of what I can do to get it working correctly. If it makes any difference, I am using Vivado 2018.3 on a Windows 10 computer.

Thanks for your help.

 

0 Kudos
2 Replies
Highlighted
Xilinx Employee
Xilinx Employee
145 Views
Registered: ‎11-30-2007

Re: Having trouble initialising RAM from file (VHDL)

I copied and modified the Initializing Block RAM From an External Data File (VHDL) example found in the Vivado Design Suite Synthesis User Guide (UG901; v2019.2; pp 157-158).  I modified to make a ROM.  You could modify to automatically calculate the address width but I just filled in manually for testing.  I created a 8-bit x 1024-depth.

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

entity rams_init_file is
generic (
  DEPTH : integer := 1024;
  DATA_WIDTH : integer := 8);
port (
  clk  : in  std_logic;
  en   : in  std_logic;
  addr : in  std_logic_vector(8 downto 0);
  dout : out std_logic_vector(DATA_WIDTH-1  downto 0));
end rams_init_file;

architecture syn of rams_init_file is

 type RamType is array (0 to DEPTH-1) of bit_vector(DATA_WIDTH-1 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 I in RamType'range loop   readline(RamFile, RamFileLine);
   read(RamFileLine, RAM(I));
 end loop;
   return RAM;
 end function;
 
 signal RAM : RamType := InitRamFromFile("C:/X/Forums/2020_03_25/data.txt");

begin

 process(clk)
 begin
   if rising_edge(clk) then
     if (en='1') then
       dout <= to_stdlogicvector(RAM(to_integer(unsigned(addr))));
     end if;
   end if;
 end process;
 
end syn;

I have attached the data.txt file used to initialize the ROM.

You can see the properties of the BRAM in the Synthesized Design Checkpoint.

forums_rom_post_synth.jpg

 

Highlighted
Visitor
Visitor
108 Views
Registered: ‎04-05-2019

Re: Having trouble initialising RAM from file (VHDL)

Thank you. I know that it works when reading in the whole vector from the line at once. I had since modified the data file so that the bits were not separated by a space and read in the data as in your example.

My original data file had each bit separated by a space so I was trying to read in each bit at a time, which I couldn't get working correctly. I'm still curious as to why that was not working.

 

0 Kudos