基于FPGA的PS2键盘人机输入显示系统
本次半定制器件课程设计主要涉及FPGA逻辑设计和Verilog HDL等方面的知识应用,根据课程设计要求完成了基于FPGA的人机输入显示系统,本系统目前还可以继续完善,目前实现的内容也相对来说较为基础,主要针对FPGA等逻辑器件设计的入门级玩家,有兴趣的旁友可以继续添加。
对于想要获取此课程设计报告word/PDF版本的同学,欢迎光顾小生寒舍 GitHub:https://github.com/ChromeWei?tab=repositories
特此感谢, 课程设计过程中任课老师张老师给予的指导和帮助!
第一部分 课程设计概述
1 课程设计的目的与任务
(1)熟练掌握EDA工具软件QuartusII的使用;
(2)熟练用Verilog HDL硬件描述语言描述数字电路;
(3)学会使用Verilog HDL进行大规模集成电路设计;
(4)学会用CPLD\FPGA使用系统硬件验证电路设计的正确性;
(5)初步掌握EDA技术并具备一定的可编程逻辑芯片的开发能力;
2 课程设计题目
人机输入显示系统:PS/2键盘输入, LCD显示
3 设计功能要求
(1)实现PS/2键盘的输入
(2)将键盘输入的内容显示在液晶显示器上;
(3)键盘的功能实现自定,例如是否考虑功能键,是否使用连击等;
(4)显示格式自定,例如是否使用多行,是否使用大小写等。
4 设计实现提示
方法是将PS/2模块与LCD模块连接
(1)问题是数据如何传递?
(2)利用LCD数据存储器?
(3)使用RAM宏模块?
5 课程设计的内容与要求
5.1 设计内容
(1)系统功能的分析;
(2)实现系统功能的实际方案;
(3)编写各功能模块的VHDL语言程序;
(4)对各功能模块进行编译、综合、仿真、分析;
(5)顶层文件设计
(6)对整个系统进行编译、综合、仿真、分析;
(7)在CPLD\FPGA实验开发系统试验箱上进行硬件验证;
(8)写课程设计报告;
5.2 设计要求
(1)按所布置的题目要求,每一位学生独立完成全过程;
(2)分模块层次化设计;
(3)各功能模块的底层文件必须用VHDL语言设计,顶层文件可用VHDL语言设计,也可以用原理图设计。
第二部分 实验仪器及平台
(1)PC机;
(2)QuartusII软件;
(3)黑金FPGA实验开发系统,芯片为Cyclone II的EP2C5Q208C8;
第三部分 设计方案
1 PS2解码
图1为PS2的接口图。我使用的的右边的PS2接口,即1脚为数据脚,5脚为时钟脚,同时我编写的VHDL代码只对1脚和5脚操作。
第N位 | 属性 |
---|---|
0 | 开始位 |
1~8 | 数据位 |
9 | 校验位 |
10 | 结束位 |
键盘的编码有“通码(Make)”和“断码(Break)”之分。通码相当于某个按键按下了,断码相当于某个按键释放了。假设,我们按下了“Z”键不放,大约每秒有10个X“1A”的通码(10KHz),而当我们释放“Z”键,就会输出断码X“F0”和X“1A”。同时,键盘编码一次只能有一个输出,即多个按键同时按下时,只有一个有效。
下表为第二套PC键盘扫描码。
2 设计思路
(1)PS2时钟的检测;
(2)PS2数据的接受并提取需要的8位数据;
(3)对PS2提取的8位数据进行解码,确定按键;
(4)通过LED灯显示按键的解码的结果;
(5)设置多个按键,多种LED显示方式;
对于PS2键盘扫描程序,我的设计思路是一个模块一个功能,这样能清晰分辨模块,同时易于修改代码。代码条理清晰,便于解读。而对于多个模块则使用层次化的形式来编写,顶层文件并不包含功能的设定,只包含各个子功能模块。
3 模块设计
PS2键盘扫描分为:电平检测,PS2解码,PS2组合,LED控制和总PS组合六个模块。下面为各个模块的简易模块图。
3.1 PS2时钟检测模块:
3.2 PS2解码模块:
3.3 PS2组合模块:
3.4 控制LED模块:
3.5 PS2总的组合模块:
4 各模块分析
4.1 PS2时钟检测模块
PS2电平检测模块主要的作用是检测PS2接口键盘的时钟信号,因为PS2的协议规定数据是在时钟的下降沿读取的。所以电平检测模块要检测PS2时钟的下降沿,有下降沿来临时,要做相应的数据读取动作。下面是代码的分析。
LIBRARY IEEE; --库
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
------------------------------------------------------------------------------------------------------------------------------------------
ENTITY PS2_detect_module IS --实体声明
PORT(
CLK,RSTn : IN STD_LOGIC;
PS2_CLK_Pin_In : IN STD_LOGIC;
H_L_Sig : OUT STD_LOGIC; --电平由高变低,输出一个信号
L_H_Sig : OUT STD_LOGIC --电平由低变高,输出一个信号
);
END ENTITY PS2_detect_module;
------------------------------------------------------------------------------------------------------------------------------------------
ARCHITECTURE PS2_detect OF PS2_detect_module IS --结构体声明
SIGNAL H_L_F1 : STD_LOGIC :='1'; --声明4个信号,用于电平输入的变化
SIGNAL H_L_F2 : STD_LOGIC :='1'; --4个信号都赋了初值
SIGNAL L_H_F1 : STD_LOGIC :='0';
SIGNAL L_H_F2 : STD_LOGIC :='0';
BEGIN
PROCESS(CLK,RSTn)
BEGIN
IF (CLK'event AND CLK='1') THEN --同步进行
IF (RSTn='0') THEN --同步复位动作
H_L_F1 <= '1';H_L_F2 <= '1';L_H_F1 <= '0';L_H_F2 <= '0';
ELSE
H_L_F1 <= PS2_CLK_Pin_In;H_L_F2 <= H_L_F1;
L_H_F1 <= PS2_CLK_Pin_In;L_H_F2 <= L_H_F1;
END IF;
END IF;
END PROCESS;
H_L_Sig <= H_L_F2 AND (NOT H_L_F1); --输出信号
L_H_Sig <= L_H_F1 AND (NOT L_H_F2);
END ARCHITECTURE PS2_detect; --结构体结束
在结构体中声明了4个信号,用于电平的检测F2信号是接着F1信号的,如果F1信号变化了,F2信号还不会立即变化,F2还会保持F1的前一个状态,以两者的逻辑关系,可以判断输入的是上升沿还是下降沿。结果如表格3。
时间 | H_L_F1 | H_L_F2 | H_L_Sig <= H_L_F2 AND (NOT H_L_F1) |
---|---|---|---|
Initial | 1 | 1 | 0 |
T1 | 0 | 1 | 1 |
T2 | 0 | 0 | 0 |
时间 | L_H_F1 | L_H_F2 | L_H_Sig <= L_H_F1 AND (NOT L_H_F2); |
Initial | 0 | 0 | 0 |
T1 | 1 | 0 | 1 |
T2 | 1 | 1 | 0 |
4.2 PS2解码模块
LIBRARY IEEE; --库
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
------------------------------------------------------------------------------------------------------------------------------------------
ENTITY PS2_decode_module IS --实体声明
PORT(
CLK,RSTn : IN STD_LOGIC;
H_L_Sig : IN STD_LOGIC;
PS2_Data_Pin_In : IN STD_LOGIC;
PS2_Done_Sig : OUT STD_LOGIC;
PS2_Data : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END ENTITY PS2_decode_module;
------------------------------------------------------------------------------------------------------------------------------------------
ARCHITECTURE PS2_decode OF PS2_decode_module IS
SIGNAL Done : STD_LOGIC :='0'; --声明一个完成信号
SIGNAL i : STD_LOGIC_VECTOR(4 DOWNTO 0) :="00001"; --声明步骤i
SIGNAL Data : STD_LOGIC_VECTOR(7 DOWNTO 0) :=X"32";
BEGIN
PROCESS(CLK,RSTn,i)
BEGIN
IF (CLK'event AND CLK='1') THEN
IF (RSTn='0') THEN
i <= "00001";Done <= '0';Data <= X"00";
ELSE
CASE i IS
WHEN "00000" => i <= "00001";
WHEN "00001" => IF (H_L_Sig='1') THEN i <= "00010";Data(0) <= PS2_Data_Pin_In;END IF;
WHEN "00010" => IF (H_L_Sig='1') THEN i <= "00011";Data(1) <= PS2_Data_Pin_In;END IF;
WHEN "00011" => IF (H_L_Sig='1') THEN i <= "00100";Data(2) <= PS2_Data_Pin_In;END IF;
WHEN "00100" => IF (H_L_Sig='1') THEN i <= "00101";Data(3) <= PS2_Data_Pin_In;END IF;
WHEN "00101" => IF (H_L_Sig='1') THEN i <= "00110";Data(4) <= PS2_Data_Pin_In;END IF;
WHEN "00110" => IF (H_L_Sig='1') THEN i <= "00111";Data(5) <= PS2_Data_Pin_In;END IF;
WHEN "00111" => IF (H_L_Sig='1') THEN i <= "01000";Data(6) <= PS2_Data_Pin_In;END IF;
WHEN "01000" => IF (H_L_Sig='1') THEN i <= "01001";Data(7) <= PS2_Data_Pin_In;END IF;
WHEN "01001" => IF (H_L_Sig='1') THEN i <= "01010";END IF;
WHEN "01010" => IF (H_L_Sig='1') THEN i <= "01011";END IF;
WHEN "01011" => IF (Data=X"F0") THEN i <= "01100";ELSE i <= "10110";END IF;
WHEN "01100" => IF (H_L_Sig='1') THEN i <= "01101";END IF;
WHEN "01101" => IF (H_L_Sig='1') THEN i <= "01110";END IF;
WHEN "01110" => IF (H_L_Sig='1') THEN i <= "01111";END IF;
WHEN "01111" => IF (H_L_Sig='1') THEN i <= "10000";END IF;
WHEN "10000" => IF (H_L_Sig='1') THEN i <= "10001";END IF;
WHEN "10001" => IF (H_L_Sig='1') THEN i <= "10010";END IF;
WHEN "10010" => IF (H_L_Sig='1') THEN i <= "10011";END IF;
WHEN "10011" => IF (H_L_Sig='1') THEN i <= "10100";END IF;
WHEN "10100" => IF (H_L_Sig='1') THEN i <= "10101";END IF;
WHEN "10101" => IF (H_L_Sig='1') THEN i <= "10110";END IF;
WHEN "10110" => IF (H_L_Sig='1') THEN i <= "10111";Done <= '1';END IF;
WHEN "10111" => IF (H_L_Sig='1') THEN i <= "00001";Done <= '0';END IF;
WHEN OTHERS => i <= "00001";
END CASE;
END IF;
END IF;
END PROCESS;
PS2_Data <= Data;
PS2_Done_Sig <= Done;
END ARCHITECTURE PS2_decode;
这个模块我有点偷懒,只对键盘输入的8位有效数据进行了提取,其他位基本是忽略了,第一位开始位忽略了,然后是读取8位有效数据,第9步和第10步跳过了检测位和结束位,然后是判断。如果是0XF0,则证明是断码,断码的话后面的直接跳过,如果不是0XF0,则证明是有效的数据,立即跳到步骤22,向顶层的模块回馈一个完成信号,并将有效数据输出。
4.3 PS2组合模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
------------------------------------------------------------------------------------------------------------------------------------------
ENTITY PS2 IS
PORT(
CLK,RSTn : IN STD_LOGIC;
PS2_Data_Pin_In : IN STD_LOGIC;
PS2_CLK_Pin_In : IN STD_LOGIC;
PS2_Done_Sig : BUFFER STD_LOGIC;
PS2_Data : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END ENTITY PS2;
------------------------------------------------------------------------------------------------------------------------------------------
ARCHITECTURE PS2_behave OF PS2 IS
COMPONENT PS2_detect_module
PORT(
CLK,RSTn : IN STD_LOGIC;
PS2_CLK_Pin_In : IN STD_LOGIC;
H_L_Sig : OUT STD_LOGIC;
L_H_Sig : OUT STD_LOGIC
);
END COMPONENT;
COMPONENT PS2_decode_module
PORT(
CLK,RSTn : IN STD_LOGIC;
H_L_Sig : IN STD_LOGIC;
PS2_Data_Pin_In : IN STD_LOGIC;
PS2_Done_Sig : OUT STD_LOGIC;
PS2_Data : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
COMPONENT PS2_code_module
PORT(
CLK,RSTn : IN STD_LOGIC;
L_H_Sig : IN STD_LOGIC;
PS2_Done_Sig : IN STD_LOGIC;
PS2_Data_Pin_Out : OUT STD_LOGIC
);
END COMPONENT;
SIGNAL H_L : STD_LOGIC;
SIGNAL L_H : STD_LOGIC;
SIGNAL PS2_Data_Pin_Out : STD_LOGIC;
BEGIN
U1:PS2_detect_module PORT MAP(CLK,RSTn,PS2_CLK_Pin_In,H_L,L_H);
U2:PS2_decode_module PORT MAP(CLK,RSTn,H_L,PS2_Data_Pin_In,PS2_Done_Sig,PS2_Data);
U2:PS2_decode_module PORT MAP(CLK,RSTn,H_L,PS2_Data_Pin_Out,PS2_Done_Sig,PS2_Data);
U3:PS2_code_module PORT MAP(CLK,RSTn,L_H,PS2_Done_Sig,PS2_Data_Pin_Out);
END ARCHITECTURE PS2_behave;
这是一个组合例化的模块,是对PS2时钟电平检测和PS2解码的一个简单模块。这一个模块初步实现了PS2的解码功能。上面的是代码的方法实现例化功能,同时也可以使用原理图的方式来实现例化,下面为原理图例化的图。
4.4 控制LED模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
------------------------------------------------------------------------------------------------------------------------------------------
ENTITY PS2_contorl_module IS
PORT(
CLK,RSTn : IN STD_LOGIC;
PS2_Done_Sig : IN STD_LOGIC;
PS2_Data : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
Data_Out : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END ENTITY PS2_contorl_module;
------------------------------------------------------------------------------------------------------------------------------------------
ARCHITECTURE PS2_contorl OF PS2_contorl_module IS
SIGNAL Data : STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
PROCESS(CLK,RSTn)
BEGIN
IF (CLK'event AND CLK='1') THEN
IF (RSTn='0') THEN
Data <= "0001";
ELSIF(PS2_Done_Sig='1') THEN
CASE PS2_Data IS
WHEN X"22" => Data <= (Data(2 DOWNTO 0)&Data(3));
WHEN X"1A" => Data <= (Data(0)&Data(3 DOWNTO 1));
WHEN X"14" => Data <= (Data(0)&Data(1)&Data(2)&Data(3));
WHEN X"21" => Data <= "1111";WHEN X"2A" => Data <= "0000";
WHEN X"5A" => Data <= "0001";WHEN X"32" => Data <= "0001";
WHEN X"31" => Data <= "0011";WHEN X"3A" => Data <= "0111";
WHEN OTHERS => Data <= Data;
END CASE;
END IF;
END IF;
END PROCESS;
Data_Out <= Data;
END ARCHITECTURE PS2_contorl;
LED控制模块主要的作用是用于显示结果。在PS2键盘扫描后,得到的8位有效结果,使用4盏LED灯作为检查结果的输出,使用不用的LED闪亮方式来表示不同的按键按下了。本程序只做了11个按键,分别是“Z”,“X”,“C”,“V”,“B”,“N”,“M”,“Entet”和“Ctrl”。“Z”按下后,LED向左移一个单位,“X”是向右移一个单位,“Ctrl”是LED灯互换,“B”是点亮一盏LED,“N”是点亮两盏LED,“M”是点亮三盏LED,“Entet”是复原LED灯的情况。
4.5 PS2总的组合模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
------------------------------------------------------------------------------------------------------------------------------------------
ENTITY PS2_module IS
PORT(
CLK,RSTn : IN STD_LOGIC;
PS2_Data_Pin_In : IN STD_LOGIC;
PS2_CLK_Pin_In : IN STD_LOGIC;
Data_Out : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END ENTITY PS2_module;
------------------------------------------------------------------------------------------------------------------------------------------
ARCHITECTURE PS2 OF PS2_module IS
COMPONENT PS2
PORT(
CLK,RSTn : IN STD_LOGIC;
PS2_Data_Pin_In : IN STD_LOGIC;
PS2_CLK_Pin_In : IN STD_LOGIC;
PS2_Done_Sig : OUT STD_LOGIC;
PS2_Data : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END COMPONENT;
COMPONENT PS2_contorl_module
PORT(
CLK,RSTn : IN STD_LOGIC;
PS2_Done_Sig : IN STD_LOGIC;
PS2_Data : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
Data_Out : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
END COMPONENT;
SIGNAL Done_Sig : STD_LOGIC;
SIGNAL Data : STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
U1:PS2 PORT MAP(CLK,RSTn,PS2_Data_Pin_In,PS2_CLK_Pin_In,Done_Sig,Data);
-- U1:PS2 PORT MAP(CLK,RSTn,PS2_CLK_Pin_In,Done_Sig,Data);
U2:PS2_contorl_module PORT MAP(CLK,RSTn,Done_Sig,Data,Data_Out);
END ARCHITECTURE PS2;
这是一个组合例化的模块,是对PS2功能模块和LED控制的一个简单组合的模块。这一个模块是PS2键盘扫描的最顶层文件,只做例化作用,不包含其他功能代码。上面的是代码的方法实现例化功能,同时也可以使用原理图的方式来实现例化,下面为原理图例化的图。
第四部分 综合与仿真
1 综合
对编写好的源程序进行综合,同时生成RTL电路图,RTL电路图如下。
2 综合仿真
在本次设计中,仿真工作只对电平检测模块,LED灯控制模块和PS2 _module总模块进行了仿真。对于前两个模块,采用的仿真方法是使用Quartus II自带的波形仿真软件进行仿真,而对于PS2_module总模块的仿真则使用了编写代码的方式进行仿真。因为PS2_module总模块对键盘按键的波形设置很麻烦,而且仿真效果不好,所以直接使用代码的方式产生一个键盘按键,同时观察波形来检测。
2.1 电平检测模块仿真
电平检测模块原理图如下:
仿真波形如下:
2.2 LED灯控制模块仿真
LED灯控制模块原理图如下:
系统时钟给了10ns,RSTn复位在一开始的时候给了‘0’,进行了一次复位,PS2 _Done_Sig完成信号则是100ns一次,PS2_Data给的是X“22”(即X被按下)。复位后Data_Out输出的是“0001”,第一盏LED灯点亮,然后在PS2_Done_Sig信号后,Data_Out输出变化了,变为了“0010”,LED第二盏给点亮了,LED灯移位了。因为一直是X被按下,所以信号不断移位,LED分别为1,2,4,8。在最后那里,由于PS2_Data给的是X“20”,并没有在控制那设置这个按键,所以LED没反应,一直保持在2(即第二盏灯点亮)。
2.3 PS2_module总模块仿真
由于PS2总仿真的时候需要键盘的通码输入,但使用波形的改变来作为通码输入的方式太麻烦了,而且很容易出错,得不到想要的波形。所以为了克服这个问题,我使用了另外的一种方法来仿真,直接写键盘编码来给整个模块,然后开输出波形就可以观察。
PS2_module总模块仿真点简单方框图如下:
PS2_code_module键盘编码模块代码如下:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
------------------------------------------------------------------------------------------------------------------------------------------
ENTITY PS2_code_module IS
PORT(
CLK,RSTn : IN STD_LOGIC;
L_H_Sig : IN STD_LOGIC;
PS2_Done_Sig : IN STD_LOGIC;
PS2_Data_Pin_Out : OUT STD_LOGIC
);
END ENTITY PS2_code_module;
------------------------------------------------------------------------------------------------------------------------------------------
ARCHITECTURE PS2_code OF PS2_code_module IS
CONSTANT n_0:STD_LOGIC_VECTOR:=X"22";CONSTANT n_1:STD_LOGIC_VECTOR:=X"1A";
CONSTANT n_2:STD_LOGIC_VECTOR:=X"14";CONSTANT n_3:STD_LOGIC_VECTOR:=X"21";
CONSTANT n_4:STD_LOGIC_VECTOR:=X"2A";CONSTANT n_n:STD_LOGIC_VECTOR:=X"F0";
SIGNAL data : STD_LOGIC :='0';
SIGNAL i : STD_LOGIC_VECTOR(4 DOWNTO 0) :="00000";
BEGIN
PROCESS(CLK,RSTn,i)
BEGIN
IF (CLK'event AND CLK='1') THEN
IF (RSTn='0') THEN
i <= "00000";
data <= '0';
ELSE
CASE i IS
WHEN "00000" => i <= "00001";
WHEN "00001" => IF (L_H_Sig='1') THEN i <= "00010";data <= n_1(0);END IF;
WHEN "00010" => IF (L_H_Sig='1') THEN i <= "00011";data <= n_1(1);END IF;
WHEN "00011" => IF (L_H_Sig='1') THEN i <= "00100";data <= n_1(2);END IF;
WHEN "00100" => IF (L_H_Sig='1') THEN i <= "00101";data <= n_1(3);END IF;
WHEN "00101" => IF (L_H_Sig='1') THEN i <= "00110";data <= n_1(4);END IF;
WHEN "00110" => IF (L_H_Sig='1') THEN i <= "00111";data <= n_1(5);END IF;
WHEN "00111" => IF (L_H_Sig='1') THEN i <= "01000";data <= n_1(6);END IF;
WHEN "01000" => IF (L_H_Sig='1') THEN i <= "01001";data <= n_1(7);END IF;
WHEN "01001" => IF (L_H_Sig='1') THEN i <= "01010";END IF;
WHEN "01010" => IF (L_H_Sig='1') THEN i <= "01011";END IF;
WHEN "01011" => IF (PS2_Done_Sig='1') THEN i <= "01100";END IF;
WHEN "01100" => IF (L_H_Sig='1') THEN i <= "01101";data <= n_n(0);END IF;
WHEN "01101" => IF (L_H_Sig='1') THEN i <= "01110";data <= n_n(1);END IF;
WHEN "01110" => IF (L_H_Sig='1') THEN i <= "01111";data <= n_n(2);END IF;
WHEN "01111" => IF (L_H_Sig='1') THEN i <= "10000";data <= n_n(3);END IF; WHEN "10000" => IF (L_H_Sig='1') THEN i <= "10001";data <= n_n(4);END IF;
WHEN "10001" => IF (L_H_Sig='1') THEN i <= "10010";data <= n_n(5);END IF;
WHEN "10010" => IF (L_H_Sig='1') THEN i <= "10011";data <= n_n(6);END IF;
WHEN "10011" => IF (L_H_Sig='1') THEN i <= "10100";data <= n_n(7);END IF;
WHEN "10100" => IF (L_H_Sig='1') THEN i <= "10101";END IF;
WHEN "10101" => IF (L_H_Sig='1') THEN i <= "10110";END IF;
WHEN "10110" => IF (L_H_Sig='1') THEN i <= "10111";END IF;
WHEN "10111" => IF (L_H_Sig='1') THEN i <= "00000";END IF;
WHEN OTHERS => i <= "00000";
END CASE;
END IF;
END IF;
END PROCESS;
PS2_Data_Pin_Out <= data;
END ARCHITECTURE PS2_code;
代码实现的功能就是每一个PS2_CLK_Pin_In的上升沿来临的时候,设置好数据给S2_CLK_Pin_In的下降沿时后面模块的读取,时间要与PS2_decode_module模块同步。
仿真出来的波形图如下:
第五部分 硬件下载
先设置好芯片类型,因为我是使用自己的FPGA开发板,所以我用的芯片是Cyclone II的EP2C5Q208C8,如下图。
设置芯片后,接着的是设置不用到引脚位,将不用的引脚设置为三态输入,以防芯片烧坏,设置方式如下图:
成功编译后,是引脚分配,将需要用到的端口分配到FPGA的引脚上关联起来,引脚分配如下图:
最后的操作是硬件下载,在PROGRAMMER中进行,要设置好USB仿真口,FPGA下载方式是JTAG,下载图如下:
第六部分 心得体会
第七部分 参考文献
来源:CSDN
作者:Tony Zhang
链接:https://blog.csdn.net/Charmve/article/details/103462640