概述

PS/2驱动框架分为四个部分:

1.预处理部分,用来同步ps/2_clk和ps/2_sda,从而进行边沿检测。

2.接收部分,当flag来了,接收sda的数据。

3.译码部分,根据ps/2数据手册对接收的数据进行转译。

4.显示部分,将转译过来的内容显示在数码管上。(因为我只做了数字0-9的显示,所以4位的data就足够了)

框架如下图所示:

预处理部分

首先对ps/2_clk进行上升沿寄存,因为时钟都是上升沿采样。通过寄存两拍(check_reg_clk)和寄存一拍的取反(~syn_reg_clk[1])相与得到flag_neg。正常采样的点为A点,但因为A点采不到,所以C作为A的近似点采样,寄存一拍(sda : C)后要采样的数据正好和flag_neg对齐。

预处理代码

module pre_handle (input    wire         clk,input    wire         ps2_clk,input    wire         ps2_sda,output   wire         flag_neg,output   wire         sda);reg            [1:0]  syn_reg_clk; //同步寄存ps2_clkreg            [1:0]  syn_reg_sda;//同步寄存ps2_sdareg                   check_reg_clk;    always @ (posedge clk) syn_reg_clk <= {syn_reg_clk[0],ps2_clk};always @ (posedge clk) syn_reg_sda <= {syn_reg_sda[0],ps2_sda};assign sda = syn_reg_sda[1];always @ (posedge clk) check_reg_clk <= syn_reg_clk[1];assign flag_neg = check_reg_clk & (~syn_reg_clk[1]);  endmodule 

接收部分

在接收部分定义了一个11位的捕获寄存器cap_reg,把每一次新接收到的sda都放在cap_reg的第一位,以此类推,接收11位后就是一个完整的数据,【停止位,校验位,8位数据位,起始位】

10

9

8

87

6

5

4

3

2

1

0

start

10

9

8

87

6

5

4

3

2

1

0

A0

start

10

9

8

87

6

5

4

3

2

1

0

A1

A0

start

10

9

8

87

6

5

4

3

2

1

0

A2

A1

A0

start

10

9

8

87

6

5

4

3

2

1

0

A3

A2

A1

A0

start

10

9

8

87

6

5

4

3

2

1

0

A4

A3

A2

A1

A0

start

10

9

8

87

6

5

4

3

2

1

0

A5

A4

A3

A2

A1

A0

start

10

9

8

87

6

5

4

3

2

1

0

A6

A5

A4

A3

A2

A1

A0

start

10

9

8

87

6

5

4

3

2

1

0

A7

A6

A5

A4

A3

A2

A1

A0

start

10

9

8

87

6

5

4

3

2

1

0

校验

A7

A6

A5

A4

A3

A2

A1

A0

start

10

9

8

87

6

5

4

3

2

1

0

Stop

校验

A7

A6

A5

A4

A3

A2

A1

A0

start

最开始接收起始位 start 放在第10,然后接收A0放在第10位,start位向右平移,处于第9位。此类推 当全部接收完,start位在第0位。

最后 第9位为检验位

[8:1]为数据位

把9-1为进行异或(^[9:1]),若异或结果为1,说明数据正确 把[8:1]输出给数码管。若不正确则不输出。

接收部分代码

