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

Subversion Repositories ps2

[/] [ps2/] [tags/] [rel_6/] [bench/] [verilog/] [ps2_test_bench.v] - Blame information for rev 6

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

Line No. Rev Author Line
1 2 mihad
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  ps2_test_bench.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 6 mihad
// Revision 1.2  2002/02/18 18:08:31  mihad
47
// One bug fixed
48
//
49 5 mihad
// Revision 1.1.1.1  2002/02/18 16:16:55  mihad
50
// Initial project import - working
51 2 mihad
//
52 5 mihad
//
53 2 mihad
 
54
`include "timescale.v"
55
`include "ps2_testbench_defines.v"
56
`include "ps2_defines.v"
57
 
58
`define KBD_STATUS_REG      32'h64
59
`define KBD_CNTL_REG        32'h64
60
`define KBD_DATA_REG        32'h60
61
/*
62
 * controller commands
63
 */
64
`define KBD_READ_MODE       32'h20
65
`define KBD_WRITE_MODE      32'h60
66
`define KBD_SELF_TEST       32'hAA
67
`define KBD_SELF_TEST2      32'hAB
68
`define KBD_CNTL_ENABLE     32'hAE
69
/*
70
 * keyboard commands
71
 */
72
`define KBD_ENABLE          32'hF4
73
`define KBD_DISABLE         32'hF5
74
`define KBD_RESET           32'hFF
75
/*
76
 * keyboard replies
77
 */
78
`define KBD_ACK             32'hFA
79
`define KBD_POR             32'hAA
80
/*
81
 * status register bits
82
 */
83
`define KBD_OBF             32'h01
84
`define KBD_IBF             32'h02
85
`define KBD_GTO             32'h40
86
`define KBD_PERR            32'h80
87
/*
88
 * keyboard controller mode register bits
89
 */
90
`define KBD_EKI             32'h01
91
`define KBD_SYS             32'h04
92
`define KBD_DMS             32'h20
93
`define KBD_KCC             32'h40
94
`define KBD_DISABLE_COMMAND 32'h10
95
 
96
module ps2_test_bench() ;
97
 
98
parameter [31:0] MAX_SEQUENCE_LENGTH = 10 ;
99
wire kbd_clk_cable  ;
100
wire kbd_data_cable ;
101
 
102
pullup(kbd_clk_cable)  ;
103
pullup(kbd_data_cable) ;
104
 
105
reg wb_clock ;
106
reg wb_reset ;
107
 
108
wire [7:0] received_char ;
109
wire       char_valid ;
110
 
111
`ifdef XILINX
112
    assign glbl.GSR = wb_reset ;
113
`endif
114
ps2_keyboard_model i_ps2_keyboard_model
115
(
116
    .kbd_clk_io  (kbd_clk_cable),
117
    .kbd_data_io (kbd_data_cable),
118
    .last_char_received_o (received_char),
119
    .char_valid_o (char_valid)
120
) ;
121
 
122
reg ok ;
123
reg error ;
124
 
125
integer watchdog_timer ;
126
reg     watchdog_reset ;
127
reg     watchdog_reset_previous ;
128
 
129
reg [7:0] normal_scancode_set2_mem [0:`PS2_NUM_OF_NORMAL_SCANCODES - 1] ;
130
reg [7:0] normal_scancode_set1_mem [0:`PS2_NUM_OF_NORMAL_SCANCODES - 1] ;
131
reg [7:0] extended_scancode_set2_mem [0:`PS2_NUM_OF_EXTENDED_SCANCODES - 1] ;
132
reg [7:0] extended_scancode_set1_mem [0:`PS2_NUM_OF_EXTENDED_SCANCODES - 1] ;
133
 
134
`define WB_PERIOD (1/`WB_FREQ)
135
initial
136
begin
137
 
138
    $readmemh("../../../bench/data/normal_scancodes_set2.hex", normal_scancode_set2_mem) ;
139
    $readmemh("../../../bench/data/normal_scancodes_set1.hex", normal_scancode_set1_mem) ;
140
    $readmemh("../../../bench/data/extended_scancodes_set2.hex", extended_scancode_set2_mem) ;
141
    $readmemh("../../../bench/data/extended_scancodes_set1.hex", extended_scancode_set1_mem) ;
142
 
143
    if ( ((`PS2_TIMER_5USEC_VALUE_PP * `WB_PERIOD) < 5000) || ((`PS2_TIMER_5USEC_VALUE_PP * `WB_PERIOD) > 6000) )
144
    begin
145
        $display("Warning! 5us timer max value is not defined correctly regarding to WISHBONE bus clock!") ;
146
        $stop ;
147
    end
148
 
149
    if ( ((`PS2_TIMER_60USEC_VALUE_PP * `WB_PERIOD) < 60000) || ((`PS2_TIMER_60USEC_VALUE_PP * `WB_PERIOD) > 61000) )
150
    begin
151
        $display("Warning! 60us timer max value is not defined correctly regarding to WISHBONE bus clock!") ;
152
        $stop ;
153
    end
154
 
155
    if ( (1 << `PS2_TIMER_5USEC_BITS_PP) < `PS2_TIMER_5USEC_VALUE_PP )
156
    begin
157
        $display("Warning! 5us timer max value is not defined correctly regarding to the length in bits of 5us timer!") ;
158
        $stop ;
159
    end
160
 
161
    if ( (1 << `PS2_TIMER_60USEC_BITS_PP) < `PS2_TIMER_60USEC_VALUE_PP )
162
    begin
163
        $display("Warning! 60us timer max value is not defined correctly regarding to the length in bits of 60us timer!") ;
164
        $stop ;
165
    end
166
 
167
    watchdog_timer = 32'h1000_0000 ;
168
    watchdog_reset = 0 ;
169
    watchdog_reset_previous = 0 ;
170
 
171
    wb_clock = 1'b1 ;
172
    wb_reset = 1'b1 ;
173
 
174
    #100 ;
175
 
176
    repeat ( 10 )
177
        @(posedge wb_clock) ;
178
    wb_reset <= 1'b0 ;
179
 
180
    @(posedge wb_clock) ;
181
    #1 initialize_controler ;
182
 
183
    test_scan_code_receiving ;
184
 
185
    test_normal_scancodes ;
186
 
187
    test_extended_scancodes ;
188
 
189
    test_print_screen_and_pause_scancodes ;
190
 
191
    test_keyboard_inhibit ;
192
 
193
    #400 $stop ;
194
end
195
 
196
always
197
    #(`WB_PERIOD / 2) wb_clock = !wb_clock ;
