除了顶层模块,三个底层模块分别为PS/2传输处理模块、串口传输模块以及串口波特率选择模块(下面只给出顶层模块和PS/2传输处理模块的Verilog代码)。
 Module Ps2_key(Clk,Rst_n,Ps2k_clk,Ps2k_data,Rs232_tx);
 Input Clk; //50M时钟信号
 Input Rst_n; //复位信号
 Input Ps2k_clk; //PS2接口时钟信号
 Input Ps2k_data; //PS2接口数据信号
 Output Rs232_tx; // RS232发送数据信号
 Wire[7:0] Ps2_byte; // 1byte键值
 Wire Ps2_state; //按键状态标志位
 Wire Bps_start; //接收到数据后,波特率时钟启动信号置位
 Wire Clk_bps; // Clk_bps的高电平为接收或者发送数据位的中间采样点 
 Ps2scan Ps2scan( .Clk(Clk), //按键扫描模块
 .Rst_n(Rst_n), 
 .Ps2k_clk(Ps2k_clk),
 .Ps2k_data(Ps2k_data),
 .Ps2_byte(Ps2_byte),
 .Ps2_state(Ps2_state)
 ); 
 Speed_select Speed_select( .Clk(Clk),
 .Rst_n(Rst_n),
 .Bps_start(Bps_start),
 .Clk_bps(Clk_bps)
 );
 My_uart_tx My_uart_tx( .Clk(Clk),
 .Rst_n(Rst_n),
 .Clk_bps(Clk_bps),
 .Rx_data(Ps2_byte),
 .Rx_int(Ps2_state),
 .Rs232_tx(Rs232_tx),
 .Bps_start(Bps_start)
 ); 
 Endmodule 
 Module Ps2scan(Clk,Rst_n,Ps2k_clk,Ps2k_data,Ps2_byte,Ps2_state);
 Input Clk; //50M时钟信号
 Input Rst_n; //复位信号
 Input Ps2k_clk; //PS2接口时钟信号
 Input Ps2k_data; //PS2接口数据信号
 Output[7:0] Ps2_byte; // 1byte键值,只做简单的按键扫描
 Output Ps2_state; //键盘当前状态,Ps2_state=1表示有键被按下 
 //------------------------------------------
 Reg Ps2k_clk_r0,Ps2k_clk_r1,Ps2k_clk_r2; //Ps2k_clk状态寄存器
 //Wire Pos_ps2k_clk; // Ps2k_clk上升沿标志位
 Wire Neg_ps2k_clk; // Ps2k_clk下降沿标志位
 Always @ (Posedge Clk Or Negedge Rst_n) Begin
 If(!Rst_n) Begin
 Ps2k_clk_r0 <= 1''B0;
 Ps2k_clk_r1 <= 1''B0;
 Ps2k_clk_r2 <= 1''B0;
 End
 Else Begin //锁存状态,进行滤波
 Ps2k_clk_r0 <= Ps2k_clk;
 Ps2k_clk_r1 <= Ps2k_clk_r0;
 Ps2k_clk_r2 <= Ps2k_clk_r1;
 End
 End
 Assign Neg_ps2k_clk = ~Ps2k_clk_r1 & Ps2k_clk_r2; //下降沿
 //------------------------------------------
 Reg[7:0] Ps2_byte_r; //PC接收来自PS2的一个字节数据存储器
 Reg[7:0] Temp_data; //当前接收数据寄存器
 Reg[3:0] Num; //计数寄存器
 Always @ (Posedge Clk Or Negedge Rst_n) Begin
 If(!Rst_n) Begin
 Num <= 4''D0;
 Temp_data <= 8''D0;
 End
 Else If(Neg_ps2k_clk) Begin //检测到Ps2k_clk的下降沿
