Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17267 Discussions

in-system memory read in VHDL

Altera_Forum
Honored Contributor II
2,706 Views

Hi Freinds 

I'm using QuartusII7.2 and interested in having a ROM in my project using in-system memory(do not use logic cell), i created Hexadecimal (Intel-Format) File and initialized that but i dont know how can i use this file in my VHDL codes!!:(  

thank you for your help
0 Kudos
9 Replies
Altera_Forum
Honored Contributor II
1,301 Views

Create a ROM Megafunction with the Megawizard. Define your *.hex file as initialization file.

0 Kudos
Altera_Forum
Honored Contributor II
1,301 Views

Thank you for your reply 

i implemented a rom with LPM_ROM in this way: 

tcgrom: lpm_rom 

generic map ( lpm_widthad => 16, 

lpm_outdata => "unregistered", 

lpm_address_control => "unregistered", 

lpm_file => "btest.mif", -- init data 

lpm_width => 16) 

port map ( address => addr, q => outdata); 

i must use it in process or procedures but it may couse some errors! 

please help me to use it in the procedure 

procedure tras (signal addr :in std_logic_vector(15 downto 0); signal outdata: out std_logic_vector(15 downto 0)) 

begin 

tcgrom: lpm_rom 

generic map ( lpm_widthad => 16, 

lpm_outdata => "unregistered", 

lpm_address_control => "unregistered", 

lpm_file => "btest.mif", -- init data 

lpm_width => 16) 

port map ( address => addr, q => outdata); 

 

end procedure tras; 

Error (10500): VHDL syntax error at btest.vhd(259) near text "begin"; expecting ";", or "is"
0 Kudos
Altera_Forum
Honored Contributor II
1,301 Views

VHDL generally doesn't allow to instantiate components in a process or procedure. I can't imagine a reason, why your memory can't be designed in the usual way.

0 Kudos
Altera_Forum
Honored Contributor II
1,301 Views

I prefer LPM_ROM because:  

1-this ROM must be implemented with out using logic cells 

2- my Rom is big(about 32kb) and it is difficult to list the data in vhdl code( I am using *.hex files) 

is it possible to implement a rom which uses .hex files?
0 Kudos
Altera_Forum
Honored Contributor II
1,301 Views

There's no functional difference between instantiating lpm_rom and using the Quartus MegaWizard, that creates a altsyncram instance internally. Both are referencing identical low-level libraries and generate most likely identical but surely similar code. Personally, I prefer to use the MegaWizard as a template generator and include the generated code directly, allowing parameter modifications without running the MegaWizard. 

 

Both ROM variants allow to specify a *.hex instead of a *.mif initialisation file. Also Quartus can translate between both formats. If you intend ModelSim simulation, you should use *.hex, cause ModelSim doesn't understand *.mif. 

 

I'm still wondering about your previous requirement of using the ROM inside a procedure or process. B.T.W.: The syntax error shown in the posting is a missing semicolon, but other errors are present, too.
0 Kudos
Altera_Forum
Honored Contributor II
1,301 Views

Actually in some part of my project I need to have random numbers in exponential distribution, therefore I produce uniform random numbers using Fibonacci LFSRs and then convert it to exponential distribution by look-up table. 

I need this big ROM to implement look-up table and I have to use it in the process : 

 

random_gen : process(CLK)  

 

variable qout_s : std_logic_vector(14 downto 0); 

variable tend1 :std_logic_vector(14 downto 0); 

variable tmp1 : std_logic; 

variable tmp2 : std_logic; 

variable tmp3 : std_logic; 

begin 

if (rst = '1') then 

qout_s := (others=>'1'); 

elsif (clk'event and clk = '1') then 

L1 : for j in 1 to 10 loop 

tmp1 := qout_s(2) xor qout_s(0); 

tmp2 := tmp1 xor qout_s(3); 

tmp3:= tmp2 xor qout_s(5); 

 

L2 :for i in 1 to 14 loop -- shift to right 

qout_s(i-1) := qout_s(i); 

end loop L2; 

qout_s(14) := tmp3; 

 

t1 : trans ( qout_s, inrand(j)); 

 

ttfs(j)<= inrand(j); 

 

end loop L1; 

end if; 

 

if (clk'event and clk = '0') then -- by falling edge outputs generated 

benchmark_2 (inrand ,clk, tsys_f ); 

 

end if; 

 

end process;  

--////////////////////////////////////////////////////////////////////////////////////////////////////// 

procedure trans ( addr :in std_logic_vector(14 downto 0); signal outdata: out bit_vector(15 downto 0)) is 

 

type rom is array(0 to 32767) of bit_vector(15 downto 0); 

constant mem :rom :=( 

"0000000101001011", --0 

"0000000101101000", --1 

"0000000110101011", --2 

"0000101100110000", --3 

"0000010001010100", --4 

"0000000110001110", --5 

… 

"0000110010001011", --32765 

"0000000110000010", --32766 

"0000000010011011" --32767 

 

); 

begin 

 

outdata <= mem(conv_integer(addr)); 

 

end trans; 

--/////////////////////////////////////////////////////// 

 

It is so nice for me to use *.mif or *.hex files instead of listing data’s in the vhdl codes!!!
0 Kudos
Altera_Forum
Honored Contributor II
1,301 Views

 

--- Quote Start ---  

I need this big ROM to implement look-up table and I have to use it in the process 

--- Quote End ---  

 

It can't be used in a process and I don't believe that you have to. 

 

Basically, the internal ROM is a synchronous hardware function, it uses a clock and the read data is delayed one clock cycle related to read address. Your design may need to implement a pipeline to consider the said ROM timing. You assign a value to the ROM address signal and evaluate the result in the next cycle in your process. But the ROM instance has to reside outside the process. 

 

So far the general point. But you are actually using 10 ROM instances by calling the ROM procedure in a loop. Cause each ROM has a different input address, they must exist in parallel. By utilizing the dual-port ROM option, 5 physical ROMs are needed. That means, you have an array of 10 address variables and get 10 output variables ttfs(). A for generate loop can be used to instantiate 5 dual-port ROMs connected to the respective signals. 

 

Looking at your previous code, I'm confident, that you are able to elaborate the outlined structure. Otherwise, please ask.
0 Kudos
Altera_Forum
Honored Contributor II
1,301 Views

TO_BE_DONE

0 Kudos
Altera_Forum
Honored Contributor II
1,301 Views

I thought of something like below (with an array variable for the addresses). I saw, that you have APEX II, which has an asynchronous RAM/ROM, different from all newer FPGA types. 

genrom: for i in 1 to 10 generate tcgrom: lpm_rom generic map ( lpm_widthad => 7, lpm_outdata => "unregistered", lpm_address_control => "unregistered", lpm_file => "table.hex", -- init data lpm_width => 14) port map ( address => prm(i), q => ttfs(i)); end generate;
0 Kudos
Reply