如何以如此高的像素时钟频率驱动VGA显示器?


12

我正在使用分立组件在数字电路上工作,以80x30文本模式驱动640x480 VGA显示器。

对于640x480的显示器,像素时钟为25.175MHz,周期约为40ns。我不明白我应该怎么能够经常向显示器提供新的像素。

我的电路的基本架构如下:

  1. 水平像素的二进制计数器以25.175MHz的频率计数到800(640个可见像素+ 160个前沿,同步,后沿)。在800处,增加垂直行计数器(并在525行处重置)

  2. 使用水平和垂直位置,导出当前字符的x,y坐标。

  3. 使用字符的x,y坐标,索引到视频内存中以检索ASCII字符。

  4. 使用ASCII字符在字符ROM中建立索引以获取字符的位模式

  5. 使用并行到串行移位寄存器,以像素时钟频率将8像素字符行转换为单个位

如果您遵循该链,则它会:计数器-> RAM-> ROM->并行于串行移位寄存器

使用我能找到的最快的组件,传播延迟和访问时间总计约为15ns + 20ns + 70ns + 15ns = 120ns,远大于25MHz的40ns周期。

在更高的分辨率和刷新率下,像素时钟可以远高于100MHz,这将是10ns的周期。

当RAM / ROM的访问时间已经远远超过它时,甚至不考虑系统中所有其他信号的情况下,如何能每10ns为显示器提供一个新的像素呢?


7
您使用专用的视频RAM,并将其直接输入到视频信号中。你搞清楚工作是什么,显示很久以前你真正显示出来。
炉边堡

2
阅读有关Maximite的文章。它仅使用MCU的外围硬件和一些电阻器来驱动VGA端口。首先检查他使用的PIC32外设。工作正常。(我在这里有一个Maximite。)
播出

“唐·兰开斯特(Don Lancaster)”制作的“便宜的视频食谱”
Jasen

Answers:


17

您发现这一挑战的主要原因有两个。

首先,您使用的部件比VGA时代的部件更旧,更分立(低比例集成)。

但是接下来,您将以非典型方式使用它们。具体来说,您的方法并非如此pipelined,这意味着您在确定间隔和费率时必须累加多个延迟。

相反,试图实现速度的同步数字设计尝试在寄存器之间进行尽可能少的操作。

尽管细节可能略有不同,但粗略地说,它的工作原理如下:

  • 您增加或重置地址,然后将其存入寄存器。
  • 您将地址锁存到同步存储器中
  • 您锁存同步存储器的输出
  • 您将其锁存到同步字符生成器的地址中
  • 您将字符发生器的输出锁存到输出寄存器中
  • 应用调色板查找...
  • 进入同步DAC ...

当您像这样分解一个任务时,您只会得到一个组合延迟,加上一些传播延迟,并需要设置时钟之间的寄存器建立和保持时间。

以这种方式构建的设计将花费许多时钟来产生输出- 延迟实际上比纯组合设计要高。但它会在每个时钟周期更快的时钟周期上产生新的正确输出。

嘿,这是视频,CRT是否在像素计数器后面绘制了十二个像素并不重要-您当然要在同步信号的时间中考虑到这一点,以便与实际数据相比它们是正确的从DAC出来。

实际上,几乎所有复杂的数字系统都以这种方式工作,因为这是一个好主意-直到流水线CPU遇到对较早的计算结果或条件分支的依赖...然后事情变得有趣了,因为他们谈论在下一堂数字系统课程的演讲中-幸运的是,您的VGA情况要简单得多,尤其是如果您还不担心在绘制屏幕时更改字符缓冲区时会产生撕裂效果。

实际上,如果要构建它,请在FPGA中进行。如果使用内部存储器,那么这将极大地迫使您使用同步存储器;如果使用外部存储器,则将在同步IO寄存器上施加压力。您会为适当的设计而烦恼,面料本身比分立的部件要快,当然,如果您犯了一个错误,则只需在重新编译时摇动手指,而不用花费大量的时间重新布线。


“尤其是如果您还不担心在绘制屏幕时更改字符缓冲区时会产生撕裂效果”,这就是为什么从视频协处理器诞生之初起,协处理器就可以通知主进程他们不是当前将其内存转储到屏幕上,如果他们想更改视频缓冲区,则应该立即进行。
John Dvorak

