Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Implementing logic in ram

Status
Not open for further replies.

NovNov

Newbie level 3
Joined
Apr 25, 2017
Messages
3
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
47
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

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
LIBRARY ieee;
USE ieee.std_logic_1164.all;
 
LIBRARY altera_mf;
USE altera_mf.altera_mf_components.all;
 
ENTITY RAM IS
    PORT
    (
        address     : IN STD_LOGIC_VECTOR (1 DOWNTO 0);
        clock       : IN STD_LOGIC  := '1';
        data        : IN STD_LOGIC_VECTOR (3 DOWNTO 0);
        wren        : IN STD_LOGIC ;
        q       : OUT STD_LOGIC_VECTOR (3 DOWNTO 0)
    );
END RAM;
 
 
ARCHITECTURE SYN OF ram IS
 
    SIGNAL sub_wire0    : STD_LOGIC_VECTOR (3 DOWNTO 0);
 
BEGIN
    q    <= sub_wire0(3 DOWNTO 0);
 
    altsyncram_component : altsyncram
    GENERIC MAP (
        clock_enable_input_a => "BYPASS",
        clock_enable_output_a => "BYPASS",
        init_file => "school.mif",
        intended_device_family => "Cyclone II",
        lpm_hint => "ENABLE_RUNTIME_MOD=NO",
        lpm_type => "altsyncram",
        numwords_a => 32,
        operation_mode => "SINGLE_PORT",
        outdata_aclr_a => "NONE",
        outdata_reg_a => "CLOCK0",
        power_up_uninitialized => "FALSE",
        widthad_a => 5,
        width_a => 4,
        width_byteena_a => 1
    )
    PORT MAP (
        address_a => address,
        clock0 => clock,
        data_a => data,
        wren_a => wren,
        q_a => sub_wire0
    );
process (...) 
begin 
if ... then ...
end process;
 
 
 
END SYN;



2. how do I initialise ram in the main file?

3. how do I set the inputs and outputs of the ram?

4. how do I used the memory initialisation file for binary content?
 
Last edited by a moderator:

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
 

ads-ee,

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.
 
  • Like
Reactions: ads-ee

    ads-ee

    Points: 2
    Helpful Answer Positive Rating
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.
Addr+0+1+2+3ASCII
01000010000010010...
 

Code:
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
  generic map(
    init = "file_location"
  )
  port map(
    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).

- - - Updated - - -

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.
 
  • Like
Reactions: NovNov

    NovNov

    Points: 2
    Helpful Answer Positive Rating
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...
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top