基于SDRAM的串口回环测试


前言

  本文将介绍在AWC_C4MB开发板上进行基于串口的SDRAM数据回环测试的方法和步骤。SDRAM是一种常用的存储器类型,而串口是一种常用的通信接口。通过将二者结合起来,我们可以验证SDRAM的性能和功能是否正常。
  在本测试中,我们将使用AWC_C4MB开发板作为测试平台。AWC_C4MB开发板是一款强大且灵活的硬件平台,具有丰富的资源和功能,非常适合进行SDRAM数据回环测试。同时,该开发板支持串口通信,并具有足够的计算和存储能力,方便我们进行数据的处理和分析。开发板实物图如下:

在这里插入图片描述
  SDRAM数据回环测试的目的是将数据通过串口发送到SDRAM中,然后再将其从SDRAM读取出来,并通过串口返回到主机端,最后比较发送前和发送后的数据是否完全一致。通过这种方式,我们可以验证SDRAM的写入和读取功能是否正常,并检查数据的完整性。
  本文代码开源,各位读者可至如下链接提取代码、波形图和数据手册等文件
链接:https://pan.baidu.com/s/1COZh4b3DZ8-TH9HHuGCpIg
提取码:fpga
  注:本文未编写各模块测试部分的正文,各位读者有兴趣可自行在上述链接“sim”子文件夹内找到仿真模型自行编写代码验证。

一、SDRAM简介

  本次测试使用到的SDRAM芯片型号为H57V2562GTR-75C,具有268,435,456位的存储容量。该芯片被组织为4个存储体块,每个存储体块具有4,194,304个存储容量和16位输入/输出。
  SDRAM同步动态随机存取存储器(Synchronous Dynamic Random Access Memory)的简称。其中的"同步"表示SDRAM与外部时钟同步操作,读写操作与时钟信号同步进行。这种同步操作使得存储器的速度更快,并且可以更有效地与其他系统组件进行通信。“动态”指的是SDRAM的存储单元采用的是动态存储技术。相较于静态存储器(SRAM),动态存储器具有更高的存储密度和较低的成本。SDRAM的存储单元是由电容器和晶体管构成的,电容器用于存储数据,但需要周期性地进行刷新以保持数据的稳定性。
  SDRAM在输入时钟的上升沿处锁存每个控制信号,并与输入时钟同步输入/输出数据。行列地址线是复用的,以此减少引脚资源消耗,并且所有命令都与时钟上升沿同步锁存。

二、SDRAM芯片手册解析

2.1 芯片信息

在这里插入图片描述
  开发板板载的SDRAM芯片型号为H57V2562GTR-75C,采用133MHZ时钟驱动可以达到比较好的效果。
  芯片电气特性参数表如下:

在这里插入图片描述
  上述表格描述了SDRAM在正常工作时,内部信号作用需要满足的时间参数条件。例如,SDRAM驱动时钟,低电平和高电平持续的最短时间均为2.5ns,因此SDRAM支持的最大驱动时钟为200MHZ。为了本次工程的设计方便,采用100MHZ的时钟来驱动SDRAM。

2.2 功能描述

在这里插入图片描述
  第一段描述了256Mbit SDRAM是什么计算来的,因为总共有13行,9列,4个Bank存储区域,每个存储区域可存储的数据深度为2的13次方x2的9次方,因为每个数据位宽为16位,因此总共的存储容量为2的13次方x2的9次方x16x4≈256Mbit。
  第二段描述了怎么指定行和列进行存储,首先是选择存储的Bank区域,然后指定存储的行,再指定存储的列。
  第三段告诉读者,在进行后续的读写操作或者执行其它命令时,是必须建立在SDRAM初始化完成的基础上。

2.3 指令集

