有关PS2驱动什么,我们已经在实验八完成了,这一章我们要将PS2封装。在这里笔者稍微重复一下“封装(接口)的定义”:
(一)最后的工程。
(二)使模块独立。
在5.3章中,我们对蜂鸣器的封装中调用了FIFO作为信息输入的缓冲,而使得蜂鸣器接口独立于上一层模块。相反的这一章,我们要在PS2封装中,引入FIFO作为信息输出的缓冲。
上图是 ps2_interface.v - PS2接口,PS2控制模块的左方是实验八“PS2解码”中,出现的电平检测模块和PS2解码模块。反之,PS2控制模块的右方是FIFO模块。左方是对“PS2的一帧数据”解码,右方是对“解码过后的数据”进行缓冲。然而,PS2控制模块在中间协调。(FIFO的深度是16)
ps2_control_module.v 这个控制模块比较简单,核心部分在26~37行。在29行,如果PS2_Done_Sig 信号产生高脉冲而且 Full_Sig 拉低(FIFO存在空闲空间),i递增以示下一个步骤。
在这里提醒一下,PS2_Data 输入是直接驱动 FIFO_Write_Data 输出。
在32行isReq标志寄存器拉高(isReq该寄存器是用于驱动 Write_Req_Sig ,亦即FIFO写请求信号-42行),i递增以示下一个步骤。
在35行isReq 拉低,以示一次性的FIFO的写操作已经结束。i赋值为0 以示重新等待下一次的写操作。
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 的关系。
上图是 ps2_decode_module.v 的核心功能,笔者设计的 ps2_decode_module.v 是“断码” 8'hF0 和“通码”都吃(但是不吃断码之后的通码)。当笔者按下某个按键的时候,rData 会保留某按键的通码,作为 PS2_Data 信号的驱动,然后PS2_Done_Sig 产生一个高脉冲。反之当某个按键释放的时候,rData会保留按键的断码,亦即8'hF0 作为 PS2_Data 信号的驱动,忽略某按键释放后的通码,然后PS2_Done_Sig 产生一个高脉冲。
上图是 ps2_control_module.v 的核心部分。从上面的代码,我们可以看到该控制模块,无论是“某按键的通码”还是“断码”,它都采取一视同仁的态度(断码之后的通码无视),该控制模块都会将“通码”或者“断码”通通写入 ps2_fifo_module.v 里面。
所以说呀:
假设我按下 "S键" ,那么ps2_fifo_module.v 就会被写入 8'h1b。当我释放“S键”ps2_fifo_module.v 会被写入 8'hf0。换句话说每当我按下某个某个按键,然后释放某个按键,该写入在ps2_fifo_module.v的通码,都会被 断码 8'hf0 达到强制挤出的效果。
再假设我按下某按键不放,写入在 ps2_fifo_module.v 的通码,都会被下一次写入的通码挤出。当我释放某按键的时候,该按键在 ps2_fifo_module.v 的最后一个通码,会被断码 8'hf0 挤出。
完成后的扩展图:
实验十七和实验十六比较,一个是将输出数据缓冲至FIFO,另外一个是将输入数据缓冲至FIFO。
在这个演示中,主要是演示如何调用 ps2_interface.v。在 ps2_interface_demo.v 中,除了实例化 ps2_interface.v 以外,还添写了对 ps2_interface.v 读取数据的 控制模块。最后该控制控制模块将读取到的数据的“第四位”输出至LED资源。
在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写入一连串的信息,在信息的后面必须写入一个“无关紧要”的信息来达到挤出的效果。
文章评论(0条评论)
登录后参与讨论