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

Subversion Repositories ps2

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

powered by: WebSVN 2.1.0

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