看到标题中的“打字机”三个字,你是不是脑补了下面这幅图像。这是二战电影中常出现的道具,现在恐怕都见不到了。


●电影道具“打字机”

  我要实现的当然不是这个样子,只是功能上与之相似。先让你们看看实现的效果,直接上图。

●这是串口发的字符串

●显示屏显示的字符

  之所以要写这个“打字机”工程,那是因为我在学习FPGA的道路上,它是我重要的一关。我一开始学FPGA,是从数字电路开始入门的,然后就是学习使用QuartusII,编写Verilog代码。我写的第一个工程是数字时钟(6个数码管两个一组实现时钟、分钟、秒钟的计时),通过它我学会了基本的逻辑(时序逻辑、组合逻辑,以及我们用的最频繁的译码器和选择器)。接下来就是这个“打字机”了,其实一开始这是学长给我布置的一个任务(现在想想学长也是用心良苦),通过它我基本上领会了如何驱动外设以及用各个外设组合成我们需要的工程(也就是模块化设计)。我相信,对于很多还在朝FPGA入门的同学来说,通过这个工程,你们的能力能获得显著提升。


  好了,话就不多说了,接下来就来看看这个工程是怎么实现的。我们先来看看RTL视图:

●RTL视图

  从该图中可以看到,这里一共有5个模块:PLL模块、UARTRX接收模块、DISMEM显存模块、GETZIMO字模译码模块、VGA显示模块。PLL模块产生VGA(800*600@60Hz)所需的40M时钟,UARTRX模块接收上位机发来的数据,显存模块保存需要显示的字符,字模模块将显存的字符译码成VGA模块需要的数据。PLL、UARTRX、VGA这三个模块就不讲了,这是学习FPGA必然要遇到的模块(网上有很多代码),接下来就给大家重点分析一下显存模块和字模译码模块。

  显存模块,顾名思义就是仿造显卡的显存,将显示的内容保存起来,当显示模块需要的时候再取出来。当我们按顺序将UART接收到的字符放入RAM中时,有一个问题,如果写满了RAM怎么办?当然,可以这么做,从头开始写,一直循环。那么读操作也按顺序读就会有问题了,这时如果写满了,之前显示的内容就突然没了。可是我们希望当写满时所有行都能往上卷一行,这样就和我们平时打字的效果一样了。解决这个问题的办法是改变读地址和写地址的映射关系。通常,读写地址是这么映射的:

  为了解决该问题,映射关系改成这样:

每当写满一页,读地址就往上卷动一行(也就是减去一行)。具体的代码就是:

 1 //从串口来一个数据就加1,直到计满清零
 2 always @ (posedge CLK_50M or negedge RST_N)
 3 begin
 4    if(!RST_N)
 5       RAM_WP <= 12'h0;
 6    else
 7       RAM_WP <= RAM_WP_N;
 8 end
 9
