【FPGA零基础学习之旅#16】嵌入式块RAM-双口ram的使用

news/2024/11/19 23:17:20/

🎉欢迎来到FPGA专栏~双口ram的使用


  • ☆* o(≧▽≦)o *☆~我是小夏与酒🍹
  • 博客主页:小夏与酒的博客
  • 🎈该系列文章专栏:FPGA学习之旅
  • 文章作者技术和水平有限,如果文中出现错误,希望大家能指正🙏
  • 📜 欢迎大家关注! ❤️
    FPGQ2

CSDN

🎉 目录-双口ram的使用

  • 一、效果演示
  • 二、基础知识点讲解
  • 三、ip核配置
  • 四、仿真验证与分析

遇见未来

一、效果演示

🥝将数据写入ram:
存数据
🥝从ram中读取数据:
读取数据

二、基础知识点讲解

AC620开发板中使用的为intel公司的 Cyclone IV 系列芯片,逻辑单元在 Cyclone IV 器件结构中是最小的逻辑单位。

嵌入式存储器结构由一列列 M9K 存储器模块组成,通过对这些 M9K 存储器模块进行配置,可以实现各种存储器功能,例如:RAM、移位寄存器、ROM 以及 FIFO 缓冲器

对于单端口 RAM,读写操作共用端口 A 的地址,数据通过端口 A 写入和读出;对于双端口 RAM,则是一个读端口和一个写端口。

关于ram的知识点讲解可以参考文章:RAM的理解、RAM存储器。

三、ip核配置

1、端口的选择与深度的选择:

将双端口 RAM 的使用方式设置为一个读端口和一个写端口,另一种方式为两个端口都可用做读/写;设置存储器大小的方式为按照字数确定,另一种方式为按照比特数。

1
2、配置输入和输出端口的位宽:

不同端口使用相同数的位宽;端口位宽为 8;存储器使用的存储块类型为软件自动选择;存储器深度为软件自动选择。

2
3、选择256的储存量:

3
4、配置时钟模式和读使能信号:

时钟选择这里为单时钟,不勾选创建读使能信号。这里用一个时钟和一个时钟使能信号控制存储块所有的寄存器。其他应用场所还可以设置为双时钟使用独立的输入时钟和输出时钟或者双时钟使用单独的读时钟和写时钟。

4
5、端口是否需要添加寄存器,配置时钟使能信号和寄存器端口异步清零信号:

对输出端口进行寄存;不创建时钟使能信号;不创建异步复位端口,需注意这里复位并不复位 RAM 中的数据而是只复位寄存器上的值。

5
6、单时钟控制读写数据:

6
7、是否需要对ram初始化:

7
8、默认:
8
9、默认:
9

配置好的dpram.v:

// megafunction wizard: %RAM: 2-PORT%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: altsyncram // ============================================================
// File Name: dpram.v
// Megafunction Name(s):
// 			altsyncram
//
// Simulation Library Files(s):
// 			altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 13.0.0 Build 156 04/24/2013 SJ Full Version
// ************************************************************//Copyright (C) 1991-2013 Altera Corporation
//Your use of Altera Corporation's design tools, logic functions 
//and other software and tools, and its AMPP partner logic 
//functions, and any output files from any of the foregoing 
//(including device programming or simulation files), and any 
//associated documentation or information are expressly subject 
//to the terms and conditions of the Altera Program License 
//Subscription Agreement, Altera MegaCore Function License 
//Agreement, or other applicable license agreement, including, 
//without limitation, that your use is for the sole purpose of 
//programming logic devices manufactured by Altera and sold by 
//Altera or its authorized distributors.  Please refer to the 
//applicable agreement for further details.// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module dpram (clock,data,rdaddress,wraddress,wren,q);input	  clock;input	[7:0]  data;input	[7:0]  rdaddress;input	[7:0]  wraddress;input	  wren;output	[7:0]  q;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endiftri1	  clock;tri0	  wren;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endifwire [7:0] sub_wire0;wire [7:0] q = sub_wire0[7:0];altsyncram	altsyncram_component (.address_a (wraddress),.clock0 (clock),.data_a (data),.wren_a (wren),.address_b (rdaddress),.q_b (sub_wire0),.aclr0 (1'b0),.aclr1 (1'b0),.addressstall_a (1'b0),.addressstall_b (1'b0),.byteena_a (1'b1),.byteena_b (1'b1),.clock1 (1'b1),.clocken0 (1'b1),.clocken1 (1'b1),.clocken2 (1'b1),.clocken3 (1'b1),.data_b ({8{1'b1}}),.eccstatus (),.q_a (),.rden_a (1'b1),.rden_b (1'b1),.wren_b (1'b0));defparamaltsyncram_component.address_aclr_b = "NONE",altsyncram_component.address_reg_b = "CLOCK0",altsyncram_component.clock_enable_input_a = "BYPASS",altsyncram_component.clock_enable_input_b = "BYPASS",altsyncram_component.clock_enable_output_b = "BYPASS",altsyncram_component.intended_device_family = "Cyclone IV E",altsyncram_component.lpm_type = "altsyncram",altsyncram_component.numwords_a = 256,altsyncram_component.numwords_b = 256,altsyncram_component.operation_mode = "DUAL_PORT",altsyncram_component.outdata_aclr_b = "NONE",altsyncram_component.outdata_reg_b = "CLOCK0",altsyncram_component.power_up_uninitialized = "FALSE",altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE",altsyncram_component.widthad_a = 8,altsyncram_component.widthad_b = 8,altsyncram_component.width_a = 8,altsyncram_component.width_b = 8,altsyncram_component.width_byteena_a = 1;endmodule// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
// Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
// Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
// Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
// Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
// Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
// Retrieval info: PRIVATE: CLRdata NUMERIC "0"
// Retrieval info: PRIVATE: CLRq NUMERIC "0"
// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
// Retrieval info: PRIVATE: CLRrren NUMERIC "0"
// Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
// Retrieval info: PRIVATE: CLRwren NUMERIC "0"
// Retrieval info: PRIVATE: Clock NUMERIC "0"
// Retrieval info: PRIVATE: Clock_A NUMERIC "0"
// Retrieval info: PRIVATE: Clock_B NUMERIC "0"
// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "0"
// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_B"
// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
// Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
// Retrieval info: PRIVATE: MEMSIZE NUMERIC "2048"
// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
// Retrieval info: PRIVATE: MIFfilename STRING ""
// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "2"
// Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
// Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "1"
// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "3"
// Retrieval info: PRIVATE: REGdata NUMERIC "1"
// Retrieval info: PRIVATE: REGq NUMERIC "1"
// Retrieval info: PRIVATE: REGrdaddress NUMERIC "1"
// Retrieval info: PRIVATE: REGrren NUMERIC "1"
// Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
// Retrieval info: PRIVATE: REGwren NUMERIC "1"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
// Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
// Retrieval info: PRIVATE: VarWidth NUMERIC "0"
// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "8"
// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "8"
// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "8"
// Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "8"
// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "0"
// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
// Retrieval info: PRIVATE: enable NUMERIC "0"
// Retrieval info: PRIVATE: rden NUMERIC "0"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
// Retrieval info: CONSTANT: ADDRESS_ACLR_B STRING "NONE"
// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0"
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "256"
// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "256"
// Retrieval info: CONSTANT: OPERATION_MODE STRING "DUAL_PORT"
// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "CLOCK0"
// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE"
// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "8"
// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "8"
// Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
// Retrieval info: CONSTANT: WIDTH_B NUMERIC "8"
// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
// Retrieval info: USED_PORT: data 0 0 8 0 INPUT NODEFVAL "data[7..0]"
// Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
// Retrieval info: USED_PORT: rdaddress 0 0 8 0 INPUT NODEFVAL "rdaddress[7..0]"
// Retrieval info: USED_PORT: wraddress 0 0 8 0 INPUT NODEFVAL "wraddress[7..0]"
// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT GND "wren"
// Retrieval info: CONNECT: @address_a 0 0 8 0 wraddress 0 0 8 0
// Retrieval info: CONNECT: @address_b 0 0 8 0 rdaddress 0 0 8 0
// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
// Retrieval info: CONNECT: @data_a 0 0 8 0 data 0 0 8 0
// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
// Retrieval info: CONNECT: q 0 0 8 0 @q_b 0 0 8 0
// Retrieval info: GEN_FILE: TYPE_NORMAL dpram.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL dpram.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL dpram.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL dpram.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL dpram_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL dpram_bb.v TRUE
// Retrieval info: LIB_FILE: altera_mf

顶层RTL视图:

RTL

四、仿真验证与分析

将创建好的ip核加入工程中并设置为顶层文件,开始仿真测试。

编写仿真测试激励文件:

dpram_tb.v:

