FPGA VGA缓冲器。如何读写?


8

我有一个Altera DE2开发板,正在尝试绘制精灵。我在实现屏幕缓冲区时遇到了一些麻烦。

我有一个显示实体,它以25 MHZ的速率输出用于VGA显示的像素。

我希望在SDRAM中实现一个缓冲区。最初的想法是从SDRAM以25 MHZ的速率将像素加载到下一个像素。这行得通,但我无法以这种速率将像素写入SDRAM,也无法为每个新帧足够快地清除屏幕。我需要2个时钟来写入数据,而且我的电路板工作在50 MHZ,所以我有足够的时间进行完整的读取。

我想我做的事情非常可怕,非常错误。在VHDL中通常如何实现这样的绘图画布?

我能找到的最接近的东西是使用2-3-3(RGB)配色方案来检索每个像素,并在“门廊”(空白)VGA时间期间将其写入画布ram。这意味着在每个25MHz时钟上,我只能更新15%的屏幕,而我不知何故需要我的电路知道它正在更新哪个15%的屏幕?

我不知道如何使用双缓冲,因为我不知道如何在读取时将数据写入内存。有没有一种方法可以避免协议发生混乱?这个家伙是怎么做到的?

在此处输入图片说明



@davidcary,有关如何进行双缓冲的一些详细信息,您已经回答了这个问题。我意识到这很费时间,而且我无法一掷千金,经常会给人以快速的讽刺,以帮助用户解决问题,直到有人可以写下高质量的答案。
Kortuk

3
当您说“是否有一种方法可以避免对协议进行比特冲击?”时,我认为这意味着您尚未自己编写SDRAM控制器。我建议您这样做,这是一个很好的练习,您将进一步了解SDRAM的工作方式以及如何利用其时序。
mng

Answers:


3

对于某些样式的显示可能有用的几种方法是将显示面板分成小块,然后

  1. 限制每个图块使用一小组颜色,从而允许每个像素使用少于8位,或者
  2. 在每个图块中使用一两个字节来选择从中读取位图数据的位置。
第一种方法可以降低必须从显示存储器读取数据的速率。例如,如果使用16x16的图块,并且每个图块可以从256种颜色中选择四种颜色,则无需在FPGA中使用任何额外的RAM,就可以将每16像素的内存读取次数减少到8(四种颜色值,加上位图的四个字节)。如果一个人在FPGA上增加了160个字节的缓冲/ RAM(*),则可以将每16个像素的存储器读取数量减少到四个,而每16条扫描线额外增加160个读取以读取下一组图块颜色。如果一个人希望每个图块有16种颜色,则第二种方法将需要额外的640字节RAM,除非一种方法限制了一行中可能存在的不同调色板的数量。

第二种方法可能会增加而不是减少产生显示器所需的总内存带宽,但是会减少为更新显示器而必须更新的内存量-一个可以更改一个或两个字节来更新8x8或屏幕的16x16区域。根据您要显示的内容,使用这种方式的方法来使用一个存储设备来保存图块形状,而另一个存储图块形状时可能会有所帮助。例如,可能使用一个快速的32Kx8 RAM来保存几个80x60的瓦片映射,每个瓦片两个字节。如果FPGA没有任何缓冲,则必须每四个像素读取一个字节。即使使用40ns的静态RAM,也将为CPU留下大量时间来更新显示(整个屏幕只有9600字节)。

顺便说一句,如果不想添加32Kx8 RAM但可以向FPGA添加320字节的缓冲/ RAM(**),则可以使用图块映射方法,但CPU或DMA可以将160字节提要给FPGA。每8条扫描线显示一次。即使显示器上的任何内容都没有变化,这也会给控制器带来一定的负担,但可以简化电路。

(*)缓冲区可以实现为RAM,也可以实现为32个40位长的移位寄存器和少许控制逻辑的序列。

(**)缓冲区可以实现为两个160字节RAM,或者实现为两个16个80位移位寄存器。


5

Sprite通常不使用帧缓冲区来完成(据我所知)。相反,您将x和y坐标与子画面的xmin,ymin和xmax,ymax进行比较。如果当前扫描位置位于子画面内,请从子画面存储器中输出相关颜色。

如果要显示帧缓冲区,请放心。这是我的第一个大型FPGA项目。SDRAM在100MHz时应该不是问题(我大约在十年前就开始这样做了,现在硅片的速度越来越快),所以要乘以50MHz的时钟。编写自己的控制器将很有教育意义:)

这样可以为您提供足够的带宽,然后可以加倍缓冲,这没问题。60Hz VGA平均需要18M像素/秒。如果具有16位宽的设备,则具有200 MB /秒的峰值带宽。即使您仅设法提高50%的效率(应该可行),也就是100Mpixels / sec @ 16位/像素或50Mpixels / sec @ 32位/像素。

例如,可能是您的RAM需要60ns来设置读取,但之后可能会在80 ns内突发8个字-在〜140ns内是8个字节。如果您可以让RAM进行更长的突发操作,那将有助于分摊设置读取的成本。

根据您的评论,它是一个字节侧RAM,有点超过50MBytes / sec,只有16Mpixels / sec @ 24 bit每像素:(即使在VGA上,您也没有足够的带宽来进行真彩色显示。可以很容易地每个像素8位,但是每种颜色只有2或3位-我不知道这可能适合您的应用程序,或者您可以像过去那样做256色查找表从帧缓冲区读取数据,然后使用该值在内部RAM时钟中查找,以获取24位(或18位,非常适合BRAM)的颜色输出到监视器。

双缓冲仍然有效:

显示从地址0开始的帧(只需依次读出所有像素,在消隐间隔期间暂停读取)。

下一帧写入另一个位置。对于这种双缓冲,您的DRAM控制器将必须在读写通道的竞争需求之间确定优先级。提示,因为它们是时间紧迫的,所以优先考虑读取:)


通常优先安排读取优先级,还是将数据读取到FIFO中更好,在FIFO中有一定数量的数据时赋予写入优先级,而在FIFO级别太低时赋予读取优先级呢?我发现,至少在驱动具有时钟信号的LCD时,如果所有数据都按时移出,允许读取时序相当“宽松”是很有用的。
超级猫

感谢您的发帖,我可能会看看缓冲。但是我认为读取数据需要2个时钟(1/50 MHZ),而且我还有一个8位宽的设备。
米哈伊尔(Mikhail)

@supercat:是的,这是一个更高级的解决方案,如果要增加带宽,则可能需要这样做。
马丁·汤普森

1
@Misha:需要一段时间才能设置数据读取,但是您可以一次突发读取大量数据。
Martin Thompson
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.