在这里插入图片描述
  COMMAND INHIBIT (NOP):禁止指令,该指令会抑制或禁止执行其他命令。这意味着,当COMMAND INHIBIT命令处于活动状态时,任何其他命令(例如预充电、读取、写入等)都会被延迟或阻止执行,直到COMMAND INHIBIT指令解除。
  NO OPERATION (NOP):空操作指令,不执行任何操作。它被用来作为其他命令之间的空闲时间填充,或者在需要等待一定时间的情况下使用。
  ACTIVE (select bank and activate row):激活指令,用于选择指定的bank并激活所选行的一种命令。
  READ (select bank and column, and start READ burst):读指令,用于选择指定的bank和列,并启动读取操作的命令。
  WRITE (select bank and column, and start WRITE burst):写指令,用于选择指定的bank和列,并启动写入操作的命令。
  BURST TERMINATE:突发读(写)终止指令,用于终止当前正在进行的读取或写入突发(burst)操作的命令。
  PRECHARGE (Deactivate row in bank or banks):预充电指令,用于取消激活的行(deactivate row)的命令,可以应用于一个或多个bank。
  AUTO REFRESH or SELF REFRESH (enter self refresh mode):自动刷新或者自刷新指令,在自动刷新模式下,SDRAM在特定的时间间隔内自动刷新存储的数据,以保持数据的有效性;在自刷新模式下,SDRAM会自动进行刷新操作,将存储的数据重新写入内部储存电池中,以保持数据的有效性,自刷新模式下,SDRAM的功耗较低,它处于一种较为静态休眠的状态。
  LOAD MODE REGISTER:加载模式寄存器配置的指令,用于控制SDRAM的各种工作模式和参数设置。
  其中,需要注意的是,DQM为SDRAM的数据掩码,如果该数据掩码为高电平,那么就让SDRAM读写失能,反之为低电平才能让SDRAM正常进行读写操作。

三、SDRAM配置

3.1 初始化

在这里插入图片描述
  根据上述时序图需要注意的是:
  ①在正式发送预充电命令之前,需要等待大于等于100us(有的数据手册是200us)让SDRAM内部电路稳定下来;
  ②COMMAND是由四个SDRAM四个引脚拼接而来:cs_n、ras_n、cas_n和we_n;
  ③除去发送特殊指令的时刻,其余时刻都应该发送空闲指令,防止其它指令写入;
  ④预充电状态下,应该选中所有Bank进行预充电;
  ⑤预充电结束后,需要等待大于等于tRP(20ns)时间,才能进行后续操作;
  ⑥等待tRP结束后需要发送自动刷新指令,自动刷新指令发送完成后需要等待tRFC(66ns)时间,重复进行一次自动刷新并等待操作,才能进行后续操作(实际测试发现,执行一次自动刷新操作也能满足要求);
  ⑦tRFC等待结束后,开始配置模式寄存器,模式配置参数图如下:

在这里插入图片描述
  A[12:10]为保留位,置为全0;A[9]置为0,表示进行突发写和突发读操作;A[8:7]置为全0,表示标准操作模式;A[6:4]表示潜伏期设置,为3’b010表示有两个潜伏期,为3’b011表示有三个潜伏期,潜伏期表示读指令到来时,需要等待设定的潜伏期个数个时钟周期,SDRAM才开始读出有效数据,在这里设定3个潜伏期;A[3]表示突发类型,这里设置为0表示顺序突发;A[2:0]表示突发长度,设置为整页突发,整页突发突发个数最大为一行存储的数据个数。
  ⑧模式寄存器配置完成后,需要等待大于等于tMRD(2个时钟周期)才能进行后续激活配置。
  综上绘制的SDRAM初始化状态转移图如下:

在这里插入图片描述
  根据状态转移图绘制的信号波形图如下:

在这里插入图片描述
  根据信号波形图可知:
  ①在初始状态下,设定需要等待30000个时钟周期(30ms)才会跳转到预充电状态;
  ②在预充电状态下,持续发送预充电指令,发送完成后等待8个时钟周期,等待结束后跳转到自动刷新状态;
  ③在自动刷新状态下,持续发送自动刷新指令,发送完成后等待8个时钟周期,等待结束跳转到模式寄存器设置状态;
  ④在模式寄存器设置状态下,持续发送模式寄存器配置指令,期间地址一直保持预设定的值,发送完成后等待8个时钟周期,等待结束后初始化完成信号会持续拉高,检测到此信号才可进行后续操作。

3.2 自动刷新