198
 
199
wire wb_cyc,
200
     wb_stb,
201
     wb_we,
202
     wb_ack,
203
     wb_rty,
204
     wb_int ;
205
 
206
wire [3:0] wb_sel ;
207
 
208
wire [31:0] wb_adr, wb_dat_m_s, wb_dat_s_m ;
209
 
210
ps2_sim_top
211
i_ps2_top
212
(
213
    .wb_clk_i        (wb_clock),
214
    .wb_rst_i        (wb_reset),
215
    .wb_cyc_i        (wb_cyc),
216
    .wb_stb_i        (wb_stb),
217
    .wb_we_i         (wb_we),
218
    .wb_sel_i        (wb_sel),
219
    .wb_adr_i        (wb_adr),
220
    .wb_dat_i        (wb_dat_m_s),
221
    .wb_dat_o        (wb_dat_s_m),
222
    .wb_ack_o        (wb_ack),
223
 
224
    .wb_int_o        (wb_int),
225
 
226
    .ps2_kbd_clk_io  (kbd_clk_cable),
227
    .ps2_kbd_data_io (kbd_data_cable)
228
) ;
229
 
230
WB_MASTER_BEHAVIORAL i_wb_master
231
(
232
    .CLK_I    (wb_clock),
233
    .RST_I    (wb_reset),
234
    .TAG_I    (1'b0),
235
    .TAG_O    (),
236
    .ACK_I    (wb_ack),
237
    .ADR_O    (wb_adr),
238
    .CYC_O    (wb_cyc),
239
    .DAT_I    (wb_dat_s_m),
240
    .DAT_O    (wb_dat_m_s),
241
    .ERR_I    (1'b0),
242
    .RTY_I    (1'b0),
243
    .SEL_O    (wb_sel),
244
    .STB_O    (wb_stb),
245
    .WE_O     (wb_we),
246
    .CAB_O    ()
247
);
248
 
249
always@(posedge wb_clock)
250
begin
251
    if ( watchdog_timer === 0 )
252
    begin
253
        $display("Warning! Simulation watchdog timer has expired!") ;
254
        watchdog_timer = 32'hFFFF_FFFF ;
255
    end
256
    else if ( watchdog_reset !== watchdog_reset_previous )
257
        watchdog_timer = 32'hFFFF_FFFF ;
258
 
259
    watchdog_reset_previous = watchdog_reset ;
260
 
261
end
262
 
263
task initialize_controler ;
264
    reg [7:0] data ;
265
    reg status ;
266
begin:main
267
 
268
    // simulate keyboard driver's behaviour 
269
    read_status_reg(data, status) ;
270
    if ( status !== 1 )
271
        disable main ;
272
 
273
    if ( data & `KBD_OBF )
274
        read_data_reg(data, status) ;
275
 
276
    if ( status !== 1 )
277
        disable main ;
278
 
279
    kbd_write(`KBD_CNTL_REG, `KBD_SELF_TEST, status) ;
280
 
281
    if ( status !== 1 )
282
        disable main ;
283
 
284
    // command sent - wait for commands output to be ready
285
    data = 0 ;
286
    while( status && !( data & `KBD_OBF ) )
287
        read_status_reg(data, status) ;
288
 
289
    if ( status !== 1 )
290
        disable main ;
291
 
292
    read_data_reg( data, status ) ;
293
 
294
    if ( status !== 1 )
295
        disable main ;
296
 
297
    if ( data !== 8'h55 )
298
    begin
299
        $display("Error! Keyboard controler should respond to self test command with hard coded value 0x55! ") ;
300
        #400 $stop ;
301
    end
302
 
303
    // perform self test 2
304
    kbd_write(`KBD_CNTL_REG, `KBD_SELF_TEST2, status) ;
305
 
306
    if ( status !== 1 )
307
        disable main ;
308
 
309
    // command sent - wait for commands output to be ready
310
    data = 0 ;
311
    while( status && !( data & `KBD_OBF ) )
312
        read_status_reg(data, status) ;
313
 
314
    if ( status !== 1 )
315
        disable main ;
316
 
317
    read_data_reg( data, status ) ;
318
 
319
    if ( status !== 1 )
320
        disable main ;
321
 
322
    if ( data !== 8'h00 )
323
    begin
324
        $display("Error! Keyboard controler should respond to self test command 2 with hard coded value 0x00! ") ;
325
        #400 $stop ;
326
    end
327
 
328
    kbd_write(`KBD_CNTL_REG, `KBD_CNTL_ENABLE, status);
329
 
330
    if ( status !== 1 )
331
        disable main ;
332
 
333
    // send reset command to keyboard
334
    kbd_write(`KBD_DATA_REG, `KBD_RESET, status) ;
335
 
336
    if ( status !== 1 )
337
        disable main ;
338
 
339
    fork
340
    begin
341
        // wait for keyboard to respond with acknowledge
342
        data = 0 ;
343
        while( status && !( data & `KBD_OBF ) )
344
            read_status_reg(data, status) ;
345
 
346
        if ( status !== 1 )
347
            disable main ;
348
 
349
        read_data_reg( data, status ) ;
350
 
351
        if ( status !== 1 )
352
            disable main ;
353
 
354
        if ( data !== `KBD_ACK )
355
        begin
356
            $display("Error! Expected character from keyboard was 0x%h, actualy received 0x%h!", `KBD_ACK, data ) ;
357
            #400 $stop ;
358
        end
359
 
360
        // wait for keyboard to respond with BAT status
361
        data = 0 ;
362
        while( status && !( data & `KBD_OBF ) )
363
            read_status_reg(data, status) ;
364
 
365
        if ( status !== 1 )
366
            disable main ;
367
 
368
        read_data_reg( data, status ) ;
369
 
370
        if ( status !== 1 )
371
            disable main ;
372
 
373
        if ( data !== `KBD_POR )
374
        begin
375
            $display("Error! Expected character from keyboard was 0x%h, actualy received 0x%h!", `KBD_POR, data ) ;
376
            #400 $stop ;
377
        end
378
 
379
        // send disable command to keyboard
380
        kbd_write(`KBD_DATA_REG, `KBD_DISABLE, status) ;
381
 
382
        if ( status !== 1 )
383
            disable main ;
384
 
385
        // wait for keyboard to respond with acknowledge
386
        data = 0 ;
387
        while( status && !( data & `KBD_OBF ) )
388
            read_status_reg(data, status) ;
389
 
390
        if ( status !== 1 )
391
            disable main ;
392
 
393
        read_data_reg( data, status ) ;
394
 
395
        if ( status !== 1 )
396
            disable main ;
397
 
398
        if ( data !== `KBD_ACK )
399
        begin
400
            $display("Error! Expected character from keyboard was 0x%h, actualy received 0x%h!", `KBD_ACK, data ) ;
401
            #400 $stop ;
402
        end
403
 
404
        kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, status);
405
        if ( status !== 1 )
406
            disable main ;
407
 
408
        kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`KBD_DMS|`KBD_KCC, status);
409
        if ( status !== 1 )
410
            disable main ;
411
 
412
        // send disable command to keyboard
413
        kbd_write(`KBD_DATA_REG, `KBD_ENABLE, status) ;
414
 
415
        if ( status !== 1 )
416
            disable main ;
417
 
418
        // wait for keyboard to respond with acknowledge
419
        data = 0 ;
420
        while( status && !( data & `KBD_OBF ) )
421
            read_status_reg(data, status) ;
422
 
423
        if ( status !== 1 )
424
            disable main ;
425
 
426
        read_data_reg( data, status ) ;
427
 
428
        if ( status !== 1 )
429
            disable main ;
430
 
431
        if ( data !== `KBD_ACK )
432
        begin
433
            $display("Error! Expected character from keyboard was 0x%h, actualy received 0x%h!", `KBD_ACK, data ) ;
434
            #400 $stop ;
435
        end
436
 
437
        // now check if command byte is as expected
438
        kbd_write(`KBD_CNTL_REG, `KBD_READ_MODE, status);
439
        if ( status !== 1 )
440
            disable main ;
441
 
442
        data = 0 ;
443
        while( status && !( data & `KBD_OBF ) )
444
            read_status_reg(data, status) ;
445
 
446
        if ( status !== 1 )
447
            disable main ;
448
 
449
        read_data_reg(data, status) ;
450
 
451
        if ( status !== 1 )
452
            disable main ;
453
 
454
        if ( (data & (`KBD_EKI|`KBD_SYS|`KBD_DMS|`KBD_KCC)) !== (`KBD_EKI|`KBD_SYS|`KBD_DMS|`KBD_KCC)  )
455
        begin
456
            $display("Error! Read command byte returned wrong value!") ;
457
            #400 $stop ;
458
        end
459
    end
460
    begin
461
        @(char_valid) ;
462
        if ( received_char !== `KBD_RESET )
463
        begin
464
            $display("Error! Keyboard received invalid character/command") ;
465
            #400 $stop ;
466
        end
467
 
468
        i_ps2_keyboard_model.kbd_send_char
469
        (
470
            `KBD_ACK,
471
            ok,
472
            error
473
        ) ;
474
 
475
        i_ps2_keyboard_model.kbd_send_char
476
        (
477
            `KBD_POR,
478
            ok,
479
            error
480
        ) ;
481
 
482
         @(char_valid) ;
483
        if ( received_char !== `KBD_DISABLE )
484
        begin
485
            $display("Error! Keyboard received invalid character/command") ;
486
            #400 $stop ;
487
        end
488
 
489
        i_ps2_keyboard_model.kbd_send_char
490
        (
491
            `KBD_ACK,
492
            ok,
493
            error
494
        ) ;
495
 
496
        @(char_valid) ;
497
        if ( received_char !== `KBD_ENABLE )
498
        begin
499
            $display("Error! Keyboard received invalid character/command") ;
500
            #400 $stop ;
501
        end
502
 
503
        i_ps2_keyboard_model.kbd_send_char
504
        (
505
            `KBD_ACK,
506
            ok,
507
            error
508
        ) ;
509
 
510
    end
511
    join
512
 
513
    watchdog_reset = !watchdog_reset ;
514
 
515
end
516
endtask // initialize_controler 
517
 
518
task read_data_reg ;
519
    output [7:0] return_byte_o ;
520
    output ok_o ;
521
    reg `READ_STIM_TYPE    read_data ;
522
    reg `READ_RETURN_TYPE  read_status ;
523
    reg `WB_TRANSFER_FLAGS flags ;
524
begin
525
    ok_o = 1 ;
526
    flags`WB_TRANSFER_SIZE     = 1 ;
527
    flags`WB_TRANSFER_AUTO_RTY = 0 ;
528
    flags`WB_TRANSFER_CAB      = 0 ;
529
    flags`INIT_WAITS           = 0 ;
530
    flags`SUBSEQ_WAITS         = 0 ;
531
 
532
    read_data`READ_ADDRESS = `KBD_DATA_REG ;
533 6 mihad
    read_data`READ_SEL     = 4'h8 ;
534 2 mihad
 
535
    read_status = 0 ;
536
 
537
    i_wb_master.wb_single_read( read_data, flags, read_status ) ;
538
 
539
    if ( read_status`CYC_ACK !== 1'b1 )
540
    begin
541
        $display("Error! Keyboard controler didn't acknowledge single read access!") ;
542
        #400 $stop ;
543
        ok_o = 0 ;
544
    end
545
    else
546
        return_byte_o = read_status`READ_DATA ;
547
 
548
end
549
endtask //read_data_reg
550
 
551
task read_status_reg ;
552
    output [7:0] return_byte_o ;
553
    output ok_o ;
554
    reg `READ_STIM_TYPE    read_data ;
555
    reg `READ_RETURN_TYPE  read_status ;
556
    reg `WB_TRANSFER_FLAGS flags ;
557
begin
558
    ok_o = 1 ;
559
    flags`WB_TRANSFER_SIZE     = 1 ;
560
    flags`WB_TRANSFER_AUTO_RTY = 0 ;
561
    flags`WB_TRANSFER_CAB      = 0 ;
562
    flags`INIT_WAITS           = 0 ;
563
    flags`SUBSEQ_WAITS         = 0 ;
564
 
565
    read_data`READ_ADDRESS = `KBD_STATUS_REG ;
566 6 mihad
    read_data`READ_SEL     = 4'h8 ;
567 2 mihad
 
568
    read_status = 0 ;
569
 
570
    i_wb_master.wb_single_read( read_data, flags, read_status ) ;
571
 
572
    if ( read_status`CYC_ACK !== 1'b1 )
573
    begin
574
        $display("Error! Keyboard controler didn't acknowledge single read access!") ;
575
        #400 $stop ;
576
        ok_o = 0 ;
577
    end
578
    else
579
        return_byte_o = read_status`READ_DATA ;
580
 
581
end
582
endtask // read_status_reg
583
 
584
task kbd_write ;
585
    input [31:0] address_i ;
586
    input [31:0] data_i ;
587
    output ok_o ;
588
 
589
    reg `WRITE_STIM_TYPE   write_data ;
590
    reg `WRITE_RETURN_TYPE write_status ;
591
    reg `WB_TRANSFER_FLAGS flags ;
592
    reg [7:0] kbd_status ;
593
begin:main
594
    ok_o = 1 ;
595
    flags`WB_TRANSFER_SIZE     = 1 ;
596
    flags`WB_TRANSFER_AUTO_RTY = 0 ;
597
    flags`WB_TRANSFER_CAB      = 0 ;
598
    flags`INIT_WAITS           = 0 ;
599
    flags`SUBSEQ_WAITS         = 0 ;
600
 
601
    write_data`WRITE_ADDRESS = address_i ;
602
    write_data`WRITE_DATA    = data_i ;
603 6 mihad
    write_data`WRITE_SEL     = 4'h8 ;
604 2 mihad
 
605
    read_status_reg(kbd_status, ok_o) ;
606
 
607
    while( ok_o && ( kbd_status & `KBD_IBF ))
608
    begin
609
        read_status_reg(kbd_status, ok_o) ;
610
    end
611
 
612
    if ( ok_o !== 1 )
613
        disable main ;
614
 
615
    i_wb_master.wb_single_write( write_data, flags, write_status ) ;
616
 
617
    if ( write_status`CYC_ACK !== 1 )
618
    begin
619
        $display("Error! Keyboard controller didn't acknowledge single write access") ;
620
        #400 $stop ;
621
        ok_o = 0 ;
622
    end
623
end
624
endtask // kbd_write
625
 
626
task test_scan_code_receiving ;
627
    reg ok_keyboard ;
628
    reg ok_controler ;
629
    reg ok ;
630
    reg [7:0] data ;
631
    reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] keyboard_sequence ;
632
    reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] controler_sequence ;
633
begin:main
634
    // prepare character sequence to send from keyboard to controler
635
    // L SHIFT make
636
    keyboard_sequence[7:0]   = 8'h12 ;
637
    // A make
638
    keyboard_sequence[15:8]  = 8'h1C ;
639
    // A break
640
    keyboard_sequence[23:16] = 8'hF0 ;
641
    keyboard_sequence[31:24] = 8'h1C ;
642
    // L SHIFT break
643
    keyboard_sequence[39:32] = 8'hF0 ;
644
    keyboard_sequence[47:40] = 8'h12 ;
645
 
646
    // prepare character sequence as it is received in scan code set 1 through the controler
647
    // L SHIFT make
648
    controler_sequence[7:0]   = 8'h2A ;
649
    // A make
650
    controler_sequence[15:8]  = 8'h1E ;
651
    // A break
652
    controler_sequence[23:16] = 8'h9E ;
653
    // L SHIFT break
654
    controler_sequence[31:24] = 8'hAA ;
655
 
656
    fork
657
    begin
658
        send_sequence( keyboard_sequence, 6, ok_keyboard ) ;
659
        if ( ok_keyboard !== 1 )
660
            disable main ;
661
    end
662
    begin
663
        receive_sequence( controler_sequence, 4, ok_controler ) ;
664
 
665
        if ( ok_controler !== 1 )
666
            disable main ;
667
    end
668
    join
669
 
670
    // test same thing with translation disabled!
671
    kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, ok);
672
    if ( ok !== 1 )
673
        disable main ;
674
 
675
    kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`KBD_DMS, ok);
676
    if ( ok !== 1 )
677
        disable main ;
678
 
679
    // since translation is disabled, controler sequence is the same as keyboard sequence
680
    controler_sequence = keyboard_sequence ;
681
 
682
    fork
683
    begin
684
 
685
        send_sequence( keyboard_sequence, 6, ok_keyboard ) ;
686
        if ( ok_keyboard !== 1 )
687
            disable main ;
688
 
689
    end
690
    begin
691
        receive_sequence( controler_sequence, 6, ok_controler ) ;
692
        if ( ok_controler !== 1 )
693
            disable main ;
694
    end
695
    join
696
 
697
    // turn translation on again
698
    kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, ok);
699
    if ( ok !== 1 )
700
        disable main ;
701
 
702
    kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`KBD_DMS|`KBD_KCC, ok);
703
    if ( ok !== 1 )
704
        disable main ;
705
 
706
    // test extended character receiving - rctrl + s combination
707
    // prepare sequence to send from keyboard to controler
708
    // R CTRL make
709
    keyboard_sequence[7:0]   = 8'hE0 ;
710
    keyboard_sequence[15:8]  = 8'h14 ;
711
    // S make
712
    keyboard_sequence[23:16] = 8'h1B ;
713
    // S break
714
    keyboard_sequence[31:24] = 8'hF0 ;
715
    keyboard_sequence[39:32] = 8'h1B ;
716
    // R CTRL break
717
    keyboard_sequence[47:40] = 8'hE0 ;
718
    keyboard_sequence[55:48] = 8'hF0 ;
719
    keyboard_sequence[63:56] = 8'h14 ;
720
 
721
    // prepare sequence that should be received from the controler
722
    // R CTRL make
723
    controler_sequence[7:0]   = 8'hE0 ;
724
    controler_sequence[15:8]  = 8'h1D ;
725
    // S make
726
    controler_sequence[23:16] = 8'h1F ;
727
    // S break
728
    controler_sequence[31:24] = 8'h9F ;
729
    // R CTRL break
730
    controler_sequence[39:32] = 8'hE0 ;
731
    controler_sequence[47:40] = 8'h9D ;
732
 
733
    fork
734
    begin
735
        send_sequence( keyboard_sequence, 8, ok_keyboard ) ;
736
        if ( ok_keyboard !== 1 )
737
            disable main ;
738
    end
739
    begin
740
 
741
        receive_sequence( controler_sequence, 6, ok_controler ) ;
742
 
743
        if ( ok_controler !== 1 )
744
            disable main ;
745
    end
746
    join
747
 
748
     // test same thing with translation disabled!
749
    kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, ok);
750
    if ( ok !== 1 )
751
        disable main ;
752
 
753
    kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`KBD_DMS, ok);
