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

Subversion Repositories ps2

[/] [ps2/] [tags/] [rel_6/] [bench/] [verilog/] [ps2_keyboard_model.v] - Blame information for rev 26

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 mihad
//////////////////////////////////////////////////////////////////////
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 24 primozs
// Revision 1.2  2002/04/09 13:15:16  mihad
47
// Wrong acknowledge generation during receiving repaired
48
//
49 10 mihad
// Revision 1.1.1.1  2002/02/18 16:16:55  mihad
50
// Initial project import - working
51 2 mihad
//
52 10 mihad
//
53 2 mihad
 
54
`include "timescale.v"
55
 
56
module ps2_keyboard_model
57
(
58
    kbd_clk_io,
59
    kbd_data_io,
60
    last_char_received_o,
61
    char_valid_o
62
);
63
 
64
parameter [31:0] kbd_clk_period = 50000; // chould be between 33 and 50 us to generate the clock between 30 and 20 kHz
65
 
66
inout kbd_clk_io,
67
      kbd_data_io ;
68
 
69
output [7:0] last_char_received_o ;
70
reg    [7:0] last_char_received_o ;
71
 
72
output char_valid_o ;
73
reg    char_valid_o ;
74
 
75
reg kbd_clk,
76
    kbd_data ;
77
 
78
assign kbd_clk_io  = kbd_clk ? 1'bz : 1'b0 ;
79
assign kbd_data_io = kbd_data ? 1'bz : 1'b0 ;
80
 
81
reg receiving ;
82
initial
83
begin
84
    kbd_clk  = 1'b1 ;
85
    kbd_data = 1'b1 ;
86
 
87
    last_char_received_o = 0 ;
88
    char_valid_o         = 0 ;
89
 
90
    receiving = 0 ;
91
end
92
 
93
always@(kbd_data_io or kbd_clk_io)
94
begin
95
    // check if host is driving keyboard data low and doesn't drive clock
96
    if ( !kbd_data_io && kbd_data && kbd_clk_io)
97
    begin
98
        // wait for half of clock period
99
        #(kbd_clk_period/2) ;
100
 
101
        // state hasn't changed - host wishes to send data - go receiving
102
        if ( !kbd_data_io && kbd_data && kbd_clk_io)
103
            kbd_receive_char(last_char_received_o) ;
104
    end
105
end
106
 
107
task kbd_send_char ;
108
    input [7:0] char ;
109
    output      transmited_ok ;
110
    output      severe_error ;
111
    reg   [10:0] tx_reg ;
112
    integer i ;
113
begin:main
114
    severe_error  = 1'b0 ;
115
    transmited_ok = 1'b0 ;
116
 
117
    wait ( !receiving ) ;
118
 
119
    tx_reg = { 1'b1, !(^char), char, 1'b0 } ;
120
 
121
    fork
122
    begin:wait_for_idle
123
        wait( (kbd_clk_io === 1'b1) && (kbd_data_io === 1'b1) ) ;
124
    //    disable timeout ;
125
    end
126
    /*begin:timeout
127
        #(256 * kbd_clk_period) ;
128
        $display("Error! Keyboard bus did not go idle in 256 keyboard clock cycles time!") ;
129
        severe_error  = 1'b1 ;
130
        transmited_ok = 1'b0 ;
131
        disable main ;
132
    end*/
133
    join
134
 
135
    #(kbd_clk_period/2) ;
136
    if ( !kbd_clk_io )
137
    begin
138
        transmited_ok = 1'b0 ;
139
        kbd_data = 1'b1 ;
140
        disable main ;
141
    end
142
 
143
    i = 0 ;
144
    while ( i < 11 )
145
    begin
146
        kbd_data = tx_reg[i] ;
147
 
148
        #(kbd_clk_period/2) ;
149
 
150
        if ( !kbd_clk_io )
151
        begin
152
            transmited_ok = 1'b0 ;
153
            kbd_data = 1'b1 ;
154
            disable main ;
155
        end
156
 
157
        kbd_clk = 1'b0 ;
158
 
159
        i = i + 1 ;
160
 
161
        #(kbd_clk_period/2) ;
162
        kbd_clk = 1'b1 ;
163
    end
164
 
165
    if ( i == 11 )
166
        transmited_ok = 1'b1 ;
167
end
168
endtask // kbd_send_char
169
 
170
task kbd_receive_char;
171
    output [7:0] char ;
172
    reg          parity ;
173
    integer i ;
174 10 mihad
    reg          stop_clocking ;
175 2 mihad
begin:main
176
    i = 0 ;
177
    receiving = 1 ;
178 10 mihad
    stop_clocking = 1'b0 ;
179
 
180 2 mihad
    #(kbd_clk_period/2) ;
181
 
182 10 mihad
    while ( !stop_clocking )
183 2 mihad
    begin
184
 
185
        if ( !kbd_clk_io )
186
        begin
187
            receiving = 0 ;
188
            disable main ;
189
        end
190
 
191
        kbd_clk = 1'b0 ;
192
 
193
        #(kbd_clk_period/2) ;
194
 
195
        kbd_clk = 1'b1 ;
196
 
197
        if ( i > 0 )
198
        begin
199
            if ( i <= 8 )
200
                char[i - 1] = kbd_data_io ;
201
            else if ( i == 9 )
202
            begin
203
                parity = kbd_data_io ;
204
                if ( parity !== ( !(^char) ) )
205
                    $display("Invalid parity bit received") ;
206
            end
207 10 mihad
        end
208
 
209
        i = i + 1 ;
210
        #(kbd_clk_period/4) ;
211
        if ( i > 9 )
212
        begin
213
            if ( kbd_data_io === 1'b1 )
214 2 mihad
            begin
215 10 mihad
                kbd_data <= 1'b0 ;
216
                stop_clocking = 1'b1 ;
217 2 mihad
            end
218
        end
219
 
220 10 mihad
        #(kbd_clk_period/4) ;
221 2 mihad
    end
222
 
223
    kbd_clk  = 1'b0 ;
224
 
225
    #(kbd_clk_period/2) ;
226
    kbd_clk  <= 1'b1 ;
227
    kbd_data <= 1'b1 ;
228
 
229 10 mihad
    receiving = 0 ;
230
 
231
    if ( i === 10 )
232 2 mihad
    begin
233
        char_valid_o = !char_valid_o ;
234
    end
235
end
236
endtask // kbd_receive_char
237
 
238 24 primozs
 
239
time last_clk_low;
240
time last_clk_diference;
241
 
242
 
243
 
244
initial
245
begin
246
last_clk_low  =0;
247
last_clk_diference =0;
248
 
249
end
250
 
251
always @(negedge kbd_clk_io)
252
 
253
  begin:low_time_check
254
   if (kbd_clk == 1)
255
    begin
256
    last_clk_low =$time;
257
    fork
258
    begin
259
    #61000
260
    $display(" clock low more then 61us");
261
    $display("Time %t", $time) ;
262
    #30000
263
    $display("error clock low more then 90usec");
264
    $display("Time %t", $time) ;
265
    $stop;
266
    end
267
    begin
268
    @(posedge kbd_clk_io);
269
    disable low_time_check;
270
    end
271
    join
272
     end
273
   end
274
 
275
 
276
 
277
 
278
always @(posedge kbd_clk_io )
279
  begin
280
  if (last_clk_low >0 )
281
  begin
282
  last_clk_diference = $time - last_clk_low;
283
  if (last_clk_diference < 60000)
284
  begin
285
  $display("error time< 60u");
286
  #100 $stop;
287
  end
288
  end
289
  end
290
 
291
 
292
 
293
 
294
 
295
 
296 2 mihad
endmodule // ps2_keyboard_model

powered by: WebSVN 2.1.0

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