📄 ps2_driver.v
字号:
next_state = Read_finish;
end
else begin
next_state = Read_data;
end
end
else next_state = Read_data_complete;
end
Read_finish: begin
if( key_clk == 1 && key_data == 1) begin
next_state = Idle;
end
else next_state = Read_finish;
end
//---------------------------------PS2驱动器写状态-------------------------------//
Inhibit_com: begin
if(counter_reg == TIME) begin //抑制通讯约100μS
next_state = Inhibit_com_complete;
end
else next_state = Inhibit_com;
end
Inhibit_com_complete: begin
if( k_clk == 1 ) begin
next_state = Write_start;
end
else next_state = Inhibit_com_complete;
end
Write_start: begin
if( k_clk == 0 ) begin
next_state = Write_data;
end
else next_state = Write_start;
end
Write_data: begin
if( k_clk == 1 ) begin
next_state = Write_data_complete;
end
else next_state = Write_data;
end
Write_data_complete: begin
if( k_clk == 0 ) begin
if( counter_reg == 8'd9) begin
next_state = Write_stop;
end
else begin
next_state = Write_data;
end
end
else next_state = Write_data_complete;
end
Write_stop: begin
if( k_clk == 1 ) begin
next_state = Read_ACK;
end
else next_state = Write_stop;
end
Read_ACK: begin //应答检测
if( k_clk == 0) begin
next_state = Write_finish;
end
else next_state = Read_ACK;
end
Write_finish: begin
if( k_data == 1 && k_clk == 1 ) begin
next_state = Idle;
end
else begin
next_state = Write_finish;
end
end
default: begin
next_state = 'bx;
end
endcase
//------------------------------------------------------------------------------//
// //
// PS2驱动器控制输出 //
// //
//------------------------------------------------------------------------------//
always @( posedge drv_clk or negedge clr_n)
if (!clr_n) begin
r_data_reg <= 0;
w_data_reg <= 0;
clk_w <= 0;
data_w <= 1;
key_reg <= 0;
ready <= 0;
error <= 0;
counter_reg <= 0;
end
else begin
case (current_state)
Idle: begin
$display("Idle start");
ready <= 0;
clk_w <= 0; //抑制通讯
end
//------------------------------------------------------------------------------//
// //
// PS2驱动器读操作 //
// //
//------------------------------------------------------------------------------//
Read_start: begin
clk_w <= 1;
$display("Read start");
end
Read_start_complete: begin
$display("Complete read start");
end
Read_data: begin
if( key_clk == 0 ) begin
r_data_reg [counter_reg] <= key_data; //读数据、效验位和结束位
$display("read r_data[%d] BIT is %b",counter_reg,ps2_data);
end
else $display("Wait negative edge");
end
Read_data_complete: begin
if( key_clk == 1 ) begin
counter_reg <= counter_reg + 1;
end
else $display("Wait advancing edge");
end
Read_finish: begin
ready <= 1;
counter_reg <= 0;
$display("PS2K parity bit is %b",r_data_reg [8]);
if( read_parity == r_data_reg [8] )
begin //数据效验位和接收效验位比较
$display("PS2K parity bit is right");
$display("Complete read r_data is %b",r_data);
end
else begin
$display("PS2K parity bit is error");
error <= PARITY_ERROR;
end
end
//------------------------------------------------------------------------------//
// //
// PS2驱动器写操作 //
// //
//------------------------------------------------------------------------------//
Inhibit_com: begin
counter_reg <= counter_reg + 1; //延时计数
$display("Inhibit communication");
end
Inhibit_com_complete: begin
if( k_clk == 1 ) begin
w_data_reg <= {write_parity,w_data}; //写数据寄存器
counter_reg <= 0;
end
else begin
$display("Complete Inhibit communication");
data_w <= 0; //设数据线为输出
key_reg <= 0; //置数据线为"0"
clk_w <= 1; //释放时钟线
end
end
Write_start: begin
if( k_clk == 0 ) begin
$display("write w_data_reg[%d] BIT is
%b",counter_reg,w_data_reg[counter_reg]);
key_reg <= w_data_reg [counter_reg]; //写0位数据
end
else begin
$display("Write start");
end
end
Write_data: begin
if( k_clk == 1 ) begin
counter_reg <= counter_reg + 1; //加位数计数器
key_reg <= w_data_reg [counter_reg]; //写1-7位,校验位数据
$display("write w_data_reg[%d] BIT is
%b",counter_reg,w_data_reg[counter_reg]);
end
else begin
$display("Write data");
$display("Wait advancing edge");
end
end
Write_data_complete: begin
$display("Wait negative edge");
end
Write_stop: begin
data_w <= 1; //释放数据线
counter_reg <= 0;
$display("Write stop");
end
Read_ACK: begin //应答检测
if( k_clk == 0 ) begin
if( k_data == 0) begin
$display("PS2K_DATA ACK ");
end
else begin
$display("PS2K_DATA NO ACK ");
error <= NO_ACK;
end
end
else begin
$display("Read ACK");
end
end
Write_finish: begin
$display("Complete write data");
ready <= 1;
end
endcase
end
endmodule
//1、命名规则很统一,但是不太符合惯例,惯例也就是没有人说必须,但是大家都这样做^_^,
// 一般parameter/define等用大写,其他都是小写。182-202中always @ 格式不统一。
//2、不要使用tab键或者将tab键自动转换为空格,因为不同的编辑器可能会看到不同结果,
// 就像你现在肯定不能想象我这边看到的代码是什么样子,如果使用空格就没有这个问题。
//说明一点,虽然一般代码文字编写规范不是很重要,但是好的规范会给人professional的感觉,所以还是很重要的^_^
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -