存储器,顾名思义作用就是用于存储数据。存储器分RAM和ROM两种,其中ROM为只读存储器,而RAM为可读写存储器,既可写入数据,也可读取数据。常用的存储器都为单端口存储器,即数据输入端和数据输出端用同一个端口。所以通常RAM存储器的引脚通常有一组数据线(双向)、一组地址线、一个时钟入口以及一个读写控制信号。在时钟的边沿触发下,通过读写控制信号控制读写。当进行写操作时,将数据写入地址线指定的单元,当进行读操作时将地址线指定单元的内容读出。
由于笔者项目需求,需要一个双端口的存储器,即需要设计一个存储器带有两个数据端口和两个地址端口,可同时进行读、写操作。一个端口用于读写数据,另一端用于读写指令,以满足项目需要。
实际上,在quartus ii环境下,可以通过调用IP核的方式调用单或双端口的RAM存储器,在17.1版本中,可以点击Tools->IP Catalog,搜索RAM,调用现有的RAM,如图所示
选中之后如图,可以设置存储器的数据位宽以及深度(即多少个单元)。还有多项设置,比如设置RAM初始的数据等。这也不是失去为一种调用存储器的方法。
笔者这里之所以要用VHDL再写一个双端口存储器并不是闲着没事干(确实是),主要原因除了为了提高VHDL编程能力外,大家可以看到图中的RAM存储器虽然说是单端口,但实际上数据的输入和输出并不是同一个端口。数据从data[7…0]输入而从q[7…0]输出。笔者由于项目需要,RAM需要与CPU总线相连,数据口需要为双向,因此不得不自行撰写。
说了这么多,接下来介绍一下笔者所写的双端口RAM。此RAM为一个8X1k的双端口RAM,分为数据端口和指令端口。数据端口为可读写双向端口,包含数据线inout_data、数据地址线addr_d以及数据读写控制信号DRW。当DRW为高时进行读操作,低进行写操作。指令端口作为只可读端口,包含指令数据线(单向输出)、指令地址addr_c以及指令读写控制信号CRW,为高时进行读操作。还有一个CEL数据端口选择信号,当为低电平时有效,数据端口可进行读写操作,为高则禁止数据端口操作。
代码如下:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;entity RAM is port( T3: in std_logic;DRW: in std_logic;   --数据读写控制信号,为高进行写操作,为低进行读操作CRW: in std_logic;   --指令读写控制信号,为高进行读操作CEL: in std_logic;   --双端口选择信号。为低从数据端口进,为高从指令端口进addr_c: in std_logic_vector(7 downto 0);--指令地址addr_d: in std_logic_vector(7 downto 0);--数据地址inout_data: inout std_logic_vector(7 downto 0);output_cmd: out std_logic_vector(7 downto 0));
end RAM;architecture behave of RAM istype ram_type is array (0 to 1024) of std_logic_vector(7 downto 0);signal mem: ram_type;
begin process(T3,CEL,DRW)  -- 数据端口读写操作
begin  if rising_edge(T3) thenif CEL='1' then  --数据端口选择信号,为1则禁止inout_data<=(others=>'Z');elseif DRW='1' then  --为1,数据写入内存;为0,从内存读取数据mem(to_integer(unsigned(addr_d)))<=inout_data; elseinout_data<=mem(to_integer(unsigned(addr_d)));end if; end if;end if;
end process;process(T3,CRW)  -- 指令端口读操作beginif rising_edge(T3) thenif CRW='1' thenoutput_cmd<=mem(to_integer(unsigned(addr_c)));end if;end if;
end process;
end behave;

注意了,数据端口用的信号类型是 inout std_logic_vector(7 downto 0),为双向端口。
这段代码的核心就是这一段
type ram_type is array (0 to 1024) of std_logic_vector(7 downto 0);
signal mem: ram_type;
通过这段代码,类似定义了一个ram_type类型的二维数组 mem(x)(y)。x为0 to 1024,即数据存储单元的地址,y则为0到7,用于存储数据。有了这样一个数组,就可以通过外部输入的地址信息,将外部数据写入内存单元,或者将指定内存单元的数据读出。例如写操作:
mem(to_integer(unsigned(addr_d)))<=inout_data;
将inout_data数据写入addr_d指定地址的单元中。由于输入的地址为8位2二进制数,所以需要用to_integer、unsigned,数据类型转换成整型数据。读操作同理:
output_cmd<=mem(to_integer(unsigned(addr_c)));
将指定单元的数据读出。
这样一个双端口RAM就完成了,实测有效。
若是需要在RAM初始化一部分数据,则在architecture 中定义的数组中添加如下代码

attribute ram_init_file:string;
attribute ram_init_file of mem:
signal is"RAM.hex";
其中mem为你的数组名称,RAM.hex为你预先写好的数据文件,可以通过new->file中新建下图任意一种格式的存储文件,在其中输入需要初始化的数据即可,两种文件的格式分别为.hex和.mif。

建立好数据文件后,和实体文件一同编译,之后就可以从RAM中读取初始化的数据了。
当写好了实体模块化以后,准备与其他器件相连时,要注意当双向数据端口inout_data[7…0]与其他数据线或者总线相连时,需要加上一个三态门控制端口才能正常通过编译(双击原理图输入tri即可找到),进行数据的双向传递。三态门有一个控制端口,高有效通过。
不只是双向口,当一条数据线有多个输入时,都需要加上三态门进行控制,否则数据就混乱了:)

VHDL学习—双端口存储器相关推荐

  1. 计算机组成原理双端口存储器实验,计算机组成原理双端口存储器实验报告.doc...

    计算机组成原理实验报告 实验名称 双端口存储器实验 专业 软件工程 学院 计算机与软件学院 姓名 徐振兴 班级 (2) 学号 20111344069 指导老师 任勇军 实验日期 2013.5.24 得 ...

  2. 计算机双端口实验85H,TEC-8双端口存储器实验.ppt

    TEC-8双端口存储器实验.ppt 双端口存储器实验 一 实验类别原理性 分析性二 实验目的 了解双端口静态存储器IDT7132的工作特性及其使用方法 了解半导体存储器怎样存储和读取数据 了解双端口存 ...

  3. 嵌入式学习:存储器总结

    1.nor flash:NOR采用的并行接口,其特点读取的速度比之NAND快乐很多倍,其程序可以直接在NOR里面运行.但是它的擦除速度比较慢,集成度低,成本高的.现在的NOR的容量一般在2M左右,一般 ...

  4. VHDL学习:利用Quartus自带库3步快速完成状态机

    Quartus自带库里面有各种编程语言的模板,供开发者参考. 初学者利用VHDL实现状态机比较生疏的情况下,可以调出该模板,适当修改即可. 本文将描述如何利用Quartus自带库调出状态机模板,并适当 ...

  5. VHDL学习之TEXTIO在仿真中的应用

    TEXTIO 在VHDL 仿真与磁盘文件之间架起了桥梁,使用文本文件扩展VHDL 的仿真功能.本文介绍TEXTIO 程序包,以一个加法器实例说明TEXTIO 的使用方法,最后使用ModelSim 对设 ...

  6. STM32学习:存储器组织

    一.存储结构 STM32F1有四种存储单元,依次是SRAM.Flash.FSMC和AHB到APB桥(挂载各种外设). 二.存储组织 程序存储器.数据存储器.寄存器和输入输出端口被组织在同一个4GB的线 ...

  7. VHDL学习笔记-(1)Generic类属

    首先推荐一篇文章: 链接:VHDL基本点[精解] - 刑事组之虎9527 - 博客园 (cnblogs.com) 类属: 1.常以一种说明的形式放在实体或块结构提前 2.提供了一种静态通道 3.与常数 ...

  8. VHDL学习笔记——顶层程序编写

    将大工程拆解为若干子程序: 编写子程序,分别仿真验证: 将子程序代码合并:①人为合并,将四个程序代码杂糅,创建新工程:②编写顶层代码,在顶层代码中调用子程序,归一使用. 顶层程序 library ie ...

  9. 笔记:FPGA与VHDL语言学习3

    FPGA与VHDL语言学习3 目录 1. LPM_RAM的设置和调用方法,设计一个LPM_RAM 2. 简易正弦信号发生器(这里要使用的 data7X8 .mif 文件),要求用LPM设计一个七位计数 ...

最新文章

  1. protobuf---messge嵌套get set
  2. flink java生成流式数据
  3. Go语言入门编程学习结束
  4. 根据一览,自动生成Sheet页
  5. 读写SharedPreferences中的数据
  6. php进度条实例,JavaScript_一个简单的jquery进度条示例,用jQuery实现的最简单的进度条 - phpStudy...
  7. 电子计算机和量子力学,通俗讲解一下量子计算机究竟是怎么运作的?其实量子力学并不深奥...
  8. LAMP虚拟主机架设论坛
  9. Telegram Bot 使用文档
  10. C语言socket重连和心跳,c# socket 心跳 重连
  11. 在数据库中使用关键字作为字段名
  12. 高光谱图像分析:分类 II
  13. 【tensorflow学习笔记】
  14. 本地玩邮件服务器和邮件客户端
  15. 【设计模式】我对设计模式的C语言解读(上)
  16. 年轻的乔布斯也会哭泣
  17. 虚拟机安装Ubuntu 22.4
  18. 宝塔实测-PHP网页版在线客服系统源码
  19. 读 Flink 源码,肝进阿里云 Flink 组了。。
  20. Esri携“新一代Web GIS”亮相中国地理信息产业大会

热门文章

  1. GDOI模拟 Zjr506的捕猫计划
  2. imu初始对准matlab,IMU静态初始粗对准计算姿态角
  3. x8086千行汇编项目——汇编贪吃蛇、画图、两个程序的调度
  4. win10系统键盘正常但突然不能输入
  5. EasyIPCamera-WindowsLinuxARM服务接口
  6. 最适合运动的蓝牙耳机、运动型蓝牙耳机推荐
  7. 义务教育和医疗保险,不同规则的个人分析
  8. 2008年回顾与2009年展望
  9. 一文搞定Spring及IOC,给你总结的清新脱俗!
  10. chatgpt收费吗