如何使用ModelSim在VHDL中实现RAM

存储技术

606人已加入

描述

  什么是 RAM(随机存取存储器)?

  RAM(随机存取存储器)是用于系统读/写和存储数据的存储设备。RAM 存在范围从嵌入式系统、智能手机等小型系统到台式机、笔记本电脑等大型系统。系统中使用的 RAM 对系统性能有重大影响。它负责执行多项任务并存储数据。RAM的版本越高,它的性能就越高。

  现在我们对 RAM 是什么有了清晰的认识,让我们看看如何在 VHDL 中实现 RAM。尽管业界使用了更高版本的 RAM。在本教程中,我们将实现一个简单的 32X8 RAM。它是存储设备的小规模版本。

  内存规格

  通常,内存用 M x N 表示,其中 M 是位置数,N 是数据线。所以这里 32 x 8,“32”代表 32 个位置,或者一个有 32 个位置的数组,“8”代表 8 条数据线。简单来说,一个 32 x 8 RAM 有 32 个位置,每 32 个位置可以存储 8 位数据。因此,32 x 8 RAM 可以存储的总位数为 256 位。现在,您可以想象用于笔记本电脑/台式机的 8GB、16GB RAM 的存储容量。

  下面给出了一个示意图,指示了 RAM 中的端口/线路。

vhdl

  RAM 具有数据线、地址线、写入信号、时钟信号和用于从 RAM 读取内容的数据输出端口。地址线大小/位因 M x N 规格而异。让我们了解如何计算地址线位 (A) 的大小。

  地址线位数/大小 (A):2 A =M。因此,在我们的例子中,它是 2 A =32 (M=32),其中 A=5。

  An → 地址线

  M → 位置数

  N → 数据线

  W → 写信号

  由于 RAM 是时序电路,因此它具有时钟信号。所有时序电路都有时钟信号。此外,写入信号负责将数据刻录到 RAM 中。只有当时钟和写信号都为“1”时,数据才会存储在 RAM 中。

  下面给出了与写入和时钟信号有关的事件。

vhdl

  RAM 的 VHDL 代码:

 

图书馆 IEEE;
使用 IEEE.STD_LOGIC_1164.ALL;
使用 ieee.numeric_std.ALL;
实体 RAM_32X8 是
端口(
地址:in std_logic_vector(4 downto 0);
data_in:in std_logic_vector(7 downto 0);
write_in:in std_logic;
时钟:in std_logic;
data_out:out std_logic_vector(7 downto 0) 
);
结束 RAM_32X8;
架构 RAM_32X8 的行为是
类型 ram_array 是 std_logic_vector 的数组(0 到 31 )(7 到 0);
信号 ram_data: ram_array :=( 
   b"10000000",b"01001101",x"77",x"67", 
   x"99",x"25",x"00",x"1A", 
   x"00 ",x"00",x"00",x"00", 
   x"

   x"00",x"00",b"00111100",x"00", 
   x"00",x"00",x"00",x"00", 
   x"00",x"00", x"00",x"1F" 
   ); 
开始
进程(时钟)
开始
如果(上升沿(时钟))然后
如果(写入='1')然后
ram_data(to_integer(无符号(地址)))<=数据输入;
  万一; 
万一; 
结束进程;
data_out <= ram_data(to_integer(unsigned(address))); 
结束行为;

 

让我们先一步一步来,以便我们可以跟踪事情。首先,让我们逐段编写代码,然后合并。

第一步是导入库和实体声明。就像“使用IEEE.std_logic_1164.all ”、“使用IEEE.numeric_std.ALL ”一样,导入了我们将使用的数字库。这个库的使用将在下面的代码中解释。

该实体使用标签“ RAM_32X8 ”声明。接下来,声明了所有输入和输出端口。位大小为五 (5) 的地址线 (A)、数据线 (即 N = 8)、写入信号 (W)、时钟信号和数据输出是对应的输入和输出端口,如前所述。

 

图书馆 IEEE;
使用 IEEE.STD_LOGIC_1164.ALL;
使用 ieee.numeric_std.ALL;
实体 RAM_32X8 是
港口(
 地址:在 std_logic_vector(4 downto 0) 中;
 data_in: 在 std_logic_vector(7 downto 0);
 write_in:在std_logic中;
 时钟:在 std_logic 中;
 data_out: 输出 std_logic_vector(7 downto 0)
);
结束 RAM_32X8;

 

一旦实体被声明,我们就可以从架构定义开始。该架构被标记为“RAM_32x8”。

 

RAM_32X8 的架构行为是

 

