I have a program in VHDL and I want to replace one of the processes with a rom implementation. I've created a 1 port ram using mega wizard but I'm not really sure how to proceed from here.
so my questions are:
1. do I write VHDL code for the process in the ram.vhd file like I would in the normal design entity file? e.g
1) No you don't write process code to implement a ROM LUT. You write some kind of initialization statements for the memory. For Xilinx it would be INIT generics for the ram array, not sure what the equivalent in Altera is.
2) use a MIF file and a function to read it into the memory array.
3) Addresses are your inputs and the outputs are the ROM's read data lines
4) the MIF file content is binary data formatted in human readable ASCII. see http://quartushelp.altera.com/15.0/mergedProjects/reference/glossary/def_mif.htm
ROMs can be described using a VHDL process...
Use the case statement for the address inside a clocked process and make sure all case variations are covered (and driven by constants of-course...).
Pure HDL without any initialization.
I tested it with Quartus and it generated Block RAM with the Write Enable pins disabled - I.E: ROM.
I would always check though that no wild MUXs are accidentally inferred when using this approach.
Altera doesn't support initialization generics for RAM/ROM primitives. You can either use *.MIF or *.HEX init files with the structural ROM description. Or use a synthesizable behavioral description according to the templates in the Altera documents, an initialized register array. Altera supports also Verilog $redamemb/$readmemh for initialization.
From what I understand, I will need a function to read from the main file into memory. This will be my address in the MIF file which will have some binary content that I will have specified and be the passed out as the output q?
will I then need another function to read the output from the memory?
this is what I'm trying to do.
Code:
process (count, outi, run) --converter
begin
if (run = '1') then
case count is
when "00" =>
outi <= "1000";
when "01" =>
outi <= "0100";
when "10" =>
outi <= "0001";
when "11" =>
outi <= "0010";
when others =>
outi <= "0000";
end case;
else
outi <= "0000";
end if;
end process;
ledstep <= count; -- ledr
led <= outi; -- led [0], [1], [2], [3]= 1a 2a 2b 1b
end Behavioral;
The count would be addresses and outi would be output q.
This the mif file. not entirely sure I'm doing this correctly.
more like this:
process (clock)
begin
if rising_edge (clock) then
case address is
when "00" =>
cell_content <= some_constant_1 ;
when "01" =>
cell_content <= some_constant_2 ;
when "10" =>
cell_content <= some_constant_3 ;
when "11" =>
cell_content <=some_constant_4 ;
when others =>
cell_content <= some_constant_4 ;
end case;
end if;
end process ;
I think I understand what you desire. If you want to turn that case statement into ROM.
Then this is what I recommend
1. You create the initializer file for the ROM.
2. You instantiate the component - whereby it is die specific
Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
u_some_name : instantiated_rom
genericmap(
init ="file_location")portmap(
clk => clk,
address => address, -- This is your count as shaiko stated
Q => cell_const -- This is your out1);
Sorry I'm still very new to VHDL and FPGAs so I need to make sure I'm getting this right.
You did understand correctly, I'm trying to turn the case statement into ROM.
1. You create the initializer file for the ROM.
This is the MIF file I created correct?
2. You instantiate the component - whereby it is die specific
I'm not sure how to that or understand what it meant
by die specific
So are you saying that I should include yours and shaikos code in my ram.vhd?
in the code you provided I think those assignments have already been done by default.
I think the main this is i don't understand how the ROM is being used.
how does it get its data from the rest of the program?
do i need to do anything more with the output or does it spit it out and the rest of the program continues?
does it work like i described in my earlier post?
You can build a constant array as shown on this site. I was originally under the mistaken impression you were trying to use a IP core and wanted to add code to to load the contents via synthesizable code.
I typically use a case statement in my code if the ROM is small (i.e. don't want it in a block RAM), otherwise I use $readmemb/$readmemh (I'm mostly a Verilog coder).
I think the main this is i don't understand how the ROM is being used.
how does it get its data from the rest of the program?
do i need to do anything more with the output or does it spit it out and the rest of the program continues?
does it work like i described in my earlier post?
ROM is used to look up constant data...you supply an address and it returns data that you loaded permanently at that address. The ROM doesn't get data from the rest of the program.
I'm getting the impression you don't have a good grasp of what is an address and what is data in a processor system.
- - - Updated - - -
Also from your first post the Altera megawizard should have a checkbox or something that tells the tool you want to create a ROM not a RAM. It will ask for a MIF file to load the contents of the ROM. If you generate your ROM like that you won't have to resort to writing your own ROM code (though it is not portable across vendors). I'm still not entirely sure if you even understand what a ROM is for or how you use one.
As an additional remark, a case statement in a clock triggered process, as shown by shaiko in post #6 will be automatically converted to ROM based logic under circumstances. Usually the threshold for automatic RAM/ROM interference isn't low enough to make it happen for a small case construct, but it can be adjusted by synthesis parameters.
As an additional remark, a case statement in a clock triggered process, as shown by shaiko in post #6 will be automatically converted to ROM based logic under circumstances. Usually the threshold for automatic RAM/ROM interference isn't low enough to make it happen for a small case construct, but it can be adjusted by synthesis parameters.
With that said - I would always verify it against the synthesis report to see that I got what I wanted.
Using HDL to infer logic maybe the elegant approach (as opposed to instantiating it) - but RAM/ROM are one of those things that I treat with "RTL mistrust".
Instantiating is ALWAYS the safer...