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.

How can I describe a ROM in VHDL?

Status
Not open for further replies.

skycanny

Junior Member level 3
Joined
Dec 23, 2004
Messages
30
Helped
2
Reputation
4
Reaction score
2
Trophy points
1,288
Activity points
363
hi :
all guys. I wanna discribe a ROM in VHDL , but VHDL is very new to me. And my this ROM is designed to store sine wave table. Can someone help me?

Any help would be appreciate!
 

rom vhdl

Here is a basic code for ROM in VHDL!
Hope this helps.

Code:
library ieee;
use ieee.std_logic_1164.all;

entity ROM is
  port ( address : in std_logic_vector(3 downto 0);
         data : out std_logic_vector(7 downto 0) );
end entity ROM;

architecture behavioral of ROM is
  type mem is array ( 0 to 2**4 - 1) of std_logic_vector(7 downto 0);
  constant my_Rom : mem := (
    0  => "00000000",
    1  => "00000001",
    2  => "00000010",
    3  => "00000011",
    4  => "00000100",
    5  => "11110000",
    6  => "11110000",
    7  => "11110000",
    8  => "11110000",
    9  => "11110000",
    10 => "11110000",
    11 => "11110000",
    12 => "11110000",
    13 => "11110000",
    14 => "11110000",
    15 => "11110000");
begin
   process (address)
   begin
     case address is
       when "0000" => data <= my_rom(0);
       when "0001" => data <= my_rom(1);
       when "0010" => data <= my_rom(2);
       when "0011" => data <= my_rom(3);
       when "0100" => data <= my_rom(4);
       when "0101" => data <= my_rom(5);
       when "0110" => data <= my_rom(6);
       when "0111" => data <= my_rom(7);
       when "1000" => data <= my_rom(8);
       when "1001" => data <= my_rom(9);
       when "1010" => data <= my_rom(10);
       when "1011" => data <= my_rom(11);
       when "1100" => data <= my_rom(12);
       when "1101" => data <= my_rom(13);
       when "1110" => data <= my_rom(14);
       when "1111" => data <= my_rom(15);
       when others => data <= "00000000";
	 end case;
  end process;
end architecture behavioral;
 
  • Like
Reactions: Morell and Cruel

    skycanny

    Points: 2
    Helpful Answer Positive Rating

    Cruel

    Points: 2
    Helpful Answer Positive Rating

    Morell

    Points: 2
    Helpful Answer Positive Rating
rom vhdl code

thanks for replies
The ROM I wanna describe is too large .
Is there any method else?
Any help would be appreciate!
 

rom en vhdl

Hi skycanny,
i feel u r trying to generate a direct digit synthesizer or a sine wave generator.
which is ur target device?
if u r using xilinx tools, then it's easy to generate the rom and dds using xilinx ise tool.
Coregen will automatically generate the rom which u need to generate the sine, depending upon the output sine frequency and step resolution.
 

    skycanny

    Points: 2
    Helpful Answer Positive Rating
vhdl code rom

hi,Renjith:
You are right
I am trying to implement a DDS and using Xilinx FPGA.
However, I do not want to use CoreGen because the module CoreGen creates is hard to migrate to other target device.
Could you help me?
Any help would be appreciate!
 
vhdl rom model

You can use a RAM of a FPGA inittialized with the content that you want (look at the Xilinx FPGAs BRAMs manual for instance). You just must take care that there aren't any writes to the RAM. The beautie of this is that you can easly initialize the RAM without the need to code a look-up table. The disavantage is that you waste BRAMs of the FPGA but you don't waste logic resources.
 
rom in vhdl

use "BlockRam" devices in case you plan to use xilinx devices or LPM library if you plan to use Altera ones...

both of them are very efficient.

You can treat BlockRam as a Rom Memory by disabling the RW line.

regards

maXer
 

dds vhdl

I agree with nand_gates

I think that the best way to put RAM into an FPGA is by using a two dimensional array.
This is the way that I have done it on many occasions and it’s always been successful.

If I wanted to describe a large memory

(Which I haven’t in the past because it’s often easier/less expensive, just to attach some RAM to the FPGA, but I understand that this may not be true in your case, pin count, start case and so on).