ram_array 类型是 std_logic_vector(7 到 0)的数组(0 到 31): 现在,我们必须创建一个大小为 32 的数组。因此,我们将变量“ ram_array ”声明为“类型 ram_array”,它是一个枚举类型。枚举类型什么都不是,只是列出变量的所有可能值。“is array (0 to 31)”表示“type ram_array”将是一个大小为(M)为32的数组,从0开始到31结束。这32个位置应该能够存储一个8位向量为N= 8. 因此,我们将其声明为“ std_logic_vector (7 down to 0) ”。所以通常 ram_arary 是一个有 32 个位置的数组,每个位置可以存储 8 位。

 

类型 ram_array 是 std_logic_vector 的数组(0 到 31)(从 7 到 0);

 

现在,我们必须将其存储为信号。因此,我们将“ram_data”声明为信号并将其映射到数组“ram_array”。现在“ram_array”的内容将被映射到信号“ram_data”。所以,我们必须初始化数组的内容。所以,我已经初始化了一些值。

注意:我们可以用二进制或十六进制表示/初始化。“b”代表二进制,“x”代表十六进制。然而,ModelSim 在模拟时默认将表示转换为二进制。

 

信号 ram_data: ram_array :=( 
   b"10000000",b"01001101",x"77",x"67", 
   x"99",x"25",x"00",x"1A", 
   x"00 ",x"00",x"00",x"00", 
   x"00",x"00",x"00",x"00", 
   x"00",x"0F",x"00 ",x"00", 
   x"00",x"00",b"00111100",x"00", 
   x"00",x"00",x"00",x"00", 
   x"00 ",x"00",x"00",x"1F"

 

由于整个if条件过程都依赖于时钟,我们通过“process(clock)”声明

 

开始
进程(时钟)
开始

 

if (rising_edge(clock)) then: ModelSim 有一个预定义的函数“rising_edge()”。“rising_edge”表示信号从低到高的转换点。因此,只有在发生从低到高的转换时,它才会传递到下一条语句。

 

如果(上升沿(时钟))那么

 

if (write_in='1') then:这是一个简单的 if 条件,只有当信号“write_in”为 1 时,它才会传递到下一个。

 

if(write_in='1') 那么

 

ram_data v(to_integer(unsigned(address))) <= data_in:  “ram_data”信号本身是一个数组,因此我们必须设置必须存储数据的数组的索引。该索引将只接受一个正整数。“to_integer()”将转换为整数值。“无符号”用于将二进制数转换为无符号二进制数。“IEEE.NUMERIC_STD all”包负责整数转换。

注意:默认情况下,Modelsim 会将给定的输入作为二进制。

如果您的地址是“11111”,ModelSim 有时会将“11111”解释为负数,因为 MSB(最高有效位)为“1”。因此,始终建议使用unsigned()。最后,当 ModelSim 处理这条语句时,它会是ram_data(index)。 只是我们已经将给定的地址转换为适当的索引格式。现在,“data_in”信号中的数据将被存储到适当的“ram_data”索引中。

由于我们使用了 2 个 if,我们必须通过两个“end if”来终止 if

 

万一;
 万一;
结束进程;

 

由于必须通过给定地址从 RAM 中读取数据,因此声明了“data_out”信号以从特定索引读取内容。

 

data_out <= ram_data(to_integer(unsigned(address)));

 

只需复制粘贴上面的代码,编译和模拟代码。仿真过程请参考“ModelSim中使用VHDL实现基本逻辑门”

vhdl

  沿波形移动光标以读取信号的内容。这就是用 VHDL 编写 RAM 的方式。

  图书馆 IEEE;

  使用 IEEE.STD_LOGIC_1164.ALL;

  使用 ieee.numeric_std.ALL;

  实体 RAM_32X8 是

  端口(

  地址:in std_logic_vector(4 downto 0);

  data_in:in std_logic_vector(7 downto 0);

  write_in:in std_logic;

  时钟:in std_logic;

  data_out:out std_logic_vector(7 downto 0)

  );

  结束 RAM_32X8;

  架构 RAM_32X8 的行为是

  类型 ram_array 是 std_logic_vector 的数组(0 到 31 )(7 到 0);

  信号 ram_data: ram_array :=(

  b“10000000”,b“01001101”,x“77”,x“67”,

  x“99”,x“25”,x“00”,x“1A”,

  x“00 ”,x“00”,x“00”,x“00”,

  x“00”,x“00”,b“00111100”,x“00”,

  x“00”,x“00”,x“00”,x“00”,

  x“00”,x“00”, x“00”,x“1F”

  );

  开始

  进程(时钟)

  开始

  如果(上升沿(时钟))然后

  如果(写入=‘1’)然后

  ram_data(to_integer(无符号(地址)))《=数据输入;

  万一;

  万一;

  结束进程;

  data_out 《= ram_data(to_integer(unsigned(address)));

  结束行为;

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分