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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [orp/] [orp_soc/] [rtl/] [verilog/] [ps2.old/] [ps2_wb_if.v] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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