Case (Num)
 4''D0: Num <= Num+1''B1;
 4''D1: Begin
 Num <= Num+1''B1;
 Temp_data[0] <= Ps2k_data; //Bit0
 End
 4''D2: Begin
 Num <= Num+1''B1;
 Temp_data[1] <= Ps2k_data; //Bit1
 End
 4''D3: Begin
 Num <= Num+1''B1;
 Temp_data[2] <= Ps2k_data; //Bit2
 End
 4''D4: Begin
 Num <= Num+1''B1;
 Temp_data[3] <= Ps2k_data; //Bit3
 End
 4''D5: Begin
 Num <= Num+1''B1;
 Temp_data[4] <= Ps2k_data; //Bit4
 End
 4''D6: Begin
 Num <= Num+1''B1;
 Temp_data[5] <= Ps2k_data; //Bit5
 End
 4''D7: Begin
 Num <= Num+1''B1;
 Temp_data[6] <= Ps2k_data; //Bit6
 End
 4''D8: Begin
 Num <= Num+1''B1;
 Temp_data[7] <= Ps2k_data; //Bit7
 End
 4''D9: Begin
 Num <= Num+1''B1; //奇偶校验位,不做处理
 End
 4''D10: Begin
 Num <= 4''D0; // Num清零
 End
 Default: ;
 Endcase
 End 
 End
 Reg Key_f0; //松键标志位,置1表示接收到数据8''Hf0,再接收到下一个数据后清零
 Reg Ps2_state_r; //键盘当前状态,Ps2_state_r=1表示有键被按下 
 Always @ (Posedge Clk Or Negedge Rst_n) Begin //接收数据的相应处理,这里只对1byte的键值进行处理
 If(!Rst_n) Begin
 Key_f0 <= 1''B0;
 Ps2_state_r <= 1''B0;
 End
 Else If(Num==4''D10) Begin //刚传送完一个字节数据
 If(Temp_data == 8''Hf0) Key_f0 <= 1''B1;
 Else Begin
 If(!Key_f0) Begin //说明有键按下
 Ps2_state_r <= 1''B1;
 Ps2_byte_r <= Temp_data; //锁存当前键值
 End
 Else Begin
 Ps2_state_r <= 1''B0;
 Key_f0 <= 1''B0;
 End
 End
 End
 End
 Reg[7:0] Ps2_asci; //接收数据的相应ASCII码
 Always @ (Ps2_byte_r) Begin
 Case (Ps2_byte_r) //键值转换为ASCII码,这里做的比较简单,只处理字母
 8''H15: Ps2_asci <= 8''H51; //Q
 8''H1d: Ps2_asci <= 8''H57; //W
 8''H24: Ps2_asci <= 8''H45; //E
 8''H2d: Ps2_asci <= 8''H52; //R
 8''H2c: Ps2_asci <= 8''H54; //T
 8''H35: Ps2_asci <= 8''H59; //Y
 8''H3c: Ps2_asci <= 8''H55; //U
 8''H43: Ps2_asci <= 8''H49; //I
 8''H44: Ps2_asci <= 8''H4f; //O
 8''H4d: Ps2_asci <= 8''H50; //P 
 8''H1c: Ps2_asci <= 8''H41; //A
 8''H1b: Ps2_asci <= 8''H53; //S
 8''H23: Ps2_asci <= 8''H44; //D
 8''H2b: Ps2_asci <= 8''H46; //F
 8''H34: Ps2_asci <= 8''H47; //G
 8''H33: Ps2_asci <= 8''H48; //H
 8''H3b: Ps2_asci <= 8''H4a; //J
 8''H42: Ps2_asci <= 8''H4b; //K
 8''H4b: Ps2_asci <= 8''H4c; //L
 8''H1z: Ps2_asci <= 8''H5a; //Z
 8''H22: Ps2_asci <= 8''H58; //X
 8''H21: Ps2_asci <= 8''H43; //C
 8''H2a: Ps2_asci <= 8''H56; //V
 8''H32: Ps2_asci <= 8''H42; //B
 8''H31: Ps2_asci <= 8''H4e; //N
 8''H3a: Ps2_asci <= 8''H4d; //M
 Default: ;