//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// ps2_wb_if.v ////
|
//// ps2_wb_if.v ////
|
//// ////
|
//// ////
|
//// This file is part of the "ps2" project ////
|
//// This file is part of the "ps2" project ////
|
//// http://www.opencores.org/cores/ps2/ ////
|
//// http://www.opencores.org/cores/ps2/ ////
|
//// ////
|
//// ////
|
//// Author(s): ////
|
//// Author(s): ////
|
//// - mihad@opencores.org ////
|
//// - mihad@opencores.org ////
|
//// - Miha Dolenc ////
|
//// - Miha Dolenc ////
|
//// ////
|
//// ////
|
//// All additional information is avaliable in the README.txt ////
|
//// All additional information is avaliable in the README.txt ////
|
//// file. ////
|
//// file. ////
|
//// ////
|
//// ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//// ////
|
//// ////
|
//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org ////
|
//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org ////
|
//// ////
|
//// ////
|
//// This source file may be used and distributed without ////
|
//// This source file may be used and distributed without ////
|
//// restriction provided that this copyright statement is not ////
|
//// restriction provided that this copyright statement is not ////
|
//// removed from the file and that any derivative work contains ////
|
//// removed from the file and that any derivative work contains ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// the original copyright notice and the associated disclaimer. ////
|
//// ////
|
//// ////
|
//// This source file is free software; you can redistribute it ////
|
//// This source file is free software; you can redistribute it ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// and/or modify it under the terms of the GNU Lesser General ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// Public License as published by the Free Software Foundation; ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// either version 2.1 of the License, or (at your option) any ////
|
//// later version. ////
|
//// later version. ////
|
//// ////
|
//// ////
|
//// This source is distributed in the hope that it will be ////
|
//// This source is distributed in the hope that it will be ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// PURPOSE. See the GNU Lesser General Public License for more ////
|
//// details. ////
|
//// details. ////
|
//// ////
|
//// ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// You should have received a copy of the GNU Lesser General ////
|
//// Public License along with this source; if not, download it ////
|
//// Public License along with this source; if not, download it ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// from http://www.opencores.org/lgpl.shtml ////
|
//// ////
|
//// ////
|
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
//
|
//
|
// CVS Revision History
|
// CVS Revision History
|
//
|
//
|
// $Log: not supported by cvs2svn $
|
// $Log: not supported by cvs2svn $
|
|
// Revision 1.4 2002/02/20 16:35:43 mihad
|
|
// Little/big endian changes continued
|
|
//
|
// Revision 1.3 2002/02/20 15:20:10 mihad
|
// Revision 1.3 2002/02/20 15:20:10 mihad
|
// Little/big endian changes incorporated
|
// Little/big endian changes incorporated
|
//
|
//
|
// Revision 1.2 2002/02/18 18:07:55 mihad
|
// Revision 1.2 2002/02/18 18:07:55 mihad
|
// One bug fixed
|
// One bug fixed
|
//
|
//
|
// Revision 1.1.1.1 2002/02/18 16:16:56 mihad
|
// Revision 1.1.1.1 2002/02/18 16:16:56 mihad
|
// Initial project import - working
|
// Initial project import - working
|
//
|
//
|
//
|
//
|
|
|
// synopsys translate_off
|
// synopsys translate_off
|
`include "timescale.v"
|
`include "timescale.v"
|
// synopsys translate_on
|
// synopsys translate_on
|
|
|
module ps2_wb_if
|
module ps2_wb_if
|
(
|
(
|
wb_clk_i,
|
wb_clk_i,
|
wb_rst_i,
|
wb_rst_i,
|
wb_cyc_i,
|
wb_cyc_i,
|
wb_stb_i,
|
wb_stb_i,
|
wb_we_i,
|
wb_we_i,
|
wb_sel_i,
|
wb_sel_i,
|
wb_adr_i,
|
wb_adr_i,
|
wb_dat_i,
|
wb_dat_i,
|
wb_dat_o,
|
wb_dat_o,
|
wb_ack_o,
|
wb_ack_o,
|
|
|
wb_int_o,
|
wb_int_o,
|
|
|
tx_write_ack_i,
|
tx_kbd_write_ack_i,
|
tx_data_o,
|
tx_kbd_data_o,
|
tx_write_o,
|
tx_kbd_write_o,
|
rx_scancode_i,
|
rx_scancode_i,
|
rx_data_ready_i,
|
rx_kbd_data_ready_i,
|
rx_read_o,
|
rx_kbd_read_o,
|
translate_o,
|
translate_o,
|
ps2_clk_i,
|
ps2_kbd_clk_i,
|
inhibit_kbd_if_o
|
inhibit_kbd_if_o
|
|
`ifdef PS2_AUX
|
|
,
|
|
wb_intb_o,
|
|
|
|
rx_aux_data_i,
|
|
rx_aux_data_ready_i,
|
|
rx_aux_read_o,
|
|
tx_aux_data_o,
|
|
tx_aux_write_o,
|
|
tx_aux_write_ack_i,
|
|
ps2_aux_clk_i,
|
|
inhibit_aux_if_o
|
|
`endif
|
) ;
|
) ;
|
|
|
input wb_clk_i,
|
input wb_clk_i,
|
wb_rst_i,
|
wb_rst_i,
|
wb_cyc_i,
|
wb_cyc_i,
|
wb_stb_i,
|
wb_stb_i,
|
wb_we_i ;
|
wb_we_i ;
|
|
|
input [3:0] wb_sel_i ;
|
input [3:0] wb_sel_i ;
|
|
|
input [31:0] wb_adr_i ;
|
input [31:0] wb_adr_i ;
|
|
|
input [31:0] wb_dat_i ;
|
input [31:0] wb_dat_i ;
|
|
|
output [31:0] wb_dat_o ;
|
output [31:0] wb_dat_o ;
|
|
|
output wb_ack_o ;
|
output wb_ack_o ;
|
|
|
reg wb_ack_o ;
|
reg wb_ack_o ;
|
|
|
output wb_int_o ;
|
output wb_int_o ;
|
reg wb_int_o ;
|
reg wb_int_o ;
|
|
|
input tx_write_ack_i ;
|
input tx_kbd_write_ack_i ;
|
|
|
input [7:0] rx_scancode_i ;
|
input [7:0] rx_scancode_i ;
|
input rx_data_ready_i ;
|
input rx_kbd_data_ready_i ;
|
output rx_read_o ;
|
output rx_kbd_read_o ;
|
|
|
output tx_write_o ;
|
output tx_kbd_write_o ;
|
output [7:0] tx_data_o ;
|
output [7:0] tx_kbd_data_o ;
|
|
|
output translate_o ;
|
output translate_o ;
|
input ps2_clk_i ;
|
input ps2_kbd_clk_i ;
|
|
|
output inhibit_kbd_if_o ;
|
output inhibit_kbd_if_o ;
|
|
|
reg [7:0] input_buffer,
|
reg [7:0] input_buffer,
|
output_buffer ;
|
output_buffer ;
|
|
|
assign tx_data_o = output_buffer ;
|
reg [7:0] wb_dat_i_sampled ;
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
|
begin
|
|
if ( wb_rst_i )
|
|
wb_dat_i_sampled <= #1 0 ;
|
|
else if ( wb_cyc_i && wb_stb_i && wb_we_i )
|
|
wb_dat_i_sampled <= #1 wb_dat_i[31:24] ;
|
|
end
|
|
|
|
`ifdef PS2_AUX
|
|
output wb_intb_o ;
|
|
reg wb_intb_o ;
|
|
|
|
input [7:0] rx_aux_data_i ;
|
|
input rx_aux_data_ready_i ;
|
|
output rx_aux_read_o ;
|
|
output [7:0] tx_aux_data_o ;
|
|
output tx_aux_write_o ;
|
|
input tx_aux_write_ack_i ;
|
|
input ps2_aux_clk_i ;
|
|
output inhibit_aux_if_o ;
|
|
reg inhibit_aux_if_o ;
|
|
reg aux_output_buffer_full ;
|
|
reg aux_input_buffer_full ;
|
|
reg interrupt2 ;
|
|
reg enable2 ;
|
|
assign tx_aux_data_o = output_buffer ;
|
|
assign tx_aux_write_o = aux_output_buffer_full ;
|
|
`else
|
|
wire aux_input_buffer_full = 1'b0 ;
|
|
wire aux_output_buffer_full = 1'b0 ;
|
|
wire interrupt2 = 1'b0 ;
|
|
wire enable2 = 1'b1 ;
|
|
`endif
|
|
|
|
assign tx_kbd_data_o = output_buffer ;
|
|
|
reg input_buffer_full, // receive buffer
|
reg input_buffer_full, // receive buffer
|
output_buffer_full ; // transmit buffer
|
output_buffer_full ; // transmit buffer
|
|
|
assign tx_write_o = output_buffer_full ;
|
assign tx_kbd_write_o = output_buffer_full ;
|
|
|
wire system_flag ;
|
wire system_flag ;
|
wire a2 = 1'b0 ;
|
wire a2 = 1'b0 ;
|
wire kbd_inhibit = ps2_clk_i ;
|
wire kbd_inhibit = ps2_kbd_clk_i ;
|
wire mouse_output_buffer_full = 1'b0 ;
|
|
wire timeout = 1'b0 ;
|
wire timeout = 1'b0 ;
|
wire perr = 1'b0 ;
|
wire perr = 1'b0 ;
|
|
|
wire [7:0] status_byte = {perr, timeout, mouse_output_buffer_full, kbd_inhibit, a2, system_flag, output_buffer_full, input_buffer_full} ;
|
wire [7:0] status_byte = {perr, timeout, aux_input_buffer_full, kbd_inhibit, a2, system_flag, output_buffer_full || aux_output_buffer_full, input_buffer_full} ;
|
|
|
reg read_input_buffer_reg ;
|
reg read_input_buffer_reg ;
|
wire read_input_buffer = wb_cyc_i && wb_stb_i && wb_sel_i[3] && !wb_ack_o && !read_input_buffer_reg && !wb_we_i && (wb_adr_i[2:0] == 3'h0) ;
|
wire read_input_buffer = wb_cyc_i && wb_stb_i && wb_sel_i[3] && !wb_ack_o && !read_input_buffer_reg && !wb_we_i && (wb_adr_i[2:0] == 3'h0) ;
|
|
|
reg write_output_buffer_reg ;
|
reg write_output_buffer_reg ;
|
wire write_output_buffer = wb_cyc_i && wb_stb_i && wb_sel_i[3] && !wb_ack_o && !write_output_buffer_reg && wb_we_i && (wb_adr_i[2:0] == 3'h0) ;
|
wire write_output_buffer = wb_cyc_i && wb_stb_i && wb_sel_i[3] && !wb_ack_o && !write_output_buffer_reg && wb_we_i && (wb_adr_i[2:0] == 3'h0) ;
|
|
|
reg read_status_register_reg ;
|
reg read_status_register_reg ;
|
wire read_status_register = wb_cyc_i && wb_stb_i && wb_sel_i[3] && !wb_ack_o && !read_status_register_reg && !wb_we_i && (wb_adr_i[2:0] == 3'h4) ;
|
wire read_status_register = wb_cyc_i && wb_stb_i && wb_sel_i[3] && !wb_ack_o && !read_status_register_reg && !wb_we_i && (wb_adr_i[2:0] == 3'h4) ;
|
|
|
reg send_command_reg ;
|
reg send_command_reg ;
|
wire send_command = wb_cyc_i && wb_stb_i && wb_sel_i[3] && !wb_ack_o && !send_command_reg && wb_we_i && (wb_adr_i[2:0] == 3'h4) ;
|
wire send_command = wb_cyc_i && wb_stb_i && wb_sel_i[3] && !wb_ack_o && !send_command_reg && wb_we_i && (wb_adr_i[2:0] == 3'h4) ;
|
|
|
reg translate_o,
|
reg translate_o,
|
enable1,
|
enable1,
|
system,
|
system,
|
interrupt1 ;
|
interrupt1 ;
|
|
|
reg inhibit_kbd_if_o ;
|
reg inhibit_kbd_if_o ;
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
inhibit_kbd_if_o <= #1 1'b1 ;
|
inhibit_kbd_if_o <= #1 1'b1 ;
|
else if ( ps2_clk_i && (rx_data_ready_i || enable1) )
|
else if ( ps2_kbd_clk_i && rx_kbd_data_ready_i && !enable1)
|
inhibit_kbd_if_o <= #1 1'b1 ;
|
inhibit_kbd_if_o <= #1 1'b1 ;
|
else if ( !rx_data_ready_i && !enable1 )
|
else if ( !rx_kbd_data_ready_i || enable1 )
|
inhibit_kbd_if_o <= #1 1'b0 ;
|
inhibit_kbd_if_o <= #1 1'b0 ;
|
|
|
end
|
end
|
|
|
wire interrupt2 = 1'b0 ;
|
`ifdef PS2_AUX
|
wire enable2 = 1'b1 ;
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
|
begin
|
|
if ( wb_rst_i )
|
|
inhibit_aux_if_o <= #1 1'b1 ;
|
|
else if ( ps2_aux_clk_i && rx_aux_data_ready_i && !enable2 )
|
|
inhibit_aux_if_o <= #1 1'b1 ;
|
|
else if ( !rx_aux_data_ready_i || enable2 )
|
|
inhibit_aux_if_o <= #1 1'b0 ;
|
|
|
|
end
|
|
`endif
|
|
|
assign system_flag = system ;
|
assign system_flag = system ;
|
|
|
wire [7:0] command_byte = {1'b0, translate_o, enable2, enable1, 1'b0, system, interrupt2, interrupt1} ;
|
wire [7:0] command_byte = {1'b0, translate_o, enable2, enable1, 1'b0, system, interrupt2, interrupt1} ;
|
|
|
reg [7:0] current_command ;
|
reg [7:0] current_command ;
|
reg [7:0] current_command_output ;
|
reg [7:0] current_command_output ;
|
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
begin
|
begin
|
send_command_reg <= #1 1'b0 ;
|
send_command_reg <= #1 1'b0 ;
|
read_input_buffer_reg <= #1 1'b0 ;
|
read_input_buffer_reg <= #1 1'b0 ;
|
write_output_buffer_reg <= #1 1'b0 ;
|
write_output_buffer_reg <= #1 1'b0 ;
|
read_status_register_reg <= #1 1'b0 ;
|
read_status_register_reg <= #1 1'b0 ;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
send_command_reg <= #1 send_command ;
|
send_command_reg <= #1 send_command ;
|
read_input_buffer_reg <= #1 read_input_buffer ;
|
read_input_buffer_reg <= #1 read_input_buffer ;
|
write_output_buffer_reg <= #1 write_output_buffer ;
|
write_output_buffer_reg <= #1 write_output_buffer ;
|
read_status_register_reg <= #1 read_status_register ;
|
read_status_register_reg <= #1 read_status_register ;
|
end
|
end
|
end
|
end
|
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
current_command <= #1 8'h0 ;
|
current_command <= #1 8'h0 ;
|
else if ( send_command_reg )
|
else if ( send_command_reg )
|
current_command <= #1 wb_dat_i[31:24] ;
|
current_command <= #1 wb_dat_i_sampled ;
|
end
|
end
|
|
|
reg current_command_valid,
|
reg current_command_valid,
|
current_command_returns_value,
|
current_command_returns_value,
|
current_command_gets_parameter,
|
current_command_gets_parameter,
|
current_command_gets_null_terminated_string ;
|
current_command_gets_null_terminated_string ;
|
|
|
reg write_output_buffer_reg_previous ;
|
reg write_output_buffer_reg_previous ;
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
write_output_buffer_reg_previous <= #1 1'b0 ;
|
write_output_buffer_reg_previous <= #1 1'b0 ;
|
else
|
else
|
write_output_buffer_reg_previous <= #1 write_output_buffer_reg ;
|
write_output_buffer_reg_previous <= #1 write_output_buffer_reg ;
|
end
|
end
|
|
|
wire invalidate_current_command =
|
wire invalidate_current_command =
|
current_command_valid &&
|
current_command_valid &&
|
(( current_command_returns_value && read_input_buffer_reg && input_buffer_full) ||
|
(( current_command_returns_value && read_input_buffer_reg && input_buffer_full) ||
|
( current_command_gets_parameter && write_output_buffer_reg_previous ) ||
|
( current_command_gets_parameter && write_output_buffer_reg_previous ) ||
|
( current_command_gets_null_terminated_string && write_output_buffer_reg_previous && (output_buffer == 8'h00) ) ||
|
( current_command_gets_null_terminated_string && write_output_buffer_reg_previous && (output_buffer == 8'h00) ) ||
|
( !current_command_returns_value && !current_command_gets_parameter && !current_command_gets_null_terminated_string )
|
( !current_command_returns_value && !current_command_gets_parameter && !current_command_gets_null_terminated_string )
|
) ;
|
) ;
|
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
current_command_valid <= #1 1'b0 ;
|
current_command_valid <= #1 1'b0 ;
|
else if ( invalidate_current_command )
|
else if ( invalidate_current_command )
|
current_command_valid <= #1 1'b0 ;
|
current_command_valid <= #1 1'b0 ;
|
else if ( send_command_reg )
|
else if ( send_command_reg )
|
current_command_valid <= #1 1'b1 ;
|
current_command_valid <= #1 1'b1 ;
|
|
|
end
|
end
|
|
|
reg write_command_byte ;
|
reg write_command_byte ;
|
reg current_command_output_valid ;
|
reg current_command_output_valid ;
|
always@(
|
always@(
|
current_command or
|
current_command or
|
command_byte or
|
command_byte or
|
write_output_buffer_reg_previous or
|
write_output_buffer_reg_previous or
|
current_command_valid or
|
current_command_valid or
|
output_buffer
|
output_buffer
|
)
|
)
|
begin
|
begin
|
current_command_returns_value = 1'b0 ;
|
current_command_returns_value = 1'b0 ;
|
current_command_gets_parameter = 1'b0 ;
|
current_command_gets_parameter = 1'b0 ;
|
current_command_gets_null_terminated_string = 1'b0 ;
|
current_command_gets_null_terminated_string = 1'b0 ;
|
current_command_output = 8'h00 ;
|
current_command_output = 8'h00 ;
|
write_command_byte = 1'b0 ;
|
write_command_byte = 1'b0 ;
|
current_command_output_valid = 1'b0 ;
|
current_command_output_valid = 1'b0 ;
|
case(current_command)
|
case(current_command)
|
8'h20:begin
|
8'h20:begin
|
current_command_returns_value = 1'b1 ;
|
current_command_returns_value = 1'b1 ;
|
current_command_output = command_byte ;
|
current_command_output = command_byte ;
|
current_command_output_valid = 1'b1 ;
|
current_command_output_valid = 1'b1 ;
|
end
|
end
|
8'h60:begin
|
8'h60:begin
|
current_command_gets_parameter = 1'b1 ;
|
current_command_gets_parameter = 1'b1 ;
|
write_command_byte = write_output_buffer_reg_previous && current_command_valid ;
|
write_command_byte = write_output_buffer_reg_previous && current_command_valid ;
|
end
|
end
|
8'hA1:begin
|
8'hA1:begin
|
current_command_returns_value = 1'b1 ;
|
current_command_returns_value = 1'b1 ;
|
current_command_output = 8'h00 ;
|
current_command_output = 8'h00 ;
|
current_command_output_valid = 1'b1 ;
|
current_command_output_valid = 1'b1 ;
|
end
|
end
|
8'hA4:begin
|
8'hA4:begin
|
current_command_returns_value = 1'b1 ;
|
current_command_returns_value = 1'b1 ;
|
current_command_output = 8'hF1 ;
|
current_command_output = 8'hF1 ;
|
current_command_output_valid = 1'b1 ;
|
current_command_output_valid = 1'b1 ;
|
end
|
end
|
8'hA5:begin
|
8'hA5:begin
|
current_command_gets_null_terminated_string = 1'b1 ;
|
current_command_gets_null_terminated_string = 1'b1 ;
|
end
|
end
|
8'hA6:begin
|
8'hA6:begin
|
end
|
end
|
8'hA7:begin
|
8'hA7:begin
|
end
|
end
|
8'hA8:begin
|
8'hA8:begin
|
end
|
end
|
8'hA9:begin
|
8'hA9:begin
|
current_command_returns_value = 1'b1 ;
|
current_command_returns_value = 1'b1 ;
|
current_command_output = 8'h02 ; // clock line stuck high
|
|
current_command_output_valid = 1'b1 ;
|
current_command_output_valid = 1'b1 ;
|
|
`ifdef PS2_AUX
|
|
current_command_output = 8'h00 ; // interface OK
|
|
`else
|
|
current_command_output = 8'h02 ; // clock line stuck high
|
|
`endif
|
end
|
end
|
8'hAA:begin
|
8'hAA:begin
|
current_command_returns_value = 1'b1 ;
|
current_command_returns_value = 1'b1 ;
|
current_command_output = 8'h55 ;
|
current_command_output = 8'h55 ;
|
current_command_output_valid = 1'b1 ;
|
current_command_output_valid = 1'b1 ;
|
end
|
end
|
8'hAB:begin
|
8'hAB:begin
|
current_command_returns_value = 1'b1 ;
|
current_command_returns_value = 1'b1 ;
|
current_command_output = 8'h00 ;
|
current_command_output = 8'h00 ;
|
current_command_output_valid = 1'b1 ;
|
current_command_output_valid = 1'b1 ;
|
end
|
end
|
8'hAD:begin
|
8'hAD:begin
|
end
|
end
|
8'hAE:begin
|
8'hAE:begin
|
end
|
end
|
8'hAF:begin
|
8'hAF:begin
|
current_command_returns_value = 1'b1 ;
|
current_command_returns_value = 1'b1 ;
|
current_command_output = 8'h00 ;
|
current_command_output = 8'h00 ;
|
current_command_output_valid = 1'b1 ;
|
current_command_output_valid = 1'b1 ;
|
end
|
end
|
8'hC0:begin
|
8'hC0:begin
|
current_command_returns_value = 1'b1 ;
|
current_command_returns_value = 1'b1 ;
|
current_command_output = 8'hFF ;
|
current_command_output = 8'hFF ;
|
current_command_output_valid = 1'b1 ;
|
current_command_output_valid = 1'b1 ;
|
end
|
end
|
8'hC1:begin
|
8'hC1:begin
|
end
|
end
|
8'hC2:begin
|
8'hC2:begin
|
end
|
end
|
8'hD0:begin
|
8'hD0:begin
|
current_command_returns_value = 1'b1 ;
|
current_command_returns_value = 1'b1 ;
|
current_command_output = 8'h01 ; // only system reset bit is 1
|
current_command_output = 8'h01 ; // only system reset bit is 1
|
current_command_output_valid = 1'b1 ;
|
current_command_output_valid = 1'b1 ;
|
end
|
end
|
8'hD1:begin
|
8'hD1:begin
|
current_command_gets_parameter = 1'b1 ;
|
current_command_gets_parameter = 1'b1 ;
|
end
|
end
|
8'hD2:begin
|
8'hD2:begin
|
current_command_returns_value = 1'b1 ;
|
current_command_returns_value = 1'b1 ;
|
current_command_gets_parameter = 1'b1 ;
|
current_command_gets_parameter = 1'b1 ;
|
current_command_output = output_buffer ;
|
current_command_output = output_buffer ;
|
current_command_output_valid = write_output_buffer_reg_previous ;
|
current_command_output_valid = write_output_buffer_reg_previous ;
|
end
|
end
|
8'hD3:begin
|
8'hD3:begin
|
current_command_gets_parameter = 1'b1 ;
|
current_command_gets_parameter = 1'b1 ;
|
|
`ifdef PS2_AUX
|
|
current_command_returns_value = 1'b1 ;
|
|
current_command_output = output_buffer ;
|
|
current_command_output_valid = write_output_buffer_reg_previous ;
|
|
`endif
|
end
|
end
|
8'hD4:begin
|
8'hD4:begin
|
current_command_gets_parameter = 1'b1 ;
|
current_command_gets_parameter = 1'b1 ;
|
end
|
end
|
8'hE0:begin
|
8'hE0:begin
|
current_command_returns_value = 1'b1 ;
|
current_command_returns_value = 1'b1 ;
|
current_command_output = 8'hFF ;
|
current_command_output = 8'hFF ;
|
current_command_output_valid = 1'b1 ;
|
current_command_output_valid = 1'b1 ;
|
end
|
end
|
endcase
|
endcase
|
end
|
end
|
|
|
reg cyc_i_previous ;
|
reg cyc_i_previous ;
|
reg stb_i_previous ;
|
reg stb_i_previous ;
|
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
begin
|
begin
|
cyc_i_previous <= #1 1'b0 ;
|
cyc_i_previous <= #1 1'b0 ;
|
stb_i_previous <= #1 1'b0 ;
|
stb_i_previous <= #1 1'b0 ;
|
end
|
end
|
else if ( wb_ack_o )
|
else if ( wb_ack_o )
|
begin
|
begin
|
cyc_i_previous <= #1 1'b0 ;
|
cyc_i_previous <= #1 1'b0 ;
|
stb_i_previous <= #1 1'b0 ;
|
stb_i_previous <= #1 1'b0 ;
|
end
|
end
|
else
|
else
|
begin
|
begin
|
cyc_i_previous <= #1 wb_cyc_i ;
|
cyc_i_previous <= #1 wb_cyc_i ;
|
stb_i_previous <= #1 wb_stb_i ;
|
stb_i_previous <= #1 wb_stb_i ;
|
end
|
end
|
|
|
end
|
end
|
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
wb_ack_o <= #1 1'b0 ;
|
wb_ack_o <= #1 1'b0 ;
|
else if ( wb_ack_o )
|
else if ( wb_ack_o )
|
wb_ack_o <= #1 1'b0 ;
|
wb_ack_o <= #1 1'b0 ;
|
else
|
else
|
wb_ack_o <= #1 cyc_i_previous && stb_i_previous ;
|
wb_ack_o <= #1 cyc_i_previous && stb_i_previous ;
|
end
|
end
|
|
|
reg [31:0] wb_dat_o ;
|
reg [31:0] wb_dat_o ;
|
wire wb_read = read_input_buffer_reg || read_status_register_reg ;
|
wire wb_read = read_input_buffer_reg || read_status_register_reg ;
|
|
|
wire [7:0] output_data = read_status_register_reg ? status_byte : input_buffer ;
|
wire [7:0] output_data = read_status_register_reg ? status_byte : input_buffer ;
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
wb_dat_o <= #1 32'h0 ;
|
wb_dat_o <= #1 32'h0 ;
|
else if ( wb_read )
|
else if ( wb_read )
|
wb_dat_o <= #1 {4{output_data}} ;
|
wb_dat_o <= #1 {4{output_data}} ;
|
end
|
end
|
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
output_buffer_full <= #1 1'b0 ;
|
output_buffer_full <= #1 1'b0 ;
|
else if ( output_buffer_full && tx_write_ack_i)
|
else if ( output_buffer_full && tx_kbd_write_ack_i || enable1)
|
output_buffer_full <= #1 1'b0 ;
|
output_buffer_full <= #1 1'b0 ;
|
else
|
else
|
output_buffer_full <= #1 write_output_buffer_reg && (!current_command_valid || (!current_command_gets_parameter && !current_command_gets_null_terminated_string)) ;
|
output_buffer_full <= #1 write_output_buffer_reg && (!current_command_valid || (!current_command_gets_parameter && !current_command_gets_null_terminated_string)) ;
|
end
|
end
|
|
|
|
`ifdef PS2_AUX
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
|
begin
|
|
if ( wb_rst_i )
|
|
aux_output_buffer_full <= #1 1'b0 ;
|
|
else if ( aux_output_buffer_full && tx_aux_write_ack_i || enable2)
|
|
aux_output_buffer_full <= #1 1'b0 ;
|
|
else
|
|
aux_output_buffer_full <= #1 write_output_buffer_reg && current_command_valid && (current_command == 8'hD4) ;
|
|
end
|
|
`endif
|
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
output_buffer <= #1 8'h00 ;
|
output_buffer <= #1 8'h00 ;
|
else if ( write_output_buffer_reg )
|
else if ( write_output_buffer_reg )
|
output_buffer <= #1 wb_dat_i[31:24] ;
|
output_buffer <= #1 wb_dat_i_sampled ;
|
end
|
end
|
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
begin
|
begin
|
translate_o <= #1 1'b0 ;
|
translate_o <= #1 1'b0 ;
|
system <= #1 1'b0 ;
|
system <= #1 1'b0 ;
|
interrupt1 <= #1 1'b0 ;
|
interrupt1 <= #1 1'b0 ;
|
|
`ifdef PS2_AUX
|
|
interrupt2 <= #1 1'b0 ;
|
|
`endif
|
end
|
end
|
else if ( write_command_byte )
|
else if ( write_command_byte )
|
begin
|
begin
|
translate_o <= #1 output_buffer[6] ;
|
translate_o <= #1 output_buffer[6] ;
|
system <= #1 output_buffer[2] ;
|
system <= #1 output_buffer[2] ;
|
interrupt1 <= #1 output_buffer[0] ;
|
interrupt1 <= #1 output_buffer[0] ;
|
|
`ifdef PS2_AUX
|
|
interrupt2 <= #1 output_buffer[1] ;
|
|
`endif
|
end
|
end
|
end
|
end
|
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
enable1 <= #1 1'b1 ;
|
enable1 <= #1 1'b1 ;
|
else if ( current_command_valid && (current_command == 8'hAE) )
|
else if ( current_command_valid && (current_command == 8'hAE) )
|
enable1 <= #1 1'b0 ;
|
enable1 <= #1 1'b0 ;
|
else if ( current_command_valid && (current_command == 8'hAD) )
|
else if ( current_command_valid && (current_command == 8'hAD) )
|
enable1 <= #1 1'b1 ;
|
enable1 <= #1 1'b1 ;
|
else if ( write_command_byte )
|
else if ( write_command_byte )
|
enable1 <= #1 output_buffer[4] ;
|
enable1 <= #1 output_buffer[4] ;
|
|
|
end
|
end
|
|
|
wire write_input_buffer_from_command = current_command_valid && current_command_returns_value && current_command_output_valid ;
|
`ifdef PS2_AUX
|
reg write_input_buffer_from_command_reg ;
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
write_input_buffer_from_command_reg <= #1 1'b0 ;
|
enable2 <= #1 1'b1 ;
|
else
|
else if ( current_command_valid && (current_command == 8'hA8) )
|
write_input_buffer_from_command_reg <= #1 write_input_buffer_from_command ;
|
enable2 <= #1 1'b0 ;
|
|
else if ( current_command_valid && (current_command == 8'hA7) )
|
|
enable2 <= #1 1'b1 ;
|
|
else if ( write_command_byte )
|
|
enable2 <= #1 output_buffer[5] ;
|
|
|
end
|
end
|
|
`endif
|
|
|
|
wire write_input_buffer_from_command = current_command_valid && current_command_returns_value && current_command_output_valid ;
|
|
wire write_input_buffer_from_kbd = !input_buffer_full && rx_kbd_data_ready_i && !enable1 && !current_command_valid ;
|
|
|
|
`ifdef PS2_AUX
|
|
wire write_input_buffer_from_aux = !input_buffer_full && rx_aux_data_ready_i && !enable2 && !current_command_valid && !write_input_buffer_from_kbd ;
|
|
`endif
|
|
|
|
wire load_input_buffer_value =
|
|
write_input_buffer_from_command
|
|
||
|
|
write_input_buffer_from_kbd
|
|
`ifdef PS2_AUX
|
|
||
|
|
write_input_buffer_from_aux
|
|
`endif
|
|
;
|
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
input_buffer_full <= #1 1'b0 ;
|
input_buffer_full <= #1 1'b0 ;
|
else if ( read_input_buffer_reg )
|
else if ( read_input_buffer_reg )
|
input_buffer_full <= #1 1'b0 ;
|
input_buffer_full <= #1 1'b0 ;
|
else if ( (write_input_buffer_from_command && !write_input_buffer_from_command_reg) || (rx_data_ready_i && !enable1) )
|
else if ( load_input_buffer_value )
|
input_buffer_full <= #1 1'b1 ;
|
input_buffer_full <= #1 1'b1 ;
|
end
|
end
|
|
|
|
`ifdef PS2_AUX
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
|
begin
|
|
if ( wb_rst_i )
|
|
aux_input_buffer_full <= #1 1'b0 ;
|
|
else if ( read_input_buffer_reg )
|
|
aux_input_buffer_full <= #1 1'b0 ;
|
|
else if ( write_input_buffer_from_aux || (write_input_buffer_from_command && (current_command == 8'hD3)) )
|
|
aux_input_buffer_full <= #1 1'b1 ;
|
|
end
|
|
`endif
|
|
|
reg input_buffer_filled_from_command ;
|
reg input_buffer_filled_from_command ;
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
input_buffer_filled_from_command <= #1 1'b0 ;
|
input_buffer_filled_from_command <= #1 1'b0 ;
|
else if ( read_input_buffer_reg )
|
else if ( read_input_buffer_reg )
|
input_buffer_filled_from_command <= #1 1'b0 ;
|
input_buffer_filled_from_command <= #1 1'b0 ;
|
else if ( write_input_buffer_from_command && !write_input_buffer_from_command_reg)
|
else if ( write_input_buffer_from_command )
|
input_buffer_filled_from_command <= #1 1'b1 ;
|
input_buffer_filled_from_command <= #1 1'b1 ;
|
end
|
end
|
|
|
reg rx_data_ready_reg ;
|
`ifdef PS2_AUX
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
reg [7:0] value_to_load_in_input_buffer ;
|
|
always@
|
|
(
|
|
write_input_buffer_from_command
|
|
or
|
|
current_command_output
|
|
or
|
|
rx_scancode_i
|
|
or
|
|
write_input_buffer_from_kbd
|
|
or
|
|
rx_aux_data_i
|
|
)
|
begin
|
begin
|
if ( wb_rst_i )
|
case ({write_input_buffer_from_command, write_input_buffer_from_kbd})
|
rx_data_ready_reg <= #1 1'b0 ;
|
2'b10,
|
else if ( input_buffer_filled_from_command )
|
2'b11 : value_to_load_in_input_buffer = current_command_output ;
|
rx_data_ready_reg <= #1 1'b0 ;
|
2'b01 : value_to_load_in_input_buffer = rx_scancode_i ;
|
else
|
2'b00 : value_to_load_in_input_buffer = rx_aux_data_i ;
|
rx_data_ready_reg <= #1 rx_data_ready_i ;
|
endcase
|
end
|
end
|
|
|
wire input_buffer_value_change = (rx_data_ready_i && !rx_data_ready_reg && !enable1) || (write_input_buffer_from_command && !write_input_buffer_from_command_reg) ;
|
`else
|
|
wire [7:0] value_to_load_in_input_buffer = write_input_buffer_from_command ? current_command_output : rx_scancode_i ;
|
|
`endif
|
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
input_buffer <= #1 8'h00 ;
|
input_buffer <= #1 8'h00 ;
|
else if ( input_buffer_value_change )
|
else if ( load_input_buffer_value )
|
input_buffer <= #1 current_command_valid && current_command_returns_value ? current_command_output : rx_scancode_i ;
|
input_buffer <= #1 value_to_load_in_input_buffer ;
|
end
|
end
|
|
|
assign rx_read_o = enable1 || rx_data_ready_i && !input_buffer_filled_from_command && read_input_buffer_reg ;
|
assign rx_kbd_read_o = rx_kbd_data_ready_i &&
|
|
( enable1
|
|
||
|
|
( read_input_buffer_reg
|
|
&&
|
|
input_buffer_full
|
|
&&
|
|
!input_buffer_filled_from_command
|
|
`ifdef PS2_AUX
|
|
&&
|
|
!aux_input_buffer_full
|
|
`endif
|
|
)
|
|
);
|
|
|
|
`ifdef PS2_AUX
|
|
assign rx_aux_read_o = rx_aux_data_ready_i &&
|
|
( enable2 ||
|
|
( read_input_buffer_reg
|
|
&&
|
|
input_buffer_full
|
|
&&
|
|
aux_input_buffer_full
|
|
&&
|
|
!input_buffer_filled_from_command
|
|
)
|
|
);
|
|
`endif
|
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
begin
|
begin
|
if ( wb_rst_i )
|
if ( wb_rst_i )
|
wb_int_o <= #1 1'b0 ;
|
wb_int_o <= #1 1'b0 ;
|
else if ( read_input_buffer_reg || enable1 || !interrupt1)
|
else if ( read_input_buffer_reg || enable1 || !interrupt1)
|
wb_int_o <= #1 1'b0 ;
|
wb_int_o <= #1 1'b0 ;
|
else
|
else
|
wb_int_o <= #1 input_buffer_full ;
|
wb_int_o <= #1 input_buffer_full
|
|
`ifdef PS2_AUX
|
|
&&
|
|
!aux_input_buffer_full
|
|
`endif
|
|
;
|
|
end
|
|
|
|
`ifdef PS2_AUX
|
|
always@(posedge wb_clk_i or posedge wb_rst_i)
|
|
begin
|
|
if ( wb_rst_i )
|
|
wb_intb_o <= #1 1'b0 ;
|
|
else if ( read_input_buffer_reg || enable2 || !interrupt2)
|
|
wb_intb_o <= #1 1'b0 ;
|
|
else
|
|
wb_intb_o <= #1 input_buffer_full
|
|
&&
|
|
aux_input_buffer_full
|
|
;
|
end
|
end
|
|
`endif
|
|
|
endmodule // ps2_wb_if
|
endmodule // ps2_wb_if
|
|
|