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

Subversion Repositories ps2

[/] [ps2/] [tags/] [asyst_2/] [rtl/] [verilog/] [ps2_wb_if.v] - Blame information for rev 6

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

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

powered by: WebSVN 2.1.0

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