【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八)

声明:本文为原创作品,版权归akuei2及黑金动力社区(http://www.heijin.org)共同所有,如需转载,请注明出处http://www.cnblogs.com/kingst/

【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八)_第1张图片

5.4 实验十七:PS2封装

有关PS2驱动什么,我们已经在实验八完成了,这一章我们要将PS2封装。在这里笔者稍微重复一下“封装(接口)的定义”:

(一)最后的工程。

(二)使模块独立。

5.3章中,我们对蜂鸣器的封装中调用了FIFO作为信息输入的缓冲,而使得蜂鸣器接口独立于上一层模块。相反的这一章,我们要在PS2封装中,引入FIFO作为信息输出的缓冲。

【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八)_第2张图片

上图是 ps2_interface.v - PS2接口,PS2控制模块的左方是实验八“PS2解码”中,出现的电平检测模块和PS2解码模块。反之,PS2控制模块的右方是FIFO模块。左方是对“PS2的一帧数据”解码,右方是对“解码过后的数据”进行缓冲。然而,PS2控制模块在中间协调。(FIFO的深度是16)

detect_module.v

【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八)_第3张图片

【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八)_第4张图片

ps2_decode_module.v

 

【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八)_第5张图片

ps2_control_module.v

【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八)_第6张图片

【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八)_第7张图片

ps2_control_module.v 这个控制模块比较简单,核心部分在26~37行。在29行,如果PS2_Done_Sig 信号产生高脉冲而且 Full_Sig 拉低(FIFO存在空闲空间),i递增以示下一个步骤。

在这里提醒一下,PS2_Data 输入是直接驱动 FIFO_Write_Data 输出。

32isReq标志寄存器拉高(isReq该寄存器是用于驱动 Write_Req_Sig ,亦即FIFO写请求信号-42行),i递增以示下一个步骤。

 

35isReq 拉低,以示一次性的FIFO的写操作已经结束。i赋值为0 以示重新等待下一次的写操作。

ps2_interface.v

【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八)_第8张图片

【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八)_第9张图片

ps2_interface.v 这个组合模块,基本上和“图形”一样。

实验十七说明:

这个实验比较简单,主要是基于实验八再加入ps控制模块和FIFO模块,然后封装而成。

封装过后的 PS2接口,我们只要考虑如何将“PS2解码过后的数据”写入FIFO而已。

在这里读者可能有这样一个问题:

经实验十六,我们知道由Quartus II 建立的 FIFO, 最后一个信息会发生“被卡住”的现象。那么问题来了,在 ps2_interface.v 中的 ps2_control_module.v 每当向 ps2_fifo_module.v 写入一个信息之后,是否需要写入“8'h00”来达到“强制挤出”的效果?

答案是不需要。但是为什么呢 ......

笔者来详解一下在 ps2_interface.v ps2_decode_module.v ps2_control_module.v 的关系。

【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八)_第10张图片

上图是 ps2_decode_module.v 的核心功能,笔者设计的 ps2_decode_module.v 是“断码 8'hF0 和“通码”都吃(但是不吃断码之后的通码)。当笔者按下某个按键的时候,rData 会保留某按键的通码,作为 PS2_Data 信号的驱动,然后PS2_Done_Sig 产生一个高脉冲。反之当某个按键释放的时候,rData会保留按键的断码,亦即8'hF0 作为 PS2_Data 信号的驱动,忽略某按键释放后的通码,然后 PS2_Done_Sig 产生一个高脉冲。

【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八)_第11张图片

上图是 ps2_control_module.v 的核心部分。从上面的代码,我们可以看到该控制模块,无论是“某按键的通码”还是“断码”,它都采取一视同仁的态度(断码之后的通码无视),该控制模块都会将“通码”或者“断码”通通写入 ps2_fifo_module.v 里面。

所以说呀:

假设我按下 "S" ,那么ps2_fifo_module.v 就会被写入 8'h1b。当我释放“Sps2_fifo_module.v 会被写入 8'hf0。换句话说每当我按下某个某个按键,然后释放某个按键,该写入在ps2_fifo_module.v的通码,都会被 断码 8'hf0 达到强制挤出的效果。

再假设我按下某按键不放,写入在 ps2_fifo_module.v 的通码,都会被下一次写入的通码挤出。当我释放某按键的时候,该按键在 ps2_fifo_module.v 的最后一个通码,会被断码 8'hf0 挤出。

完成后的扩展图:

【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八)_第12张图片

实验十七结论:

实验十七和实验十六比较,一个是将输出数据缓冲至FIFO,另外一个是将输入数据缓冲至FIFO


实验十七演示:

【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八)_第13张图片

在这个演示中,主要是演示如何调用 ps2_interface.v。在 ps2_interface_demo.v 中,除了实例化 ps2_interface.v 以外,还添写了对 ps2_interface.v 读取数据的 控制模块。最后该控制控制模块将读取到的数据的“第四位”输出至LED资源。

ps2_interface_demo.v

【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八)_第14张图片

 

clip_image024

27行中,先判断FIFO是否为空 , 如果FIFO不是为空的话就拉高 isRead。在同一个时间读取 FIFO_Read_Data 的数据至 rLED暂存寄存器,i递增以示下一步步骤。

30行,isRead被拉低,i赋值为0,以示一次性的读数据操作已经完成,然后重复执行下一次的读数据操作。

实验十七演示说明:

PS2接口的数据等价与读FIFO数据。

实验十七演示结论:

该演示比较简单,没有什么好补充的,但是从演示结果我们可以知道一个事实。每当我们按下A按键然后又释放A按键的时候,LED资源会显示A按键的通码,而不是断码 8'hf0(别忘了ps2_decode_module.v是断码和通码都吃, 断码之后的通码除外)。换句话说,在FIFO的环境里面,8'hf0 为了挤出A按键的通码,使得自己卡在FIFO里面(它真的很伟大)。

当再按下B按键然后又释放它的时候,原先卡在 FIFO环境里面的 8'hf0 会被读出,但是在它停留的时间很短(大约3个时钟周期而已),被人眼忽略了(人眼迟钝的关系)。然后随后B按键的通码会被读出,断码为了挤出 B按键的通码,使得自己卡在 FIFO里面。结果,LED资源会显示B按键的通码。

在这里我们可以做出这样的一个结论:

quartus II 建立的 FIFO ,当深度等于 1 的时候就会拉高 Empty_Sig 信号。为了是最后一个信息成功被读出。当为FIFO写入一连串的信息,在信息的后面必须写入一个“无关紧要”的信息来达到挤出的效果。


你可能感兴趣的:(【连载】【FPGA黑金开发板】Verilog HDL那些事儿--PS2封装(十八))