?? keyboard_test1.v
字號:
////////////////////////////////////////////////////////////////////////////////
//公司: <Company Name>
//工程師: Lawson_jian
//
//創(chuàng)建日期: 2004年12月10日
//設(shè)計(jì)名字:
//模塊名字: 鍵盤驅(qū)動(dòng)器 KeyBoard Divider
//目標(biāo)裝置:
//工具版本: <tool_versions>
//描述:
//
//屬性:
// <Dependencies here>
//修改:
// <Code_revision_information>
//附加說明:
// <Additional_comments>
////////////////////////////////////////////////////////////////////////////////
`timescale 1 ns / 1 ns
module keyboard_test1 (
PS2K_DATA,
PS2K_CLK,
R_DATA,
W_DATA,
BUSY,
Complete,
Error,
RW,
ENA,
CLK,
CLR
);
//+---------------------------KeyBoard 狀態(tài)設(shè)置---------------------------+
parameter Data_Width = 8; //輸入/輸出數(shù)據(jù)寬度
parameter Count = 5; //狀態(tài)碼寬度
//+-----------------------------------------------------------------------+
inout PS2K_DATA;
inout PS2K_CLK;
input [Data_Width-1:0] W_DATA;
input RW;
input ENA;
input CLR; // synthesis attribute clock_buffer of CLR is ibufg;
input CLK;
output [Data_Width-1:0] R_DATA;
output BUSY;
output Complete;
output [1:0] Error;
//+---------------------------頻率發(fā)生器狀態(tài)代碼-------------------------+
parameter Add_CounteState = 0;
parameter Dec_CounteState = 1;
//+---------------------------KeyBoard 讀狀態(tài)代碼-------------------------+
parameter Read_start = 4'h0;
parameter Read_start_complete = 4'h1;
parameter Read_data = 4'h2;
parameter Read_data_complete = 4'h3;
parameter Read_parity = 4'h4;
parameter Read_parity_complete = 4'h5;
parameter Read_stop = 4'h6;
parameter Read_finish = 4'h7;
//+---------------------------KeyBoard 寫狀態(tài)代碼--------------------------+
parameter Write_start = 4'h0;
parameter Restrain_read = 4'h1;
parameter Write_data = 4'h2;
parameter Write_data_complete = 4'h3;
parameter Write_parity = 4'h4;
parameter Write_parity_complete = 4'h5;
parameter Write_stop = 4'h6;
parameter Write_stop_complete = 4'h7;
parameter Write_ACK = 4'h8;
parameter Write_finish = 4'h9;
//+-----------------------------KeyBoard 錯(cuò)誤代碼--------------------------+
parameter No_R_stop_signal = 4'h1;
parameter Checkout_error = 4'h2;
parameter No_ACK_signal = 4'h3;
//+------------------------------------------------------------------------+
reg [3:0] W_State;
reg [3:0] R_State;
reg [Data_Width-1:0] R_DATA;
reg [Data_Width-1:0] W_Reg;
reg CLK_W;
reg DATA_W;
reg K_DATA;
reg BUSY;
reg Complete;
reg P_Reg;
reg [7:0] Counter;
reg [1:0] Error;
reg [Data_Width-1:0] Counter_reg; //計(jì)數(shù)器寄存器
reg CounteState; //計(jì)數(shù)器狀態(tài)寄存器
reg Pulse_Out_reg; //脈沖發(fā)生寄存器
wire [Data_Width-1:0] Half_Frequency_Data;
wire [Data_Width-1:0] Frequency_Data;
wire us_CLK;
wire P;
//----------------------------------------------------------------------------//
// //
// 接口邏輯函數(shù) //
// //
//----------------------------------------------------------------------------//
assign Frequency_Data = 8'd100; //頻率數(shù)據(jù)
assign us_CLK = Pulse_Out_reg;
assign Half_Frequency_Data = Frequency_Data/2;
assign PS2K_DATA = DATA_W ? 1'bz : K_DATA;
assign PS2K_CLK = CLK_W ? 1'bz : 0;
assign P = RW ? ^~R_DATA : ^~W_Reg;
//----------------------------------------------------------------------------//
// //
// 1ms脈沖發(fā)生器 //
// //
//----------------------------------------------------------------------------//
always @(posedge CLK or negedge CLR)
begin
if (!CLR) //復(fù)位
begin
Counter_reg = 1;
CounteState = Add_CounteState;
Pulse_Out_reg = 0;
end
else begin
Counter_reg = Counter_reg + 1;
case (CounteState)
Add_CounteState : //增量計(jì)數(shù)狀態(tài)
begin
if(Counter_reg == Half_Frequency_Data) //Half_Frequency_Data = Frequency_Reg/2 產(chǎn)生半個(gè)時(shí)鐘脈沖
begin
CounteState = Dec_CounteState;
Pulse_Out_reg = 1;
end
end
Dec_CounteState : //減量計(jì)數(shù)狀態(tài)
begin
if(Counter_reg == Frequency_Data) //產(chǎn)生完整時(shí)鐘脈沖
begin
Counter_reg = 1;
CounteState = Add_CounteState;
Pulse_Out_reg = 0;
end
end
endcase
end
end
//----------------------------------------------------------------------------//
// //
// KeyBoard Read or Wrie //
// //
//----------------------------------------------------------------------------//
always @( posedge us_CLK or negedge CLR)
if (!CLR) begin
R_DATA = 0;
W_Reg = 0;
CLK_W = 1;
DATA_W = 1;
K_DATA = 0;
BUSY = 0;
Complete = 0;
Counter = 0;
P_Reg = 0;
Error = 0;
Counter = 0;
W_State = Write_start;
R_State = Read_start;
end
else if (ENA) begin
if(RW) begin
case (R_State)
Read_start: begin
CLK_W = 1;
DATA_W = 1;
Error = 0;
Complete = 0;
if( PS2K_CLK == 0 && PS2K_DATA == 0) begin
BUSY = 1;
R_State = Read_start_complete;
end
else begin
R_State = Read_start;
end
end
Read_start_complete: begin
if( PS2K_CLK == 1) begin
Counter = 8'd0;
R_State = Read_data;
end
else R_State = Read_start_complete;
end
Read_data: begin
if( PS2K_CLK == 0 ) begin
R_DATA[Counter] = PS2K_DATA;
Counter = Counter + 1;
R_State = Read_data_complete;
$display("read R_DATA[%d] BIT is %b",Counter,PS2K_DATA);
end
else R_State = Read_data;
end
Read_data_complete: begin
if( PS2K_CLK == 1 ) begin
if( Counter == 8'd8) begin
R_State = Read_parity;
end
else begin
R_State = Read_data;
end
end
else R_State = Read_data_complete;
end
Read_parity: begin
if( PS2K_CLK == 0 ) begin
P_Reg = PS2K_DATA;
R_State = Read_parity_complete;
$display("read PS2K parity bit ");
end
else R_State = Read_parity;
end
Read_parity_complete: begin
if( PS2K_CLK == 1 ) begin
R_State = Read_stop;
end
else R_State = Read_parity_complete;
end
Read_stop: begin
if( PS2K_CLK == 0) begin
if(PS2K_DATA == 1) begin
$display("PS2K_DATA STOP ");
R_State = Read_finish;
end
else begin
Error = No_R_stop_signal;
R_State = Read_finish;
end
end
else R_State = Read_stop;
end
Read_finish: begin
if( PS2K_CLK == 1) begin
BUSY = 0;
Complete = 1;
$display("PS2K parity bit is %b",P_Reg);
if( P == P_Reg ) begin
$display("PS2K parity bit is right");
$display("Complete read R_DATA is %b",R_DATA);
R_State = Read_start;
end
else begin
$display("PS2K parity bit is error");
Error = Checkout_error;
R_State = Read_start;
end
end
else R_State = Read_finish;
end
default: begin
R_State = Read_start;
end
endcase
end
else begin
case (W_State)
Write_start: begin
CLK_W = 0;
DATA_W = 0;
W_Reg = W_DATA;
K_DATA = 1;
Counter = 0;
BUSY = 1;
Complete = 0;
Error = 0;
W_State = Restrain_read;
end
Restrain_read: begin
if(Counter == 8'd100) begin //抑制鍵盤通訊400μS
K_DATA = 0;
Counter = 0;
CLK_W = 1;
$display("Complete Restrain Read ");
W_State = Write_data;
end
else begin
Counter = Counter + 1;
W_State = Restrain_read;
end
end
Write_data: begin
if( PS2K_CLK == 0 ) begin
K_DATA = W_Reg [Counter];
Counter = Counter + 1;
$display("write W_DATA[%d] BIT is %b",Counter,W_DATA[Counter]);
W_State = Write_data_complete;
end
else W_State = Write_data;
end
Write_data_complete: begin
if( PS2K_CLK == 1 ) begin
if( Counter == 8'd8) W_State = Write_parity;
else W_State = Write_data;
end
else W_State = Write_data_complete;
end
Write_parity: begin
if( PS2K_CLK == 0 ) begin
K_DATA = P;
$display("write Parity Bit is %b",P);
W_State = Write_parity_complete;
end
else W_State = Write_parity;
end
Write_parity_complete: begin
if( PS2K_CLK == 1 ) begin
W_State = Write_stop;
end
else W_State = Write_parity_complete;
end
Write_stop: begin
if( PS2K_CLK == 0 ) begin
$display("Write stop ");
K_DATA = 1;
W_State = Write_stop_complete;
end
else W_State = Write_stop;
end
Write_stop_complete: begin
if( PS2K_CLK == 1 ) begin
DATA_W = 1;
W_State = Write_ACK;
end
else W_State = Write_stop_complete;
end
Write_ACK: begin
if( PS2K_CLK == 0) begin
if( PS2K_DATA == 0) begin
$display("PS2K_DATA ACK ");
W_State = Write_finish;
end
else begin
$display("PS2K_DATA NO ACK ");
Error = No_ACK_signal;
W_State = Write_finish;
end
end
else begin
W_State = Write_ACK;
end
end
Write_finish: begin
if( PS2K_DATA == 1 && PS2K_CLK == 1 ) begin
$display("Complete write PS2K DATA");
BUSY = 0;
Complete = 1;
W_State = Write_start;
end
else begin
W_State = Write_finish;
end
end
default: begin
W_State = Write_start;
end
endcase
end
end
endmodule
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -