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 7

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

powered by: WebSVN 2.1.0

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