在这里插入图片描述
  根据上述时序图可知:
  ①自动刷新操作开始也是需要建立在初始化完成的基础上,然后发送预充电指令,取消所激活的行,等待大于等于tRP(20ns)后执行后续操作;
  ②等待tRP结束,发送自动刷新指令,指令发送完成后等待大于等于tRFC(66ns)才能执行后续操作,在这里也是只需要发送一次自动刷新指令即可;
  ③等待tRFC结束,就可以接着发送后续的读、写等命令了;
  ④需要注意的是,自动刷新并不是只刷新一次就结束了,因为对于Bank所有行自动刷新的时间保持的最大值为tREF(64ms),即64_000_000ns,因为SDRAM驱动时钟为100MHZ,每个时钟周期为10ns,SDRAM内总共有8000行,那么用64_000_000ns/8000行,得到每一行最大的刷新时间为8000ns,用8000ns/10ns,得到利用100MHZ时钟驱动,如果发送了一个自动刷新请求信号,那么距离下一次发送自动刷新请求指令的间隔不得大于800个时钟周期。在这里进行设计,不采用计数800为计数的最大值,设定700为计数的最大值,减少发送指令的时间间隔,使得SDRAM设计出来更加稳定。
  综上绘制的状态转移图如下:

在这里插入图片描述
  根据状态转移图绘制的信号波形图如下:

在这里插入图片描述
  根据信号波形图可知:
  ①每隔700个时钟周期产生一个自动刷新请求信号,该请求信号会发送到后续的仲裁模块,由仲裁模块仲裁后产生一个自动刷新使能信号给该模块,指示自动刷新操作开始,状态也会由空闲状态跳转到预充电状态;
  ②预充电状态持续发送预充电命令完成后,跳转到等待状态,等待8个时钟周期结束,跳转到自动刷新状态;
  ③自动刷新状态持续发送自动刷新命令完成后,跳转到等待状态,等待8个时钟周期结束,拉高一个脉冲的自动刷新结束信号,然后重新回到IDLE状态。

3.3 突发写操作

在这里插入图片描述
  根据上述时序图可知:
  ①在初始化完成后,进行写操作最开始需要先发送一条激活指令,确定所激活的Bank区域,还有哪一行,激活指令发送完成后等待大于等于tRCD(20ns),才能执行后续操作;
  ②等待tRCD结束后,需要发送写指令表示要写入数据,同时与写指令同步发出的,还有突发长度个数据,数据发送完成后,在最后一位需要写入突发停止指令,发送的最后一位数据与发送预充电指令之间要大于等于tWR(≈2个时钟周期)个时钟周期才能进行下一步操作;
  ③在tWR这个时间内,刚好可以发送一个突发停止指令,无延时等待,继续发送预充电指令关闭所有激活的Bank和行,指令发送完成后等待大于等于tRP(20ns)才能执行后续操作。
  综上绘制的状态转移图如下:

在这里插入图片描述
  根据状态转移图绘制的信号波形图如下:

在这里插入图片描述
  根据信号波形图可知:
  ①在初始状态下,如果检测到写使能信号有效,就会发送激活指令,发送完成后等待2个时钟周期,然后跳转到发送写指令状态;
  ②在发送写指令状态下,数据与写指令同步发送,工程中设计突发长度为10,因此在发送完成10个数据后,就发送突发停止指令,然后紧跟预充电指令,预充电指令发送完毕后等待2个时钟周期;
  ③wr_ack为SDRAM传递到FIFO里面的读使能信号,因为本工程设置FIFO IP核时,设定读使能信号有效时,从FIFO里面读出的数据要滞后读使能信号一个时钟周期,因此为了保持同步,读使能信号需要提前一个时钟周期有效。wr_sdram_data为SDRAM从FIFO里面读出的突发长度个数据,wr_sdram_en为读出的数据的有效标志信号;
  ④等待2个时钟周期结束后拉高一个脉冲的写结束信号,指示突发写操作完成。

3.4 突发读操作

