【GD32】从零开始学GD32单片机高级篇——外部存储器控制器EXMC详解+SDRAM读写例程

article/2025/10/26 12:05:08

目录

  • 简介
  • 外部设备地址映射
    • NOR和PSRAM的地址映射
    • NAND/PC Card地址映射
    • SDRAM地址映射
  • NOR/PSRAM控制器
    • 接口描述
    • 控制时序
      • 模式1
      • 模式2
  • NAND Flash或PC Card控制器
    • 接口描述
    • 控制时序
  • SDRAM控制器
    • 接口描述
    • 控制时序
    • 突发读操作
    • 突发写操作
    • 读写FIFO
    • 跨边界读写操作
    • 低功耗模式
      • 自刷新模式
      • 掉电模式
  • 例程
    • SDRAM读写例程
      • 初始化GPIO
      • 初始化EXMC
      • 初始化SDRAM
      • SDRAM写
      • SDRAM读

简介

外部存储器控制器EXMC,用来访问各种片外存储器,通过配置寄存器,EXMC可以把AMBA
协议转换为专用的片外存储器通信协议,包括SRAM,ROM,NOR Flash,NAND Flash,PC Card和SDRAM

在这里插入图片描述

外部设备地址映射

EXMC的工作原理其实就是把外部储存器的地址映射到内部的特定地址上,用户想访问外部的存储器,我们只需要访问对应的内部地址,EXMC就会自动地帮用户寻址到外部存储器的对应地址。在GD32F4中,从0x60000000-0xDFFFFFFF之间的地址空间是留给EXMC做外部存储器地址映射的,这些地址空间又会被分成4个Bank,给不同种类的外部存储器做映射,如下图所示。

在这里插入图片描述

每个bank为256MB,bank0给NOR Flash和PSRAM做映射,bank1和bank2给NAND Flash做映射,bank3给PC Card做映射,剩下的地址给SDRAM做映射。

NOR和PSRAM的地址映射

NOR和PSRAM的bank0区域又会被分成4等份,称为Region,每个region有64MB,每份地址空间又会用作不同外部存储器的映射,如下图所示。

在这里插入图片描述

唯一的区别就是,只有region0支持SQPI-PSRAM,全部的region都支持NOR Flash和PSRAM。

NAND/PC Card地址映射

Bank1和Bank2用来访问NAND Flash,Bank3用来访问PC Card。每个Bank地址映射被分为多个存储空间,如下图所示。

在这里插入图片描述

对于NAND Flash,通用和属性空间又可以细划分为3个区域,如下图所示。

在这里插入图片描述

SDRAM地址映射

SDRAM的地址映射就比较简单,4个bank剩下的内存空间被分成2份内存空间——SDRAM device0和SDRAM device1,每个device就对应一个SDRAM存储器。
虽然说每个device最大寻址256MB,但这是在SDRAM是32bit数据宽度的前提下,不同的数据位宽最大的寻址空间也不同,可以参考下面这个表。

存储器数据宽度最大储存容量
8-bit64MB
16-bit128MB
32-bit256MB

NOR/PSRAM控制器

EXMC模块的NOR/PSRAM控制器控制Bank0,它可以支持NOR Flash、PSRAM、SRAM、ROM和CRAM外部存储器。

接口描述

NOR Flash接口信号描述:

在这里插入图片描述

PSRAM非复用接口信号描述:

在这里插入图片描述

SQPI-PSRAM接口信号描述:

在这里插入图片描述

控制时序

NOR/PSRAM控制器提供了丰富的控制时序,以满足不同的需求,如下表所示。

在这里插入图片描述

拓展模式为1指的是在该时序模式下,读时序和写时序可以设置不同的参数。
DSET为数据建立时间;ASET为地址建立时间;AHLD为地址保持时间;BUSLAT为总线延迟;DLAT为数据延迟;CKDIV为同步时钟分频比
如果参数前有“W”,说明这是写时序的参数

下面讲一下比较常用的模式1和2。

模式1

模式1用于SRAM、PSRAM和CRAM。
模式1读时序:

在这里插入图片描述

模式1写时序:

在这里插入图片描述

除开数据和写使能部分,其他的操作都是一样的,发送地址、使能芯片、选择字节、使能输出。
对于读操作,写使能一直为高,在数据建立时间内EXMC会接收到存储器发送的数据。
对于写操作,在地址建立时间后,写使能应拉低,并开始向存储器写入数据;数据写入完成后拉高写使能,并在1个HCLK周期后结束本次写操作。