754
    if ( ok !== 1 )
755
        disable main ;
756
 
757
    // since translation is disabled, controler sequence is the same as keyboard sequence
758
    controler_sequence = keyboard_sequence ;
759
 
760
    fork
761
    begin
762
        send_sequence( keyboard_sequence, 8, ok_keyboard ) ;
763
        if ( ok_keyboard !== 1 )
764
            disable main ;
765
    end
766
    begin
767
 
768
        receive_sequence( controler_sequence, 8, ok_controler ) ;
769
 
770
        if ( ok_controler !== 1 )
771
            disable main ;
772
    end
773
    join
774
 
775
    watchdog_reset = !watchdog_reset ;
776
end
777
endtask // test_scan_code_receiving
778
 
779
task test_normal_scancodes ;
780
    reg ok ;
781
    reg ok_keyboard ;
782
    reg ok_controler ;
783
    integer i ;
784
    reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] keyboard_sequence ;
785
    reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] controler_sequence ;
786
begin:main
787
    // turn translation on
788
    kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, ok);
789
    if ( ok !== 1 )
790
        disable main ;
791
 
792
    kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`KBD_DMS|`KBD_KCC, ok);
793
    if ( ok !== 1 )
794
        disable main ;
795
 
796
    for ( i = 0 ; i < `PS2_NUM_OF_NORMAL_SCANCODES ; i = i + 1 )
797
    begin
798
        keyboard_sequence[7:0]   = normal_scancode_set2_mem[i] ;
799
        keyboard_sequence[15:8]  = 8'hF0 ;
800
        keyboard_sequence[23:16] = normal_scancode_set2_mem[i] ;
801
 
802
        controler_sequence[7:0]  = normal_scancode_set1_mem[i] ;
803
        controler_sequence[15:8] = normal_scancode_set1_mem[i] | 8'h80 ;
804
        fork
805
        begin
806
            send_sequence( keyboard_sequence, 3, ok_keyboard ) ;
807
            if ( ok_keyboard !== 1 )
808
                disable main ;
809
        end
810
        begin
811
            receive_sequence( controler_sequence, 2, ok_controler ) ;
812
            if ( ok_controler !== 1 )
813
                disable main ;
814
        end
815
        join
816
    end
817
 
818
    watchdog_reset = !watchdog_reset ;
819
 
820
end
821
endtask // test_normal_scancodes
822
 
823
task test_extended_scancodes ;
824
    reg ok ;
825
    reg ok_keyboard ;
826
    reg ok_controler ;
827
    integer i ;
828
    reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] keyboard_sequence ;
829
    reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] controler_sequence ;
830
begin:main
831
    // turn translation on
832
    kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, ok);
833
    if ( ok !== 1 )
834
        disable main ;
835
 
836
    kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`KBD_DMS|`KBD_KCC, ok);
837
    if ( ok !== 1 )
838
        disable main ;
839
 
840
    for ( i = 0 ; i < `PS2_NUM_OF_EXTENDED_SCANCODES ; i = i + 1 )