我认为您过于复杂了。他已经说过他正在使用一个8位移位寄存器,该寄存器每像素时钟输出一位。大概这是一个带锁存器的8位移位寄存器。这意味着他仅需要每8个像素时钟获取一次新字节,因此速率为3.125MHz。这样一来,您就可以将所有320ns的数据获取到移位寄存器锁存器,这比他说的120ns长得多。
克里斯_F,

是的,对于一个非常简单的低分辨率单色情况,字节的时序不会太有挑战性,但是问题的关键部分是询问者试图了解典型的“真实”非平凡分辨率系统的性能。是可能的。答案与所有​​其他有用的数字系统相同:更快的技术和流水线同步设计。
克里斯·斯特拉顿

2

使用我能找到的最快的组件,传播延迟和访问时间总计约为15ns + 20ns + 70ns + 15ns = 120ns,远大于25MHz的40ns周期。

您会忘记图形适配器永远不会只绘制单个像素,而不会绘制完整的扫描线。因此,这将是一个完全可流水线的问题。

另外,请不要忘记,到目前为止已经有五十年的视频制作硬件。通常,可以通过一种特殊类型的RAM解决您的问题,在该RAM中,您可以在一个端口上呈现字母,然后依次将其读出到视频信号DAC中。该硬件比您正在寻找的方式快得多。

我的电路的基本架构如下:

  1. 水平像素的二进制计数器以25.175MHz的频率计数到800(640个可见像素+ 160个前沿,同步,后沿)。在800处,增加垂直行计数器(并在525行处重置)

  2. 使用水平和垂直位置,导出当前字符的x,y坐标。

不,你为什么要这么做?您只需将行像素放入内存的连续区域中,然后线性地将其放入DAC中-如果这是关于CPU / MCU的实现,则您甚至不会让CPU这样做,而是要对DMA单元进行编程什么也没做,只取另一个值,然后将其输出到并行数据端口,而无需任何CPU内核交互。

  1. 使用字符的x,y坐标,索引到视频内存中以检索ASCII字符。

嗯,您想即时进行渲染–不错的选择,但要付出现代内存的代价,这是不寻常的。取而代之的是,您只需要事先将字符渲染到帧缓冲区中,或者如果您的设备非常薄,则直接将字符行输出到DAC(请参见上面的DMA说明)。


1
尽管现代的东西倾向于使用预渲染的帧缓冲区,但是如果您尝试在没有太多内存的情况下工作,它们显然是一个错误的选择。如果在FPGA中执行此操作,则只需使DMA状态机从字符单元映射中获取地址,然后从相应的字符字形中读取即可。
R .. GitHub停止帮助ICE,

在这里完全同意!因此,我的第三个问题的答案部分。
MarcusMüller19年

2

除了流水线(这是您应该做的大部分工作)之外,您还缺少一些主要的东西...。

的确,并行输入,串行输出移位寄存器的时钟点输出频率为25个奇数Mhz,但是,如果您的字符说是8像素宽,则其输入频率仅为〜3.2MHz,对于VGA时代LS系列来说,这很容易达到。当移位寄存器中的当前字节结束时,您需要准备好下一个字节(这是流水线进入的地方)。

产生一个〜25MHz的像素时钟,并以该像素时钟的1/8产生一个存储器时钟,以驱动文本缓冲区和CG ROM,然后对该存储器和CG ROM访问内容进行流水线处理。

另一个技巧是,将在任意给定文本行中的每一行重复文本缓冲区输出,因此也许您可以将80个字节的文本记录到环形缓冲区中,然后停止读取接下来的7行的ram(假设8行字符),这样就可以释放内存供CPU使用,但代价是需要将80字节的RAM挂在东西的侧面。


1

很显然,这是行不通的;您需要一条管道。

1)将字符连续存储在内存中。从左上方开始。

2)在消隐间隔期间获取一个字符。继续以内存顺序获取字符。

3)将每个解码的字符和行索引传送到ROM中。

4)将ROM输出流水线到缓冲区。

5)将缓冲区流水线到移位寄存器中。从此以40ns的间隔连续读取像素。

(这意味着您需要每320ns将一个新字符加载到移位寄存器中,这甚至可以在不对整个系统其余部分进行流水线处理的情况下实现。)

6)在水平消隐期间,返回到行的开头或前进到下一个字符(即,下一行的开头)。

附加功能:由于您仅需要每320ns一个字符,因此您还可以读取一个字符+颜色对,并执行MSDOS样式或Spectrum样式的颜色字符。

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.