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 2

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

powered by: WebSVN 2.1.0

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