module ps2_rec ( input    wire         clk,input    wire         rst_n,input    wire         flag,input    wire         sda,output   reg   [7:0]  rec_code,output   reg          valid_flag,output   reg          error_flag
);reg            [3:0]  cnt;reg            [10:0] cap_reg;//捕获寄存器wire                  flag_recdone; //完成标志 always @ (posedge clk) beginif (rst_n == 0)cap_reg <= 0;elseif(flag)cap_reg <= {sda,cap_reg[10:1]};//脉冲来了 把每次新来的sda放在cap_reg的高位elsecap_reg <= cap_reg;endalways @ (posedge clk) beginif (rst_n == 0)cnt <= 0;elseif(cnt < 11)if (flag)cnt <= cnt + 1'b1;elsecnt <= cnt;elsecnt <= 0; //cnt == 11时直接清零 保持一个周期endassign flag_recdone = (cnt == 11); //cnt == 11这一个周期正好是脉冲完成的标志always @ (posedge clk) beginif (rst_n == 0)rec_code <= 0;elseif (flag_recdone && ^cap_reg[9:1] == 1)//接收完成且为奇校验rec_code <= cap_reg[8:1]; //认为cap_reg[8:1]是接收的信息elserec_code <= rec_code;endalways @ (posedge clk) beginif (rst_n == 0)valid_flag <= 0;elseif (flag_recdone && ^cap_reg[9:1] == 1) //接收完成且为奇校验valid_flag <= 1; //正确接收elsevalid_flag <= 0;endalways @ (posedge clk) beginif (rst_n == 0)error_flag <= 0;elseif (flag_recdone && ^cap_reg[9:1] == 0) //接收完成但不是奇校验error_flag <= 1; //有错误elseerror_flag <= 0;end
endmodule 

译码部分

定义一个16位的缓存数据,把新来的8位数据放在后8位。

0000

0000

0000

0000

显示为

0

0

1

C

A

1

C

1

C

A

1

C

1

C

A

.

A

.

A

.

A

1

C

1

C

A

1

C

F

0

0

F

0

1

C

0

1

C

3

2

B

3

2

3

2

B

.

B

.

B

.

B

3

2

3

2

B

3

2

F

0

0

F

0

3

2

0

开始16bit数都为0 当A按下时 显示001C 持续按住A 显示1C1C,1CF0为瞬态(处于按下与松开之间的状态)  按键结束为F01C 这时再按下按键B 显示为1C32  持续按住B 显示3232,32F0为瞬态(处于按下与松开之间的状态)。按键结束为F032 。

总结:高8位为F0时,显示为零。高8为不为F0时,显示低8位对应的码值。

译码代码

module ps2_decoder (input    wire         clk,input    wire         rst_n,input    wire         flag,input    wire  [7:0]  code,output   reg   [3:0]  data   );reg            [15:0] buf_code;always @ (posedge clk) beginif (rst_n == 0)buf_code <= 0;elseif (flag)buf_code <= {buf_code[7:0],code};//新来的8位放后面elsebuf_code <= buf_code;endalways @ (posedge clk) beginif (rst_n == 0)data <= 0;elseif (buf_code[15:8] == 8'hf0)data <= 0;elsecase (buf_code[7:0])8'h45    :    data<=0;8'h16    :    data<=1;8'h1e    :    data<=2;8'h26    :    data<=3;8'h25    :    data<=4;8'h2e    :    data<=5;8'h36    :    data<=6;8'h3d    :    data<=7;8'h3e    :    data<=8;8'h46    :    data<=9;8'h1c    :    data<=10;8'h32    :    data<=11;8'h21    :    data<=12;8'h23    :    data<=13;8'h24    :    data<=14;8'h2b    :    data<=15;default  :    data<=0;endcaseend
endmodule 

显示部分

显示部分就是把译码中的4位data显示在数码管上,这个根据数码管驱动不同略有区别。

总结

最后就是把4个模块实例化到一个总代码中,编译成功后如下图所示:

最后的RTL级视图也和我们的框架图一致,ps/2驱动就完成了。