I would use the method described by nand_gates and try to extend this idea using something like the “generate” statement.

Hope that helps

Kind Regards Bob
 

    skycanny

    Points: 2
    Helpful Answer Positive Rating
vhdl rom code

skycanny said:
hi,Renjith:
I am trying to implement a DDS and using Xilinx FPGA.
However, I do not want to use CoreGen because the module CoreGen creates is hard to migrate to other target device.

ok... r u trying to target to some other xilinx family or non-xilinx families or an ASIC prototype.
if it's other xilinx families itself, then coregen is a solution for u.
if the target is a non-xilinx family, then u r right,
as u cannot port coregen modules to that.

so what i cud guess is, u want to generate a generic vhdl model of DDS.
in that case,u have to store the sine coeffiecients in the rom manually,
as nandgates suggested.

Again, u can use ur coregen tool to generate the sine coeffiencts,
when u r generating a DDS model thrg Coregen, then it automatically creates a .mif file, which has all the coefficients inside as per ur spec.
u have to take this and put it in your vhdl code, no matter which ever ur target is.
 
vhdl rom example

i also suggest the generate command. It is useful for a large number of similar devices one has to write code for. If you are newbie, just refer to the VHDL manual about generate command. Using Xilinx ISE is the fast way but anyway you should know VHDL code.
 

vhdl code for rom

thank all guys
 
vhdl ram data initialization rom