在这里插入图片描述
  根据上述时序图可知:
  ①在初始化完成后,进行突发读操作时,也是需要先发送激活指令,确定激活的Bank区域和行,激活后等待大于等于tRCD(20ns),跳转到发送读指令状态;
  ②在发送读指令状态时,因为在初始化时配置了一系列的操作模式,其中有潜伏期的设置,在本工程中设置的潜伏期为3,因此在发送读指令后,需要等待3个时钟周期才能接收到从SDRAM中读出的正确数据;
  ③潜伏期等待结束且读出突发长度个数据后,同样也是需要写入突发停止指令,接着紧跟预充电指令关闭所有激活的Bank区域和激活行,指令发送完成后等待大于等于tRP(20ns)才能执行后续操作。
  综上绘制的状态转移图如下:

在这里插入图片描述
  根据状态转移图绘制的信号波形图如下:

在这里插入图片描述
  根据信号波形图可知:
  ①初始化完成后,检测到读使能信号有效,状态就会由初始状态跳转到发送激活指令状态,激活指令发送完成后,等待8个时钟周期后跳转到读数据状态;
  ②在读数据状态下,完成发成读指令,等待3个时钟周期的潜伏期,然后就跳转到接收数据状态,但是需要注意的是,突发停止指令并不是在读出最后一个数据完成之后发送,是从发送读指令为第一个时钟周期算起,到突发长度个时钟周期结束,然后就发送突发停止指令;
  ③在读出完成突发长度个数据后,就发送预充电指令,等待8个时钟周期完成后,拉高读结束信号,指示一次突发读操作完成。

3.5 仲裁

  在SDRAM初始化完成后,进行自动刷新、读和写操作的仲裁是为了确保存储器的正常操作和数据的完整性。如果不对这三者进行仲裁,那么如果在同一时刻,检测到三者的工作使能信号,SDRAM执行的工作就会错乱。因此,要设置这三者的优先级,使得优先级:自动刷新>写操作>读操作,因为自动刷新操作是SDRAM存储芯片中存储单元的基本要求,它们需要定期进行刷新以保持数据的稳定性和可靠性。如果其它操作的优先级高于刷新操作,那么在刷新周期内,其它操作可能会干扰刷新操作,导致数据错误或丢失。同时,写操作涉及到向SDRAM中写入新的数据,而读操作则是从SDRAM中获取已有的数据,得先有数据,才能从存储器里面读出数据。
  综上所述,仲裁操作状态转移图如下:

在这里插入图片描述
  如图所示,在空闲状态下,如果检测到初始化结束信号,状态就会由空闲状态跳转到仲裁状态,在仲裁状态下,如果检测到自动刷新请求信号、写请求信号或者读请求信号,状态分别跳转到自动刷新状态,写操作状态或者读操作状态,在检测到每个状态的结束信号时,又重新跳转到仲裁状态。
  综上绘制的信号波形图如下所示:

在这里插入图片描述
  其中,写请求信号和读请求信号都是由顶层模块传入进来的,写请求信号拉高条件是在FIFO里面写满了突发长度个数据,然后SDRAM写请求信号就会持续拉高;读请求信号拉高条件是对串口发送数据标志信号进行计数,当计数满突发长度个数时就持续拉高。这里虽然两者的拉高条件看似不同,但都是对串口发送端发送的数据个数进行计数,满足突发长度个数即可拉高。因此,当某一请求信号和另一请求信号同时为高电平时,仲裁模块先对优先级高的请求信号进行处理,产生对应的使能信号,而优先级低的请求信号则会继续保持拉高,SDRAM将高优先级请求信号处理完毕后才会处理低优先级请求信号。

3.5 FIFO控制

  因为SDRAM数据写入和数据读出端工作时钟均为100MHZ,串口数据输入和数据都存储工作时钟均为50MHZ,因此PC机通过串口向SDRAM写入数据或者从SDRAM读出数据,都是需要引入作为跨时钟域处理数据缓存器的。同时,通过读FIFO从SDRAM读出数据,因为使用的是突发读数据,因此也是需要引入一个FIFO来作为数据缓存,如下图所示:

