OpenCores
URL https://opencores.org/ocsvn/m1_core/m1_core/trunk

Subversion Repositories m1_core

[/] [m1_core/] [trunk/] [hdl/] [behav/] [ps2_keyboard_model/] [ps2_keyboard_model.v] - Blame information for rev 54

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 36 fafa1971
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  ps2_keyboard_model.v                                        ////
4
////                                                              ////
5
////  This file is part of the "ps2" project                      ////
6
////  http://www.opencores.org/cores/ps2/                         ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - mihad@opencores.org                                   ////
10
////      - Miha Dolenc                                           ////
11
////                                                              ////
12
////  All additional information is avaliable in the README.txt   ////
13
////  file.                                                       ////
14
////                                                              ////
15
////                                                              ////
16
//////////////////////////////////////////////////////////////////////
17
////                                                              ////
18
//// Copyright (C) 2000 Miha Dolenc, mihad@opencores.org          ////
19
////                                                              ////
20
//// This source file may be used and distributed without         ////
21
//// restriction provided that this copyright statement is not    ////
22
//// removed from the file and that any derivative work contains  ////
23
//// the original copyright notice and the associated disclaimer. ////
24
////                                                              ////
25
//// This source file is free software; you can redistribute it   ////
26
//// and/or modify it under the terms of the GNU Lesser General   ////
27
//// Public License as published by the Free Software Foundation; ////
28
//// either version 2.1 of the License, or (at your option) any   ////
29
//// later version.                                               ////
30
////                                                              ////
31
//// This source is distributed in the hope that it will be       ////
32
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
33
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
34
//// PURPOSE.  See the GNU Lesser General Public License for more ////
35
//// details.                                                     ////
36
////                                                              ////
37
//// You should have received a copy of the GNU Lesser General    ////
38
//// Public License along with this source; if not, download it   ////
39
//// from http://www.opencores.org/lgpl.shtml                     ////
40
////                                                              ////
41
//////////////////////////////////////////////////////////////////////
42
//
43
// CVS Revision History
44
//
45
// $Log: not supported by cvs2svn $
46
// Revision 1.3  2003/10/03 10:16:50  primozs
47
// support for configurable devider added
48
//
49
// Revision 1.2  2002/04/09 13:15:16  mihad
50
// Wrong acknowledge generation during receiving repaired
51
//
52
// Revision 1.1.1.1  2002/02/18 16:16:55  mihad
53
// Initial project import - working
54
//
55
//
56
 
