求教!应用vhdl有关模拟标准ps/2键盘写入数据的时序问题!!!

2019-07-15 21:49发布

写了一个非标准键盘的程序,用ps/2连接FPGA开发板和电脑,实现在开发板上的矩阵键盘上按个键,然后能在电脑上显示。
下面是我的ps/2模块,请各位大神帮忙看下写出来的时序是对的吗?
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.std_logic_arith.all;
  4. use ieee.std_logic_unsigned.all;
  5. entity ps2 is
  6. port(en_in:in std_logic; --按键使能标志
  7.         ym_tong:in std_logic_vector(7 downto 0); --按键对应的通码
  8.         clk:in std_logic;
  9.         clk1:in std_logic;
  10.         ps2data:out std_logic;--输出ps2数据
  11.         ps2ccclock:out std_logic; --输出ps2时钟
  12.         xiaoyan:in std_logic; --校验位
  13.         en:buffer std_logic; --按下按键标志
  14.         shifangen:buffer std_logic --释放按键标志
  15.         );
  16. end ps2;
  17. architecture one of ps2 is
  18. signal cnt:std_logic_vector(3 downto 0);
  19. signal cnt0:std_logic_vector(3 downto 0);
  20. signal cnt1:std_logic_vector(4 downto 0);
  21. signal cnt2:std_logic_vector(4 downto 0);
  22. signal en0,en00,en000:std_logic;
  23. signal shifang0,shifangen00:std_logic;
  24. signal ym_tong1,ym_tong2:std_logic_vector(7 downto 0);
  25. begin
  26.        
  27. process(en_in)---
  28. begin
  29. if(clk'event and clk='1')then
  30. en0<=en_in;
  31. end if;
  32. end process;


  33. process(clk)---有按键产生时,生成一个按键产生标志en
  34. begin
  35. if(clk'event and clk='1')then
  36. if(en0='0' and en_in='1')then
  37. en<='1';
  38. ym_tong1<=ym_tong;
  39. elsif(cnt="1011")then
  40. en<='0';
  41. else en<=en;
  42. end if;
  43. end if;
  44. end process;

  45. process(clk)---
  46. begin
  47. if(clk'event and clk='1')then
  48. if( en0='0' and en_in='1')then
  49. cnt<="0000";
  50. elsif(cnt="1011")then
  51. cnt<="0000";
  52. else
  53. cnt<=cnt+1;
  54. end if;
  55. end if;
  56. end process;

  57. process(en)
  58. begin
  59. if(clk'event and clk='1')then
  60. en00<=en;
  61. end if;
  62. end process;

  63. process(en)---
  64. begin
  65. if(clk'event and clk='1')then
  66. if(en00='0' and en='1')then
  67. cnt0<="0001";
  68. elsif(en='1')then
  69. if(cnt0<"1100")then
  70. cnt0<=cnt0+1;
  71. else cnt0<="0000";
  72. end if;
  73. end if;
  74. end if;
  75. end process;

  76. process(en_in)
  77. begin
  78. if(clk'event and clk='1')then
  79. shifang0<=en_in;
  80. end if;
  81. end process;

  82. process(clk)--有按键释放时,产生一个释放标志shifangen
  83. begin
  84. if(clk'event and clk='1')then
  85. if(shifang0='1' and en_in='0')then
  86. shifangen<='1';
  87. ym_tong2<=ym_tong;
  88. elsif(cnt1="10110")then
  89. shifangen<='0';
  90. else shifangen<=shifangen;
  91. end if;
  92. end if;
  93. end process;

  94. process(clk)
  95. begin
  96. if(clk'event and clk='1')then
  97. if(shifang0='1' and en_in='0')then
  98. cnt1<="00000";
  99. elsif(cnt1="10110")then
  100. cnt1<="00000";
  101. else
  102. cnt1<=cnt1+1;
  103. end if;
  104. end if;
  105. end process;


  106. process(en)
  107. begin
  108. if(clk'event and clk='1')then
  109. shifangen00<=shifangen;
  110. end if;
  111. end process;

  112. process(shifangen)
  113. begin
  114. if(clk'event and clk='1')then
  115. if(shifangen00='0' and shifangen='1')then
  116. cnt2<="00001";
  117. elsif(shifangen='1')then
  118. if(cnt2<"10111")then cnt2<=cnt2+1;
  119. else cnt2<="00000";
  120. end if;
  121. end if;
  122. end if;
  123. end process;

  124. process(clk1)---产生ps2时钟
  125. begin
  126. if(clk1'event and clk1='1')then
  127. if((en00='0'and en='1') or (shifangen00='0' and shifangen='1'))then
  128. ps2ccclock<='1';
  129. elsif(en='1'or shifangen='1')then
  130. ps2ccclock<=clk;
  131. else ps2ccclock<='1';
  132. end if;
  133. end if;
  134. end process;

  135. process(cnt0,cnt2)--写入数据
  136. begin
  137. if(clk'event and clk='0')then

  138. case cnt2 is
  139. when "00000"=>ps2data<='1';
  140. when "00001" =>ps2data<='0';
  141. when"00010" =>ps2data<='1';
  142. when "00011" =>ps2data<='1';
  143. when "00100"=>ps2data<='1';
  144. when "00101"=>ps2data<='1';
  145. when "00110"=>ps2data<='0';
  146. when "00111"=>ps2data<='0';
  147. when "01000"=>ps2data<='0';
  148. when "01001"=>ps2data<='0';
  149. when "01010"=>ps2data<='1';
  150. when "01011"=>ps2data<='1';
  151. when"01100" =>ps2data<='0';
  152. when"01101" =>ps2data<=ym_tong2(0);
  153. when "01110" => ps2data<=ym_tong2(1);
  154. when "01111"=>ps2data<=ym_tong2(2);
  155. when "10000"=>ps2data<=ym_tong2(3);
  156. when "10001"=>ps2data<=ym_tong2(4);
  157. when "10010"=>ps2data<=ym_tong2(5);
  158. when "10011"=>ps2data<=ym_tong2(6);
  159. when "10100"=>ps2data<=ym_tong2(7);
  160. when "10101"=>ps2data<=xiaoyan;
  161. when "10110"=>ps2data<='1';
  162. when others => NULL;
  163. end case;
  164. case cnt0 is
  165. when "0000" => ps2data<='1';
  166. when "0001" => ps2data<='0';
  167. when "0010" =>ps2data<=ym_tong1(0);
  168. when "0011" => ps2data<=ym_tong1(1);
  169. when "0100"=>ps2data<=ym_tong1(2);
  170. when "0101"=>ps2data<=ym_tong1(3);
  171. when "0110"=>ps2data<=ym_tong1(4);
  172. when "0111"=>ps2data<=ym_tong1(5);
  173. when "1000"=>ps2data<=ym_tong1(6);
  174. when "1001"=>ps2data<=ym_tong1(7);
  175. when "1010"=>ps2data<=xiaoyan;
  176. when "1011"=>ps2data<='1';
  177. when others => NULL;
  178. end case;
  179. end if;
  180. end process;
  181. end architecture one;
复制代码

这是仿真出来的ps/2时序图 这是仿真出来的ps/2时序图
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。