原创 RAM之VHDL描述

2006-12-3 12:31 5851 10 12 分类: FPGA/CPLD
 


    现在的FPGA基本上都提供了Block RAM供用户使用,所以在自己的工程怎么用VHDL来使用这些Block RAM就非常重要。当然,还是推荐使用开发商提供的软件来生成一个RAM模块,但是这样的RAM块不论移植性还是灵活性都降低了。所以这里采用VHDL来描述一个RAM,对于不同的综合工具和约束条件,综合出的结果可能有所不同,尽管这样,其移植性和灵活性还是要比使用工具生成的RAM块好。使用不同的综合工具,只要稍加修改就可以满足自己设计的要求。


       下面的VHDL代码使用ISE的XST综合,综合结果使用了Block RAM,这是我们期望的。当然有时对于用到的容量很小的RAM,我们并不需要其使用Block RAM,那么只要稍微修改一下就可以综合成Distribute RAM。具体如何修改后面再做介绍。


--------------------------------------------------------------------------------
-- Engineer:       skycanny
-- Module Name:    ram - Behavioral
-- Tool versions:  ISE 7.1 
-- Description:    This module is designed to generate a RAM
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity ram is
 generic(width: integer := 16;   -- used to change the memory data's width
    depth: integer := 8);   -- used to change the memery address' width during
             -- instantiation.
 port(
  clk : in std_logic;                           --clock
  addr : in std_logic_vector(depth - 1 downto 0); --address bus
  cs : in std_logic;       --chip select
  oe : in std_logic;       --output enable
             --high for write
             --low for read
  data_i: in std_logic_vector(width - 1 downto 0); --write data bus
  data_o: out std_logic_vector(width - 1 downto 0)  --read data bus
  );
end ram;


architecture Behavioral of ram is


type ram is array(2 ** depth - 1 downto 0) of std_logic_vector(width - 1 downto 0);
signal ram1  : ram;