模式2

模式2是用于NOR Flash。
模式2读时序:

在这里插入图片描述

模式2写时序:

在这里插入图片描述

模式2的时序和上面讲到的模式1时序区别也不大,主要在于地址有效线的控制。
在模式2中,每一次读写数据都需要将地址有效线拉高,表示此时地址无效。

NAND Flash或PC Card控制器

EXMC外设支持8位、16位的NAND FLASH以及16位PC卡;对于NAND FLASH,EXMC还提供ECC计算模块。

接口描述

8 位/16 位NAND接口信号描述:

在这里插入图片描述

16位PC Card接口信号描述:

在这里插入图片描述
在这里插入图片描述

控制时序

该控制器提供了以下可编程参数来控制存储器:

参数功能描述最小值(单位:HCLK)最大值(单位:HCLK)
存储器数据总线高阻时间(HIZ)启动写操作之后保持数据总线为高阻态的时间1255
存储器保持时间(HLD)在发送命令结束后保持地址的时钟(HCLK)周期数目,写操作时也是数据的保持时间1254
存储器等待时间(WAIT)发出命令的最短持续时间时钟(HCLK)周期数目2255
存储器建立时间(SET)发出命令之前建立地址的(HCLK)时钟周期数目1256

NAND Flash的通用空间操作时序如下图所示:

在这里插入图片描述

NAND Flash的简要操作步骤如下:

  1. 配置NAND Flash相关寄存器;
  2. 往通用空间写入NAND Flash读数据命令(在EXMC_NCE和EXMC_NWE有效时,EXMC_CLE(A[16])变为有效电平(高));
  3. 往通用空间写入读操作的起始地址(在EXMC_NCE和EXMC_NWE有效期间,EXMC_ALE(A[17])变为有效电平(高));
  4. 等待 NAND 就绪信号;
  5. 从通用空间的数据区逐字节的读出数据;
  6. 不写入新的命令和地址,可以自动读出 NAND 下一页数据;或转到3写入新的地址进
    行下一页的读取;或转到2写入新的命令和地址。

SDRAM控制器

该控制器支持8 位,16 位,32 位数据带宽;AHB字、半字、字节访问;写使能和字节选择输出;自动进行行和bank边界管理;多个bank的乒乓访问;具有16x35位深度的写数据FIFO;具有16x31位深度的写地址FIFO;6x32位深度的可缓存的读数据FIFO;6x14位深度的可缓存读地址FIFO;可调整的读数据采样时钟;自刷新模式。

在这里插入图片描述

接口描述

在这里插入图片描述

控制时序

SDRAM的控制相对来说复杂,总体的步骤可分为下面几步:

  1. 初始化SDRAM寄存器,包括设置控制参数、时序参数、预充电、自刷新模式、自刷新频率。

预充电:若SDRAM控制器在存取时需要进行行切换,那么首先需要将该行地址对应块的读写放大器去使能,使其进入空闲状态,为下一行的读写操作进行准备。这个过程叫做预充电,或者行去使能。

  1. 发送行使能命令。该命令将行地址所在的块使能,完整的行地址由2比特的块地址EXMC_A[15:14]和13比特的行地址EXMC_A[12:0]组成。
  2. 发送列地址并进行读写访问。为了连续访问,控制器通常会保存之前操作的行号。若下一次的读取位置是在相同的行号或是已经使能的其他行号,那么读操作会未中断的执行。

突发读操作

突发读操作是对一个未被使能的行突发读操作,在读之前发送了行使能指令。

在这里插入图片描述

由上图可以看到,当发送了列地址后,数据并没有被立即读取,而是延迟了一定的HCLK周期后再进行采样。
这是因为当HCLK采样数据不准的时候,用户可以使用根据HCLK微调的内部可调时钟。当使能这个时钟的时候,读取的数据在进入AHB总线之前会先存储在异步FIFO中。2-3个HCLK延迟会被添加到读命令过程中。

RCD:行到列延迟。它代表了行使能到SDRAM读写间的最小等待时间。

突发写操作

突发写操作是对一个未被使能的行突发写操作,在写之前发送了行使能指令。

在这里插入图片描述

读写FIFO