在这里插入图片描述
  对于写FIFO wr_fifo和读FIFO rd_fifo,两个存储器之间的控制信号,要和之前产生的几个模块的信号相关联,因此需要引入一个FIFO控制模块,将两个FIFO和之前编写的模块级联起来。绘制的信号波形图如图所示:

在这里插入图片描述
  wr_fifo_wr_clk是串口写时钟,也是将数据写入到写FIFO里面的时钟,频率为50MHZ;
  wr_fifo_wr_req是串口写入数据使能信号,wr_fifo_wr_data是与之对应传入的数据;
  sdram_wr_b_addr是SDRAM写入数据的初始行地址,本工程将之设置为0;
  sdram_wr_e_addr是SDRAM写入数据的结束行地址,将之设定为突发长度;
  wr_burst_len是突发长度,为固定值;
  rd_fifo_rd_clk是串口读时钟,也是从读FIFO里面读出数据的时钟,频率为50MHZ;
  rd_fifo_rd_req是读FIFO读数据信号,是由另一个读FIFO模块传递进来的信号;
  sdram_rd_b_addr是SDRAM读出数据的初始行地址,为0;
  sdram_rd_e_addr是SDRAM读出数据的结束行地址,为突发长度;
  rd_burst_len是SDRAM读突发长度;
  read_valid是读数据有效信号,当FIFO里面的数据达到突发长度个时,该信号就拉高,如果数据处理完毕后,该信号就拉低;
  sdram_wr_ack是从写FIFO里面读出数据并传输至SDRAM的使能信号;
  sdram_rd_ack是从SDRAM里面读出数据并传输至读FIFO的使能信号;
  sdram_data_out是从SDRAM读出的数据;
  wr_ack_fall是单脉冲信号,指示将数据写入到SDRAM一次操作完成;
  rd_ack_fall也是单脉冲信号,指示将数据从SDRAM读出的一次操作完成;
  wr_fiffo_num是写入到写FIFO里面的数据个数,用来判断有没有达到突发长度,如果达到就持续拉高SDRAM写请求信号,传递到仲裁模块;
  rd_fifo_rd_data是从读FIFO里面读出的数据;
  rd_fifo_num是读FIFO里面的数据个数,初始有突发长度个数据,到最后全部读出;
  sdram_wr_req是写数据请求信号,当发送端发送了突发长度个数据,该信号就会拉高,拉高后传递到仲裁模块仲裁;
  sdram_wr_addr是SDRAM写入数据的地址,如果检测到写FIFO内写入完成突发长度个数据,写入地址就是sdram写初地址;
  sdram_data_in是要向SDRAM写入的数据;
  sdram_rd_req是读数据请求信号,当发送端发送了突发长度个数据,等待一定时间直到SDRAM将数据接收完成,拉高此请求信号并将它传递给仲裁模块;
  sdram_rd_addr是读数据地址,如果检测到SDRAM内存入突发长度个数据,读出地主之就是SDRAM读数据初地址。

3.5 FIFO数据读

  引入FIFO数据读模块的作用是,从SDRAM内读出的突发长度个数据,是要回传到串口的。回传到串口的数据读出速率,是受到波特率限制的,因此读使能信号产生也是受一定限制的。将读使能信号拉高一个脉冲后,需要等待串口将数据处理完,才能再次将读使能信号拉高一个脉冲。综上绘制的信号波形图如下:

在这里插入图片描述
  波形图说明:首先判断读FIFO内数据,如果数据达到突发长度个,则拉高读FIFO读使能信号。因为设置的FIFO是使读出的数据滞后读使能信号一个时钟周期,所以pi_data之后read_en一个时钟周期,同时pi_data数据的读出,也会使得读FIFO里面的数据个数减少,相反,FIFO数据读模块里面存储的数据就会增多。当FIFO数据读模块内数据增加到突发长度个数据时,此时就设定一个有效的工作使能信号,用来对波特率和发送的比特数进行计数,同时在最后一个时钟周期拉高FIFO数据读使能信号,依次读出FIFO里面的串口回环的数据。

四、结果验证

  设置突发长度为10,波特率为9600,通过串口调试助手发送十个8bit数据,接收到的也是这十个数据,基于SDRAM的串口回环测试验证通过。

在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值