FPGA——PS/2驱动相关推荐

  1. (38)FPGA数码管驱动设计(第8天)

    (38)FPGA数码管驱动设计(第8天) 1 文章目录 1)文章目录 2)FPGA初级课程介绍 3)FPGA初级课程架构 4)FPGA数码管驱动设计(第8天) 5)技术交流 6)参考资料 2 FPGA ...

  2. (49)FPGA线性单驱动(wire型)

    (49)FPGA线性单驱动(wire型) 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)FPGA线性单驱动(wire型) 5)结语 1.2 FPGA简介 FPGA(Fi ...

  3. (48)FPGA三态多驱动(tri型)

    (48)FPGA三态多驱动(tri型) 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)FPGA三态多驱动(tri型) 5)结语 1.2 FPGA简介 FPGA(Fiel ...

  4. 读书笔记:详解FPGA人工智能的驱动引擎(石侃)

    最近读了一本关于我偶像的一本书,知名up主老石的一本书<详解FPGA人工智能的驱动引擎>,这本书写了老石对FPGA的一些心得和行业总结,个人觉得写的非常不错,第一次看还是有点难以深刻理解, ...

  5. FPGA Verilog AD7606驱动代码,包含SPI模式读取和并行模式读取两种

    FPGA Verilog AD7606驱动代码,包含SPI模式读取和并行模式读取两种,代码注释详细 编号:7428665912784264白衫如初oh

  6. FPGA—HDMI 显示器驱动设计与验证(附代码)

    目录 1.理论 2.实操 2.1 顶层模块 2.2 时钟生成模块 2.3 HDMI 驱动控制模块 2.3.1 编码模块 2.3.2 并行转串行模块 2.4 顶层仿真验证 3.总结 1.理论 HDMI简 ...

  7. FPGA下载器驱动的安装

    FPGA下载器驱动的安装 安装驱动 点击完成   如果驱动已经更新,安装就到此结束,如果驱动没有更新,继续往下做. 二.更新USB blaster 1.右键此电脑(我的电脑)选择管理 双击设备管理 查 ...

  8. 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验十二:串口模块① — 发送

    实验十二:串口模块① - 发送 串口固然是典型的实验,想必许多同学已经作烂,不过笔者还要循例介绍一下.我们知道串口有发送与接收之分,实验十二的实验目的就是实现串口发送,然而不同的是 ... 笔者会用另 ...

  9. 【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验二十七:TFT模块 - 显示

    实验二十七:TFT模块 - 显示 所谓TFT(Thin Film Transistor)就是众多LCD当中,其中一种支持颜色的LCD,相较古老的点阵LCD(12864笑),它可谓高级了.黑金的TFT ...

最新文章

  1. python 倒计时_用Python帮你远离猝死悲剧
  2. c++ 外部组件发生异常_谁再悄咪咪的吃掉异常,我上去就是一 JIO
  3. Apache ZooKeeper - ZK的数据和文件
  4. Linux下 WRF Domain Wizard 使用教程(PART1:下载+安装)
  5. 2.1 网站防******与企业虚拟化需求分析
  6. oracle 三个口令管理,Oracle学习笔记(12)口令和资源管理
  7. C#使用了未赋值的局部变量
  8. Java开发必须掌握的日志分析命令
  9. java 画笔跟swing组件_Java学习教程(基础)--Java版本历史(二)
  10. x射线直接投影成像的条件_告诉你如何区分X射线DR、CR和胶片成像?
  11. 1006 换个格式输出整数 (15 分)—PAT (Basic Level) Practice (中文)
  12. MyBatis的9种设计模式,我猜你不知道
  13. Qt登录界面实现以及跳转不同界面
  14. Pygame实战之外星人入侵NO.12——点击按钮开始游戏
  15. 元·认知·人机环·渔樵耕读
  16. 计算机辅助设计技术领域的应用,关于计算机辅助设计技术在规划设计中的应用...
  17. 安卓开发个人小作品(1) - 有声计算器
  18. 9 款炫酷的 MySQL 可视化管理工具!好用到爆!!
  19. 计算机网络管理员设备清单,网络管理员资料:计算机网络互联设备路由器
  20. android 防止屏幕误碰,小米11带来硬件防误触解决方案,彻底解决曲面屏误触问题...

热门文章

  1. Canvas学习参考文档
  2. 文本编辑器,选什么好
  3. 《修炼之道:互联网产品从设计到运营》荣获“2012最受读者喜爱的IT人文类图书奖”!
  4. xiuno 邮箱设置
  5. 618买什么蓝牙耳机最划算?四款高品质蓝牙耳机测评
  6. 面部表情识别---学习笔记
  7. 达到英语欧洲语言C2级的书有,剑桥少儿英语二级书
  8. 全球与中国汽车内饰牛皮革市场发展调研及未来前景预测报告2022-2028年
  9. 武汉疫情之后,中国即将发生的10大变化!!
  10. 企业如何利用小程序引流?小程序常见的4个引流方法