在进行读写操作时会充分地利用SDRAM控制器中的FIFO;FIFO有两组,一组给读操作使用,一组给写操作使用;每组中有2个FIFO,一个储存地址,一个储存数据。数据FIFO能够最多缓存6个32位的数据字,同时地址FIFO携带6个14位的地址标签
当在AHB总线上出现一个读命令时,读写命令预处理模块将首先检查这个地址是否和某个地址
标签匹配,如果匹配,则直接从FIFO中读取数据。否则,向存储器发一个新的读命令,FIFO会
被新的数据更新。如果FIFO满了,旧的数据会被丢失。
当一个写访问或者预充电命令出现时,读FIFO缓冲区中的数据就会被清除掉,用以填充新的数
据。

跨边界读写操作

跨边界读写操作就是一次读写中会操作不同的行或bank的读写操作。
它们的时序其实就是加上了行预充电的延迟而已,如下图所示。

跨边界读操作:

在这里插入图片描述

跨边界写操作:

在这里插入图片描述

低功耗模式

对于SDRAM来说,它的性质和我们平常用的电脑内存是差不多的,是一种易失性的存储器。为了保持SDRAM中的数据,我们需要不断地刷新SDRAM;因为SDRAM的储存单元是由电容所组成的,若长时间不对电容充电是会损失数据的。
低功耗模式就是设置SDRAM的刷新策略;EXMC对SDRAM提供了2种低功耗模式——自刷新模式和掉电模式

自刷新模式

在自刷新模式下,EXMC不提供时钟信号,刷新完全由SDRAM内部提供。
下面演示了如何进入和退出自刷新模式:

在这里插入图片描述

当发送ARef命令后,EXMC关闭时钟输入,关闭时钟使能,命令保持在NOP操作,SDRAM进入自刷新模式;退出该模式也是通过发送ARef命令,使能时钟来实现。

掉电模式

在掉电模式中,刷新则由SDRAM控制器提供。
下面演示了如何进入和退出掉电模式:

在这里插入图片描述

进入掉电模式,只需要关闭时钟即可;而退出该模式除了打开时钟外,还需要发送Active命令。

例程

SDRAM读写例程

在本例程中,我使用的是立创梁山派开发板,这个开发板搭载GD32F470ZGT6主控,自带一颗华邦(Winbond)型号为W9825G6KH-6L的SDRAM芯片,储存容量高达256MB

在这里插入图片描述

因为SDRAM的驱动动则上百行,下面就以每一步的要点进行讲解。

初始化GPIO

GPIO的初始化就不放代码了,大家应该都会写的。GOIO的初始化包括13根地址线(EXMC_A[0-12])、16根数据线(EXMC_D[0-15])、写数据标记线(EXMC_NBL[0-1])、时钟使能信号线(EXMC_CKE0)、Bank片选线(EXMC_BA[0-1])、时钟信号线(EXMC_CLK)、列地址选通线(EXMC_NCAS)、行地址选通线(EXMC_NRAS)、读使能线(EXMC_NOE)、写使能线(EXMC_NWE)
所有的GPIO口全部设置成复用推挽上拉模式,并且全部GPIO口都要将复用口映射到GPIO_AF_12中

SDRAM涉及的GPIO接口较多,建议在数据手册中查找对应的GPIO口;在初始化RCU的时候也要注意初始化SDRAM用到的所有GPIO时钟。

初始化EXMC