841
    begin
842
        keyboard_sequence[7:0]   = 8'hE0 ;
843
        keyboard_sequence[15:8]  = extended_scancode_set2_mem[i] ;
844
        keyboard_sequence[23:16] = 8'hE0 ;
845
        keyboard_sequence[31:24] = 8'hF0 ;
846
        keyboard_sequence[39:32] = extended_scancode_set2_mem[i] ;
847
 
848
        controler_sequence[7:0]   = 8'hE0 ;
849
        controler_sequence[15:8]  = extended_scancode_set1_mem[i] ;
850
        controler_sequence[23:16] = 8'hE0 ;
851
        controler_sequence[31:24] = extended_scancode_set1_mem[i] | 8'h80 ;
852
        fork
853
        begin
854
            send_sequence( keyboard_sequence, 5, ok_keyboard ) ;
855
            if ( ok_keyboard !== 1 )
856
                disable main ;
857
        end
858
        begin
859
            receive_sequence( controler_sequence, 4, ok_controler ) ;
860
            if ( ok_controler !== 1 )
861
                disable main ;
862
        end
863
        join
864
    end
865
 
866
    watchdog_reset = !watchdog_reset ;
867
 
868
end
869
endtask // test_extended_scancodes
870
 
871
task return_scan_code_on_irq ;
872
    output [7:0] scan_code_o ;