begin
 process(clk)
 begin
  if(clk'event and clk = '1') then
   if(cs = '0') then 
    if(oe = '0') then
     data_o <= ram1(conv_integer(addr));
    else
     ram1(conv_integer(addr)) <= data_i;
    end if;
   end if;
  end if;
 end process;
end Behavioral;
----------------------------------------------------------------------------------------------------


我们看一下综合报告:


=========================================================================
*                           HDL Synthesis                               *
=========================================================================


Synthesizing Unit <ram>.
    Related source file is "G:/vhdl/ram/ram.vhd".
    Found 256x16-bit single-port block RAM for signal <ram1>.
    -----------------------------------------------------------------------
    | mode               | no-change                           |          |
    | aspect ratio       | 256-word x 16-bit                   |          |
    | clock              | connected to signal <clk>           | rise     |
    | enable             | connected to signal <cs>            | low      |
    | write enable       | connected to signal <oe>            | high     |
    | address            | connected to signal <addr>          |          |
    | data in            | connected to signal <data_i>        |          |
    | data out           | connected to signal <data_o>        |          |
    | ram_style          | Auto                                |          |
    -----------------------------------------------------------------------
    Summary:
 inferred   1 RAM(s).
Unit <ram> synthesized.


可见确实综合成了Block RAM。并且只要改变Width和Depth,就可以改变生成RAM的宽度和容量 。


下面是把上面的代码稍做修改后生成Distribute RAM的代码和其综合报告,可见改动是非常小的。


entity ram is
 generic(width: integer := 16;   -- used to change the memory data's width
    depth: integer := 8);   -- used to change the memery address' width during
             -- instantiation.
 port(
  clk : in std_logic;                           --clock
  addr : in std_logic_vector(depth - 1 downto 0); --address bus
  cs : in std_logic;       --chip select
  oe : in std_logic;       --output enable
             --low for read
  wr : in std_logic;       --low for write    --add for distribute ram
  data_i: in std_logic_vector(width - 1 downto 0); --write data bus
  data_o: out std_logic_vector(width - 1 downto 0)  --read data bus
  );
end ram;


architecture Behavioral of ram is


type ram is array(2 ** depth - 1 downto 0) of std_logic_vector(width - 1 downto 0);
signal ram1  : ram;


begin
 process(clk)
 begin
  if(clk'event and clk = '1') then
   if(cs = '0') then 
    if(oe = '0') then     
     data_o <= ram1(conv_integer(addr)); 
    elsif(wr = '0') then          --change for distribute ram
     ram1(conv_integer(addr)) <= data_i;
    end if;
   end if;
  end if;
 end process;
end Behavioral;


=========================================================================
*                           HDL Synthesis                               *
=========================================================================


Synthesizing Unit <ram>.
    Related source file is "G:/vhdl/ram/ram.vhd".
    Found 256x16-bit single-port distributed RAM for signal <ram1>.
    -----------------------------------------------------------------------
    | aspect ratio       | 256-word x 16-bit                   |          |
    | clock              | connected to signal <clk>           | rise     |
    | write enable       | connected to internal node          | high     |
    | address            | connected to signal <addr>          |          |
    | data in            | connected to signal <data_i>        |          |
    | data out           | connected to internal node          |          |
    | ram_style          | Auto                                |          |
    -----------------------------------------------------------------------
    Found 16-bit register for signal <data_o>.
    Summary:
 inferred   1 RAM(s).
 inferred  16 D-type flip-flop(s).
Unit <ram> synthesized.


由以上的讨论我们可以看出,用VHDL来描述RAM其实是非常方便,更加重要的这种方法在移植是时候有着更加优越的特点。

文章评论2条评论)

登录后参与讨论

用户377235 2014-11-12 17:03

我试过不好用

用户377235 2014-11-12 17:03

我试过不好用

用户377235 2014-10-14 18:12

如果是考试 ,谁是幸运者,谁又在感慨

用户1711475 2014-7-8 17:35

突然让人感慨当年不少同学买答案,买耳机的往事

用户111215 2007-12-27 17:14

add my qq :158946212  or msn:mabenli82@gmail.com

希望彼此有所帮助

ash_riple_768180695 2006-12-12 08:54

第一次知道Xilinx的分布式ram是怎样用hdl语言调用的,太感谢博主了。投一票。

相关推荐阅读
用户60452 2008-11-14 20:53
原创java连载--泛型(7)
类型擦除(Type Erasure)       当我们实例化一个泛型的时候,编译器使用一种叫做类型擦除(type erasure)的技术。在类型擦除的过程中,编译器会去除掉 类与接口中所有和类型参数...
用户60452 2008-11-13 22:08
原创java连载--泛型(6)
通配符       在泛型中,我们可以用一个通配符”?”来代替一个未知的类型。例如,使用下面的代码为某种animal指定一个cage:Cage<? extends Animal> some...
用户60452 2008-11-12 20:59
原创java连载--泛型(5)
泛型的子类型       只要两种类型能够相符,我们可以把一种类型的对象赋给另外一种类型的对象。例如,可以把一个Integer赋给一个Object,因为Object是Integer的父类之一。    ...
用户60452 2008-11-10 22:20
原创java连载--泛型(4)
受限的类型参数(Bounded Type Parameters)       有时候,我们要限制传递给类型参数的具体参数。例如,对数进行操作的方法就只能接受Number或者其子类的对象作为改方法的参数...
用户60452 2008-11-09 21:49
原创java连载--泛型(3)
泛型方法和构造器       如果在申明方法或者构造器的时候使用类型参数的话,就可以定义泛型方法和泛型构造器。这和定义一个普通的泛型基本上无二样,除了类型参数的作用范围只是在定义它的方法或者构造器之中...
用户60452 2008-11-08 19:13
原创java连载--泛型(2)
我们可以通过将"public class Box" 修改为 "public class Box<T>"而定义一个泛型,在这个定义中,使用了一个类型变量(type variable) T,而...
我要评论
2
10
关闭 站长推荐上一条 /2 下一条