Hi skycanny,
You can use a high level language to do the job.
By using the "fprint" like function(fprint is a C funtion) to print out the rom content and other words(as nand_gates's code) to a single file. This code is portable.

I do the similar job by using Matlab.

Regard,
Jarod
 

    skycanny

    Points: 2
    Helpful Answer Positive Rating
rom+vhdl

Hi,jarodz:
thank you
I have done it by Matlab and added it to code
 

vhdl coding for rom

hey...i created a rom this way

Code:
library ieee;
use ieee.std_logic_1164.all;

entity ROM is
  port ( clk : in std_logic;
			e : in std_logic;
			r : in std_logic;
         data : out std_logic_vector(7 downto 0) );
end entity ROM;

architecture behavioral of ROM is

signal i: integer range 0 to 6063:=0;
signal enable : STD_LOGIC:='0'; 

type mem is array ( 0 to 6063) of std_logic_vector(7 downto 0);

constant my_Rom : mem :=

DATA HERE...
...
...
...

since i have to put inside it a large code, almost 10000 8bit packets, i created a script in matlab (using fprintf) that generated the data i need to put in file.
my problem now is that when synthetizing in ise, this takes almost 40 minutes to complete.
coregen isnt a solution for me since we are not allowed to use it...
i hope anyone could give me a hand with this
thanks
 

text file rom vhdl

moreins said:
/.../problem now is that when synthetizing in ise,
this takes almost 40 minutes/.../

you've created a large constant, not a ROM block,
that's why the compiler needs so much time to connect
inputs of logic cells to "1's" and "0's" accordingly
to your description;

the tool should recognize the ROM if you write it somehow
like in an example below:


Code:
process(clk)
   begin
      if(rising_edge(clk)) then
      q <= my_Rom(addr);  <=======
      end if;
end process;
---
 

ram and rom in vhdl

hello
thanks for you reply

this is the complete code that i sinthetized last night. it took about 40 minutes.

Code:
library ieee;
use ieee.std_logic_1164.all;

entity ROM is
  port ( clk : in std_logic;
			e : in std_logic;
			r : in std_logic;
         data : out std_logic_vector(7 downto 0) );
end entity ROM;

architecture behavioral of ROM is

signal i: integer range 0 to 6063:=0;
signal enable : STD_LOGIC:='0'; 

type mem is array ( 0 to 6063) of std_logic_vector(7 downto 0);

constant my_Rom : mem := (
"10000011",
"10000100",
"10000101",
"10000011",

....
....
....
....
...

....7000 more lines 

);


begin

process(e)
begin
if e'event and e='1' then
enable<='1';
end if;
end process;

process(clk)
begin
if r = '1' then
		data <="00000000";
elsif enable='1' then
	if clk'event and clk='1' then
		data<=my_rom(i);
		i<=i+1;
	end if;
end if;


end process;
end architecture behavioral;

i didnt post before the end of my code. here it is. maybe thats what youre trying to say with the example you gave me...

hope you can help me

thanks
 

rom using vhdl coding

first - change the i range in your file to 7-0,
compile and carefully read compilation's messages;
look at the schematics and resource usage report;

I'm not experienced in vhdl, but even if the example
below is not perfect it should create a rom memory,
and give you a hint how it should be done;

I think it's better to keep a memory content values
in a seperate text file then in the RTL code;
how to do it ypu have to find out yourself in the
ise manual/handbook;


Code:
entity rom is
port 
  (
     clk     : in std_logic;
     e       : in std_logic;
     r       : in std_logic;
     data_out: out std_logic_vector (7 downto 0)
  );
end rom;

architecture rtl of rom is

signal i      : integer range 0 to 7:=0;  -- change the range value
signal enable : std_logic:='0'; 
signal data   : std_logic_vector (7 downto 0);

BEGIN

  process (e) -- i don't like this, would be better 
  begin       -- to use clk as a sync. signal
     if e'event and e = '1' then 
       enable <= '1'; 
     end if; 
  end process;

  process ( clk)
  begin
    if rising_edge (clk) then
       if (enable = '1')   then
         i <= i + 1;
       end if;
    end if;
  end process;  

  process (clk)
  begin
    if rising_edge (clk) then
      case  i is
        when  0  => data <= "10111100";
        when  1  => data <= "11011001";
        when  2  => data <= "00000111";
        when  3  => data <= "10101000";
        when  4  => data <= "10101001";
        when  5  => data <= "10101000";
        when  6  => data <= "10101011";
        when  7  => data <= "10110010";
        -- ....    fill in the correct values here for larger 'i' index
      end case;
    end if;
  end process;
 
  process (r,data)
  begin
    if r = '1' then  data_out <= "00000000";
    else             data_out <= data;  
    end if;
  end process;
    
END rtl;
---
 

dds vhdls

you can use quartus LMP ROM, it very easy. if you cann't do it yourself, tell me>
 

rom coding in vhdl

The rules for ROM inference from HDL code are tool dependant. As you are apparently using Xilinx, you should check the respective software handbooks. In addition, the ROM structure must be representable by the existing device hardware in terms of required address and/or data output latches.

A typical reason, why ROM or RAM inference fails is to include a logic feature, that isn't available in the hardware. I guess, this is the case with the r='1' condition in your design. You may want to remove this condition and also the enable signal first. Most likely, an auxilary register between the ROM and the output port is required to allow ROM inference in this case.
Code:
if r = '1' then 
      data <="00000000"; 
elsif enable='1' then 
   if clk'event and clk='1' then 
      data<=my_rom(i); 
      i<=i+1; 
   end if; 
end if;

I append an Altera Quartus ROM template for reference. Please pay attention to the structure of the output process, that has no additional conditions. It may work with Xilinx as well.
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity single_port_rom is

	generic 
	(
		DATA_WIDTH : natural := 8;
		ADDR_WIDTH : natural := 8
	);

	port 
	(
		clk		: in std_logic;
		addr	: in natural range 0 to 2**ADDR_WIDTH - 1;
		q		: out std_logic_vector((DATA_WIDTH -1) downto 0)
	);

end entity;

architecture rtl of single_port_rom is

	-- Build a 2-D array type for the RoM
	subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0);
	type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t;

	function init_rom
		return memory_t is 
		variable tmp : memory_t := (others => (others => '0'));
	begin 
		for addr_pos in 0 to 2**ADDR_WIDTH - 1 loop 
			-- Initialize each address with the address itself
			tmp(addr_pos) := std_logic_vector(to_unsigned(addr_pos, DATA_WIDTH));
		end loop;
		return tmp;
	end init_rom;	 

	-- Declare the ROM signal and specify a default value.	Quartus II
	-- will create a memory initialization file (.mif) based on the 
	-- default value.
	signal rom : memory_t := init_rom;

begin

	process(clk)
	begin
	if(rising_edge(clk)) then
		q <= rom(addr);
	end if;
	end process;

end rtl;
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top