57
`include "timescale.v"
58
 
59
module ps2_keyboard_model
60
(
61
    kbd_clk_io,
62
    kbd_data_io,
63
    last_char_received_o,
64
    char_valid_o
65
);
66
 
67
parameter [31:0] kbd_clk_period = 50000; // chould be between 33 and 50 us to generate the clock between 30 and 20 kHz
68
 
69
inout kbd_clk_io,
70
      kbd_data_io ;
71
 
72
output [7:0] last_char_received_o ;
73
reg    [7:0] last_char_received_o ;
74
 
75
output char_valid_o ;
76
reg    char_valid_o ;
77
 
78
reg kbd_clk,
79
    kbd_data ;
80
 
81
assign kbd_clk_io  = kbd_clk ? 1'bz : 1'b0 ;
82
assign kbd_data_io = kbd_data ? 1'bz : 1'b0 ;
83
 
84
reg receiving ;
85
initial
86
begin
87
    kbd_clk  = 1'b1 ;
88
    kbd_data = 1'b1 ;
89
 
90
    last_char_received_o = 0 ;
91
    char_valid_o         = 0 ;
92
 
93
    receiving = 0 ;
94
end
95
 
96
always@(kbd_data_io or kbd_clk_io)
97
begin
98
    // check if host is driving keyboard data low and doesn't drive clock
99
    if ( !kbd_data_io && kbd_data && kbd_clk_io)
100
    begin
101
        // wait for half of clock period
102
        #(kbd_clk_period/2) ;
103
 
104
        // state hasn't changed - host wishes to send data - go receiving
105
        if ( !kbd_data_io && kbd_data && kbd_clk_io)
106
            kbd_receive_char(last_char_received_o) ;
107
    end
108
end
109
 
110
task kbd_send_char ;
111
    input [7:0] char ;
112
    output      transmited_ok ;
113
    output      severe_error ;
114
    reg   [10:0] tx_reg ;
115
    integer i ;
116
begin:main
117
    severe_error  = 1'b0 ;
118
    transmited_ok = 1'b0 ;
119
 
120
    wait ( !receiving ) ;
121
 
122
    tx_reg = { 1'b1, !(^char), char, 1'b0 } ;
123
 
124
    fork
125
    begin:wait_for_idle
126
        wait( (kbd_clk_io === 1'b1) && (kbd_data_io === 1'b1) ) ;
127
    //    disable timeout ;
128
    end
129
    /*begin:timeout
130
        #(256 * kbd_clk_period) ;
131
        $display("Error! Keyboard bus did not go idle in 256 keyboard clock cycles time!") ;
132
        severe_error  = 1'b1 ;
133
        transmited_ok = 1'b0 ;
134
        disable main ;
135
    end*/
136
    join
137
 
138
    #(kbd_clk_period/2) ;
139
    if ( !kbd_clk_io )
140
    begin
141
        transmited_ok = 1'b0 ;
142
        kbd_data = 1'b1 ;
143
        disable main ;
144
    end
145
 
146
    i = 0 ;
147
    while ( i < 11 )
148
    begin
149
        kbd_data = tx_reg[i] ;
150
 
151
        #(kbd_clk_period/2) ;
152
 
153
        if ( !kbd_clk_io )
154
        begin
155
            transmited_ok = 1'b0 ;
156
            kbd_data = 1'b1 ;
157
            disable main ;
158
        end
159
 
160
        kbd_clk = 1'b0 ;
161
 
162
        i = i + 1 ;
163
 
164
        #(kbd_clk_period/2) ;
165
        kbd_clk = 1'b1 ;
166
    end
167
 
168
    if ( i == 11 )
169
        transmited_ok = 1'b1 ;
170
end
171
endtask // kbd_send_char
172
 
173
task kbd_receive_char;
174
    output [7:0] char ;
175
    reg          parity ;
176
    integer i ;
177
    reg          stop_clocking ;
178
begin:main
179
    i = 0 ;
180
    receiving = 1 ;
181
    stop_clocking = 1'b0 ;
182
 
183
    #(kbd_clk_period/2) ;
184
 
185
    while ( !stop_clocking )
186
    begin
187
 
188
        if ( !kbd_clk_io )
189
        begin
190
            receiving = 0 ;
191
            disable main ;
192
        end
193
 
194
        kbd_clk = 1'b0 ;
195
 
196
        #(kbd_clk_period/2) ;
197
 
198
        kbd_clk = 1'b1 ;
199
 
200
        if ( i > 0 )
201
        begin
202
            if ( i <= 8 )
203
                char[i - 1] = kbd_data_io ;
204
            else if ( i == 9 )
205
            begin
206
                parity = kbd_data_io ;
207
                if ( parity !== ( !(^char) ) )
208
                    $display("Invalid parity bit received") ;
209
            end
210
        end
211
 
212
        i = i + 1 ;
213
        #(kbd_clk_period/4) ;
214
        if ( i > 9 )
215
        begin
216
            if ( kbd_data_io === 1'b1 )
217
            begin
218
                kbd_data <= 1'b0 ;
219
                stop_clocking = 1'b1 ;
220
            end
221
        end
222
 
223
        #(kbd_clk_period/4) ;
224
    end
225
 
226
    kbd_clk  = 1'b0 ;
227
 
228
    #(kbd_clk_period/2) ;
229
    kbd_clk  <= 1'b1 ;
230
    kbd_data <= 1'b1 ;
231
 
232
    receiving = 0 ;
233
 
234
    if ( i === 10 )
235
    begin
236
        char_valid_o = !char_valid_o ;
237
    end
238
end
239
endtask // kbd_receive_char
240
 
241
 
242
time last_clk_low;
243
time last_clk_diference;
244
 
245
 
246
 
247
initial
248
begin
249
last_clk_low  =0;
250
last_clk_diference =0;
251
 
252
end
253
 
254
always @(negedge kbd_clk_io)
255
 
256
  begin:low_time_check
257
   if (kbd_clk == 1)
258
    begin
259
    last_clk_low =$time;
260
    fork
261
    begin
262
    #61000
263
    $display(" clock low more then 61us");
264
    $display("Time %t", $time) ;
265
    #30000
266
    $display("error clock low more then 90usec");
267
    $display("Time %t", $time) ;
268
    $stop;
269
    end
270
    begin
271
    @(posedge kbd_clk_io);
272
    disable low_time_check;
273
    end
274
    join
275
     end
276
   end
277
 
278
 
279
 
280
 
281
always @(posedge kbd_clk_io )
282
  begin
283
  if (last_clk_low >0 )
284
  begin
285
  last_clk_diference = $time - last_clk_low;
286
  if (last_clk_diference < 60000)
287
  begin
288
  $display("error time< 60u");
289
  #100 $stop;
290
  end
291
  end
292
  end
293
 
294
 
295
 
296
 
297
 
298
 
299
endmodule // ps2_keyboard_model

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.