Verilog "initial" block with $readmemb or $readmemh
Memories can be initialized using $readmemb or $readmemh system tasks with a memory initialization file (.mif) (download complete example here):
reg [DATA_WIDTH-1:0] mem[0:2**ADDR_WIDTH-1];
initial begin
$readmemh("mem_init_vlog.mif", mem, 0, 255);
end
$readmemh("mem_init_vlog.mif", mem, 0, 255);
end
XST has two different Verilog parsers depending on the target device. The old parser is used for Virtex5/Spartan3 and older devices. For Virtex6/Spartan6 and newer devices, the new parser will be used. The old parser has a few restrictions on the memory initialization:
- The entire memory array must be initialized. For example, if the memory has 256 words, all 256 words must be explicitly initialized. Otherwise the initialization will be ignored with this warning message: WARNING:Xst:2319 - "rom_vlog.v" line 21: Signal mem in initial block is partially initialized. The initialization will be ignored.
- Make sure the .mif file does NOT have any unnecessary white spaces (especially "tab") anywhere. Or it will issue some obscure error message like this: ERROR:Xst:2354 - "rom_vlog_mif.v" line 18: Value 262025260 found at line 256 is not hexadecimal in call of system task $readmemh.
- Starting address (@hh), Verilog comments (// or /* */), and multiple values per line are not supported in the .mif file. Or as you guessed it, it will issue other weird errors.
VHDL functions
Memory can be initialized in VHDL by using a function at signal declaration. Functions like sin(), cos()in the IEEE math_real library are supported by XST for initializing memories. The code snippet below shows how to generate a look up table with a cosine wave (download complete example here):
constant MEM_DEPTH : integer := 2**ADDR_WIDTH;
type mem_type is array (0 to MEM_DEPTH-1) of signed(DATA_WIDTH-1 downto 0);
function init_mem return mem_type is
constant SCALE : real := 2**(real(DATA_WIDTH-2));
constant STEP : real := 1.0/real(MEM_DEPTH);
variable temp_mem : mem_type;
begin
for i in 0 to MEM_DEPTH-1 loop
temp_mem(i) := to_signed(integer(cos(2.0*MATH_PI*real(i)*STEP)*SCALE), DATA_WIDTH);
end loop;
return temp_mem;
end;
constant mem : mem_type := init_mem;
VHDL with external data files
XST User Guide has VHDL examples of initializing block RAMs with external data files. It's listed here so that you are aware of this option. The XST UG should always be your first stop for coding styles and techniques. I would like to point out two things highlighted in red in the code snippet below (download complete example here):
- The "file" declaration in XST UG uses VHDL-87 syntax. The code snippet below uses VHDL-93 syntax because that is the default VHDL starndard XST uses.
- The second argument for the "read" function needs to be a bit_vector. std_logic_vector or signed types are not supported by the "read" function in IEEE std.textio package.
constant MEM_DEPTH : integer := 2**ADDR_WIDTH;
type mem_type is array (0 to MEM_DEPTH-1) of signed(DATA_WIDTH-1 downto 0);
impure function init_mem(mif_file_name : in string) return mem_type is
file mif_file : text open read_mode is mif_file_name;
variable mif_line : line;
variable temp_bv : bit_vector(DATA_WIDTH-1 downto 0);
variable temp_mem : mem_type;
begin
for i in mem_type'range loop
readline(mif_file, mif_line);
read(mif_line, temp_bv);
temp_mem(i) := signed(to_stdlogicvector(temp_bv));
end loop;
return temp_mem;
end function;
constant mem : mem_type := init_mem("mem_init_vhd.mif");
Verify Memory Content in Synthesized Netlist
There are a couple of ways to verify that the memory is correctly initialized by the synthesis tool:
- The values of INIT_xx attributes of the block RAM can be examined in PlanAhead by opening the netlist design in PlanAhead, selecting the instance for the memory, and selecting the "Attributes" tab of the "Instance Properties" window.
- A post-synthesis simulation model can be generated for the synthesized netlist in Project Navigator or by using netgen tool. This simulation model can be used in the existing testbench to check if the initialization data made into the netlist correctly. The waveform below shows the correct outputs from the ROMs created in the Verilog .mif (counter) and VHDL function (sine wave) methods.
According to UG687, XST supports specifying initial memory contents using an external data file. Here is the corresponding VHDL code snippet:
ReplyDeletetype RamType is array(0 to 127) of bit_vector(31 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("rams_20c.data");
@Guy Eschemann, thanks a lot for posting this code snippiet. My main intention is to talk about things not directly covered in the UGs, especially XST UG, which should be the first stop for coding styles and techniques. Having said that, I will add a complete example using external file in VHDL.
ReplyDeletehello jim,
ReplyDeleteI have a simple question. Will this work. I dun want to initialize my memory. Basically zero values is fine for me.
will this code work?
module register_file_behav(clk,write,r1_addr,r2_addr,wr_addr,wr_data,r1_data,r2_data);
input clk;
input write;
input [4:0] r1_addr;
input [4:0] r2_addr;
input [4:0] wr_addr;
input [31:0] wr_data;
output reg[31:0] r1_data;
output reg[31:0] r2_data;
integer i;
reg [31:0]out_reg [31:0];
always @(posedge clk)
begin
r1_data<= out_reg[r1_addr];
r2_data<= out_reg[r2_addr];
if(write)
begin
out_reg[wr_addr]<= wr_data;
end
end
endmodule
regards,
sid
@sid If you only read a memory location after you write to it, your code looks fine to me.
ReplyDeleteHello Jim.
ReplyDeleteThank you for your wonderful post.
I have used for my LUT to read values from a text file and assign them to the address in the LUT. I need to write a test bench for my VHDL code, but I am having difficulties due to the FOR loop and reading from a text file in the test bench itself.
Can you please help me? or show me how I can use the FOR loop in my case (NB. my code is very similar to yours above).
Here’s my VHDL code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use STD.TEXTIO.ALL;
use IEEE.STD_LOGIC_TEXTIO.ALL;
Entity ROM_ent is
Port(
ADDR: IN std_logic_VECTOR(7 downto 0);
CLK: IN std_logic;
DATA: OUT std_logic_VECTOR(7 downto 0)
);
end ROM_ent;
Architecture Behavioral of ROM_ent is
type rom_type is array (255 downto 0) of std_logic_vector (7 downto 0);
impure function InitRomFromFile (RomFileName : in string) return rom_type is
FILE romfile : text is in RomFileName;
variable RomFileLine : line;
variable ROM : rom_type;
begin
for i in rom_type'range loop
readline(romfile, RomFileLine);
read(RomFileLine, ROM(i));
end loop;
return ROM;
end function;
Constant ROM : rom_type := InitRomFromFile("Doc1.Txt");
begin
process (CLK)
begin
if(CLK'event and CLK = '1') then
DATA <= ROM(to_integer(unsigned(ADDR)));
end if;
end process;
end Behavioral;
Thank you !!!
Kind Regards,
Ahmed
*** I need to use a FOR loop in my test bench ***
ReplyDeletehello friends
ReplyDeletei am new to xilinx ise
i have xilinx 12.3
ver-m.70d
i am getting error in behavioural model simulation
'INFO:ProjectMgmt - The selected process was not run because a prior process failed.'
my rtl logic is also done,and implementaion view is fully done.plz help
hello friends
ReplyDeletei am new to xilinx ise
i have xilinx 12.3
ver-m.70d
i am getting error in behavioural model simulation
'INFO:ProjectMgmt - The selected process was not run because a prior process failed.'
my rtl logic is also done,and implementaion view is fully done.plz help
@Ashwani Since your question has nothing to do with the post, please open a webcase with Xilinx tech support or post the question to the simulation board on Xilinx forums: http://forums.xilinx.com/t5/Simulation-and-Verification/bd-p/SIMANDVERIBD
ReplyDeleteHello friends,
ReplyDeleteI have a question.I want to store fixed point numbers(integer+fraction) on fpga.I was unable to do with above discussed code by jim.Could u help me
Thanks for this nice article.
ReplyDeleteCould you please let me know if there has been any update regarding this or it is still the same.
Moreover, is there any way to initialize memory with floating numbers?
Thanks!
Thank you,
ReplyDeletePlease any one help me how to read the mif file in VHDL , Itried the code here output still 0s
Hi Jim, it is still not clear to me if this method is synthesisable or just good for simulation. Thanks, Yacine
ReplyDeletehello friends,
ReplyDeletei am trying to use vga interface with nexys4 board.
but i am facing the problem with block ram .
i have tried two ways to store the file into bram but not working very well , may be i am missing some steps but which steps , i don't know. can you please share the steps for storing the image hex codes into the block ram
My name is Clifford John from USA taxes, I want to share a testimony of how Dr_Ogodo1 herbal mixture cream saves me from shame and disgrace, my penis was a big problem to me as the size was really so embarrassing,and i was also having weak erection problem. I can't make love to my wife and my penis was just too small a full grown man like me having 4 inches penis and to worsen it i don't last in sex i can't even last two minutes it was really a thing of shame to me. My wife was really tired of me because my sex life was very poor,she never enjoyed sex,i was always thinking and searching for solutions everywhere until when i saw a testimony of how Dr_Ogodo1 herbal mixture cream have been helping people regarding their sex life, so i decided to give him a try and to my greatest surprise in less than one week of taking the herbs my penis grow to 8 inches i couldn't believe my eyes and as i speak now my penis is now 8 inches and i do not have week erection again. I can make love to my wife longer in bed. And my marriage is now stable,my wife now enjoy me very well in bed.
ReplyDelete* He can also bring back your Ex
*Love spell
* Herpes virus diseases
*Diabetes
*Aid virus
*STD/HSV
*Cancer/typhoid E.t.c you contact him through the mail. Ogodoherbalhomesolution@gmail.com
You can also WhatsApp him on +2349044680467
i will never ever in my life stop telling the whole entire world the great Job Dr. Abolo whose contact details is Abolospell@gmail.com did for me by making my relationship the best and the perfect one i wished for with his powerful love spell that works beyond human oh my goodness his spells is so effective and secondly there is know side effect and most importantly he is very legit what ever he says that is what he dose. now this was how meant with him that change my love life all of a sudden. I saw a comment here a few weeks ago about Dr Abolo and i decided to contact him as instructed, thanks to this man for bringing joy to me as wished for. i followed instructions which he gave in other to get my lover back who left me and the kids for 3years now, but thanks to Dr Abolo because they are back to me now for good and we are happy together. please do contact him for help too if in relationship problem via email at: ( Abolospell@gmail.com ) And testify for yourself.
ReplyDeleteWe can always make our relationship the best for us, life or career a successful as we desire, it only take you to put in the right effort and if you feel you need help then look for help. After my man left me heartbroken. I was lonely, devastated and sad luckily I was directed to a very kind and powerful man (Dr Akhigbe) who helped me brought back my man and now he loves me far more than ever am so happy with life now thank you so much drakhigbespellhome7@gmail.com or Whatsapp +2349021374574
ReplyDelete