URL
https://opencores.org/ocsvn/ps2/ps2/trunk
Subversion Repositories ps2
[/] [ps2/] [tags/] [rel_2/] [bench/] [verilog/] [ps2_keyboard_model.v] - Rev 2
Go to most recent revision | Compare with Previous | Blame | View Log
////////////////////////////////////////////////////////////////////// //// //// //// ps2_keyboard_model.v //// //// //// //// This file is part of the "ps2" project //// //// http://www.opencores.org/cores/ps2/ //// //// //// //// Author(s): //// //// - mihad@opencores.org //// //// - Miha Dolenc //// //// //// //// All additional information is avaliable in the README.txt //// //// file. //// //// //// //// //// ////////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org //// //// //// //// This source file may be used and distributed without //// //// restriction provided that this copyright statement is not //// //// removed from the file and that any derivative work contains //// //// the original copyright notice and the associated disclaimer. //// //// //// //// This source file is free software; you can redistribute it //// //// and/or modify it under the terms of the GNU Lesser General //// //// Public License as published by the Free Software Foundation; //// //// either version 2.1 of the License, or (at your option) any //// //// later version. //// //// //// //// This source is distributed in the hope that it will be //// //// useful, but WITHOUT ANY WARRANTY; without even the implied //// //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// //// PURPOSE. See the GNU Lesser General Public License for more //// //// details. //// //// //// //// You should have received a copy of the GNU Lesser General //// //// Public License along with this source; if not, download it //// //// from http://www.opencores.org/lgpl.shtml //// //// //// ////////////////////////////////////////////////////////////////////// // // CVS Revision History // // $Log: not supported by cvs2svn $ // `include "timescale.v" module ps2_keyboard_model ( kbd_clk_io, kbd_data_io, last_char_received_o, char_valid_o ); parameter [31:0] kbd_clk_period = 50000; // chould be between 33 and 50 us to generate the clock between 30 and 20 kHz inout kbd_clk_io, kbd_data_io ; output [7:0] last_char_received_o ; reg [7:0] last_char_received_o ; output char_valid_o ; reg char_valid_o ; reg kbd_clk, kbd_data ; assign kbd_clk_io = kbd_clk ? 1'bz : 1'b0 ; assign kbd_data_io = kbd_data ? 1'bz : 1'b0 ; reg receiving ; initial begin kbd_clk = 1'b1 ; kbd_data = 1'b1 ; last_char_received_o = 0 ; char_valid_o = 0 ; receiving = 0 ; end always@(kbd_data_io or kbd_clk_io) begin // check if host is driving keyboard data low and doesn't drive clock if ( !kbd_data_io && kbd_data && kbd_clk_io) begin // wait for half of clock period #(kbd_clk_period/2) ; // state hasn't changed - host wishes to send data - go receiving if ( !kbd_data_io && kbd_data && kbd_clk_io) kbd_receive_char(last_char_received_o) ; end end task kbd_send_char ; input [7:0] char ; output transmited_ok ; output severe_error ; reg [10:0] tx_reg ; integer i ; begin:main severe_error = 1'b0 ; transmited_ok = 1'b0 ; wait ( !receiving ) ; tx_reg = { 1'b1, !(^char), char, 1'b0 } ; fork begin:wait_for_idle wait( (kbd_clk_io === 1'b1) && (kbd_data_io === 1'b1) ) ; // disable timeout ; end /*begin:timeout #(256 * kbd_clk_period) ; $display("Error! Keyboard bus did not go idle in 256 keyboard clock cycles time!") ; severe_error = 1'b1 ; transmited_ok = 1'b0 ; disable main ; end*/ join #(kbd_clk_period/2) ; if ( !kbd_clk_io ) begin transmited_ok = 1'b0 ; kbd_data = 1'b1 ; disable main ; end i = 0 ; while ( i < 11 ) begin kbd_data = tx_reg[i] ; #(kbd_clk_period/2) ; if ( !kbd_clk_io ) begin transmited_ok = 1'b0 ; kbd_data = 1'b1 ; disable main ; end kbd_clk = 1'b0 ; i = i + 1 ; #(kbd_clk_period/2) ; kbd_clk = 1'b1 ; end if ( i == 11 ) transmited_ok = 1'b1 ; end endtask // kbd_send_char task kbd_receive_char; output [7:0] char ; reg parity ; integer i ; reg stop_bit_received ; begin:main i = 0 ; stop_bit_received = 1 ; receiving = 1 ; #(kbd_clk_period/2) ; while ( i < 11 ) begin if ( !kbd_clk_io ) begin receiving = 0 ; disable main ; end kbd_clk = 1'b0 ; #(kbd_clk_period/2) ; kbd_clk = 1'b1 ; if ( i > 0 ) begin if ( i <= 8 ) char[i - 1] = kbd_data_io ; else if ( i == 9 ) begin parity = kbd_data_io ; if ( parity !== ( !(^char) ) ) $display("Invalid parity bit received") ; end else begin if ( kbd_data_io !== 1'b1 ) begin i = i - 1 ; stop_bit_received = 0 ; end else begin kbd_data = 1'b0 ; end end end i = i + 1 ; #(kbd_clk_period/2) ; end if ( !kbd_clk_io ) begin receiving = 0 ; disable main ; end kbd_clk = 1'b0 ; #(kbd_clk_period/2) ; kbd_clk <= 1'b1 ; kbd_data <= 1'b1 ; if ( stop_bit_received ) begin char_valid_o = !char_valid_o ; end receiving = 0 ; end endtask // kbd_receive_char endmodule // ps2_keyboard_model
Go to most recent revision | Compare with Previous | Blame | View Log