exmc_sdram_parameter_struct sdram_init_struct;
exmc_sdram_timing_parameter_struct sdram_timing_init_struct;/* enable EXMC clock */
rcu_periph_clock_enable(RCU_EXMC);/* config SDRAM timing registers */
/* LMRD: 2 clock cycles */
sdram_timing_init_struct.load_mode_register_delay = 2;
/* XSRD: 9 / 120MHz = 75ns */
sdram_timing_init_struct.exit_selfrefresh_delay = 9;
/* RASD: 5 / 120MHz = 45ns */
sdram_timing_init_struct.row_address_select_delay = 5;
/* ARFD: 8 / 120MHz = 74ns */
sdram_timing_init_struct.auto_refresh_delay = 8;
/* WRD:  min = 2 Clock cycles */
sdram_timing_init_struct.write_recovery_delay = 3;
/* RPD:  3 / 120MHz = 27ns */
sdram_timing_init_struct.row_precharge_delay = 3;
/* RCD:  3 / 120MHz = 27ns */
sdram_timing_init_struct.row_to_column_delay = 3;/* config SDRAM control registers */
sdram_init_struct.sdram_device = EXMC_SDRAM_DEVICEx;
sdram_init_struct.column_address_width = EXMC_SDRAM_COW_ADDRESS_9;  // 9bit of column address
sdram_init_struct.row_address_width = EXMC_SDRAM_ROW_ADDRESS_13;  // 13bit of row address
sdram_init_struct.data_width = EXMC_SDRAM_DATABUS_WIDTH_16B;  // 16bit of data width
sdram_init_struct.internal_bank_number = EXMC_SDRAM_4_INTER_BANK;  // 4 internal bank
sdram_init_struct.cas_latency = EXMC_CAS_LATENCY_3_SDCLK;  // 3 sdram clock of CAS latency
sdram_init_struct.write_protection = DISABLE;
sdram_init_struct.sdclock_config = EXMC_SDCLK_PERIODS_2_HCLK;  // SDCLK = HCLK / 2 = 240MHz / 2 = 120MHz
sdram_init_struct.burst_read_switch = ENABLE;
sdram_init_struct.pipeline_read_delay = EXMC_PIPELINE_DELAY_2_HCLK;
sdram_init_struct.timing = &sdram_timing_init_struct;exmc_sdram_init(&sdram_init_struct);

这一部分别用到两个结构体——exmc_sdram_parameter_struct和exmc_sdram_timing_parameter_struct,一个是用于初始化SDRAM的控制寄存器,一个是用于初始化SDRAM的时序寄存器。

这里先设置SDRAM的时序寄存器,结构体的成员名字其实都写得很清楚是哪一部分的时序,但为了照顾部分英语不好的同学,我简单翻译一下。
上面时序初始化结构体成员从上到下为模式寄存器加载延迟、自刷新模式退出延迟、行地址选通延迟、自刷新延迟、写恢复延迟、行预充电延迟、行到列延迟
这些时序该如何填写需要参考对应SDRAM芯片数据手册的说明,但有时候不同厂商对同一种时序的命名是不同的,所以如果实在找不到的话可以参考兆易创新官方的例程,或者把数值设得大一点,因为一般来说控制得慢一点是没有问题的。

接着设置SDRAM的控制寄存器,从上到下到下的设置为SDRAM设备片选,这个取决于你想把SDRAM挂载在哪里,一般选SDRAM_DEVICE0就行了;列地址宽度,选择9位;行地址宽度,选择13位;内部bank数目,4个;CAS延迟,2个或3个SDCLK周期都行,不同的选择,SDRAM的最高工作频率会不同,这里选择3个周期,对应最高工作频率为166MHz;

下面是我使用的这颗SDRAM的CAS延迟与频率参考表:
在这里插入图片描述
可以看到如果CAS延迟选3个SDCLK周期,那么SDRAM能最高工作在166MHz的速度下,如果选择2个SDCLK周期就只能最高工作在133MHz速度下。

写保护,不使能;时钟频率,选择HCLK二分频,这个频率十分重要,上面时序的计算就要用到这个频率,而且这个频率不能高于SDRAM的最高工作频率突发读切换,使能;管道读延迟,2个HCLK周期;时序,填入我们设置好的时序初始化结构体。

初始化SDRAM

单片机的外设初始化完成后,我们还要通过发送命令初始化SDRAM。这里要用到exmc_sdram_command_parameter_struct这个结构体。

exmc_sdram_command_parameter_struct sdram_command_init_struct;/* configure CKE high command */
sdram_command_init_struct.command = EXMC_SDRAM_CLOCK_ENABLE;
sdram_command_init_struct.bank_select = EXMC_SDRAM_DEVICEx_SELECT;
sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_2_SDCLK;
sdram_command_init_struct.mode_register_content = 0;
/* wait until the SDRAM controller is ready */
timeout = SDRAM_TIMEOUT;
while((exmc_flag_get(EXMC_SDRAM_DEVICEx, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)) {timeout--;
}
/* send the command */
exmc_sdram_command_config(&sdram_command_init_struct);
delay_1ms(10);/* configure precharge all command */
sdram_command_init_struct.command = EXMC_SDRAM_PRECHARGE_ALL;
sdram_command_init_struct.bank_select = EXMC_SDRAM_DEVICEx_SELECT;
sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_2_SDCLK;
sdram_command_init_struct.mode_register_content = 0;
/* wait until the SDRAM controller is ready */
timeout = SDRAM_TIMEOUT;
while((exmc_flag_get(EXMC_SDRAM_DEVICEx, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)) {timeout--;
}
/* send the command */
exmc_sdram_command_config(&sdram_command_init_struct);/* configure Auto-Refresh command */
sdram_command_init_struct.command = EXMC_SDRAM_AUTO_REFRESH;
sdram_command_init_struct.bank_select = EXMC_SDRAM_DEVICEx_SELECT;
sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_9_SDCLK;
sdram_command_init_struct.mode_register_content = 0;
/* wait until the SDRAM controller is ready */
timeout = SDRAM_TIMEOUT;
while((exmc_flag_get(EXMC_SDRAM_DEVICEx, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)) {timeout--;
}
/* send the command */
exmc_sdram_command_config(&sdram_command_init_struct);/* configure load mode register command */
/* program mode register */
uint32_t command_content = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1   |SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL               |SDRAM_MODEREG_CAS_LATENCY_3                       |SDRAM_MODEREG_WRITEBURST_READBURST;sdram_command_init_struct.command = EXMC_SDRAM_LOAD_MODE_REGISTER;
sdram_command_init_struct.bank_select = EXMC_SDRAM_DEVICEx_SELECT;
sdram_command_init_struct.auto_refresh_number = EXMC_SDRAM_AUTO_REFLESH_2_SDCLK;
sdram_command_init_struct.mode_register_content = command_content;/* wait until the SDRAM controller is ready */
timeout = SDRAM_TIMEOUT;
while((exmc_flag_get(EXMC_SDRAM_DEVICEx, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)) {timeout--;
}
/* send the command */
exmc_sdram_command_config(&sdram_command_init_struct);/* step 8 : set the auto-refresh rate counter--------------------------------*/
/* 64ms, 8192-cycle refresh, 64ms/8192=7.81us */
/* SDCLK_Freq = SYS_Freq/2 */
/* (7.81 us * SDCLK_Freq) - 20 */
exmc_sdram_refresh_count_set(761);/* wait until the SDRAM controller is ready */
timeout = SDRAM_TIMEOUT;
while((exmc_flag_get(EXMC_SDRAM_DEVICEx, EXMC_SDRAM_FLAG_NREADY) != RESET) && (timeout > 0)) {timeout--;
}

第一步,发送SDRAM时钟使能命令;第二步,预充电所有行;第三步,使能自刷新;第四步,设置模式加载寄存器,模式加载寄存器的内容每个SDRAM芯片都不尽相同,我这颗芯片的模式加载寄存器如下图。
在这里插入图片描述

第1-3位设置的是突发读写的长度,可以选择1位、2位、4位、8位和整页;第4位设置的是寻址模式,可以选择顺序模式和插入模式;第5-7位设置的是CAS延迟,可以选择2个或3个SDCLK周期;第10位设置的是单独写模式,可以设置突发读写和突发读单独写。

我的设置是突发读写长度为1位,寻址模式为顺序模式,CAS延迟和之前初始化结构体一样为3个SDCLK周期,单独写模式为突发读和写。

第五步,设置自刷新计数寄存器值,GD官方的例程中给出了这个值的计算公式,但是看了半天也不知道是怎么计算的,所有如果有大神看懂了,欢迎在评论区留言。

至此,SDRAM就完全初始化好了,可以开始读写数据了。

SDRAM写

void SDRAM_WriteBuffer(uint8_t *buf, uint32_t writeaddr, uint32_t num)
{/* while there is data to  */for(uint32_t i = 0; i < num; ++i){/* read a byte from the memory */*(uint8_t *)(SDRAM_DEVICE0_ADDR + writeaddr) = buf[i];/* increment the address */++writeaddr;}
}

因为EXMC帮我们完成了两个存储器地址之间的映射和通行工作,所以我们读写SDRAM跟操作单片机内部的内存一样简单。
向SDRAM写一串数据,只需要将SDRAM设备的基地址加上地址偏移即可得到写入的地址,解指针后为其赋值即可将数据存入SDRAM。

SDRAM设备0的基地址为0xC0000000
SDRAM设备1的基地址为0xD0000000

SDRAM读

void SDRAM_ReadBuffer(uint8_t *buf, uint32_t readaddr, uint32_t num)
{/* while there is data to read */for(uint32_t i = 0; i < num; ++i){/* read a byte from the memory */buf[i] = *(uint8_t *)(SDRAM_DEVICE0_ADDR + readaddr);/* increment the address */++readaddr;}
}

SDRAM的读跟写差不多,也是得到目标地址,解指针后将值赋给数组或变量,即可实现SDRAM的读。

下面SDRAM读写的串口输出结果

在这里插入图片描述


http://chatgpt.dhexx.cn/article/6MaBsGIU.shtml

相关文章

初识内存控制器和SDRAM【一文了解】

原文链接&#xff1a;https://blog.csdn.net/qq_36243942/article/details/85596249 目录 1.引入内存控制器 2.不同位宽内存设备之间的连接 3.如何确定芯片的访问地址 4.分析读写NOR FLASH的读写时序 5.SDRAM初识 6.编程读/写 SDRAM 附录&#xff1a;源代码 1.引入内存控制器 我…

存储控制器(SDRAM操作)

什么是存储控制器 2440是32位单片机&#xff0c;进行数据访问时通过32位地址访问。 CPU发出32位地址信号给存储控制器&#xff0c;存储控制器根据地址信号设置片选信号及地址总线&#xff0c;将相应数据通过数据总线传回存储控制器&#xff0c;存储控制器将收到的数据以字节为…

数字IC实践项目(2)——高速SDRAM控制器的设计与综合(入门级工程项目)

数字IC实践项目&#xff08;2&#xff09;—高速SDRAM控制器的设计与综合&#xff08;入门级工程项目&#xff09; 写在前面的话项目简介和学习目的SDRAM简介SDRAM控制器简介完整项目框图SDRAM控制器项目框图SDRAM初始化模块SDRAM自动刷新模块SDRAM写模块SDRAM读模块SDRAM仲裁机…

SDRAM控制器——仲裁模块的实现

前面一文中&#xff0c;我们已经对SDRAM的上电初始化、自动刷新以及突发读写进行了学习。 本文跟着大佬学习SDRAM中的仲裁模块。 仲裁机制 仲裁&#xff08;arbit&#xff09;&#xff1a;在FPGA中&#xff0c;当多个source源同时发出请求&#xff0c;容易导致操作冲突&#x…

SDRAM读写控制器

第1节 –作者&#xff1a;小黑同学 本文为明德扬原创及录用文章&#xff0c;转载请注明出处&#xff01; 1.1 总体设计 1.1.1 概述 同步动态随机存取内存&#xff08;synchronous dynamic randon-access menory&#xff0c;简称SDRAM&#xff09;是有一个同步接口的动态随…

FPGA综合项目——SDRAM控制器

FPGA综合项目——SDRAM控制器 目录 1.整体框架2.串口接收模块3.接收模块测试仿真4.串口发送模块5.发送模块测试仿真6.SDRAM基础学习7.SDRAM顶层模块8.SDRAM初始化模块设计与仿真测试9.自动刷新模块设计与测试10.写模块设计与测试11.读模块设计与仿真测试12.通信处理模块13.顶层…

细说SDRAM控制器

SDRAM的基本概念 SDRAM凭借其极高的性价比&#xff0c;广泛应用于高速数据存储、实时图像处理等设计当中&#xff0c;但是相对于SRAM、FIFO等其他存储器件&#xff0c;SDRAM的控制相对复杂。虽说是复杂&#xff0c;但也不代表没办法实现&#xff0c;仔细梳理一下&#xff0c;发…

SDRAM控制器

1.SDRAM简介 简介&#xff1a;SDRAM为同步动态随机存储内存&#xff0c;同步指的是时钟与外部输入的时钟保持一致&#xff0c;也就是与外部共用一个时钟&#xff1b;动态指的是每个时间段内&#xff0c;都要进行一次刷新操作&#xff0c;否则里面的数据会丢失&#xff0c;这也…

FPGA学习历程(四):SDRAM 控制器(初始化与刷新)

目录 一、数据手册相关信息1.1 命令真值表1.2 时间参数1.3 模式寄存器配置 二、初始化模块2.1 模块时序图2.2 模块源码2.2.1 sdram_init.v2.2.2 sdram_top.v2.2.3 tb_sdram_top.v 2.3 Modelsim仿真 三、刷新模块3.1 模块时序图3.2 模块源码3.2.1 sdram_aref.v3.2.2 sdram_top.v…

手把手带你实现SDRAM控制器(带Verilog代码)

上篇博客&#xff0c;我们了解了SDRAM的控制命令以及寻址方式&#xff0c;SDRAM芯片需要配合专门的控制电路使用才能发挥功能&#xff0c;这一节我们将一步步分析&#xff0c;使用Verilog搭建一个SDRAM驱动控制器。 目录 学习目标 问题分析 初始化模块 信息收集 模块接口确…

SDRAM 控制器(一)

1、基础知识 SDRAM&#xff08;synchronous Dynamic Random &#xff09;&#xff0c;同步动态随机存储器&#xff0c;同步指内存工作需要同步时钟&#xff0c;内存的命令的发送和数据的接收都以它为标准。动态是指需要不断地刷新来保证数据不丢失&#xff08;电容存储&#xf…

操作系统面试题(二十一):什么是DMA

DMA DMA&#xff08;Direct Memory Access 直接内存访问&#xff09; DMA意味着CPU授予I/O模块权限不涉及在不涉及CPU的情况下依然可以读取/写入内存&#xff0c;即DMA不需要CPUde支持 DMAC&#xff08;DMA 控制器&#xff09; 控制直接内存访问的过程 DMA的优点&#xff1a…

操作系统面试题:虚拟内存是什么,解决了什么问题,如何映射?

虚拟内存是什么&#xff1f; 虚拟内存别称虚拟存储器&#xff08;Virtual Memory&#xff09;。电脑中所运行的程序均需经由内存执行&#xff0c;若执行的程序占用内存很大或很多&#xff0c;则会导致内存消耗殆尽。为解决该问题&#xff0c;Windows中运用了虚拟内存技术&…

Linux面试题(34道)

1、Linux中各个目录的作用 1&#xff09;/ 根目录 2&#xff09;/boot 引导程序&#xff0c;内核等存放的目录 3&#xff09;/sbin 超级用户可以使用的命令的存放目录 4&#xff09;/bin 普通用户可以使用的命令的存放目录 5&#xff09;/lib 根目录下的所程序的共享库目录 6&…

【游戏客户端面试题干货】-- 2021年度最新游戏客户端面试干货(操作系统篇)

【游戏客户端面试题干货】-- 2021年度最新游戏客户端面试干货(操作系统篇&#xff09; 大家好&#xff0c;我是Lampard~~ 经过一番艰苦奋战之后&#xff0c;我终于是进入了心仪的公司。 今天给大家分享一下我在之前精心准备的一套面试知识。 今天和大家分享的是操作系统相关的面…

操作系统和网络(一):计算机网络常见面试题

计算机网络常见面试题总结 1. OSI &#xff0c; TCP/IP &#xff0c;五层协议的体系结构 OSI分层&#xff08;7层&#xff09; &#xff1a;物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。 TCP/IP分层&#xff08;4层&#xff09; &#xff1a;网络接…

【Java实习生】每日面试题打卡——操作系统篇

临近秋招&#xff0c;备战暑期实习&#xff0c;祝大家每天进步亿点点&#xff01;Day15本篇总结的是 操作系统 相关的面试题&#xff0c;后续会每日更新~ 1、请分别简单说一说进程和线程以及它们的区别? 根本区别&#xff1a;进程是操作系统资源分配的基本单位&#xff0c;而…

操作系统面试题(一)

请你说一下进程与线程的概念&#xff0c;以及为什么要有进程线程&#xff0c;其中有什么区别&#xff0c;他们各自又是怎么同步的 参考回答&#xff1a; 基本概念&#xff1a; 进程是对运行时程序的封装&#xff0c;是系统进行资源调度和分配的的基本单位&#xff0c;实现了…

操作系统面试常问——for考研复试面试

关于操作系统的一些面试常问问题 前言&#xff1a; 本人22考研党已上岸&#xff0c;发一些复试准备整理的资料作为对考研准备的一个收尾。由于近几年基本都是线上复试&#xff0c;线上的话会更加注重概念的考察&#xff0c;本人在复试准备期间搜集了面试题&#xff0c;整理了…

操作系统面试题(三)

请你来说一说协程 参考回答&#xff1a; 1、概念&#xff1a; 协程&#xff0c;又称微线程&#xff0c;纤程&#xff0c;英文名Coroutine。协程看上去也是子程序&#xff0c;但执行过程中&#xff0c;在子程序内部可中断&#xff0c;然后转而执行别的子程序&#xff0c;在适…