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

Subversion Repositories ps2

[/] [ps2/] [tags/] [rel_5/] [rtl/] [verilog/] [ps2_wb_if.v] - Blame information for rev 5

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

Line No. Rev Author Line
1 2 mihad
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  ps2_wb_if.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 5 mihad
// Revision 1.1.1.1  2002/02/18 16:16:56  mihad
47
// Initial project import - working
48 2 mihad
//
49 5 mihad
//
50 2 mihad
 
51
// synopsys translate_off
52
`include "timescale.v"
53
// synopsys translate_on
54
 
55
module ps2_wb_if
56
(
57
    wb_clk_i,
58
    wb_rst_i,
59
    wb_cyc_i,
60
    wb_stb_i,
61
    wb_we_i,
62
    wb_sel_i,
63
    wb_adr_i,
64
    wb_dat_i,
65
    wb_dat_o,
66
    wb_ack_o,
67
 
68
    wb_int_o,
69
 
70
    tx_write_ack_i,
71
    tx_data_o,
72
    tx_write_o,
73
    rx_scancode_i,
74
    rx_data_ready_i,
75
    rx_read_o,
76
    translate_o,
77
    ps2_clk_i,
78
    inhibit_kbd_if_o
79
) ;
80
 
81
input wb_clk_i,
82
      wb_rst_i,
83
      wb_cyc_i,
84
      wb_stb_i,
85
      wb_we_i ;
86
 
87
input [3:0]  wb_sel_i ;
88
 
89
input [31:0] wb_adr_i ;
90
 
91
input [31:0]  wb_dat_i ;
92
 
93
output [31:0] wb_dat_o ;
94
 
95
output wb_ack_o ;
96
 
97
reg wb_ack_o ;
98
 
99
output wb_int_o ;
100
reg    wb_int_o ;
101
 
102
input tx_write_ack_i ;
103
 
104
input [7:0] rx_scancode_i ;
105
input       rx_data_ready_i ;
106
output      rx_read_o ;
107
 
108
output      tx_write_o ;
109
output [7:0] tx_data_o ;
110
 
111
output translate_o ;
112
input  ps2_clk_i ;
113
 
114
output inhibit_kbd_if_o ;
115
 
116
reg [7:0] input_buffer,
117
          output_buffer ;
118
 
119
assign tx_data_o = output_buffer ;
120
 
121
reg input_buffer_full,   // receive buffer
122
    output_buffer_full ; // transmit buffer
123
 
124
assign tx_write_o = output_buffer_full ;
125
 
126
wire system_flag ;
127
wire a2                       = 1'b0 ;
128
wire kbd_inhibit              = ps2_clk_i ;
129
wire mouse_output_buffer_full = 1'b0 ;
130
wire timeout                  = 1'b0 ;
131
wire perr                     = 1'b0 ;
132
 
133
wire [7:0] status_byte = {perr, timeout, mouse_output_buffer_full, kbd_inhibit, a2, system_flag, output_buffer_full, input_buffer_full} ;
134
 
135
reg  read_input_buffer_reg ;
136
wire read_input_buffer = wb_cyc_i && wb_stb_i && wb_sel_i[0] && !wb_ack_o && !read_input_buffer_reg && !wb_we_i && (wb_adr_i[2:0] == 3'h0) ;
137
 
138
reg  write_output_buffer_reg ;
139
wire write_output_buffer  = wb_cyc_i && wb_stb_i && wb_sel_i[0] && !wb_ack_o && !write_output_buffer_reg && wb_we_i  && (wb_adr_i[2:0] == 3'h0) ;
140
 
141
reg  read_status_register_reg ;
142
wire read_status_register = wb_cyc_i && wb_stb_i && wb_sel_i[0] && !wb_ack_o && !read_status_register_reg && !wb_we_i && (wb_adr_i[2:0] == 3'h4) ;
143
 
144
reg  send_command_reg ;
145
wire send_command = wb_cyc_i && wb_stb_i && wb_sel_i[0] && !wb_ack_o && !send_command_reg && wb_we_i  && (wb_adr_i[2:0] == 3'h4) ;
146
 
147
reg  translate_o,
148
     enable1,
149
     system,
150
     interrupt1 ;
151
 
152
reg inhibit_kbd_if_o ;
153
always@(posedge wb_clk_i or posedge wb_rst_i)
154
begin
155
    if ( wb_rst_i )
156
        inhibit_kbd_if_o <= #1 1'b1 ;
157
    else if ( ps2_clk_i && (rx_data_ready_i || enable1) )
158
        inhibit_kbd_if_o <= #1 1'b1 ;
159
    else if ( !rx_data_ready_i && !enable1 )
160
        inhibit_kbd_if_o <= #1 1'b0 ;
161
 
162
end
163
 
164
wire interrupt2 = 1'b0 ;
165
wire enable2    = 1'b1 ;
166
 
167
assign system_flag = system ;
168
 
169
wire [7:0] command_byte = {1'b0, translate_o, enable2, enable1, 1'b0, system, interrupt2, interrupt1} ;
170
 
171
reg [7:0] current_command ;
172
reg [7:0] current_command_output ;
173
 
174
always@(posedge wb_clk_i or posedge wb_rst_i)
175
begin
176
    if ( wb_rst_i )
177
    begin
178
        send_command_reg         <= #1 1'b0 ;
179
        read_input_buffer_reg    <= #1 1'b0 ;
180
        write_output_buffer_reg  <= #1 1'b0 ;
181
        read_status_register_reg <= #1 1'b0 ;
182
    end
183
    else
184
    begin
185
        send_command_reg         <= #1 send_command ;
186
        read_input_buffer_reg    <= #1 read_input_buffer ;
187
        write_output_buffer_reg  <= #1 write_output_buffer ;
188
        read_status_register_reg <= #1 read_status_register ;
189
    end
190
end
191
 
192
always@(posedge wb_clk_i or posedge wb_rst_i)
193
begin
194
    if ( wb_rst_i )
195
        current_command <= #1 8'h0 ;
196
    else if ( send_command_reg )
197
        current_command <= #1 wb_dat_i[7:0] ;
198
end
199
 
200
reg current_command_valid,
201
    current_command_returns_value,
202
    current_command_gets_parameter,
203
    current_command_gets_null_terminated_string ;
204
 
205
reg write_output_buffer_reg_previous ;
206
always@(posedge wb_clk_i or posedge wb_rst_i)
207
begin
208
    if ( wb_rst_i )
209
        write_output_buffer_reg_previous <= #1 1'b0 ;
210
    else
211
        write_output_buffer_reg_previous <= #1 write_output_buffer_reg ;
212
end
213
 
214
wire invalidate_current_command =
215
     current_command_valid &&
216
     (( current_command_returns_value && read_input_buffer_reg && input_buffer_full) ||
217
      ( current_command_gets_parameter && write_output_buffer_reg_previous ) ||
218
      ( current_command_gets_null_terminated_string && write_output_buffer_reg_previous && (output_buffer == 8'h00) ) ||
219
      ( !current_command_returns_value && !current_command_gets_parameter && !current_command_gets_null_terminated_string )
220
     ) ;
221
 
222
always@(posedge wb_clk_i or posedge wb_rst_i)
223
begin
224
    if ( wb_rst_i )
225
        current_command_valid <= #1 1'b0 ;
226
    else if ( invalidate_current_command )
227
        current_command_valid <= #1 1'b0 ;
228
    else if ( send_command_reg )
229
        current_command_valid <= #1 1'b1 ;
230
 
231
end
232
 
233
reg write_command_byte ;
234
reg current_command_output_valid ;
235
always@(
236
    current_command or
237
    command_byte or
238
    write_output_buffer_reg_previous or
239
    current_command_valid or
240
    output_buffer
241
)
242
begin
243
    current_command_returns_value               = 1'b0 ;
244
    current_command_gets_parameter              = 1'b0 ;
245
    current_command_gets_null_terminated_string = 1'b0 ;
246
    current_command_output                      = 8'h00 ;
247
    write_command_byte                          = 1'b0 ;
248
    current_command_output_valid                = 1'b0 ;
249
    case(current_command)
250
        8'h20:begin
251
                  current_command_returns_value  = 1'b1 ;
252
                  current_command_output         = command_byte ;
253
                  current_command_output_valid   = 1'b1 ;
254
              end
255
        8'h60:begin
256
                  current_command_gets_parameter = 1'b1 ;
257
                  write_command_byte             = write_output_buffer_reg_previous && current_command_valid ;
258
              end
259
        8'hA1:begin
260
                  current_command_returns_value = 1'b1 ;
261
                  current_command_output        = 8'h00 ;
262
                  current_command_output_valid  = 1'b1 ;
263
              end
264
        8'hA4:begin
265
                  current_command_returns_value = 1'b1 ;
266
                  current_command_output        = 8'hF1 ;
267
                  current_command_output_valid  = 1'b1 ;
268
              end
269
        8'hA5:begin
270
                  current_command_gets_null_terminated_string = 1'b1 ;
271
              end
272
        8'hA6:begin
273
              end
274
        8'hA7:begin
275
              end
276
        8'hA8:begin
277
              end
278
        8'hA9:begin
279
                  current_command_returns_value = 1'b1 ;
280
                  current_command_output        = 8'h02 ; // clock line stuck high
281
                  current_command_output_valid  = 1'b1 ;
282
              end
283
        8'hAA:begin
284
                  current_command_returns_value = 1'b1 ;
285
                  current_command_output        = 8'h55 ;
286
                  current_command_output_valid  = 1'b1 ;
287
              end
288
        8'hAB:begin
289
                  current_command_returns_value = 1'b1 ;
290
                  current_command_output        = 8'h00 ;
291
                  current_command_output_valid  = 1'b1 ;
292
              end
293
        8'hAD:begin
294
              end
295
        8'hAE:begin
296
              end
297
        8'hAF:begin
298
                  current_command_returns_value = 1'b1 ;
299
                  current_command_output        = 8'h00 ;
300
                  current_command_output_valid  = 1'b1 ;
301
              end
302
        8'hC0:begin
303
                  current_command_returns_value = 1'b1 ;
304
                  current_command_output        = 8'hFF ;
305
                  current_command_output_valid  = 1'b1 ;
306
              end
307
        8'hC1:begin
308
              end
309
        8'hC2:begin
310
              end
311
        8'hD0:begin
312
                  current_command_returns_value = 1'b1 ;
313
                  current_command_output        = 8'h01 ; // only system reset bit is 1
314
                  current_command_output_valid  = 1'b1 ;
315
              end
316
        8'hD1:begin
317
                  current_command_gets_parameter = 1'b1 ;
318
              end
319
        8'hD2:begin
320 5 mihad
                  current_command_returns_value   = 1'b1 ;
321 2 mihad
                  current_command_gets_parameter  = 1'b1 ;
322
                  current_command_output          = output_buffer ;
323
                  current_command_output_valid    = write_output_buffer_reg_previous ;
324
              end
325
        8'hD3:begin
326
                  current_command_gets_parameter = 1'b1 ;
327
              end
328
        8'hD4:begin
329
                  current_command_gets_parameter = 1'b1 ;
330
              end
331
        8'hE0:begin
332
                  current_command_returns_value = 1'b1 ;
333
                  current_command_output        = 8'hFF ;
334
                  current_command_output_valid  = 1'b1 ;
335
              end
336
    endcase
337
end
338
 
339
reg cyc_i_previous ;
340
reg stb_i_previous ;
341
 
342
always@(posedge wb_clk_i or posedge wb_rst_i)
343
begin
344
    if ( wb_rst_i )
345
    begin
346
        cyc_i_previous <= #1 1'b0 ;
347
        stb_i_previous <= #1 1'b0 ;
348
    end
349
    else if ( wb_ack_o )
350
    begin
351
        cyc_i_previous <= #1 1'b0 ;
352
        stb_i_previous <= #1 1'b0 ;
353
    end
354
    else
355
    begin
356
        cyc_i_previous <= #1 wb_cyc_i ;
357
        stb_i_previous <= #1 wb_stb_i ;
358
    end
359
 
360
end
361
 
362
always@(posedge wb_clk_i or posedge wb_rst_i)
363
begin
364
    if ( wb_rst_i )
365
        wb_ack_o <= #1 1'b0 ;
366
    else if ( wb_ack_o )
367
        wb_ack_o <= #1 1'b0 ;
368
    else
369
        wb_ack_o <= #1 cyc_i_previous && stb_i_previous ;
370
end
371
 
372
reg [31:0] wb_dat_o ;
373
wire wb_read = read_input_buffer_reg || read_status_register_reg ;
374
 
375
wire [7:0] output_data = read_status_register_reg ? status_byte : input_buffer ;
376
always@(posedge wb_clk_i or posedge wb_rst_i)
377
begin
378
    if ( wb_rst_i )
379
        wb_dat_o <= #1 32'h0 ;
380
    else if ( wb_read )
381
        wb_dat_o <= #1 {4{output_data}} ;
382
end
383
 
384
always@(posedge wb_clk_i or posedge wb_rst_i)
385
begin
386
    if ( wb_rst_i )
387
        output_buffer_full <= #1 1'b0 ;
388
    else if ( output_buffer_full && tx_write_ack_i)
389
        output_buffer_full <= #1 1'b0 ;
390
    else
391
        output_buffer_full <= #1 write_output_buffer_reg && (!current_command_valid || (!current_command_gets_parameter && !current_command_gets_null_terminated_string)) ;
392
end
393
 
394
always@(posedge wb_clk_i or posedge wb_rst_i)
395
begin
396
    if ( wb_rst_i )
397
        output_buffer <= #1 8'h00 ;
398
    else if ( write_output_buffer_reg )
399
        output_buffer <= #1 wb_dat_i[7:0] ;
400
end
401
 
402
always@(posedge wb_clk_i or posedge wb_rst_i)
403
begin
404
    if ( wb_rst_i )
405
    begin
406
        translate_o <= #1 1'b0 ;
407
        system      <= #1 1'b0 ;
408
        interrupt1  <= #1 1'b0 ;
409
    end
410
    else if ( write_command_byte )
411
    begin
412
        translate_o <= #1 output_buffer[6] ;
413
        system      <= #1 output_buffer[2] ;
414
        interrupt1  <= #1 output_buffer[0] ;
415
    end
416
end
417
 
418
always@(posedge wb_clk_i or posedge wb_rst_i)
419
begin
420
    if ( wb_rst_i )
421
        enable1 <= #1 1'b1 ;
422
    else if ( current_command_valid && (current_command == 8'hAE) )
423
        enable1 <= #1 1'b0 ;
424
    else if ( current_command_valid && (current_command == 8'hAD) )
425
        enable1 <= #1 1'b1 ;
426
    else if ( write_command_byte )
427
        enable1 <= #1 output_buffer[4] ;
428
 
429
end
430
 
431
wire write_input_buffer_from_command = current_command_valid && current_command_returns_value && current_command_output_valid ;
432
reg  write_input_buffer_from_command_reg ;
433
always@(posedge wb_clk_i or posedge wb_rst_i)
434
begin
435
    if ( wb_rst_i )
436
        write_input_buffer_from_command_reg <= #1 1'b0 ;
437
    else
438
        write_input_buffer_from_command_reg <= #1 write_input_buffer_from_command ;
439
end
440
 
441
always@(posedge wb_clk_i or posedge wb_rst_i)
442
begin
443
    if ( wb_rst_i )
444
        input_buffer_full <= #1 1'b0 ;
445
    else if ( read_input_buffer_reg )
446
        input_buffer_full <= #1 1'b0 ;
447
    else if ( (write_input_buffer_from_command && !write_input_buffer_from_command_reg) || (rx_data_ready_i && !enable1) )
448
        input_buffer_full <= #1 1'b1 ;
449
end
450
 
451
reg input_buffer_filled_from_command ;
452
always@(posedge wb_clk_i or posedge wb_rst_i)
453
begin
454
    if ( wb_rst_i )
455
        input_buffer_filled_from_command <= #1 1'b0 ;
456
    else if ( read_input_buffer_reg )
457
        input_buffer_filled_from_command <= #1 1'b0 ;
458
    else if ( write_input_buffer_from_command && !write_input_buffer_from_command_reg)
459
        input_buffer_filled_from_command <= #1 1'b1 ;
460
end
461
 
462
reg rx_data_ready_reg ;
463
always@(posedge wb_clk_i or posedge wb_rst_i)
464
begin
465
    if ( wb_rst_i )
466
        rx_data_ready_reg <= #1 1'b0 ;
467
    else if ( input_buffer_filled_from_command )
468
        rx_data_ready_reg <= #1 1'b0 ;
469
    else
470
        rx_data_ready_reg <= #1 rx_data_ready_i ;
471
end
472
 
473
wire input_buffer_value_change = (rx_data_ready_i && !rx_data_ready_reg && !enable1) || (write_input_buffer_from_command && !write_input_buffer_from_command_reg) ;
474
 
475
always@(posedge wb_clk_i or posedge wb_rst_i)
476
begin
477
    if ( wb_rst_i )
478
        input_buffer <= #1 8'h00 ;
479
    else if ( input_buffer_value_change )
480
        input_buffer <= #1 current_command_valid && current_command_returns_value ? current_command_output : rx_scancode_i ;
481
end
482
 
483
assign rx_read_o = enable1 || rx_data_ready_i && !input_buffer_filled_from_command && read_input_buffer_reg ;
484
 
485
always@(posedge wb_clk_i or posedge wb_rst_i)
486
begin
487
    if ( wb_rst_i )
488
        wb_int_o <= #1 1'b0 ;
489
    else if ( read_input_buffer_reg || enable1 || !interrupt1)
490
        wb_int_o <= #1 1'b0 ;
491
    else
492
        wb_int_o <= #1 input_buffer_full ;
493
end
494
 
495
endmodule // ps2_wb_if

powered by: WebSVN 2.1.0

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