`timescale 1ns/1ns
`define clock_period 20module dpram_tb;reg clock;reg [7:0]data;reg [7:0]rdaddress;reg [7:0]wraddress;reg wren;wire [7:0]q;integer i;dpram dpram(.clock(clock),.data(data),.rdaddress(rdaddress),.wraddress(wraddress),.wren(wren),.q(q));initial clock = 1;always#(`clock_period / 2) clock = ~clock;initial begindata = 0;rdaddress = 0;wraddress = 0;wren = 0;#(`clock_period * 20 + 1);//写入数据for(i = 0;i <= 15;i = i + 1)beginwren = 1;data = 255 - i;wraddress = i;#(`clock_period);endwren = 0;#(`clock_period * 20);//读取数据for(i = 0;i <= 15;i = i + 1)beginrdaddress = i;#(`clock_period);end#(`clock_period * 20);$stop;endendmodule

仿真结果:

🥝数据存储:
存储
🥝数据读取:
读取

仿真结果分析:

存储分析
注意观察上述时钟信号,当写地址为1的时候,存入的数据为254。
读取分析
而在读取数据的时候,当读地址为2的时候,q的输出才是254。这是因为我们在配置ip核的时候,选择了在输出端添加一个寄存器,导致q的输出慢一拍。(一般情况下在输出端添加寄存器,是为了保证数据的完好性。)

csdn

🧸结尾


  • ❤️ 感谢您的支持和鼓励! 😊🙏
  • 📜您可能感兴趣的内容:
  • 【FPGA零基础学习之旅#14】串口发送字符串
  • 【Python】串口通信-与FPGA、蓝牙模块实现串口通信(Python+FPGA)
  • 【Arduino TinyGo】【最新】使用Go语言编写Arduino-环境搭建和点亮LED灯
  • 【全网首发开源教程】【Labview机器人仿真与控制】Labview与Solidworks多路支配关系-四足爬行机器人仿真与控制
    遇见未来

http://www.ppmy.cn/news/1168779.html

相关文章

【Edabit 算法 ★☆☆☆☆☆】 Less Than 100?

【Edabit 算法 ★☆☆☆☆☆】 Less Than 100? language_fundamentals math validation Instructions Given two numbers, return true if the sum of both numbers is less than 100. Otherwise return false. Examples lessThan100(22, 15) // true // 22 15 37lessTha…

推特爆火!超越ChatGPT和Llama2,新一代检索增强方法Self-RAG来了原创

作者 | ZenMoore 前言 大型语言模型&#xff08;LLMs&#xff09;具有出色的能力&#xff0c;但由于完全依赖其内部的参数化知识&#xff0c;它们经常产生包含事实错误的回答&#xff0c;尤其在长尾知识中。为了解决这一问题&#xff0c;之前的研究人员提出了检索增强生成&…

061:mapboxGL利用fitBounds同时将多个点放在可视范围内

第061个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+mapbox中加载geojson数据,利用fitBounds同时将多个点放在可视范围内。 直接复制下面的 vue+mapbox源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共134行)相关API参考:专栏目标示例…

二、ElasticSearch中索引库与文档操作

文章目录 二、索引库与文档2.1 mapping映射属性2.2 操作索引库2.3 文档操作 二、索引库与文档 2.1 mapping映射属性 mapping映射属性 官方网址&#xff1a;https://www.elastic.co/guide/en/elasticsearch/reference/7.12/dynamic-mapping.html mapping 是对索引库中文档的…

数据结构-树的概念结构及存储

&#x1f5e1;CSDN主页&#xff1a;d1ff1cult.&#x1f5e1; &#x1f5e1;代码云仓库&#xff1a;d1ff1cult.&#x1f5e1; &#x1f5e1;文章栏目&#xff1a;数据结构专栏&#x1f5e1; 目录 一、树的基本概念及结构 1树的概念 2树的存储 二、二叉树的概念及结构 1二叉树的概…

大数据Flink(一百):SQL自定义函数(UDF)和标量函数(Scalar Function)

文章目录 SQL自定义函数(UDF)和标量函数(Scalar Function)

RT-Thread学习笔记(四):RT-Thread Studio工具使用

RT-Thread Studio工具使用 官网详细资料实用操作1. 查看 RT-Thread RTOS API 文档2.打开已创建的工程3.添加头文件路径4. 如何设置生成hex文件5.新建工程 官网详细资料 RT-Thread Studio 用户手册 实用操作 1. 查看 RT-Thread RTOS API 文档 2.打开已创建的工程 如果打开项目…

Leetcode—2525.根据规则将箱子分类【简单】

2023每日刷题&#xff08;五&#xff09; Leetcode—2525.根据规则将箱子分类 实现代码 char * categorizeBox(int length, int width, int height, int mass){long long volume;long long len (long long)length;long long wid (long long)width;long long heig (long lo…