10 always @ (*)
11 begin
12    if(RAM_WP == 12'd3699 && DATAFLAG)
13       RAM_WP_N = 12'h0;
14    else if(DATAFLAG)
15       RAM_WP_N = RAM_WP + 12'h1;
16    else
17       RAM_WP_N = RAM_WP;
18 end
19
20 //RAM_WP对100取模得RAM_WP100,可以作为写指针的列
21 always @ (posedge CLK_50M or negedge RST_N)
22 begin
23    if(!RST_N)
24       RAM_WP100 <= 12'h0;
25    else
26       RAM_WP100 <= RAM_WP100_N;
27 end
28 always @ (*)
29 begin
30    if(RAM_WP100 == 12'd99 && DATAFLAG)
31       RAM_WP100_N = 12'h0;
32    else if(DATAFLAG)
33       RAM_WP100_N = RAM_WP100 + 12'h1;
34    else
35       RAM_WP100_N = RAM_WP100;
36 end
37
38 //以下实现卷行
39
40 //判断页尾,判断成功则一直保持
41 always @ (posedge CLK_50M or negedge RST_N)
42 begin
43    if(!RST_N)
44       sroll_flag <= 1'b0;
45    else
46       sroll_flag <= sroll_flag_n;
47 end
48 always @ (*)
49 begin
50    if(RAM_WP == 12'd3699 && DATAFLAG)
51       sroll_flag_n = 1'b1;
52    else
53       sroll_flag_n = sroll_flag;
54 end

  字模译码模块就是将从显存RAM中的字符译码得到VGA需要显示的数据,这是因为字符是不能直接给VGA显示的,所以有这个译码的过程。译码过程需要根据显示的位置得到VGA显示的像素,也就是根据字符从ROM中(里面存有字模信息)取得字符的字模,其过程见代码:

 1 //得到需要输出的字模数据的哪行,打一拍
 2 always @ (posedge CLK_50M or negedge RST_N)
 3 begin
 4    if(!RST_N)
 5       linechar <= 4'h0;
 6    else
 7       linechar <= position_VS[3:0];
 8 end
 9 //得到该行数据
10 GETLINE getlineA
11 (
12    .CLK_50M       (CLK_50M       ),
13    .CHAR          (CHAR          ),
14    .linechar      (linechar      ),
15    .dataline      (dataline      )
16 );
17
18 //得到需要输出字模数据的某列
19 always @ (posedge CLK_50M or negedge RST_N)
20 begin
21    if(!RST_N)
22       bitcnt <= 3'h0;
23    else
24       bitcnt <= bitcnt_n;
25 end
26
27 always @ (posedge CLK_50M or negedge RST_N)
28 begin
29    if(!RST_N)
30       bitcnt_n <= 3'h0;
31    else
32       bitcnt_n <= position_HS[2:0];
33 end
34
35 //得到字模数据某行某列上的值,并将这一位值译成8位数据(8'hff或8'h0)
36 DECODEPIXEL decodeA
37 (
38    .datain           (dataline      ),
39    .bitcnt           (bitcnt        ),
40    .dataout          (databit       )
41 );
42
43 assign DATAOUT = databit;

  这个“打字机”的工作流程可以通过下图来理解,数据由上位机发过来,UART模块接收,当接收到一个完整字符时,将这个字符写入到RAM。RAM中的数据读出后经过ROM译码,最后通过VGA送给显示器显示。


●字符信息流

   “打字机”的具体实现就是上面将的这些,有兴趣的朋友可以在此基础上改进,改进的内容可以是增加控制字符的操作,也可以是将显示的字符保存到SDRAM中这样就可以容纳更多的字符了。另外,需要源码的朋友可以在这个地址下载: https://pan.baidu.com/s/1jIqnI1C。

  让大家看一下我的实物,最近入手了一块锆石科技出品的A4开发板。在这块开发板上搭载了一颗Altera公司的EP4CE10F17C8,功能强大并且外设齐全,非常适合初学者。


  需要说明一下,这篇文章是仅仅我发的第一篇博文,而且只是一个小工程,也是让大家在学习FPGA的过程中有一个很好的练手的机会。在后面,我还会定期推出更多的自己在FPGA学习道路上的经验心得,而且绝对是干货(比如USB2.0、USB3.0、DDR2、SDcard、摄像头等等)哦!小伙伴们可以持续关注我,更多惊喜等着你。

转载于:https://www.cnblogs.com/bigbearfpga/p/7053870.html

FPGA实现“打字机”(VGA UART)相关推荐

  1. 【FPGA实验】VGA显示

    [FPGA实验]VGA显示 一. VGA介绍 ​ VGA的全称是Video Graphics Array,即视频图形阵列,是一个使用模拟信号进行视频传 输的标准.早期的CRT显示器由于设计制造上的原因 ...

  2. FPGA实现VGA显示(六)——————多字符显示及基于fpga的“打字机”实现

    前面笔者总结了如何显示单字符,设立通过一个简单的任务来总结如何实现vga多字符显示. 实验要求 基础: 由PC通过UART发送数据在VGA显示.数据可以为字母,数字,汉字(任选10个字),VGA分为左 ...

  3. 【FPGA】八、UART串口通信

    文章目录 前言 一.UART简介 1.基本概念 2.UART协议 3.波特率简介 二.UART串口回环实验 1.设计思路 2.程序代码 ① 串口接收模块 ② 串口发送模块 ③ 串口顶层模块 ④ 串口仿 ...

  4. 基于FPGA通用异步收发器UART设计

    摘要 通用异步收发器(UART)是一种能同时支持近距离和远距离传输的异步串行接口,具有传输速率较高.传输距离长.抗干扰性能好.电路结构简单以及节省布线资源等优点.然而,随着社会的发展,信息传输容量越来 ...

  5. 【FPGA练习】(一): UART串口通信实验

    由于之前学习FPGA的过程中,没有做一个良好的记录,以及已学知识的扩展,所以从今天开始每一个实验例程和扩展应用,都要做文档记录.本实验,是基于正点原子达芬奇xc7a35tfgg484-2开发板.开发板 ...

  6. FPGA学习记录——VGA的一些使用(一)

    参考书目:<FPGA Verilog开发实战指南--基于Xilinx Artix7>.<FPGA Verilog开发实战指南--基于Altera EP4CE10>. 参考视频: ...

  7. FPGA学习.4——VGA显示驱动设计

    前言 图像显示设备在日常生活中随处可见,例如家庭电视机.计算机显示屏幕等,这些设备之所以能够显示我们需要的数据图像信息,归功于视频传输接口.常见的视频传输接口有三种:VGA接口.DVI接口和HDMI接 ...

  8. FPGA基础之VGA(一)满屏红色

    一. 项目分析 用VGA显示全屏的红色,VGA(Video Graphics Array,视频图形阵列)是一种电脑显示标准.开发板采用至芯科技zx-1学习板,VGA视频显示接口是256色,颜色位深为8 ...

  9. ZYNQ——FPGA工程之VGA彩条显示

    参考: https://blog.csdn.net/Taneeyo/article/details/115180568?spm=1001.2014.3001.5501 https://www.bili ...

  10. 基于FPGA的UART接口协议设计

    一.PC终端概述 PC终端,Personal Computer 智能终端,通俗的讲,就是利用电脑GUI界面控制我们的外部硬件电路. 因此设计到了PC与外部硬件电路的通信接口.对于台式电脑.个人笔记本, ...

最新文章

  1. 基于ThinkPHP的在线编辑器调用
  2. TensorFlow预训练模型在新图中权重部分加载
  3. Python那些优雅的写法:switch-case
  4. rabbitmq 同步策略_RabbitMQ高可用方案总结
  5. 设计一个简单分页存储管理系统_【系统架构】如何设计一个简单灵活的收银系统?看这里!(1)...
  6. Java 控制台程序的基本结构测试分析草稿
  7. 内存分配(malloc()和free())
  8. 郭明錤爆料:苹果造车团队已解散
  9. 更新wordpress遇到prepare警告问题的解决
  10. Python命令行参数
  11. zencart 商城 Twitter推广技巧
  12. 安装破解版的edraw max
  13. 文件传输-FTP使用简介
  14. 【Algorithm】算法设计与分析(第二版)- 王红梅 - JAVA实现:1.3 设计算法求数组中相差最小的两个元素(称为最接近数)的差
  15. anki 神级插件 fastWQ 提取本地朗文音频
  16. 冰冻三尺非一日之寒-自学篇 浅谈个人学习方法
  17. win10桌面图标全部变成白色的怎么办
  18. SPSS处理单元素,多元素logistic,详细流程和操作截图
  19. 高并发系统设计 --基于MySQL构建评论系统
  20. Python查询手机号码所在地区的几种方式

热门文章

  1. R文本分类之RTextTools
  2. 广告投入是怎样提高新用户数的(岭回归及主成分回归) | R语言商业分析实践3
  3. thrift java first demo
  4. Linux常用命令的缩写含义
  5. 常见的防火墙技术介绍
  6. 更靠谱的横竖屏检测方法
  7. hdu-5673 Robot(默次金数)
  8. Java:Spi 小实战
  9. B和strong以及i和em的区别
  10. 明天发布一个基于Silverlight的类Visio小型绘图工具项目。