873
    output       ok_o ;
874
    reg    [7:0] temp_data ;
875
begin:main
876
    wait ( wb_int === 1 ) ;
877
    read_status_reg( temp_data, ok_o ) ;
878
 
879
    if ( ok_o !== 1'b1 )
880
        disable main ;
881
 
882
    if ( !( temp_data & `KBD_OBF ) )
883
    begin
884
        $display("Error! Interrupt received from keyboard controler when OBF status not set!") ;
885
        #400 $stop ;
886
    end
887
 
888
    read_data_reg( temp_data, ok_o ) ;
889
 
890
    if ( ok_o !== 1'b1 )
891
        disable main ;
892
 
893
    scan_code_o = temp_data ;
894
end
895
endtask // return_scan_code_on_irq
896
 
897
task send_sequence ;
898
    input [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] sequence_i ;
899
    input [31:0] num_of_chars_i ;
900
    output ok_o ;
901
    reg [7:0] current_char ;
902
    integer i ;
903
    reg ok ;
904
    reg error ;
905
begin:main
906
 
907
    error = 0 ;
908
    ok_o  = 1 ;
909
    ok    = 0 ;
910
 
911
    for( i = 0 ; i < num_of_chars_i ; i = i + 1 )
912
    begin
913
        current_char = sequence_i[7:0] ;
914
 
915
        sequence_i = sequence_i >> 8 ;
916
        ok = 0 ;
917
        error = 0 ;
918
        while ( (ok !== 1) && (error === 0) )
919
        begin
920
            i_ps2_keyboard_model.kbd_send_char
921
            (
922
                current_char,
923
                ok,
924
                error
925
            ) ;
926
        end
927
 
928
        if ( error )
929
        begin
930
            $display("Time %t", $time) ;
931
            $display("Keyboard model signaled an error!") ;
932
            ok_o = 0 ;
933
            disable main ;
934
        end
935
    end
936
end
937
endtask // send_sequence
938
 
939
task receive_sequence ;
940
    input [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] sequence_i ;
941
    input [31:0] num_of_chars_i ;
942
    output ok_o ;
943
    reg [7:0] current_char ;
944
    reg [7:0] data ;
945
    integer i ;
946
begin:main
947
 
948
    ok_o  = 1 ;
949
 
950
    for( i = 0 ; i < num_of_chars_i ; i = i + 1 )
951
    begin
952
        current_char = sequence_i[7:0] ;
953
 
954
        sequence_i = sequence_i >> 8 ;
955
 
956
        return_scan_code_on_irq( data, ok_o ) ;
957
 
958
        if ( ok_o !== 1 )
959
            disable main ;
960
 
961
        if ( data !== current_char )
962
        begin
963
            $display("Time %t", $time) ;
964
            $display("Error! Character received was wrong!") ;
965
            $display("Expected character: %h, received %h ", current_char, data ) ;
966
        end
967
    end
968
end
969
endtask // receive_seqence
970
 
971
task test_keyboard_inhibit ;
972
    reg ok_controler ;
973
    reg ok_keyboard ;
974
    reg error ;
975
    reg [7:0] data ;
976
begin:main
977
    // first test, if keyboard stays inhibited after character is received, but not read from the controler
978
    i_ps2_keyboard_model.kbd_send_char
979
    (
980
        8'hE0,
981
        ok_keyboard,
982
        error
983
    ) ;
984
 
985
    if ( error )
986
    begin
987
        $display("Error! Keyboard signaled an error while sending character!") ;
988
        disable main ;
989
    end
990
 
991
    if ( !ok_keyboard )
992
    begin
993
        $display("Something is wrong! Keyboard wasn't able to send a character!") ;
994
        disable main ;
995
    end
996
 
997
    // wait 5 us to see, if keyboard is inhibited
998
    #5000 ;
999
 
1000
    // now check, if clock line is low!
1001
    if ( kbd_clk_cable !== 0 )
1002
    begin
1003
        $display("Error! Keyboard wasn't inhibited when output buffer was filled!") ;
1004
        disable main ;
1005
    end
1006
 
1007
    // now read the character from input buffer and check if clock was released
1008
    return_scan_code_on_irq( data, ok_controler ) ;
1009
    if ( ok_controler !== 1'b1 )
1010
        disable main ;
1011
 
1012
    if ( data !== 8'hE0 )
1013
    begin
1014
        $display("Time %t", $time) ;
1015
        $display("Error! Character read from controler not as expected!") ;
1016
    end
1017
 
1018
    fork
1019
    begin
1020
        repeat(10)
1021
            @(posedge wb_clock) ;
1022
 
1023
        if ( kbd_clk_cable !== 1 )
1024
        begin
1025
            $display("Error! Keyboard wasn't released from inhibited state when output buffer was read!") ;
1026
            disable main ;
1027
        end
1028
    end
1029
    begin
1030
        i_ps2_keyboard_model.kbd_send_char
1031
        (
1032
            8'h1C,
1033
            ok_keyboard,
1034
            error
1035
        ) ;
1036
        if ( !ok_keyboard )
1037
        begin
1038
            $display("Something is wrong! Keyboard wasn't able to send a character!") ;
1039
            disable main ;
1040
        end
1041
    end
1042
    begin
1043
        return_scan_code_on_irq( data, ok_controler ) ;
1044
        if ( ok_controler !== 1'b1 )
1045
            disable main ;
1046
 
1047
        if ( data !== 8'h1E )
1048
        begin
1049
            $display("Time %t", $time) ;
1050
            $display("Error! Character read from controler not as expected!") ;
1051
        end
1052
    end
1053
    join
1054
 
1055
    // disable keyboard controler
1056
    kbd_write( `KBD_CNTL_REG, `KBD_WRITE_MODE, ok_controler ) ;
1057
    if ( ok_controler !== 1 )
1058
        disable main ;
1059
 
1060
    kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`KBD_DMS|`KBD_KCC | `KBD_DISABLE_COMMAND, ok_controler);
1061
 
1062
    if ( ok_controler !== 1 )
1063
        disable main ;
1064
 
1065
    repeat( 5 )
1066
        @(posedge wb_clock) ;
1067
 
1068
    // now check, if clock line is low!
1069
    if ( kbd_clk_cable !== 0 )
1070
    begin
1071
        $display("Error! Keyboard wasn't inhibited when keyboard controler was disabled!") ;
1072
        disable main ;
1073
    end
1074
 
1075
    // send character and enable keyboard controler at the same time
1076
    fork
1077
    begin
1078
        i_ps2_keyboard_model.kbd_send_char
1079
        (
1080
            8'hE0,
1081
            ok_keyboard,
1082
            error
1083
        ) ;
1084
 
1085
        if ( !ok_keyboard )
1086
        begin
1087
            $display("Something is wrong! Keyboard wasn't able to send a character!") ;
1088
            disable main ;
1089
        end
1090
    end
1091
    begin
1092
        // enable keyboard controler
1093
        kbd_write( `KBD_CNTL_REG, `KBD_WRITE_MODE, ok_controler ) ;
1094
        if ( ok_controler !== 1 )
1095
            disable main ;
1096
 
1097
        kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`KBD_DMS|`KBD_KCC, ok_controler);
1098
        if ( ok_controler !== 1 )
1099
            disable main ;
1100
    end
1101
    begin
1102
        return_scan_code_on_irq( data, ok_controler ) ;
1103
        if ( ok_controler !== 1'b1 )
1104
            disable main ;
1105
 
1106
        if ( data !== 8'hE0 )
1107
        begin
1108
            $display("Time %t", $time) ;
1109
            $display("Error! Character read from controler not as expected!") ;
1110
        end
1111
    end
1112
    join
1113 5 mihad
 
1114
    // do D2 command, that copies parameter in input buffer to output buffer
1115
    kbd_write( `KBD_CNTL_REG, 32'hD2, ok_controler ) ;
1116
    if ( ok_controler !== 1 )
1117
        disable main ;
1118
 
1119
    kbd_write(`KBD_DATA_REG, 32'h5555_5555, ok_controler) ;
1120
 
1121
    if ( ok_controler !== 1 )
1122
        disable main ;
1123
 
1124
    return_scan_code_on_irq( data, ok_controler ) ;
1125
    if ( ok_controler !== 1 )
1126
        disable main ;
1127
 
1128
    if ( data !== 8'h55 )
1129
    begin
1130
        $display("Error! D2 command doesn't work properly") ;
1131
    end
1132
 
1133 2 mihad
end
1134
endtask // test_keyboard_inhibit
1135
 
1136
task test_print_screen_and_pause_scancodes ;
1137
    reg ok ;
1138
    reg ok_keyboard ;
1139
    reg ok_controler ;
1140
    integer i ;
1141
    reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] keyboard_sequence ;
1142
    reg [(MAX_SEQUENCE_LENGTH*8 - 1) : 0] controler_sequence ;
1143
begin:main
1144
    // turn translation on
1145
    kbd_write(`KBD_CNTL_REG, `KBD_WRITE_MODE, ok);
1146
    if ( ok !== 1 )
1147
        disable main ;
1148
 
1149
    kbd_write(`KBD_DATA_REG, `KBD_EKI|`KBD_SYS|`KBD_DMS|`KBD_KCC, ok);
1150
    if ( ok !== 1 )
1151
        disable main ;
1152
 
1153
    // prepare character sequence to send from keyboard to controler - pause
1154
    keyboard_sequence[7:0]   = 8'hE1 ;
1155
    keyboard_sequence[15:8]  = 8'h14 ;
1156
    keyboard_sequence[23:16] = 8'h77 ;
1157
    keyboard_sequence[31:24] = 8'hE1 ;
1158
    keyboard_sequence[39:32] = 8'hF0 ;
1159
    keyboard_sequence[47:40] = 8'h14 ;
1160
    keyboard_sequence[55:48] = 8'hF0 ;
1161
    keyboard_sequence[63:56] = 8'h77 ;
1162
 
1163
    // prepare character sequence as it is received in scan code set 1 through the controler
1164
    controler_sequence[7:0]   = 8'hE1 ;
1165
    controler_sequence[15:8]  = 8'h1D ;
1166
    controler_sequence[23:16] = 8'h45 ;
1167
    controler_sequence[31:24] = 8'hE1 ;
1168
    controler_sequence[39:32] = 8'h9D ;
1169
    controler_sequence[47:40] = 8'hC5 ;
1170
 
1171
    fork
1172
    begin
1173
        send_sequence( keyboard_sequence, 8, ok_keyboard ) ;
1174
        if ( ok_keyboard !== 1 )
1175
            disable main ;
1176
    end
1177
    begin
1178
        receive_sequence( controler_sequence, 6, ok_controler ) ;
1179
        if ( ok_controler !== 1 )
1180
            disable main ;
1181
    end
1182
    join
1183
 
1184
    // prepare character sequence to send from keyboard to controler - make print screen
1185
    keyboard_sequence[7:0]   = 8'hE0 ;
1186
    keyboard_sequence[15:8]  = 8'h12 ;
1187
    keyboard_sequence[23:16] = 8'hE0 ;
1188
    keyboard_sequence[31:24] = 8'h7C ;
1189
 
1190
    // prepare character sequence as it is received in scan code set 1 through the controler
1191
    controler_sequence[7:0]   = 8'hE0 ;
1192
    controler_sequence[15:8]  = 8'h2A ;
1193
    controler_sequence[23:16] = 8'hE0 ;
1194
    controler_sequence[31:24] = 8'h37 ;
1195
 
1196
    fork
1197
    begin
1198
        send_sequence( keyboard_sequence, 4, ok_keyboard ) ;
1199
        if ( ok_keyboard !== 1 )
1200
            disable main ;
1201
    end
1202
    begin
1203
        receive_sequence( controler_sequence, 4, ok_controler ) ;
1204
        if ( ok_controler !== 1 )
1205
            disable main ;
1206
    end
1207
    join
1208
 
1209
    // prepare character sequence to send from keyboard to controler - break print screen
1210
    keyboard_sequence[7:0]   = 8'hE0 ;
1211
    keyboard_sequence[15:8]  = 8'hF0 ;
1212
    keyboard_sequence[23:16] = 8'h7C ;
1213
    keyboard_sequence[31:24] = 8'hE0 ;
1214
    keyboard_sequence[39:32] = 8'hF0 ;
1215
    keyboard_sequence[47:40] = 8'h12 ;
1216
 
1217
    // prepare character sequence as it is received in scan code set 1 through the controler
1218
    controler_sequence[7:0]   = 8'hE0 ;
1219
    controler_sequence[15:8]  = 8'hB7 ;
1220
    controler_sequence[23:16] = 8'hE0 ;
1221
    controler_sequence[31:24] = 8'hAA ;
1222
 
1223
    fork
1224
    begin
1225
        send_sequence( keyboard_sequence, 6, ok_keyboard ) ;
1226
        if ( ok_keyboard !== 1 )
1227
            disable main ;
1228
    end
1229
    begin
1230
        receive_sequence( controler_sequence, 4, ok_controler ) ;
1231
        if ( ok_controler !== 1 )
1232
            disable main ;
1233
    end
1234
    join
1235
end
1236
endtask // test_print_screen_and_pause_scancodes
1237
 
1238
endmodule // ps2_test_bench

powered by: WebSVN 2.1.0

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